diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-01-09 02:29:11 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-01-09 02:29:11 +0100 |
commit | 659c54e32b859b5a1f748e613543d52e17c4c2c3 (patch) | |
tree | 12d6f61aaaf868f0176e7f42b694b1eef3f9f104 | |
parent | 9963da900583dc54f46c649978aa8a574a0bd508 (diff) | |
download | serenity-659c54e32b859b5a1f748e613543d52e17c4c2c3.zip |
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.
-rwxr-xr-x | Kernel/Boot/boot.asm | 37 | ||||
-rw-r--r-- | Kernel/Makefile | 9 | ||||
-rw-r--r-- | Kernel/MemoryManager.cpp | 18 | ||||
-rw-r--r-- | Kernel/MemoryManager.h | 3 | ||||
-rw-r--r-- | Kernel/Process.cpp | 73 | ||||
-rw-r--r-- | Kernel/Process.h | 12 | ||||
-rw-r--r-- | Kernel/WindowComposer.cpp | 12 | ||||
-rw-r--r-- | Kernel/WindowComposer.h | 7 | ||||
-rw-r--r-- | Kernel/init.cpp | 3 |
9 files changed, 172 insertions, 2 deletions
diff --git a/Kernel/Boot/boot.asm b/Kernel/Boot/boot.asm index fdd0027e94..77caf40398 100755 --- a/Kernel/Boot/boot.asm +++ b/Kernel/Boot/boot.asm @@ -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 diff --git a/Kernel/Makefile b/Kernel/Makefile index 8ed28871b4..590a12d51b 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -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 diff --git a/Kernel/MemoryManager.cpp b/Kernel/MemoryManager.cpp index 63c3a7758b..2d263311a3 100644 --- a/Kernel/MemoryManager.cpp +++ b/Kernel/MemoryManager.cpp @@ -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)) diff --git a/Kernel/MemoryManager.h b/Kernel/MemoryManager.h index c5732a3ea8..cb8863ac81 100644 --- a/Kernel/MemoryManager.h +++ b/Kernel/MemoryManager.h @@ -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 }; diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index c13c824b60..60347dfcd9 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -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; +} diff --git a/Kernel/Process.h b/Kernel/Process.h index 64770bcdb2..f84ca09fb7 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -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; diff --git a/Kernel/WindowComposer.cpp b/Kernel/WindowComposer.cpp new file mode 100644 index 0000000000..b6be2f4575 --- /dev/null +++ b/Kernel/WindowComposer.cpp @@ -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 (;;) { + + } +} diff --git a/Kernel/WindowComposer.h b/Kernel/WindowComposer.h new file mode 100644 index 0000000000..3aecaf817b --- /dev/null +++ b/Kernel/WindowComposer.h @@ -0,0 +1,7 @@ +#pragma once + +class WindowComposer { +public: + +}; + diff --git a/Kernel/init.cpp b/Kernel/init.cpp index f36e3baa94..3b6074d21a 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -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(); } |