diff --git a/build.rs b/build.rs index acc24d2292ebdca53b054ebd4b702f1e244845a9..53c7b15d00df6de31278953c3196c5404067540f 100644 --- a/build.rs +++ b/build.rs @@ -1,9 +1,8 @@ +use std::collections::HashMap; use std::env; use std::fs; use std::io::{Error, Write}; use std::path::Path; -use std::collections::HashMap; - // View loc folder with subfolders, get listings // Returns touple (folder_map, file_list) @@ -36,7 +35,9 @@ fn scan_folder(loc: &Path) -> (HashMap<String, Vec<String>>, Vec<String>) { } current.sort(); - folders.entry(String::from(loc.to_str().unwrap()).replace("\\", "/")).or_insert(current); + folders + .entry(String::from(loc.to_str().unwrap()).replace("\\", "/")) + .or_insert(current); } else { panic!("{:?} is not a folder!", loc); } @@ -45,9 +46,9 @@ fn scan_folder(loc: &Path) -> (HashMap<String, Vec<String>>, Vec<String>) { } // Write folder/file information to output file -fn fill_from_location(f: &mut fs::File, loc: &Path ) -> Result<(), (Error)> { +fn fill_from_location(f: &mut fs::File, loc: &Path) -> Result<(), Error> { let (folders, mut files) = scan_folder(loc); - let mut folder_it:Vec<_> = folders.keys().collect(); + let mut folder_it: Vec<_> = folders.keys().collect(); let loc_str = loc.to_str().unwrap(); let mut idx = loc_str.len(); @@ -80,7 +81,11 @@ fn fill_from_location(f: &mut fs::File, loc: &Path ) -> Result<(), (Error)> { for name in files.iter() { let (_, strip) = name.split_at(idx); - write!(f, " files.insert(b\"{}\", (include_bytes!(\"{}\"), false));\n", strip, name)?; + write!( + f, + " files.insert(b\"{}\", (include_bytes!(\"{}\"), false));\n", + strip, name + )?; } Ok(()) @@ -96,29 +101,39 @@ fn main() { let src = env::var("INITFS_FOLDER"); // Write header - f.write_all(b" + f.write_all( + b" mod gen { use alloc::collections::BTreeMap; pub fn gen() -> BTreeMap<&'static [u8], (&'static [u8], bool)> { let mut files: BTreeMap<&'static [u8], (&'static [u8], bool)> = BTreeMap::new(); -").unwrap(); +", + ) + .unwrap(); match src { Ok(v) => { println!("cargo:rerun-if-changed={}", v); fill_from_location(&mut f, Path::new(&v)).unwrap() - }, + } Err(e) => { f.write_all( - b" files.clear();" // Silence mutability warning - ).unwrap(); - println!("cargo:warning=location not found: {}, please set proper INITFS_FOLDER.", e); + b" files.clear();", // Silence mutability warning + ) + .unwrap(); + println!( + "cargo:warning=location not found: {}, please set proper INITFS_FOLDER.", + e + ); } } - f.write_all(b" + f.write_all( + b" files } } -").unwrap(); +", + ) + .unwrap(); } diff --git a/src/arch/x86_64/paging/mod.rs b/src/arch/x86_64/paging/mod.rs index 2b4cce240684c4a1369c3d4795de222e964eaefe..4221cc63035cbe6140f31aa3dca13092dc6fb785 100644 --- a/src/arch/x86_64/paging/mod.rs +++ b/src/arch/x86_64/paging/mod.rs @@ -1,8 +1,8 @@ //! # Paging //! Some code was borrowed from [Phil Opp's Blog](http://os.phil-opp.com/modifying-page-tables.html) -use core::{mem, ptr}; use core::ops::{Deref, DerefMut}; +use core::{mem, ptr}; use spin::Mutex; use x86::shared::{control_regs, msr, tlb}; @@ -45,9 +45,7 @@ fn page_table_lock() { return; } } - unsafe { - crate::arch::interrupt::pause(); - } + crate::arch::interrupt::pause(); } } @@ -75,13 +73,22 @@ unsafe fn init_pat() { let pat6 = pat2; let pat7 = pat3; - msr::wrmsr(msr::IA32_PAT, pat7 << 56 | pat6 << 48 | pat5 << 40 | pat4 << 32 - | pat3 << 24 | pat2 << 16 | pat1 << 8 | pat0); + msr::wrmsr( + msr::IA32_PAT, + pat7 << 56 + | pat6 << 48 + | pat5 << 40 + | pat4 << 32 + | pat3 << 24 + | pat2 << 16 + | pat1 << 8 + | pat0, + ); } /// Copy tdata, clear tbss, set TCB self pointer unsafe fn init_tcb(cpu_id: usize) -> usize { - extern { + extern "C" { /// The starting byte of the thread data segment static mut __tdata_start: u8; /// The ending byte of the thread data segment @@ -94,14 +101,14 @@ unsafe fn init_tcb(cpu_id: usize) -> usize { let tcb_offset; { - let size = & __tbss_end as *const _ as usize - & __tdata_start as *const _ as usize; - let tbss_offset = & __tbss_start as *const _ as usize - & __tdata_start as *const _ as usize; + let size = &__tbss_end as *const _ as usize - &__tdata_start as *const _ as usize; + let tbss_offset = &__tbss_start as *const _ as usize - &__tdata_start as *const _ as usize; let start = crate::KERNEL_PERCPU_OFFSET + crate::KERNEL_PERCPU_SIZE * cpu_id; let end = start + size; tcb_offset = end - mem::size_of::<usize>(); - ptr::copy(& __tdata_start as *const u8, start as *mut u8, tbss_offset); + ptr::copy(&__tdata_start as *const u8, start as *mut u8, tbss_offset); ptr::write_bytes((start + tbss_offset) as *mut u8, 0, size - tbss_offset); *(tcb_offset as *mut usize) = end; @@ -112,8 +119,14 @@ unsafe fn init_tcb(cpu_id: usize) -> usize { /// Initialize paging /// /// Returns page table and thread control block offset -pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_start: usize, stack_end: usize) -> (ActivePageTable, usize) { - extern { +pub unsafe fn init( + cpu_id: usize, + kernel_start: usize, + kernel_end: usize, + stack_start: usize, + stack_end: usize, +) -> (ActivePageTable, usize) { + extern "C" { /// The starting byte of the text (code) data segment. static mut __text_start: u8; /// The ending byte of the text (code) data segment. @@ -144,7 +157,9 @@ pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_ let mut active_table = ActivePageTable::new_unlocked(); - let mut temporary_page = TemporaryPage::new(Page::containing_address(VirtualAddress::new(crate::USER_TMP_MISC_OFFSET))); + let mut temporary_page = TemporaryPage::new(Page::containing_address(VirtualAddress::new( + crate::USER_TMP_MISC_OFFSET, + ))); let mut new_table = { let frame = allocate_frames(1).expect("no more frames in paging::init new_table"); @@ -154,13 +169,28 @@ pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_ active_table.with(&mut new_table, &mut temporary_page, |mapper| { // Remap stack writable, no execute { - let start_frame = Frame::containing_address(PhysicalAddress::new(stack_start - crate::KERNEL_OFFSET)); - let end_frame = Frame::containing_address(PhysicalAddress::new(stack_end - crate::KERNEL_OFFSET - 1)); + let start_frame = + Frame::containing_address(PhysicalAddress::new(stack_start - crate::KERNEL_OFFSET)); + let end_frame = Frame::containing_address(PhysicalAddress::new( + stack_end - crate::KERNEL_OFFSET - 1, + )); for frame in Frame::range_inclusive(start_frame, end_frame) { - let page = Page::containing_address(VirtualAddress::new(frame.start_address().get() + crate::KERNEL_OFFSET)); - let result = mapper.map_to(page, frame, EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE); + let page = Page::containing_address(VirtualAddress::new( + frame.start_address().get() + crate::KERNEL_OFFSET, + )); + let result = mapper.map_to( + page, + frame, + EntryFlags::PRESENT + | EntryFlags::GLOBAL + | EntryFlags::NO_EXECUTE + | EntryFlags::WRITABLE, + ); // The flush can be ignored as this is not the active table. See later active_table.switch - /* unsafe */ { result.ignore(); } + /* unsafe */ + { + result.ignore(); + } } } @@ -173,10 +203,10 @@ pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_ let virt_addr = phys_addr + crate::KERNEL_OFFSET; macro_rules! in_section { - ($n: ident) => ( - virt_addr >= & concat_idents!(__, $n, _start) as *const u8 as usize && - virt_addr < & concat_idents!(__, $n, _end) as *const u8 as usize - ); + ($n: ident) => { + virt_addr >= &concat_idents!(__, $n, _start) as *const u8 as usize + && virt_addr < &concat_idents!(__, $n, _end) as *const u8 as usize + }; } let flags = if in_section!(text) { @@ -187,13 +217,19 @@ pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_ EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE } else if in_section!(data) { // Remap data writable, no execute - EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE + EntryFlags::PRESENT + | EntryFlags::GLOBAL + | EntryFlags::NO_EXECUTE + | EntryFlags::WRITABLE } else if in_section!(tdata) { // Remap tdata master read-only, no execute EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE } else if in_section!(bss) { // Remap bss writable, no execute - EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE + EntryFlags::PRESENT + | EntryFlags::GLOBAL + | EntryFlags::NO_EXECUTE + | EntryFlags::WRITABLE } else { // Remap anything else read-only, no execute EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE @@ -202,13 +238,16 @@ pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_ let page = Page::containing_address(VirtualAddress::new(virt_addr)); let result = mapper.map_to(page, frame, flags); // The flush can be ignored as this is not the active table. See later active_table.switch - /* unsafe */ { result.ignore(); } + /* unsafe */ + { + result.ignore(); + } } } // Map tdata and tbss { - let size = & __tbss_end as *const _ as usize - & __tdata_start as *const _ as usize; + let size = &__tbss_end as *const _ as usize - &__tdata_start as *const _ as usize; let start = crate::KERNEL_PERCPU_OFFSET + crate::KERNEL_PERCPU_SIZE * cpu_id; let end = start + size; @@ -216,7 +255,13 @@ pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_ let start_page = Page::containing_address(VirtualAddress::new(start)); let end_page = Page::containing_address(VirtualAddress::new(end - 1)); for page in Page::range_inclusive(start_page, end_page) { - let result = mapper.map(page, EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE); + let result = mapper.map( + page, + EntryFlags::PRESENT + | EntryFlags::GLOBAL + | EntryFlags::NO_EXECUTE + | EntryFlags::WRITABLE, + ); // The flush can be ignored as this is not the active table. See later active_table.switch result.ignore(); } @@ -230,8 +275,13 @@ pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_ (active_table, init_tcb(cpu_id)) } -pub unsafe fn init_ap(cpu_id: usize, bsp_table: usize, stack_start: usize, stack_end: usize) -> usize { - extern { +pub unsafe fn init_ap( + cpu_id: usize, + bsp_table: usize, + stack_start: usize, + stack_end: usize, +) -> usize { + extern "C" { /// The starting byte of the thread data segment static mut __tdata_start: u8; /// The ending byte of the thread data segment @@ -248,12 +298,14 @@ pub unsafe fn init_ap(cpu_id: usize, bsp_table: usize, stack_start: usize, stack let mut new_table = InactivePageTable::from_address(bsp_table); - let mut temporary_page = TemporaryPage::new(Page::containing_address(VirtualAddress::new(crate::USER_TMP_MISC_OFFSET))); + let mut temporary_page = TemporaryPage::new(Page::containing_address(VirtualAddress::new( + crate::USER_TMP_MISC_OFFSET, + ))); active_table.with(&mut new_table, &mut temporary_page, |mapper| { // Map tdata and tbss { - let size = & __tbss_end as *const _ as usize - & __tdata_start as *const _ as usize; + let size = &__tbss_end as *const _ as usize - &__tdata_start as *const _ as usize; let start = crate::KERNEL_PERCPU_OFFSET + crate::KERNEL_PERCPU_SIZE * cpu_id; let end = start + size; @@ -261,7 +313,13 @@ pub unsafe fn init_ap(cpu_id: usize, bsp_table: usize, stack_start: usize, stack let start_page = Page::containing_address(VirtualAddress::new(start)); let end_page = Page::containing_address(VirtualAddress::new(end - 1)); for page in Page::range_inclusive(start_page, end_page) { - let result = mapper.map(page, EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE); + let result = mapper.map( + page, + EntryFlags::PRESENT + | EntryFlags::GLOBAL + | EntryFlags::NO_EXECUTE + | EntryFlags::WRITABLE, + ); // The flush can be ignored as this is not the active table. See later active_table.switch result.ignore(); } @@ -272,7 +330,9 @@ pub unsafe fn init_ap(cpu_id: usize, bsp_table: usize, stack_start: usize, stack let start_frame = Frame::containing_address(PhysicalAddress::new(start)); let end_frame = Frame::containing_address(PhysicalAddress::new(end - 1)); for frame in Frame::range_inclusive(start_frame, end_frame) { - let page = Page::containing_address(VirtualAddress::new(frame.start_address().get() + crate::KERNEL_OFFSET)); + let page = Page::containing_address(VirtualAddress::new( + frame.start_address().get() + crate::KERNEL_OFFSET, + )); let result = mapper.map_to(page, frame, flags); // The flush can be ignored as this is not the active table. See later active_table.switch result.ignore(); @@ -281,7 +341,14 @@ pub unsafe fn init_ap(cpu_id: usize, bsp_table: usize, stack_start: usize, stack }; // Remap stack writable, no execute - remap(stack_start - crate::KERNEL_OFFSET, stack_end - crate::KERNEL_OFFSET, EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE); + remap( + stack_start - crate::KERNEL_OFFSET, + stack_end - crate::KERNEL_OFFSET, + EntryFlags::PRESENT + | EntryFlags::GLOBAL + | EntryFlags::NO_EXECUTE + | EntryFlags::WRITABLE, + ); }); // This switches the active table, which is setup by the bootloader, to a correct table @@ -328,9 +395,9 @@ impl ActivePageTable { pub fn switch(&mut self, new_table: InactivePageTable) -> InactivePageTable { let old_table = InactivePageTable { - p4_frame: Frame::containing_address( - PhysicalAddress::new(unsafe { control_regs::cr3() } as usize) - ), + p4_frame: Frame::containing_address(PhysicalAddress::new( + unsafe { control_regs::cr3() } as usize, + )), }; unsafe { control_regs::cr3_write(new_table.p4_frame.start_address().get() as u64); @@ -339,31 +406,52 @@ impl ActivePageTable { } pub fn flush(&mut self, page: Page) { - unsafe { tlb::flush(page.start_address().get()); } + unsafe { + tlb::flush(page.start_address().get()); + } } pub fn flush_all(&mut self) { - unsafe { tlb::flush_all(); } + unsafe { + tlb::flush_all(); + } } - pub fn with<F>(&mut self, table: &mut InactivePageTable, temporary_page: &mut TemporaryPage, f: F) - where F: FnOnce(&mut Mapper) + pub fn with<F>( + &mut self, + table: &mut InactivePageTable, + temporary_page: &mut TemporaryPage, + f: F, + ) where + F: FnOnce(&mut Mapper), { { - let backup = Frame::containing_address(PhysicalAddress::new(unsafe { control_regs::cr3() as usize })); + let backup = Frame::containing_address(PhysicalAddress::new(unsafe { + control_regs::cr3() as usize + })); // map temporary_page to current p4 table - let p4_table = temporary_page.map_table_frame(backup.clone(), EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE, self); + let p4_table = temporary_page.map_table_frame( + backup.clone(), + EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE, + self, + ); // overwrite recursive mapping - self.p4_mut()[crate::RECURSIVE_PAGE_PML4].set(table.p4_frame.clone(), EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE); + self.p4_mut()[crate::RECURSIVE_PAGE_PML4].set( + table.p4_frame.clone(), + EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE, + ); self.flush_all(); // execute f in the new context f(self); // restore recursive mapping to original p4 table - p4_table[crate::RECURSIVE_PAGE_PML4].set(backup, EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE); + p4_table[crate::RECURSIVE_PAGE_PML4].set( + backup, + EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE, + ); self.flush_all(); } @@ -389,13 +477,24 @@ pub struct InactivePageTable { } impl InactivePageTable { - pub fn new(frame: Frame, active_table: &mut ActivePageTable, temporary_page: &mut TemporaryPage) -> InactivePageTable { + pub fn new( + frame: Frame, + active_table: &mut ActivePageTable, + temporary_page: &mut TemporaryPage, + ) -> InactivePageTable { { - let table = temporary_page.map_table_frame(frame.clone(), EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE, active_table); + let table = temporary_page.map_table_frame( + frame.clone(), + EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE, + active_table, + ); // now we are able to zero the table table.zero(); // set up recursive mapping for the table - table[crate::RECURSIVE_PAGE_PML4].set(frame.clone(), EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE); + table[crate::RECURSIVE_PAGE_PML4].set( + frame.clone(), + EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE, + ); } temporary_page.unmap(active_table); @@ -403,7 +502,9 @@ impl InactivePageTable { } pub unsafe fn from_address(cr3: usize) -> InactivePageTable { - InactivePageTable { p4_frame: Frame::containing_address(PhysicalAddress::new(cr3)) } + InactivePageTable { + p4_frame: Frame::containing_address(PhysicalAddress::new(cr3)), + } } pub unsafe fn address(&self) -> usize { @@ -442,7 +543,7 @@ impl VirtualAddress { /// Page #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct Page { - number: usize + number: usize, } impl Page { @@ -469,7 +570,9 @@ impl Page { pub fn containing_address(address: VirtualAddress) -> Page { //TODO assert!(address.get() < 0x0000_8000_0000_0000 || address.get() >= 0xffff_8000_0000_0000, // "invalid address: 0x{:x}", address.get()); - Page { number: address.get() / PAGE_SIZE } + Page { + number: address.get() / PAGE_SIZE, + } } pub fn range_inclusive(start: Page, end: Page) -> PageIter { @@ -477,7 +580,9 @@ impl Page { } pub fn next(self) -> Page { - Self { number: self.number + 1 } + Self { + number: self.number + 1, + } } } diff --git a/src/devices/uart_16550.rs b/src/devices/uart_16550.rs index d482504b054c2affbc114df2d5f9d6bcf4d26dad..776303b6ef9b2b089a0266b48c6e3ea3c0bf9b62 100644 --- a/src/devices/uart_16550.rs +++ b/src/devices/uart_16550.rs @@ -1,6 +1,6 @@ use core::convert::TryInto; -use crate::syscall::io::{Io, Pio, Mmio, ReadOnly}; +use crate::syscall::io::{Io, Mmio, Pio, ReadOnly}; bitflags! { /// Interrupt enable flags @@ -51,7 +51,7 @@ impl SerialPort<Pio<u8>> { line_ctrl: Pio::new(base + 3), modem_ctrl: Pio::new(base + 4), line_sts: ReadOnly::new(Pio::new(base + 5)), - modem_sts: ReadOnly::new(Pio::new(base + 6)) + modem_sts: ReadOnly::new(Pio::new(base + 6)), } } } @@ -63,30 +63,37 @@ impl SerialPort<Mmio<u32>> { } impl<T: Io> SerialPort<T> - where T::Value: From<u8> + TryInto<u8> +where + T::Value: From<u8> + TryInto<u8>, { pub fn init(&mut self) { //TODO: Cleanup - self.int_en.write(0x00.into()); - self.line_ctrl.write(0x80.into()); - self.data.write(0x01.into()); - self.int_en.write(0x00.into()); - self.line_ctrl.write(0x03.into()); - self.fifo_ctrl.write(0xC7.into()); - self.modem_ctrl.write(0x0B.into()); - self.int_en.write(0x01.into()); + unsafe { + self.int_en.write(0x00.into()); + self.line_ctrl.write(0x80.into()); + self.data.write(0x01.into()); + self.int_en.write(0x00.into()); + self.line_ctrl.write(0x03.into()); + self.fifo_ctrl.write(0xC7.into()); + self.modem_ctrl.write(0x0B.into()); + self.int_en.write(0x01.into()); + } } fn line_sts(&self) -> LineStsFlags { LineStsFlags::from_bits_truncate( - (self.line_sts.read() & 0xFF.into()).try_into().unwrap_or(0) + (unsafe { self.line_sts.read() } & 0xFF.into()) + .try_into() + .unwrap_or(0), ) } pub fn receive(&mut self) -> Option<u8> { if self.line_sts().contains(LineStsFlags::INPUT_FULL) { Some( - (self.data.read() & 0xFF.into()).try_into().unwrap_or(0) + (unsafe { self.data.read() } & 0xFF.into()) + .try_into() + .unwrap_or(0), ) } else { None @@ -94,8 +101,8 @@ impl<T: Io> SerialPort<T> } pub fn send(&mut self, data: u8) { - while ! self.line_sts().contains(LineStsFlags::OUTPUT_EMPTY) {} - self.data.write(data.into()); + while !self.line_sts().contains(LineStsFlags::OUTPUT_EMPTY) {} + unsafe { self.data.write(data.into()) } } pub fn write(&mut self, buf: &[u8]) { @@ -105,11 +112,11 @@ impl<T: Io> SerialPort<T> self.send(8); self.send(b' '); self.send(8); - }, + } b'\n' => { self.send(b'\r'); self.send(b'\n'); - }, + } _ => { self.send(b); }