From a0ad3689f31bc90ebefe116b74bba7845386af8e Mon Sep 17 00:00:00 2001 From: Jack Halford Date: Mon, 9 Apr 2018 13:33:16 +0200 Subject: [PATCH] code doesnt work anymore but i'm commiting anyway, shoot me --- kernel-rs/Cargo.toml | 10 +- kernel-rs/src/acpi/dsdt.rs | 56 +-- kernel-rs/src/acpi/fadt.rs | 80 ++--- kernel-rs/src/acpi/mod.rs | 63 ++-- kernel-rs/src/acpi/rsdp.rs | 30 +- kernel-rs/src/acpi/rsdt.rs | 10 +- kernel-rs/src/acpi/xsdt.rs | 10 +- kernel-rs/src/allocator/mod.rs | 6 +- kernel-rs/src/arch/x86/device/cpu.rs | 318 +++++++++++++----- kernel-rs/src/arch/x86/device/local_apic.rs | 6 +- kernel-rs/src/arch/x86/device/mod.rs | 2 +- kernel-rs/src/arch/x86/device/pic.rs | 57 ++-- kernel-rs/src/arch/x86/gdt.rs | 12 +- kernel-rs/src/arch/x86/interrupt/exception.rs | 7 +- kernel-rs/src/arch/x86/interrupt/mod.rs | 6 +- kernel-rs/src/arch/x86/mod.rs | 20 +- kernel-rs/src/arch/x86/paging/mapper.rs | 17 +- kernel-rs/src/arch/x86/paging/mod.rs | 115 ++++--- kernel-rs/src/arch/x86/paging/table.rs | 31 +- .../src/arch/x86/paging/temporary_page.rs | 40 +-- kernel-rs/src/arch/x86/pti.rs | 16 +- kernel-rs/src/console.rs | 46 +-- kernel-rs/src/cpuio.rs | 22 +- kernel-rs/src/io/mod.rs | 8 +- kernel-rs/src/keyboard.rs | 27 +- kernel-rs/src/lib.rs | 30 +- kernel-rs/src/memory/bump.rs | 69 ++-- kernel-rs/src/memory/mod.rs | 21 +- kernel-rs/src/memory/recycle.rs | 4 +- kernel-rs/src/vga/mod.rs | 62 ++-- 30 files changed, 725 insertions(+), 476 deletions(-) diff --git a/kernel-rs/Cargo.toml b/kernel-rs/Cargo.toml index d2b8779f..efc5451c 100644 --- a/kernel-rs/Cargo.toml +++ b/kernel-rs/Cargo.toml @@ -13,12 +13,12 @@ spin = "0.4" slab_allocator = "0.3.1" multiboot2 = { path = "multiboot2-elf64" } # added rsdp tag x86 = { path = "x86" } # forked for IA32 -raw-cpuid = { path = "rust-cpuid" } +# raw-cpuid = { path = "rust-cpuid" } -# [dependencies.raw-cpuid] -# # need to use github/master because of features not yet on crates.io -# git = "https://github.com/gz/rust-cpuid" -# features = ["nightly"] +[dependencies.raw-cpuid] +# need to use github/master because of features not yet on crates.io +git = "https://github.com/gz/rust-cpuid" +features = ["nightly"] [dependencies.lazy_static] version = "1.0.0" diff --git a/kernel-rs/src/acpi/dsdt.rs b/kernel-rs/src/acpi/dsdt.rs index aa3456e2..32309cf1 100644 --- a/kernel-rs/src/acpi/dsdt.rs +++ b/kernel-rs/src/acpi/dsdt.rs @@ -1,4 +1,4 @@ -use super::{check_signature,ACPISDTHeader}; +use super::{check_signature, ACPISDTHeader}; use core::mem; use cpuio; @@ -7,7 +7,7 @@ static mut DSDT: DSDT = DSDT { dsdt: None, s5_ptr: 0, slp_typ_a: 0, - slp_typ_b: 0 + slp_typ_b: 0, }; struct DSDT { @@ -15,24 +15,26 @@ struct DSDT { dsdt: Option<&'static ACPISDTHeader>, s5_ptr: u32, slp_typ_a: u16, - slp_typ_b: u16 + slp_typ_b: u16, } impl DSDT { - fn init(&mut self, addr: u32) -> Result <(), &'static str> { - self.dsdt = Some(unsafe{ &(*(addr as *const ACPISDTHeader)) }); + fn init(&mut self, addr: u32) -> Result<(), &'static str> { + self.dsdt = Some(unsafe { &(*(addr as *const ACPISDTHeader)) }); self.s5_ptr = self.find_s5(addr)?; self.parse_s5(); self.valid = true; Ok(()) } - fn find_s5(&self, addr: u32) -> Result { + fn find_s5(&self, addr: u32) -> Result { let dsdt_start = addr + mem::size_of::() as u32; let dsdt_end = dsdt_start + self.dsdt.unwrap().length; for addr in dsdt_start..dsdt_end { if check_signature(addr, "_S5_") { - if (check_signature(addr - 1, "\x08") || check_signature(addr - 2, "\x08\\")) && check_signature(addr + 4, "\x12") { + if (check_signature(addr - 1, "\x08") || check_signature(addr - 2, "\x08\\")) + && check_signature(addr + 4, "\x12") + { return Ok(addr); } } @@ -42,43 +44,51 @@ impl DSDT { fn parse_s5(&mut self) { let ptr = self.s5_ptr + 5; - let ptr = ((unsafe{*(ptr as *const u8)} & 0xC0) >> 6) + 2; - let ptr = if unsafe{*(ptr as *const u8)} == 0x0A { ptr + 1 } else { ptr };// Skip bytePrefix - self.slp_typ_a = (unsafe {*(ptr as *const u8)} as u16) << 10; + let ptr = ((unsafe { *(ptr as *const u8) } & 0xC0) >> 6) + 2; + let ptr = if unsafe { *(ptr as *const u8) } == 0x0A { + ptr + 1 + } else { + ptr + }; // Skip bytePrefix + self.slp_typ_a = (unsafe { *(ptr as *const u8) } as u16) << 10; let ptr = ptr + 1; - let ptr = if unsafe{*(ptr as *const u8)} == 0x0A { ptr + 1 } else { ptr };// Skip bytePrefix - self.slp_typ_b = (unsafe {*(ptr as *const u8)} as u16) << 10; + let ptr = if unsafe { *(ptr as *const u8) } == 0x0A { + ptr + 1 + } else { + ptr + }; // Skip bytePrefix + self.slp_typ_b = (unsafe { *(ptr as *const u8) } as u16) << 10; } } -fn is_init() -> Result <(), &'static str> { - match unsafe {DSDT.valid} { +fn is_init() -> Result<(), &'static str> { + match unsafe { DSDT.valid } { true => Ok(()), - false => match unsafe {DSDT.dsdt} { + false => match unsafe { DSDT.dsdt } { Some(_) => Err("Differentiated System Description Pointer (DSDP) is not valid"), - None => Err("Differentiated System Description Pointer (DSDP) is not initialized") - } + None => Err("Differentiated System Description Pointer (DSDP) is not initialized"), + }, } } /// ## Initialize Differentiated System Description Table (DSDT) /// input param addr is contain in FADT -pub fn init(addr: u32) -> Result <(), &'static str> { +pub fn init(addr: u32) -> Result<(), &'static str> { if ACPISDTHeader::valid(addr, "DSDT") { - return unsafe {DSDT.init(addr)}; + return unsafe { DSDT.init(addr) }; } return Err("Can not find Differentiated System Description Table (DSDT)."); } /// NOT COMPATIBLE WITH VIRTUALBOX /// Send shutdown signal -/// outw(PM1a_CNT_BLK, SLP_TYPx | SLP_EN) -pub fn shutdown(pm1_cnt: [u16; 2]) -> Result <(), &'static str> { +/// outw(PM1a_CNT_BLK, SLP_TYPx | SLP_EN) +pub fn shutdown(pm1_cnt: [u16; 2]) -> Result<(), &'static str> { is_init()?; - let slp_typ = unsafe{ DSDT.slp_typ_a } | (1 << 13); + let slp_typ = unsafe { DSDT.slp_typ_a } | (1 << 13); cpuio::outw(pm1_cnt[0], slp_typ); if pm1_cnt[1] != 0 { - let slp_typ = unsafe{ DSDT.slp_typ_b } | (1 << 13); + let slp_typ = unsafe { DSDT.slp_typ_b } | (1 << 13); cpuio::outw(pm1_cnt[1], slp_typ); } Ok(()) diff --git a/kernel-rs/src/acpi/fadt.rs b/kernel-rs/src/acpi/fadt.rs index ed5da011..edbdcbd2 100644 --- a/kernel-rs/src/acpi/fadt.rs +++ b/kernel-rs/src/acpi/fadt.rs @@ -1,4 +1,4 @@ -use super::{ACPISDTHeader,ACPISDTIter}; +use super::{ACPISDTHeader, ACPISDTIter}; use cpuio; #[repr(C)] @@ -9,13 +9,12 @@ struct GenericAddressStructure { bitoffset: u8, accesssize: u8, noused: u32, - address: u64 + address: u64, } #[repr(C)] #[derive(Debug, Clone)] -struct FADT -{ +struct FADT { header: ACPISDTHeader, firmwarectrl: u32, dsdt: u32, @@ -28,33 +27,33 @@ struct FADT smi_commandport: u32, acpi_enable: u8, acpidisable: u8, - s4bios_req: u8, //no use - pstate_control: u8, //no use + s4bios_req: u8, //no use + pstate_control: u8, //no use pm1aeventblock: u32, //no use pm1beventblock: u32, //no use pm1acontrolblock: u32, pm1bcontrolblock: u32, pm2controlblock: u32, //no use - pmtimerblock: u32, //no use - gpe0block: u32, //no use - gpe1block: u32, //no use - pm1eventlength: u8, //no use + pmtimerblock: u32, //no use + gpe0block: u32, //no use + gpe1block: u32, //no use + pm1eventlength: u8, //no use pm1controllength: u8, pm2controllength: u8, //no use - pmtimerlength: u8, //no use - gpe0length: u8, //no use - gpe1length: u8, //no use - gpe1base: u8, //no use - cstatecontrol: u8, //no use - worstc2latency: u16, //no use - worstc3latency: u16, //no use - flushsize: u16, //no use - flushstride: u16, //no use - dutyoffset: u8, //no use - dutywidth: u8, //no use - dayalarm: u8, //no use - monthalarm: u8, //no use - century: u8, //no use + pmtimerlength: u8, //no use + gpe0length: u8, //no use + gpe1length: u8, //no use + gpe1base: u8, //no use + cstatecontrol: u8, //no use + worstc2latency: u16, //no use + worstc3latency: u16, //no use + flushsize: u16, //no use + flushstride: u16, //no use + dutyoffset: u8, //no use + dutywidth: u8, //no use + dayalarm: u8, //no use + monthalarm: u8, //no use + century: u8, //no use // reserved in acpi 1.0; used since acpi 2.0+ bootarchitectureflags: u16, @@ -80,19 +79,20 @@ struct FADT x_pmtimerblock: GenericAddressStructure, x_gpe0block: GenericAddressStructure, x_gpe1block: GenericAddressStructure, - } static mut FADT: Option = None; /// ## Initialize Fixed ACPI Description Table (FADT) /// input param addr is contain in other ptr of rsdt -pub fn init(sdt_iter: ACPISDTIter) -> Result <(), &'static str> { +pub fn init(sdt_iter: ACPISDTIter) -> Result<(), &'static str> { for sdt_ptr in sdt_iter { - if ACPISDTHeader::valid(sdt_ptr, "FACP") { // Where is "FADT"? Shut up is magic - let fadt_tmp: FADT = unsafe{ (*(sdt_ptr as *const FADT)).clone() }; - unsafe {FADT = Some(fadt_tmp.clone())}; - if !is_enable()? { // TODO do i have to check if enabled before init ??? + if ACPISDTHeader::valid(sdt_ptr, "FACP") { + // Where is "FADT"? Shut up is magic + let fadt_tmp: FADT = unsafe { (*(sdt_ptr as *const FADT)).clone() }; + unsafe { FADT = Some(fadt_tmp.clone()) }; + if !is_enable()? { + // TODO do i have to check if enabled before init ??? let smi_cmd = fadt_tmp.smi_commandport as u16; // TODO WHY DO I NEED THIS FUCKING CAST let acpi_enable = fadt_tmp.acpi_enable; cpuio::outb(smi_cmd, acpi_enable); // send acpi enable command @@ -103,16 +103,16 @@ pub fn init(sdt_iter: ACPISDTIter) -> Result <(), &'static str> { return Err("Can not find Fixed ACPI Description Table (FADT)."); } -fn is_init() -> Result { - match unsafe {FADT.clone()} { - Some(fadt) => Ok(fadt), - None => Err("Fixed ACPI Description Table (FADT) is not initialized") +fn is_init() -> Result { + match unsafe { FADT.clone() } { + Some(fadt) => Ok(fadt), + None => Err("Fixed ACPI Description Table (FADT) is not initialized"), } } /// Return Dsdt address /// FADT must have been initialized first -pub fn dsdtaddr() -> Result { +pub fn dsdtaddr() -> Result { let fadt = is_init()?; return Ok(fadt.dsdt); } @@ -122,7 +122,7 @@ fn get_cnt(fadt: FADT) -> [u16; 2] { } /// Return true/false depending of acpi is enable -pub fn is_enable() -> Result { +pub fn is_enable() -> Result { let fadt = is_init()?; let pm1_cnt = get_cnt(fadt); if pm1_cnt[1] == 0 { @@ -134,13 +134,13 @@ pub fn is_enable() -> Result { /// Return a array with [pm1a, pm1b] /// FADT must have been initialized first -pub fn get_controlblock() -> Result <[u16; 2], &'static str> { +pub fn get_controlblock() -> Result<[u16; 2], &'static str> { if !is_enable()? { Err("ACPI is not enabled") } else { - // println!("HALT"); - // flush!(); - // cpuio::halt(); + // println!("HALT"); + // flush!(); + // cpuio::halt(); Ok(get_cnt(is_init()?)) // TODO redondant call to is_init } } diff --git a/kernel-rs/src/acpi/mod.rs b/kernel-rs/src/acpi/mod.rs index 35b9f2f0..3b0544a8 100644 --- a/kernel-rs/src/acpi/mod.rs +++ b/kernel-rs/src/acpi/mod.rs @@ -26,7 +26,7 @@ impl ACPISDTHeader { pub fn valid(addr: u32, signature: &str) -> bool { if check_signature(addr, signature) { let ptr_tmp = addr as *const ACPISDTHeader; - if check_checksum(addr, unsafe {(*ptr_tmp).length} as usize) { + if check_checksum(addr, unsafe { (*ptr_tmp).length } as usize) { return true; } } @@ -36,16 +36,16 @@ impl ACPISDTHeader { static mut ACPI: Acpi = Acpi { valid: false, - v2: false + v2: false, }; struct Acpi { valid: bool, - v2: bool + v2: bool, } impl Acpi { - fn common_init(&mut self) -> Result <(), &'static str> { + 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. @@ -58,20 +58,21 @@ impl Acpi { dsdt::init(fadt::dsdtaddr()?)?; self.valid = true; Ok(()) - } - fn init(&mut self) -> Result <(), &'static str> { + fn init(&mut self) -> Result<(), &'static str> { self.v2 = rsdp::init()?; self.common_init() } - fn load(&mut self, rsdp_addr: u32) -> Result <(), &'static str> { + fn load(&mut self, rsdp_addr: u32) -> Result<(), &'static str> { self.v2 = rsdp::load(rsdp_addr)?; self.common_init() } } fn check_signature(addr: u32, id: &str) -> bool { - let signature = match core::str::from_utf8(unsafe {core::slice::from_raw_parts_mut(addr as *mut u8, id.len())}) { + let signature = match core::str::from_utf8(unsafe { + core::slice::from_raw_parts_mut(addr as *mut u8, id.len()) + }) { Ok(y) => y, Err(_) => return false, }; @@ -79,7 +80,7 @@ fn check_signature(addr: u32, id: &str) -> bool { } fn check_checksum(addr: u32, len: usize) -> bool { - let byte_array = unsafe {core::slice::from_raw_parts_mut(addr as *mut u8, len)}; + let byte_array = unsafe { core::slice::from_raw_parts_mut(addr as *mut u8, len) }; let mut sum: u32 = 0; for byte in byte_array { sum += *byte as u32; @@ -91,19 +92,23 @@ pub struct ACPISDTIter { pos: usize, width: usize, sdt: u32, - len: usize + len: usize, } impl ACPISDTIter { - fn new(acpi_sdt: Option<*const ACPISDTHeader>, ptr_len: usize) -> Result { + fn new( + acpi_sdt: Option<*const ACPISDTHeader>, + ptr_len: usize, + ) -> Result { match acpi_sdt { - None => Err("There is no ACPI System Description Table (ACPISDTHeader) to iter on."), - Some(ptr) => Ok(ACPISDTIter { + None => Err("There is no ACPI System Description Table (ACPISDTHeader) to iter on."), + Some(ptr) => Ok(ACPISDTIter { pos: 0, width: ptr_len, sdt: ptr as u32 + mem::size_of::() as u32, - len: (unsafe {(*ptr).length} as usize - mem::size_of::()) / ptr_len - }) + len: (unsafe { (*ptr).length } as usize - mem::size_of::()) + / ptr_len, + }), } } } @@ -116,47 +121,53 @@ impl Iterator for ACPISDTIter { if self.pos > self.len { return None; } - let ret = Some(unsafe {*(self.sdt as *const u32)}); + let ret = Some(unsafe { *(self.sdt as *const u32) }); self.sdt += self.width as u32; return ret; } } -fn is_init() -> Result <(), &'static str> { - if unsafe {ACPI.valid} { +fn is_init() -> Result<(), &'static str> { + if unsafe { ACPI.valid } { Ok(()) } else { Err("ACPI is not initialized") } } - /// Initalized the ACPI module -pub fn init() -> Result <(), &'static str> { +pub fn init() -> Result<(), &'static str> { if let Ok(()) = is_init() { return Ok(()); } - unsafe {ACPI.init()} + unsafe { ACPI.init() } } /// Load the ACPI module, addr given is a ptr to RSDP -pub fn load(rsdp_addr: u32) -> Result <(), &'static str> { +pub fn load(rsdp_addr: u32) -> Result<(), &'static str> { if let Ok(()) = is_init() { return Ok(()); } - unsafe {ACPI.load(rsdp_addr)} + unsafe { ACPI.load(rsdp_addr) } } /// Proceed to ACPI shutdown /// This function doesn't work with Virtual Box yet -pub fn shutdown() -> Result <(), &'static str> { +pub fn shutdown() -> Result<(), &'static str> { is_init()?; dsdt::shutdown(fadt::get_controlblock()?) } /// Display state of ACPI -pub fn info() -> Result <(), &'static str> { +pub fn info() -> Result<(), &'static str> { is_init()?; - println!("ACPI STATE:\n {}", if fadt::is_enable()? {"ENABLED"} else {"DISABLED"}); + println!( + "ACPI STATE:\n {}", + if fadt::is_enable()? { + "ENABLED" + } else { + "DISABLED" + } + ); Ok(()) } diff --git a/kernel-rs/src/acpi/rsdp.rs b/kernel-rs/src/acpi/rsdp.rs index 02ff4914..028f1451 100644 --- a/kernel-rs/src/acpi/rsdp.rs +++ b/kernel-rs/src/acpi/rsdp.rs @@ -1,4 +1,4 @@ -use super::{check_signature,check_checksum}; +use super::{check_checksum, check_signature}; use core::mem; #[repr(C)] @@ -27,39 +27,41 @@ static mut RSDPTR: Option = None; /// Return a bool /// true => RSDP is V2 /// false => RSDP is V1 -pub fn load(addr: u32) -> Result { +pub fn load(addr: u32) -> Result { if check_signature(addr, "RSD PTR ") { - let rsdp_tmp: RSDP20 = unsafe{ (*(addr as *const RSDP20)).clone() }; + let rsdp_tmp: RSDP20 = unsafe { (*(addr as *const RSDP20)).clone() }; 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)}; + if (revision == 0 && check_checksum(addr, mem::size_of::())) + || (revision == 2 && check_checksum(addr, mem::size_of::())) + { + unsafe { RSDPTR = Some(rsdp_tmp) }; return Ok(revision == 2); } } Err("Not a valid RSD ptr") } -fn memory_finding() -> Result { +fn memory_finding() -> Result { let mut i = 0; while i < 0x1000000 { i += 8; if let Ok(result) = load(i) { - return Ok(result) + return Ok(result); } } Err("Can not find Root System Description Pointer (RSDP).") } -fn is_init() -> Result { - match unsafe {RSDPTR.clone()} { - Some(rsdptr) => Ok(rsdptr), - None => Err("Root System Description Pointer (RSDP) is not initialized") +fn is_init() -> Result { + match unsafe { RSDPTR.clone() } { + Some(rsdptr) => Ok(rsdptr), + None => Err("Root System Description Pointer (RSDP) is not initialized"), } } /// Return a ptr on xsdt /// RSDP must have been initialized first -pub fn xsdtaddr() -> Result { +pub fn xsdtaddr() -> Result { let rsdptr = is_init()?; let revision = rsdptr.rsdp.revision; if revision != 2 { @@ -70,7 +72,7 @@ pub fn xsdtaddr() -> Result { /// Return a ptr on rsdt /// RSDP must have been initialized first -pub fn rsdtaddr() -> Result { +pub fn rsdtaddr() -> Result { let rsdptr = is_init()?; return Ok(rsdptr.rsdp.rsdtaddr); } @@ -78,6 +80,6 @@ pub fn rsdtaddr() -> Result { /// RSDP init will iter on addr in [0x0 - 0x1000000] to find "RSDP PTR " /// 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 { +pub fn init() -> Result { memory_finding() } diff --git a/kernel-rs/src/acpi/rsdt.rs b/kernel-rs/src/acpi/rsdt.rs index dd2cb047..59ed0fb0 100644 --- a/kernel-rs/src/acpi/rsdt.rs +++ b/kernel-rs/src/acpi/rsdt.rs @@ -1,13 +1,13 @@ -use super::{ACPISDTHeader,ACPISDTIter}; +use super::{ACPISDTHeader, ACPISDTIter}; //TODO this can work only if pagging is disabled static mut RSDT: Option<*const ACPISDTHeader> = None; /// ## Initialize Root System Description Table (RSDT) /// input param addr is contain in RSDP -pub fn init(addr: u32) -> Result <(), &'static str> { +pub fn init(addr: u32) -> Result<(), &'static str> { if ACPISDTHeader::valid(addr, "RSDT") { - unsafe {RSDT = Some(addr as *const ACPISDTHeader)}; + unsafe { RSDT = Some(addr as *const ACPISDTHeader) }; return Ok(()); } return Err("Can not find Root System Description Table (RSDT)."); @@ -15,6 +15,6 @@ pub fn init(addr: u32) -> Result <(), &'static str> { /// Return a iterable of ptr contained in RSDT /// RSDT must have been initialized first -pub fn iter() -> Result { - ACPISDTIter::new(unsafe {RSDT}, 4) +pub fn iter() -> Result { + ACPISDTIter::new(unsafe { RSDT }, 4) } diff --git a/kernel-rs/src/acpi/xsdt.rs b/kernel-rs/src/acpi/xsdt.rs index 06ae29bd..eb05c1ae 100644 --- a/kernel-rs/src/acpi/xsdt.rs +++ b/kernel-rs/src/acpi/xsdt.rs @@ -1,15 +1,15 @@ -use super::{ACPISDTHeader,ACPISDTIter}; +use super::{ACPISDTHeader, ACPISDTIter}; //TODO this can work only if pagging is disabled static mut XSDT: Option<*const ACPISDTHeader> = None; /// ## Initialize Root System Description Table (XSDT) /// input param addr is contain in RSDP -pub fn init(addr: u64) -> Result <(), &'static str> { +pub fn init(addr: u64) -> Result<(), &'static str> { assert!((addr as u32) as u64 == addr); let addr: u32 = addr as u32; if ACPISDTHeader::valid(addr, "XSDT") { - unsafe {XSDT = Some(addr as *const ACPISDTHeader)}; + unsafe { XSDT = Some(addr as *const ACPISDTHeader) }; return Ok(()); } return Err("Can not find eXtended System Descriptor Table (XSDT)."); @@ -17,6 +17,6 @@ pub fn init(addr: u64) -> Result <(), &'static str> { /// Return a iterable of ptr contained in XSDT /// XSDT must have been initialized first -pub fn iter() -> Result { - ACPISDTIter::new(unsafe {XSDT}, 8) +pub fn iter() -> Result { + ACPISDTIter::new(unsafe { XSDT }, 8) } diff --git a/kernel-rs/src/allocator/mod.rs b/kernel-rs/src/allocator/mod.rs index 2a4ca765..9707bd8a 100644 --- a/kernel-rs/src/allocator/mod.rs +++ b/kernel-rs/src/allocator/mod.rs @@ -5,11 +5,9 @@ use x86::*; use x86::structures::paging::*; use arch::x86::paging::*; -fn map_heap(active_table: &mut ActivePageTable, offset: usize, size: usize) -{ +fn map_heap(active_table: &mut ActivePageTable, offset: usize, size: usize) { let heap_start_page = Page::containing_address(VirtAddr::new(offset as u32)); - let heap_end_page = Page::containing_address(VirtAddr::new( - offset as u32 + size as u32 - 1)); + let heap_end_page = Page::containing_address(VirtAddr::new(offset as u32 + size as u32 - 1)); for page in heap_start_page..heap_end_page + 1 { active_table.map(page, PageTableFlags::WRITABLE); diff --git a/kernel-rs/src/arch/x86/device/cpu.rs b/kernel-rs/src/arch/x86/device/cpu.rs index eaadb10b..35c56a7c 100644 --- a/kernel-rs/src/arch/x86/device/cpu.rs +++ b/kernel-rs/src/arch/x86/device/cpu.rs @@ -1,6 +1,6 @@ extern crate raw_cpuid; -use core::fmt::{Result}; +use core::fmt::Result; use self::raw_cpuid::CpuId; @@ -29,102 +29,260 @@ pub fn cpu_info() -> Result { if let Some(info) = cpuid.get_feature_info() { print!("Features:"); - if info.has_fpu() { print!(" fpu") }; - if info.has_vme() { print!(", vme") }; - if info.has_de() { print!(", de") }; - if info.has_pse() { print!(", pse") }; - if info.has_tsc() { print!(", tsc") }; - if info.has_msr() { print!(", msr") }; - if info.has_pae() { print!(", pae") }; - if info.has_mce() { print!(", mce") }; + if info.has_fpu() { + print!(" fpu") + }; + if info.has_vme() { + print!(", vme") + }; + if info.has_de() { + print!(", de") + }; + if info.has_pse() { + print!(", pse") + }; + if info.has_tsc() { + print!(", tsc") + }; + if info.has_msr() { + print!(", msr") + }; + if info.has_pae() { + print!(", pae") + }; + if info.has_mce() { + print!(", mce") + }; - if info.has_cmpxchg8b() { print!(", cx8") }; - if info.has_apic() { print!(", apic") }; - if info.has_sysenter_sysexit() { print!(", sep") }; - if info.has_mtrr() { print!(", mtrr") }; - if info.has_pge() { print!(", pge") }; - if info.has_mca() { print!(", mca") }; - if info.has_cmov() { print!(", cmov") }; - if info.has_pat() { print!(", pat") }; + if info.has_cmpxchg8b() { + print!(", cx8") + }; + if info.has_apic() { + print!(", apic") + }; + if info.has_sysenter_sysexit() { + print!(", sep") + }; + if info.has_mtrr() { + print!(", mtrr") + }; + if info.has_pge() { + print!(", pge") + }; + if info.has_mca() { + print!(", mca") + }; + if info.has_cmov() { + print!(", cmov") + }; + if info.has_pat() { + print!(", pat") + }; - if info.has_pse36() { print!(", pse36") }; - if info.has_psn() { print!(", psn") }; - if info.has_clflush() { print!(", clflush") }; - if info.has_ds() { print!(", ds") }; - if info.has_acpi() { print!(", acpi") }; - if info.has_mmx() { print!(", mmx") }; - if info.has_fxsave_fxstor() { print!(", fxsr") }; - if info.has_sse() { print!(", sse") }; + if info.has_pse36() { + print!(", pse36") + }; + if info.has_psn() { + print!(", psn") + }; + if info.has_clflush() { + print!(", clflush") + }; + if info.has_ds() { + print!(", ds") + }; + if info.has_acpi() { + print!(", acpi") + }; + if info.has_mmx() { + print!(", mmx") + }; + if info.has_fxsave_fxstor() { + print!(", fxsr") + }; + if info.has_sse() { + print!(", sse") + }; - if info.has_sse2() { print!(", sse2") }; - if info.has_ss() { print!(", ss") }; - if info.has_htt() { print!(", ht") }; - if info.has_tm() { print!(", tm") }; - if info.has_pbe() { print!(", pbe") }; + if info.has_sse2() { + print!(", sse2") + }; + if info.has_ss() { + print!(", ss") + }; + if info.has_htt() { + print!(", ht") + }; + if info.has_tm() { + print!(", tm") + }; + if info.has_pbe() { + print!(", pbe") + }; - if info.has_sse3() { print!(", sse3") }; - if info.has_pclmulqdq() { print!(", pclmulqdq") }; - if info.has_ds_area() { print!(", dtes64") }; - if info.has_monitor_mwait() { print!(", monitor") }; - if info.has_cpl() { print!(", ds_cpl") }; - if info.has_vmx() { print!(", vmx") }; - if info.has_smx() { print!(", smx") }; - if info.has_eist() { print!(", est") }; + if info.has_sse3() { + print!(", sse3") + }; + if info.has_pclmulqdq() { + print!(", pclmulqdq") + }; + if info.has_ds_area() { + print!(", dtes64") + }; + if info.has_monitor_mwait() { + print!(", monitor") + }; + if info.has_cpl() { + print!(", ds_cpl") + }; + if info.has_vmx() { + print!(", vmx") + }; + if info.has_smx() { + print!(", smx") + }; + if info.has_eist() { + print!(", est") + }; - if info.has_tm2() { print!(", tm2") }; - if info.has_ssse3() { print!(", ssse3") }; - if info.has_cnxtid() { print!(", cnxtid") }; - if info.has_fma() { print!(", fma") }; - if info.has_cmpxchg16b() { print!(", cx16") }; - if info.has_pdcm() { print!(", pdcm") }; - if info.has_pcid() { print!(", pcid") }; - if info.has_dca() { print!(", dca") }; + if info.has_tm2() { + print!(", tm2") + }; + if info.has_ssse3() { + print!(", ssse3") + }; + if info.has_cnxtid() { + print!(", cnxtid") + }; + if info.has_fma() { + print!(", fma") + }; + if info.has_cmpxchg16b() { + print!(", cx16") + }; + if info.has_pdcm() { + print!(", pdcm") + }; + if info.has_pcid() { + print!(", pcid") + }; + if info.has_dca() { + print!(", dca") + }; - if info.has_sse41() { print!(", sse4_1") }; - if info.has_sse42() { print!(", sse4_2") }; - if info.has_x2apic() { print!(", x2apic") }; - if info.has_movbe() { print!(", movbe") }; - if info.has_popcnt() { print!(", popcnt") }; - if info.has_tsc_deadline() { print!(", tsc_deadline_timer") }; - if info.has_aesni() { print!(", aes") }; - if info.has_xsave() { print!(", xsave") }; + if info.has_sse41() { + print!(", sse4_1") + }; + if info.has_sse42() { + print!(", sse4_2") + }; + if info.has_x2apic() { + print!(", x2apic") + }; + if info.has_movbe() { + print!(", movbe") + }; + if info.has_popcnt() { + print!(", popcnt") + }; + if info.has_tsc_deadline() { + print!(", tsc_deadline_timer") + }; + if info.has_aesni() { + print!(", aes") + }; + if info.has_xsave() { + print!(", xsave") + }; - if info.has_oxsave() { print!(", xsaveopt") }; - if info.has_avx() { print!(", avx") }; - if info.has_f16c() { print!(", f16c") }; - if info.has_rdrand() { print!(", rdrand") }; + if info.has_oxsave() { + print!(", xsaveopt") + }; + if info.has_avx() { + print!(", avx") + }; + if info.has_f16c() { + print!(", f16c") + }; + if info.has_rdrand() { + print!(", rdrand") + }; println!(""); } if let Some(info) = cpuid.get_extended_function_info() { print!("Extended function:"); - if info.has_64bit_mode() { print!(" lm") }; - if info.has_rdtscp() { print!(", rdtscp") }; - if info.has_1gib_pages() { print!(", pdpe1gb") }; - if info.has_execute_disable() { print!(", nx") }; - if info.has_syscall_sysret() { print!(", syscall") }; - if info.has_prefetchw() { print!(", prefetchw") }; - if info.has_lzcnt() { print!(", lzcnt") }; - if info.has_lahf_sahf() { print!(", lahf_lm") }; - if info.has_invariant_tsc() { print!(", constant_tsc") }; + if info.has_64bit_mode() { + print!(" lm") + }; + if info.has_rdtscp() { + print!(", rdtscp") + }; + if info.has_1gib_pages() { + print!(", pdpe1gb") + }; + if info.has_execute_disable() { + print!(", nx") + }; + if info.has_syscall_sysret() { + print!(", syscall") + }; + if info.has_prefetchw() { + print!(", prefetchw") + }; + if info.has_lzcnt() { + print!(", lzcnt") + }; + if info.has_lahf_sahf() { + print!(", lahf_lm") + }; + if info.has_invariant_tsc() { + print!(", constant_tsc") + }; println!(""); } if let Some(info) = cpuid.get_extended_feature_info() { print!("Extended features:"); - if info.has_fsgsbase() { print!(" fsgsbase") }; - if info.has_tsc_adjust_msr() { print!(", tsc_adjust") }; - if info.has_bmi1() { print!(", bmi1") }; - if info.has_hle() { print!(", hle") }; - if info.has_avx2() { print!(", avx2") }; - if info.has_smep() { print!(", smep") }; - if info.has_bmi2() { print!(", bmi2") }; - if info.has_rep_movsb_stosb() { print!(", erms") }; - if info.has_invpcid() { print!(", invpcid") }; - if info.has_rtm() { print!(", rtm") }; - if info.has_qm() { print!(", qm") }; - if info.has_fpu_cs_ds_deprecated() { print!(", fpu_seg") }; - if info.has_mpx() { print!(", mpx") }; + if info.has_fsgsbase() { + print!(" fsgsbase") + }; + if info.has_tsc_adjust_msr() { + print!(", tsc_adjust") + }; + if info.has_bmi1() { + print!(", bmi1") + }; + if info.has_hle() { + print!(", hle") + }; + if info.has_avx2() { + print!(", avx2") + }; + if info.has_smep() { + print!(", smep") + }; + if info.has_bmi2() { + print!(", bmi2") + }; + if info.has_rep_movsb_stosb() { + print!(", erms") + }; + if info.has_invpcid() { + print!(", invpcid") + }; + if info.has_rtm() { + print!(", rtm") + }; + if info.has_qm() { + print!(", qm") + }; + if info.has_fpu_cs_ds_deprecated() { + print!(", fpu_seg") + }; + if info.has_mpx() { + print!(", mpx") + }; println!(""); } diff --git a/kernel-rs/src/arch/x86/device/local_apic.rs b/kernel-rs/src/arch/x86/device/local_apic.rs index 3a4e79c6..058be3fd 100644 --- a/kernel-rs/src/arch/x86/device/local_apic.rs +++ b/kernel-rs/src/arch/x86/device/local_apic.rs @@ -1,8 +1,8 @@ -use ::arch::x86::paging::ActivePageTable; +use arch::x86::paging::ActivePageTable; pub static mut LOCAL_APIC: LocalApic = LocalApic { address: 0, - x2: false + x2: false, }; pub unsafe fn init(active_table: &mut ActivePageTable) { @@ -11,7 +11,7 @@ pub unsafe fn init(active_table: &mut ActivePageTable) { pub struct LocalApic { pub address: usize, - pub x2: bool + pub x2: bool, } impl LocalApic { diff --git a/kernel-rs/src/arch/x86/device/mod.rs b/kernel-rs/src/arch/x86/device/mod.rs index dc1eac30..1a0a08a9 100644 --- a/kernel-rs/src/arch/x86/device/mod.rs +++ b/kernel-rs/src/arch/x86/device/mod.rs @@ -1,4 +1,4 @@ -use ::arch::x86::paging::ActivePageTable; +use arch::x86::paging::ActivePageTable; pub mod pic; pub mod local_apic; pub mod cpu; diff --git a/kernel-rs/src/arch/x86/device/pic.rs b/kernel-rs/src/arch/x86/device/pic.rs index 00b5ab21..39a4f2f7 100644 --- a/kernel-rs/src/arch/x86/device/pic.rs +++ b/kernel-rs/src/arch/x86/device/pic.rs @@ -1,47 +1,64 @@ -use ::io::{Io, Pio}; +use io::{Io, Pio}; pub static mut MASTER: Pic = Pic::new(0x20); pub static mut SLAVE: Pic = Pic::new(0xA0); pub static mut WAIT_PORT: Pio = Pio::new(0x80); pub unsafe fn init() { - let wait = || {WAIT_PORT.write(0)}; + let wait = || WAIT_PORT.write(0); let master_mask = MASTER.data.read(); let slave_mask = SLAVE.data.read(); // Start initialization - MASTER.cmd.write(0x11); wait(); - SLAVE.cmd.write(0x11); wait(); + MASTER.cmd.write(0x11); + wait(); + SLAVE.cmd.write(0x11); + wait(); // Set offsets - MASTER.data.write(0x20); wait(); - SLAVE.data.write(0x28); wait(); + MASTER.data.write(0x20); + wait(); + SLAVE.data.write(0x28); + wait(); // Set up cascade - MASTER.data.write(4); wait(); - SLAVE.data.write(2); wait(); + MASTER.data.write(4); + wait(); + SLAVE.data.write(2); + wait(); // Set up interrupt mode (1 is 8086/88 mode, 2 is auto EOI) - MASTER.data.write(1); wait(); - SLAVE.data.write(1); wait(); + MASTER.data.write(1); + wait(); + SLAVE.data.write(1); + wait(); // Unmask interrupts - MASTER.data.write(0); wait(); - SLAVE.data.write(0); wait(); + MASTER.data.write(0); + wait(); + SLAVE.data.write(0); + wait(); // Ack remaining interrupts - MASTER.ack(); wait(); - SLAVE.ack(); wait(); + MASTER.ack(); + wait(); + SLAVE.ack(); + wait(); - MASTER.data.write(master_mask); wait(); - SLAVE.data.write(slave_mask); wait(); + MASTER.data.write(master_mask); + wait(); + SLAVE.data.write(slave_mask); + wait(); // disable all irqs - MASTER.data.write(!0); wait(); - SLAVE.data.write(!0); wait(); - + MASTER.data.write(!0); + wait(); + SLAVE.data.write(!0); + wait(); + // keyboard active - MASTER.mask_clear(1); wait(); + MASTER.mask_clear(1); + wait(); // asm!("sti"); ::x86::instructions::interrupts::enable(); diff --git a/kernel-rs/src/arch/x86/gdt.rs b/kernel-rs/src/arch/x86/gdt.rs index 0fed6425..ff682cba 100644 --- a/kernel-rs/src/arch/x86/gdt.rs +++ b/kernel-rs/src/arch/x86/gdt.rs @@ -4,15 +4,15 @@ use x86::instructions::segmentation::set_cs; use x86::instructions::tables::load_tss; use spin::Once; -static GDT: Once = Once::new(); -static TSS: Once = Once::new(); +// static GDT: Once = Once::new(); +// static TSS: Once = Once::new(); pub fn init() { // let tss = tss::TaskStateSegment::new(); - let tss = TSS.call_once(|| { - let mut tss = tss::TaskStateSegment::new(); - tss - }); + // let tss = TSS.call_once(|| { + // let mut tss = tss::TaskStateSegment::new(); + // tss + // }); // let mut code_selector = gdt::SegmentSelector(0); // let mut tss_selector = gdt::SegmentSelector(0); diff --git a/kernel-rs/src/arch/x86/interrupt/exception.rs b/kernel-rs/src/arch/x86/interrupt/exception.rs index 9a75ef24..88bd80c5 100644 --- a/kernel-rs/src/arch/x86/interrupt/exception.rs +++ b/kernel-rs/src/arch/x86/interrupt/exception.rs @@ -1,6 +1,6 @@ // https://wiki.osdev.org/Exceptions -use ::arch::x86::pti; +use arch::x86::pti; macro_rules! exception { ($name:ident, $func:block) => { @@ -62,8 +62,9 @@ exception_err!(stack_segment, {}); exception_err!(general_protection, {}); pub extern "x86-interrupt" fn page_fault( - stack_frame: &mut ExceptionStackFrame, code: PageFaultErrorCode) -{ + stack_frame: &mut ExceptionStackFrame, + code: PageFaultErrorCode, +) { println!("Exception: page_fault"); println!("Error code: {:#b}", code); println!("{:#?}", stack_frame); diff --git a/kernel-rs/src/arch/x86/interrupt/mod.rs b/kernel-rs/src/arch/x86/interrupt/mod.rs index 81c73a70..c8a97f14 100644 --- a/kernel-rs/src/arch/x86/interrupt/mod.rs +++ b/kernel-rs/src/arch/x86/interrupt/mod.rs @@ -1,2 +1,4 @@ -#[macro_use] pub mod exception; -#[macro_use] pub mod irq; +#[macro_use] +pub mod exception; +#[macro_use] +pub mod irq; diff --git a/kernel-rs/src/arch/x86/mod.rs b/kernel-rs/src/arch/x86/mod.rs index 74572557..9f32c21d 100644 --- a/kernel-rs/src/arch/x86/mod.rs +++ b/kernel-rs/src/arch/x86/mod.rs @@ -6,14 +6,14 @@ pub mod interrupt; pub mod device; pub mod pti; -pub mod gdt; +// pub mod gdt; pub mod idt; use multiboot2; use acpi; #[no_mangle] -pub unsafe extern fn x86_rust_start(multiboot_info_addr: usize) { +pub unsafe extern "C" fn x86_rust_start(multiboot_info_addr: usize) { // parse multiboot2 info let boot_info = multiboot2::load(multiboot_info_addr); @@ -26,24 +26,26 @@ pub unsafe extern fn x86_rust_start(multiboot_info_addr: usize) { acpi::init().expect("ACPI failed"); } + // fill and load idt (exceptions + irqs) + idt::init(); + // set up physical allocator - ::memory::init(&boot_info); + ::memory::init(&boot_info); // set up virtual mapping let mut active_table = paging::init(&boot_info); + asm!("hlt"); + // set up heap ::allocator::init(&mut active_table); - // set up memory segmentation - // gdt::init(); - - // set up interrupts - idt::init(); - // set up pic & apic device::init(&mut active_table); + // fill and load gdt + // gdt::init(); + // primary CPU entry point ::kmain(); } diff --git a/kernel-rs/src/arch/x86/paging/mapper.rs b/kernel-rs/src/arch/x86/paging/mapper.rs index 128e82be..56ba3517 100644 --- a/kernel-rs/src/arch/x86/paging/mapper.rs +++ b/kernel-rs/src/arch/x86/paging/mapper.rs @@ -31,8 +31,7 @@ impl Mapper { } /// virtual addr to physical addr translation - pub fn translate(&self, virtual_address: VirtAddr) -> Option - { + pub fn translate(&self, virtual_address: VirtAddr) -> Option { let offset = virtual_address.as_u32() % PAGE_SIZE as u32; self.translate_page(Page::containing_address(virtual_address)) .map(|frame| frame.start_address() + offset) @@ -54,33 +53,29 @@ impl Mapper { }; p1.and_then(|p1| p1[page.p1_index()].pointed_frame()) - .or_else(huge_page) + .or_else(huge_page) } /// map a virtual page to a physical frame in the page tables - pub fn map_to(&mut self, page: Page, frame: PhysFrame, flags: PageTableFlags) - { + pub fn map_to(&mut self, page: Page, frame: PhysFrame, flags: PageTableFlags) { let p2 = self.p2_mut(); let p1 = p2.next_table_create(usize_from(u32::from(page.p2_index()))); assert!(p1[page.p1_index()].is_unused()); p1[page.p1_index()].set(frame, flags | PageTableFlags::PRESENT); } - pub fn map(&mut self, page: Page, flags: PageTableFlags) - { + pub fn map(&mut self, page: Page, flags: PageTableFlags) { let frame = ::memory::allocate_frames(1).expect("out of frames"); self.map_to(page, frame, flags) } - pub fn identity_map(&mut self, frame: PhysFrame, flags: PageTableFlags) - { + pub fn identity_map(&mut self, frame: PhysFrame, flags: PageTableFlags) { let virt_addr = VirtAddr::new(frame.start_address().as_u32()); let page = Page::containing_address(virt_addr); self.map_to(page, frame, flags); } - pub fn unmap(&mut self, page: Page) - { + pub fn unmap(&mut self, page: Page) { assert!(self.translate(page.start_address()).is_some()); let p1 = self.p2_mut() diff --git a/kernel-rs/src/arch/x86/paging/mod.rs b/kernel-rs/src/arch/x86/paging/mod.rs index 1a4db1c7..39e87944 100644 --- a/kernel-rs/src/arch/x86/paging/mod.rs +++ b/kernel-rs/src/arch/x86/paging/mod.rs @@ -51,34 +51,40 @@ impl ActivePageTable { } } - pub fn with(&mut self, - table: &mut InactivePageTable, - temporary_page: &mut temporary_page::TemporaryPage, - f: F) - where F: FnOnce(&mut Mapper) - { - let (cr3_back, _cr3flags_back) = Cr3::read(); + pub fn with( + &mut self, + table: &mut InactivePageTable, + temporary_page: &mut temporary_page::TemporaryPage, + f: F, + ) where + F: FnOnce(&mut Mapper), + { + let (cr3_back, _cr3flags_back) = Cr3::read(); - // map temp page to current p2 - let p2_table = temporary_page.map_table_frame(cr3_back.clone(), self); + // map temp page to current p2 + let p2_table = temporary_page.map_table_frame(cr3_back.clone(), self); - // overwrite recursive map - self.p2_mut()[1023].set(table.p2_frame.clone(), PageTableFlags::PRESENT | PageTableFlags::WRITABLE); - tlb::flush_all(); + // overwrite recursive map + self.p2_mut()[1023].set( + table.p2_frame.clone(), + PageTableFlags::PRESENT | PageTableFlags::WRITABLE, + ); + tlb::flush_all(); - // execute f in the new context - f(self); + // execute f in the new context + f(self); - // restore recursive mapping to original p2 table - p2_table[1023].set(cr3_back, PageTableFlags::PRESENT | PageTableFlags::WRITABLE); - } + // restore recursive mapping to original p2 table + p2_table[1023].set(cr3_back, PageTableFlags::PRESENT | PageTableFlags::WRITABLE); + } pub fn switch(&mut self, new_table: InactivePageTable) -> InactivePageTable { - let (p2_frame, cr3_flags) = Cr3::read(); let old_table = InactivePageTable { p2_frame }; - unsafe { Cr3::write(new_table.p2_frame, cr3_flags); } + unsafe { + Cr3::write(new_table.p2_frame, cr3_flags); + } old_table } @@ -89,39 +95,44 @@ pub struct InactivePageTable { } impl InactivePageTable { - pub fn new(frame: PhysFrame, - active_table: &mut ActivePageTable, - temporary_page: &mut TemporaryPage) - -> InactivePageTable { - { - let table = temporary_page.map_table_frame(frame.clone(), active_table); + pub fn new( + frame: PhysFrame, + active_table: &mut ActivePageTable, + temporary_page: &mut TemporaryPage, + ) -> InactivePageTable { + { + let table = temporary_page.map_table_frame(frame.clone(), active_table); - table.zero(); - // set up recursive mapping for the table - table[1023].set(frame.clone(), PageTableFlags::PRESENT | PageTableFlags::WRITABLE) - } - temporary_page.unmap(active_table); - InactivePageTable { p2_frame: frame } + table.zero(); + // set up recursive mapping for the table + table[1023].set( + frame.clone(), + PageTableFlags::PRESENT | PageTableFlags::WRITABLE, + ) } + temporary_page.unmap(active_table); + InactivePageTable { p2_frame: frame } + } } -pub fn remap_the_kernel(boot_info: &BootInformation) -> ActivePageTable -{ - let mut temporary_page = TemporaryPage::new(Page{number: 0xcafe}); +pub fn remap_the_kernel(boot_info: &BootInformation) -> ActivePageTable { + let mut temporary_page = TemporaryPage::new(Page { number: 0xcafe }); let mut active_table = unsafe { ActivePageTable::new() }; let mut new_table = { let frame = ::memory::allocate_frames(1).expect("no more frames"); InactivePageTable::new(frame, &mut active_table, &mut temporary_page) }; - + unsafe { + asm!("hlt"); + } active_table.with(&mut new_table, &mut temporary_page, |mapper| { - // id map vga buffer let vga_buffer_frame = PhysFrame::containing_address(PhysAddr::new(0xb8000)); mapper.identity_map(vga_buffer_frame, PageTableFlags::WRITABLE); - let elf_sections_tag = boot_info.elf_sections_tag() + let elf_sections_tag = boot_info + .elf_sections_tag() .expect("Memory map tag required"); // id map kernel sections @@ -129,24 +140,26 @@ pub fn remap_the_kernel(boot_info: &BootInformation) -> ActivePageTable if !section.is_allocated() { continue; } - assert!(section.start_address() % PAGE_SIZE as u64 == 0, - "sections need to be page aligned"); + assert!( + section.start_address() % PAGE_SIZE as u64 == 0, + "sections need to be page aligned" + ); let flags = elf_to_pagetable_flags(§ion.flags()); - let start_frame = PhysFrame::containing_address( - PhysAddr::new(section.start_address() as u32)); - let end_frame = PhysFrame::containing_address( - PhysAddr::new(section.end_address() as u32 - 1)); + let start_frame = + PhysFrame::containing_address(PhysAddr::new(section.start_address() as u32)); + let end_frame = + PhysFrame::containing_address(PhysAddr::new(section.end_address() as u32 - 1)); for frame in start_frame..end_frame + 1 { mapper.identity_map(frame, flags); } } // id map multiboot - let multiboot_start = PhysFrame::containing_address( - PhysAddr::new(boot_info.start_address() as u32)); - let multiboot_end = PhysFrame::containing_address( - PhysAddr::new(boot_info.end_address() as u32 - 1)); + let multiboot_start = + PhysFrame::containing_address(PhysAddr::new(boot_info.start_address() as u32)); + let multiboot_end = + PhysFrame::containing_address(PhysAddr::new(boot_info.end_address() as u32 - 1)); for frame in multiboot_start..multiboot_end + 1 { mapper.identity_map(frame, PageTableFlags::PRESENT); } @@ -154,17 +167,15 @@ pub fn remap_the_kernel(boot_info: &BootInformation) -> ActivePageTable let old_table = active_table.switch(new_table); - let old_p2_page = Page::containing_address( - VirtAddr::new(old_table.p2_frame.start_address().as_u32())); + let old_p2_page = + Page::containing_address(VirtAddr::new(old_table.p2_frame.start_address().as_u32())); active_table.unmap(old_p2_page); active_table } -fn elf_to_pagetable_flags(elf_flags: &multiboot2::ElfSectionFlags) - -> PageTableFlags -{ +fn elf_to_pagetable_flags(elf_flags: &multiboot2::ElfSectionFlags) -> PageTableFlags { use multiboot2::ElfSectionFlags; let mut flags = PageTableFlags::empty(); diff --git a/kernel-rs/src/arch/x86/paging/table.rs b/kernel-rs/src/arch/x86/paging/table.rs index 41eec7e0..3b774172 100644 --- a/kernel-rs/src/arch/x86/paging/table.rs +++ b/kernel-rs/src/arch/x86/paging/table.rs @@ -1,20 +1,18 @@ use x86::structures::paging::*; -pub trait RecTable -{ +pub trait RecTable { fn next_table_address(&self, index: usize) -> Option; fn next_table(&self, index: usize) -> Option<&PageTable>; fn next_table_mut(&mut self, index: usize) -> Option<&mut PageTable>; - fn next_table_create(&mut self, - index: usize) - -> &mut PageTable; + fn next_table_create(&mut self, index: usize) -> &mut PageTable; } -impl RecTable for PageTable -{ +impl RecTable for PageTable { fn next_table_address(&self, index: usize) -> Option { let entry_flags = self[index].flags(); - if entry_flags.contains(PageTableFlags::PRESENT) && !entry_flags.contains(PageTableFlags::HUGE_PAGE) { + if entry_flags.contains(PageTableFlags::PRESENT) + && !entry_flags.contains(PageTableFlags::HUGE_PAGE) + { let table_address = self as *const _ as usize; Some((table_address << 10 | index << 12) as u32) } else { @@ -32,16 +30,17 @@ impl RecTable for PageTable .map(|address| unsafe { &mut *(address as *mut _) }) } - fn next_table_create(&mut self, - index: usize) -> &mut PageTable - { + fn next_table_create(&mut self, index: usize) -> &mut PageTable { if self.next_table(index).is_none() { - assert!(!self[index].flags().contains(PageTableFlags::HUGE_PAGE), - "mapping code does not support huge pages"); - let frame = ::memory::allocate_frames(1) - .expect("out of memory"); + assert!( + !self[index].flags().contains(PageTableFlags::HUGE_PAGE), + "mapping code does not support huge pages" + ); + let frame = ::memory::allocate_frames(1).expect("out of memory"); self[index].set(frame, PageTableFlags::PRESENT | PageTableFlags::WRITABLE); - self.next_table_mut(index).expect("next_table_mut gave None").zero() + self.next_table_mut(index) + .expect("next_table_mut gave None") + .zero() } self.next_table_mut(index).expect("no next table 2") } diff --git a/kernel-rs/src/arch/x86/paging/temporary_page.rs b/kernel-rs/src/arch/x86/paging/temporary_page.rs index becdb0fc..b712fcfb 100644 --- a/kernel-rs/src/arch/x86/paging/temporary_page.rs +++ b/kernel-rs/src/arch/x86/paging/temporary_page.rs @@ -7,24 +7,25 @@ pub struct TemporaryPage { } impl TemporaryPage { - pub fn new(page: Page) -> TemporaryPage - { + pub fn new(page: Page) -> TemporaryPage { TemporaryPage { page: page } } /// Maps the temporary page to the given frame in the active table. /// Returns the start address of the temporary page. - pub fn map(&mut self, frame: PhysFrame, active_table: &mut ActivePageTable) - -> VirtAddr - { - assert!(active_table.translate_page(self.page).is_none(), - "temporary page is already mapped"); - active_table.map_to(self.page, frame, PageTableFlags::WRITABLE); - // this kind of check should be done in a test routine - assert!(active_table.translate_page(self.page).is_some(), - "temporary page was not mapped"); - self.page.start_address() - } + pub fn map(&mut self, frame: PhysFrame, active_table: &mut ActivePageTable) -> VirtAddr { + assert!( + active_table.translate_page(self.page).is_none(), + "temporary page is already mapped" + ); + active_table.map_to(self.page, frame, PageTableFlags::WRITABLE); + // this kind of check should be done in a test routine + assert!( + active_table.translate_page(self.page).is_some(), + "temporary page was not mapped" + ); + self.page.start_address() + } /// Unmaps the temporary page in the active table. pub fn unmap(&mut self, active_table: &mut ActivePageTable) { @@ -33,10 +34,11 @@ impl TemporaryPage { /// Maps the temporary page to the given page table frame in the active /// table. Returns a reference to the now mapped table. - pub fn map_table_frame(&mut self, - frame: PhysFrame, - active_table: &mut ActivePageTable) - -> &mut PageTable { - unsafe { &mut *(self.map(frame, active_table).as_u32() as *mut PageTable) } - } + pub fn map_table_frame( + &mut self, + frame: PhysFrame, + active_table: &mut ActivePageTable, + ) -> &mut PageTable { + unsafe { &mut *(self.map(frame, active_table).as_u32() as *mut PageTable) } + } } diff --git a/kernel-rs/src/arch/x86/pti.rs b/kernel-rs/src/arch/x86/pti.rs index 7942d611..91f488c1 100644 --- a/kernel-rs/src/arch/x86/pti.rs +++ b/kernel-rs/src/arch/x86/pti.rs @@ -20,11 +20,7 @@ unsafe fn switch_stack(old: usize, new: usize) { let new_esp = new - offset_esp; - ptr::copy_nonoverlapping( - old_esp as *const u8, - new_esp as *mut u8, - offset_esp - ); + ptr::copy_nonoverlapping(old_esp as *const u8, new_esp as *mut u8, offset_esp); // switch the esp with the new one asm!("" : : "{esp}"(new_esp) : : "intel", "volatile"); @@ -47,13 +43,19 @@ pub unsafe fn map() { // } // Switch to per-context stack - switch_stack(PTI_CPU_STACK.as_ptr() as usize + PTI_CPU_STACK.len(), PTI_CONTEXT_STACK); + switch_stack( + PTI_CPU_STACK.as_ptr() as usize + PTI_CPU_STACK.len(), + PTI_CONTEXT_STACK, + ); } #[inline(always)] pub unsafe fn unmap() { // Switch to per-CPU stack - switch_stack(PTI_CONTEXT_STACK, PTI_CPU_STACK.as_ptr() as usize + PTI_CPU_STACK.len()); + switch_stack( + PTI_CONTEXT_STACK, + PTI_CPU_STACK.as_ptr() as usize + PTI_CPU_STACK.len(), + ); // { // let mut active_table = unsafe { ActivePageTable::new() }; diff --git a/kernel-rs/src/console.rs b/kernel-rs/src/console.rs index 29a8f583..0e1eff02 100644 --- a/kernel-rs/src/console.rs +++ b/kernel-rs/src/console.rs @@ -6,9 +6,9 @@ use cpuio; use core::char; use vga::*; -fn dispatch(command: &str) -> Result <(), &'static str> { +fn dispatch(command: &str) -> Result<(), &'static str> { match command { - "help" | "h" => self::help(), + "help" | "h" => self::help(), // multiboot // "memory" => self::mb2_memory(), @@ -16,20 +16,20 @@ fn dispatch(command: &str) -> Result <(), &'static str> { // "sections" => self::mb2_sections(), // ACPI - "acpi" => self::acpi_info(), - "reboot" => self::reboot(), - "shutdown" | "halt" | "q" => self::shutdown(), + "acpi" => self::acpi_info(), + "reboot" => self::reboot(), + "shutdown" | "halt" | "q" => self::shutdown(), // x86 specific - "stack" => self::print_stack(), - "regs" => self::regs(), - "cpu" => self::cpu(), + "stack" => self::print_stack(), + "regs" => self::regs(), + "cpu" => self::cpu(), - _ => Err("Command unknown. (h|help for help)"), + _ => Err("Command unknown. (h|help for help)"), } } -pub fn exec(cli: &Writer) -> Result <(), &'static str> { +pub fn exec(cli: &Writer) -> Result<(), &'static str> { let command = cli.get_command()?; if let Err(msg) = self::dispatch(command) { set_color!(Red); @@ -39,7 +39,7 @@ pub fn exec(cli: &Writer) -> Result <(), &'static str> { Ok(()) } -fn help() -> Result <(), &'static str> { +fn help() -> Result<(), &'static str> { println!("acpi => Return acpi state (ENABLED|DISABLE)"); println!("help | h => Print this help"); // println!("memory => Print memory areas"); @@ -59,14 +59,14 @@ fn help() -> Result <(), &'static str> { /// If reboot failed, will loop on a halt cmd /// fn reboot() -> ! { - unsafe {asm!("cli")}; //TODO volatile ????? - // I will now clear the keyboard buffer + unsafe { asm!("cli") }; //TODO volatile ????? + // I will now clear the keyboard buffer let mut buffer: u8 = 0x02; while buffer & 0x02 != 0 { cpuio::inb(0x60); buffer = cpuio::inb(0x64); } - cpuio::outb(0x64, 0xFE);//Send reset value to CPU //TODO doesn't work in QEMU ==> it seems that qemu cannot reboot + cpuio::outb(0x64, 0xFE); //Send reset value to CPU //TODO doesn't work in QEMU ==> it seems that qemu cannot reboot println!("Unable to perform reboot. Kernel will be halted"); cpuio::halt(); } @@ -76,7 +76,7 @@ fn reboot() -> ! { /// If shutdown is performed but failed, will loop on a halt cmd /// If shutdown cannot be called, return a Err(&str) /// -fn shutdown() -> Result <(), &'static str> { +fn shutdown() -> Result<(), &'static str> { acpi::shutdown()?; println!("Unable to perform ACPI shutdown. Kernel will be halted"); cpuio::halt(); @@ -102,14 +102,14 @@ fn print_line(line: &[u8], address: usize) { for byte in line { print!("{:02x} ", *byte); } - let length : usize = 16 - line.len(); + let length: usize = 16 - line.len(); for _ in 0..length { print!(" "); } print!("|"); for byte in line { match is_control(*byte as char) { - true => print!("."), + true => print!("."), false => print!("{}", *byte as char), }; } @@ -117,7 +117,7 @@ fn print_line(line: &[u8], address: usize) { } /// Print the kernel stack -fn print_stack() -> Result <(), &'static str> { +fn print_stack() -> Result<(), &'static str> { let esp: usize; let ebp: usize; unsafe { asm!("" : "={esp}"(esp), "={ebp}"(ebp):::) }; @@ -172,14 +172,14 @@ fn print_stack() -> Result <(), &'static str> { // Ok(()) // } -pub fn acpi_info() -> Result <(), &'static str> { +pub fn acpi_info() -> Result<(), &'static str> { acpi::info()?; Ok(()) } /// Dump control registers -pub fn regs() -> Result <(), &'static str> { - use ::x86::registers::control::*; +pub fn regs() -> Result<(), &'static str> { + use x86::registers::control::*; println!("cr0 = {:?}", Cr0::read()); println!("cr3 = {:?}", Cr3::read()); println!("cr4 = {:?}", Cr4::read()); @@ -188,8 +188,8 @@ pub fn regs() -> Result <(), &'static str> { } /// Dump cpu info, should add power management info -pub fn cpu() -> Result <(), &'static str> { - use ::arch::x86::device::cpu; +pub fn cpu() -> Result<(), &'static str> { + use arch::x86::device::cpu; cpu::cpu_info().expect("cpu info not available"); flush!(); Ok(()) diff --git a/kernel-rs/src/cpuio.rs b/kernel-rs/src/cpuio.rs index 15788763..1343789d 100644 --- a/kernel-rs/src/cpuio.rs +++ b/kernel-rs/src/cpuio.rs @@ -5,50 +5,52 @@ pub fn inb(port: u16) -> u8 { // The registers for the `in` and `out` instructions are always the // same: `a` for value, and `d` for the port address. let result: u8; - unsafe {asm!("inb %dx, %al" : "={al}"(result) : "{dx}"(port) :: "volatile")}; + unsafe { asm!("inb %dx, %al" : "={al}"(result) : "{dx}"(port) :: "volatile") }; result } /// Write a `u8`-sized `value` to `port`. pub fn outb(port: u16, value: u8) { - unsafe {asm!("outb %al, %dx" :: "{dx}"(port), "{al}"(value) :: "volatile")}; + unsafe { asm!("outb %al, %dx" :: "{dx}"(port), "{al}"(value) :: "volatile") }; } /// Read a `u16`-sized value from `port`. pub fn inw(port: u16) -> u16 { let result: u16; - unsafe {asm!("inw %dx, %ax" : "={ax}"(result) : "{dx}"(port) :: "volatile")}; + unsafe { asm!("inw %dx, %ax" : "={ax}"(result) : "{dx}"(port) :: "volatile") }; result } /// Write a `u8`-sized `value` to `port`. pub fn outw(port: u16, value: u16) { - unsafe {asm!("outw %ax, %dx" :: "{dx}"(port), "{ax}"(value) :: "volatile")}; + unsafe { asm!("outw %ax, %dx" :: "{dx}"(port), "{ax}"(value) :: "volatile") }; } /// Read a `u32`-sized value from `port`. pub fn inl(port: u16) -> u32 { let result: u32; - unsafe {asm!("inl %dx, %eax" : "={eax}"(result) : "{dx}"(port) :: "volatile")}; + unsafe { asm!("inl %dx, %eax" : "={eax}"(result) : "{dx}"(port) :: "volatile") }; result } /// Write a `u32`-sized `value` to `port`. pub fn outl(port: u16, value: u32) { - unsafe {asm!("outl %eax, %dx" :: "{dx}"(port), "{eax}"(value) :: "volatile")}; + unsafe { asm!("outl %eax, %dx" :: "{dx}"(port), "{eax}"(value) :: "volatile") }; } /// Halt system pub fn halt() -> ! { - unsafe {asm!("cli" : : : : "volatile")}; + unsafe { asm!("cli" : : : : "volatile") }; loop { - unsafe {asm!("hlt" : : : : "volatile")}; + unsafe { asm!("hlt" : : : : "volatile") }; } } /// wait for an io operation to complete pub fn io_wait() { - unsafe { asm!("jmp 1f\n\t + unsafe { + asm!("jmp 1f\n\t 1:jmp 2f\n\t - 2:" : : : : "volatile")} + 2:" : : : : "volatile") + } } diff --git a/kernel-rs/src/io/mod.rs b/kernel-rs/src/io/mod.rs index 3bb33f5f..0382a50a 100644 --- a/kernel-rs/src/io/mod.rs +++ b/kernel-rs/src/io/mod.rs @@ -5,13 +5,17 @@ pub use self::pio::*; use core::ops::{BitAnd, BitOr, Not}; pub trait Io { - type Value: Copy + PartialEq + BitAnd + BitOr + Not; + type Value: Copy + + PartialEq + + BitAnd + + BitOr + + Not; fn read(&self) -> Self::Value; fn write(&mut self, value: Self::Value); #[inline(always)] - fn readf(&self, flags: Self::Value) -> bool { + fn readf(&self, flags: Self::Value) -> bool { (self.read() & flags) as Self::Value == flags } diff --git a/kernel-rs/src/keyboard.rs b/kernel-rs/src/keyboard.rs index c456d45f..d7c4a16a 100644 --- a/kernel-rs/src/keyboard.rs +++ b/kernel-rs/src/keyboard.rs @@ -4,7 +4,7 @@ use cpuio; use vga; const MAX_KEYS: usize = 59; -const KEYMAP_US: [[u8;2]; MAX_KEYS] = [ +const KEYMAP_US: [[u8; 2]; MAX_KEYS] = [ *b"\0\0", *b"\0\0",//escape *b"1!", @@ -84,25 +84,24 @@ pub fn kbd_callback() { if (control & 1) == 1 { let scancode = cpuio::inb(0x60); let (is_release, scancode) = check_key_state(scancode); - unsafe {//TODO remove unsafe + unsafe { + //TODO remove unsafe match self::KEYMAP_US.get(scancode as usize) { - Some(b"\0\0") => { - match scancode { - 0x2A | 0x36 => {SHIFT = !is_release}, - 0x38 => {ALT = !is_release}, - 0x1D => {CTRL = !is_release}, - 0x0E if !is_release => { - vga::VGA.backspace(); - } - _ => {} + Some(b"\0\0") => match scancode { + 0x2A | 0x36 => SHIFT = !is_release, + 0x38 => ALT = !is_release, + 0x1D => CTRL = !is_release, + 0x0E if !is_release => { + vga::VGA.backspace(); } + _ => {} }, Some(ascii) if !is_release => { let sym = if SHIFT { ascii[1] } else { ascii[0] }; vga::VGA.keypress(sym); - }, - Some(_) => {}, - None =>{}, + } + Some(_) => {} + None => {} } } } diff --git a/kernel-rs/src/lib.rs b/kernel-rs/src/lib.rs index 8db6c338..9d542d82 100644 --- a/kernel-rs/src/lib.rs +++ b/kernel-rs/src/lib.rs @@ -7,28 +7,28 @@ #![feature(ptr_internals)] #![feature(asm)] #![feature(thread_local)] - // home made heap #![feature(alloc)] #![feature(allocator_api)] #![feature(global_allocator)] - // x86 specific #![feature(abi_x86_interrupt)] -extern crate rlibc; extern crate alloc; -extern crate spin; -#[macro_use] extern crate lazy_static; +#[macro_use] +extern crate lazy_static; extern crate multiboot2; -extern crate slab_allocator; extern crate raw_cpuid; +extern crate rlibc; +extern crate slab_allocator; +extern crate spin; // used by arch/x86, need conditional compilation here extern crate x86; /// 80x25 terminal driver -#[macro_use] pub mod vga; +#[macro_use] +pub mod vga; /// PS/2 detection and processing pub mod keyboard; /// simplisitc kernel commands @@ -45,9 +45,10 @@ pub mod memory; /// arch specific entry points pub mod arch; -/// kernel entry point. arch module is responsible for calling this +/// kernel entry point. arch module is responsible for +/// calling this once the core has loaded pub fn kmain() -> ! { - // core is loaded now + // heap avalaible for tracking free'd frames memory::init_noncore(); // x86::instructions::interrupts::int3(); @@ -66,12 +67,13 @@ pub fn kmain() -> ! { loop {} } -#[lang = "eh_personality"] #[no_mangle] -pub extern fn eh_personality() {} +#[lang = "eh_personality"] +#[no_mangle] +pub extern "C" fn eh_personality() {} -#[lang = "panic_fmt"] #[no_mangle] -pub extern fn panic_fmt(fmt: core::fmt::Arguments, file: &'static str, line: u32) --> ! { +#[lang = "panic_fmt"] +#[no_mangle] +pub extern "C" fn panic_fmt(fmt: core::fmt::Arguments, file: &'static str, line: u32) -> ! { println!("PANIC: {}", fmt); println!("FILE: {}", file); println!("LINE: {}", line); diff --git a/kernel-rs/src/memory/bump.rs b/kernel-rs/src/memory/bump.rs index d45e595c..4e62a672 100644 --- a/kernel-rs/src/memory/bump.rs +++ b/kernel-rs/src/memory/bump.rs @@ -1,4 +1,4 @@ -use multiboot2::{MemoryAreaIter, MemoryArea}; +use multiboot2::{MemoryArea, MemoryAreaIter}; use x86::*; use x86::structures::paging::PhysFrame; use super::FrameAllocator; @@ -14,21 +14,21 @@ pub struct BumpFrameAllocator { } impl BumpFrameAllocator { - pub fn new(kernel_start: usize, kernel_end: usize, - multiboot_start: usize, multiboot_end: usize, - memory_areas: MemoryAreaIter) -> BumpFrameAllocator { + pub fn new( + kernel_start: usize, + kernel_end: usize, + multiboot_start: usize, + multiboot_end: usize, + memory_areas: MemoryAreaIter, + ) -> BumpFrameAllocator { let mut allocator = BumpFrameAllocator { next_free_frame: PhysFrame { number: 0 }, current_area: None, areas: memory_areas, - kernel_start: PhysFrame::containing_address( - PhysAddr::new(kernel_start as u32)), - kernel_end: PhysFrame::containing_address( - PhysAddr::new(kernel_end as u32)), - multiboot_start: PhysFrame::containing_address( - PhysAddr::new(multiboot_start as u32)), - multiboot_end: PhysFrame::containing_address( - PhysAddr::new(multiboot_end as u32)), + kernel_start: PhysFrame::containing_address(PhysAddr::new(kernel_start as u32)), + kernel_end: PhysFrame::containing_address(PhysAddr::new(kernel_end as u32)), + multiboot_start: PhysFrame::containing_address(PhysAddr::new(multiboot_start as u32)), + multiboot_end: PhysFrame::containing_address(PhysAddr::new(multiboot_end as u32)), }; allocator.choose_next_area(); allocator @@ -36,13 +36,16 @@ impl BumpFrameAllocator { fn choose_next_area(&mut self) { // get next area with free frames - self.current_area = self.areas.clone().filter(|area| { - area.end_address() >= self.next_free_frame.start_address().as_u32() as usize - }).min_by_key(|area| area.start_address()); + self.current_area = self.areas + .clone() + .filter(|area| { + area.end_address() >= self.next_free_frame.start_address().as_u32() as usize + }) + .min_by_key(|area| area.start_address()); if let Some(area) = self.current_area { - let start_frame = PhysFrame::containing_address( - PhysAddr::new(area.start_address() as u32)); + let start_frame = + PhysFrame::containing_address(PhysAddr::new(area.start_address() as u32)); if self.next_free_frame < start_frame { self.next_free_frame = start_frame; } @@ -52,22 +55,32 @@ impl BumpFrameAllocator { impl FrameAllocator for BumpFrameAllocator { fn allocate_frames(&mut self, count: usize) -> Option { - if count == 0 { return None }; + if count == 0 { + return None; + }; if let Some(area) = self.current_area { - let start_frame = PhysFrame { number: self.next_free_frame.number }; - let end_frame = PhysFrame { number: self.next_free_frame.number + count as u32 - 1 }; + let start_frame = PhysFrame { + number: self.next_free_frame.number, + }; + let end_frame = PhysFrame { + number: self.next_free_frame.number + count as u32 - 1, + }; - let current_area_last_frame = PhysFrame::containing_address( - PhysAddr::new(area.end_address() as u32)); + let current_area_last_frame = + PhysFrame::containing_address(PhysAddr::new(area.end_address() as u32)); if end_frame > current_area_last_frame { // all frames are taken in this area self.choose_next_area(); - } else if (start_frame >= self.kernel_start && start_frame <= self.kernel_end) || (end_frame >= self.kernel_start && end_frame <= self.kernel_end) { + } else if (start_frame >= self.kernel_start && start_frame <= self.kernel_end) + || (end_frame >= self.kernel_start && end_frame <= self.kernel_end) + { // frame used by kernel self.next_free_frame = PhysFrame { number: self.kernel_end.number + 1, }; - } else if (start_frame >= self.multiboot_start && start_frame <= self.multiboot_end) || (end_frame >= self.multiboot_start && end_frame <= self.multiboot_end) { + } else if (start_frame >= self.multiboot_start && start_frame <= self.multiboot_end) + || (end_frame >= self.multiboot_start && end_frame <= self.multiboot_end) + { // frame used by multiboot self.next_free_frame = PhysFrame { number: self.multiboot_end.number + 1, @@ -79,13 +92,17 @@ impl FrameAllocator for BumpFrameAllocator { // try again with next_free_frame self.allocate_frames(count) } else { - None + None } } fn deallocate_frames(&mut self, frame: PhysFrame, count: usize) { // bump doesnt deallocate, must be used inside of a recycler - println!("lost frames {:#x} ({})", frame.start_address().as_u32(), count); + println!( + "lost frames {:#x} ({})", + frame.start_address().as_u32(), + count + ); // unimplemented!(); } } diff --git a/kernel-rs/src/memory/mod.rs b/kernel-rs/src/memory/mod.rs index a8c28ed5..7d9de270 100644 --- a/kernel-rs/src/memory/mod.rs +++ b/kernel-rs/src/memory/mod.rs @@ -24,20 +24,27 @@ pub fn init(boot_info: &multiboot2::BootInformation) { let elf_sections_tag = boot_info.elf_sections_tag().unwrap(); let memory_map_tag = boot_info.memory_map_tag().unwrap(); - let kernel_start = elf_sections_tag.sections() + let kernel_start = elf_sections_tag + .sections() .filter(|s| s.is_allocated()) .map(|s| s.start_address()) - .min().unwrap(); + .min() + .unwrap(); - let kernel_end = elf_sections_tag.sections() + let kernel_end = elf_sections_tag + .sections() .filter(|s| s.is_allocated()) .map(|s| s.start_address() + s.size()) - .max().unwrap(); + .max() + .unwrap(); let bump_allocator = BumpFrameAllocator::new( - kernel_start as usize, kernel_end as usize, - boot_info.start_address(), boot_info.end_address(), - memory_map_tag.memory_areas()); + kernel_start as usize, + kernel_end as usize, + boot_info.start_address(), + boot_info.end_address(), + memory_map_tag.memory_areas(), + ); let frame_allocator = RecycleAllocator::new(bump_allocator); diff --git a/kernel-rs/src/memory/recycle.rs b/kernel-rs/src/memory/recycle.rs index 6cebe2b4..69373d5c 100644 --- a/kernel-rs/src/memory/recycle.rs +++ b/kernel-rs/src/memory/recycle.rs @@ -26,7 +26,7 @@ impl RecycleAllocator { } fn merge(&mut self, address: usize, count: usize) -> bool { - for i in 0 .. self.free.len() { + for i in 0..self.free.len() { let changed = { let free = &mut self.free[i]; if address + count * 4096 == free.0 { @@ -97,7 +97,7 @@ impl FrameAllocator for RecycleAllocator { self.inner.deallocate_frames(frame, count); } else { let address = frame.start_address().as_u32() as usize; - if ! self.merge(address, count) { + if !self.merge(address, count) { self.free.push((address, count)); } } diff --git a/kernel-rs/src/vga/mod.rs b/kernel-rs/src/vga/mod.rs index b773b4ff..ba38317b 100644 --- a/kernel-rs/src/vga/mod.rs +++ b/kernel-rs/src/vga/mod.rs @@ -40,7 +40,9 @@ macro_rules! set_color { pub fn print(args: fmt::Arguments) { use core::fmt::Write; - unsafe { self::VGA.write_fmt(args).unwrap(); } + unsafe { + self::VGA.write_fmt(args).unwrap(); + } } extern crate core; @@ -51,7 +53,8 @@ const BUFFER_COLS: usize = 80 * 2; pub struct Writer { pub buffer_pos: usize, pub color_code: ColorCode, - buffer: [u8; BUFFER_ROWS * BUFFER_COLS], command: [u8; 10], + buffer: [u8; BUFFER_ROWS * BUFFER_COLS], + command: [u8; 10], command_len: usize, } @@ -80,13 +83,11 @@ impl Writer { } } - pub fn get_command(&self) -> Result <&str, &'static str> { - + pub fn get_command(&self) -> Result<&str, &'static str> { match core::str::from_utf8(&self.command) { Ok(y) => Ok(&y[..self.command_len]), - Err(_) => Err("Command is not utf8 char") + Err(_) => Err("Command is not utf8 char"), } - } pub fn keypress(&mut self, ascii: u8) { @@ -106,9 +107,11 @@ impl Writer { self.prompt(); } _ if self.command_len >= 10 => (), - byte if self.command_len == 0 && byte == b' ' => (), + byte if self.command_len == 0 && byte == b' ' => (), byte => { - if self.command_len >= 10 { return }; + if self.command_len >= 10 { + return; + }; self.command[self.command_len] = byte; self.write_byte(byte); self.command_len += 1; @@ -130,7 +133,6 @@ impl Writer { let i = self.buffer_pos; match byte { - b'\n' => { let current_line = self.buffer_pos / (BUFFER_COLS); self.buffer_pos = (current_line + 1) * BUFFER_COLS; @@ -178,7 +180,7 @@ impl Writer { } } - for col in 0..BUFFER_COLS/2 { + for col in 0..BUFFER_COLS / 2 { self.buffer[((BUFFER_ROWS - 1) * BUFFER_COLS) + (col * 2)] = b' '; } @@ -199,22 +201,28 @@ impl fmt::Write for Writer { pub fn init() { set_color!(White, Cyan); - print!("{}{}{}{}{}{}{}{}{}{}{}{}{}{}", - format_args!("{: ^80}", r#" ,--, "#), - format_args!("{: ^80}", r#" ,--.'| ,----, "#), - format_args!("{: ^80}", r#" ,--, | : .' .' \ "#), - format_args!("{: ^80}", r#",---.'| : ' ,----,' | "#), - format_args!("{: ^80}", r#"; : | | ; | : . ; "#), - format_args!("{: ^80}", r#"| | : _' | ; |.' / "#), - format_args!("{: ^80}", r#": : |.' | `----'/ ; "#), - format_args!("{: ^80}", r#"| ' ' ; : / ; / "#), - format_args!("{: ^80}", r#"\ \ .'. | ; / /-, "#), - format_args!("{: ^80}", r#" `---`: | ' / / /.`| "#), - format_args!("{: ^80}", r#" ' ; |./__; : "#), - format_args!("{: ^80}", r#" | : ;| : .' "#), - format_args!("{: ^80}", r#" ' ,/ ; | .' "#), - format_args!("{: ^80}", r#" '--' `---' "#)); + print!( + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}", + format_args!("{: ^80}", r#" ,--, "#), + format_args!("{: ^80}", r#" ,--.'| ,----, "#), + format_args!("{: ^80}", r#" ,--, | : .' .' \ "#), + format_args!("{: ^80}", r#",---.'| : ' ,----,' | "#), + format_args!("{: ^80}", r#"; : | | ; | : . ; "#), + format_args!("{: ^80}", r#"| | : _' | ; |.' / "#), + format_args!("{: ^80}", r#": : |.' | `----'/ ; "#), + format_args!("{: ^80}", r#"| ' ' ; : / ; / "#), + format_args!("{: ^80}", r#"\ \ .'. | ; / /-, "#), + format_args!("{: ^80}", r#" `---`: | ' / / /.`| "#), + format_args!("{: ^80}", r#" ' ; |./__; : "#), + format_args!("{: ^80}", r#" | : ;| : .' "#), + format_args!("{: ^80}", r#" ' ,/ ; | .' "#), + format_args!("{: ^80}", r#" '--' `---' "#) + ); set_color!(); - unsafe { VGA.prompt(); } - unsafe { VGA.flush(); } + unsafe { + VGA.prompt(); + } + unsafe { + VGA.flush(); + } }