mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 17:52:45 +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 changed files with 172 additions and 2 deletions
				
			
		|  | @ -9,6 +9,43 @@ boot: | ||||||
|     mov     ss, ax |     mov     ss, ax | ||||||
|     mov     sp, 0xffff |     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 |     push    cs | ||||||
|     pop     ds |     pop     ds | ||||||
|     xor     bx, bx |     xor     bx, bx | ||||||
|  |  | ||||||
|  | @ -24,7 +24,8 @@ KERNEL_OBJS = \ | ||||||
|        DoubleBuffer.o \
 |        DoubleBuffer.o \
 | ||||||
|        ELFImage.o \
 |        ELFImage.o \
 | ||||||
|        ELFLoader.o \
 |        ELFLoader.o \
 | ||||||
|        KSyms.o |        KSyms.o \
 | ||||||
|  |        WindowComposer.o | ||||||
| 
 | 
 | ||||||
| VFS_OBJS = \
 | VFS_OBJS = \
 | ||||||
|     ../VirtualFileSystem/DiskDevice.o \
 |     ../VirtualFileSystem/DiskDevice.o \
 | ||||||
|  | @ -40,13 +41,17 @@ VFS_OBJS = \ | ||||||
|     ../VirtualFileSystem/FileDescriptor.o \
 |     ../VirtualFileSystem/FileDescriptor.o \
 | ||||||
|     ../VirtualFileSystem/SyntheticFileSystem.o |     ../VirtualFileSystem/SyntheticFileSystem.o | ||||||
| 
 | 
 | ||||||
|  | WIDGETS_OBJS = \
 | ||||||
|  |     ../Widgets/Window.o \
 | ||||||
|  |     ../Widgets/Painter.o | ||||||
|  | 
 | ||||||
| AK_OBJS = \
 | AK_OBJS = \
 | ||||||
|     ../AK/String.o \
 |     ../AK/String.o \
 | ||||||
|     ../AK/StringImpl.o \
 |     ../AK/StringImpl.o \
 | ||||||
|     ../AK/StringBuilder.o \
 |     ../AK/StringBuilder.o \
 | ||||||
|     ../AK/FileSystemPath.o |     ../AK/FileSystemPath.o | ||||||
| 
 | 
 | ||||||
| OBJS = $(KERNEL_OBJS) $(VFS_OBJS) $(AK_OBJS) $(ELFLOADER_OBJS) | OBJS = $(KERNEL_OBJS) $(VFS_OBJS) $(AK_OBJS) $(WIDGETS_OBJS) | ||||||
| 
 | 
 | ||||||
