summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiav A <liavalb@gmail.com>2022-04-30 15:53:02 +0300
committerAndreas Kling <kling@serenityos.org>2022-05-05 20:55:57 +0200
commitd49a35df3121e6fc88fade2b20c386d58510a249 (patch)
treec64941744bcf33b3c5f18c120303e199d20653df
parente301af8352c50dc76234aa767d5a18f6ff52d86e (diff)
downloadserenity-d49a35df3121e6fc88fade2b20c386d58510a249.zip
Kernel/Graphics: Simplify the feature level of the Graphics subsystem
Instead of letting the user to determine whether framebuffer devices will be created (which is useless because they are gone by now), let's simplify the flow by allowing the user to choose between full, limited or disabled functionality. The determination happens only once, so, if the user decided to disable graphics support, the initialize method exits immediately. If limited functionality is chosen, then a generic DisplayConnector is initialized with the preset framebuffer resolution, if present, and then the initialize method exits. As a default, the code proceeds to initialize all drivers as usual.
-rw-r--r--Base/usr/share/man/man7/boot_parameters.md3
-rw-r--r--Kernel/CommandLine.cpp18
-rw-r--r--Kernel/CommandLine.h8
-rw-r--r--Kernel/Graphics/GraphicsManagement.cpp51
-rw-r--r--Kernel/Graphics/GraphicsManagement.h7
5 files changed, 36 insertions, 51 deletions
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
-{
- 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;
+UNMAP_AFTER_INIT CommandLine::GraphicsSubsystemMode CommandLine::graphics_subsystem_mode() const
+{
+ 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<GenericGraphicsAdapter> 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>, DisplayConnector&);
void detach_display_connector(Badge<DisplayConnector>, 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<GenericGraphicsAdapter> m_graphics_devices;
RefPtr<Graphics::Console> m_console;
+ // Note: This is only used when booting with kernel commandline that includes "graphics_subsystem_mode=limited"
+ RefPtr<GenericDisplayConnector> m_preset_resolution_generic_display_connector;
+
// Note: there could be multiple VGA adapters, but only one can operate in VGA mode
RefPtr<VGACompatibleAdapter> m_vga_adapter;
unsigned m_current_minor_number { 0 };