mirror of
https://github.com/SerenityOS/serenity
synced 2024-09-06 17:06:31 +00:00
Switch into 1024x768x32bpp VESA LFB mode at boot.
This is going to be pretty cool once I can hook up the Widgets/ code to it.
This commit is contained in:
parent
9963da9005
commit
659c54e32b
|
@ -9,6 +9,43 @@ boot:
|
|||
mov ss, ax
|
||||
mov sp, 0xffff
|
||||
|
||||
; get vesa modes
|
||||
mov ax, 0x4f00
|
||||
xor dx, dx
|
||||
mov es, dx
|
||||
mov di, 0xc000
|
||||
mov [es:di], byte 'V'
|
||||
mov [es:di+1], byte 'B'
|
||||
mov [es:di+2], byte 'E'
|
||||
mov [es:di+3], byte '2'
|
||||
int 0x10
|
||||
cmp ax, 0x004f
|
||||
jne fug
|
||||
cmp [es:di], byte 'V'
|
||||
jne fug
|
||||
cmp [es:di+1], byte 'E'
|
||||
jne fug
|
||||
cmp [es:di+2], byte 'S'
|
||||
jne fug
|
||||
cmp [es:di+3], byte 'A'
|
||||
jne fug
|
||||
|
||||
; get vesa info
|
||||
mov ax, 0x4f01
|
||||
mov cx, 0x144
|
||||
xor dx, dx
|
||||
mov es, dx
|
||||
mov di, 0x2000
|
||||
int 0x10
|
||||
cmp ax, 0x004f
|
||||
jne fug
|
||||
|
||||
mov ax, 0x4f02
|
||||
mov bx, 0x4144
|
||||
int 0x10
|
||||
cmp ax, 0x004f
|
||||
jne fug
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
xor bx, bx
|
||||
|
|
|
@ -24,7 +24,8 @@ KERNEL_OBJS = \
|
|||
DoubleBuffer.o \
|
||||
ELFImage.o \
|
||||
ELFLoader.o \
|
||||
KSyms.o
|
||||
KSyms.o \
|
||||
WindowComposer.o
|
||||
|
||||
VFS_OBJS = \
|
||||
../VirtualFileSystem/DiskDevice.o \
|
||||
|
@ -40,13 +41,17 @@ VFS_OBJS = \
|
|||
../VirtualFileSystem/FileDescriptor.o \
|
||||
../VirtualFileSystem/SyntheticFileSystem.o
|
||||
|
||||
WIDGETS_OBJS = \
|
||||
../Widgets/Window.o \
|
||||
../Widgets/Painter.o
|
||||
|
||||
AK_OBJS = \
|
||||
../AK/String.o \
|
||||
../AK/StringImpl.o \
|
||||
../AK/StringBuilder.o \
|
||||
../AK/FileSystemPath.o
|
||||
|
||||
OBJS = $(KERNEL_OBJS) $(VFS_OBJS) $(AK_OBJS) $(ELFLOADER_OBJS)
|
||||
OBJS = $(KERNEL_OBJS) $(VFS_OBJS) $(AK_OBJS) $(WIDGETS_OBJS)
|
||||
|
||||
NASM = nasm
|
||||
KERNEL = kernel
|
||||
|
|
|
@ -652,6 +652,12 @@ RetainPtr<VMObject> VMObject::create_anonymous(size_t size)
|
|||
return adopt(*new VMObject(size));
|
||||
}
|
||||
|
||||
RetainPtr<VMObject> VMObject::create_framebuffer_wrapper(PhysicalAddress paddr, size_t size)
|
||||
{
|
||||
size = ceilDiv(size, PAGE_SIZE) * PAGE_SIZE;
|
||||
return adopt(*new VMObject(paddr, size));
|
||||
}
|
||||
|
||||
RetainPtr<VMObject> VMObject::clone()
|
||||
{
|
||||
return adopt(*new VMObject(*this));
|
||||
|
@ -676,6 +682,18 @@ VMObject::VMObject(size_t size)
|
|||
m_physical_pages.resize(page_count());
|
||||
}
|
||||
|
||||
VMObject::VMObject(PhysicalAddress paddr, size_t size)
|
||||
: m_anonymous(true)
|
||||
, m_size(size)
|
||||
{
|
||||
MM.register_vmo(*this);
|
||||
for (size_t i = 0; i < size; i += PAGE_SIZE) {
|
||||
m_physical_pages.append(adopt(*new PhysicalPage(paddr.offset(i), false)));
|
||||
}
|
||||
ASSERT(m_physical_pages.size() == page_count());
|
||||
}
|
||||
|
||||
|
||||
VMObject::VMObject(RetainPtr<Vnode>&& vnode, size_t size)
|
||||
: m_size(size)
|
||||
, m_vnode(move(vnode))
|
||||
|
|
|
@ -23,6 +23,7 @@ class PhysicalPage {
|
|||
AK_MAKE_ETERNAL
|
||||
friend class MemoryManager;
|
||||
friend class PageDirectory;
|
||||
friend class VMObject;
|
||||
public:
|
||||
PhysicalAddress paddr() const { return m_paddr; }
|
||||
|
||||
|
@ -73,6 +74,7 @@ class VMObject : public Retainable<VMObject> {
|
|||
public:
|
||||
static RetainPtr<VMObject> create_file_backed(RetainPtr<Vnode>&&, size_t);
|
||||
static RetainPtr<VMObject> create_anonymous(size_t);
|
||||
static RetainPtr<VMObject> create_framebuffer_wrapper(PhysicalAddress, size_t);
|
||||
RetainPtr<VMObject> clone();
|
||||
|
||||
~VMObject();
|
||||
|
@ -93,6 +95,7 @@ private:
|
|||
VMObject(RetainPtr<Vnode>&&, size_t);
|
||||
explicit VMObject(VMObject&);
|
||||
explicit VMObject(size_t);
|
||||
VMObject(PhysicalAddress, size_t);
|
||||
String m_name;
|
||||
bool m_anonymous { false };
|
||||
Unix::off_t m_vnode_offset { 0 };
|
||||
|
|
|
@ -1811,3 +1811,76 @@ Unix::clock_t Process::sys$times(Unix::tms* times)
|
|||
times->tms_cstime = m_ticks_in_kernel_for_dead_children;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct vbe_info_structure {
|
||||
char signature[4]; // must be "VESA" to indicate valid VBE support
|
||||
word version; // VBE version; high byte is major version, low byte is minor version
|
||||
dword oem; // segment:offset pointer to OEM
|
||||
dword capabilities; // bitfield that describes card capabilities
|
||||
dword video_modes; // segment:offset pointer to list of supported video modes
|
||||
word video_memory; // amount of video memory in 64KB blocks
|
||||
word software_rev; // software revision
|
||||
dword vendor; // segment:offset to card vendor string
|
||||
dword product_name; // segment:offset to card model name
|
||||
dword product_rev; // segment:offset pointer to product revision
|
||||
char reserved[222]; // reserved for future expansion
|
||||
char oem_data[256]; // OEM BIOSes store their strings in this area
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct vbe_mode_info_structure {
|
||||
word attributes; // deprecated, only bit 7 should be of interest to you, and it indicates the mode supports a linear frame buffer.
|
||||
byte window_a; // deprecated
|
||||
byte window_b; // deprecated
|
||||
word granularity; // deprecated; used while calculating bank numbers
|
||||
word window_size;
|
||||
word segment_a;
|
||||
word segment_b;
|
||||
dword win_func_ptr; // deprecated; used to switch banks from protected mode without returning to real mode
|
||||
word pitch; // number of bytes per horizontal line
|
||||
word width; // width in pixels
|
||||
word height; // height in pixels
|
||||
byte w_char; // unused...
|
||||
byte y_char; // ...
|
||||
byte planes;
|
||||
byte bpp; // bits per pixel in this mode
|
||||
byte banks; // deprecated; total number of banks in this mode
|
||||
byte memory_model;
|
||||
byte bank_size; // deprecated; size of a bank, almost always 64 KB but may be 16 KB...
|
||||
byte image_pages;
|
||||
byte reserved0;
|
||||
|
||||
byte red_mask;
|
||||
byte red_position;
|
||||
byte green_mask;
|
||||
byte green_position;
|
||||
byte blue_mask;
|
||||
byte blue_position;
|
||||
byte reserved_mask;
|
||||
byte reserved_position;
|
||||
byte direct_color_attributes;
|
||||
|
||||
dword framebuffer; // physical address of the linear frame buffer; write here to draw to the screen
|
||||
dword off_screen_mem_off;
|
||||
word off_screen_mem_size; // size of memory in the framebuffer but not being displayed on the screen
|
||||
byte reserved1[206];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
DisplayInfo Process::get_display_info()
|
||||
{
|
||||
DisplayInfo info;
|
||||
//auto* vinfo = reinterpret_cast<vbe_info_structure*>(0xc000);
|
||||
auto* vmode = reinterpret_cast<vbe_mode_info_structure*>(0x2000);
|
||||
dbgprintf("VESA framebuffer, %ux%u, %u bpp @ P%x\n", vmode->width, vmode->height, vmode->bpp, vmode->framebuffer);
|
||||
dbgprintf("Returning display info in %s<%u>\n", name().characters(), pid());
|
||||
info.width = vmode->width;
|
||||
info.height = vmode->height;
|
||||
info.bpp = vmode->bpp;
|
||||
info.pitch = vmode->pitch;
|
||||
size_t framebuffer_size = info.pitch * info.height;
|
||||
if (!m_display_framebuffer_region) {
|
||||
auto framebuffer_vmo = VMObject::create_framebuffer_wrapper(PhysicalAddress(vmode->framebuffer), framebuffer_size);
|
||||
m_display_framebuffer_region = allocate_region_with_vmo(LinearAddress(0xe0000000), framebuffer_size, move(framebuffer_vmo), 0, "framebuffer", true, true);
|
||||
}
|
||||
info.framebuffer = m_display_framebuffer_region->linearAddress.asPtr();
|
||||
return info;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,14 @@ struct SignalActionData {
|
|||
LinearAddress restorer;
|
||||
};
|
||||
|
||||
struct DisplayInfo {
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
unsigned bpp;
|
||||
unsigned pitch;
|
||||
byte* framebuffer;
|
||||
};
|
||||
|
||||
class Process : public InlineLinkedListNode<Process> {
|
||||
friend class InlineLinkedListNode<Process>;
|
||||
public:
|
||||
|
@ -175,6 +183,8 @@ public:
|
|||
Unix::clock_t sys$times(Unix::tms*);
|
||||
int sys$utime(const char* pathname, const struct Unix::utimbuf*);
|
||||
|
||||
DisplayInfo get_display_info();
|
||||
|
||||
static void initialize();
|
||||
|
||||
void crash() NORETURN;
|
||||
|
@ -317,6 +327,8 @@ private:
|
|||
Region* m_stack_region { nullptr };
|
||||
Region* m_signal_stack_user_region { nullptr };
|
||||
Region* m_signal_stack_kernel_region { nullptr };
|
||||
|
||||
RetainPtr<Region> m_display_framebuffer_region;
|
||||
};
|
||||
|
||||
extern Process* current;
|
||||
|
|
12
Kernel/WindowComposer.cpp
Normal file
12
Kernel/WindowComposer.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include "WindowComposer.h"
|
||||
#include "Process.h"
|
||||
|
||||
void WindowComposer_main()
|
||||
{
|
||||
auto info = current->get_display_info();
|
||||
|
||||
dbgprintf("Entering WindowComposer main loop.\n");
|
||||
for (;;) {
|
||||
|
||||
}
|
||||
}
|
7
Kernel/WindowComposer.h
Normal file
7
Kernel/WindowComposer.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
class WindowComposer {
|
||||
public:
|
||||
|
||||
};
|
||||
|
|
@ -102,6 +102,9 @@ static void init_stage2()
|
|||
Process::create_kernel_process("spawn_stress", spawn_stress);
|
||||
#endif
|
||||
|
||||
extern void WindowComposer_main();
|
||||
Process::create_kernel_process("WindowComposer", WindowComposer_main);
|
||||
|
||||
current->sys$exit(0);
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue