diff --git a/api/src/info.rs b/api/src/info.rs index 1a494291..b3db8d4f 100644 --- a/api/src/info.rs +++ b/api/src/info.rs @@ -158,17 +158,12 @@ pub enum MemoryRegionKind { #[repr(C)] pub struct FrameBuffer { pub(crate) buffer_start: u64, - pub(crate) buffer_byte_len: usize, pub(crate) info: FrameBufferInfo, } impl FrameBuffer { - pub fn new(buffer_start: u64, buffer_byte_len: usize, info: FrameBufferInfo) -> Self { - Self { - buffer_start, - buffer_byte_len, - info, - } + pub fn new(buffer_start: u64, info: FrameBufferInfo) -> Self { + Self { buffer_start, info } } /// Returns the raw bytes of the framebuffer as slice. @@ -182,11 +177,11 @@ impl FrameBuffer { } unsafe fn create_buffer<'a>(&self) -> &'a [u8] { - unsafe { slice::from_raw_parts(self.buffer_start as *const u8, self.buffer_byte_len) } + unsafe { slice::from_raw_parts(self.buffer_start as *const u8, self.info.byte_len) } } unsafe fn create_buffer_mut<'a>(&self) -> &'a mut [u8] { - unsafe { slice::from_raw_parts_mut(self.buffer_start as *mut u8, self.buffer_byte_len) } + unsafe { slice::from_raw_parts_mut(self.buffer_start as *mut u8, self.info.byte_len) } } /// Returns layout and pixel format information of the framebuffer. diff --git a/bios/stage-4/src/main.rs b/bios/stage-4/src/main.rs index 1bedc2d4..86a97328 100644 --- a/bios/stage-4/src/main.rs +++ b/bios/stage-4/src/main.rs @@ -4,6 +4,7 @@ use crate::memory_descriptor::MemoryRegion; use bootloader_api::info::{FrameBufferInfo, PixelFormat}; use bootloader_x86_64_bios_common::{BiosFramebufferInfo, BiosInfo, E820MemoryRegion}; +use bootloader_x86_64_common::RawFrameBufferInfo; use bootloader_x86_64_common::{ legacy_memory_region::LegacyFrameAllocator, load_and_switch_to_kernel, Kernel, PageTables, SystemInfo, @@ -112,8 +113,10 @@ pub extern "C" fn _start(info: &mut BiosInfo) -> ! { let kernel = Kernel::parse(kernel_slice); let system_info = SystemInfo { - framebuffer_addr: PhysAddr::new(info.framebuffer.region.start), - framebuffer_info, + framebuffer: Some(RawFrameBufferInfo { + addr: PhysAddr::new(info.framebuffer.region.start), + info: framebuffer_info, + }), rsdp_addr: detect_rsdp(), }; diff --git a/common/src/level_4_entries.rs b/common/src/level_4_entries.rs index ce040d93..2e5e1c4c 100644 --- a/common/src/level_4_entries.rs +++ b/common/src/level_4_entries.rs @@ -1,4 +1,4 @@ -use crate::{entropy, BootInfo}; +use crate::{entropy, BootInfo, RawFrameBufferInfo}; use bootloader_api::{config, info::MemoryRegion, BootloaderConfig}; use core::{alloc::Layout, iter::Step}; use rand::{ @@ -31,7 +31,7 @@ impl UsedLevel4Entries { pub fn new( max_phys_addr: PhysAddr, regions_len: usize, - framebuffer_size: usize, + framebuffer: Option<&RawFrameBufferInfo>, config: &BootloaderConfig, ) -> Self { let mut used = UsedLevel4Entries { @@ -70,7 +70,9 @@ impl UsedLevel4Entries { } if let config::Mapping::FixedAddress(framebuffer_address) = config.mappings.framebuffer { - used.mark_range_as_used(framebuffer_address, framebuffer_size); + if let Some(framebuffer) = framebuffer { + used.mark_range_as_used(framebuffer_address, framebuffer.info.byte_len); + } } // Mark everything before the dynamic range as unusable. diff --git a/common/src/lib.rs b/common/src/lib.rs index 0a8a6990..8b49945f 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -45,14 +45,21 @@ pub fn init_logger(framebuffer: &'static mut [u8], info: FrameBufferInfo) { /// Required system information that should be queried from the BIOS or UEFI firmware. #[derive(Debug, Copy, Clone)] pub struct SystemInfo { - /// Start address of the pixel-based framebuffer. - pub framebuffer_addr: PhysAddr, - /// Information about the framebuffer, including layout and pixel format. - pub framebuffer_info: FrameBufferInfo, + /// Information about the (still unmapped) framebuffer. + pub framebuffer: Option, /// Address of the _Root System Description Pointer_ structure of the ACPI standard. pub rsdp_addr: Option, } +/// The physical address of the framebuffer and information about the framebuffer. +#[derive(Debug, Copy, Clone)] +pub struct RawFrameBufferInfo { + /// Start address of the pixel-based framebuffer. + pub addr: PhysAddr, + /// Information about the framebuffer, including layout and pixel format. + pub info: FrameBufferInfo, +} + pub struct Kernel<'a> { pub elf: ElfFile<'a>, pub config: BootloaderConfig, @@ -100,8 +107,7 @@ where kernel, &mut frame_allocator, &mut page_tables, - system_info.framebuffer_addr, - system_info.framebuffer_info.byte_len, + system_info.framebuffer.as_ref(), &config, ); let boot_info = create_boot_info( @@ -132,8 +138,7 @@ pub fn set_up_mappings( kernel: Kernel, frame_allocator: &mut LegacyFrameAllocator, page_tables: &mut PageTables, - framebuffer_addr: PhysAddr, - framebuffer_size: usize, + framebuffer: Option<&RawFrameBufferInfo>, config: &BootloaderConfig, ) -> Mappings where @@ -145,7 +150,7 @@ where let mut used_entries = UsedLevel4Entries::new( frame_allocator.max_phys_addr(), frame_allocator.len(), - framebuffer_size, + framebuffer, config, ); @@ -220,15 +225,15 @@ where } // map framebuffer - let framebuffer_virt_addr = { + let framebuffer_virt_addr = if let Some(framebuffer) = framebuffer { log::info!("Map framebuffer"); - let framebuffer_start_frame: PhysFrame = PhysFrame::containing_address(framebuffer_addr); + let framebuffer_start_frame: PhysFrame = PhysFrame::containing_address(framebuffer.addr); let framebuffer_end_frame = - PhysFrame::containing_address(framebuffer_addr + framebuffer_size - 1u64); + PhysFrame::containing_address(framebuffer.addr + framebuffer.info.byte_len - 1u64); let start_page = Page::from_start_address(mapping_addr( config.mappings.framebuffer, - u64::from_usize(framebuffer_size), + u64::from_usize(framebuffer.info.byte_len), Size4KiB::SIZE, &mut used_entries, )) @@ -248,6 +253,8 @@ where } let framebuffer_virt_addr = start_page.start_address(); Some(framebuffer_virt_addr) + } else { + None }; let physical_memory_offset = if let Some(mapping) = config.mappings.physical_memory { @@ -440,13 +447,7 @@ where let mut info = BootInfo::new(memory_regions.into()); info.framebuffer = mappings .framebuffer - .map(|addr| { - FrameBuffer::new( - addr.as_u64(), - system_info.framebuffer_info.byte_len, - system_info.framebuffer_info, - ) - }) + .map(|addr| FrameBuffer::new(addr.as_u64(), system_info.framebuffer.expect("there shouldn't be a mapping for the framebuffer if there is not framebuffer").info)) .into(); info.physical_memory_offset = mappings.physical_memory_offset.map(VirtAddr::as_u64).into(); info.recursive_index = mappings.recursive_index.map(Into::into).into(); diff --git a/uefi/src/main.rs b/uefi/src/main.rs index 5c8bced4..f72996bd 100644 --- a/uefi/src/main.rs +++ b/uefi/src/main.rs @@ -5,7 +5,9 @@ use crate::memory_descriptor::UefiMemoryDescriptor; use bootloader_api::{info::FrameBufferInfo, BootloaderConfig}; -use bootloader_x86_64_common::{legacy_memory_region::LegacyFrameAllocator, Kernel, SystemInfo}; +use bootloader_x86_64_common::{ + legacy_memory_region::LegacyFrameAllocator, Kernel, RawFrameBufferInfo, SystemInfo, +}; use core::{arch::asm, cell::UnsafeCell, fmt::Write, mem, panic::PanicInfo, ptr, slice}; use uefi::{ prelude::{entry, Boot, Handle, Status, SystemTable}, @@ -74,7 +76,7 @@ fn main_inner(image: Handle, mut st: SystemTable) -> Status { let kernel = load_kernel(image, &mut st); - let (framebuffer_addr, framebuffer_info) = init_logger(&st, kernel.config); + let framebuffer = init_logger(&st, kernel.config); // we no longer need the system table for printing panics unsafe { @@ -83,7 +85,9 @@ fn main_inner(image: Handle, mut st: SystemTable) -> Status { log::info!("UEFI bootloader started"); log::info!("Reading kernel and configuration from disk was successful"); - log::info!("Using framebuffer at {:#x}", framebuffer_addr); + if let Some(framebuffer) = framebuffer { + log::info!("Using framebuffer at {:#x}", framebuffer.addr); + } let mmap_storage = { let max_mmap_size = @@ -105,8 +109,7 @@ fn main_inner(image: Handle, mut st: SystemTable) -> Status { let page_tables = create_page_tables(&mut frame_allocator); let system_info = SystemInfo { - framebuffer_addr, - framebuffer_info, + framebuffer, rsdp_addr: { use uefi::table::cfg; let mut config_entries = system_table.config_table().iter(); @@ -362,11 +365,11 @@ fn create_page_tables( } } -fn init_logger(st: &SystemTable, config: BootloaderConfig) -> (PhysAddr, FrameBufferInfo) { +fn init_logger(st: &SystemTable, config: BootloaderConfig) -> Option { let gop = st .boot_services() .locate_protocol::() - .expect("failed to locate gop"); + .ok()?; let gop = unsafe { &mut *gop.get() }; let mode = { @@ -419,7 +422,10 @@ fn init_logger(st: &SystemTable, config: BootloaderConfig) -> (PhysAddr, F bootloader_x86_64_common::init_logger(slice, info); - (PhysAddr::new(framebuffer.as_mut_ptr() as u64), info) + Some(RawFrameBufferInfo { + addr: PhysAddr::new(framebuffer.as_mut_ptr() as u64), + info, + }) } #[panic_handler]