From c7cc51427b95c8048cd10f02e0b5cbda20c59a80 Mon Sep 17 00:00:00 2001 From: Arthur Beck Date: Sat, 18 Jan 2025 20:57:32 -0600 Subject: [PATCH] Progress on implementing multiboot; Realized there are issues with current implementation of aphrodite::multiboot2::Modules, thinking of fix. --- emulation/bochs | 1 + kernel/src/include/multiboot2.rs | 11 ++--- kernel/src/internal/arch/x86/entry.rs | 69 +++++++++++++++++++++++++-- 3 files changed, 71 insertions(+), 10 deletions(-) create mode 160000 emulation/bochs diff --git a/emulation/bochs b/emulation/bochs new file mode 160000 index 0000000..fd6f101 --- /dev/null +++ b/emulation/bochs @@ -0,0 +1 @@ +Subproject commit fd6f101699b11129be91c1ac8cb67bebb65a5c9b diff --git a/kernel/src/include/multiboot2.rs b/kernel/src/include/multiboot2.rs index 8a163ac..3cd9200 100644 --- a/kernel/src/include/multiboot2.rs +++ b/kernel/src/include/multiboot2.rs @@ -34,9 +34,7 @@ pub struct Tag { /// The type of the tag. pub tag_type: u32, /// The length of the tag. - pub tag_len: u32, - /// A pointer to after [tag_len](Tag::tag_len). This is where most type-specific data is. - pub data_ptr: *const u8 + pub tag_len: u32 } /// The root tag. The official Multiboot2 name is literally the "fixed part" of the tags, so I made a better name. @@ -49,8 +47,6 @@ pub struct RootTag { pub total_len: u32, /// Reserved space. Unused for anything. reserved: u32, - /// A pointer to right after the reserved space. Should be a pointer to the next tag. - pub tag_ptr: *const u8 } /// A Multiboot2 module. See https://github.com/AverseABFun/aphrodite/wiki/Plan/#Bootloader-modules (remember to update link later!). @@ -220,10 +216,13 @@ pub struct BootInfo { // VBE table is ignored for a similar reason to above: it's deprecated. Good luck if you need it. + /// Provides information on the framebuffer. pub framebuffer_info: Option, // Even though SMBIOS is documented for Multiboot2, we're not using it and will instead search for it ourselves. // This is because right now I cannot figure out what format it provides the SMBIOS table in. - + // EFI memory map and image handle pointers are not included for portability. + + // "Image load base physical address" is not included as at the moment the kernel is not relocatable. } \ No newline at end of file diff --git a/kernel/src/internal/arch/x86/entry.rs b/kernel/src/internal/arch/x86/entry.rs index 8c93576..28c9f7b 100644 --- a/kernel/src/internal/arch/x86/entry.rs +++ b/kernel/src/internal/arch/x86/entry.rs @@ -3,8 +3,8 @@ #![no_main] #![warn(missing_docs)] -use core::{arch::asm, hint::unreachable_unchecked, panic::PanicInfo}; -use aphrodite::multiboot2::{BootInfo, RootTag, Tag}; +use core::{arch::asm, ffi::CStr, hint::unreachable_unchecked, panic::PanicInfo}; +use aphrodite::multiboot2::{BootInfo, CString, RootTag, Tag}; #[unsafe(link_section = ".multiboot2")] static MULTIBOOT_HEADER: [u16; 14] = [ @@ -20,9 +20,23 @@ static MULTIBOOT_HEADER: [u16; 14] = [ 0x0000, 0x0000, ]; +// The root tag, provided directly from the multiboot bootloader. static mut RT: *const RootTag = core::ptr::null(); -static mut BI: *const BootInfo = core::ptr::null(); +// The boot info struct, created from all of the tags. +static mut BI: BootInfo = BootInfo { + mem_lower: None, + mem_upper: None, + cmdline: None, + modules: None, + memory_map: None, + bootloader_name: None, + framebuffer_info: None +}; + +// The raw pointer to bootloader-specific data. static mut O: *const u8 = core::ptr::null(); + +// The magic number in eax. 0x36D76289 for multiboot2. static mut MAGIC: u32 = 0xFFFFFFFF; #[unsafe(link_section = ".start")] @@ -38,10 +52,57 @@ extern "C" fn _start() -> ! { } unsafe { match MAGIC { - 0x36d76289 => { // Multiboot2 + 0x36D76289 => { // Multiboot2 RT = O as *const RootTag; // This is unsafe rust! We can do whatever we want! *manical laughter* + let mut ptr = O as usize; + ptr += size_of::(); + let mut current_tag = ptr as *const Tag; + + loop { + match (*current_tag).tag_type { + 0 => { // Ending tag + if (*current_tag).tag_len != 8 { // Unexpected size, something is probably up + panic!("Size of ending tag != 8"); + } + break + }, + 4 => { // Basic memory information + if (*current_tag).tag_len != 16 { // Unexpected size, something is probably up + panic!("Size of basic memory information tag != 16"); + } + + BI.mem_lower = Some(*((current_tag as usize + 8) as *const u32)); + BI.mem_upper = Some(*((current_tag as usize + 12) as *const u32)); + // The end result of the above is adding an offset to a pointer and retrieving the value at that pointer + + current_tag = (current_tag as usize + 16) as *const Tag; + }, + 1 => { // Command line + if (*current_tag).tag_len < 8 { // Unexpected size, something is probably up + panic!("Size of command line tag < 8"); + } + let cstring = CStr::from_ptr((current_tag as usize + 8) as *const i8); + // creates a &core::ffi::CStr from the start of the command line... + + let cstring = CString { + ptr: cstring.as_ptr() as *const u8, + len: cstring.to_bytes().len() + }; + // ...which can then be converted to a aphrodite::multiboot2::CString... + + current_tag = (current_tag as usize + 8 + cstring.len) as *const Tag; + // ...before the current_tag is incremented to prevent ownership issues... + + BI.cmdline = Some(cstring); + // ...before lastly the BootInfo's commandline is set. + }, + _ => { // Unknown tag type + todo!("Implement tag"); + } + } + } }, _ => { // Unknown bootloader, triple fault asm!(