diff --git a/kernel-rs/src/acpi/mod.rs b/kernel-rs/src/acpi/mod.rs index de7a7358..35b9f2f0 100644 --- a/kernel-rs/src/acpi/mod.rs +++ b/kernel-rs/src/acpi/mod.rs @@ -45,8 +45,7 @@ struct Acpi { } impl Acpi { - fn init(&mut self) -> Result <(), &'static str> { - self.v2 = rsdp::init()?; + fn common_init(&mut self) -> Result <(), &'static str> { if self.v2 { // Xsdt Address: // 64-bit physical address of the XSDT table. If you detect ACPI Version 2.0 you should use this table instead of RSDT even on x86, casting the address to uint32_t. @@ -59,6 +58,15 @@ impl Acpi { dsdt::init(fadt::dsdtaddr()?)?; self.valid = true; Ok(()) + + } + fn init(&mut self) -> Result <(), &'static str> { + self.v2 = rsdp::init()?; + self.common_init() + } + fn load(&mut self, rsdp_addr: u32) -> Result <(), &'static str> { + self.v2 = rsdp::load(rsdp_addr)?; + self.common_init() } } @@ -131,6 +139,14 @@ pub fn init() -> Result <(), &'static str> { unsafe {ACPI.init()} } +/// Load the ACPI module, addr given is a ptr to RSDP +pub fn load(rsdp_addr: u32) -> Result <(), &'static str> { + if let Ok(()) = is_init() { + return Ok(()); + } + unsafe {ACPI.load(rsdp_addr)} +} + /// Proceed to ACPI shutdown /// This function doesn't work with Virtual Box yet pub fn shutdown() -> Result <(), &'static str> { diff --git a/kernel-rs/src/acpi/rsdp.rs b/kernel-rs/src/acpi/rsdp.rs index 5d1e2dc8..02ff4914 100644 --- a/kernel-rs/src/acpi/rsdp.rs +++ b/kernel-rs/src/acpi/rsdp.rs @@ -33,25 +33,20 @@ pub fn load(addr: u32) -> Result { let revision = rsdp_tmp.rsdp.revision; if (revision == 0 && check_checksum(addr, mem::size_of::())) || (revision == 2 && check_checksum(addr, mem::size_of::())) { unsafe {RSDPTR = Some(rsdp_tmp)}; - println!("Found rsdptr at {:#x}", addr); return Ok(revision == 2); } } Err("Not a valid RSD ptr") } -fn memory_finding(bound: u32) -> Result { +fn memory_finding() -> Result { let mut i = 0; while i < 0x1000000 { - i += bound; + i += 8; if let Ok(result) = load(i) { return Ok(result) } } - // HACK because RSDP is not always aligned on 16 bytes boundary with QEMU - if bound > 1 { - return memory_finding(bound / 2); - } Err("Can not find Root System Description Pointer (RSDP).") } @@ -84,5 +79,5 @@ pub fn rsdtaddr() -> Result { /// if you already know the location, you should prefer to use load function /// return an Error if there is no RSDP in memory, or return the value of load function pub fn init() -> Result { - memory_finding(16) + memory_finding() } diff --git a/kernel-rs/src/arch/x86/boot.asm b/kernel-rs/src/arch/x86/boot.asm index 8e6f56da..1be8474b 100644 --- a/kernel-rs/src/arch/x86/boot.asm +++ b/kernel-rs/src/arch/x86/boot.asm @@ -122,7 +122,7 @@ GDTR: DW 0xffff ; Limit ( bits 0 -15 ) DW 0x0 ; Base ( bits 0 -15 ) DB 0x0 ; Base ( bits 16 -23 ) - DB 0xFE ; [ Access Flags: 0x9A=11111110b = (present)|(Privilege Ring 3=11b)|(1)|(code => 1)|(expand up => 1)|(readable)|(0) ] + DB 0xFE ; [ Access Flags: 0xFE=11111110b = (present)|(Privilege Ring 3=11b)|(1)|(code => 1)|(expand up => 1)|(readable)|(0) ] DB 0xCF ; [ Flags: C=1100b = (granularity)|(32bit)|(!64bit)|(0) ] / [ Limits: (bits 16-19): F=1111b ] DB 0x0 ; Base ( bits 24 -31 ) @@ -130,7 +130,7 @@ GDTR: DW 0xffff ; Limit ( bits 0 -15 ) DW 0x0 ; Base ( bits 0 -15 ) DB 0x0 ; Base ( bits 16 -23 ) - DB 0xF2 ; [ Access Flags: 0x9A=11110010b = (present)|(Privilege Ring 3=11b)|(1)|(data => 0)|(expand down => 0)|(readable)|(0) ] + DB 0xF2 ; [ Access Flags: 0xF2=11110010b = (present)|(Privilege Ring 3=11b)|(1)|(data => 0)|(expand down => 0)|(readable)|(0) ] DB 0xCF ; [ Flags: C=1100b = (granularity)|(32bit)|(!64bit)|(0) ] / [ Limits: (bits 16-19): F=1111b ] DB 0x0 ; Base ( bits 24 -31 ) @@ -138,8 +138,8 @@ GDTR: DW 0x0 ; Limit ( bits 0 -15 ) DW 0x0 ; Base ( bits 0 -15 ) DB 0x0 ; Base ( bits 16 -23 ) - DB 0x00 ; [ Access Flags: 0x9A=11110110b = (present)|(Privilege Ring 3=11b)|(1)|(data => 0)|(expand up => 1)|(readable)|(0) ] - DB 0x00 ; [ Flags: C=1100b = (granularity)|(32bit)|(!64bit)|(0) ] / [ Limits: (bits 16-19): F=1111b ] + DB 0xF6 ; [ Access Flags: 0xF2=11110110b = (present)|(Privilege Ring 3=11b)|(1)|(data => 0)|(expand up => 1)|(readable)|(0) ] + DB 0xCF ; [ Flags: C=1100b = (granularity)|(32bit)|(!64bit)|(0) ] / [ Limits: (bits 16-19): F=1111b ] DB 0x0 ; Base ( bits 24 -31 ) .gdt_bottom: diff --git a/kernel-rs/src/console.rs b/kernel-rs/src/console.rs index 91f046dd..bf8bc88e 100644 --- a/kernel-rs/src/console.rs +++ b/kernel-rs/src/console.rs @@ -40,15 +40,16 @@ pub fn exec(cli: &Writer) -> Result <(), &'static str> { } fn help() -> Result <(), &'static str> { - print!("{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n", - "acpi => Return acpi state (ENABLED|DISABLE)", - "help | h => Print this help", - "memory => print memory areas", // TODO - "multiboot => print multiboot information", // TODO - "reboot => reboot", - "sections => print elf sections", // TODO - "shutdown | halt | q => Kill a kitten, then shutdown", - "stack => Print kernel stack in a fancy way"); + println!("acpi => Return acpi state (ENABLED|DISABLE)"); + println!("help | h => Print this help"); + // println!("memory => Print memory areas"); + // println!("multiboot => Print multiboot information"); + println!("reboot => Reboot"); + // println!("sections => Print elf sections"); + println!("shutdown | halt | q => Kill a kitten, then shutdown"); + println!("stack => Print kernel stack in a fancy way"); + println!("regs => Print controle register"); + flush!(); Ok(()) } diff --git a/kernel-rs/src/lib.rs b/kernel-rs/src/lib.rs index 69020f85..65b0d353 100644 --- a/kernel-rs/src/lib.rs +++ b/kernel-rs/src/lib.rs @@ -29,16 +29,37 @@ pub mod memory; /// a few x86 register and instruction wrappers pub mod x86; -#[no_mangle] -pub extern fn kmain(multiboot_info_addr: usize) -> ! { - acpi::init().unwrap(); - - let boot_info = unsafe { multiboot2::load(multiboot_info_addr) }; +fn init_kernel(multiboot_info_addr: usize) -> Result <(), &'static str> { + let boot_info = unsafe { multiboot2::load(multiboot_info_addr)}; + if let Some(rsdp) = boot_info.rsdp_v2_tag() { + acpi::load(rsdp)?; + } else if let Some(rsdp) = boot_info.rsdp_tag() { + acpi::load(rsdp)?; + } + else { + acpi::init()?; + } enable_paging(); enable_write_protect_bit(); - memory::init(&boot_info); vga::init(); + Ok(()) +} + +fn enable_paging() { + unsafe { x86::cr0_write(x86::cr0() | (1 << 31)) }; +} + +fn enable_write_protect_bit() { + unsafe { x86::cr0_write(x86::cr0() | (1 << 16)) }; +} + +#[no_mangle] +pub extern fn kmain(multiboot_info_addr: usize) -> ! { + if let Err(msg) = init_kernel(multiboot_info_addr) { + println!("Kernel initialization has failed: {}", msg); + cpuio::halt(); + } use alloc::boxed::Box; let mut heap_test = Box::new(42); @@ -55,14 +76,6 @@ pub extern fn kmain(multiboot_info_addr: usize) -> ! { loop { keyboard::kbd_callback(); } } -fn enable_paging() { - unsafe { x86::cr0_write(x86::cr0() | (1 << 31)) }; -} - -fn enable_write_protect_bit() { - unsafe { x86::cr0_write(x86::cr0() | (1 << 16)) }; -} - #[lang = "eh_personality"] #[no_mangle] pub extern fn eh_personality() { diff --git a/kernel-rs/src/vga/mod.rs b/kernel-rs/src/vga/mod.rs index 45227206..26013c44 100644 --- a/kernel-rs/src/vga/mod.rs +++ b/kernel-rs/src/vga/mod.rs @@ -123,7 +123,6 @@ impl Writer { self.buffer[i] = b' '; self.buffer[i + 1] = 0; self.flush(); - // flush!(); } pub fn write_byte(&mut self, byte: u8) {