mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-28 13:43:45 +03:00
Kernel: Add option to force using only the bootloader framebuffer
This allows forcing the use of only the framebuffer set up by the bootloader and skips instantiating devices for any other graphics cards that may be present.
This commit is contained in:
parent
01b3666894
commit
785c10fda9
Notes:
sideshowbarker
2024-07-17 21:31:44 +09:00
Author: https://github.com/tomuta Commit: https://github.com/SerenityOS/serenity/commit/785c10fda9f Pull-request: https://github.com/SerenityOS/serenity/pull/11652 Reviewed-by: https://github.com/Quaker762 ✅ Reviewed-by: https://github.com/linusg
@ -41,7 +41,7 @@ List of options:
|
|||||||
but only if **`acpi`** is set to **`limited`** or **`on`**, and a `MADT` (APIC) table is available.
|
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.
|
Otherwise, the kernel will fallback to use the i8259 PICs.
|
||||||
|
|
||||||
* **`fbdev`** - This parameter expects **`on`** or **`off`**.
|
* **`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.
|
||||||
|
|
||||||
* **`force_pio`** - If present on the command line, the IDE controllers will be force into PIO mode when initialized IDE Channels on boot.
|
* **`force_pio`** - If present on the command line, the IDE controllers will be force into PIO mode when initialized IDE Channels on boot.
|
||||||
|
|
||||||
|
@ -245,9 +245,14 @@ PanicMode CommandLine::panic_mode(Validate should_validate) const
|
|||||||
return PanicMode::Halt;
|
return PanicMode::Halt;
|
||||||
}
|
}
|
||||||
|
|
||||||
UNMAP_AFTER_INIT bool CommandLine::are_framebuffer_devices_enabled() const
|
UNMAP_AFTER_INIT auto CommandLine::are_framebuffer_devices_enabled() const -> FrameBufferDevices
|
||||||
{
|
{
|
||||||
return lookup("fbdev"sv).value_or("on"sv) == "on"sv;
|
const auto 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringView CommandLine::userspace_init() const
|
StringView CommandLine::userspace_init() const
|
||||||
|
@ -52,6 +52,12 @@ public:
|
|||||||
No,
|
No,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class FrameBufferDevices {
|
||||||
|
Enabled,
|
||||||
|
ConsoleOnly,
|
||||||
|
BootloaderOnly
|
||||||
|
};
|
||||||
|
|
||||||
[[nodiscard]] const String& string() const { return m_string; }
|
[[nodiscard]] const String& string() const { return m_string; }
|
||||||
Optional<StringView> lookup(StringView key) const;
|
Optional<StringView> lookup(StringView key) const;
|
||||||
[[nodiscard]] bool contains(StringView key) const;
|
[[nodiscard]] bool contains(StringView key) const;
|
||||||
@ -65,7 +71,7 @@ public:
|
|||||||
[[nodiscard]] bool is_vmmouse_enabled() const;
|
[[nodiscard]] bool is_vmmouse_enabled() const;
|
||||||
[[nodiscard]] PCIAccessLevel pci_access_level() const;
|
[[nodiscard]] PCIAccessLevel pci_access_level() const;
|
||||||
[[nodiscard]] bool is_legacy_time_enabled() const;
|
[[nodiscard]] bool is_legacy_time_enabled() const;
|
||||||
[[nodiscard]] bool are_framebuffer_devices_enabled() const;
|
[[nodiscard]] FrameBufferDevices are_framebuffer_devices_enabled() const;
|
||||||
[[nodiscard]] bool is_force_pio() const;
|
[[nodiscard]] bool is_force_pio() const;
|
||||||
[[nodiscard]] AcpiFeatureLevel acpi_feature_level() const;
|
[[nodiscard]] AcpiFeatureLevel acpi_feature_level() const;
|
||||||
[[nodiscard]] StringView system_mode() const;
|
[[nodiscard]] StringView system_mode() const;
|
||||||
|
@ -36,9 +36,14 @@ UNMAP_AFTER_INIT GraphicsManagement::GraphicsManagement()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GraphicsManagement::framebuffer_devices_allowed() const
|
bool GraphicsManagement::framebuffer_devices_use_bootloader_framebuffer() const
|
||||||
{
|
{
|
||||||
return kernel_command_line().are_framebuffer_devices_enabled();
|
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::deactivate_graphical_mode()
|
void GraphicsManagement::deactivate_graphical_mode()
|
||||||
@ -73,7 +78,7 @@ 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));
|
VERIFY(is_vga_compatible_pci_device(device_identifier) || is_display_controller_pci_device(device_identifier));
|
||||||
auto add_and_configure_adapter = [&](GenericGraphicsAdapter& graphics_device) {
|
auto add_and_configure_adapter = [&](GenericGraphicsAdapter& graphics_device) {
|
||||||
m_graphics_devices.append(graphics_device);
|
m_graphics_devices.append(graphics_device);
|
||||||
if (!framebuffer_devices_allowed()) {
|
if (framebuffer_devices_console_only()) {
|
||||||
graphics_device.enable_consoles();
|
graphics_device.enable_consoles();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -81,52 +86,63 @@ UNMAP_AFTER_INIT bool GraphicsManagement::determine_and_initialize_graphics_devi
|
|||||||
};
|
};
|
||||||
|
|
||||||
RefPtr<GenericGraphicsAdapter> adapter;
|
RefPtr<GenericGraphicsAdapter> adapter;
|
||||||
switch (device_identifier.hardware_id().vendor_id) {
|
|
||||||
case PCI::VendorID::QEMUOld:
|
auto create_bootloader_framebuffer_device = [&]() {
|
||||||
if (device_identifier.hardware_id().device_id == 0x1111)
|
if (multiboot_framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_RGB) {
|
||||||
adapter = BochsGraphicsAdapter::initialize(device_identifier);
|
dmesgln("Graphics: Using a preset resolution from the bootloader");
|
||||||
break;
|
adapter = VGACompatibleAdapter::initialize_with_preset_resolution(device_identifier,
|
||||||
case PCI::VendorID::VirtualBox:
|
multiboot_framebuffer_addr,
|
||||||
if (device_identifier.hardware_id().device_id == 0xbeef)
|
multiboot_framebuffer_width,
|
||||||
adapter = BochsGraphicsAdapter::initialize(device_identifier);
|
multiboot_framebuffer_height,
|
||||||
break;
|
multiboot_framebuffer_pitch);
|
||||||
case PCI::VendorID::Intel:
|
}
|
||||||
adapter = IntelNativeGraphicsAdapter::initialize(device_identifier);
|
};
|
||||||
break;
|
|
||||||
case PCI::VendorID::VirtIO:
|
if (framebuffer_devices_use_bootloader_framebuffer())
|
||||||
dmesgln("Graphics: Using VirtIO console");
|
create_bootloader_framebuffer_device();
|
||||||
adapter = Graphics::VirtIOGPU::GraphicsAdapter::initialize(device_identifier);
|
|
||||||
break;
|
if (!adapter) {
|
||||||
default:
|
switch (device_identifier.hardware_id().vendor_id) {
|
||||||
if (!is_vga_compatible_pci_device(device_identifier))
|
case PCI::VendorID::QEMUOld:
|
||||||
break;
|
if (device_identifier.hardware_id().device_id == 0x1111)
|
||||||
// Note: Although technically possible that a system has a
|
adapter = BochsGraphicsAdapter::initialize(device_identifier);
|
||||||
// non-compatible VGA graphics device that was initialized by the
|
break;
|
||||||
// Multiboot bootloader to provide a framebuffer, in practice we
|
case PCI::VendorID::VirtualBox:
|
||||||
// probably want to support these devices natively instead of
|
if (device_identifier.hardware_id().device_id == 0xbeef)
|
||||||
// initializing them as some sort of a generic GenericGraphicsAdapter. For now,
|
adapter = BochsGraphicsAdapter::initialize(device_identifier);
|
||||||
// the only known example of this sort of device is qxl in QEMU. For VGA
|
break;
|
||||||
// compatible devices we don't have a special driver for (e.g. ati-vga,
|
case PCI::VendorID::Intel:
|
||||||
// qxl-vga, cirrus-vga, vmware-svga in QEMU), it's much more likely that
|
adapter = IntelNativeGraphicsAdapter::initialize(device_identifier);
|
||||||
// these devices will be supported by the Multiboot loader that will
|
break;
|
||||||
// utilize VESA BIOS extensions (that we don't currently) of these cards
|
case PCI::VendorID::VirtIO:
|
||||||
// support, so we want to utilize the provided framebuffer of these
|
dmesgln("Graphics: Using VirtIO console");
|
||||||
// devices, if possible.
|
adapter = Graphics::VirtIOGPU::GraphicsAdapter::initialize(device_identifier);
|
||||||
if (!m_vga_adapter && PCI::is_io_space_enabled(device_identifier.address())) {
|
break;
|
||||||
if (multiboot_framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_RGB) {
|
default:
|
||||||
dmesgln("Graphics: Using a preset resolution from the bootloader");
|
if (!is_vga_compatible_pci_device(device_identifier))
|
||||||
adapter = VGACompatibleAdapter::initialize_with_preset_resolution(device_identifier,
|
break;
|
||||||
multiboot_framebuffer_addr,
|
// Note: Although technically possible that a system has a
|
||||||
multiboot_framebuffer_width,
|
// non-compatible VGA graphics device that was initialized by the
|
||||||
multiboot_framebuffer_height,
|
// Multiboot bootloader to provide a framebuffer, in practice we
|
||||||
multiboot_framebuffer_pitch);
|
// probably want to support these devices natively instead of
|
||||||
}
|
// initializing them as some sort of a generic GenericGraphicsAdapter. For now,
|
||||||
} else {
|
// the only known example of this sort of device is qxl in QEMU. For VGA
|
||||||
dmesgln("Graphics: Using a VGA compatible generic adapter");
|
// compatible devices we don't have a special driver for (e.g. ati-vga,
|
||||||
adapter = VGACompatibleAdapter::initialize(device_identifier);
|
// qxl-vga, cirrus-vga, vmware-svga in QEMU), it's much more likely that
|
||||||
|
// these devices will be supported by the Multiboot loader that will
|
||||||
|
// utilize VESA BIOS extensions (that we don't currently) of these cards
|
||||||
|
// support, so we want to utilize the provided framebuffer of these
|
||||||
|
// devices, if possible.
|
||||||
|
if (!m_vga_adapter && PCI::is_io_space_enabled(device_identifier.address())) {
|
||||||
|
create_bootloader_framebuffer_device();
|
||||||
|
} else {
|
||||||
|
dmesgln("Graphics: Using a VGA compatible generic adapter");
|
||||||
|
adapter = VGACompatibleAdapter::initialize(device_identifier);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!adapter)
|
if (!adapter)
|
||||||
return false;
|
return false;
|
||||||
add_and_configure_adapter(*adapter);
|
add_and_configure_adapter(*adapter);
|
||||||
@ -179,8 +195,10 @@ UNMAP_AFTER_INIT bool GraphicsManagement::initialize()
|
|||||||
* be created, so SystemServer will not try to initialize WindowServer.
|
* be created, so SystemServer will not try to initialize WindowServer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!framebuffer_devices_allowed())
|
if (framebuffer_devices_console_only())
|
||||||
dbgln("Forcing non-initialization of framebuffer devices");
|
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");
|
||||||
|
|
||||||
PCI::enumerate([&](PCI::DeviceIdentifier const& device_identifier) {
|
PCI::enumerate([&](PCI::DeviceIdentifier const& device_identifier) {
|
||||||
// Note: Each graphics controller will try to set its native screen resolution
|
// Note: Each graphics controller will try to set its native screen resolution
|
||||||
|
@ -36,7 +36,8 @@ public:
|
|||||||
unsigned allocate_minor_device_number() { return m_current_minor_number++; };
|
unsigned allocate_minor_device_number() { return m_current_minor_number++; };
|
||||||
GraphicsManagement();
|
GraphicsManagement();
|
||||||
|
|
||||||
bool framebuffer_devices_allowed() const;
|
bool framebuffer_devices_console_only() const;
|
||||||
|
bool framebuffer_devices_use_bootloader_framebuffer() const;
|
||||||
bool framebuffer_devices_exist() const;
|
bool framebuffer_devices_exist() const;
|
||||||
|
|
||||||
Spinlock& main_vga_lock() { return m_main_vga_lock; }
|
Spinlock& main_vga_lock() { return m_main_vga_lock; }
|
||||||
|
Loading…
Reference in New Issue
Block a user