diff --git a/Base/usr/share/man/man7/boot_parameters.md b/Base/usr/share/man/man7/boot_parameters.md index 4765146136..4aa0a6d4f3 100644 --- a/Base/usr/share/man/man7/boot_parameters.md +++ b/Base/usr/share/man/man7/boot_parameters.md @@ -47,7 +47,8 @@ List of options: but only if **`acpi`** is set to **`limited`** or **`on`**, and a `MADT` (APIC) table is available. Otherwise, the kernel will fallback to use the i8259 PICs. -* **`fbdev`** - This parameter expects one of the following values. **`on`**- Boot into the graphical environment (default). **`off`** - Boot into text mode. **`bootloader`** - Boot into the graphical environment, but only use the frame buffer set up by the bootloader and do not initialize any other graphics cards. +* **`graphics_subsystem_mode`** - This parameter expects one of the following values. **`on`**- Boot into the graphical environment if possible (default). **`off`** - Boot into text mode, don't initialize any driver. **`limited`** - Boot into the pre-defined framebuffer that the bootloader +has set up before booting the Kernel, don't initialize any driver. * **`force_pio`** - If present on the command line, the IDE controllers will be force into PIO mode when initialized IDE Channels on boot. diff --git a/Kernel/CommandLine.cpp b/Kernel/CommandLine.cpp index 1369b02b8f..b43487fb5a 100644 --- a/Kernel/CommandLine.cpp +++ b/Kernel/CommandLine.cpp @@ -282,14 +282,16 @@ PanicMode CommandLine::panic_mode(Validate should_validate) const return PanicMode::Halt; } -UNMAP_AFTER_INIT auto CommandLine::are_framebuffer_devices_enabled() const -> FrameBufferDevices +UNMAP_AFTER_INIT CommandLine::GraphicsSubsystemMode CommandLine::graphics_subsystem_mode() const { - auto const fbdev_value = lookup("fbdev"sv).value_or("on"sv); - if (fbdev_value == "on"sv) - return FrameBufferDevices::Enabled; - if (fbdev_value == "bootloader"sv) - return FrameBufferDevices::BootloaderOnly; - return FrameBufferDevices::ConsoleOnly; + auto const graphics_subsystem_mode_value = lookup("graphics_subsystem_mode"sv).value_or("on"sv); + if (graphics_subsystem_mode_value == "on"sv) + return GraphicsSubsystemMode::Enabled; + if (graphics_subsystem_mode_value == "limited"sv) + return GraphicsSubsystemMode::Limited; + if (graphics_subsystem_mode_value == "off"sv) + return GraphicsSubsystemMode::Disabled; + PANIC("Invalid graphics_subsystem_mode value: {}", graphics_subsystem_mode_value); } StringView CommandLine::userspace_init() const diff --git a/Kernel/CommandLine.h b/Kernel/CommandLine.h index a52e2daa35..618f031088 100644 --- a/Kernel/CommandLine.h +++ b/Kernel/CommandLine.h @@ -53,10 +53,10 @@ public: No, }; - enum class FrameBufferDevices { + enum class GraphicsSubsystemMode { Enabled, - ConsoleOnly, - BootloaderOnly + Limited, + Disabled }; [[nodiscard]] StringView string() const { return m_string->view(); } @@ -74,7 +74,7 @@ public: [[nodiscard]] bool is_pci_disabled() const; [[nodiscard]] bool is_legacy_time_enabled() const; [[nodiscard]] bool is_pc_speaker_enabled() const; - [[nodiscard]] FrameBufferDevices are_framebuffer_devices_enabled() const; + [[nodiscard]] GraphicsSubsystemMode graphics_subsystem_mode() const; [[nodiscard]] bool is_force_pio() const; [[nodiscard]] AcpiFeatureLevel acpi_feature_level() const; [[nodiscard]] StringView system_mode() const; diff --git a/Kernel/Graphics/GraphicsManagement.cpp b/Kernel/Graphics/GraphicsManagement.cpp index 1d2cf0516c..e74ea4a815 100644 --- a/Kernel/Graphics/GraphicsManagement.cpp +++ b/Kernel/Graphics/GraphicsManagement.cpp @@ -41,16 +41,6 @@ UNMAP_AFTER_INIT GraphicsManagement::GraphicsManagement() { } -bool GraphicsManagement::framebuffer_devices_use_bootloader_framebuffer() const -{ - return kernel_command_line().are_framebuffer_devices_enabled() == CommandLine::FrameBufferDevices::BootloaderOnly; -} - -bool GraphicsManagement::framebuffer_devices_console_only() const -{ - return kernel_command_line().are_framebuffer_devices_enabled() == CommandLine::FrameBufferDevices::ConsoleOnly; -} - void GraphicsManagement::disable_vga_emulation_access_permanently() { SpinlockLocker locker(m_main_vga_lock); @@ -154,22 +144,18 @@ UNMAP_AFTER_INIT bool GraphicsManagement::determine_and_initialize_graphics_devi VERIFY(is_vga_compatible_pci_device(device_identifier) || is_display_controller_pci_device(device_identifier)); auto add_and_configure_adapter = [&](GenericGraphicsAdapter& graphics_device) { m_graphics_devices.append(graphics_device); - if (framebuffer_devices_console_only()) { - graphics_device.enable_consoles(); - return; - } + graphics_device.enable_consoles(); graphics_device.initialize_framebuffer_devices(); }; - RefPtr adapter; auto create_bootloader_framebuffer_device = [&]() { 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"); + dmesgln("Graphics: Bootloader did not set up a framebuffer"); } else if (multiboot_framebuffer_type != MULTIBOOT_FRAMEBUFFER_TYPE_RGB) { - dmesgln("Graphics: The framebuffer set up by the bootloader is not RGB, ignoring fbdev argument"); + dmesgln("Graphics: The framebuffer set up by the bootloader is not RGB"); } else { dmesgln("Graphics: Using a preset resolution from the bootloader"); adapter = PCIVGACompatibleAdapter::initialize_with_preset_resolution(device_identifier, @@ -180,9 +166,6 @@ UNMAP_AFTER_INIT bool GraphicsManagement::determine_and_initialize_graphics_devi } }; - if (framebuffer_devices_use_bootloader_framebuffer()) - create_bootloader_framebuffer_device(); - if (!adapter) { switch (device_identifier.hardware_id().vendor_id) { case PCI::VendorID::QEMUOld: @@ -282,16 +265,25 @@ UNMAP_AFTER_INIT bool GraphicsManagement::initialize() * be created, so SystemServer will not try to initialize WindowServer. */ + auto graphics_subsystem_mode = kernel_command_line().graphics_subsystem_mode(); + if (graphics_subsystem_mode == CommandLine::GraphicsSubsystemMode::Disabled) + return true; + + if (graphics_subsystem_mode == CommandLine::GraphicsSubsystemMode::Limited && !multiboot_framebuffer_addr.is_null() && multiboot_framebuffer_type != MULTIBOOT_FRAMEBUFFER_TYPE_RGB) { + dmesgln("Graphics: Using a preset resolution from the bootloader, without knowing the PCI device"); + m_preset_resolution_generic_display_connector = GenericDisplayConnector::must_create_with_preset_resolution( + multiboot_framebuffer_addr, + multiboot_framebuffer_width, + multiboot_framebuffer_height, + multiboot_framebuffer_pitch); + return true; + } + if (PCI::Access::is_disabled()) { determine_and_initialize_isa_graphics_device(); return true; } - if (framebuffer_devices_console_only()) - dbgln("Forcing non-initialization of framebuffer devices (console only)"); - else if (framebuffer_devices_use_bootloader_framebuffer()) - dbgln("Forcing use of framebuffer set up by the bootloader"); - MUST(PCI::enumerate([&](PCI::DeviceIdentifier const& device_identifier) { // Note: Each graphics controller will try to set its native screen resolution // upon creation. Later on, if we don't want to have framebuffer devices, a @@ -317,15 +309,6 @@ UNMAP_AFTER_INIT bool GraphicsManagement::initialize() return true; } -bool GraphicsManagement::framebuffer_devices_exist() const -{ - for (auto& graphics_device : m_graphics_devices) { - if (graphics_device.framebuffer_devices_initialized()) - return true; - } - return false; -} - void GraphicsManagement::set_console(Graphics::Console& console) { m_console = console; diff --git a/Kernel/Graphics/GraphicsManagement.h b/Kernel/Graphics/GraphicsManagement.h index 0bbbb6fc25..6d05e36ef3 100644 --- a/Kernel/Graphics/GraphicsManagement.h +++ b/Kernel/Graphics/GraphicsManagement.h @@ -33,10 +33,6 @@ public: void attach_new_display_connector(Badge, DisplayConnector&); void detach_display_connector(Badge, DisplayConnector&); - bool framebuffer_devices_console_only() const; - bool framebuffer_devices_use_bootloader_framebuffer() const; - bool framebuffer_devices_exist() const; - void set_vga_text_mode_cursor(size_t console_width, size_t x, size_t y); void disable_vga_text_mode_console_cursor(); void disable_vga_emulation_access_permanently(); @@ -55,6 +51,9 @@ private: NonnullRefPtrVector m_graphics_devices; RefPtr m_console; + // Note: This is only used when booting with kernel commandline that includes "graphics_subsystem_mode=limited" + RefPtr m_preset_resolution_generic_display_connector; + // Note: there could be multiple VGA adapters, but only one can operate in VGA mode RefPtr m_vga_adapter; unsigned m_current_minor_number { 0 };