Browse Source

Kernel: Only use multiboot framebuffer details if present

We should only look at the framebuffer structure members if the
MULTIBOOT_INFO_FRAMEBUFFER_INFO bit is set in the flags field.

Also add some logging if we ignored the fbdev command line argument
due to either not having a framebuffer provided by the bootloader, or
because we don't support the framebuffer format.
Tom 3 năm trước cách đây
mục cha
commit
6a4d06e739

+ 7 - 1
Kernel/Graphics/GraphicsManagement.cpp

@@ -88,7 +88,13 @@ UNMAP_AFTER_INIT bool GraphicsManagement::determine_and_initialize_graphics_devi
     RefPtr<GenericGraphicsAdapter> adapter;
     RefPtr<GenericGraphicsAdapter> adapter;
 
 
     auto create_bootloader_framebuffer_device = [&]() {
     auto create_bootloader_framebuffer_device = [&]() {
-        if (multiboot_framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_RGB) {
+        if (multiboot_framebuffer_addr.is_null()) {
+            // Prekernel sets the framebuffer address to 0 if MULTIBOOT_INFO_FRAMEBUFFER_INFO
+            // is not present, as there is likely never a valid framebuffer at this physical address.
+            dmesgln("Graphics: Bootloader did not set up a framebuffer, ignoring fbdev argument");
+        } else if (multiboot_framebuffer_type != MULTIBOOT_FRAMEBUFFER_TYPE_RGB) {
+            dmesgln("Graphics: The framebuffer set up by the bootloader is not RGB, ignoring fbdev argument");
+        } else {
             dmesgln("Graphics: Using a preset resolution from the bootloader");
             dmesgln("Graphics: Using a preset resolution from the bootloader");
             adapter = VGACompatibleAdapter::initialize_with_preset_resolution(device_identifier,
             adapter = VGACompatibleAdapter::initialize_with_preset_resolution(device_identifier,
                 multiboot_framebuffer_addr,
                 multiboot_framebuffer_addr,

+ 2 - 0
Kernel/Multiboot.h

@@ -46,6 +46,8 @@ struct multiboot_mmap_entry {
 } __attribute__((packed));
 } __attribute__((packed));
 typedef struct multiboot_mmap_entry multiboot_memory_map_t;
 typedef struct multiboot_mmap_entry multiboot_memory_map_t;
 
 
+#define MULTIBOOT_INFO_FRAMEBUFFER_INFO (1 << 12)
+
 struct multiboot_info {
 struct multiboot_info {
     // Multiboot info version number.
     // Multiboot info version number.
     u32 flags;
     u32 flags;

+ 9 - 7
Kernel/Prekernel/init.cpp

@@ -167,7 +167,7 @@ extern "C" [[noreturn]] void init()
         return (decltype(ptr))((FlatPtr)ptr + kernel_mapping_base);
         return (decltype(ptr))((FlatPtr)ptr + kernel_mapping_base);
     };
     };
 
 
-    BootInfo info;
+    BootInfo info {};
     info.start_of_prekernel_image = (PhysicalPtr)start_of_prekernel_image;
     info.start_of_prekernel_image = (PhysicalPtr)start_of_prekernel_image;
     info.end_of_prekernel_image = (PhysicalPtr)end_of_prekernel_image;
     info.end_of_prekernel_image = (PhysicalPtr)end_of_prekernel_image;
     info.physical_to_virtual_offset = kernel_load_base - kernel_physical_base;
     info.physical_to_virtual_offset = kernel_load_base - kernel_physical_base;
@@ -188,12 +188,14 @@ extern "C" [[noreturn]] void init()
     info.multiboot_memory_map_count = multiboot_info_ptr->mmap_length / sizeof(multiboot_memory_map_t);
     info.multiboot_memory_map_count = multiboot_info_ptr->mmap_length / sizeof(multiboot_memory_map_t);
     info.multiboot_modules = adjust_by_mapping_base((FlatPtr)multiboot_info_ptr->mods_addr);
     info.multiboot_modules = adjust_by_mapping_base((FlatPtr)multiboot_info_ptr->mods_addr);
     info.multiboot_modules_count = multiboot_info_ptr->mods_count;
     info.multiboot_modules_count = multiboot_info_ptr->mods_count;
-    info.multiboot_framebuffer_addr = multiboot_info_ptr->framebuffer_addr;
-    info.multiboot_framebuffer_pitch = multiboot_info_ptr->framebuffer_pitch;
-    info.multiboot_framebuffer_width = multiboot_info_ptr->framebuffer_width;
-    info.multiboot_framebuffer_height = multiboot_info_ptr->framebuffer_height;
-    info.multiboot_framebuffer_bpp = multiboot_info_ptr->framebuffer_bpp;
-    info.multiboot_framebuffer_type = multiboot_info_ptr->framebuffer_type;
+    if ((multiboot_info_ptr->flags & MULTIBOOT_INFO_FRAMEBUFFER_INFO) != 0) {
+        info.multiboot_framebuffer_addr = multiboot_info_ptr->framebuffer_addr;
+        info.multiboot_framebuffer_pitch = multiboot_info_ptr->framebuffer_pitch;
+        info.multiboot_framebuffer_width = multiboot_info_ptr->framebuffer_width;
+        info.multiboot_framebuffer_height = multiboot_info_ptr->framebuffer_height;
+        info.multiboot_framebuffer_bpp = multiboot_info_ptr->framebuffer_bpp;
+        info.multiboot_framebuffer_type = multiboot_info_ptr->framebuffer_type;
+    }
 
 
     asm(
     asm(
 #if ARCH(I386)
 #if ARCH(I386)