From a2fc6cec915116859eaa296e8649040e688398ea Mon Sep 17 00:00:00 2001 From: Kenny Strawn Date: Mon, 27 Mar 2023 10:54:07 -0700 Subject: [PATCH 01/18] Refactor UEFI implementation for compliance with rust-lang/rust#107457 lint --- Cargo.lock | 49 +++++++++++++++++++++++++++++------------ Cargo.toml | 2 +- tests/runner/src/lib.rs | 4 ++++ uefi/Cargo.toml | 2 +- uefi/src/main.rs | 7 +++--- 5 files changed, 44 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e4ebb85f..c12f94cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -148,7 +148,7 @@ dependencies = [ [[package]] name = "bootloader" -version = "0.11.3" +version = "0.11.4" dependencies = [ "anyhow", "async-process", @@ -173,22 +173,22 @@ dependencies = [ [[package]] name = "bootloader-boot-config" -version = "0.11.3" +version = "0.11.4" dependencies = [ "serde", ] [[package]] name = "bootloader-x86_64-bios-boot-sector" -version = "0.11.3" +version = "0.11.4" [[package]] name = "bootloader-x86_64-bios-common" -version = "0.11.3" +version = "0.11.4" [[package]] name = "bootloader-x86_64-bios-stage-2" -version = "0.11.3" +version = "0.11.4" dependencies = [ "bootloader-x86_64-bios-common", "byteorder", @@ -197,7 +197,7 @@ dependencies = [ [[package]] name = "bootloader-x86_64-bios-stage-3" -version = "0.11.3" +version = "0.11.4" dependencies = [ "bootloader-x86_64-bios-common", "noto-sans-mono-bitmap 0.1.6", @@ -205,7 +205,7 @@ dependencies = [ [[package]] name = "bootloader-x86_64-bios-stage-4" -version = "0.11.3" +version = "0.11.4" dependencies = [ "bootloader-boot-config", "bootloader-x86_64-bios-common", @@ -220,7 +220,7 @@ dependencies = [ [[package]] name = "bootloader-x86_64-common" -version = "0.11.3" +version = "0.11.4" dependencies = [ "bootloader-boot-config", "bootloader_api", @@ -239,7 +239,7 @@ dependencies = [ [[package]] name = "bootloader-x86_64-uefi" -version = "0.11.3" +version = "0.11.4" dependencies = [ "bootloader-boot-config", "bootloader-x86_64-common", @@ -252,7 +252,7 @@ dependencies = [ [[package]] name = "bootloader_api" -version = "0.11.3" +version = "0.11.4" dependencies = [ "rand", ] @@ -728,6 +728,26 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "ptr_meta" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcada80daa06c42ed5f48c9a043865edea5dc44cbf9ac009fda3b89526e28607" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bca9224df2e20e7c5548aeb5f110a0f3b77ef05f8585139b7148b59056168ed2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "quote" version = "1.0.23" @@ -1122,21 +1142,22 @@ dependencies = [ [[package]] name = "uefi" -version = "0.18.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07b87700863d65dd4841556be3374d8d4f9f8dbb577ad93a39859e70b3b91f35" +checksum = "ab39d5e7740f21ed4c46d6659f31038bbe3fe7a8be1f702d8a984348837c43b1" dependencies = [ "bitflags", "log", + "ptr_meta", "ucs2", "uefi-macros", ] [[package]] name = "uefi-macros" -version = "0.9.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "275f054a1d9fd7e43a2ce91cc24298a87b281117dea8afc120ae95faa0e96b94" +checksum = "e0caeb0e7b31b9f1f347e541106be10aa8c66c76fa722a3298a4cd21433fabd4" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 9c3ce126..1d83a0f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ exclude = ["examples/basic", "examples/test_framework"] [workspace.package] # don't forget to update `workspace.dependencies` below -version = "0.11.3" +version = "0.11.4" license = "MIT/Apache-2.0" repository = "https://github.com/rust-osdev/bootloader" diff --git a/tests/runner/src/lib.rs b/tests/runner/src/lib.rs index 7d293c1e..ea158139 100644 --- a/tests/runner/src/lib.rs +++ b/tests/runner/src/lib.rs @@ -2,6 +2,7 @@ use bootloader::BootConfig; use bootloader::DiskImageBuilder; use std::{io::Read, path::Path, process::Command}; +#[allow(dead_code)] const QEMU_ARGS: &[&str] = &[ "-device", "isa-debug-exit,iobase=0xf4,iosize=0x04", @@ -11,6 +12,8 @@ const QEMU_ARGS: &[&str] = &[ "none", "--no-reboot", ]; + +#[allow(dead_code)] const SEPARATOR: &str = "\n____________________________________\n"; pub fn run_test_kernel(kernel_binary_path: &str) { @@ -98,6 +101,7 @@ pub fn run_test_kernel_on_uefi_pxe(out_tftp_path: &Path) { run_qemu(args); } +#[allow(dead_code)] fn run_qemu<'a, A>(args: A) where A: IntoIterator, diff --git a/uefi/Cargo.toml b/uefi/Cargo.toml index b9f5ec29..80168be5 100644 --- a/uefi/Cargo.toml +++ b/uefi/Cargo.toml @@ -13,6 +13,6 @@ bootloader_api = { workspace = true } bootloader-x86_64-common = { workspace = true } bootloader-boot-config = { workspace = true } log = "0.4.14" -uefi = "0.18.0" x86_64 = "0.14.8" serde-json-core = "0.5.0" +uefi = "0.20.0" diff --git a/uefi/src/main.rs b/uefi/src/main.rs index d0cee33b..a1470716 100644 --- a/uefi/src/main.rs +++ b/uefi/src/main.rs @@ -136,7 +136,7 @@ fn main_inner(image: Handle, mut st: SystemTable) -> Status { } ); - let mmap_storage = { + let _mmap_storage = { let mut memory_map_size = st.boot_services().memory_map_size(); loop { let ptr = st @@ -162,11 +162,10 @@ fn main_inner(image: Handle, mut st: SystemTable) -> Status { log::trace!("exiting boot services"); let (system_table, memory_map) = st - .exit_boot_services(image, mmap_storage) - .expect("Failed to exit boot services"); + .exit_boot_services(); let mut frame_allocator = - LegacyFrameAllocator::new(memory_map.copied().map(UefiMemoryDescriptor)); + LegacyFrameAllocator::new(memory_map.entries().copied().map(UefiMemoryDescriptor)); let page_tables = create_page_tables(&mut frame_allocator); let mut ramdisk_len = 0u64; From fd818fc8609b5dd158a2488cefe63cb696c798c6 Mon Sep 17 00:00:00 2001 From: Kenny Strawn Date: Mon, 27 Mar 2023 10:58:46 -0700 Subject: [PATCH 02/18] rustfmt --- uefi/src/main.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/uefi/src/main.rs b/uefi/src/main.rs index a1470716..7d5986ab 100644 --- a/uefi/src/main.rs +++ b/uefi/src/main.rs @@ -161,8 +161,7 @@ fn main_inner(image: Handle, mut st: SystemTable) -> Status { }; log::trace!("exiting boot services"); - let (system_table, memory_map) = st - .exit_boot_services(); + let (system_table, memory_map) = st.exit_boot_services(); let mut frame_allocator = LegacyFrameAllocator::new(memory_map.entries().copied().map(UefiMemoryDescriptor)); From 57bd85d54a40ab3b57d07ed6d494d88e0800f1f6 Mon Sep 17 00:00:00 2001 From: Kenny Strawn Date: Wed, 12 Apr 2023 16:17:38 -0700 Subject: [PATCH 03/18] rust-osdev/bootloader#360: Resolve @phil-opp's concerns (1/5) --- uefi/src/main.rs | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/uefi/src/main.rs b/uefi/src/main.rs index 7d5986ab..7b0aa5af 100644 --- a/uefi/src/main.rs +++ b/uefi/src/main.rs @@ -136,30 +136,6 @@ fn main_inner(image: Handle, mut st: SystemTable) -> Status { } ); - let _mmap_storage = { - let mut memory_map_size = st.boot_services().memory_map_size(); - loop { - let ptr = st - .boot_services() - .allocate_pool(MemoryType::LOADER_DATA, memory_map_size.map_size) - .expect("Failed to allocate memory for mmap storage"); - - let storage = unsafe { slice::from_raw_parts_mut(ptr, memory_map_size.map_size) }; - - if st.boot_services().memory_map(storage).is_ok() { - break storage; - } - - // By measuring the size here, we can find out exactly how much we need. - // We may hit this code twice, if the map allocation ends up spanning more pages. - memory_map_size = st.boot_services().memory_map_size(); - // allocated memory region was not big enough -> free it again - st.boot_services() - .free_pool(ptr) - .expect("Failed to free temporary memory for memory map!"); - } - }; - log::trace!("exiting boot services"); let (system_table, memory_map) = st.exit_boot_services(); From ec7cbaabaa420a18969d2b0c1a2add363557b023 Mon Sep 17 00:00:00 2001 From: Kenny Strawn Date: Wed, 12 Apr 2023 16:18:25 -0700 Subject: [PATCH 04/18] rust-osdev/bootloader#360: Resolve @phil-opp's concerns (2/5) --- Cargo.lock | 20 ++++++++++---------- Cargo.toml | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c12f94cd..381364d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -148,7 +148,7 @@ dependencies = [ [[package]] name = "bootloader" -version = "0.11.4" +version = "0.11.3" dependencies = [ "anyhow", "async-process", @@ -173,22 +173,22 @@ dependencies = [ [[package]] name = "bootloader-boot-config" -version = "0.11.4" +version = "0.11.3" dependencies = [ "serde", ] [[package]] name = "bootloader-x86_64-bios-boot-sector" -version = "0.11.4" +version = "0.11.3" [[package]] name = "bootloader-x86_64-bios-common" -version = "0.11.4" +version = "0.11.3" [[package]] name = "bootloader-x86_64-bios-stage-2" -version = "0.11.4" +version = "0.11.3" dependencies = [ "bootloader-x86_64-bios-common", "byteorder", @@ -197,7 +197,7 @@ dependencies = [ [[package]] name = "bootloader-x86_64-bios-stage-3" -version = "0.11.4" +version = "0.11.3" dependencies = [ "bootloader-x86_64-bios-common", "noto-sans-mono-bitmap 0.1.6", @@ -205,7 +205,7 @@ dependencies = [ [[package]] name = "bootloader-x86_64-bios-stage-4" -version = "0.11.4" +version = "0.11.3" dependencies = [ "bootloader-boot-config", "bootloader-x86_64-bios-common", @@ -220,7 +220,7 @@ dependencies = [ [[package]] name = "bootloader-x86_64-common" -version = "0.11.4" +version = "0.11.3" dependencies = [ "bootloader-boot-config", "bootloader_api", @@ -239,7 +239,7 @@ dependencies = [ [[package]] name = "bootloader-x86_64-uefi" -version = "0.11.4" +version = "0.11.3" dependencies = [ "bootloader-boot-config", "bootloader-x86_64-common", @@ -252,7 +252,7 @@ dependencies = [ [[package]] name = "bootloader_api" -version = "0.11.4" +version = "0.11.3" dependencies = [ "rand", ] diff --git a/Cargo.toml b/Cargo.toml index 1d83a0f0..9c3ce126 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ exclude = ["examples/basic", "examples/test_framework"] [workspace.package] # don't forget to update `workspace.dependencies` below -version = "0.11.4" +version = "0.11.3" license = "MIT/Apache-2.0" repository = "https://github.com/rust-osdev/bootloader" From d18076e6c30eb583d5ee9c96a3849c26c7550057 Mon Sep 17 00:00:00 2001 From: Kenny Strawn Date: Wed, 12 Apr 2023 16:21:33 -0700 Subject: [PATCH 05/18] rust-osdev/bootloader#360: Resolve @phil-opp's concerns (3/5 + 4/5) --- tests/runner/src/lib.rs | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/tests/runner/src/lib.rs b/tests/runner/src/lib.rs index ea158139..4de40e45 100644 --- a/tests/runner/src/lib.rs +++ b/tests/runner/src/lib.rs @@ -2,20 +2,6 @@ use bootloader::BootConfig; use bootloader::DiskImageBuilder; use std::{io::Read, path::Path, process::Command}; -#[allow(dead_code)] -const QEMU_ARGS: &[&str] = &[ - "-device", - "isa-debug-exit,iobase=0xf4,iosize=0x04", - "-serial", - "stdio", - "-display", - "none", - "--no-reboot", -]; - -#[allow(dead_code)] -const SEPARATOR: &str = "\n____________________________________\n"; - pub fn run_test_kernel(kernel_binary_path: &str) { run_test_kernel_internal(kernel_binary_path, None, None) } @@ -106,6 +92,18 @@ fn run_qemu<'a, A>(args: A) where A: IntoIterator, { + const QEMU_ARGS: &[&str] = &[ + "-device", + "isa-debug-exit,iobase=0xf4,iosize=0x04", + "-serial", + "stdio", + "-display", + "none", + "--no-reboot", + ]; + + const SEPARATOR: &str = "\n____________________________________\n"; + use std::process::Stdio; let mut run_cmd = Command::new("qemu-system-x86_64"); From 5d153e3a05c88e328dbad4c99190d8b5cb9916e1 Mon Sep 17 00:00:00 2001 From: Kenny Strawn Date: Wed, 12 Apr 2023 16:25:33 -0700 Subject: [PATCH 06/18] Update tests/runner/src/lib.rs Co-authored-by: Philipp Oppermann --- tests/runner/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/runner/src/lib.rs b/tests/runner/src/lib.rs index 4de40e45..c8d7e355 100644 --- a/tests/runner/src/lib.rs +++ b/tests/runner/src/lib.rs @@ -87,7 +87,7 @@ pub fn run_test_kernel_on_uefi_pxe(out_tftp_path: &Path) { run_qemu(args); } -#[allow(dead_code)] +#[cfg(any(feature = "uefi", feature = "bios"))] fn run_qemu<'a, A>(args: A) where A: IntoIterator, From 02ecbb2d3821870169e9734b6e741e1a0e88891b Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 13 Apr 2023 08:35:11 +0200 Subject: [PATCH 07/18] Fix unused import warning --- tests/runner/src/lib.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/runner/src/lib.rs b/tests/runner/src/lib.rs index c8d7e355..3edb4d94 100644 --- a/tests/runner/src/lib.rs +++ b/tests/runner/src/lib.rs @@ -1,6 +1,6 @@ use bootloader::BootConfig; use bootloader::DiskImageBuilder; -use std::{io::Read, path::Path, process::Command}; +use std::path::Path; pub fn run_test_kernel(kernel_binary_path: &str) { run_test_kernel_internal(kernel_binary_path, None, None) @@ -92,6 +92,11 @@ fn run_qemu<'a, A>(args: A) where A: IntoIterator, { + use std::{ + io::Read, + process::{Command, Stdio}, + }; + const QEMU_ARGS: &[&str] = &[ "-device", "isa-debug-exit,iobase=0xf4,iosize=0x04", @@ -104,8 +109,6 @@ where const SEPARATOR: &str = "\n____________________________________\n"; - use std::process::Stdio; - let mut run_cmd = Command::new("qemu-system-x86_64"); run_cmd.args(args); run_cmd.args(QEMU_ARGS); From 84d3f621a3e2d83993b7f5f119c2dc11d01d3102 Mon Sep 17 00:00:00 2001 From: Kenny Strawn Date: Sat, 15 Apr 2023 11:53:56 -0700 Subject: [PATCH 08/18] Use highest resolution available on real hardware --- Cargo.lock | 1 + uefi/Cargo.toml | 1 + uefi/src/main.rs | 50 +++++++++++++++++++++++++++++------------------- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 301a224f..d254e334 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -245,6 +245,7 @@ dependencies = [ "bootloader-x86_64-common", "bootloader_api", "log", + "raw-cpuid", "serde-json-core", "uefi", "x86_64", diff --git a/uefi/Cargo.toml b/uefi/Cargo.toml index 80168be5..fc0b1837 100644 --- a/uefi/Cargo.toml +++ b/uefi/Cargo.toml @@ -16,3 +16,4 @@ log = "0.4.14" x86_64 = "0.14.8" serde-json-core = "0.5.0" uefi = "0.20.0" +raw-cpuid = "10.7.0" diff --git a/uefi/src/main.rs b/uefi/src/main.rs index 7b0aa5af..c081729d 100644 --- a/uefi/src/main.rs +++ b/uefi/src/main.rs @@ -8,6 +8,7 @@ use bootloader_boot_config::BootConfig; use bootloader_x86_64_common::{ legacy_memory_region::LegacyFrameAllocator, Kernel, RawFrameBufferInfo, SystemInfo, }; +use raw_cpuid::CpuId; use core::{ cell::UnsafeCell, ops::{Deref, DerefMut}, @@ -469,26 +470,35 @@ fn init_logger( }; let mode = { - let modes = gop.modes(); - match ( - config - .frame_buffer - .minimum_framebuffer_height - .map(|v| usize::try_from(v).unwrap()), - config - .frame_buffer - .minimum_framebuffer_width - .map(|v| usize::try_from(v).unwrap()), - ) { - (Some(height), Some(width)) => modes - .filter(|m| { - let res = m.info().resolution(); - res.1 >= height && res.0 >= width - }) - .last(), - (Some(height), None) => modes.filter(|m| m.info().resolution().1 >= height).last(), - (None, Some(width)) => modes.filter(|m| m.info().resolution().0 >= width).last(), - _ => None, + let mut modes = gop.modes(); + + if let Some(_) = CpuId::new().get_hypervisor_info() { + match ( + config + .frame_buffer + .minimum_framebuffer_height + .map(|v| usize::try_from(v).unwrap()), + config + .frame_buffer + .minimum_framebuffer_width + .map(|v| usize::try_from(v).unwrap()), + ) { + (Some(height), Some(width)) => modes + .filter(|m| { + let res = m.info().resolution(); + res.1 >= height && res.0 >= width + }) + .last(), + (Some(height), None) => modes.filter(|m| m.info().resolution().1 >= height).last(), + (None, Some(width)) => modes.filter(|m| m.info().resolution().0 >= width).last(), + _ => None, + } + } else { + // Default to using the highest resolution available on real hardware + let x = gop.modes().map(|m| m.info().resolution().0).max().unwrap(); + let y = gop.modes().map(|m| m.info().resolution().1).max().unwrap(); + + modes.find(|m| m.info().resolution().0 == x && m.info().resolution().1 == y) } }; if let Some(mode) = mode { From d8d4b9c980d1e83c9f207443b2a98137851e3543 Mon Sep 17 00:00:00 2001 From: Kenny Strawn Date: Sat, 15 Apr 2023 11:58:27 -0700 Subject: [PATCH 09/18] rustfmt --- uefi/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uefi/src/main.rs b/uefi/src/main.rs index c081729d..02639f40 100644 --- a/uefi/src/main.rs +++ b/uefi/src/main.rs @@ -8,12 +8,12 @@ use bootloader_boot_config::BootConfig; use bootloader_x86_64_common::{ legacy_memory_region::LegacyFrameAllocator, Kernel, RawFrameBufferInfo, SystemInfo, }; -use raw_cpuid::CpuId; use core::{ cell::UnsafeCell, ops::{Deref, DerefMut}, ptr, slice, }; +use raw_cpuid::CpuId; use uefi::{ prelude::{entry, Boot, Handle, Status, SystemTable}, proto::{ From 16330cde16a312d1c005059000e11a52ded2fdbc Mon Sep 17 00:00:00 2001 From: Kenny Strawn Date: Sun, 30 Apr 2023 16:22:46 -0700 Subject: [PATCH 10/18] #364: Use different configs for VMs vs real hardware --- bios/stage-4/src/main.rs | 8 ++--- common/config/src/lib.rs | 10 ++++-- uefi/src/main.rs | 72 +++++++++++++++++++++++++++++++--------- 3 files changed, 67 insertions(+), 23 deletions(-) diff --git a/bios/stage-4/src/main.rs b/bios/stage-4/src/main.rs index 260dd622..2d40a6a2 100644 --- a/bios/stage-4/src/main.rs +++ b/bios/stage-4/src/main.rs @@ -129,13 +129,13 @@ pub extern "C" fn _start(info: &mut BiosInfo) -> ! { }; #[allow(deprecated)] - if config.frame_buffer.minimum_framebuffer_height.is_none() { - config.frame_buffer.minimum_framebuffer_height = + if config.frame_buffer_physical.minimum_framebuffer_height.is_none() { + config.frame_buffer_physical.minimum_framebuffer_height = kernel.config.frame_buffer.minimum_framebuffer_height; } #[allow(deprecated)] - if config.frame_buffer.minimum_framebuffer_width.is_none() { - config.frame_buffer.minimum_framebuffer_width = + if config.frame_buffer_physical.minimum_framebuffer_width.is_none() { + config.frame_buffer_physical.minimum_framebuffer_width = kernel.config.frame_buffer.minimum_framebuffer_width; } let framebuffer_info = init_logger( diff --git a/common/config/src/lib.rs b/common/config/src/lib.rs index 1b294331..2ee11fc0 100644 --- a/common/config/src/lib.rs +++ b/common/config/src/lib.rs @@ -7,8 +7,11 @@ use serde::{Deserialize, Serialize}; #[serde(default)] #[non_exhaustive] pub struct BootConfig { - /// Configuration for the frame buffer setup. - pub frame_buffer: FrameBuffer, + /// Configuration for the frame buffer setup on physical hardware. + pub frame_buffer_physical: FrameBuffer, + + /// Configuration for the frame buffer setup in a virtual machine + pub frame_buffer_virtual: FrameBuffer, /// The minimum log level that is printed to the screen during boot. /// @@ -32,7 +35,8 @@ pub struct BootConfig { impl Default for BootConfig { fn default() -> Self { Self { - frame_buffer: Default::default(), + frame_buffer_virtual: Default::default(), + frame_buffer_physical: Default::default(), log_level: Default::default(), frame_buffer_logging: true, serial_logging: true, diff --git a/uefi/src/main.rs b/uefi/src/main.rs index ad11cfa2..9ffc3077 100644 --- a/uefi/src/main.rs +++ b/uefi/src/main.rs @@ -13,7 +13,7 @@ use core::{ ops::{Deref, DerefMut}, ptr, slice, }; -use raw_cpuid::CpuId; +use raw_cpuid::{CpuId, Hypervisor}; use uefi::{ prelude::{entry, Boot, Handle, Status, SystemTable}, proto::{ @@ -98,13 +98,13 @@ fn main_inner(image: Handle, mut st: SystemTable) -> Status { }; #[allow(deprecated)] - if config.frame_buffer.minimum_framebuffer_height.is_none() { - config.frame_buffer.minimum_framebuffer_height = + if config.frame_buffer_physical.minimum_framebuffer_height.is_none() { + config.frame_buffer_physical.minimum_framebuffer_height = kernel.config.frame_buffer.minimum_framebuffer_height; } #[allow(deprecated)] - if config.frame_buffer.minimum_framebuffer_width.is_none() { - config.frame_buffer.minimum_framebuffer_width = + if config.frame_buffer_physical.minimum_framebuffer_width.is_none() { + config.frame_buffer_physical.minimum_framebuffer_width = kernel.config.frame_buffer.minimum_framebuffer_width; } let framebuffer = init_logger(image, &st, &config); @@ -472,16 +472,62 @@ fn init_logger( }; let mode = { - let mut modes = gop.modes(); - - if let Some(_) = CpuId::new().get_hypervisor_info() { + let modes = gop.modes(); + + if let Some(hypervisor) = CpuId::new().get_hypervisor_info() { + if let Hypervisor::Xen = hypervisor.identify() { + // Use same rules as real hardware since Xen uses the whole screen + match ( + config + .frame_buffer_physical + .minimum_framebuffer_height + .map(|v| usize::try_from(v).unwrap()), + config + .frame_buffer_physical + .minimum_framebuffer_width + .map(|v| usize::try_from(v).unwrap()), + ) { + (Some(height), Some(width)) => modes + .filter(|m| { + let res = m.info().resolution(); + res.1 >= height && res.0 >= width + }) + .last(), + (Some(height), None) => modes.filter(|m| m.info().resolution().1 >= height).last(), + (None, Some(width)) => modes.filter(|m| m.info().resolution().0 >= width).last(), + _ => None, + } + } else { + match ( + config + .frame_buffer_virtual + .minimum_framebuffer_height + .map(|v| usize::try_from(v).unwrap()), + config + .frame_buffer_virtual + .minimum_framebuffer_width + .map(|v| usize::try_from(v).unwrap()), + ) { + (Some(height), Some(width)) => modes + .filter(|m| { + let res = m.info().resolution(); + res.1 >= height && res.0 >= width + }) + .last(), + (Some(height), None) => modes.filter(|m| m.info().resolution().1 >= height).last(), + (None, Some(width)) => modes.filter(|m| m.info().resolution().0 >= width).last(), + _ => None, + } + } + } else { + // On real hardware; set rules accordingly match ( config - .frame_buffer + .frame_buffer_physical .minimum_framebuffer_height .map(|v| usize::try_from(v).unwrap()), config - .frame_buffer + .frame_buffer_physical .minimum_framebuffer_width .map(|v| usize::try_from(v).unwrap()), ) { @@ -495,12 +541,6 @@ fn init_logger( (None, Some(width)) => modes.filter(|m| m.info().resolution().0 >= width).last(), _ => None, } - } else { - // Default to using the highest resolution available on real hardware - let x = gop.modes().map(|m| m.info().resolution().0).max().unwrap(); - let y = gop.modes().map(|m| m.info().resolution().1).max().unwrap(); - - modes.find(|m| m.info().resolution().0 == x && m.info().resolution().1 == y) } }; if let Some(mode) = mode { From 2f66e58d088402a5752a0745671574f89f8fbff7 Mon Sep 17 00:00:00 2001 From: Kenny Strawn Date: Sun, 30 Apr 2023 16:29:22 -0700 Subject: [PATCH 11/18] #364: rustfmt --- bios/stage-4/src/main.rs | 12 ++++++++++-- uefi/src/main.rs | 28 ++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/bios/stage-4/src/main.rs b/bios/stage-4/src/main.rs index 2d40a6a2..e69ee6bc 100644 --- a/bios/stage-4/src/main.rs +++ b/bios/stage-4/src/main.rs @@ -129,12 +129,20 @@ pub extern "C" fn _start(info: &mut BiosInfo) -> ! { }; #[allow(deprecated)] - if config.frame_buffer_physical.minimum_framebuffer_height.is_none() { + if config + .frame_buffer_physical + .minimum_framebuffer_height + .is_none() + { config.frame_buffer_physical.minimum_framebuffer_height = kernel.config.frame_buffer.minimum_framebuffer_height; } #[allow(deprecated)] - if config.frame_buffer_physical.minimum_framebuffer_width.is_none() { + if config + .frame_buffer_physical + .minimum_framebuffer_width + .is_none() + { config.frame_buffer_physical.minimum_framebuffer_width = kernel.config.frame_buffer.minimum_framebuffer_width; } diff --git a/uefi/src/main.rs b/uefi/src/main.rs index 9ffc3077..c9544794 100644 --- a/uefi/src/main.rs +++ b/uefi/src/main.rs @@ -98,12 +98,20 @@ fn main_inner(image: Handle, mut st: SystemTable) -> Status { }; #[allow(deprecated)] - if config.frame_buffer_physical.minimum_framebuffer_height.is_none() { + if config + .frame_buffer_physical + .minimum_framebuffer_height + .is_none() + { config.frame_buffer_physical.minimum_framebuffer_height = kernel.config.frame_buffer.minimum_framebuffer_height; } #[allow(deprecated)] - if config.frame_buffer_physical.minimum_framebuffer_width.is_none() { + if config + .frame_buffer_physical + .minimum_framebuffer_width + .is_none() + { config.frame_buffer_physical.minimum_framebuffer_width = kernel.config.frame_buffer.minimum_framebuffer_width; } @@ -493,8 +501,12 @@ fn init_logger( res.1 >= height && res.0 >= width }) .last(), - (Some(height), None) => modes.filter(|m| m.info().resolution().1 >= height).last(), - (None, Some(width)) => modes.filter(|m| m.info().resolution().0 >= width).last(), + (Some(height), None) => { + modes.filter(|m| m.info().resolution().1 >= height).last() + } + (None, Some(width)) => { + modes.filter(|m| m.info().resolution().0 >= width).last() + } _ => None, } } else { @@ -514,8 +526,12 @@ fn init_logger( res.1 >= height && res.0 >= width }) .last(), - (Some(height), None) => modes.filter(|m| m.info().resolution().1 >= height).last(), - (None, Some(width)) => modes.filter(|m| m.info().resolution().0 >= width).last(), + (Some(height), None) => { + modes.filter(|m| m.info().resolution().1 >= height).last() + } + (None, Some(width)) => { + modes.filter(|m| m.info().resolution().0 >= width).last() + } _ => None, } } From 299a6700c1991faa765c32d193e1c529387e4c27 Mon Sep 17 00:00:00 2001 From: Kenny Strawn Date: Sun, 1 Oct 2023 17:34:03 -0700 Subject: [PATCH 12/18] Pass the UEFI runtime services table address to the BootInfo if running on UEFI --- api/Cargo.toml | 1 + api/src/info.rs | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/api/Cargo.toml b/api/Cargo.toml index ef687b0c..a21d3a97 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -9,6 +9,7 @@ description = "Makes a kernel compatible with the bootloader crate" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +uefi = "0.24.0" [dev-dependencies] rand = "0.8.4" diff --git a/api/src/info.rs b/api/src/info.rs index 965fcf40..064c4216 100644 --- a/api/src/info.rs +++ b/api/src/info.rs @@ -63,6 +63,9 @@ pub struct BootInfo { /// Virtual address of the loaded kernel image. pub kernel_image_offset: u64, + /// UEFI runtime table address (if running on UEFI) + pub rt_table_addr: Optional, + #[doc(hidden)] pub _test_sentinel: u64, } @@ -85,6 +88,7 @@ impl BootInfo { kernel_addr: 0, kernel_len: 0, kernel_image_offset: 0, + rt_table_addr: Optional::None, _test_sentinel: 0, } } From 68a123e5158d952d1d4261e69f9d394dbb98245d Mon Sep 17 00:00:00 2001 From: Kenny Strawn Date: Sun, 1 Oct 2023 17:34:12 -0700 Subject: [PATCH 13/18] Pass the UEFI runtime services table address to the BootInfo if running on UEFI --- Cargo.lock | 48 ++++++++++++++++++++++++++++++++++++++-- bios/stage-4/src/main.rs | 1 + common/src/lib.rs | 13 +++++++++-- uefi/src/main.rs | 1 + 4 files changed, 59 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5023a397..ab7f04c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -253,7 +253,7 @@ dependencies = [ "bootloader_api", "log", "serde-json-core", - "uefi", + "uefi 0.20.0", "x86_64", ] @@ -262,6 +262,7 @@ name = "bootloader_api" version = "0.11.4" dependencies = [ "rand", + "uefi 0.24.0", ] [[package]] @@ -1173,7 +1174,22 @@ dependencies = [ "log", "ptr_meta", "ucs2", - "uefi-macros", + "uefi-macros 0.11.0", +] + +[[package]] +name = "uefi" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b63e82686b4bdb0db74f18b2abbd60a0470354fb640aa69e115598d714d0a10" +dependencies = [ + "bitflags 2.3.3", + "log", + "ptr_meta", + "ucs2", + "uefi-macros 0.12.0", + "uefi-raw", + "uguid", ] [[package]] @@ -1187,6 +1203,34 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "uefi-macros" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "023d94ef8e135d068b9a3bd94614ef2610b2b0419ade0a9d8f3501fa9cd08e95" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.23", +] + +[[package]] +name = "uefi-raw" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62642516099c6441a5f41b0da8486d5fc3515a0603b0fdaea67b31600e22082e" +dependencies = [ + "bitflags 2.3.3", + "ptr_meta", + "uguid", +] + +[[package]] +name = "uguid" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16dfbd255defbd727b3a30e8950695d2e6d045841ee250ff0f1f7ced17917f8d" + [[package]] name = "unicode-ident" version = "1.0.10" diff --git a/bios/stage-4/src/main.rs b/bios/stage-4/src/main.rs index 260dd622..a6361c47 100644 --- a/bios/stage-4/src/main.rs +++ b/bios/stage-4/src/main.rs @@ -164,6 +164,7 @@ pub extern "C" fn _start(info: &mut BiosInfo) -> ! { _ => Some(info.ramdisk.start), }, ramdisk_len: info.ramdisk.len, + rt_table_addr: None, }; load_and_switch_to_kernel(kernel, config, frame_allocator, page_tables, system_info); diff --git a/common/src/lib.rs b/common/src/lib.rs index 3c407644..7be711e7 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -5,7 +5,7 @@ use crate::legacy_memory_region::{LegacyFrameAllocator, LegacyMemoryRegion}; use bootloader_api::{ config::Mapping, - info::{FrameBuffer, FrameBufferInfo, MemoryRegion, TlsTemplate}, + info::{FrameBuffer, FrameBufferInfo, MemoryRegion, TlsTemplate, Optional}, BootInfo, BootloaderConfig, }; use bootloader_boot_config::{BootConfig, LevelFilter}; @@ -72,7 +72,7 @@ fn convert_level(level: LevelFilter) -> log::LevelFilter { } /// Required system information that should be queried from the BIOS or UEFI firmware. -#[derive(Debug, Copy, Clone)] +#[derive(Debug)] pub struct SystemInfo { /// Information about the (still unmapped) framebuffer. pub framebuffer: Option, @@ -80,6 +80,10 @@ pub struct SystemInfo { pub rsdp_addr: Option, pub ramdisk_addr: Option, pub ramdisk_len: u64, + + /// UEFI runtime table address (on a UEFI system) + // #[cfg(target_os = "uefi")] + pub rt_table_addr: Option, } /// The physical address of the framebuffer and information about the framebuffer. @@ -551,6 +555,11 @@ where info.kernel_len = mappings.kernel_slice_len as _; info.kernel_image_offset = mappings.kernel_image_offset.as_u64(); info._test_sentinel = boot_config._test_sentinel; + info.rt_table_addr = if let Some(addr) = system_info.rt_table_addr { + Optional::Some(addr) + } else { + Optional::None + }; info }); diff --git a/uefi/src/main.rs b/uefi/src/main.rs index 93dfb6c7..2c39e877 100644 --- a/uefi/src/main.rs +++ b/uefi/src/main.rs @@ -166,6 +166,7 @@ fn main_inner(image: Handle, mut st: SystemTable) -> Status { }, ramdisk_addr, ramdisk_len, + rt_table_addr: Some(system_table.get_current_system_table_addr()), }; bootloader_x86_64_common::load_and_switch_to_kernel( From c5b6e04e2809bbabb429d5826d9e821e3444fb32 Mon Sep 17 00:00:00 2001 From: Kenny Strawn Date: Sun, 1 Oct 2023 17:42:19 -0700 Subject: [PATCH 14/18] rustfmt --- common/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/lib.rs b/common/src/lib.rs index 7be711e7..8770e0d1 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -5,7 +5,7 @@ use crate::legacy_memory_region::{LegacyFrameAllocator, LegacyMemoryRegion}; use bootloader_api::{ config::Mapping, - info::{FrameBuffer, FrameBufferInfo, MemoryRegion, TlsTemplate, Optional}, + info::{FrameBuffer, FrameBufferInfo, MemoryRegion, Optional, TlsTemplate}, BootInfo, BootloaderConfig, }; use bootloader_boot_config::{BootConfig, LevelFilter}; From 0b028dba1852911db37a7e17cd99b1baa507ad18 Mon Sep 17 00:00:00 2001 From: Kenny Strawn Date: Sun, 1 Oct 2023 17:53:02 -0700 Subject: [PATCH 15/18] Remove redundant dependencies --- Cargo.lock | 48 ++---------------------------------------------- api/Cargo.toml | 5 ----- 2 files changed, 2 insertions(+), 51 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ab7f04c9..5023a397 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -253,7 +253,7 @@ dependencies = [ "bootloader_api", "log", "serde-json-core", - "uefi 0.20.0", + "uefi", "x86_64", ] @@ -262,7 +262,6 @@ name = "bootloader_api" version = "0.11.4" dependencies = [ "rand", - "uefi 0.24.0", ] [[package]] @@ -1174,22 +1173,7 @@ dependencies = [ "log", "ptr_meta", "ucs2", - "uefi-macros 0.11.0", -] - -[[package]] -name = "uefi" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b63e82686b4bdb0db74f18b2abbd60a0470354fb640aa69e115598d714d0a10" -dependencies = [ - "bitflags 2.3.3", - "log", - "ptr_meta", - "ucs2", - "uefi-macros 0.12.0", - "uefi-raw", - "uguid", + "uefi-macros", ] [[package]] @@ -1203,34 +1187,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "uefi-macros" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "023d94ef8e135d068b9a3bd94614ef2610b2b0419ade0a9d8f3501fa9cd08e95" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.23", -] - -[[package]] -name = "uefi-raw" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62642516099c6441a5f41b0da8486d5fc3515a0603b0fdaea67b31600e22082e" -dependencies = [ - "bitflags 2.3.3", - "ptr_meta", - "uguid", -] - -[[package]] -name = "uguid" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16dfbd255defbd727b3a30e8950695d2e6d045841ee250ff0f1f7ced17917f8d" - [[package]] name = "unicode-ident" version = "1.0.10" diff --git a/api/Cargo.toml b/api/Cargo.toml index a21d3a97..8d075843 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -6,10 +6,5 @@ repository.workspace = true edition = "2021" description = "Makes a kernel compatible with the bootloader crate" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -uefi = "0.24.0" - [dev-dependencies] rand = "0.8.4" From 35bcae6477a15f0a2a2dec04f96cd347856dac44 Mon Sep 17 00:00:00 2001 From: Kenny Strawn Date: Sun, 1 Oct 2023 17:55:09 -0700 Subject: [PATCH 16/18] Add back the Copy and Clone impls --- common/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/lib.rs b/common/src/lib.rs index 8770e0d1..9ec13214 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -72,7 +72,7 @@ fn convert_level(level: LevelFilter) -> log::LevelFilter { } /// Required system information that should be queried from the BIOS or UEFI firmware. -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] pub struct SystemInfo { /// Information about the (still unmapped) framebuffer. pub framebuffer: Option, From 5578f36edc46dc3fb68c98c51419dfc6136167d9 Mon Sep 17 00:00:00 2001 From: Kenny Strawn Date: Sun, 1 Oct 2023 18:00:23 -0700 Subject: [PATCH 17/18] Fix doc comments --- common/src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/common/src/lib.rs b/common/src/lib.rs index 9ec13214..a72bca89 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -81,8 +81,9 @@ pub struct SystemInfo { pub ramdisk_addr: Option, pub ramdisk_len: u64, - /// UEFI runtime table address (on a UEFI system) - // #[cfg(target_os = "uefi")] + /// UEFI runtime table address (if running on UEFI). + /// + /// Use a raw pointer from your kernel to this address to access UEFI Runtime Services. pub rt_table_addr: Option, } From 20dbee73e708279ded6ed594eeac127ba1c62e01 Mon Sep 17 00:00:00 2001 From: Kenny Strawn Date: Sun, 1 Oct 2023 18:07:09 -0700 Subject: [PATCH 18/18] rustfmt --- common/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/lib.rs b/common/src/lib.rs index a72bca89..20c5c4cc 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -82,7 +82,7 @@ pub struct SystemInfo { pub ramdisk_len: u64, /// UEFI runtime table address (if running on UEFI). - /// + /// /// Use a raw pointer from your kernel to this address to access UEFI Runtime Services. pub rt_table_addr: Option, }