diff --git a/mk/aarch64-unknown-uefi.mk b/mk/aarch64-unknown-uefi.mk index 6c0b741ded..773f614704 100644 --- a/mk/aarch64-unknown-uefi.mk +++ b/mk/aarch64-unknown-uefi.mk @@ -51,6 +51,6 @@ qemu: $(BUILD)/harddrive.bin $(BUILD)/firmware.rom -mon chardev=debug \ -machine virt \ -net none \ - -cpu cortex-a57 \ + -cpu max \ -bios $(BUILD)/firmware.rom \ -drive file=$<,format=raw diff --git a/src/os/uefi/arch/aarch64/mod.rs b/src/os/uefi/arch/aarch64/mod.rs index 474484222b..49c145bc09 100644 --- a/src/os/uefi/arch/aarch64/mod.rs +++ b/src/os/uefi/arch/aarch64/mod.rs @@ -1,6 +1,5 @@ use alloc::{ string::String, - vec::Vec, }; use core::{mem, ptr, slice}; use orbclient::{Color, Renderer}; @@ -22,9 +21,6 @@ use self::paging::paging; mod memory_map; mod paging; -mod partitions; - -static KERNEL: &'static str = "\\redox_bootloader\\kernel"; static KERNEL_OFFSET: u64 = 0xFFFF_FF00_0000_0000; @@ -63,52 +59,12 @@ unsafe fn exit_boot_services(key: usize) { } unsafe fn enter() -> ! { - let entry_fn: extern "C" fn(dtb: u64) -> ! = mem::transmute(( + let entry_fn: extern "C" fn(dtb: u64) -> ! = mem::transmute( KERNEL_PHYSICAL + KERNEL_ENTRY - KERNEL_OFFSET - )); + ); entry_fn(DTB_PHYSICAL); } -fn get_correct_block_io() -> Result { - // Get all BlockIo handles. - let mut handles = vec! [uefi::Handle(0); 128]; - let mut size = handles.len() * mem::size_of::(); - - (std::system_table().BootServices.LocateHandle)(uefi::boot::LocateSearchType::ByProtocol, &uefi::guid::BLOCK_IO_GUID, 0, &mut size, handles.as_mut_ptr())?; - - let max_size = size / mem::size_of::(); - let actual_size = std::cmp::min(handles.len(), max_size); - - // Return the handle that seems bootable. - for handle in handles.into_iter().take(actual_size) { - let block_io = DiskEfi::handle_protocol(handle)?; - if !block_io.0.Media.LogicalPartition { - continue; - } - - let part = partitions::PartitionProto::handle_protocol(handle)?.0; - if part.sys == 1 { - continue; - } - assert_eq!({part.rev}, partitions::PARTITION_INFO_PROTOCOL_REVISION); - if part.ty == partitions::PartitionProtoDataTy::Gpt as u32 { - let gpt = unsafe { part.info.gpt }; - assert_ne!(gpt.part_ty_guid, partitions::ESP_GUID, "detected esp partition again"); - if gpt.part_ty_guid == partitions::REDOX_FS_GUID || gpt.part_ty_guid == partitions::LINUX_FS_GUID { - return Ok(block_io); - } - } else if part.ty == partitions::PartitionProtoDataTy::Mbr as u32 { - let mbr = unsafe { part.info.mbr }; - if mbr.ty == 0x83 { - return Ok(block_io); - } - } else { - continue; - } - } - panic!("Couldn't find handle for partition"); -} - static DTB_GUID: Guid = Guid(0xb1b621d5, 0xf19c, 0x41a5, [0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0]); fn find_dtb() -> Result<()> { @@ -127,10 +83,19 @@ fn find_dtb() -> Result<()> { } fn redoxfs() -> Result> { - // TODO: Scan multiple partitions for a kernel. - // TODO: pass block_opt for performance reasons - redoxfs::FileSystem::open(get_correct_block_io()?, None) - .map_err(|_| Error::DeviceError) + for (i, block_io) in DiskEfi::all().into_iter().enumerate() { + if !block_io.0.Media.LogicalPartition { + continue; + } + + match redoxfs::FileSystem::open(block_io, Some(0)) { + Ok(ok) => return Ok(ok), + Err(err) => { + log::error!("Failed to open RedoxFS on block I/O {}: {}", i, err); + } + } + } + panic!("Failed to find RedoxFS"); } const MB: usize = 1024 * 1024; @@ -252,98 +217,8 @@ fn inner() -> Result<()> { } } -fn select_mode(output: &mut Output) -> Result { - loop { - for i in 0..output.0.Mode.MaxMode { - let mut mode_ptr = ::core::ptr::null_mut(); - let mut mode_size = 0; - (output.0.QueryMode)(output.0, i, &mut mode_size, &mut mode_ptr)?; - - let mode = unsafe { &mut *mode_ptr }; - let w = mode.HorizontalResolution; - let h = mode.VerticalResolution; - - print!("\r{}x{}: Is this OK? (y)es/(n)o", w, h); - - if key(true)? == Key::Character('y') { - println!(""); - - return Ok(i); - } - } - } -} - -fn pretty_pipe Result>(f: F) -> Result { - let mut output = Output::one()?; - let mut display = Display::new(&mut output); - let mut display = ScaledDisplay::new(&mut display); - - { - let bg = Color::rgb(0x4a, 0xa3, 0xfd); - - display.set(bg); - - { - let prompt = format!( - "Redox Bootloader {} {}", - env!("CARGO_PKG_VERSION"), - env!("TARGET").split('-').next().unwrap_or("") - ); - let mut x = (display.width() as i32 - prompt.len() as i32 * 8)/2; - let y = display.height() as i32 - 32; - for c in prompt.chars() { - display.char(x, y, c, Color::rgb(0xff, 0xff, 0xff)); - x += 8; - } - } - - display.sync(); - } - - { - let cols = 80; - let off_x = (display.width() as i32 - cols as i32 * 8)/2; - let off_y = 16; - let rows = (display.height() as i32 - 64 - off_y - 1) as usize/16; - display.rect(off_x, off_y, cols as u32 * 8, rows as u32 * 16, Color::rgb(0, 0, 0)); - display.sync(); - - let mut text = TextDisplay::new(display); - text.off_x = off_x; - text.off_y = off_y; - text.cols = cols; - text.rows = rows; - text.pipe(f) - } -} - pub fn main() -> Result<()> { inner()?; - /* TODO - if let Ok(mut output) = Output::one() { - let mut splash = Image::new(0, 0); - { - println!("Loading Splash..."); - if let Ok(image) = image::bmp::parse(&SPLASHBMP) { - splash = image; - } - println!(" Done"); - } - - /* TODO - let mode = pretty_pipe(&splash, || { - select_mode(&mut output) - })?; - (output.0.SetMode)(output.0, mode)?; - */ - - pretty_pipe(&splash, inner)?; - } else { - inner()?; - } - */ - Ok(()) } diff --git a/src/os/uefi/arch/aarch64/partitions.rs b/src/os/uefi/arch/aarch64/partitions.rs deleted file mode 100644 index bc126631ef..0000000000 --- a/src/os/uefi/arch/aarch64/partitions.rs +++ /dev/null @@ -1,63 +0,0 @@ -use std::proto::Protocol; - -#[repr(packed)] -#[derive(Clone, Copy, Debug)] -pub struct PartitionProtoInfoMbr { - pub boot: u8, - pub chs_start: [u8; 3], - pub ty: u8, - pub chs_end: [u8; 3], - pub start_lba: u32, - pub lba_size: u32, -} - -#[repr(packed)] -#[derive(Clone, Copy)] -pub struct PartitionProtoInfoGpt { - pub part_ty_guid: [u8; 16], - pub uniq_guid: [u8; 16], - pub start_lba: u64, - pub end_lba: u64, - pub attrs: u64, - pub name: [u16; 36], - // reserved until end of block -} - -#[repr(packed)] -#[derive(Clone, Copy)] -pub union PartitionProtoDataInfo { - pub mbr: PartitionProtoInfoMbr, - pub gpt: PartitionProtoInfoGpt, -} - -#[repr(packed)] -pub struct PartitionProtoData { - pub rev: u32, - pub ty: u32, - pub sys: u8, - pub resv: [u8; 7], - pub info: PartitionProtoDataInfo, -} - -pub const PARTITION_INFO_PROTOCOL_REVISION: u32 = 0x1000; -pub const ESP_GUID: [u8; 16] = [0x28, 0x73, 0x2a, 0xc1, 0x1f, 0xf8, 0xd2, 0x11, 0xba, 0x4b, 0x0, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b]; // c12a7328-f81f-11d2-bA4b-00a0c93ec93b -pub const LINUX_FS_GUID: [u8; 16] = [0xaf, 0x3d, 0xc6, 0xf, 0x83, 0x84, 0x72, 0x47, 0x8e, 0x79, 0x3d, 0x69, 0xd8, 0x47, 0x7d, 0xe4]; // 0fc63daf-8483-4772-8e79-3d69d8477de4 -pub const REDOX_FS_GUID: [u8; 16] = [0xfd, 0x98, 0x78, 0x52, 0xe3, 0xff, 0xc2, 0x42, 0xe3, 0x96, 0x10, 0x5b, 0xa6, 0x3f, 0x5a, 0xbf]; // 527898fd-ffe3-42c2-96e3-bf5a3fa65b10 - -#[repr(u32)] -pub enum PartitionProtoDataTy { - Other = 0, - Mbr = 1, - Gpt = 2, -} - -pub struct PartitionProto(pub &'static mut PartitionProtoData); - -impl Protocol for PartitionProto { - fn guid() -> uefi::guid::Guid { - uefi::guid::Guid(0x8cf2f62c, 0xbc9b, 0x4821, [0x80, 0x8d, 0xec, 0x9e, 0xc4, 0x21, 0xa1, 0xa0]) - } - fn new(inner: &'static mut PartitionProtoData) -> Self { - Self(inner) - } -} diff --git a/src/os/uefi/arch/x86_64/mod.rs b/src/os/uefi/arch/x86_64/mod.rs index c7c2dfcb27..0bcc0c7527 100644 --- a/src/os/uefi/arch/x86_64/mod.rs +++ b/src/os/uefi/arch/x86_64/mod.rs @@ -20,7 +20,6 @@ use self::paging::{paging_create, paging_enter}; mod memory_map; mod paging; -mod partitions; static PHYS_OFFSET: u64 = 0xFFFF800000000000; @@ -88,46 +87,6 @@ unsafe fn enter() -> ! { entry_fn(&args); } -fn get_correct_block_io() -> Result { - // Get all BlockIo handles. - let mut handles = vec! [uefi::Handle(0); 128]; - let mut size = handles.len() * mem::size_of::(); - - (std::system_table().BootServices.LocateHandle)(uefi::boot::LocateSearchType::ByProtocol, &uefi::guid::BLOCK_IO_GUID, 0, &mut size, handles.as_mut_ptr())?; - - let max_size = size / mem::size_of::(); - let actual_size = std::cmp::min(handles.len(), max_size); - - // Return the handle that seems bootable. - for handle in handles.into_iter().take(actual_size) { - let block_io = DiskEfi::handle_protocol(handle)?; - if !block_io.0.Media.LogicalPartition { - continue; - } - - let part = partitions::PartitionProto::handle_protocol(handle)?.0; - if part.sys == 1 { - continue; - } - assert_eq!({part.rev}, partitions::PARTITION_INFO_PROTOCOL_REVISION); - if part.ty == partitions::PartitionProtoDataTy::Gpt as u32 { - let gpt = unsafe { part.info.gpt }; - assert_ne!(gpt.part_ty_guid, partitions::ESP_GUID, "detected esp partition again"); - if gpt.part_ty_guid == partitions::REDOX_FS_GUID || gpt.part_ty_guid == partitions::LINUX_FS_GUID { - return Ok(block_io); - } - } else if part.ty == partitions::PartitionProtoDataTy::Mbr as u32 { - let mbr = unsafe { part.info.mbr }; - if mbr.ty == 0x83 { - return Ok(block_io); - } - } else { - continue; - } - } - panic!("Couldn't find handle for partition"); -} - struct Invalid; fn validate_rsdp(address: usize, v2: bool) -> core::result::Result { @@ -202,10 +161,19 @@ fn find_acpi_table_pointers() -> Result<()> { } fn redoxfs() -> Result> { - // TODO: Scan multiple partitions for a kernel. - // TODO: pass block_opt for performance reasons - redoxfs::FileSystem::open(get_correct_block_io()?, None) - .map_err(|_| Error::DeviceError) + for (i, block_io) in DiskEfi::all().into_iter().enumerate() { + if !block_io.0.Media.LogicalPartition { + continue; + } + + match redoxfs::FileSystem::open(block_io, Some(0)) { + Ok(ok) => return Ok(ok), + Err(err) => { + log::error!("Failed to open RedoxFS on block I/O {}: {}", i, err); + } + } + } + panic!("Failed to find RedoxFS"); } const MB: usize = 1024 * 1024; @@ -434,7 +402,7 @@ fn select_mode(output: &mut Output) -> Result<()> { let mut row = 0; let mut col = 0; - for (i, w, h, text) in modes.iter() { + for (i, _w, _h, text) in modes.iter() { if row >= rows as i32 { col += 1; row = 0; diff --git a/src/os/uefi/arch/x86_64/partitions.rs b/src/os/uefi/arch/x86_64/partitions.rs deleted file mode 100644 index bc126631ef..0000000000 --- a/src/os/uefi/arch/x86_64/partitions.rs +++ /dev/null @@ -1,63 +0,0 @@ -use std::proto::Protocol; - -#[repr(packed)] -#[derive(Clone, Copy, Debug)] -pub struct PartitionProtoInfoMbr { - pub boot: u8, - pub chs_start: [u8; 3], - pub ty: u8, - pub chs_end: [u8; 3], - pub start_lba: u32, - pub lba_size: u32, -} - -#[repr(packed)] -#[derive(Clone, Copy)] -pub struct PartitionProtoInfoGpt { - pub part_ty_guid: [u8; 16], - pub uniq_guid: [u8; 16], - pub start_lba: u64, - pub end_lba: u64, - pub attrs: u64, - pub name: [u16; 36], - // reserved until end of block -} - -#[repr(packed)] -#[derive(Clone, Copy)] -pub union PartitionProtoDataInfo { - pub mbr: PartitionProtoInfoMbr, - pub gpt: PartitionProtoInfoGpt, -} - -#[repr(packed)] -pub struct PartitionProtoData { - pub rev: u32, - pub ty: u32, - pub sys: u8, - pub resv: [u8; 7], - pub info: PartitionProtoDataInfo, -} - -pub const PARTITION_INFO_PROTOCOL_REVISION: u32 = 0x1000; -pub const ESP_GUID: [u8; 16] = [0x28, 0x73, 0x2a, 0xc1, 0x1f, 0xf8, 0xd2, 0x11, 0xba, 0x4b, 0x0, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b]; // c12a7328-f81f-11d2-bA4b-00a0c93ec93b -pub const LINUX_FS_GUID: [u8; 16] = [0xaf, 0x3d, 0xc6, 0xf, 0x83, 0x84, 0x72, 0x47, 0x8e, 0x79, 0x3d, 0x69, 0xd8, 0x47, 0x7d, 0xe4]; // 0fc63daf-8483-4772-8e79-3d69d8477de4 -pub const REDOX_FS_GUID: [u8; 16] = [0xfd, 0x98, 0x78, 0x52, 0xe3, 0xff, 0xc2, 0x42, 0xe3, 0x96, 0x10, 0x5b, 0xa6, 0x3f, 0x5a, 0xbf]; // 527898fd-ffe3-42c2-96e3-bf5a3fa65b10 - -#[repr(u32)] -pub enum PartitionProtoDataTy { - Other = 0, - Mbr = 1, - Gpt = 2, -} - -pub struct PartitionProto(pub &'static mut PartitionProtoData); - -impl Protocol for PartitionProto { - fn guid() -> uefi::guid::Guid { - uefi::guid::Guid(0x8cf2f62c, 0xbc9b, 0x4821, [0x80, 0x8d, 0xec, 0x9e, 0xc4, 0x21, 0xa1, 0xa0]) - } - fn new(inner: &'static mut PartitionProtoData) -> Self { - Self(inner) - } -} diff --git a/src/os/uefi/mod.rs b/src/os/uefi/mod.rs index 46bcd06347..1e5e220160 100644 --- a/src/os/uefi/mod.rs +++ b/src/os/uefi/mod.rs @@ -7,7 +7,6 @@ mod arch; mod disk; mod display; mod key; -pub mod null; pub mod text; fn set_max_mode(output: &uefi::text::TextOutput) -> Result<()> { diff --git a/src/os/uefi/null.rs b/src/os/uefi/null.rs deleted file mode 100644 index 1656d5576f..0000000000 --- a/src/os/uefi/null.rs +++ /dev/null @@ -1,128 +0,0 @@ -use core::mem; -use core::ops::Deref; -use std::boxed::Box; -use uefi::Handle; -use uefi::boot::InterfaceType; -use uefi::guid::SIMPLE_TEXT_OUTPUT_GUID; -use uefi::status::{Result, Status}; -use uefi::text::TextOutputMode; - -#[repr(C)] -#[allow(non_snake_case)] -pub struct NullDisplay { - pub Reset: extern "win64" fn(&mut NullDisplay, bool) -> Status, - pub OutputString: extern "win64" fn(&mut NullDisplay, *const u16) -> Status, - pub TestString: extern "win64" fn(&mut NullDisplay, *const u16) -> Status, - pub QueryMode: extern "win64" fn(&mut NullDisplay, usize, &mut usize, &mut usize) -> Status, - pub SetMode: extern "win64" fn(&mut NullDisplay, usize) -> Status, - pub SetAttribute: extern "win64" fn(&mut NullDisplay, usize) -> Status, - pub ClearScreen: extern "win64" fn(&mut NullDisplay) -> Status, - pub SetCursorPosition: extern "win64" fn(&mut NullDisplay, usize, usize) -> Status, - pub EnableCursor: extern "win64" fn(&mut NullDisplay, bool) -> Status, - pub Mode: &'static TextOutputMode, - - pub mode: Box, -} - -extern "win64" fn reset(_output: &mut NullDisplay, _extra: bool) -> Status { - Status(0) -} - -extern "win64" fn output_string(_output: &mut NullDisplay, _string: *const u16) -> Status { - Status(0) -} - -extern "win64" fn test_string(_output: &mut NullDisplay, _string: *const u16) -> Status { - Status(0) -} - -extern "win64" fn query_mode(_output: &mut NullDisplay, _mode: usize, columns: &mut usize, rows: &mut usize) -> Status { - *columns = 80; - *rows = 30; - Status(0) -} - -extern "win64" fn set_mode(_output: &mut NullDisplay, _mode: usize) -> Status { - Status(0) -} - -extern "win64" fn set_attribute(output: &mut NullDisplay, attribute: usize) -> Status { - output.mode.Attribute = attribute as i32; - Status(0) -} - -extern "win64" fn clear_screen(_output: &mut NullDisplay) -> Status { - Status(0) -} - -extern "win64" fn set_cursor_position(output: &mut NullDisplay, column: usize, row: usize) -> Status { - output.mode.CursorColumn = column as i32; - output.mode.CursorRow = row as i32; - Status(0) -} - -extern "win64" fn enable_cursor(output: &mut NullDisplay, enable: bool) -> Status { - output.mode.CursorVisible = enable; - Status(0) -} - -impl NullDisplay { - pub fn new() -> NullDisplay { - let mode = Box::new(TextOutputMode { - MaxMode: 0, - Mode: 0, - Attribute: 0, - CursorColumn: 0, - CursorRow: 0, - CursorVisible: false, - }); - - NullDisplay { - Reset: reset, - OutputString: output_string, - TestString: test_string, - QueryMode: query_mode, - SetMode: set_mode, - SetAttribute: set_attribute, - ClearScreen: clear_screen, - SetCursorPosition: set_cursor_position, - EnableCursor: enable_cursor, - Mode: unsafe { mem::transmute(&*mode.deref()) }, - - mode: mode - } - } - - pub fn pipe Result>(&mut self, mut f: F) -> Result { - let uefi = unsafe { std::system_table_mut() }; - - let stdout = self as *mut _; - let mut stdout_handle = Handle(0); - (uefi.BootServices.InstallProtocolInterface)(&mut stdout_handle, &SIMPLE_TEXT_OUTPUT_GUID, InterfaceType::Native, stdout as usize)?; - - let old_stdout_handle = uefi.ConsoleOutHandle; - let old_stdout = uefi.ConsoleOut as *mut _; - let old_stderr_handle = uefi.ConsoleErrorHandle; - let old_stderr = uefi.ConsoleError as *mut _; - - uefi.ConsoleOutHandle = stdout_handle; - uefi.ConsoleOut = unsafe { mem::transmute(&mut *stdout) }; - uefi.ConsoleErrorHandle = stdout_handle; - uefi.ConsoleError = unsafe { mem::transmute(&mut *stdout) }; - - let res = f(); - - uefi.ConsoleOutHandle = old_stdout_handle; - uefi.ConsoleOut = unsafe { mem::transmute(&mut *old_stdout) }; - uefi.ConsoleErrorHandle = old_stderr_handle; - uefi.ConsoleError = unsafe { mem::transmute(&mut *old_stderr) }; - - let _ = (uefi.BootServices.UninstallProtocolInterface)(stdout_handle, &SIMPLE_TEXT_OUTPUT_GUID, stdout as usize); - - res - } -} - -pub fn pipe Result>(f: F) -> Result { - NullDisplay::new().pipe(f) -}