| NASM = nasm | NASM = nasm | ||||||
| KERNEL = kernel | KERNEL = kernel | ||||||
|  |  | ||||||
|  | @ -652,6 +652,12 @@ RetainPtr<VMObject> VMObject::create_anonymous(size_t size) | ||||||
|     return adopt(*new VMObject(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() | RetainPtr<VMObject> VMObject::clone() | ||||||
| { | { | ||||||
|     return adopt(*new VMObject(*this)); |     return adopt(*new VMObject(*this)); | ||||||
|  | @ -676,6 +682,18 @@ VMObject::VMObject(size_t size) | ||||||
|     m_physical_pages.resize(page_count()); |     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) | VMObject::VMObject(RetainPtr<Vnode>&& vnode, size_t size) | ||||||
|     : m_size(size) |     : m_size(size) | ||||||
|     , m_vnode(move(vnode)) |     , m_vnode(move(vnode)) | ||||||
|  |  | ||||||
|  | @ -23,6 +23,7 @@ class PhysicalPage { | ||||||
|     AK_MAKE_ETERNAL |     AK_MAKE_ETERNAL | ||||||
|     friend class MemoryManager; |     friend class MemoryManager; | ||||||
|     friend class PageDirectory; |     friend class PageDirectory; | ||||||
|  |     friend class VMObject; | ||||||
| public: | public: | ||||||
|     PhysicalAddress paddr() const { return m_paddr; } |     PhysicalAddress paddr() const { return m_paddr; } | ||||||
| 
 | 
 | ||||||
|  | @ -73,6 +74,7 @@ class VMObject : public Retainable<VMObject> { | ||||||
| public: | public: | ||||||
|     static RetainPtr<VMObject> create_file_backed(RetainPtr<Vnode>&&, size_t); |     static RetainPtr<VMObject> create_file_backed(RetainPtr<Vnode>&&, size_t); | ||||||
|     static RetainPtr<VMObject> create_anonymous(size_t); |     static RetainPtr<VMObject> create_anonymous(size_t); | ||||||
|  |     static RetainPtr<VMObject> create_framebuffer_wrapper(PhysicalAddress, size_t); | ||||||
|     RetainPtr<VMObject> clone(); |     RetainPtr<VMObject> clone(); | ||||||
| 
 | 
 | ||||||
|     ~VMObject(); |     ~VMObject(); | ||||||
|  | @ -93,6 +95,7 @@ private: | ||||||
|     VMObject(RetainPtr<Vnode>&&, size_t); |     VMObject(RetainPtr<Vnode>&&, size_t); | ||||||
|     explicit VMObject(VMObject&); |     explicit VMObject(VMObject&); | ||||||
|     explicit VMObject(size_t); |     explicit VMObject(size_t); | ||||||
|  |     VMObject(PhysicalAddress, size_t); | ||||||
|     String m_name; |     String m_name; | ||||||
|     bool m_anonymous { false }; |     bool m_anonymous { false }; | ||||||
|     Unix::off_t m_vnode_offset { 0 }; |     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; |     times->tms_cstime = m_ticks_in_kernel_for_dead_children; | ||||||
|     return 0; |     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; |     LinearAddress restorer; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | struct DisplayInfo { | ||||||
|  |     unsigned width; | ||||||
|  |     unsigned height; | ||||||
|  |     unsigned bpp; | ||||||
|  |     unsigned pitch; | ||||||
|  |     byte* framebuffer; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| class Process : public InlineLinkedListNode<Process> { | class Process : public InlineLinkedListNode<Process> { | ||||||
|     friend class InlineLinkedListNode<Process>; |     friend class InlineLinkedListNode<Process>; | ||||||
| public: | public: | ||||||
|  | @ -175,6 +183,8 @@ public: | ||||||
|     Unix::clock_t sys$times(Unix::tms*); |     Unix::clock_t sys$times(Unix::tms*); | ||||||
|     int sys$utime(const char* pathname, const struct Unix::utimbuf*); |     int sys$utime(const char* pathname, const struct Unix::utimbuf*); | ||||||
| 
 | 
 | ||||||
|  |     DisplayInfo get_display_info(); | ||||||
|  | 
 | ||||||
|     static void initialize(); |     static void initialize(); | ||||||
| 
 | 
 | ||||||
|     void crash() NORETURN; |     void crash() NORETURN; | ||||||
|  | @ -317,6 +327,8 @@ private: | ||||||
|     Region* m_stack_region { nullptr }; |     Region* m_stack_region { nullptr }; | ||||||
|     Region* m_signal_stack_user_region { nullptr }; |     Region* m_signal_stack_user_region { nullptr }; | ||||||
|     Region* m_signal_stack_kernel_region { nullptr }; |     Region* m_signal_stack_kernel_region { nullptr }; | ||||||
|  | 
 | ||||||
|  |     RetainPtr<Region> m_display_framebuffer_region; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| extern Process* current; | 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); |     Process::create_kernel_process("spawn_stress", spawn_stress); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  |     extern void WindowComposer_main(); | ||||||
|  |     Process::create_kernel_process("WindowComposer", WindowComposer_main); | ||||||
|  | 
 | ||||||
|     current->sys$exit(0); |     current->sys$exit(0); | ||||||
|     ASSERT_NOT_REACHED(); |     ASSERT_NOT_REACHED(); | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling