From fe88f4f77fd0472e1046597618e78090d095b7e4 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Wed, 27 Mar 2019 18:38:42 +0800 Subject: [PATCH 1/8] Fix sys_readv not updating file offset --- kernel/src/syscall/fs.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index 5081ebf..130fd19 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -273,8 +273,7 @@ pub fn sys_readv(fd: usize, iov_ptr: *const IoVec, iov_count: usize) -> SysResul let mut iovs = IoVecs::check_and_new(iov_ptr, iov_count, &proc.vm, true)?; // read all data to a buf - let mut file = proc.get_file(fd)?.clone(); - drop(proc); + let mut file = proc.get_file(fd)?; let mut buf = iovs.new_buf(true); let len = file.read(buf.as_mut_slice())?; // copy data to user From b836b1179274d4f8e547cb32353225a9bb9281ef Mon Sep 17 00:00:00 2001 From: WangRunji Date: Wed, 27 Mar 2019 18:35:08 +0800 Subject: [PATCH 2/8] reformat code using `cargo fmt` --- crate/bit-allocator/src/lib.rs | 12 +- crate/memory/src/addr.rs | 34 ++- crate/memory/src/cow.rs | 134 ++++---- crate/memory/src/lib.rs | 10 +- .../memory/src/memory_set/handler/byframe.rs | 2 +- crate/memory/src/memory_set/handler/linear.rs | 2 +- crate/memory/src/memory_set/handler/mod.rs | 6 +- crate/memory/src/memory_set/mod.rs | 285 +++++++++++------- crate/memory/src/no_mmu.rs | 18 +- crate/memory/src/paging/ext.rs | 11 +- crate/memory/src/paging/mock_page_table.rs | 148 +++++---- crate/memory/src/paging/mod.rs | 9 +- crate/memory/src/swap/fifo.rs | 22 +- crate/memory/src/swap/mock_swapper.rs | 26 +- crate/memory/src/swap/mod.rs | 273 ++++++++++------- crate/sync/src/main.rs | 6 +- crate/sync/src/monitor.rs | 31 +- crate/sync/src/mutex.rs | 25 +- crate/thread/build.rs | 3 +- crate/thread/src/lib.rs | 6 +- crate/thread/src/processor.rs | 36 ++- crate/thread/src/scheduler/rr.rs | 6 +- crate/thread/src/scheduler/stride.rs | 6 +- crate/thread/src/std_thread.rs | 25 +- crate/thread/src/thread_pool.rs | 23 +- crate/thread/src/timer.rs | 4 +- kernel/build.rs | 69 ++--- kernel/src/arch/aarch64/board/raspi3/fb.rs | 10 +- .../src/arch/aarch64/board/raspi3/mailbox.rs | 201 ++++++------ kernel/src/arch/aarch64/board/raspi3/mod.rs | 6 +- .../src/arch/aarch64/board/raspi3/serial.rs | 4 +- .../aarch64/driver/console/fonts/font8x16.rs | 255 ---------------- kernel/src/arch/aarch64/driver/console/mod.rs | 12 +- kernel/src/arch/aarch64/interrupt/context.rs | 60 ++-- kernel/src/arch/aarch64/interrupt/handler.rs | 2 +- kernel/src/arch/aarch64/interrupt/mod.rs | 2 +- kernel/src/arch/aarch64/io.rs | 2 +- kernel/src/arch/aarch64/memory.rs | 64 +++- kernel/src/arch/aarch64/mod.rs | 12 +- kernel/src/arch/aarch64/paging.rs | 163 ++++++---- kernel/src/arch/aarch64/rand.rs | 2 +- kernel/src/arch/aarch64/timer.rs | 2 +- kernel/src/arch/riscv32/board/u540/mod.rs | 5 +- kernel/src/arch/riscv32/compiler_rt.rs | 2 +- kernel/src/arch/riscv32/consts.rs | 2 +- kernel/src/arch/riscv32/context.rs | 79 +++-- kernel/src/arch/riscv32/cpu.rs | 4 +- kernel/src/arch/riscv32/interrupt.rs | 36 ++- kernel/src/arch/riscv32/io.rs | 4 +- kernel/src/arch/riscv32/memory.rs | 95 ++++-- kernel/src/arch/riscv32/mod.rs | 51 ++-- kernel/src/arch/riscv32/paging.rs | 152 ++++++---- kernel/src/arch/riscv32/rand.rs | 2 +- kernel/src/arch/riscv32/sbi.rs | 14 +- kernel/src/arch/riscv32/timer.rs | 6 +- kernel/src/arch/x86_64/cpu.rs | 7 +- kernel/src/arch/x86_64/driver/ide.rs | 35 ++- kernel/src/arch/x86_64/driver/keyboard.rs | 13 +- kernel/src/arch/x86_64/driver/mod.rs | 10 +- kernel/src/arch/x86_64/driver/pic.rs | 14 +- kernel/src/arch/x86_64/driver/pit.rs | 10 +- kernel/src/arch/x86_64/driver/rtc_cmos.rs | 3 +- kernel/src/arch/x86_64/driver/vga.rs | 30 +- kernel/src/arch/x86_64/gdt.rs | 25 +- kernel/src/arch/x86_64/idt.rs | 8 +- kernel/src/arch/x86_64/interrupt/consts.rs | 2 +- .../src/arch/x86_64/interrupt/fast_syscall.rs | 9 +- kernel/src/arch/x86_64/interrupt/handler.rs | 22 +- kernel/src/arch/x86_64/interrupt/mod.rs | 8 +- kernel/src/arch/x86_64/interrupt/trapframe.rs | 60 +++- kernel/src/arch/x86_64/io.rs | 14 +- kernel/src/arch/x86_64/memory.rs | 20 +- kernel/src/arch/x86_64/mod.rs | 16 +- kernel/src/arch/x86_64/paging.rs | 104 +++++-- kernel/src/arch/x86_64/timer.rs | 2 +- kernel/src/backtrace.rs | 17 +- kernel/src/drivers/device_tree.rs | 2 +- kernel/src/drivers/mod.rs | 2 +- kernel/src/fs/device.rs | 14 +- kernel/src/fs/file.rs | 12 +- kernel/src/fs/mod.rs | 20 +- kernel/src/fs/stdio.rs | 12 +- kernel/src/lang.rs | 13 +- kernel/src/lib.rs | 24 +- kernel/src/logging.rs | 14 +- kernel/src/main.rs | 2 +- kernel/src/memory.rs | 46 +-- kernel/src/net/structs.rs | 2 +- kernel/src/process/abi.rs | 38 ++- kernel/src/process/mod.rs | 26 +- kernel/src/process/structs.rs | 143 ++++++--- kernel/src/shell.rs | 24 +- kernel/src/sync/condvar.rs | 9 +- kernel/src/sync/mod.rs | 4 +- kernel/src/sync/mpsc.rs | 14 +- kernel/src/sync/mutex.rs | 59 ++-- kernel/src/sync/semaphore.rs | 2 +- kernel/src/sync/test.rs | 53 ++-- kernel/src/syscall/custom.rs | 8 +- kernel/src/syscall/fs.rs | 277 ++++++++++------- kernel/src/syscall/mem.rs | 7 +- kernel/src/syscall/misc.rs | 13 +- kernel/src/syscall/mod.rs | 115 +++++-- kernel/src/syscall/proc.rs | 70 ++++- kernel/src/syscall/time.rs | 8 +- kernel/src/trap.rs | 12 +- kernel/src/util/escape_parser.rs | 8 +- kernel/src/util/mod.rs | 2 +- 108 files changed, 2324 insertions(+), 1641 deletions(-) diff --git a/crate/bit-allocator/src/lib.rs b/crate/bit-allocator/src/lib.rs index a147aa0..6c30948 100644 --- a/crate/bit-allocator/src/lib.rs +++ b/crate/bit-allocator/src/lib.rs @@ -80,8 +80,16 @@ impl BitAllocCascade16 { assert!(start <= end); assert!(end <= Self::CAP); for i in start / T::CAP..=(end - 1) / T::CAP { - let begin = if start / T::CAP == i { start % T::CAP } else { 0 }; - let end = if end / T::CAP == i { end % T::CAP } else { T::CAP }; + let begin = if start / T::CAP == i { + start % T::CAP + } else { + 0 + }; + let end = if end / T::CAP == i { + end % T::CAP + } else { + T::CAP + }; f(&mut self.sub[i], begin..end); self.bitset.set_bit(i, self.sub[i].any()); } diff --git a/crate/memory/src/addr.rs b/crate/memory/src/addr.rs index c5ea30d..9239081 100644 --- a/crate/memory/src/addr.rs +++ b/crate/memory/src/addr.rs @@ -12,27 +12,29 @@ pub struct Page { impl Page { /* - ** @brief get the virtual address of beginning of the page - ** @retval VirtAddr the virtual address of beginning of the page - */ + ** @brief get the virtual address of beginning of the page + ** @retval VirtAddr the virtual address of beginning of the page + */ pub fn start_address(&self) -> VirtAddr { self.number * PAGE_SIZE } /* - ** @brief get the page of a given virtual address - ** @param addr: VirtAddr the given virtual address - ** @retval Page the page of the given virtual address - */ + ** @brief get the page of a given virtual address + ** @param addr: VirtAddr the given virtual address + ** @retval Page the page of the given virtual address + */ pub fn of_addr(addr: VirtAddr) -> Self { - Page { number: addr / PAGE_SIZE } + Page { + number: addr / PAGE_SIZE, + } } /* - ** @brief get a pageRange between two virtual address - ** @param begin: VirtAddr the virtual address of the beginning - ** @param end: VirtAddr the virtual address of the end - ** @retval PageRange the page of the given virtual address - */ + ** @brief get a pageRange between two virtual address + ** @param begin: VirtAddr the virtual address of the beginning + ** @param end: VirtAddr the virtual address of the end + ** @retval PageRange the page of the given virtual address + */ pub fn range_of(begin: VirtAddr, end: VirtAddr) -> PageRange { PageRange { start: Page::of_addr(begin), @@ -44,7 +46,9 @@ impl Page { impl Add for Page { type Output = Self; fn add(self, rhs: usize) -> Self::Output { - Page { number: self.number + rhs } + Page { + number: self.number + rhs, + } } } @@ -116,4 +120,4 @@ impl PartialEq for Frame { } } -impl Eq for Frame {} \ No newline at end of file +impl Eq for Frame {} diff --git a/crate/memory/src/cow.rs b/crate/memory/src/cow.rs index e616e42..2ee6b10 100644 --- a/crate/memory/src/cow.rs +++ b/crate/memory/src/cow.rs @@ -33,10 +33,10 @@ pub struct CowExt { impl CowExt { /* - ** @brief create a COW extension - ** @param page_table: T the inner page table - ** @retval CowExt the COW extension created - */ + ** @brief create a COW extension + ** @param page_table: T the inner page table + ** @retval CowExt the COW extension created + */ pub fn new(page_table: T) -> Self { CowExt { page_table, @@ -44,13 +44,13 @@ impl CowExt { } } /* - ** @brief map the virtual address to a target physics address as shared - ** @param addr: VirtAddr the virual address to map - ** @param target: VirtAddr the target physics address - ** @param writable: bool if it is true, set the page as writable and shared - ** else set the page as readonly and shared - ** @retval none - */ + ** @brief map the virtual address to a target physics address as shared + ** @param addr: VirtAddr the virual address to map + ** @param target: VirtAddr the target physics address + ** @param writable: bool if it is true, set the page as writable and shared + ** else set the page as readonly and shared + ** @retval none + */ pub fn map_to_shared(&mut self, addr: VirtAddr, target: PhysAddr, writable: bool) { let entry = self.page_table.map(addr, target); entry.set_writable(false); @@ -63,14 +63,13 @@ impl CowExt { } } /* - ** @brief unmap a virual address from physics address - ** with apecial additional process for shared page - ** @param addr: VirtAddr the virual address to unmap - ** @retval none - */ + ** @brief unmap a virual address from physics address + ** with apecial additional process for shared page + ** @param addr: VirtAddr the virual address to unmap + ** @retval none + */ pub fn unmap_shared(&mut self, addr: VirtAddr) { - let entry = self.page_table.get_entry(addr) - .expect("entry not exist"); + let entry = self.page_table.get_entry(addr).expect("entry not exist"); let frame = entry.target() / PAGE_SIZE; if entry.readonly_shared() { self.rc_map.read_decrease(&frame); @@ -80,16 +79,20 @@ impl CowExt { self.page_table.unmap(addr); } /* - ** @brief execute the COW process for page fault - ** This function must be called whenever PageFault happens. - ** @param addr: VirtAddr the virual address of the page fault - ** @param alloc_frame: impl FnOnce() -> PhysAddr - ** the page allocation function - ** that allocate a page and returns physics address - ** of beginning of the page - ** @retval bool whether copy-on-write happens. - */ - pub fn page_fault_handler(&mut self, addr: VirtAddr, alloc_frame: impl FnOnce() -> PhysAddr) -> bool { + ** @brief execute the COW process for page fault + ** This function must be called whenever PageFault happens. + ** @param addr: VirtAddr the virual address of the page fault + ** @param alloc_frame: impl FnOnce() -> PhysAddr + ** the page allocation function + ** that allocate a page and returns physics address + ** of beginning of the page + ** @retval bool whether copy-on-write happens. + */ + pub fn page_fault_handler( + &mut self, + addr: VirtAddr, + alloc_frame: impl FnOnce() -> PhysAddr, + ) -> bool { let entry = self.page_table.get_entry(addr); if entry.is_none() { return false; @@ -113,7 +116,8 @@ impl CowExt { self.unmap_shared(addr); self.map(addr, alloc_frame()); - self.get_page_slice_mut(addr).copy_from_slice(&temp_data[..]); + self.get_page_slice_mut(addr) + .copy_from_slice(&temp_data[..]); true } } @@ -142,60 +146,60 @@ type Frame = usize; impl FrameRcMap { /* - ** @brief get the read reference count of the frame - ** @param frame: &Frame the frame to get the read reference count - ** @retval u16 the read reference count - */ + ** @brief get the read reference count of the frame + ** @param frame: &Frame the frame to get the read reference count + ** @retval u16 the read reference count + */ fn read_count(&mut self, frame: &Frame) -> u16 { self.map().get(frame).unwrap_or(&(0, 0)).0 } /* - ** @brief get the write reference count of the frame - ** @param frame: &Frame the frame to get the write reference count - ** @retval u16 the write reference count - */ + ** @brief get the write reference count of the frame + ** @param frame: &Frame the frame to get the write reference count + ** @retval u16 the write reference count + */ fn write_count(&mut self, frame: &Frame) -> u16 { self.map().get(frame).unwrap_or(&(0, 0)).1 } /* - ** @brief increase the read reference count of the frame - ** @param frame: &Frame the frame to increase the read reference count - ** @retval none - */ + ** @brief increase the read reference count of the frame + ** @param frame: &Frame the frame to increase the read reference count + ** @retval none + */ fn read_increase(&mut self, frame: &Frame) { let (r, w) = self.map().get(&frame).unwrap_or(&(0, 0)).clone(); self.map().insert(frame.clone(), (r + 1, w)); } /* - ** @brief decrease the read reference count of the frame - ** @param frame: &Frame the frame to decrease the read reference count - ** @retval none - */ + ** @brief decrease the read reference count of the frame + ** @param frame: &Frame the frame to decrease the read reference count + ** @retval none + */ fn read_decrease(&mut self, frame: &Frame) { self.map().get_mut(frame).unwrap().0 -= 1; } /* - ** @brief increase the write reference count of the frame - ** @param frame: &Frame the frame to increase the write reference count - ** @retval none - */ + ** @brief increase the write reference count of the frame + ** @param frame: &Frame the frame to increase the write reference count + ** @retval none + */ fn write_increase(&mut self, frame: &Frame) { let (r, w) = self.map().get(&frame).unwrap_or(&(0, 0)).clone(); self.map().insert(frame.clone(), (r, w + 1)); } /* - ** @brief decrease the write reference count of the frame - ** @param frame: &Frame the frame to decrease the write reference count - ** @retval none - */ + ** @brief decrease the write reference count of the frame + ** @param frame: &Frame the frame to decrease the write reference count + ** @retval none + */ fn write_decrease(&mut self, frame: &Frame) { self.map().get_mut(frame).unwrap().1 -= 1; } /* - ** @brief get the internal btree map, lazily initialize the btree map if it is not present - ** @retval &mut BTreeMap - ** the internal btree map - */ + ** @brief get the internal btree map, lazily initialize the btree map if it is not present + ** @retval &mut BTreeMap + ** the internal btree map + */ fn map(&mut self) -> &mut BTreeMap { if self.0.is_none() { self.0 = Some(BTreeMap::new()); @@ -222,9 +226,10 @@ pub mod test { } let mut alloc = FrameAlloc(4); - pt.page_table.set_handler(Box::new(move |_, addr: VirtAddr| { - pt0.page_fault_handler(addr, || alloc.alloc()); - })); + pt.page_table + .set_handler(Box::new(move |_, addr: VirtAddr| { + pt0.page_fault_handler(addr, || alloc.alloc()); + })); test_with(&mut pt); } @@ -263,9 +268,12 @@ pub mod test { pt.write(0x2000, 3); assert_eq!(pt.rc_map.read_count(&frame), 0); assert_eq!(pt.rc_map.write_count(&frame), 0); - assert_eq!(pt.get_entry(0x2000).unwrap().target(), target, - "The last write reference should not allocate new frame."); + assert_eq!( + pt.get_entry(0x2000).unwrap().target(), + target, + "The last write reference should not allocate new frame." + ); assert_eq!(pt.read(0x1000), 2); assert_eq!(pt.read(0x2000), 3); } -} \ No newline at end of file +} diff --git a/crate/memory/src/lib.rs b/crate/memory/src/lib.rs index a162b20..d4b5dc5 100644 --- a/crate/memory/src/lib.rs +++ b/crate/memory/src/lib.rs @@ -6,17 +6,17 @@ use log::*; extern crate alloc; -pub mod paging; +mod addr; pub mod cow; -pub mod swap; pub mod memory_set; -mod addr; pub mod no_mmu; +pub mod paging; +pub mod swap; pub use crate::addr::*; pub enum VMError { - InvalidPtr + InvalidPtr, } -pub type VMResult = Result; \ No newline at end of file +pub type VMResult = Result; diff --git a/crate/memory/src/memory_set/handler/byframe.rs b/crate/memory/src/memory_set/handler/byframe.rs index 89b45cc..e7f90db 100644 --- a/crate/memory/src/memory_set/handler/byframe.rs +++ b/crate/memory/src/memory_set/handler/byframe.rs @@ -31,4 +31,4 @@ impl ByFrame { pub fn new(allocator: T) -> Self { ByFrame { allocator } } -} \ No newline at end of file +} diff --git a/crate/memory/src/memory_set/handler/linear.rs b/crate/memory/src/memory_set/handler/linear.rs index a3c8bab..1e10b90 100644 --- a/crate/memory/src/memory_set/handler/linear.rs +++ b/crate/memory/src/memory_set/handler/linear.rs @@ -29,4 +29,4 @@ impl Linear { pub fn new(offset: isize) -> Self { Linear { offset } } -} \ No newline at end of file +} diff --git a/crate/memory/src/memory_set/handler/mod.rs b/crate/memory/src/memory_set/handler/mod.rs index 68fdf16..fd6602c 100644 --- a/crate/memory/src/memory_set/handler/mod.rs +++ b/crate/memory/src/memory_set/handler/mod.rs @@ -7,7 +7,7 @@ pub trait MemoryHandler: Debug + 'static { /// Map `addr` in the page table /// Should set page flags here instead of in page_fault_handler fn map(&self, pt: &mut PageTable, addr: VirtAddr, attr: &MemoryAttr); - + /// Map `addr` in the page table eagerly (i.e. no delay allocation) /// Should set page flags here instead of in page_fault_handler fn map_eager(&self, pt: &mut PageTable, addr: VirtAddr, attr: &MemoryAttr) { @@ -34,11 +34,11 @@ pub trait FrameAllocator: Debug + Clone + 'static { fn dealloc(&self, target: PhysAddr); } -mod linear; mod byframe; mod delay; +mod linear; //mod swap; -pub use self::linear::Linear; pub use self::byframe::ByFrame; pub use self::delay::Delay; +pub use self::linear::Linear; diff --git a/crate/memory/src/memory_set/mod.rs b/crate/memory/src/memory_set/mod.rs index adbe962..77eddc1 100644 --- a/crate/memory/src/memory_set/mod.rs +++ b/crate/memory/src/memory_set/mod.rs @@ -1,7 +1,7 @@ //! memory set, area //! and the inactive page table -use alloc::{boxed::Box, vec::Vec, string::String}; +use alloc::{boxed::Box, string::String, vec::Vec}; use core::fmt::{Debug, Error, Formatter}; use crate::paging::*; @@ -23,35 +23,40 @@ pub struct MemoryArea { name: &'static str, } -unsafe impl Send for MemoryArea { } +unsafe impl Send for MemoryArea {} impl MemoryArea { /* - ** @brief get slice of the content in the memory area - ** @retval &[u8] the slice of the content in the memory area - */ + ** @brief get slice of the content in the memory area + ** @retval &[u8] the slice of the content in the memory area + */ pub unsafe fn as_slice(&self) -> &[u8] { - ::core::slice::from_raw_parts(self.start_addr as *const u8, self.end_addr - self.start_addr) + ::core::slice::from_raw_parts( + self.start_addr as *const u8, + self.end_addr - self.start_addr, + ) } /* - ** @brief get mutable slice of the content in the memory area - ** @retval &mut[u8] the mutable slice of the content in the memory area - */ + ** @brief get mutable slice of the content in the memory area + ** @retval &mut[u8] the mutable slice of the content in the memory area + */ pub unsafe fn as_slice_mut(&self) -> &mut [u8] { - ::core::slice::from_raw_parts_mut(self.start_addr as *mut u8, self.end_addr - self.start_addr) + ::core::slice::from_raw_parts_mut( + self.start_addr as *mut u8, + self.end_addr - self.start_addr, + ) } /* - ** @brief test whether a virtual address is in the memory area - ** @param addr: VirtAddr the virtual address to test - ** @retval bool whether the virtual address is in the memory area - */ + ** @brief test whether a virtual address is in the memory area + ** @param addr: VirtAddr the virtual address to test + ** @retval bool whether the virtual address is in the memory area + */ pub fn contains(&self, addr: VirtAddr) -> bool { addr >= self.start_addr && addr < self.end_addr } /// Check the array is within the readable memory fn check_read_array(&self, ptr: *const S, count: usize) -> bool { - ptr as usize >= self.start_addr && - unsafe { ptr.add(count) as usize } <= self.end_addr + ptr as usize >= self.start_addr && unsafe { ptr.add(count) as usize } <= self.end_addr } /// Check the array is within the writable memory fn check_write_array(&self, ptr: *mut S, count: usize) -> bool { @@ -80,30 +85,30 @@ impl MemoryArea { !(p1 <= p2 || p0 >= p3) } /* - ** @brief map the memory area to the physice address in a page table - ** @param pt: &mut T::Active the page table to use - ** @retval none - */ + ** @brief map the memory area to the physice address in a page table + ** @param pt: &mut T::Active the page table to use + ** @retval none + */ fn map(&self, pt: &mut PageTable) { for page in Page::range_of(self.start_addr, self.end_addr) { self.handler.map(pt, page.start_address(), &self.attr); } } /* - ** @brief map the memory area to the physice address in a page table eagerly - ** @param pt: &mut T::Active the page table to use - ** @retval none - */ + ** @brief map the memory area to the physice address in a page table eagerly + ** @param pt: &mut T::Active the page table to use + ** @retval none + */ fn map_eager(&self, pt: &mut PageTable) { for page in Page::range_of(self.start_addr, self.end_addr) { self.handler.map_eager(pt, page.start_address(), &self.attr); } } /* - ** @brief unmap the memory area from the physice address in a page table - ** @param pt: &mut T::Active the page table to use - ** @retval none - */ + ** @brief unmap the memory area from the physice address in a page table + ** @param pt: &mut T::Active the page table to use + ** @retval none + */ fn unmap(&self, pt: &mut PageTable) { for page in Page::range_of(self.start_addr, self.end_addr) { self.handler.unmap(pt, page.start_address()); @@ -122,41 +127,41 @@ pub struct MemoryAttr { impl MemoryAttr { /* - ** @brief set the memory attribute's user bit - ** @retval MemoryAttr the memory attribute itself - */ + ** @brief set the memory attribute's user bit + ** @retval MemoryAttr the memory attribute itself + */ pub fn user(mut self) -> Self { self.user = true; self } /* - ** @brief set the memory attribute's readonly bit - ** @retval MemoryAttr the memory attribute itself - */ + ** @brief set the memory attribute's readonly bit + ** @retval MemoryAttr the memory attribute itself + */ pub fn readonly(mut self) -> Self { self.readonly = true; self } /* - ** @brief unset the memory attribute's readonly bit - ** @retval MemoryAttr the memory attribute itself - */ + ** @brief unset the memory attribute's readonly bit + ** @retval MemoryAttr the memory attribute itself + */ pub fn writable(mut self) -> Self { self.readonly = false; self } /* - ** @brief set the memory attribute's execute bit - ** @retval MemoryAttr the memory attribute itself - */ + ** @brief set the memory attribute's execute bit + ** @retval MemoryAttr the memory attribute itself + */ pub fn execute(mut self) -> Self { self.execute = true; self } /* - ** @brief set the MMIO type - ** @retval MemoryAttr the memory attribute itself - */ + ** @brief set the MMIO type + ** @retval MemoryAttr the memory attribute itself + */ pub fn mmio(mut self, value: u8) -> Self { self.mmio = value; self @@ -181,9 +186,9 @@ pub struct MemorySet { impl MemorySet { /* - ** @brief create a memory set - ** @retval MemorySet the memory set created - */ + ** @brief create a memory set + ** @retval MemorySet the memory set created + */ pub fn new() -> Self { MemorySet { areas: Vec::new(), @@ -206,24 +211,30 @@ impl MemorySet { } /// Check the array is within the readable memory pub fn check_read_array(&self, ptr: *const S, count: usize) -> VMResult<()> { - self.areas.iter() + self.areas + .iter() .find(|area| area.check_read_array(ptr, count)) - .map(|_|()).ok_or(VMError::InvalidPtr) + .map(|_| ()) + .ok_or(VMError::InvalidPtr) } /// Check the array is within the writable memory pub fn check_write_array(&self, ptr: *mut S, count: usize) -> VMResult<()> { - self.areas.iter() + self.areas + .iter() .find(|area| area.check_write_array(ptr, count)) - .map(|_|()).ok_or(VMError::InvalidPtr) + .map(|_| ()) + .ok_or(VMError::InvalidPtr) } /// Check the null-end C string is within the readable memory, and is valid. /// If so, clone it to a String. /// /// Unsafe: the page table must be active. pub unsafe fn check_and_clone_cstr(&self, ptr: *const u8) -> VMResult { - self.areas.iter() + self.areas + .iter() .filter_map(|area| area.check_and_clone_cstr(ptr)) - .next().ok_or(VMError::InvalidPtr) + .next() + .ok_or(VMError::InvalidPtr) } /// Find a free area with hint address `addr_hint` and length `len`. /// Return the start address of found free area. @@ -239,28 +250,45 @@ impl MemorySet { } /// Test if [`start_addr`, `end_addr`) is a free area fn test_free_area(&self, start_addr: usize, end_addr: usize) -> bool { - self.areas.iter() + self.areas + .iter() .find(|area| area.is_overlap_with(start_addr, end_addr)) .is_none() } /* - ** @brief add the memory area to the memory set - ** @param area: MemoryArea the memory area to add - ** @retval none - */ - pub fn push(&mut self, start_addr: VirtAddr, end_addr: VirtAddr, attr: MemoryAttr, handler: impl MemoryHandler, name: &'static str) { + ** @brief add the memory area to the memory set + ** @param area: MemoryArea the memory area to add + ** @retval none + */ + pub fn push( + &mut self, + start_addr: VirtAddr, + end_addr: VirtAddr, + attr: MemoryAttr, + handler: impl MemoryHandler, + name: &'static str, + ) { assert!(start_addr <= end_addr, "invalid memory area"); - assert!(self.test_free_area(start_addr, end_addr), "memory area overlap"); - let area = MemoryArea { start_addr, end_addr, attr, handler: Box::new(handler), name }; + assert!( + self.test_free_area(start_addr, end_addr), + "memory area overlap" + ); + let area = MemoryArea { + start_addr, + end_addr, + attr, + handler: Box::new(handler), + name, + }; self.page_table.edit(|pt| area.map(pt)); self.areas.push(area); } /* - ** @brief remove the memory area from the memory set - ** @param area: MemoryArea the memory area to remove - ** @retval none - */ + ** @brief remove the memory area from the memory set + ** @param area: MemoryArea the memory area to remove + ** @retval none + */ pub fn pop(&mut self, start_addr: VirtAddr, end_addr: VirtAddr) { assert!(start_addr <= end_addr, "invalid memory area"); for i in 0..self.areas.len() { @@ -274,10 +302,10 @@ impl MemorySet { } /* - ** @brief remove the memory area from the memory set and split existed ones when necessary - ** @param area: MemoryArea the memory area to remove - ** @retval none - */ + ** @brief remove the memory area from the memory set and split existed ones when necessary + ** @param area: MemoryArea the memory area to remove + ** @retval none + */ pub fn pop_with_split(&mut self, start_addr: VirtAddr, end_addr: VirtAddr) { assert!(start_addr <= end_addr, "invalid memory area"); let mut i = 0; @@ -288,28 +316,73 @@ impl MemorySet { let area = self.areas.remove(i); self.page_table.edit(|pt| area.unmap(pt)); i -= 1; - } else if self.areas[i].start_addr >= start_addr && self.areas[i].start_addr < end_addr { + } else if self.areas[i].start_addr >= start_addr + && self.areas[i].start_addr < end_addr + { // prefix let area = self.areas.remove(i); - let dead_area = MemoryArea { start_addr: area.start_addr, end_addr, attr: area.attr, handler: area.handler.box_clone(), name: area.name }; + let dead_area = MemoryArea { + start_addr: area.start_addr, + end_addr, + attr: area.attr, + handler: area.handler.box_clone(), + name: area.name, + }; self.page_table.edit(|pt| dead_area.unmap(pt)); - let new_area = MemoryArea { start_addr: end_addr, end_addr: area.end_addr, attr: area.attr, handler: area.handler, name: area.name }; + let new_area = MemoryArea { + start_addr: end_addr, + end_addr: area.end_addr, + attr: area.attr, + handler: area.handler, + name: area.name, + }; self.areas.insert(i, new_area); - } else if self.areas[i].end_addr <= end_addr && self.areas[i].end_addr > start_addr { + } else if self.areas[i].end_addr <= end_addr && self.areas[i].end_addr > start_addr + { // postfix let area = self.areas.remove(i); - let dead_area = MemoryArea { start_addr: start_addr, end_addr: area.end_addr, attr: area.attr, handler: area.handler.box_clone(), name: area.name }; + let dead_area = MemoryArea { + start_addr: start_addr, + end_addr: area.end_addr, + attr: area.attr, + handler: area.handler.box_clone(), + name: area.name, + }; self.page_table.edit(|pt| dead_area.unmap(pt)); - let new_area = MemoryArea { start_addr: area.start_addr, end_addr: start_addr, attr: area.attr, handler: area.handler, name: area.name }; + let new_area = MemoryArea { + start_addr: area.start_addr, + end_addr: start_addr, + attr: area.attr, + handler: area.handler, + name: area.name, + }; self.areas.insert(i, new_area); } else { // superset let area = self.areas.remove(i); - let dead_area = MemoryArea { start_addr: start_addr, end_addr: end_addr, attr: area.attr, handler: area.handler.box_clone(), name: area.name }; + let dead_area = MemoryArea { + start_addr: start_addr, + end_addr: end_addr, + attr: area.attr, + handler: area.handler.box_clone(), + name: area.name, + }; self.page_table.edit(|pt| dead_area.unmap(pt)); - let new_area_left = MemoryArea { start_addr: area.start_addr, end_addr: start_addr, attr: area.attr, handler: area.handler.box_clone(), name: area.name }; + let new_area_left = MemoryArea { + start_addr: area.start_addr, + end_addr: start_addr, + attr: area.attr, + handler: area.handler.box_clone(), + name: area.name, + }; self.areas.insert(i, new_area_left); - let new_area_right = MemoryArea { start_addr: end_addr, end_addr: area.end_addr, attr: area.attr, handler: area.handler, name: area.name }; + let new_area_right = MemoryArea { + start_addr: end_addr, + end_addr: area.end_addr, + attr: area.attr, + handler: area.handler, + name: area.name, + }; self.areas.insert(i + 1, new_area_right); i += 1; } @@ -319,44 +392,48 @@ impl MemorySet { } /* - ** @brief get iterator of the memory area - ** @retval impl Iterator - ** the memory area iterator - */ - pub fn iter(&self) -> impl Iterator { + ** @brief get iterator of the memory area + ** @retval impl Iterator + ** the memory area iterator + */ + pub fn iter(&self) -> impl Iterator { self.areas.iter() } pub fn edit(&mut self, f: impl FnOnce(&mut T::Active)) { self.page_table.edit(f); } /* - ** @brief execute function with the associated page table - ** @param f: impl FnOnce() the function to be executed - ** @retval none - */ + ** @brief execute function with the associated page table + ** @param f: impl FnOnce() the function to be executed + ** @retval none + */ pub unsafe fn with(&self, f: impl FnOnce()) { self.page_table.with(f); } /* - ** @brief activate the associated page table - ** @retval none - */ + ** @brief activate the associated page table + ** @retval none + */ pub unsafe fn activate(&self) { self.page_table.activate(); } /* - ** @brief get the token of the associated page table - ** @retval usize the token of the inactive page table - */ + ** @brief get the token of the associated page table + ** @retval usize the token of the inactive page table + */ pub fn token(&self) -> usize { self.page_table.token() } /* - ** @brief clear the memory set - ** @retval none - */ + ** @brief clear the memory set + ** @retval none + */ pub fn clear(&mut self) { - let Self { ref mut page_table, ref mut areas, .. } = self; + let Self { + ref mut page_table, + ref mut areas, + .. + } = self; page_table.edit(|pt| { for area in areas.iter() { area.unmap(pt); @@ -379,17 +456,19 @@ impl MemorySet { } /* - ** @brief get the mutable reference for the inactive page table - ** @retval: &mut T the mutable reference of the inactive page table - */ - pub fn get_page_table_mut(&mut self) -> &mut T{ + ** @brief get the mutable reference for the inactive page table + ** @retval: &mut T the mutable reference of the inactive page table + */ + pub fn get_page_table_mut(&mut self) -> &mut T { &mut self.page_table } pub fn handle_page_fault(&mut self, addr: VirtAddr) -> bool { let area = self.areas.iter().find(|area| area.contains(addr)); match area { - Some(area) => self.page_table.edit(|pt| area.handler.handle_page_fault(pt, addr)), + Some(area) => self + .page_table + .edit(|pt| area.handler.handle_page_fault(pt, addr)), None => false, } } @@ -419,8 +498,6 @@ impl Drop for MemorySet { impl Debug for MemorySet { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { - f.debug_list() - .entries(self.areas.iter()) - .finish() + f.debug_list().entries(self.areas.iter()).finish() } } diff --git a/crate/memory/src/no_mmu.rs b/crate/memory/src/no_mmu.rs index 8d2f966..e1d128f 100644 --- a/crate/memory/src/no_mmu.rs +++ b/crate/memory/src/no_mmu.rs @@ -1,5 +1,5 @@ +use alloc::alloc::{GlobalAlloc, Layout}; use alloc::vec::Vec; -use alloc::alloc::{Layout, GlobalAlloc}; use core::marker::PhantomData; pub trait NoMMUSupport { @@ -28,8 +28,12 @@ impl MemorySet { slice } // empty impls - pub fn with(&self, f: impl FnOnce() -> T) -> T { f() } - pub fn token(&self) -> usize { 0 } + pub fn with(&self, f: impl FnOnce() -> T) -> T { + f() + } + pub fn token(&self) -> usize { + 0 + } pub unsafe fn activate(&self) {} } @@ -44,7 +48,11 @@ impl MemoryArea { fn new(size: usize) -> Self { let layout = Layout::from_size_align(size, 1).unwrap(); let ptr = unsafe { S::allocator().alloc(layout) } as usize; - MemoryArea { ptr, layout, support: PhantomData } + MemoryArea { + ptr, + layout, + support: PhantomData, + } } unsafe fn as_buf(&self) -> &'static mut [u8] { core::slice::from_raw_parts_mut(self.ptr as *mut u8, self.layout.size()) @@ -63,4 +71,4 @@ impl Drop for MemoryArea { fn drop(&mut self) { unsafe { S::allocator().dealloc(self.ptr as *mut u8, self.layout) } } -} \ No newline at end of file +} diff --git a/crate/memory/src/paging/ext.rs b/crate/memory/src/paging/ext.rs index a5d7822..7ada6f3 100644 --- a/crate/memory/src/paging/ext.rs +++ b/crate/memory/src/paging/ext.rs @@ -8,11 +8,16 @@ pub trait PageTableExt: PageTable { // So this should be really high in kernel space when necessary. const TEMP_PAGE_ADDR: VirtAddr = 0xcafeb000; - fn with_temporary_map(&mut self, target: PhysAddr, f: impl FnOnce(&mut Self, &mut D) -> T) -> T { + fn with_temporary_map( + &mut self, + target: PhysAddr, + f: impl FnOnce(&mut Self, &mut D) -> T, + ) -> T { self.map(Self::TEMP_PAGE_ADDR, target); - let data = unsafe { &mut *(self.get_page_slice_mut(Self::TEMP_PAGE_ADDR).as_ptr() as *mut D) }; + let data = + unsafe { &mut *(self.get_page_slice_mut(Self::TEMP_PAGE_ADDR).as_ptr() as *mut D) }; let ret = f(self, data); self.unmap(Self::TEMP_PAGE_ADDR); ret } -} \ No newline at end of file +} diff --git a/crate/memory/src/paging/mock_page_table.rs b/crate/memory/src/paging/mock_page_table.rs index cfcdf2e..6395325 100644 --- a/crate/memory/src/paging/mock_page_table.rs +++ b/crate/memory/src/paging/mock_page_table.rs @@ -3,8 +3,8 @@ //! An mock implementation for the PageTable. //! Used to test page table operation. -use alloc::boxed::Box; use super::*; +use alloc::boxed::Box; const PAGE_COUNT: usize = 16; const PAGE_SIZE: usize = 4096; @@ -31,18 +31,42 @@ pub struct MockEntry { impl Entry for MockEntry { fn update(&mut self) {} - fn accessed(&self) -> bool { self.accessed } - fn dirty(&self) -> bool { self.dirty } - fn writable(&self) -> bool { self.writable } - fn present(&self) -> bool { self.present } - fn clear_accessed(&mut self) { self.accessed = false; } - fn clear_dirty(&mut self) { self.dirty = false; } - fn set_writable(&mut self, value: bool) { self.writable = value; } - fn set_present(&mut self, value: bool) { self.present = value; } - fn target(&self) -> usize { self.target } - fn set_target(&mut self, target: usize) { self.target = target; } - fn writable_shared(&self) -> bool { self.writable_shared } - fn readonly_shared(&self) -> bool { self.readonly_shared } + fn accessed(&self) -> bool { + self.accessed + } + fn dirty(&self) -> bool { + self.dirty + } + fn writable(&self) -> bool { + self.writable + } + fn present(&self) -> bool { + self.present + } + fn clear_accessed(&mut self) { + self.accessed = false; + } + fn clear_dirty(&mut self) { + self.dirty = false; + } + fn set_writable(&mut self, value: bool) { + self.writable = value; + } + fn set_present(&mut self, value: bool) { + self.present = value; + } + fn target(&self) -> usize { + self.target + } + fn set_target(&mut self, target: usize) { + self.target = target; + } + fn writable_shared(&self) -> bool { + self.writable_shared + } + fn readonly_shared(&self) -> bool { + self.readonly_shared + } fn set_shared(&mut self, writable: bool) { self.writable_shared = writable; self.readonly_shared = !writable; @@ -51,20 +75,36 @@ impl Entry for MockEntry { self.writable_shared = false; self.readonly_shared = false; } - fn swapped(&self) -> bool { self.swapped } - fn set_swapped(&mut self, value: bool) { self.swapped = value; } - fn user(&self) -> bool { unimplemented!() } - fn set_user(&mut self, _value: bool) { unimplemented!() } - fn execute(&self) -> bool { unimplemented!() } - fn set_execute(&mut self, _value: bool) { unimplemented!() } - fn mmio(&self) -> u8 { unimplemented!() } - fn set_mmio(&mut self, _value: u8) { unimplemented!() } + fn swapped(&self) -> bool { + self.swapped + } + fn set_swapped(&mut self, value: bool) { + self.swapped = value; + } + fn user(&self) -> bool { + unimplemented!() + } + fn set_user(&mut self, _value: bool) { + unimplemented!() + } + fn execute(&self) -> bool { + unimplemented!() + } + fn set_execute(&mut self, _value: bool) { + unimplemented!() + } + fn mmio(&self) -> u8 { + unimplemented!() + } + fn set_mmio(&mut self, _value: u8) { + unimplemented!() + } } type PageFaultHandler = Box; impl PageTable for MockPageTable { -// type Entry = MockEntry; + // type Entry = MockEntry; fn map(&mut self, addr: VirtAddr, target: PhysAddr) -> &mut Entry { let entry = &mut self.entries[addr / PAGE_SIZE]; @@ -82,10 +122,10 @@ impl PageTable for MockPageTable { fn get_entry(&mut self, addr: VirtAddr) -> Option<&mut Entry> { Some(&mut self.entries[addr / PAGE_SIZE]) } - fn get_page_slice_mut<'a,'b>(&'a mut self, addr: VirtAddr) -> &'b mut [u8] { + fn get_page_slice_mut<'a, 'b>(&'a mut self, addr: VirtAddr) -> &'b mut [u8] { self._read(addr); let pa = self.translate(addr) & !(PAGE_SIZE - 1); - let data = unsafe{ &mut *(&mut self.data as *mut [u8; PAGE_SIZE * PAGE_COUNT])}; + let data = unsafe { &mut *(&mut self.data as *mut [u8; PAGE_SIZE * PAGE_COUNT]) }; &mut data[pa..pa + PAGE_SIZE] } fn read(&mut self, addr: usize) -> u8 { @@ -100,9 +140,9 @@ impl PageTable for MockPageTable { impl MockPageTable { /* - ** @brief create a new MockPageTable - ** @retval MockPageTable the mock page table created - */ + ** @brief create a new MockPageTable + ** @retval MockPageTable the mock page table created + */ pub fn new() -> Self { use core::mem::uninitialized; MockPageTable { @@ -112,21 +152,21 @@ impl MockPageTable { } } /* - ** @brief set the page fault handler - ** used for mock the page fault feature - ** @param page_fault_handler: PageFaultHandler - ** the page fault handler - ** @retval none - */ + ** @brief set the page fault handler + ** used for mock the page fault feature + ** @param page_fault_handler: PageFaultHandler + ** the page fault handler + ** @retval none + */ pub fn set_handler(&mut self, page_fault_handler: PageFaultHandler) { self.page_fault_handler = Some(page_fault_handler); } /* - ** @brief trigger page fault - ** used for mock the page fault feature - ** @param addr: VirtAddr the virtual address used to trigger the page fault - ** @retval none - */ + ** @brief trigger page fault + ** used for mock the page fault feature + ** @param addr: VirtAddr the virtual address used to trigger the page fault + ** @retval none + */ fn trigger_page_fault(&mut self, addr: VirtAddr) { // In order to call the handler with &mut self as an argument // We have to first take the handler out of self, finally put it back @@ -135,11 +175,11 @@ impl MockPageTable { self.page_fault_handler = Some(handler); } /* - ** @brief translate virtual address to physics address - ** used for mock address translation feature - ** @param addr: VirtAddr the virtual address to translation - ** @retval PhysAddr the translation result - */ + ** @brief translate virtual address to physics address + ** used for mock address translation feature + ** @param addr: VirtAddr the virtual address to translation + ** @retval PhysAddr the translation result + */ fn translate(&self, addr: VirtAddr) -> PhysAddr { let entry = &self.entries[addr / PAGE_SIZE]; assert!(entry.present); @@ -148,11 +188,11 @@ impl MockPageTable { pa } /* - ** @brief attempt to read the virtual address - ** trigger page fault when failed - ** @param addr: VirtAddr the virual address of data to read - ** @retval none - */ + ** @brief attempt to read the virtual address + ** trigger page fault when failed + ** @param addr: VirtAddr the virual address of data to read + ** @retval none + */ fn _read(&mut self, addr: VirtAddr) { while !self.entries[addr / PAGE_SIZE].present { self.trigger_page_fault(addr); @@ -160,11 +200,11 @@ impl MockPageTable { self.entries[addr / PAGE_SIZE].accessed = true; } /* - ** @brief attempt to write the virtual address - ** trigger page fault when failed - ** @param addr: VirtAddr the virual address of data to write - ** @retval none - */ + ** @brief attempt to write the virtual address + ** trigger page fault when failed + ** @param addr: VirtAddr the virual address of data to write + ** @retval none + */ fn _write(&mut self, addr: VirtAddr) { while !(self.entries[addr / PAGE_SIZE].present && self.entries[addr / PAGE_SIZE].writable) { self.trigger_page_fault(addr); @@ -255,4 +295,4 @@ mod test { pt.read(0); assert_eq!(*page_fault_count.borrow(), 2); } -} \ No newline at end of file +} diff --git a/crate/memory/src/paging/mod.rs b/crate/memory/src/paging/mod.rs index 8ce357f..8f53bf2 100644 --- a/crate/memory/src/paging/mod.rs +++ b/crate/memory/src/paging/mod.rs @@ -2,18 +2,17 @@ //! //! Implemented for every architecture, used by OS. -use super::*; +pub use self::ext::*; #[cfg(test)] pub use self::mock_page_table::MockPageTable; -pub use self::ext::*; +use super::*; +mod ext; #[cfg(test)] mod mock_page_table; -mod ext; - pub trait PageTable { -// type Entry: Entry; + // type Entry: Entry; /// Map a page of virual address `addr` to the frame of physics address `target` /// Return the page table entry of the mapped virual address diff --git a/crate/memory/src/swap/fifo.rs b/crate/memory/src/swap/fifo.rs index f282965..70e67b9 100644 --- a/crate/memory/src/swap/fifo.rs +++ b/crate/memory/src/swap/fifo.rs @@ -1,11 +1,10 @@ //! Implememnt the swap manager with the FIFO page replacement algorithm -use alloc::collections::VecDeque; use super::*; - +use alloc::collections::VecDeque; #[derive(Default)] -pub struct FifoSwapManager { +pub struct FifoSwapManager { deque: VecDeque, } @@ -13,22 +12,29 @@ impl SwapManager for FifoSwapManager { fn tick(&mut self) {} fn push(&mut self, frame: Frame) { - info!("SwapManager push token: {:x?} vaddr: {:x?}", frame.get_token(), frame.get_virtaddr()); + info!( + "SwapManager push token: {:x?} vaddr: {:x?}", + frame.get_token(), + frame.get_virtaddr() + ); self.deque.push_back(frame); } fn remove(&mut self, token: usize, addr: VirtAddr) { info!("SwapManager remove token: {:x?} vaddr: {:x?}", token, addr); - let id = self.deque.iter() + let id = self + .deque + .iter() .position(|ref x| x.get_virtaddr() == addr && x.get_token() == token) .expect("address not found"); self.deque.remove(id); //info!("SwapManager remove token finished: {:x?} vaddr: {:x?}", token, addr); - } fn pop(&mut self, _: &mut T, _: &mut S) -> Option - where T: PageTable, S: Swapper + where + T: PageTable, + S: Swapper, { self.deque.pop_front() } @@ -56,4 +62,4 @@ mod test { test_manager(FifoSwapManager::default(), &ops, &pgfault_count); } } -*/ \ No newline at end of file +*/ diff --git a/crate/memory/src/swap/mock_swapper.rs b/crate/memory/src/swap/mock_swapper.rs index 36effe7..74564c0 100644 --- a/crate/memory/src/swap/mock_swapper.rs +++ b/crate/memory/src/swap/mock_swapper.rs @@ -17,7 +17,7 @@ pub struct MockSwapper { impl Swapper for MockSwapper { fn swap_out(&mut self, data: &[u8]) -> Result { let id = self.alloc_id(); - let mut slice: [u8; PAGE_SIZE] = unsafe{ uninitialized() }; + let mut slice: [u8; PAGE_SIZE] = unsafe { uninitialized() }; slice.copy_from_slice(data); self.map.insert(id, slice); Ok(id) @@ -27,7 +27,7 @@ impl Swapper for MockSwapper { if !self.map.contains_key(&token) { return Err(()); } - let mut slice: [u8; PAGE_SIZE] = unsafe{ uninitialized() }; + let mut slice: [u8; PAGE_SIZE] = unsafe { uninitialized() }; slice.copy_from_slice(data); self.map.insert(token, slice); Ok(()) @@ -43,11 +43,11 @@ impl Swapper for MockSwapper { impl MockSwapper { /* - ** @brief allocate an unused id for location on the mock device - ** @retval usize the allocated location id - */ + ** @brief allocate an unused id for location on the mock device + ** @retval usize the allocated location id + */ fn alloc_id(&self) -> usize { - (0 .. 100usize).find(|i| !self.map.contains_key(i)).unwrap() + (0..100usize).find(|i| !self.map.contains_key(i)).unwrap() } } @@ -64,8 +64,8 @@ mod test { #[test] fn swap_out_in() { let mut swapper = MockSwapper::default(); - let mut data: [u8; 4096] = unsafe{ uninitialized() }; - let data1: [u8; 4096] = unsafe{ uninitialized() }; + let mut data: [u8; 4096] = unsafe { uninitialized() }; + let data1: [u8; 4096] = unsafe { uninitialized() }; let token = swapper.swap_out(&data1).unwrap(); swapper.swap_in(token, &mut data).unwrap(); assert_data_eq(&data, &data1); @@ -74,9 +74,9 @@ mod test { #[test] fn swap_update() { let mut swapper = MockSwapper::default(); - let mut data: [u8; 4096] = unsafe{ uninitialized() }; - let data1: [u8; 4096] = unsafe{ uninitialized() }; - let data2: [u8; 4096] = unsafe{ uninitialized() }; + let mut data: [u8; 4096] = unsafe { uninitialized() }; + let data1: [u8; 4096] = unsafe { uninitialized() }; + let data2: [u8; 4096] = unsafe { uninitialized() }; let token = swapper.swap_out(&data1).unwrap(); swapper.swap_update(token, &data2).unwrap(); swapper.swap_in(token, &mut data).unwrap(); @@ -86,7 +86,7 @@ mod test { #[test] fn invalid_token() { let mut swapper = MockSwapper::default(); - let mut data: [u8; 4096] = unsafe{ uninitialized() }; + let mut data: [u8; 4096] = unsafe { uninitialized() }; assert_eq!(swapper.swap_in(0, &mut data), Err(())); } -} \ No newline at end of file +} diff --git a/crate/memory/src/swap/mod.rs b/crate/memory/src/swap/mod.rs index a161dcb..3451df8 100644 --- a/crate/memory/src/swap/mod.rs +++ b/crate/memory/src/swap/mod.rs @@ -6,9 +6,9 @@ //! Invoke page_fault_handler() on the SwapExt to run the swap process //! If the method above returns true, a page is swapped in, else do your own things. -use super::*; -use super::paging::*; use super::addr::Frame; +use super::paging::*; +use super::*; use core::ops::{Deref, DerefMut}; //pub use self::fifo::FifoSwapManager; @@ -24,58 +24,60 @@ pub mod mock_swapper; pub trait SwapManager { //type Inactive: InactivePageTable; /* - ** @brief update intarnal state pre tick - ** Called when tick interrupt occured - ** @retval none - */ + ** @brief update intarnal state pre tick + ** Called when tick interrupt occured + ** @retval none + */ fn tick(&mut self); /* - ** @brief update intarnal state when page is pushed into memory - ** Called when map a swappable page into the memory - ** @param frame: Frame the Frame recording the swappable frame info - ** @retval none - */ + ** @brief update intarnal state when page is pushed into memory + ** Called when map a swappable page into the memory + ** @param frame: Frame the Frame recording the swappable frame info + ** @retval none + */ fn push(&mut self, frame: Frame); /* - ** @brief update intarnal state when page is removed from memory - ** Called to delete the addr entry from the swap manager - ** @param token: usize the inactive page table token for the virtual address - ** @param addr: VirtAddr the virual address of the page removed from memory - ** @retval none - */ + ** @brief update intarnal state when page is removed from memory + ** Called to delete the addr entry from the swap manager + ** @param token: usize the inactive page table token for the virtual address + ** @param addr: VirtAddr the virual address of the page removed from memory + ** @retval none + */ fn remove(&mut self, token: usize, addr: VirtAddr); /* - ** @brief select swap out victim when there is need to swap out a page - ** (The params is only used by `EnhancedClockSwapManager` currently) - ** @param page_table: &mut T the current page table - ** @param swapper: &mut S the swapper used - ** @retval Option the Frame of the victim page, if present - */ + ** @brief select swap out victim when there is need to swap out a page + ** (The params is only used by `EnhancedClockSwapManager` currently) + ** @param page_table: &mut T the current page table + ** @param swapper: &mut S the swapper used + ** @retval Option the Frame of the victim page, if present + */ fn pop(&mut self, page_table: &mut T, swapper: &mut S) -> Option - where T: PageTable, S: Swapper; + where + T: PageTable, + S: Swapper; } /// Implement swap in & out execution pub trait Swapper { /* - ** @brief Allocate space on device and write data to it - ** @param data: &[u8] the data to write to the device - ** @retval Result the execute result, and a token indicating the location on the device if success - */ + ** @brief Allocate space on device and write data to it + ** @param data: &[u8] the data to write to the device + ** @retval Result the execute result, and a token indicating the location on the device if success + */ fn swap_out(&mut self, data: &[u8]) -> Result; /* - ** @brief Update data on device. - ** @param token: usize the token indicating the location on the device - ** @param data: &[u8] the data to overwrite on the device - ** @retval Result<(), ()> the execute result - */ + ** @brief Update data on device. + ** @param token: usize the token indicating the location on the device + ** @param data: &[u8] the data to overwrite on the device + ** @retval Result<(), ()> the execute result + */ fn swap_update(&mut self, token: usize, data: &[u8]) -> Result<(), ()>; /* - ** @brief Recover data from device and deallocate the space. - ** @param token: usize the token indicating the location on the device - ** @param data: &mut [u8] the reference to data in the space in memory - ** @retval Result<(), ()> the execute result - */ + ** @brief Recover data from device and deallocate the space. + ** @param token: usize the token indicating the location on the device + ** @param data: &mut [u8] the reference to data in the space in memory + ** @retval Result<(), ()> the execute result + */ fn swap_in(&mut self, token: usize, data: &mut [u8]) -> Result<(), ()>; } @@ -88,12 +90,12 @@ pub struct SwapExt { impl SwapExt { /* - ** @brief create a swap extension - ** @param page_table: T the inner page table - ** @param swap_manager: M the SwapManager used - ** @param swapper: S the Swapper used - ** @retval SwapExt the swap extension created - */ + ** @brief create a swap extension + ** @param page_table: T the inner page table + ** @param swap_manager: M the SwapManager used + ** @param swapper: S the Swapper used + ** @retval SwapExt the swap extension created + */ pub fn new(page_table: T, swap_manager: M, swapper: S) -> Self { SwapExt { page_table, @@ -103,19 +105,29 @@ impl SwapExt { } /* - ** @brief set a page swappable - ** @param pt: *mut T2 the raw pointer for the target page's inactive page table - ** @param addr: VirtAddr the target page's virtual address - */ - pub unsafe fn set_swappable(&mut self, pt: *mut T2, addr: VirtAddr){ - let Self {ref mut page_table, ref mut swap_manager, ..} = self; + ** @brief set a page swappable + ** @param pt: *mut T2 the raw pointer for the target page's inactive page table + ** @param addr: VirtAddr the target page's virtual address + */ + pub unsafe fn set_swappable(&mut self, pt: *mut T2, addr: VirtAddr) { + let Self { + ref mut page_table, + ref mut swap_manager, + .. + } = self; let targetpt = &mut *(pt); let pttoken = { - info!("SET_SWAPPABLE: the target page table token is {:x?}, addr is {:x?}", targetpt.token(), addr); + info!( + "SET_SWAPPABLE: the target page table token is {:x?}, addr is {:x?}", + targetpt.token(), + addr + ); targetpt.token() }; - targetpt.with(||{ - let entry = page_table.get_entry(addr).expect("failed to get page entry when set swappable"); + targetpt.with(|| { + let entry = page_table + .get_entry(addr) + .expect("failed to get page entry when set swappable"); if entry.present() { let frame = Frame::new(pt as usize, addr, pttoken); swap_manager.push(frame); @@ -131,25 +143,38 @@ impl SwapExt { } /* - ** @brief remove a page (given virtual address) from swappable pages, if the page is swapped, swap in at first - ** @param pt: *mut T2 the raw pointer for the target page's inactive page table - ** @param addr: VirtAddr the target page's virtual address - ** @param alloc_frame: the function to alloc a free physical frame for once - */ - pub unsafe fn remove_from_swappable(&mut self, pt: *mut T2, addr: VirtAddr, alloc_frame: impl FnOnce() -> PhysAddr){ + ** @brief remove a page (given virtual address) from swappable pages, if the page is swapped, swap in at first + ** @param pt: *mut T2 the raw pointer for the target page's inactive page table + ** @param addr: VirtAddr the target page's virtual address + ** @param alloc_frame: the function to alloc a free physical frame for once + */ + pub unsafe fn remove_from_swappable( + &mut self, + pt: *mut T2, + addr: VirtAddr, + alloc_frame: impl FnOnce() -> PhysAddr, + ) { //info!("come into remove_from swappable"); - let Self {ref mut page_table, ref mut swap_manager, ref mut swapper} = self; + let Self { + ref mut page_table, + ref mut swap_manager, + ref mut swapper, + } = self; let targetpt = &mut *(pt); let pttoken = { - info!("SET_UNSWAPPABLE: the target page table token is {:x?}, addr is {:x?}", targetpt.token(), addr); + info!( + "SET_UNSWAPPABLE: the target page table token is {:x?}, addr is {:x?}", + targetpt.token(), + addr + ); targetpt.token() }; //info!("try to change pagetable"); - targetpt.with(||{ + targetpt.with(|| { let token = { let entry = page_table.get_entry(addr).unwrap(); if !entry.swapped() { - if entry.present(){ + if entry.present() { // if the addr isn't indicating a swapped page, panic occured here swap_manager.remove(pttoken, addr); } @@ -171,11 +196,11 @@ impl SwapExt { } /* - ** @brief map the virtual address to a target physics address as swappable - ** @param addr: VirtAddr the virual address to map - ** @param target: VirtAddr the target physics address - ** @retval none - */ + ** @brief map the virtual address to a target physics address as swappable + ** @param addr: VirtAddr the virual address to map + ** @param target: VirtAddr the target physics address + ** @retval none + */ /* pub fn map_to_swappable(&mut self, addr: VirtAddr, target: PhysAddr) -> &mut T::Entry { self.swap_manager.push(addr); @@ -183,15 +208,19 @@ impl SwapExt { }*/ /* - ** @brief Swap out any one of the swapped pages - ** @retval Result - ** the physics address of released frame if success, - ** the error if failed - */ + ** @brief Swap out any one of the swapped pages + ** @retval Result + ** the physics address of released frame if success, + ** the error if failed + */ pub fn swap_out_any(&mut self) -> Result { info!("COME in to swap_out_any"); let victim: Option = { - let Self {ref mut page_table, ref mut swap_manager, ref mut swapper} = self; + let Self { + ref mut page_table, + ref mut swap_manager, + ref mut swapper, + } = self; swap_manager.pop(page_table, swapper) }; info!("swap out page {}", victim.unwrap().get_virtaddr()); @@ -202,21 +231,26 @@ impl SwapExt { } /* - ** @brief Swap out page - ** @param frame: Frame the Frame of page recording the page info - ** @retval Result - ** the physics address of the original map target frame if success, - ** the error if failed - */ + ** @brief Swap out page + ** @param frame: Frame the Frame of page recording the page info + ** @retval Result + ** the physics address of the original map target frame if success, + ** the error if failed + */ fn swap_out(&mut self, frame: &Frame) -> Result { - let Self {ref mut page_table, ref mut swapper, ..} = self; - let ret = unsafe{ + let Self { + ref mut page_table, + ref mut swapper, + .. + } = self; + let ret = unsafe { let pt = &mut *(frame.get_page_table() as *mut T2); pt.with(|| { //use core::slice; //let data = unsafe { slice::from_raw_parts_mut((frame.virtaddr & !(PAGE_SIZE - 1)) as *mut u8, PAGE_SIZE) }; let data = page_table.get_page_slice_mut(frame.get_virtaddr()); - let entry = page_table.get_entry(frame.get_virtaddr()) + let entry = page_table + .get_entry(frame.get_virtaddr()) .ok_or(SwapError::NotMapped)?; if entry.swapped() { return Err(SwapError::AlreadySwapped); @@ -235,16 +269,23 @@ impl SwapExt { ret } /* - ** @brief map the virtual address to a target physics address and then swap in page data, noted that the page should be in the current page table - ** @param pt: *mut T2 the raw pointer for the swapping page's inactive page table - ** @param addr: VirtAddr the virual address of beginning of page - ** @param target: PhysAddr the target physics address - ** @retval Result<()), SwapError> - ** the execute result, and the error if failed - */ - fn swap_in(&mut self, pt: *mut T2, addr: VirtAddr, target: PhysAddr) -> Result<(), SwapError> { + ** @brief map the virtual address to a target physics address and then swap in page data, noted that the page should be in the current page table + ** @param pt: *mut T2 the raw pointer for the swapping page's inactive page table + ** @param addr: VirtAddr the virual address of beginning of page + ** @param target: PhysAddr the target physics address + ** @retval Result<()), SwapError> + ** the execute result, and the error if failed + */ + fn swap_in( + &mut self, + pt: *mut T2, + addr: VirtAddr, + target: PhysAddr, + ) -> Result<(), SwapError> { info!("come in to swap in"); - let entry = self.page_table.get_entry(addr) + let entry = self + .page_table + .get_entry(addr) .ok_or(SwapError::NotMapped)?; if !entry.swapped() { return Err(SwapError::NotSwapped); @@ -255,32 +296,38 @@ impl SwapExt { entry.set_present(true); entry.update(); let data = self.page_table.get_page_slice_mut(addr); - self.swapper.swap_in(token, data).map_err(|_| SwapError::IOError)?; - let pttoken = unsafe{ - (*pt).token() - }; + self.swapper + .swap_in(token, data) + .map_err(|_| SwapError::IOError)?; + let pttoken = unsafe { (*pt).token() }; let frame = Frame::new(pt as usize, addr, pttoken); ; self.swap_manager.push(frame); Ok(()) } /* - ** @brief execute the frame delayed allocate and swap process for page fault - ** This function must be called whenever PageFault happens. - ** @param pt: *mut T2 the raw pointer for the target page's inactive page table (exactly the current page table) - ** @param addr: VirtAddr the virual address of the page fault - ** @param swapin: bool whether to set the page swappable if delayed allocate a frame for a page - ** @param alloc_frame: impl FnOnce() -> PhysAddr - ** the page allocation function - ** that allocate a page and returns physics address - ** of beginning of the page - ** @retval bool whether swap in happens. - */ - pub fn page_fault_handler(&mut self, pt: *mut T2, addr: VirtAddr, swapin: bool, alloc_frame: impl FnOnce() -> PhysAddr) -> bool { + ** @brief execute the frame delayed allocate and swap process for page fault + ** This function must be called whenever PageFault happens. + ** @param pt: *mut T2 the raw pointer for the target page's inactive page table (exactly the current page table) + ** @param addr: VirtAddr the virual address of the page fault + ** @param swapin: bool whether to set the page swappable if delayed allocate a frame for a page + ** @param alloc_frame: impl FnOnce() -> PhysAddr + ** the page allocation function + ** that allocate a page and returns physics address + ** of beginning of the page + ** @retval bool whether swap in happens. + */ + pub fn page_fault_handler( + &mut self, + pt: *mut T2, + addr: VirtAddr, + swapin: bool, + alloc_frame: impl FnOnce() -> PhysAddr, + ) -> bool { // handle page delayed allocating { info!("try handling delayed frame allocator"); - let need_alloc ={ + let need_alloc = { let entry = self.page_table.get_entry(addr).expect("fail to get entry"); //info!("got entry!"); !entry.present() && !entry.swapped() @@ -311,7 +358,11 @@ impl SwapExt { match self.page_table.get_entry(addr) { // infact the get_entry(addr) should not be None here None => return false, - Some(entry) => if !entry.swapped() { return false; }, + Some(entry) => { + if !entry.swapped() { + return false; + } + } } // Allocate a frame, if failed, swap out a page let frame = alloc_frame(); @@ -411,4 +462,4 @@ mod test { } } } -*/ \ No newline at end of file +*/ diff --git a/crate/sync/src/main.rs b/crate/sync/src/main.rs index 0837505..725a633 100644 --- a/crate/sync/src/main.rs +++ b/crate/sync/src/main.rs @@ -1,9 +1,9 @@ //! entrance to test the communication in processes with solving five philosophers problem -mod mutex; mod monitor; +mod mutex; fn main() { -// mutex::main(); + // mutex::main(); monitor::main(); -} \ No newline at end of file +} diff --git a/crate/sync/src/monitor.rs b/crate/sync/src/monitor.rs index b984fbc..09d4209 100644 --- a/crate/sync/src/monitor.rs +++ b/crate/sync/src/monitor.rs @@ -1,7 +1,7 @@ //! solve the five philosophers problem with monitor +use std::sync::{Arc, Condvar, Mutex}; use std::thread; -use std::sync::{Mutex, Condvar, Arc}; use std::time::Duration; struct Philosopher { @@ -57,7 +57,13 @@ struct Table { pub fn main() { let table = Arc::new(Table { fork_status: Mutex::new(vec![false; 5]), - fork_condvar: vec![Condvar::new(), Condvar::new(), Condvar::new(), Condvar::new(), Condvar::new()], + fork_condvar: vec![ + Condvar::new(), + Condvar::new(), + Condvar::new(), + Condvar::new(), + Condvar::new(), + ], }); let philosophers = vec![ @@ -68,18 +74,21 @@ pub fn main() { Philosopher::new("5", 0, 4), ]; - let handles: Vec<_> = philosophers.into_iter().map(|p| { - let table = table.clone(); + let handles: Vec<_> = philosophers + .into_iter() + .map(|p| { + let table = table.clone(); - thread::spawn(move || { - for _ in 0..5 { - p.think(); - p.eat(&table); - } + thread::spawn(move || { + for _ in 0..5 { + p.think(); + p.eat(&table); + } + }) }) - }).collect(); + .collect(); for h in handles { h.join().unwrap(); } -} \ No newline at end of file +} diff --git a/crate/sync/src/mutex.rs b/crate/sync/src/mutex.rs index eeef0f4..b20efe7 100644 --- a/crate/sync/src/mutex.rs +++ b/crate/sync/src/mutex.rs @@ -1,7 +1,7 @@ //! solve the five philosophers problem with mutex +use std::sync::{Arc, Mutex}; use std::thread; -use std::sync::{Mutex, Arc}; use std::time::Duration; struct Philosopher { @@ -46,7 +46,7 @@ pub fn main() { Mutex::new(()), Mutex::new(()), Mutex::new(()), - ] + ], }); let philosophers = vec![ @@ -57,18 +57,21 @@ pub fn main() { Philosopher::new("5", 0, 4), ]; - let handles: Vec<_> = philosophers.into_iter().map(|p| { - let table = table.clone(); + let handles: Vec<_> = philosophers + .into_iter() + .map(|p| { + let table = table.clone(); - thread::spawn(move || { - for _ in 0..5 { - p.think(); - p.eat(&table); - } + thread::spawn(move || { + for _ in 0..5 { + p.think(); + p.eat(&table); + } + }) }) - }).collect(); + .collect(); for h in handles { h.join().unwrap(); } -} \ No newline at end of file +} diff --git a/crate/thread/build.rs b/crate/thread/build.rs index ea3850b..f328e4d 100644 --- a/crate/thread/build.rs +++ b/crate/thread/build.rs @@ -1,2 +1 @@ -fn main() { -} \ No newline at end of file +fn main() {} diff --git a/crate/thread/src/lib.rs b/crate/thread/src/lib.rs index 242c984..1a66d6a 100644 --- a/crate/thread/src/lib.rs +++ b/crate/thread/src/lib.rs @@ -8,12 +8,12 @@ extern crate alloc; -mod thread_pool; +mod interrupt; mod processor; pub mod scheduler; pub mod std_thread; +mod thread_pool; mod timer; -mod interrupt; -pub use crate::thread_pool::*; pub use crate::processor::Processor; +pub use crate::thread_pool::*; diff --git a/crate/thread/src/processor.rs b/crate/thread/src/processor.rs index 9f3d506..e935087 100644 --- a/crate/thread/src/processor.rs +++ b/crate/thread/src/processor.rs @@ -1,9 +1,9 @@ +use crate::interrupt; +use crate::thread_pool::*; use alloc::boxed::Box; use alloc::sync::Arc; -use log::*; use core::cell::UnsafeCell; -use crate::thread_pool::*; -use crate::interrupt; +use log::*; /// Thread executor /// @@ -25,7 +25,9 @@ struct ProcessorInner { impl Processor { pub const fn new() -> Self { - Processor { inner: UnsafeCell::new(None) } + Processor { + inner: UnsafeCell::new(None), + } } pub unsafe fn init(&self, id: usize, context: Box, manager: Arc) { @@ -38,7 +40,8 @@ impl Processor { } fn inner(&self) -> &mut ProcessorInner { - unsafe { &mut *self.inner.get() }.as_mut() + unsafe { &mut *self.inner.get() } + .as_mut() .expect("Processor is not initialized") } @@ -51,22 +54,30 @@ impl Processor { /// via switch back to the scheduler. pub fn run(&self) -> ! { let inner = self.inner(); - unsafe { interrupt::disable_and_store(); } + unsafe { + interrupt::disable_and_store(); + } loop { if let Some(proc) = inner.manager.run(inner.id) { trace!("CPU{} begin running thread {}", inner.id, proc.0); inner.proc = Some(proc); unsafe { - inner.loop_context.switch_to(&mut *inner.proc.as_mut().unwrap().1); + inner + .loop_context + .switch_to(&mut *inner.proc.as_mut().unwrap().1); } let (tid, context) = inner.proc.take().unwrap(); trace!("CPU{} stop running thread {}", inner.id, tid); inner.manager.stop(tid, context); } else { trace!("CPU{} idle", inner.id); - unsafe { interrupt::enable_and_wfi(); } + unsafe { + interrupt::enable_and_wfi(); + } // wait for a timer interrupt - unsafe { interrupt::disable_and_store(); } + unsafe { + interrupt::disable_and_store(); + } } } } @@ -79,7 +90,12 @@ impl Processor { let inner = self.inner(); unsafe { let flags = interrupt::disable_and_store(); - inner.proc.as_mut().unwrap().1.switch_to(&mut *inner.loop_context); + inner + .proc + .as_mut() + .unwrap() + .1 + .switch_to(&mut *inner.loop_context); interrupt::restore(flags); } } diff --git a/crate/thread/src/scheduler/rr.rs b/crate/thread/src/scheduler/rr.rs index acbc375..d111dab 100644 --- a/crate/thread/src/scheduler/rr.rs +++ b/crate/thread/src/scheduler/rr.rs @@ -36,7 +36,9 @@ impl RRScheduler { max_time_slice, infos: Vec::default(), }; - RRScheduler { inner: Mutex::new(inner) } + RRScheduler { + inner: Mutex::new(inner), + } } } @@ -63,7 +65,7 @@ impl RRSchedulerInner { self.infos[tid].present = false; self._list_remove(tid); Some(tid - 1) - }, + } }; trace!("rr pop {:?}", ret); ret diff --git a/crate/thread/src/scheduler/stride.rs b/crate/thread/src/scheduler/stride.rs index 1d1ed71..3ac0ffd 100644 --- a/crate/thread/src/scheduler/stride.rs +++ b/crate/thread/src/scheduler/stride.rs @@ -1,5 +1,5 @@ //! Stride scheduler -//! +//! //! Each task is assigned a priority. Each task has a running stride. //! The task with least stride is selected to run. //! When a task is rescheduled, its stride is added to proportional to 1 / priority. @@ -62,7 +62,9 @@ impl StrideScheduler { infos: Vec::default(), queue: BinaryHeap::default(), }; - StrideScheduler { inner: Mutex::new(inner) } + StrideScheduler { + inner: Mutex::new(inner), + } } } diff --git a/crate/thread/src/std_thread.rs b/crate/thread/src/std_thread.rs index db5c178..048f6d7 100644 --- a/crate/thread/src/std_thread.rs +++ b/crate/thread/src/std_thread.rs @@ -6,12 +6,12 @@ //! - `processor`: Get a reference of the current `Processor` //! - `new_kernel_context`: Construct a `Context` of the new kernel thread +use crate::processor::*; +use crate::thread_pool::*; use alloc::boxed::Box; use core::marker::PhantomData; use core::time::Duration; use log::*; -use crate::processor::*; -use crate::thread_pool::*; #[linkage = "weak"] #[no_mangle] @@ -23,14 +23,15 @@ fn processor() -> &'static Processor { #[linkage = "weak"] #[no_mangle] /// Construct a `Context` of the new kernel thread -fn new_kernel_context(_entry: extern fn(usize) -> !, _arg: usize) -> Box { +fn new_kernel_context(_entry: extern "C" fn(usize) -> !, _arg: usize) -> Box { unimplemented!("thread: Please implement and export `new_kernel_context`") } - /// Gets a handle to the thread that invokes it. pub fn current() -> Thread { - Thread { tid: processor().tid() } + Thread { + tid: processor().tid(), + } } /// Puts the current thread to sleep for the specified amount of time. @@ -50,9 +51,9 @@ pub fn sleep(dur: Duration) { /// `F`: Type of the function `f` /// `T`: Type of the return value of `f` pub fn spawn(f: F) -> JoinHandle - where - F: Send + 'static + FnOnce() -> T, - T: Send + 'static, +where + F: Send + 'static + FnOnce() -> T, + T: Send + 'static, { trace!("spawn:"); @@ -69,10 +70,10 @@ pub fn spawn(f: F) -> JoinHandle // // 注意到它具有泛型参数,因此对每一次spawn调用, // 由于F类型是独特的,因此都会生成一个新的kernel_thread_entry - extern fn kernel_thread_entry(f: usize) -> ! - where - F: Send + 'static + FnOnce() -> T, - T: Send + 'static, + extern "C" fn kernel_thread_entry(f: usize) -> ! + where + F: Send + 'static + FnOnce() -> T, + T: Send + 'static, { // 在静态函数内部: // 根据传进来的指针,恢复f diff --git a/crate/thread/src/thread_pool.rs b/crate/thread/src/thread_pool.rs index 441bc47..10d5471 100644 --- a/crate/thread/src/thread_pool.rs +++ b/crate/thread/src/thread_pool.rs @@ -1,9 +1,9 @@ +use crate::scheduler::Scheduler; +use crate::timer::Timer; use alloc::boxed::Box; use alloc::vec::Vec; -use spin::{Mutex, MutexGuard}; use log::*; -use crate::scheduler::Scheduler; -use crate::timer::Timer; +use spin::{Mutex, MutexGuard}; struct Thread { status: Status, @@ -105,13 +105,12 @@ impl ThreadPool { /// The manager first mark it `Running`, /// then take out and return its Context. pub(crate) fn run(&self, cpu_id: usize) -> Option<(Tid, Box)> { - self.scheduler.pop(cpu_id) - .map(|tid| { - let mut proc_lock = self.threads[tid].lock(); - let mut proc = proc_lock.as_mut().expect("thread not exist"); - proc.status = Status::Running(cpu_id); - (tid, proc.context.take().expect("context not exist")) - }) + self.scheduler.pop(cpu_id).map(|tid| { + let mut proc_lock = self.threads[tid].lock(); + let mut proc = proc_lock.as_mut().expect("thread not exist"); + proc.status = Status::Running(cpu_id); + (tid, proc.context.take().expect("context not exist")) + }) } /// Called by Processor to finish running a thread @@ -150,7 +149,7 @@ impl ThreadPool { (Status::Ready, _) => panic!("can not remove a thread from ready queue"), (Status::Exited(_), _) => panic!("can not set status for a exited thread"), (Status::Sleeping, Status::Exited(_)) => self.timer.lock().stop(Event::Wakeup(tid)), - (Status::Running(_), Status::Ready) => {} // thread will be added to scheduler in stop() + (Status::Running(_), Status::Ready) => {} // thread will be added to scheduler in stop() (_, Status::Ready) => self.scheduler.push(tid), _ => {} } @@ -175,7 +174,7 @@ impl ThreadPool { // release the tid *proc_lock = None; Some(code) - }, + } _ => None, } } diff --git a/crate/thread/src/timer.rs b/crate/thread/src/timer.rs index 9854f14..5917d72 100644 --- a/crate/thread/src/timer.rs +++ b/crate/thread/src/timer.rs @@ -45,7 +45,7 @@ impl Timer { let time = self.tick + time_after; let event = Event { time, data }; let mut it = self.timers.iter(); - let mut i : usize = 0; + let mut i: usize = 0; loop { match it.next() { None => break, @@ -62,4 +62,4 @@ impl Timer { self.timers.remove(i); } } -} \ No newline at end of file +} diff --git a/kernel/build.rs b/kernel/build.rs index 6f94b3f..57c7ee7 100644 --- a/kernel/build.rs +++ b/kernel/build.rs @@ -4,46 +4,43 @@ use std::fs::File; use std::io::{Result, Write}; fn main() { - println!("cargo:rerun-if-env-changed=LOG"); - println!("cargo:rerun-if-env-changed=BOARD"); - println!("cargo:rerun-if-env-changed=SFSIMG"); + println!("cargo:rerun-if-env-changed=LOG"); + println!("cargo:rerun-if-env-changed=BOARD"); + println!("cargo:rerun-if-env-changed=SFSIMG"); - let arch: String = std::env::var("ARCH").unwrap(); - let board: String = std::env::var("BOARD").unwrap(); - match arch.as_str() { - "x86_64" => { - gen_vector_asm().unwrap(); - } - "riscv32" => { - } - "riscv64" => { - } - "aarch64" => { - } - _ => panic!("Unknown arch {}", arch), - } + let arch: String = std::env::var("ARCH").unwrap(); + let board: String = std::env::var("BOARD").unwrap(); + match arch.as_str() { + "x86_64" => { + gen_vector_asm().unwrap(); + } + "riscv32" => {} + "riscv64" => {} + "aarch64" => {} + _ => panic!("Unknown arch {}", arch), + } } fn gen_vector_asm() -> Result<()> { - let mut f = File::create("src/arch/x86_64/interrupt/vector.asm").unwrap(); + let mut f = File::create("src/arch/x86_64/interrupt/vector.asm").unwrap(); - writeln!(f, "# generated by build.rs - do not edit")?; - writeln!(f, ".section .text")?; - writeln!(f, ".intel_syntax noprefix")?; - for i in 0..256 { - writeln!(f, "vector{}:", i)?; - if !(i == 8 || (i >= 10 && i <= 14) || i == 17) { - writeln!(f, "\tpush 0")?; - } - writeln!(f, "\tpush {}", i)?; - writeln!(f, "\tjmp __alltraps")?; - } + writeln!(f, "# generated by build.rs - do not edit")?; + writeln!(f, ".section .text")?; + writeln!(f, ".intel_syntax noprefix")?; + for i in 0..256 { + writeln!(f, "vector{}:", i)?; + if !(i == 8 || (i >= 10 && i <= 14) || i == 17) { + writeln!(f, "\tpush 0")?; + } + writeln!(f, "\tpush {}", i)?; + writeln!(f, "\tjmp __alltraps")?; + } - writeln!(f, "\n.section .rodata")?; - writeln!(f, ".global __vectors")?; - writeln!(f, "__vectors:")?; - for i in 0..256 { - writeln!(f, "\t.quad vector{}", i)?; - } - Ok(()) + writeln!(f, "\n.section .rodata")?; + writeln!(f, ".global __vectors")?; + writeln!(f, "__vectors:")?; + for i in 0..256 { + writeln!(f, "\t.quad vector{}", i)?; + } + Ok(()) } diff --git a/kernel/src/arch/aarch64/board/raspi3/fb.rs b/kernel/src/arch/aarch64/board/raspi3/fb.rs index 02c647a..ff3b31f 100644 --- a/kernel/src/arch/aarch64/board/raspi3/fb.rs +++ b/kernel/src/arch/aarch64/board/raspi3/fb.rs @@ -57,16 +57,10 @@ impl ColorBuffer { unsafe { match color_depth { ColorDepth16 => ColorBuffer { - buf16: core::slice::from_raw_parts_mut( - base_addr as *mut u16, - size / 2, - ), + buf16: core::slice::from_raw_parts_mut(base_addr as *mut u16, size / 2), }, ColorDepth32 => ColorBuffer { - buf32: core::slice::from_raw_parts_mut( - base_addr as *mut u32, - size / 4, - ), + buf32: core::slice::from_raw_parts_mut(base_addr as *mut u32, size / 4), }, } } diff --git a/kernel/src/arch/aarch64/board/raspi3/mailbox.rs b/kernel/src/arch/aarch64/board/raspi3/mailbox.rs index 9b63027..ae80fd2 100644 --- a/kernel/src/arch/aarch64/board/raspi3/mailbox.rs +++ b/kernel/src/arch/aarch64/board/raspi3/mailbox.rs @@ -3,12 +3,12 @@ //! (ref: https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface) use super::fb::FramebufferInfo; -use bcm2837::mailbox::{Mailbox, MailboxChannel}; -use lazy_static::lazy_static; +use aarch64::asm; use alloc::string::String; +use bcm2837::mailbox::{Mailbox, MailboxChannel}; use core::mem; +use lazy_static::lazy_static; use spin::Mutex; -use aarch64::asm; lazy_static! { static ref MAILBOX: Mutex = Mutex::new(Mailbox::new()); @@ -33,7 +33,7 @@ impl From for String { enum PropertyMailboxStatus { RPI_FIRMWARE_STATUS_REQUEST = 0, RPI_FIRMWARE_STATUS_SUCCESS = 0x80000000, - RPI_FIRMWARE_STATUS_ERROR = 0x80000001, + RPI_FIRMWARE_STATUS_ERROR = 0x80000001, } use self::PropertyMailboxStatus::*; @@ -44,104 +44,104 @@ use self::PropertyMailboxStatus::*; #[derive(Copy, Clone, Debug)] #[allow(non_camel_case_types)] enum PropertyMailboxTagId { - RPI_FIRMWARE_PROPERTY_END = 0, - RPI_FIRMWARE_GET_FIRMWARE_REVISION = 0x00000001, + RPI_FIRMWARE_PROPERTY_END = 0, + RPI_FIRMWARE_GET_FIRMWARE_REVISION = 0x00000001, - RPI_FIRMWARE_SET_CURSOR_INFO = 0x00008010, - RPI_FIRMWARE_SET_CURSOR_STATE = 0x00008011, + RPI_FIRMWARE_SET_CURSOR_INFO = 0x00008010, + RPI_FIRMWARE_SET_CURSOR_STATE = 0x00008011, - RPI_FIRMWARE_GET_BOARD_MODEL = 0x00010001, - RPI_FIRMWARE_GET_BOARD_REVISION = 0x00010002, - RPI_FIRMWARE_GET_BOARD_MAC_ADDRESS = 0x00010003, - RPI_FIRMWARE_GET_BOARD_SERIAL = 0x00010004, - RPI_FIRMWARE_GET_ARM_MEMORY = 0x00010005, - RPI_FIRMWARE_GET_VC_MEMORY = 0x00010006, - RPI_FIRMWARE_GET_CLOCKS = 0x00010007, - RPI_FIRMWARE_GET_POWER_STATE = 0x00020001, - RPI_FIRMWARE_GET_TIMING = 0x00020002, - RPI_FIRMWARE_SET_POWER_STATE = 0x00028001, - RPI_FIRMWARE_GET_CLOCK_STATE = 0x00030001, - RPI_FIRMWARE_GET_CLOCK_RATE = 0x00030002, - RPI_FIRMWARE_GET_VOLTAGE = 0x00030003, - RPI_FIRMWARE_GET_MAX_CLOCK_RATE = 0x00030004, - RPI_FIRMWARE_GET_MAX_VOLTAGE = 0x00030005, - RPI_FIRMWARE_GET_TEMPERATURE = 0x00030006, - RPI_FIRMWARE_GET_MIN_CLOCK_RATE = 0x00030007, - RPI_FIRMWARE_GET_MIN_VOLTAGE = 0x00030008, - RPI_FIRMWARE_GET_TURBO = 0x00030009, - RPI_FIRMWARE_GET_MAX_TEMPERATURE = 0x0003000a, - RPI_FIRMWARE_GET_STC = 0x0003000b, - RPI_FIRMWARE_ALLOCATE_MEMORY = 0x0003000c, - RPI_FIRMWARE_LOCK_MEMORY = 0x0003000d, - RPI_FIRMWARE_UNLOCK_MEMORY = 0x0003000e, - RPI_FIRMWARE_RELEASE_MEMORY = 0x0003000f, - RPI_FIRMWARE_EXECUTE_CODE = 0x00030010, - RPI_FIRMWARE_EXECUTE_QPU = 0x00030011, - RPI_FIRMWARE_SET_ENABLE_QPU = 0x00030012, - RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE = 0x00030014, - RPI_FIRMWARE_GET_EDID_BLOCK = 0x00030020, - RPI_FIRMWARE_GET_CUSTOMER_OTP = 0x00030021, - RPI_FIRMWARE_GET_DOMAIN_STATE = 0x00030030, - RPI_FIRMWARE_GET_THROTTLED = 0x00030046, - RPI_FIRMWARE_GET_CLOCK_MEASURED = 0x00030047, - RPI_FIRMWARE_NOTIFY_REBOOT = 0x00030048, - RPI_FIRMWARE_SET_CLOCK_STATE = 0x00038001, - RPI_FIRMWARE_SET_CLOCK_RATE = 0x00038002, - RPI_FIRMWARE_SET_VOLTAGE = 0x00038003, - RPI_FIRMWARE_SET_TURBO = 0x00038009, - RPI_FIRMWARE_SET_CUSTOMER_OTP = 0x00038021, - RPI_FIRMWARE_SET_DOMAIN_STATE = 0x00038030, - RPI_FIRMWARE_GET_GPIO_STATE = 0x00030041, - RPI_FIRMWARE_SET_GPIO_STATE = 0x00038041, - RPI_FIRMWARE_SET_SDHOST_CLOCK = 0x00038042, - RPI_FIRMWARE_GET_GPIO_CONFIG = 0x00030043, - RPI_FIRMWARE_SET_GPIO_CONFIG = 0x00038043, - RPI_FIRMWARE_GET_PERIPH_REG = 0x00030045, - RPI_FIRMWARE_SET_PERIPH_REG = 0x00038045, - RPI_FIRMWARE_GET_POE_HAT_VAL = 0x00030049, - RPI_FIRMWARE_SET_POE_HAT_VAL = 0x00030050, + RPI_FIRMWARE_GET_BOARD_MODEL = 0x00010001, + RPI_FIRMWARE_GET_BOARD_REVISION = 0x00010002, + RPI_FIRMWARE_GET_BOARD_MAC_ADDRESS = 0x00010003, + RPI_FIRMWARE_GET_BOARD_SERIAL = 0x00010004, + RPI_FIRMWARE_GET_ARM_MEMORY = 0x00010005, + RPI_FIRMWARE_GET_VC_MEMORY = 0x00010006, + RPI_FIRMWARE_GET_CLOCKS = 0x00010007, + RPI_FIRMWARE_GET_POWER_STATE = 0x00020001, + RPI_FIRMWARE_GET_TIMING = 0x00020002, + RPI_FIRMWARE_SET_POWER_STATE = 0x00028001, + RPI_FIRMWARE_GET_CLOCK_STATE = 0x00030001, + RPI_FIRMWARE_GET_CLOCK_RATE = 0x00030002, + RPI_FIRMWARE_GET_VOLTAGE = 0x00030003, + RPI_FIRMWARE_GET_MAX_CLOCK_RATE = 0x00030004, + RPI_FIRMWARE_GET_MAX_VOLTAGE = 0x00030005, + RPI_FIRMWARE_GET_TEMPERATURE = 0x00030006, + RPI_FIRMWARE_GET_MIN_CLOCK_RATE = 0x00030007, + RPI_FIRMWARE_GET_MIN_VOLTAGE = 0x00030008, + RPI_FIRMWARE_GET_TURBO = 0x00030009, + RPI_FIRMWARE_GET_MAX_TEMPERATURE = 0x0003000a, + RPI_FIRMWARE_GET_STC = 0x0003000b, + RPI_FIRMWARE_ALLOCATE_MEMORY = 0x0003000c, + RPI_FIRMWARE_LOCK_MEMORY = 0x0003000d, + RPI_FIRMWARE_UNLOCK_MEMORY = 0x0003000e, + RPI_FIRMWARE_RELEASE_MEMORY = 0x0003000f, + RPI_FIRMWARE_EXECUTE_CODE = 0x00030010, + RPI_FIRMWARE_EXECUTE_QPU = 0x00030011, + RPI_FIRMWARE_SET_ENABLE_QPU = 0x00030012, + RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE = 0x00030014, + RPI_FIRMWARE_GET_EDID_BLOCK = 0x00030020, + RPI_FIRMWARE_GET_CUSTOMER_OTP = 0x00030021, + RPI_FIRMWARE_GET_DOMAIN_STATE = 0x00030030, + RPI_FIRMWARE_GET_THROTTLED = 0x00030046, + RPI_FIRMWARE_GET_CLOCK_MEASURED = 0x00030047, + RPI_FIRMWARE_NOTIFY_REBOOT = 0x00030048, + RPI_FIRMWARE_SET_CLOCK_STATE = 0x00038001, + RPI_FIRMWARE_SET_CLOCK_RATE = 0x00038002, + RPI_FIRMWARE_SET_VOLTAGE = 0x00038003, + RPI_FIRMWARE_SET_TURBO = 0x00038009, + RPI_FIRMWARE_SET_CUSTOMER_OTP = 0x00038021, + RPI_FIRMWARE_SET_DOMAIN_STATE = 0x00038030, + RPI_FIRMWARE_GET_GPIO_STATE = 0x00030041, + RPI_FIRMWARE_SET_GPIO_STATE = 0x00038041, + RPI_FIRMWARE_SET_SDHOST_CLOCK = 0x00038042, + RPI_FIRMWARE_GET_GPIO_CONFIG = 0x00030043, + RPI_FIRMWARE_SET_GPIO_CONFIG = 0x00038043, + RPI_FIRMWARE_GET_PERIPH_REG = 0x00030045, + RPI_FIRMWARE_SET_PERIPH_REG = 0x00038045, + RPI_FIRMWARE_GET_POE_HAT_VAL = 0x00030049, + RPI_FIRMWARE_SET_POE_HAT_VAL = 0x00030050, /* Dispmanx TAGS */ - RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001, - RPI_FIRMWARE_FRAMEBUFFER_BLANK = 0x00040002, - RPI_FIRMWARE_FRAMEBUFFER_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, - RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, - RPI_FIRMWARE_FRAMEBUFFER_GET_DEPTH = 0x00040005, - RPI_FIRMWARE_FRAMEBUFFER_GET_PIXEL_ORDER = 0x00040006, - RPI_FIRMWARE_FRAMEBUFFER_GET_ALPHA_MODE = 0x00040007, - RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH = 0x00040008, - RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_OFFSET = 0x00040009, - RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN = 0x0004000a, - RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE = 0x0004000b, - RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF = 0x0004000f, - RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF = 0x00040010, - RPI_FIRMWARE_FRAMEBUFFER_RELEASE = 0x00048001, + RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001, + RPI_FIRMWARE_FRAMEBUFFER_BLANK = 0x00040002, + RPI_FIRMWARE_FRAMEBUFFER_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, + RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, + RPI_FIRMWARE_FRAMEBUFFER_GET_DEPTH = 0x00040005, + RPI_FIRMWARE_FRAMEBUFFER_GET_PIXEL_ORDER = 0x00040006, + RPI_FIRMWARE_FRAMEBUFFER_GET_ALPHA_MODE = 0x00040007, + RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH = 0x00040008, + RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_OFFSET = 0x00040009, + RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN = 0x0004000a, + RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE = 0x0004000b, + RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF = 0x0004000f, + RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF = 0x00040010, + RPI_FIRMWARE_FRAMEBUFFER_RELEASE = 0x00048001, RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, - RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, - RPI_FIRMWARE_FRAMEBUFFER_TEST_DEPTH = 0x00044005, - RPI_FIRMWARE_FRAMEBUFFER_TEST_PIXEL_ORDER = 0x00044006, - RPI_FIRMWARE_FRAMEBUFFER_TEST_ALPHA_MODE = 0x00044007, - RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_OFFSET = 0x00044009, - RPI_FIRMWARE_FRAMEBUFFER_TEST_OVERSCAN = 0x0004400a, - RPI_FIRMWARE_FRAMEBUFFER_TEST_PALETTE = 0x0004400b, - RPI_FIRMWARE_FRAMEBUFFER_TEST_VSYNC = 0x0004400e, - RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, - RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, - RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH = 0x00048005, - RPI_FIRMWARE_FRAMEBUFFER_SET_PIXEL_ORDER = 0x00048006, - RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE = 0x00048007, - RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009, - RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a, - RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b, - RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF = 0x0004801f, - RPI_FIRMWARE_FRAMEBUFFER_SET_GPIOVIRTBUF = 0x00048020, - RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC = 0x0004800e, - RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT = 0x0004800f, + RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, + RPI_FIRMWARE_FRAMEBUFFER_TEST_DEPTH = 0x00044005, + RPI_FIRMWARE_FRAMEBUFFER_TEST_PIXEL_ORDER = 0x00044006, + RPI_FIRMWARE_FRAMEBUFFER_TEST_ALPHA_MODE = 0x00044007, + RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_OFFSET = 0x00044009, + RPI_FIRMWARE_FRAMEBUFFER_TEST_OVERSCAN = 0x0004400a, + RPI_FIRMWARE_FRAMEBUFFER_TEST_PALETTE = 0x0004400b, + RPI_FIRMWARE_FRAMEBUFFER_TEST_VSYNC = 0x0004400e, + RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, + RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, + RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH = 0x00048005, + RPI_FIRMWARE_FRAMEBUFFER_SET_PIXEL_ORDER = 0x00048006, + RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE = 0x00048007, + RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009, + RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a, + RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b, + RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF = 0x0004801f, + RPI_FIRMWARE_FRAMEBUFFER_SET_GPIOVIRTBUF = 0x00048020, + RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC = 0x0004800e, + RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT = 0x0004800f, - RPI_FIRMWARE_VCHIQ_INIT = 0x00048010, + RPI_FIRMWARE_VCHIQ_INIT = 0x00048010, - RPI_FIRMWARE_GET_COMMAND_LINE = 0x00050001, - RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, + RPI_FIRMWARE_GET_COMMAND_LINE = 0x00050001, + RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, } use self::PropertyMailboxTagId::*; @@ -268,7 +268,10 @@ pub fn framebuffer_get_depth() -> PropertyMailboxResult { /// Set virtual offset. Returns `(X, Y)` in pixel. /// The response may not be the same as the request so it must be checked. /// May be the previous offset or 0 for unsupported. -pub fn framebuffer_set_virtual_offset(xoffset: u32, yoffset: u32) -> PropertyMailboxResult<(u32, u32)> { +pub fn framebuffer_set_virtual_offset( + xoffset: u32, + yoffset: u32, +) -> PropertyMailboxResult<(u32, u32)> { let ret = send_one_tag!( RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET, [xoffset, yoffset] @@ -278,7 +281,11 @@ pub fn framebuffer_set_virtual_offset(xoffset: u32, yoffset: u32) -> PropertyMai /// Allocate framebuffer on GPU and try to set width/height/depth. /// Returns `FramebufferInfo`. -pub fn framebuffer_alloc(width: u32, height: u32, depth: u32) -> PropertyMailboxResult { +pub fn framebuffer_alloc( + width: u32, + height: u32, + depth: u32, +) -> PropertyMailboxResult { #[repr(C, packed)] #[derive(Debug)] struct FramebufferAllocTag { diff --git a/kernel/src/arch/aarch64/board/raspi3/mod.rs b/kernel/src/arch/aarch64/board/raspi3/mod.rs index ff959e4..713c725 100644 --- a/kernel/src/arch/aarch64/board/raspi3/mod.rs +++ b/kernel/src/arch/aarch64/board/raspi3/mod.rs @@ -1,13 +1,13 @@ //! Raspberry PI 3 Model B/B+ -use once::*; use bcm2837::atags::Atags; +use once::*; pub mod fb; pub mod irq; -pub mod timer; -pub mod serial; pub mod mailbox; +pub mod serial; +pub mod timer; pub const IO_REMAP_BASE: usize = bcm2837::consts::IO_BASE; pub const IO_REMAP_END: usize = bcm2837::consts::KERNEL_OFFSET + 0x4000_1000; diff --git a/kernel/src/arch/aarch64/board/raspi3/serial.rs b/kernel/src/arch/aarch64/board/raspi3/serial.rs index bdec9ac..b7796d3 100644 --- a/kernel/src/arch/aarch64/board/raspi3/serial.rs +++ b/kernel/src/arch/aarch64/board/raspi3/serial.rs @@ -1,8 +1,8 @@ use bcm2837::mini_uart::{MiniUart, MiniUartInterruptId}; -use lazy_static::lazy_static; use core::fmt; -use spin::Mutex; +use lazy_static::lazy_static; use once::*; +use spin::Mutex; /// Struct to get a global SerialPort interface pub struct SerialPort { diff --git a/kernel/src/arch/aarch64/driver/console/fonts/font8x16.rs b/kernel/src/arch/aarch64/driver/console/fonts/font8x16.rs index 89ffe67..7513e85 100644 --- a/kernel/src/arch/aarch64/driver/console/fonts/font8x16.rs +++ b/kernel/src/arch/aarch64/driver/console/fonts/font8x16.rs @@ -25,7 +25,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 1 0x01 '^A' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -43,7 +42,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 2 0x02 '^B' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -61,7 +59,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 3 0x03 '^C' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -79,7 +76,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 4 0x04 '^D' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -97,7 +93,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 5 0x05 '^E' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -115,7 +110,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 6 0x06 '^F' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -133,7 +127,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 7 0x07 '^G' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -151,7 +144,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 8 0x08 '^H' */ 0xff, /* 11111111 */ 0xff, /* 11111111 */ @@ -169,7 +161,6 @@ impl Font8x16 { 0xff, /* 11111111 */ 0xff, /* 11111111 */ 0xff, /* 11111111 */ - /* 9 0x09 '^I' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -187,7 +178,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 10 0x0a '^J' */ 0xff, /* 11111111 */ 0xff, /* 11111111 */ @@ -205,7 +195,6 @@ impl Font8x16 { 0xff, /* 11111111 */ 0xff, /* 11111111 */ 0xff, /* 11111111 */ - /* 11 0x0b '^K' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -223,7 +212,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 12 0x0c '^L' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -241,7 +229,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 13 0x0d '^M' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -259,7 +246,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 14 0x0e '^N' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -277,7 +263,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 15 0x0f '^O' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -295,7 +280,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 16 0x10 '^P' */ 0x00, /* 00000000 */ 0x80, /* 10000000 */ @@ -313,7 +297,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 17 0x11 '^Q' */ 0x00, /* 00000000 */ 0x02, /* 00000010 */ @@ -331,7 +314,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 18 0x12 '^R' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -349,7 +331,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 19 0x13 '^S' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -367,7 +348,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 20 0x14 '^T' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -385,7 +365,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 21 0x15 '^U' */ 0x00, /* 00000000 */ 0x7c, /* 01111100 */ @@ -403,7 +382,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 22 0x16 '^V' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -421,7 +399,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 23 0x17 '^W' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -439,7 +416,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 24 0x18 '^X' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -457,7 +433,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 25 0x19 '^Y' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -475,7 +450,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 26 0x1a '^Z' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -493,7 +467,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 27 0x1b '^[' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -511,7 +484,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 28 0x1c '^\' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -529,7 +501,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 29 0x1d '^]' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -547,7 +518,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 30 0x1e '^^' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -565,7 +535,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 31 0x1f '^_' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -583,7 +552,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 32 0x20 ' ' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -601,7 +569,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 33 0x21 '!' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -619,7 +586,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 34 0x22 '"' */ 0x00, /* 00000000 */ 0x66, /* 01100110 */ @@ -637,7 +603,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 35 0x23 '#' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -655,7 +620,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 36 0x24 '$' */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ @@ -673,7 +637,6 @@ impl Font8x16 { 0x18, /* 00011000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 37 0x25 '%' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -691,7 +654,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 38 0x26 '&' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -709,7 +671,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 39 0x27 ''' */ 0x00, /* 00000000 */ 0x30, /* 00110000 */ @@ -727,7 +688,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 40 0x28 '(' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -745,7 +705,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 41 0x29 ')' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -763,7 +722,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 42 0x2a '*' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -781,7 +739,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 43 0x2b '+' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -799,7 +756,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 44 0x2c ',' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -817,7 +773,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 45 0x2d '-' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -835,7 +790,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 46 0x2e '.' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -853,7 +807,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 47 0x2f '/' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -871,7 +824,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 48 0x30 '0' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -889,7 +841,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 49 0x31 '1' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -907,7 +858,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 50 0x32 '2' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -925,7 +875,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 51 0x33 '3' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -943,7 +892,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 52 0x34 '4' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -961,7 +909,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 53 0x35 '5' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -979,7 +926,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 54 0x36 '6' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -997,7 +943,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 55 0x37 '7' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1015,7 +960,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 56 0x38 '8' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1033,7 +977,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 57 0x39 '9' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1051,7 +994,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 58 0x3a ':' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1069,7 +1011,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 59 0x3b ';' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1087,7 +1028,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 60 0x3c '<' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1105,7 +1045,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 61 0x3d '=' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1123,7 +1062,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 62 0x3e '>' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1141,7 +1079,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 63 0x3f '?' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1159,7 +1096,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 64 0x40 '@' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1177,7 +1113,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 65 0x41 'A' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1195,7 +1130,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 66 0x42 'B' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1213,7 +1147,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 67 0x43 'C' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1231,7 +1164,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 68 0x44 'D' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1249,7 +1181,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 69 0x45 'E' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1267,7 +1198,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 70 0x46 'F' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1285,7 +1215,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 71 0x47 'G' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1303,7 +1232,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 72 0x48 'H' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1321,7 +1249,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 73 0x49 'I' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1339,7 +1266,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 74 0x4a 'J' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1357,7 +1283,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 75 0x4b 'K' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1375,7 +1300,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 76 0x4c 'L' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1393,7 +1317,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 77 0x4d 'M' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1411,7 +1334,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 78 0x4e 'N' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1429,7 +1351,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 79 0x4f 'O' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1447,7 +1368,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 80 0x50 'P' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1465,7 +1385,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 81 0x51 'Q' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1483,7 +1402,6 @@ impl Font8x16 { 0x0e, /* 00001110 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 82 0x52 'R' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1501,7 +1419,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 83 0x53 'S' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1519,7 +1436,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 84 0x54 'T' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1537,7 +1453,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 85 0x55 'U' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1555,7 +1470,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 86 0x56 'V' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1573,7 +1487,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 87 0x57 'W' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1591,7 +1504,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 88 0x58 'X' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1609,7 +1521,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 89 0x59 'Y' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1627,7 +1538,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 90 0x5a 'Z' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1645,7 +1555,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 91 0x5b '[' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1663,7 +1572,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 92 0x5c '\' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1681,7 +1589,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 93 0x5d ']' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1699,7 +1606,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 94 0x5e '^' */ 0x10, /* 00010000 */ 0x38, /* 00111000 */ @@ -1717,7 +1623,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 95 0x5f '_' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1735,7 +1640,6 @@ impl Font8x16 { 0xff, /* 11111111 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 96 0x60 '`' */ 0x00, /* 00000000 */ 0x30, /* 00110000 */ @@ -1753,7 +1657,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 97 0x61 'a' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1771,7 +1674,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 98 0x62 'b' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1789,7 +1691,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 99 0x63 'c' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1807,7 +1708,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 100 0x64 'd' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1825,7 +1725,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 101 0x65 'e' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1843,7 +1742,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 102 0x66 'f' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1861,7 +1759,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 103 0x67 'g' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1879,7 +1776,6 @@ impl Font8x16 { 0xcc, /* 11001100 */ 0x78, /* 01111000 */ 0x00, /* 00000000 */ - /* 104 0x68 'h' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1897,7 +1793,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 105 0x69 'i' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1915,7 +1810,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 106 0x6a 'j' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1933,7 +1827,6 @@ impl Font8x16 { 0x66, /* 01100110 */ 0x3c, /* 00111100 */ 0x00, /* 00000000 */ - /* 107 0x6b 'k' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1951,7 +1844,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 108 0x6c 'l' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1969,7 +1861,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 109 0x6d 'm' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1987,7 +1878,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 110 0x6e 'n' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2005,7 +1895,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 111 0x6f 'o' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2023,7 +1912,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 112 0x70 'p' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2041,7 +1929,6 @@ impl Font8x16 { 0x60, /* 01100000 */ 0xf0, /* 11110000 */ 0x00, /* 00000000 */ - /* 113 0x71 'q' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2059,7 +1946,6 @@ impl Font8x16 { 0x0c, /* 00001100 */ 0x1e, /* 00011110 */ 0x00, /* 00000000 */ - /* 114 0x72 'r' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2077,7 +1963,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 115 0x73 's' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2095,7 +1980,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 116 0x74 't' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2113,7 +1997,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 117 0x75 'u' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2131,7 +2014,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 118 0x76 'v' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2149,7 +2031,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 119 0x77 'w' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2167,7 +2048,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 120 0x78 'x' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2185,7 +2065,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 121 0x79 'y' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2203,7 +2082,6 @@ impl Font8x16 { 0x0c, /* 00001100 */ 0xf8, /* 11111000 */ 0x00, /* 00000000 */ - /* 122 0x7a 'z' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2221,7 +2099,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 123 0x7b '{' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2239,7 +2116,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 124 0x7c '|' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2257,7 +2133,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 125 0x7d '}' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2275,7 +2150,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 126 0x7e '~' */ 0x00, /* 00000000 */ 0x76, /* 01110110 */ @@ -2293,7 +2167,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 127 0x7f '' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2311,7 +2184,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 128 0x80 'Ç' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2329,7 +2201,6 @@ impl Font8x16 { 0x70, /* 01110000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 129 0x81 'ü' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2347,7 +2218,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 130 0x82 'é' */ 0x00, /* 00000000 */ 0x0c, /* 00001100 */ @@ -2365,7 +2235,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 131 0x83 'â' */ 0x00, /* 00000000 */ 0x10, /* 00010000 */ @@ -2383,7 +2252,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 132 0x84 'ä' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2401,7 +2269,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 133 0x85 'à' */ 0x00, /* 00000000 */ 0x60, /* 01100000 */ @@ -2419,7 +2286,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 134 0x86 'å' */ 0x00, /* 00000000 */ 0x38, /* 00111000 */ @@ -2437,7 +2303,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 135 0x87 'ç' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2455,7 +2320,6 @@ impl Font8x16 { 0x70, /* 01110000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 136 0x88 'ê' */ 0x00, /* 00000000 */ 0x10, /* 00010000 */ @@ -2473,7 +2337,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 137 0x89 'ë' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2491,7 +2354,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 138 0x8a 'è' */ 0x00, /* 00000000 */ 0x60, /* 01100000 */ @@ -2509,7 +2371,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 139 0x8b 'ï' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2527,7 +2388,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 140 0x8c 'î' */ 0x00, /* 00000000 */ 0x18, /* 00011000 */ @@ -2545,7 +2405,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 141 0x8d 'ì' */ 0x00, /* 00000000 */ 0x60, /* 01100000 */ @@ -2563,7 +2422,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 142 0x8e 'Ä' */ 0x00, /* 00000000 */ 0xc6, /* 11000110 */ @@ -2581,7 +2439,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 143 0x8f 'Å' */ 0x38, /* 00111000 */ 0x6c, /* 01101100 */ @@ -2599,7 +2456,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 144 0x90 'É' */ 0x0c, /* 00001100 */ 0x18, /* 00011000 */ @@ -2617,7 +2473,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 145 0x91 'æ' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2635,7 +2490,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 146 0x92 'Æ' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2653,7 +2507,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 147 0x93 'ô' */ 0x00, /* 00000000 */ 0x10, /* 00010000 */ @@ -2671,7 +2524,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 148 0x94 'ö' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2689,7 +2541,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 149 0x95 'ò' */ 0x00, /* 00000000 */ 0x60, /* 01100000 */ @@ -2707,7 +2558,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 150 0x96 'û' */ 0x00, /* 00000000 */ 0x30, /* 00110000 */ @@ -2725,7 +2575,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 151 0x97 'ù' */ 0x00, /* 00000000 */ 0x60, /* 01100000 */ @@ -2743,7 +2592,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 152 0x98 'ÿ' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2761,7 +2609,6 @@ impl Font8x16 { 0x0c, /* 00001100 */ 0x78, /* 01111000 */ 0x00, /* 00000000 */ - /* 153 0x99 'Ö' */ 0x00, /* 00000000 */ 0xc6, /* 11000110 */ @@ -2779,7 +2626,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 154 0x9a 'Ü' */ 0x00, /* 00000000 */ 0xc6, /* 11000110 */ @@ -2797,7 +2643,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 155 0x9b '¢' */ 0x00, /* 00000000 */ 0x18, /* 00011000 */ @@ -2815,7 +2660,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 156 0x9c '£' */ 0x00, /* 00000000 */ 0x38, /* 00111000 */ @@ -2833,7 +2677,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 157 0x9d '¥' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2851,7 +2694,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 158 0x9e '₧' */ 0x00, /* 00000000 */ 0xf8, /* 11111000 */ @@ -2869,7 +2711,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 159 0x9f 'ƒ' */ 0x00, /* 00000000 */ 0x0e, /* 00001110 */ @@ -2887,7 +2728,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 160 0xa0 'á' */ 0x00, /* 00000000 */ 0x18, /* 00011000 */ @@ -2905,7 +2745,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 161 0xa1 'í' */ 0x00, /* 00000000 */ 0x0c, /* 00001100 */ @@ -2923,7 +2762,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 162 0xa2 'ó' */ 0x00, /* 00000000 */ 0x18, /* 00011000 */ @@ -2941,7 +2779,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 163 0xa3 'ú' */ 0x00, /* 00000000 */ 0x18, /* 00011000 */ @@ -2959,7 +2796,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 164 0xa4 'ñ' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2977,7 +2813,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 165 0xa5 'Ñ' */ 0x76, /* 01110110 */ 0xdc, /* 11011100 */ @@ -2995,7 +2830,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 166 0xa6 'ª' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3013,7 +2847,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 167 0xa7 'º' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3031,7 +2864,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 168 0xa8 '¿' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3049,7 +2881,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 169 0xa9 '⌐' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3067,7 +2898,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 170 0xaa '¬' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3085,7 +2915,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 171 0xab '½' */ 0x00, /* 00000000 */ 0x60, /* 01100000 */ @@ -3103,7 +2932,6 @@ impl Font8x16 { 0x3e, /* 00111110 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 172 0xac '¼' */ 0x00, /* 00000000 */ 0x60, /* 01100000 */ @@ -3121,7 +2949,6 @@ impl Font8x16 { 0x06, /* 00000110 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 173 0xad '¡' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3139,7 +2966,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 174 0xae '«' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3157,7 +2983,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 175 0xaf '»' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3175,7 +3000,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 176 0xb0 '░' */ 0x11, /* 00010001 */ 0x44, /* 01000100 */ @@ -3193,7 +3017,6 @@ impl Font8x16 { 0x44, /* 01000100 */ 0x11, /* 00010001 */ 0x44, /* 01000100 */ - /* 177 0xb1 '▒' */ 0x55, /* 01010101 */ 0xaa, /* 10101010 */ @@ -3211,7 +3034,6 @@ impl Font8x16 { 0xaa, /* 10101010 */ 0x55, /* 01010101 */ 0xaa, /* 10101010 */ - /* 178 0xb2 '▓' */ 0xdd, /* 11011101 */ 0x77, /* 01110111 */ @@ -3229,7 +3051,6 @@ impl Font8x16 { 0x77, /* 01110111 */ 0xdd, /* 11011101 */ 0x77, /* 01110111 */ - /* 179 0xb3 '│' */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ @@ -3247,7 +3068,6 @@ impl Font8x16 { 0x18, /* 00011000 */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ - /* 180 0xb4 '┤' */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ @@ -3265,7 +3085,6 @@ impl Font8x16 { 0x18, /* 00011000 */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ - /* 181 0xb5 '╡' */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ @@ -3283,7 +3102,6 @@ impl Font8x16 { 0x18, /* 00011000 */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ - /* 182 0xb6 '╢' */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ @@ -3301,7 +3119,6 @@ impl Font8x16 { 0x36, /* 00110110 */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ - /* 183 0xb7 '╖' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3319,7 +3136,6 @@ impl Font8x16 { 0x36, /* 00110110 */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ - /* 184 0xb8 '╕' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3337,7 +3153,6 @@ impl Font8x16 { 0x18, /* 00011000 */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ - /* 185 0xb9 '╣' */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ @@ -3355,7 +3170,6 @@ impl Font8x16 { 0x36, /* 00110110 */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ - /* 186 0xba '║' */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ @@ -3373,7 +3187,6 @@ impl Font8x16 { 0x36, /* 00110110 */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ - /* 187 0xbb '╗' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3391,7 +3204,6 @@ impl Font8x16 { 0x36, /* 00110110 */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ - /* 188 0xbc '╝' */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ @@ -3409,7 +3221,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 189 0xbd '╜' */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ @@ -3427,7 +3238,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 190 0xbe '╛' */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ @@ -3445,7 +3255,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 191 0xbf '┐' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3463,7 +3272,6 @@ impl Font8x16 { 0x18, /* 00011000 */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ - /* 192 0xc0 '└' */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ @@ -3481,7 +3289,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 193 0xc1 '┴' */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ @@ -3499,7 +3306,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 194 0xc2 '┬' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3517,7 +3323,6 @@ impl Font8x16 { 0x18, /* 00011000 */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ - /* 195 0xc3 '├' */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ @@ -3535,7 +3340,6 @@ impl Font8x16 { 0x18, /* 00011000 */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ - /* 196 0xc4 '─' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3553,7 +3357,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 197 0xc5 '┼' */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ @@ -3571,7 +3374,6 @@ impl Font8x16 { 0x18, /* 00011000 */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ - /* 198 0xc6 '╞' */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ @@ -3589,7 +3391,6 @@ impl Font8x16 { 0x18, /* 00011000 */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ - /* 199 0xc7 '╟' */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ @@ -3607,7 +3408,6 @@ impl Font8x16 { 0x36, /* 00110110 */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ - /* 200 0xc8 '╚' */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ @@ -3625,7 +3425,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 201 0xc9 '╔' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3643,7 +3442,6 @@ impl Font8x16 { 0x36, /* 00110110 */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ - /* 202 0xca '╩' */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ @@ -3661,7 +3459,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 203 0xcb '╦' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3679,7 +3476,6 @@ impl Font8x16 { 0x36, /* 00110110 */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ - /* 204 0xcc '╠' */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ @@ -3697,7 +3493,6 @@ impl Font8x16 { 0x36, /* 00110110 */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ - /* 205 0xcd '═' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3715,7 +3510,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 206 0xce '╬' */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ @@ -3733,7 +3527,6 @@ impl Font8x16 { 0x36, /* 00110110 */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ - /* 207 0xcf '╧' */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ @@ -3751,7 +3544,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 208 0xd0 '╨' */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ @@ -3769,7 +3561,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 209 0xd1 '╤' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3787,7 +3578,6 @@ impl Font8x16 { 0x18, /* 00011000 */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ - /* 210 0xd2 '╥' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3805,7 +3595,6 @@ impl Font8x16 { 0x36, /* 00110110 */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ - /* 211 0xd3 '╙' */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ @@ -3823,7 +3612,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 212 0xd4 '╘' */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ @@ -3841,7 +3629,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 213 0xd5 '╒' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3859,7 +3646,6 @@ impl Font8x16 { 0x18, /* 00011000 */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ - /* 214 0xd6 '╓' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3877,7 +3663,6 @@ impl Font8x16 { 0x36, /* 00110110 */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ - /* 215 0xd7 '╫' */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ @@ -3895,7 +3680,6 @@ impl Font8x16 { 0x36, /* 00110110 */ 0x36, /* 00110110 */ 0x36, /* 00110110 */ - /* 216 0xd8 '╪' */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ @@ -3913,7 +3697,6 @@ impl Font8x16 { 0x18, /* 00011000 */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ - /* 217 0xd9 '┘' */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ @@ -3931,7 +3714,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 218 0xda '┌' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3949,7 +3731,6 @@ impl Font8x16 { 0x18, /* 00011000 */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ - /* 219 0xdb '█' */ 0xff, /* 11111111 */ 0xff, /* 11111111 */ @@ -3967,7 +3748,6 @@ impl Font8x16 { 0xff, /* 11111111 */ 0xff, /* 11111111 */ 0xff, /* 11111111 */ - /* 220 0xdc '▄' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3985,7 +3765,6 @@ impl Font8x16 { 0xff, /* 11111111 */ 0xff, /* 11111111 */ 0xff, /* 11111111 */ - /* 221 0xdd '▌' */ 0xf0, /* 11110000 */ 0xf0, /* 11110000 */ @@ -4003,7 +3782,6 @@ impl Font8x16 { 0xf0, /* 11110000 */ 0xf0, /* 11110000 */ 0xf0, /* 11110000 */ - /* 222 0xde '▐' */ 0x0f, /* 00001111 */ 0x0f, /* 00001111 */ @@ -4021,7 +3799,6 @@ impl Font8x16 { 0x0f, /* 00001111 */ 0x0f, /* 00001111 */ 0x0f, /* 00001111 */ - /* 223 0xdf '▀' */ 0xff, /* 11111111 */ 0xff, /* 11111111 */ @@ -4039,7 +3816,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 224 0xe0 'α' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4057,7 +3833,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 225 0xe1 'ß' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4075,7 +3850,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 226 0xe2 'Γ' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4093,7 +3867,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 227 0xe3 'π' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4111,7 +3884,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 228 0xe4 'Σ' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4129,7 +3901,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 229 0xe5 'σ' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4147,7 +3918,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 230 0xe6 'µ' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4165,7 +3935,6 @@ impl Font8x16 { 0x60, /* 01100000 */ 0xc0, /* 11000000 */ 0x00, /* 00000000 */ - /* 231 0xe7 'τ' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4183,7 +3952,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 232 0xe8 'Φ' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4201,7 +3969,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 233 0xe9 'Θ' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4219,7 +3986,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 234 0xea 'Ω' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4237,7 +4003,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 235 0xeb 'δ' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4255,7 +4020,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 236 0xec '∞' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4273,7 +4037,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 237 0xed 'φ' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4291,7 +4054,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 238 0xee 'ε' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4309,7 +4071,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 239 0xef '∩' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4327,7 +4088,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 240 0xf0 '≡' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4345,7 +4105,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 241 0xf1 '±' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4363,7 +4122,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 242 0xf2 '≥' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4381,7 +4139,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 243 0xf3 '≤' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4399,7 +4156,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 244 0xf4 '⌠' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4417,7 +4173,6 @@ impl Font8x16 { 0x18, /* 00011000 */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ - /* 245 0xf5 '⌡' */ 0x18, /* 00011000 */ 0x18, /* 00011000 */ @@ -4435,7 +4190,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 246 0xf6 '÷' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4453,7 +4207,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 247 0xf7 '≈' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4471,7 +4224,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 248 0xf8 '°' */ 0x00, /* 00000000 */ 0x38, /* 00111000 */ @@ -4489,7 +4241,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 249 0xf9 '·' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4507,7 +4258,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 250 0xfa '•' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4525,7 +4275,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 251 0xfb '√' */ 0x00, /* 00000000 */ 0x0f, /* 00001111 */ @@ -4543,7 +4292,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 252 0xfc 'ⁿ' */ 0x00, /* 00000000 */ 0x6c, /* 01101100 */ @@ -4561,7 +4309,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 253 0xfd '²' */ 0x00, /* 00000000 */ 0x3c, /* 00111100 */ @@ -4579,7 +4326,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 254 0xfe '■' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -4597,7 +4343,6 @@ impl Font8x16 { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 255 0xff ' ' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ diff --git a/kernel/src/arch/aarch64/driver/console/mod.rs b/kernel/src/arch/aarch64/driver/console/mod.rs index 0947ce6..b16ae13 100644 --- a/kernel/src/arch/aarch64/driver/console/mod.rs +++ b/kernel/src/arch/aarch64/driver/console/mod.rs @@ -10,7 +10,7 @@ use spin::Mutex; use crate::util::escape_parser::{CharacterAttribute, EscapeParser}; -use super::fb::{ColorDepth::*, FRAME_BUFFER, FramebufferInfo}; +use super::fb::{ColorDepth::*, FramebufferInfo, FRAME_BUFFER}; use self::color::FramebufferColor; use self::fonts::{Font, Font8x16}; @@ -67,10 +67,7 @@ impl ConsoleBuffer { ch.attr.foreground.pack16() as u32, ch.attr.background.pack16() as u32, ), - ColorDepth32 => ( - ch.attr.foreground.pack32(), - ch.attr.background.pack32(), - ), + ColorDepth32 => (ch.attr.foreground.pack32(), ch.attr.background.pack32()), }; if ch.attr.reverse { core::mem::swap(&mut foreground, &mut background); @@ -87,7 +84,10 @@ impl ConsoleBuffer { }; for y in 0..F::HEIGHT { for x in 0..F::WIDTH { - let pixel = if y == underline_y || y == strikethrough_y || F::get(ch.ascii_char, x, y) { + let pixel = if y == underline_y + || y == strikethrough_y + || F::get(ch.ascii_char, x, y) + { foreground } else { background diff --git a/kernel/src/arch/aarch64/interrupt/context.rs b/kernel/src/arch/aarch64/interrupt/context.rs index fce337b..6639ab8 100644 --- a/kernel/src/arch/aarch64/interrupt/context.rs +++ b/kernel/src/arch/aarch64/interrupt/context.rs @@ -1,11 +1,11 @@ //! TrapFrame and context definitions for aarch64. -use spin::Mutex; -use lazy_static::lazy_static; -use aarch64::barrier; use aarch64::addr::PhysAddr; -use aarch64::paging::PhysFrame; use aarch64::asm::{tlb_invalidate_all, ttbr_el1_read, ttbr_el1_write_asid}; +use aarch64::barrier; +use aarch64::paging::PhysFrame; +use lazy_static::lazy_static; +use spin::Mutex; #[repr(C)] #[derive(Default, Debug, Copy, Clone)] @@ -23,7 +23,7 @@ pub struct TrapFrame { /// 用于在内核栈中构造新线程的中断帧 impl TrapFrame { - fn new_kernel_thread(entry: extern fn(usize) -> !, arg: usize, sp: usize) -> Self { + fn new_kernel_thread(entry: extern "C" fn(usize) -> !, arg: usize, sp: usize) -> Self { use core::mem::zeroed; let mut tf: Self = unsafe { zeroed() }; tf.x0 = arg; @@ -65,7 +65,7 @@ impl InitStack { } } -extern { +extern "C" { fn __trapret(); } @@ -78,7 +78,10 @@ struct ContextData { impl ContextData { fn new() -> Self { - ContextData { lr: __trapret as usize, ..ContextData::default() } + ContextData { + lr: __trapret as usize, + ..ContextData::default() + } } } @@ -99,7 +102,7 @@ impl Context { /// Pop all callee-saved registers, then return to the target. #[naked] #[inline(never)] - unsafe extern fn __switch(_self_stack: &mut usize, _target_stack: &mut usize) { + unsafe extern "C" fn __switch(_self_stack: &mut usize, _target_stack: &mut usize) { asm!( " mov x10, #-(12 * 8) @@ -144,17 +147,30 @@ impl Context { } } - pub unsafe fn new_kernel_thread(entry: extern fn(usize) -> !, arg: usize, kstack_top: usize, ttbr: usize) -> Self { + pub unsafe fn new_kernel_thread( + entry: extern "C" fn(usize) -> !, + arg: usize, + kstack_top: usize, + ttbr: usize, + ) -> Self { InitStack { context: ContextData::new(), tf: TrapFrame::new_kernel_thread(entry, arg, kstack_top), - }.push_at(kstack_top, ttbr) + } + .push_at(kstack_top, ttbr) } - pub unsafe fn new_user_thread(entry_addr: usize, ustack_top: usize, kstack_top: usize, _is32: bool, ttbr: usize) -> Self { + pub unsafe fn new_user_thread( + entry_addr: usize, + ustack_top: usize, + kstack_top: usize, + _is32: bool, + ttbr: usize, + ) -> Self { InitStack { context: ContextData::new(), tf: TrapFrame::new_user_thread(entry_addr, ustack_top), - }.push_at(kstack_top, ttbr) + } + .push_at(kstack_top, ttbr) } pub unsafe fn new_fork(tf: &TrapFrame, kstack_top: usize, ttbr: usize) -> Self { InitStack { @@ -164,9 +180,16 @@ impl Context { tf.x0 = 0; tf }, - }.push_at(kstack_top, ttbr) + } + .push_at(kstack_top, ttbr) } - pub unsafe fn new_clone(tf: &TrapFrame, ustack_top: usize, kstack_top: usize, ttbr: usize, tls: usize) -> Self { + pub unsafe fn new_clone( + tf: &TrapFrame, + ustack_top: usize, + kstack_top: usize, + ttbr: usize, + tls: usize, + ) -> Self { InitStack { context: ContextData::new(), tf: { @@ -176,14 +199,14 @@ impl Context { tf.x0 = 0; tf }, - }.push_at(kstack_top, ttbr) + } + .push_at(kstack_top, ttbr) } /// Called at a new user context /// To get the init TrapFrame in sys_exec pub unsafe fn get_init_tf(&self) -> TrapFrame { (*(self.stack_top as *const InitStack)).tf.clone() } - } const ASID_MASK: u16 = 0xffff; @@ -199,7 +222,10 @@ struct AsidAllocator(Asid); impl AsidAllocator { fn new() -> Self { - AsidAllocator(Asid { value: 0, generation: 1 }) + AsidAllocator(Asid { + value: 0, + generation: 1, + }) } fn alloc(&mut self, old_asid: Asid) -> Asid { diff --git a/kernel/src/arch/aarch64/interrupt/handler.rs b/kernel/src/arch/aarch64/interrupt/handler.rs index 0e997b5..fb74726 100644 --- a/kernel/src/arch/aarch64/interrupt/handler.rs +++ b/kernel/src/arch/aarch64/interrupt/handler.rs @@ -1,8 +1,8 @@ //! Trap handler -use crate::arch::board::irq::handle_irq; use super::context::TrapFrame; use super::syndrome::{Fault, Syndrome}; +use crate::arch::board::irq::handle_irq; use aarch64::regs::*; use log::*; diff --git a/kernel/src/arch/aarch64/interrupt/mod.rs b/kernel/src/arch/aarch64/interrupt/mod.rs index bba925a..70b05cb 100644 --- a/kernel/src/arch/aarch64/interrupt/mod.rs +++ b/kernel/src/arch/aarch64/interrupt/mod.rs @@ -1,7 +1,7 @@ //! Interrupt and exception for aarch64. -mod handler; mod context; +mod handler; mod syndrome; use aarch64::regs::*; diff --git a/kernel/src/arch/aarch64/io.rs b/kernel/src/arch/aarch64/io.rs index d452fcb..312e896 100644 --- a/kernel/src/arch/aarch64/io.rs +++ b/kernel/src/arch/aarch64/io.rs @@ -1,7 +1,7 @@ //! Input/output for aarch64. -use super::driver::serial::*; use super::driver::console::CONSOLE; +use super::driver::serial::*; use core::fmt::{Arguments, Write}; pub fn getchar() -> char { diff --git a/kernel/src/arch/aarch64/memory.rs b/kernel/src/arch/aarch64/memory.rs index 061c4f5..49bb094 100644 --- a/kernel/src/arch/aarch64/memory.rs +++ b/kernel/src/arch/aarch64/memory.rs @@ -1,8 +1,8 @@ //! Memory initialization for aarch64. -use crate::memory::{init_heap, Linear, MemoryAttr, MemorySet, FRAME_ALLOCATOR}; -use crate::consts::{MEMORY_OFFSET, KERNEL_OFFSET}; use super::paging::MMIOType; +use crate::consts::{KERNEL_OFFSET, MEMORY_OFFSET}; +use crate::memory::{init_heap, Linear, MemoryAttr, MemorySet, FRAME_ALLOCATOR}; use aarch64::regs::*; use log::*; use rcore_memory::PAGE_SIZE; @@ -19,7 +19,9 @@ fn init_frame_allocator() { use bit_allocator::BitAlloc; use core::ops::Range; - let end = super::board::probe_memory().expect("failed to find memory map").1; + let end = super::board::probe_memory() + .expect("failed to find memory map") + .1; let start = (_end as u64 + PAGE_SIZE as u64).wrapping_sub(KERNEL_OFFSET as u64) as usize; let mut ba = FRAME_ALLOCATOR.lock(); ba.insert(to_range(start, end)); @@ -39,14 +41,50 @@ static mut KERNEL_MEMORY_SET: Option = None; fn remap_the_kernel() { let offset = -(KERNEL_OFFSET as isize); let mut ms = MemorySet::new_bare(); - ms.push(stext as usize, etext as usize, MemoryAttr::default().execute().readonly(), Linear::new(offset), "text"); - ms.push(sdata as usize, edata as usize, MemoryAttr::default(), Linear::new(offset), "data"); - ms.push(srodata as usize, erodata as usize, MemoryAttr::default().readonly(), Linear::new(offset), "rodata"); - ms.push(sbss as usize, ebss as usize, MemoryAttr::default(), Linear::new(offset), "bss"); - ms.push(bootstack as usize, bootstacktop as usize, MemoryAttr::default(), Linear::new(offset), "kstack"); + ms.push( + stext as usize, + etext as usize, + MemoryAttr::default().execute().readonly(), + Linear::new(offset), + "text", + ); + ms.push( + sdata as usize, + edata as usize, + MemoryAttr::default(), + Linear::new(offset), + "data", + ); + ms.push( + srodata as usize, + erodata as usize, + MemoryAttr::default().readonly(), + Linear::new(offset), + "rodata", + ); + ms.push( + sbss as usize, + ebss as usize, + MemoryAttr::default(), + Linear::new(offset), + "bss", + ); + ms.push( + bootstack as usize, + bootstacktop as usize, + MemoryAttr::default(), + Linear::new(offset), + "kstack", + ); use super::board::{IO_REMAP_BASE, IO_REMAP_END}; - ms.push(IO_REMAP_BASE, IO_REMAP_END, MemoryAttr::default().mmio(MMIOType::Device as u8), Linear::new(offset), "io_remap"); + ms.push( + IO_REMAP_BASE, + IO_REMAP_END, + MemoryAttr::default().mmio(MMIOType::Device as u8), + Linear::new(offset), + "io_remap", + ); info!("{:#x?}", ms); unsafe { ms.get_page_table_mut().activate_as_kernel() } @@ -58,7 +96,13 @@ pub fn ioremap(paddr: usize, len: usize, name: &'static str) -> usize { let offset = -(KERNEL_OFFSET as isize); let vaddr = paddr.wrapping_add(KERNEL_OFFSET); if let Some(ms) = unsafe { KERNEL_MEMORY_SET.as_mut() } { - ms.push(vaddr, vaddr + len, MemoryAttr::default().mmio(MMIOType::NormalNonCacheable as u8), Linear::new(offset), name); + ms.push( + vaddr, + vaddr + len, + MemoryAttr::default().mmio(MMIOType::NormalNonCacheable as u8), + Linear::new(offset), + name, + ); return vaddr; } 0 diff --git a/kernel/src/arch/aarch64/mod.rs b/kernel/src/arch/aarch64/mod.rs index 39e25cc..eb8bc37 100644 --- a/kernel/src/arch/aarch64/mod.rs +++ b/kernel/src/arch/aarch64/mod.rs @@ -1,15 +1,15 @@ //! Entrance and initialization for aarch64. -pub mod io; -pub mod paging; -pub mod memory; -pub mod interrupt; pub mod consts; pub mod cpu; pub mod driver; -pub mod timer; -pub mod syscall; +pub mod interrupt; +pub mod io; +pub mod memory; +pub mod paging; pub mod rand; +pub mod syscall; +pub mod timer; #[cfg(feature = "board_raspi3")] #[path = "board/raspi3/mod.rs"] diff --git a/kernel/src/arch/aarch64/paging.rs b/kernel/src/arch/aarch64/paging.rs index e5da2bb..fc03b45 100644 --- a/kernel/src/arch/aarch64/paging.rs +++ b/kernel/src/arch/aarch64/paging.rs @@ -1,11 +1,13 @@ //! Page table implementations for aarch64. -use rcore_memory::paging::*; use aarch64::asm::{tlb_invalidate, tlb_invalidate_all, ttbr_el1_read, ttbr_el1_write}; -use aarch64::{PhysAddr, VirtAddr}; -use aarch64::paging::{Mapper, PageTable as Aarch64PageTable, PageTableEntry, PageTableFlags as EF, RecursivePageTable}; -use aarch64::paging::{FrameAllocator, FrameDeallocator, Page, PhysFrame as Frame, Size4KiB}; use aarch64::paging::memory_attribute::*; +use aarch64::paging::{FrameAllocator, FrameDeallocator, Page, PhysFrame as Frame, Size4KiB}; +use aarch64::paging::{ + Mapper, PageTable as Aarch64PageTable, PageTableEntry, PageTableFlags as EF, RecursivePageTable, +}; +use aarch64::{PhysAddr, VirtAddr}; use log::*; +use rcore_memory::paging::*; // Depends on kernel use crate::consts::{KERNEL_OFFSET, KERNEL_PML4, RECURSIVE_INDEX}; use crate::memory::{active_table, alloc_frame, dealloc_frame}; @@ -18,8 +20,16 @@ impl PageTable for ActivePageTable { fn map(&mut self, addr: usize, target: usize) -> &mut Entry { let flags = EF::default(); let attr = MairNormal::attr_value(); - self.0.map_to(Page::of_addr(addr as u64), Frame::of_addr(target as u64), flags, attr, &mut FrameAllocatorForAarch64) - .unwrap().flush(); + self.0 + .map_to( + Page::of_addr(addr as u64), + Frame::of_addr(target as u64), + flags, + attr, + &mut FrameAllocatorForAarch64, + ) + .unwrap() + .flush(); self.get_entry(addr).expect("fail to get entry") } @@ -30,7 +40,8 @@ impl PageTable for ActivePageTable { fn get_entry(&mut self, vaddr: usize) -> Option<&mut Entry> { // get p1 entry - let entry_addr = ((vaddr >> 9) & 0o777_777_777_7770) | (RECURSIVE_INDEX << 39) | (vaddr & KERNEL_OFFSET); + let entry_addr = + ((vaddr >> 9) & 0o777_777_777_7770) | (RECURSIVE_INDEX << 39) | (vaddr & KERNEL_OFFSET); Some(unsafe { &mut *(entry_addr as *mut PageEntry) }) } } @@ -39,12 +50,12 @@ impl PageTableExt for ActivePageTable { const TEMP_PAGE_ADDR: usize = KERNEL_OFFSET | 0xcafeb000; } -const ROOT_PAGE_TABLE: *mut Aarch64PageTable = - (KERNEL_OFFSET | - (RECURSIVE_INDEX << 39) | - (RECURSIVE_INDEX << 30) | - (RECURSIVE_INDEX << 21) | - (RECURSIVE_INDEX << 12)) as *mut Aarch64PageTable; +const ROOT_PAGE_TABLE: *mut Aarch64PageTable = (KERNEL_OFFSET + | (RECURSIVE_INDEX << 39) + | (RECURSIVE_INDEX << 30) + | (RECURSIVE_INDEX << 21) + | (RECURSIVE_INDEX << 12)) + as *mut Aarch64PageTable; impl ActivePageTable { pub unsafe fn new() -> Self { @@ -66,38 +77,63 @@ impl Entry for PageEntry { tlb_invalidate(addr); } - fn present(&self) -> bool { self.0.flags().contains(EF::VALID) } - fn accessed(&self) -> bool { self.0.flags().contains(EF::AF) } - fn writable(&self) -> bool { self.0.flags().contains(EF::WRITE) } - fn dirty(&self) -> bool { self.hw_dirty() && self.sw_dirty() } + fn present(&self) -> bool { + self.0.flags().contains(EF::VALID) + } + fn accessed(&self) -> bool { + self.0.flags().contains(EF::AF) + } + fn writable(&self) -> bool { + self.0.flags().contains(EF::WRITE) + } + fn dirty(&self) -> bool { + self.hw_dirty() && self.sw_dirty() + } - fn clear_accessed(&mut self) { self.as_flags().remove(EF::AF); } - fn clear_dirty(&mut self) - { + fn clear_accessed(&mut self) { + self.as_flags().remove(EF::AF); + } + fn clear_dirty(&mut self) { self.as_flags().remove(EF::DIRTY); self.as_flags().insert(EF::AP_RO); } - fn set_writable(&mut self, value: bool) - { + fn set_writable(&mut self, value: bool) { self.as_flags().set(EF::AP_RO, !value); self.as_flags().set(EF::WRITE, value); } - fn set_present(&mut self, value: bool) { self.as_flags().set(EF::VALID, value); } - fn target(&self) -> usize { self.0.addr().as_u64() as usize } + fn set_present(&mut self, value: bool) { + self.as_flags().set(EF::VALID, value); + } + fn target(&self) -> usize { + self.0.addr().as_u64() as usize + } fn set_target(&mut self, target: usize) { self.0.modify_addr(PhysAddr::new(target as u64)); } - fn writable_shared(&self) -> bool { self.0.flags().contains(EF::WRITABLE_SHARED) } - fn readonly_shared(&self) -> bool { self.0.flags().contains(EF::READONLY_SHARED) } + fn writable_shared(&self) -> bool { + self.0.flags().contains(EF::WRITABLE_SHARED) + } + fn readonly_shared(&self) -> bool { + self.0.flags().contains(EF::READONLY_SHARED) + } fn set_shared(&mut self, writable: bool) { let flags = self.as_flags(); flags.set(EF::WRITABLE_SHARED, writable); flags.set(EF::READONLY_SHARED, !writable); } - fn clear_shared(&mut self) { self.as_flags().remove(EF::WRITABLE_SHARED | EF::READONLY_SHARED); } - fn user(&self) -> bool { self.0.flags().contains(EF::AP_EL0) } - fn swapped(&self) -> bool { self.0.flags().contains(EF::SWAPPED) } - fn set_swapped(&mut self, value: bool) { self.as_flags().set(EF::SWAPPED, value); } + fn clear_shared(&mut self) { + self.as_flags() + .remove(EF::WRITABLE_SHARED | EF::READONLY_SHARED); + } + fn user(&self) -> bool { + self.0.flags().contains(EF::AP_EL0) + } + fn swapped(&self) -> bool { + self.0.flags().contains(EF::SWAPPED) + } + fn set_swapped(&mut self, value: bool) { + self.as_flags().set(EF::SWAPPED, value); + } fn set_user(&mut self, value: bool) { self.as_flags().set(EF::AP_EL0, value); self.as_flags().set(EF::nG, value); // set non-global to use ASID @@ -140,9 +176,15 @@ impl Entry for PageEntry { } impl PageEntry { - fn read_only(&self) -> bool { self.0.flags().contains(EF::AP_RO) } - fn hw_dirty(&self) -> bool { self.writable() && !self.read_only() } - fn sw_dirty(&self) -> bool { self.0.flags().contains(EF::DIRTY) } + fn read_only(&self) -> bool { + self.0.flags().contains(EF::AP_RO) + } + fn hw_dirty(&self) -> bool { + self.writable() && !self.read_only() + } + fn sw_dirty(&self) -> bool { + self.0.flags().contains(EF::DIRTY) + } fn as_flags(&mut self) -> &mut EF { unsafe { &mut *(self as *mut _ as *mut EF) } } @@ -168,7 +210,11 @@ impl InactivePageTable for InactivePageTable0 { active_table().with_temporary_map(target, |_, table: &mut Aarch64PageTable| { table.zero(); // set up recursive mapping for the table - table[RECURSIVE_INDEX].set_frame(frame.clone(), EF::default(), MairNormal::attr_value()); + table[RECURSIVE_INDEX].set_frame( + frame.clone(), + EF::default(), + MairNormal::attr_value(), + ); }); InactivePageTable0 { p4_frame: frame } } @@ -179,7 +225,11 @@ impl InactivePageTable for InactivePageTable0 { assert!(!e0.is_unused()); self.edit(|_| { - table[KERNEL_PML4].set_frame(Frame::containing_address(e0.addr()), EF::default(), MairNormal::attr_value()); + table[KERNEL_PML4].set_frame( + Frame::containing_address(e0.addr()), + EF::default(), + MairNormal::attr_value(), + ); }); } @@ -201,24 +251,31 @@ impl InactivePageTable for InactivePageTable0 { fn edit(&mut self, f: impl FnOnce(&mut Self::Active) -> T) -> T { let target = ttbr_el1_read(1).start_address().as_u64() as usize; - active_table().with_temporary_map(target, |active_table, p4_table: &mut Aarch64PageTable| { - let backup = p4_table[RECURSIVE_INDEX].clone(); - let old_frame = ttbr_el1_read(0); - - // overwrite recursive mapping - p4_table[RECURSIVE_INDEX].set_frame(self.p4_frame.clone(), EF::default(), MairNormal::attr_value()); - ttbr_el1_write(0, self.p4_frame.clone()); - tlb_invalidate_all(); - - // execute f in the new context - let ret = f(active_table); - - // restore recursive mapping to original p4 table - p4_table[RECURSIVE_INDEX] = backup; - ttbr_el1_write(0, old_frame); - tlb_invalidate_all(); - ret - }) + active_table().with_temporary_map( + target, + |active_table, p4_table: &mut Aarch64PageTable| { + let backup = p4_table[RECURSIVE_INDEX].clone(); + let old_frame = ttbr_el1_read(0); + + // overwrite recursive mapping + p4_table[RECURSIVE_INDEX].set_frame( + self.p4_frame.clone(), + EF::default(), + MairNormal::attr_value(), + ); + ttbr_el1_write(0, self.p4_frame.clone()); + tlb_invalidate_all(); + + // execute f in the new context + let ret = f(active_table); + + // restore recursive mapping to original p4 table + p4_table[RECURSIVE_INDEX] = backup; + ttbr_el1_write(0, old_frame); + tlb_invalidate_all(); + ret + }, + ) } } diff --git a/kernel/src/arch/aarch64/rand.rs b/kernel/src/arch/aarch64/rand.rs index 7395793..f2f1e2c 100644 --- a/kernel/src/arch/aarch64/rand.rs +++ b/kernel/src/arch/aarch64/rand.rs @@ -1,3 +1,3 @@ pub fn rand() -> u64 { return 0; -} \ No newline at end of file +} diff --git a/kernel/src/arch/aarch64/timer.rs b/kernel/src/arch/aarch64/timer.rs index ac8a51d..510557b 100644 --- a/kernel/src/arch/aarch64/timer.rs +++ b/kernel/src/arch/aarch64/timer.rs @@ -1,3 +1,3 @@ pub fn read_epoch() -> u64 { 0 -} \ No newline at end of file +} diff --git a/kernel/src/arch/riscv32/board/u540/mod.rs b/kernel/src/arch/riscv32/board/u540/mod.rs index cc53874..2e9f7a6 100644 --- a/kernel/src/arch/riscv32/board/u540/mod.rs +++ b/kernel/src/arch/riscv32/board/u540/mod.rs @@ -10,9 +10,10 @@ pub unsafe fn init_external_interrupt() { /// Claim and complete external interrupt by reading and writing to /// PLIC Interrupt Claim/Complete Register. pub unsafe fn handle_external_interrupt() { - const HART1_S_MODE_INTERRUPT_CLAIM_COMPLETE: *mut u32 = (KERNEL_OFFSET + 0x0C20_2004) as *mut u32; + const HART1_S_MODE_INTERRUPT_CLAIM_COMPLETE: *mut u32 = + (KERNEL_OFFSET + 0x0C20_2004) as *mut u32; // claim let source = HART1_S_MODE_INTERRUPT_CLAIM_COMPLETE.read(); // complete HART1_S_MODE_INTERRUPT_CLAIM_COMPLETE.write(source); -} \ No newline at end of file +} diff --git a/kernel/src/arch/riscv32/compiler_rt.rs b/kernel/src/arch/riscv32/compiler_rt.rs index b49a3ce..04ed3c3 100644 --- a/kernel/src/arch/riscv32/compiler_rt.rs +++ b/kernel/src/arch/riscv32/compiler_rt.rs @@ -3,6 +3,6 @@ //! [atomic](http://llvm.org/docs/Atomics.html#libcalls-atomic) #[no_mangle] -pub extern fn abort() { +pub extern "C" fn abort() { panic!("abort"); } diff --git a/kernel/src/arch/riscv32/consts.rs b/kernel/src/arch/riscv32/consts.rs index 3aecac1..a3004b0 100644 --- a/kernel/src/arch/riscv32/consts.rs +++ b/kernel/src/arch/riscv32/consts.rs @@ -39,4 +39,4 @@ pub const USER_STACK_OFFSET: usize = 0x80000000 - USER_STACK_SIZE; pub const USER_STACK_SIZE: usize = 0x10000; pub const USER32_STACK_OFFSET: usize = 0xC0000000 - USER_STACK_SIZE; -pub const MAX_DTB_SIZE: usize = 0x2000; \ No newline at end of file +pub const MAX_DTB_SIZE: usize = 0x2000; diff --git a/kernel/src/arch/riscv32/context.rs b/kernel/src/arch/riscv32/context.rs index a8b6e5f..e05dafe 100644 --- a/kernel/src/arch/riscv32/context.rs +++ b/kernel/src/arch/riscv32/context.rs @@ -1,8 +1,4 @@ -use riscv::register::{ - sstatus, - sstatus::Sstatus, - scause::Scause, -}; +use riscv::register::{scause::Scause, sstatus, sstatus::Sstatus}; /// Saved registers on a trap. #[derive(Clone)] @@ -27,7 +23,7 @@ impl TrapFrame { /// /// The new thread starts at function `entry` with an usize argument `arg`. /// The stack pointer will be set to `sp`. - fn new_kernel_thread(entry: extern fn(usize) -> !, arg: usize, sp: usize) -> Self { + fn new_kernel_thread(entry: extern "C" fn(usize) -> !, arg: usize, sp: usize) -> Self { use core::mem::zeroed; let mut tf: Self = unsafe { zeroed() }; tf.x[10] = arg; // a0 @@ -57,17 +53,17 @@ impl TrapFrame { } } -use core::fmt::{Debug, Formatter, Error}; +use core::fmt::{Debug, Error, Formatter}; impl Debug for TrapFrame { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { struct Regs<'a>(&'a [usize; 32]); impl<'a> Debug for Regs<'a> { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { const REG_NAME: [&str; 32] = [ - "zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", - "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", - "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", - "t3", "t4", "t5", "t6"]; + "zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", + "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", + "s10", "s11", "t3", "t4", "t5", "t6", + ]; f.debug_map().entries(REG_NAME.iter().zip(self.0)).finish() } } @@ -98,7 +94,7 @@ impl InitStack { } } -extern { +extern "C" { fn trap_return(); } @@ -116,7 +112,11 @@ struct ContextData { impl ContextData { fn new(satp: usize) -> Self { - ContextData { ra: trap_return as usize, satp, ..ContextData::default() } + ContextData { + ra: trap_return as usize, + satp, + ..ContextData::default() + } } } @@ -137,25 +137,29 @@ impl Context { /// Pop all callee-saved registers, then return to the target. #[naked] #[inline(never)] - pub unsafe extern fn switch(&mut self, _target: &mut Self) { + pub unsafe extern "C" fn switch(&mut self, _target: &mut Self) { #[cfg(target_arch = "riscv32")] - asm!(r" + asm!( + r" .equ XLENB, 4 .macro Load reg, mem lw \reg, \mem .endm .macro Store reg, mem sw \reg, \mem - .endm"); + .endm" + ); #[cfg(target_arch = "riscv64")] - asm!(r" + asm!( + r" .equ XLENB, 8 .macro Load reg, mem ld \reg, \mem .endm .macro Store reg, mem sd \reg, \mem - .endm"); + .endm" + ); asm!(" // save from's registers addi sp, sp, (-XLENB*14) @@ -210,11 +214,17 @@ impl Context { /// The new thread starts at function `entry` with an usize argument `arg`. /// The stack pointer will be set to `kstack_top`. /// The SATP register will be set to `satp`. - pub unsafe fn new_kernel_thread(entry: extern fn(usize) -> !, arg: usize, kstack_top: usize, satp: usize) -> Self { + pub unsafe fn new_kernel_thread( + entry: extern "C" fn(usize) -> !, + arg: usize, + kstack_top: usize, + satp: usize, + ) -> Self { InitStack { context: ContextData::new(satp), tf: TrapFrame::new_kernel_thread(entry, arg, kstack_top), - }.push_at(kstack_top) + } + .push_at(kstack_top) } /// Constructs Context for a new user thread. @@ -222,11 +232,18 @@ impl Context { /// The new thread starts at `entry_addr`. /// The stack pointer of user and kernel mode will be set to `ustack_top`, `kstack_top`. /// The SATP register will be set to `satp`. - pub unsafe fn new_user_thread(entry_addr: usize, ustack_top: usize, kstack_top: usize, _is32: bool, satp: usize) -> Self { + pub unsafe fn new_user_thread( + entry_addr: usize, + ustack_top: usize, + kstack_top: usize, + _is32: bool, + satp: usize, + ) -> Self { InitStack { context: ContextData::new(satp), tf: TrapFrame::new_user_thread(entry_addr, ustack_top), - }.push_at(kstack_top) + } + .push_at(kstack_top) } /// Fork a user process and get the new Context. @@ -243,7 +260,8 @@ impl Context { tf.x[10] = 0; // a0 tf }, - }.push_at(kstack_top) + } + .push_at(kstack_top) } /// Fork a user thread and get the new Context. @@ -253,17 +271,24 @@ impl Context { /// The new user stack will be set to `ustack_top`. /// The new thread pointer will be set to `tls`. /// All the other registers are same as the original. - pub unsafe fn new_clone(tf: &TrapFrame, ustack_top: usize, kstack_top: usize, satp: usize, tls: usize) -> Self { + pub unsafe fn new_clone( + tf: &TrapFrame, + ustack_top: usize, + kstack_top: usize, + satp: usize, + tls: usize, + ) -> Self { InitStack { context: ContextData::new(satp), tf: { let mut tf = tf.clone(); - tf.x[2] = ustack_top; // sp + tf.x[2] = ustack_top; // sp tf.x[4] = tls; // tp - tf.x[10] = 0; // a0 + tf.x[10] = 0; // a0 tf }, - }.push_at(kstack_top) + } + .push_at(kstack_top) } /// Used for getting the init TrapFrame of a new user context in `sys_exec`. diff --git a/kernel/src/arch/riscv32/cpu.rs b/kernel/src/arch/riscv32/cpu.rs index dea1df9..b0a4836 100644 --- a/kernel/src/arch/riscv32/cpu.rs +++ b/kernel/src/arch/riscv32/cpu.rs @@ -9,7 +9,9 @@ pub unsafe fn set_cpu_id(cpu_id: usize) { pub fn id() -> usize { let cpu_id; - unsafe { asm!("mv $0, gp" : "=r"(cpu_id)); } + unsafe { + asm!("mv $0, gp" : "=r"(cpu_id)); + } cpu_id } diff --git a/kernel/src/arch/riscv32/interrupt.rs b/kernel/src/arch/riscv32/interrupt.rs index 08e33d0..b498e65 100644 --- a/kernel/src/arch/riscv32/interrupt.rs +++ b/kernel/src/arch/riscv32/interrupt.rs @@ -1,14 +1,14 @@ -use riscv::register::*; -use crate::drivers::DRIVERS; pub use self::context::*; +use crate::drivers::DRIVERS; use log::*; +use riscv::register::*; #[path = "context.rs"] mod context; /// Initialize interrupt pub fn init() { - extern { + extern "C" { fn trap_entry(); } unsafe { @@ -53,9 +53,13 @@ pub unsafe fn restore(flags: usize) { /// /// This function is called from `trap.asm`. #[no_mangle] -pub extern fn rust_trap(tf: &mut TrapFrame) { - use self::scause::{Trap, Interrupt as I, Exception as E}; - trace!("Interrupt @ CPU{}: {:?} ", super::cpu::id(), tf.scause.cause()); +pub extern "C" fn rust_trap(tf: &mut TrapFrame) { + use self::scause::{Exception as E, Interrupt as I, Trap}; + trace!( + "Interrupt @ CPU{}: {:?} ", + super::cpu::id(), + tf.scause.cause() + ); match tf.scause.cause() { Trap::Interrupt(I::SupervisorExternal) => external(), Trap::Interrupt(I::SupervisorSoft) => ipi(), @@ -71,13 +75,15 @@ pub extern fn rust_trap(tf: &mut TrapFrame) { fn external() { #[cfg(feature = "board_u540")] - unsafe { super::board::handle_external_interrupt(); } + unsafe { + super::board::handle_external_interrupt(); + } // true means handled, false otherwise let handlers = [try_process_serial, try_process_drivers]; for handler in handlers.iter() { if handler() == true { - break + break; } } } @@ -88,17 +94,17 @@ fn try_process_serial() -> bool { crate::trap::serial(ch); true } - None => false + None => false, } } fn try_process_drivers() -> bool { for driver in DRIVERS.read().iter() { if driver.try_handle_interrupt(None) == true { - return true + return true; } } - return false + return false; } fn ipi() { @@ -112,8 +118,12 @@ fn timer() { } fn syscall(tf: &mut TrapFrame) { - tf.sepc += 4; // Must before syscall, because of fork. - let ret = crate::syscall::syscall(tf.x[17], [tf.x[10], tf.x[11], tf.x[12], tf.x[13], tf.x[14], tf.x[15]], tf); + tf.sepc += 4; // Must before syscall, because of fork. + let ret = crate::syscall::syscall( + tf.x[17], + [tf.x[10], tf.x[11], tf.x[12], tf.x[13], tf.x[14], tf.x[15]], + tf, + ); tf.x[10] = ret as usize; } diff --git a/kernel/src/arch/riscv32/io.rs b/kernel/src/arch/riscv32/io.rs index 5f405ee..161dfd1 100644 --- a/kernel/src/arch/riscv32/io.rs +++ b/kernel/src/arch/riscv32/io.rs @@ -1,5 +1,5 @@ -use core::fmt::{Write, Result, Arguments}; use super::sbi; +use core::fmt::{Arguments, Result, Write}; struct SerialPort; @@ -31,7 +31,7 @@ pub fn getchar() -> char { let c = sbi::console_getchar() as u8; match c { - 255 => '\0', // null + 255 => '\0', // null c => c as char, } } diff --git a/kernel/src/arch/riscv32/memory.rs b/kernel/src/arch/riscv32/memory.rs index 79ba0d3..b10bb2d 100644 --- a/kernel/src/arch/riscv32/memory.rs +++ b/kernel/src/arch/riscv32/memory.rs @@ -1,15 +1,17 @@ +use crate::consts::{KERNEL_OFFSET, MEMORY_END, MEMORY_OFFSET}; +use crate::memory::{init_heap, Linear, MemoryAttr, MemorySet, FRAME_ALLOCATOR}; use core::mem; -use riscv::{addr::*, register::sstatus}; -use rcore_memory::PAGE_SIZE; use log::*; -use crate::memory::{FRAME_ALLOCATOR, init_heap, MemoryAttr, MemorySet, Linear}; -use crate::consts::{MEMORY_OFFSET, MEMORY_END, KERNEL_OFFSET}; +use rcore_memory::PAGE_SIZE; use riscv::register::satp; +use riscv::{addr::*, register::sstatus}; /// Initialize the memory management module pub fn init(dtb: usize) { - unsafe { sstatus::set_sum(); } // Allow user memory access - // initialize heap and Frame allocator + unsafe { + sstatus::set_sum(); + } // Allow user memory access + // initialize heap and Frame allocator init_frame_allocator(); init_heap(); // remap the kernel use 4K page @@ -18,7 +20,7 @@ pub fn init(dtb: usize) { pub fn init_other() { unsafe { - sstatus::set_sum(); // Allow user memory access + sstatus::set_sum(); // Allow user memory access asm!("csrw satp, $0; sfence.vma" :: "r"(SATP) :: "volatile"); } } @@ -28,7 +30,10 @@ fn init_frame_allocator() { use core::ops::Range; let mut ba = FRAME_ALLOCATOR.lock(); - let range = to_range((end as usize) - KERNEL_OFFSET + MEMORY_OFFSET + PAGE_SIZE, MEMORY_END); + let range = to_range( + (end as usize) - KERNEL_OFFSET + MEMORY_OFFSET + PAGE_SIZE, + MEMORY_END, + ); ba.insert(range); info!("frame allocator: init end"); @@ -46,18 +51,70 @@ fn init_frame_allocator() { fn remap_the_kernel(dtb: usize) { let offset = -(KERNEL_OFFSET as isize - MEMORY_OFFSET as isize); let mut ms = MemorySet::new_bare(); - ms.push(stext as usize, etext as usize, MemoryAttr::default().execute().readonly(), Linear::new(offset), "text"); - ms.push(sdata as usize, edata as usize, MemoryAttr::default(), Linear::new(offset), "data"); - ms.push(srodata as usize, erodata as usize, MemoryAttr::default().readonly(), Linear::new(offset), "rodata"); - ms.push(bootstack as usize, bootstacktop as usize, MemoryAttr::default(), Linear::new(offset), "stack"); - ms.push(sbss as usize, ebss as usize, MemoryAttr::default(), Linear::new(offset), "bss"); - ms.push(dtb, dtb + super::consts::MAX_DTB_SIZE, MemoryAttr::default().readonly(), Linear::new(offset), "dts"); + ms.push( + stext as usize, + etext as usize, + MemoryAttr::default().execute().readonly(), + Linear::new(offset), + "text", + ); + ms.push( + sdata as usize, + edata as usize, + MemoryAttr::default(), + Linear::new(offset), + "data", + ); + ms.push( + srodata as usize, + erodata as usize, + MemoryAttr::default().readonly(), + Linear::new(offset), + "rodata", + ); + ms.push( + bootstack as usize, + bootstacktop as usize, + MemoryAttr::default(), + Linear::new(offset), + "stack", + ); + ms.push( + sbss as usize, + ebss as usize, + MemoryAttr::default(), + Linear::new(offset), + "bss", + ); + ms.push( + dtb, + dtb + super::consts::MAX_DTB_SIZE, + MemoryAttr::default().readonly(), + Linear::new(offset), + "dts", + ); // map PLIC for HiFiveU let offset = -(KERNEL_OFFSET as isize); - ms.push(KERNEL_OFFSET + 0x0C00_2000, KERNEL_OFFSET + 0x0C00_2000 + PAGE_SIZE, MemoryAttr::default(), Linear::new(offset), "plic0"); - ms.push(KERNEL_OFFSET + 0x0C20_2000, KERNEL_OFFSET + 0x0C20_2000 + PAGE_SIZE, MemoryAttr::default(), Linear::new(offset), "plic1"); - unsafe { ms.activate(); } - unsafe { SATP = ms.token(); } + ms.push( + KERNEL_OFFSET + 0x0C00_2000, + KERNEL_OFFSET + 0x0C00_2000 + PAGE_SIZE, + MemoryAttr::default(), + Linear::new(offset), + "plic0", + ); + ms.push( + KERNEL_OFFSET + 0x0C20_2000, + KERNEL_OFFSET + 0x0C20_2000 + PAGE_SIZE, + MemoryAttr::default(), + Linear::new(offset), + "plic1", + ); + unsafe { + ms.activate(); + } + unsafe { + SATP = ms.token(); + } mem::forget(ms); info!("remap kernel end"); } @@ -77,7 +134,7 @@ pub unsafe fn clear_bss() { // Symbols provided by linker script #[allow(dead_code)] -extern { +extern "C" { fn stext(); fn etext(); fn sdata(); diff --git a/kernel/src/arch/riscv32/mod.rs b/kernel/src/arch/riscv32/mod.rs index bdd6d6f..650e881 100644 --- a/kernel/src/arch/riscv32/mod.rs +++ b/kernel/src/arch/riscv32/mod.rs @@ -1,34 +1,38 @@ -pub mod io; -pub mod interrupt; -pub mod timer; -pub mod paging; -pub mod memory; +#[cfg(feature = "board_u540")] +#[path = "board/u540/mod.rs"] +mod board; pub mod compiler_rt; pub mod consts; pub mod cpu; -pub mod syscall; +pub mod interrupt; +pub mod io; +pub mod memory; +pub mod paging; pub mod rand; -#[cfg(feature = "board_u540")] -#[path = "board/u540/mod.rs"] -mod board; mod sbi; +pub mod syscall; +pub mod timer; use log::*; #[no_mangle] -pub extern fn rust_main(hartid: usize, dtb: usize, hart_mask: usize) -> ! { +pub extern "C" fn rust_main(hartid: usize, dtb: usize, hart_mask: usize) -> ! { // An initial recursive page table has been set by BBL (shared by all cores) - unsafe { cpu::set_cpu_id(hartid); } + unsafe { + cpu::set_cpu_id(hartid); + } if hartid != BOOT_HART_ID { - while unsafe { !cpu::has_started(hartid) } { } + while unsafe { !cpu::has_started(hartid) } {} println!("Hello RISCV! in hart {}, dtb @ {:#x}", hartid, dtb); others_main(); //other_main -> ! } - unsafe { memory::clear_bss(); } + unsafe { + memory::clear_bss(); + } println!("Hello RISCV! in hart {}, dtb @ {:#x}", hartid, dtb); @@ -40,10 +44,14 @@ pub extern fn rust_main(hartid: usize, dtb: usize, hart_mask: usize) -> ! { #[cfg(not(feature = "board_u540"))] crate::drivers::init(dtb); #[cfg(feature = "board_u540")] - unsafe { board::init_external_interrupt(); } + unsafe { + board::init_external_interrupt(); + } crate::process::init(); - unsafe { cpu::start_others(hart_mask); } + unsafe { + cpu::start_others(hart_mask); + } crate::kmain(); } @@ -61,7 +69,8 @@ const BOOT_HART_ID: usize = 1; /// Constant & Macro for `trap.asm` #[cfg(target_arch = "riscv32")] -global_asm!(r" +global_asm!( + r" .equ XLENB, 4 .equ XLENb, 32 .macro LOAD a1, a2 @@ -70,9 +79,11 @@ global_asm!(r" .macro STORE a1, a2 sw \a1, \a2*XLENB(sp) .endm -"); +" +); #[cfg(target_arch = "riscv64")] -global_asm!(r" +global_asm!( + r" .equ XLENB, 8 .equ XLENb, 64 .macro LOAD a1, a2 @@ -81,8 +92,8 @@ global_asm!(r" .macro STORE a1, a2 sd \a1, \a2*XLENB(sp) .endm -"); - +" +); global_asm!(include_str!("boot/entry.asm")); global_asm!(include_str!("boot/trap.asm")); diff --git a/kernel/src/arch/riscv32/paging.rs b/kernel/src/arch/riscv32/paging.rs index a392865..12e61ec 100644 --- a/kernel/src/arch/riscv32/paging.rs +++ b/kernel/src/arch/riscv32/paging.rs @@ -1,17 +1,20 @@ use crate::consts::RECURSIVE_INDEX; // Depends on kernel +#[cfg(target_arch = "riscv32")] +use crate::consts::KERNEL_P2_INDEX; +#[cfg(target_arch = "riscv64")] +use crate::consts::KERNEL_P4_INDEX; use crate::memory::{active_table, alloc_frame, dealloc_frame}; +use log::*; +use rcore_memory::paging::*; use riscv::addr::*; use riscv::asm::{sfence_vma, sfence_vma_all}; -use riscv::paging::{Mapper, PageTable as RvPageTable, PageTableEntry, PageTableFlags as EF, RecursivePageTable, PageTableType}; use riscv::paging::{FrameAllocator, FrameDeallocator}; +use riscv::paging::{ + Mapper, PageTable as RvPageTable, PageTableEntry, PageTableFlags as EF, PageTableType, + RecursivePageTable, +}; use riscv::register::satp; -use rcore_memory::paging::*; -use log::*; -#[cfg(target_arch = "riscv32")] -use crate::consts::KERNEL_P2_INDEX; -#[cfg(target_arch = "riscv64")] -use crate::consts::KERNEL_P4_INDEX; pub struct ActivePageTable(RecursivePageTable<'static>, PageEntry); @@ -20,7 +23,6 @@ pub struct ActivePageTable(RecursivePageTable<'static>, PageEntry); pub struct PageEntry(&'static mut PageTableEntry, Page); impl PageTable for ActivePageTable { - fn map(&mut self, addr: usize, target: usize) -> &mut Entry { // use riscv::paging:Mapper::map_to, // map the 4K `page` to the 4K `frame` with `flags` @@ -29,7 +31,10 @@ impl PageTable for ActivePageTable { let frame = Frame::of_addr(PhysAddr::new(target)); // map the page to the frame using FrameAllocatorForRiscv // we may need frame allocator to alloc frame for new page table(first/second) - self.0.map_to(page, frame, flags, &mut FrameAllocatorForRiscv).unwrap().flush(); + self.0 + .map_to(page, frame, flags, &mut FrameAllocatorForRiscv) + .unwrap() + .flush(); self.get_entry(addr).expect("fail to get entry") } @@ -56,29 +61,26 @@ impl PageTableExt for ActivePageTable {} /// The virtual address of root page table #[cfg(target_arch = "riscv32")] const ROOT_PAGE_TABLE: *mut RvPageTable = - ((RECURSIVE_INDEX << 12 << 10) | - ((RECURSIVE_INDEX+1) << 12)) as *mut RvPageTable; + ((RECURSIVE_INDEX << 12 << 10) | ((RECURSIVE_INDEX + 1) << 12)) as *mut RvPageTable; #[cfg(all(target_arch = "riscv64", feature = "sv39"))] -const ROOT_PAGE_TABLE: *mut RvPageTable = - ((0xFFFF_0000_0000_0000) | - (0o777 << 12 << 9 << 9 << 9) | - (RECURSIVE_INDEX << 12 << 9 << 9) | - (RECURSIVE_INDEX << 12 << 9) | - ((RECURSIVE_INDEX+1) << 12)) as *mut RvPageTable; +const ROOT_PAGE_TABLE: *mut RvPageTable = ((0xFFFF_0000_0000_0000) + | (0o777 << 12 << 9 << 9 << 9) + | (RECURSIVE_INDEX << 12 << 9 << 9) + | (RECURSIVE_INDEX << 12 << 9) + | ((RECURSIVE_INDEX + 1) << 12)) as *mut RvPageTable; #[cfg(all(target_arch = "riscv64", not(feature = "sv39")))] -const ROOT_PAGE_TABLE: *mut RvPageTable = - ((0xFFFF_0000_0000_0000) | - (RECURSIVE_INDEX << 12 << 9 << 9 << 9) | - (RECURSIVE_INDEX << 12 << 9 << 9) | - (RECURSIVE_INDEX << 12 << 9) | - ((RECURSIVE_INDEX+1) << 12)) as *mut RvPageTable; +const ROOT_PAGE_TABLE: *mut RvPageTable = ((0xFFFF_0000_0000_0000) + | (RECURSIVE_INDEX << 12 << 9 << 9 << 9) + | (RECURSIVE_INDEX << 12 << 9 << 9) + | (RECURSIVE_INDEX << 12 << 9) + | ((RECURSIVE_INDEX + 1) << 12)) as *mut RvPageTable; impl ActivePageTable { #[cfg(target_arch = "riscv32")] pub unsafe fn new() -> Self { ActivePageTable( RecursivePageTable::new(&mut *ROOT_PAGE_TABLE).unwrap(), - ::core::mem::uninitialized() + ::core::mem::uninitialized(), ) } #[cfg(target_arch = "riscv64")] @@ -89,7 +91,7 @@ impl ActivePageTable { let type_ = PageTableType::Sv48; ActivePageTable( RecursivePageTable::new(&mut *ROOT_PAGE_TABLE, type_).unwrap(), - ::core::mem::uninitialized() + ::core::mem::uninitialized(), ) } } @@ -97,38 +99,78 @@ impl ActivePageTable { /// implementation for the Entry trait in /crate/memory/src/paging/mod.rs impl Entry for PageEntry { fn update(&mut self) { - unsafe { sfence_vma(0, self.1.start_address().as_usize()); } - } - fn accessed(&self) -> bool { self.0.flags().contains(EF::ACCESSED) } - fn dirty(&self) -> bool { self.0.flags().contains(EF::DIRTY) } - fn writable(&self) -> bool { self.0.flags().contains(EF::WRITABLE) } - fn present(&self) -> bool { self.0.flags().contains(EF::VALID | EF::READABLE) } - fn clear_accessed(&mut self) { self.0.flags_mut().remove(EF::ACCESSED); } - fn clear_dirty(&mut self) { self.0.flags_mut().remove(EF::DIRTY); } - fn set_writable(&mut self, value: bool) { self.0.flags_mut().set(EF::WRITABLE, value); } - fn set_present(&mut self, value: bool) { self.0.flags_mut().set(EF::VALID | EF::READABLE, value); } - fn target(&self) -> usize { self.0.addr().as_usize() } + unsafe { + sfence_vma(0, self.1.start_address().as_usize()); + } + } + fn accessed(&self) -> bool { + self.0.flags().contains(EF::ACCESSED) + } + fn dirty(&self) -> bool { + self.0.flags().contains(EF::DIRTY) + } + fn writable(&self) -> bool { + self.0.flags().contains(EF::WRITABLE) + } + fn present(&self) -> bool { + self.0.flags().contains(EF::VALID | EF::READABLE) + } + fn clear_accessed(&mut self) { + self.0.flags_mut().remove(EF::ACCESSED); + } + fn clear_dirty(&mut self) { + self.0.flags_mut().remove(EF::DIRTY); + } + fn set_writable(&mut self, value: bool) { + self.0.flags_mut().set(EF::WRITABLE, value); + } + fn set_present(&mut self, value: bool) { + self.0.flags_mut().set(EF::VALID | EF::READABLE, value); + } + fn target(&self) -> usize { + self.0.addr().as_usize() + } fn set_target(&mut self, target: usize) { let flags = self.0.flags(); let frame = Frame::of_addr(PhysAddr::new(target)); self.0.set(frame, flags); } - fn writable_shared(&self) -> bool { self.0.flags().contains(EF::RESERVED1) } - fn readonly_shared(&self) -> bool { self.0.flags().contains(EF::RESERVED2) } + fn writable_shared(&self) -> bool { + self.0.flags().contains(EF::RESERVED1) + } + fn readonly_shared(&self) -> bool { + self.0.flags().contains(EF::RESERVED2) + } fn set_shared(&mut self, writable: bool) { let flags = self.0.flags_mut(); flags.set(EF::RESERVED1, writable); flags.set(EF::RESERVED2, !writable); } - fn clear_shared(&mut self) { self.0.flags_mut().remove(EF::RESERVED1 | EF::RESERVED2); } - fn swapped(&self) -> bool { self.0.flags().contains(EF::RESERVED1) } - fn set_swapped(&mut self, value: bool) { self.0.flags_mut().set(EF::RESERVED1, value); } - fn user(&self) -> bool { self.0.flags().contains(EF::USER) } - fn set_user(&mut self, value: bool) { self.0.flags_mut().set(EF::USER, value); } - fn execute(&self) -> bool { self.0.flags().contains(EF::EXECUTABLE) } - fn set_execute(&mut self, value: bool) { self.0.flags_mut().set(EF::EXECUTABLE, value); } - fn mmio(&self) -> u8 { 0 } - fn set_mmio(&mut self, _value: u8) { } + fn clear_shared(&mut self) { + self.0.flags_mut().remove(EF::RESERVED1 | EF::RESERVED2); + } + fn swapped(&self) -> bool { + self.0.flags().contains(EF::RESERVED1) + } + fn set_swapped(&mut self, value: bool) { + self.0.flags_mut().set(EF::RESERVED1, value); + } + fn user(&self) -> bool { + self.0.flags().contains(EF::USER) + } + fn set_user(&mut self, value: bool) { + self.0.flags_mut().set(EF::USER, value); + } + fn execute(&self) -> bool { + self.0.flags().contains(EF::EXECUTABLE) + } + fn set_execute(&mut self, value: bool) { + self.0.flags_mut().set(EF::EXECUTABLE, value); + } + fn mmio(&self) -> u8 { + 0 + } + fn set_mmio(&mut self, _value: u8) {} } #[derive(Debug)] @@ -152,7 +194,7 @@ impl InactivePageTable for InactivePageTable0 { #[cfg(target_arch = "riscv32")] fn map_kernel(&mut self) { let table = unsafe { &mut *ROOT_PAGE_TABLE }; - extern { + extern "C" { fn start(); fn end(); } @@ -191,7 +233,7 @@ impl InactivePageTable for InactivePageTable0 { fn token(&self) -> usize { use bit_field::BitField; let mut satp = self.root_frame.number(); - satp.set_bits(44..60, 0); // AS is 0 + satp.set_bits(44..60, 0); // AS is 0 #[cfg(feature = "sv39")] satp.set_bits(60..64, satp::Mode::Sv39 as usize); #[cfg(not(feature = "sv39"))] @@ -208,7 +250,9 @@ impl InactivePageTable for InactivePageTable0 { } fn flush_tlb() { - unsafe { sfence_vma_all(); } + unsafe { + sfence_vma_all(); + } } fn edit(&mut self, f: impl FnOnce(&mut Self::Active) -> T) -> T { @@ -218,14 +262,18 @@ impl InactivePageTable for InactivePageTable0 { // overwrite recursive mapping root_table[RECURSIVE_INDEX].set(self.root_frame.clone(), EF::VALID); - unsafe { sfence_vma_all(); } + unsafe { + sfence_vma_all(); + } // execute f in the new context let ret = f(active_table); // restore recursive mapping to original p2 table root_table[RECURSIVE_INDEX] = backup; - unsafe { sfence_vma_all(); } + unsafe { + sfence_vma_all(); + } ret }) diff --git a/kernel/src/arch/riscv32/rand.rs b/kernel/src/arch/riscv32/rand.rs index 7395793..f2f1e2c 100644 --- a/kernel/src/arch/riscv32/rand.rs +++ b/kernel/src/arch/riscv32/rand.rs @@ -1,3 +1,3 @@ pub fn rand() -> u64 { return 0; -} \ No newline at end of file +} diff --git a/kernel/src/arch/riscv32/sbi.rs b/kernel/src/arch/riscv32/sbi.rs index 0357642..6a56ff1 100644 --- a/kernel/src/arch/riscv32/sbi.rs +++ b/kernel/src/arch/riscv32/sbi.rs @@ -28,7 +28,12 @@ pub fn shutdown() -> ! { pub fn set_timer(stime_value: u64) { #[cfg(target_pointer_width = "32")] - sbi_call(SBI_SET_TIMER, stime_value as usize, (stime_value >> 32) as usize, 0); + sbi_call( + SBI_SET_TIMER, + stime_value as usize, + (stime_value >> 32) as usize, + 0, + ); #[cfg(target_pointer_width = "64")] sbi_call(SBI_SET_TIMER, stime_value as usize, 0, 0); } @@ -50,7 +55,12 @@ pub fn remote_sfence_vma(hart_mask: usize, _start: usize, _size: usize) { } pub fn remote_sfence_vma_asid(hart_mask: usize, _start: usize, _size: usize, _asid: usize) { - sbi_call(SBI_REMOTE_SFENCE_VMA_ASID, &hart_mask as *const _ as usize, 0, 0); + sbi_call( + SBI_REMOTE_SFENCE_VMA_ASID, + &hart_mask as *const _ as usize, + 0, + 0, + ); } const SBI_SET_TIMER: usize = 0; diff --git a/kernel/src/arch/riscv32/timer.rs b/kernel/src/arch/riscv32/timer.rs index 8f10c73..a405b21 100644 --- a/kernel/src/arch/riscv32/timer.rs +++ b/kernel/src/arch/riscv32/timer.rs @@ -1,6 +1,6 @@ -use riscv::register::*; use super::sbi; use log::*; +use riscv::register::*; #[cfg(target_pointer_width = "64")] pub fn get_cycle() -> u64 { @@ -27,7 +27,9 @@ pub fn read_epoch() -> u64 { /// Enable timer interrupt pub fn init() { // Enable supervisor timer interrupt - unsafe { sie::set_stimer(); } + unsafe { + sie::set_stimer(); + } set_next(); info!("timer: init end"); } diff --git a/kernel/src/arch/x86_64/cpu.rs b/kernel/src/arch/x86_64/cpu.rs index 2a1eea9..d226c6b 100644 --- a/kernel/src/arch/x86_64/cpu.rs +++ b/kernel/src/arch/x86_64/cpu.rs @@ -14,7 +14,10 @@ pub unsafe fn exit_in_qemu(error_code: u8) -> ! { } pub fn id() -> usize { - CpuId::new().get_feature_info().unwrap().initial_local_apic_id() as usize + CpuId::new() + .get_feature_info() + .unwrap() + .initial_local_apic_id() as usize } pub fn send_ipi(cpu_id: usize) { @@ -31,7 +34,7 @@ pub fn init() { unsafe { asm!("mov %cr4, $0" : "=r" (value)); // OSFXSR | OSXMMEXCPT - value |= 1 << 9 | 1 << 10 ; + value |= 1 << 9 | 1 << 10; asm!("mov $0, %cr4" :: "r" (value) : "memory"); Cr0::update(|cr0| { cr0.remove(Cr0Flags::EMULATE_COPROCESSOR); diff --git a/kernel/src/arch/x86_64/driver/ide.rs b/kernel/src/arch/x86_64/driver/ide.rs index 097e1a4..fff1534 100644 --- a/kernel/src/arch/x86_64/driver/ide.rs +++ b/kernel/src/arch/x86_64/driver/ide.rs @@ -16,10 +16,26 @@ pub struct IDE { impl IDE { pub fn new(num: u8) -> Self { let ide = match num { - 0 => IDE { num: 0, base: 0x1f0, ctrl: 0x3f4 }, - 1 => IDE { num: 1, base: 0x1f0, ctrl: 0x3f4 }, - 2 => IDE { num: 2, base: 0x170, ctrl: 0x374 }, - 3 => IDE { num: 3, base: 0x170, ctrl: 0x374 }, + 0 => IDE { + num: 0, + base: 0x1f0, + ctrl: 0x3f4, + }, + 1 => IDE { + num: 1, + base: 0x1f0, + ctrl: 0x3f4, + }, + 2 => IDE { + num: 2, + base: 0x170, + ctrl: 0x374, + }, + 3 => IDE { + num: 3, + base: 0x170, + ctrl: 0x374, + }, _ => panic!("ide number should be 0,1,2,3"), }; ide.init(); @@ -103,14 +119,17 @@ impl IDE { port::outb(self.base + ISA_SECTOR, (sector & 0xFF) as u8); port::outb(self.base + ISA_CYL_LO, ((sector >> 8) & 0xFF) as u8); port::outb(self.base + ISA_CYL_HI, ((sector >> 16) & 0xFF) as u8); - port::outb(self.base + ISA_SDH, 0xE0 | ((self.num & 1) << 4) | (((sector >> 24) & 0xF) as u8)); + port::outb( + self.base + ISA_SDH, + 0xE0 | ((self.num & 1) << 4) | (((sector >> 24) & 0xF) as u8), + ); } } } const SECTOR_SIZE: usize = 128; -const MAX_DMA_SECTORS: usize = 0x1F_F000 / SECTOR_SIZE; // Limited by sector count (and PRDT entries) -// 512 PDRT entries, assume maximum fragmentation = 512 * 4K max = 2^21 = 2MB per transfer +const MAX_DMA_SECTORS: usize = 0x1F_F000 / SECTOR_SIZE; // Limited by sector count (and PRDT entries) + // 512 PDRT entries, assume maximum fragmentation = 512 * 4K max = 2^21 = 2MB per transfer const ISA_DATA: u16 = 0x00; const ISA_ERROR: u16 = 0x01; @@ -146,4 +165,4 @@ mod port { pub unsafe fn outb(port: u16, value: u8) { Port::new(port).write(value) } -} \ No newline at end of file +} diff --git a/kernel/src/arch/x86_64/driver/keyboard.rs b/kernel/src/arch/x86_64/driver/keyboard.rs index e67baf9..c67fbbc 100644 --- a/kernel/src/arch/x86_64/driver/keyboard.rs +++ b/kernel/src/arch/x86_64/driver/keyboard.rs @@ -1,20 +1,21 @@ +use lazy_static::lazy_static; +use pc_keyboard::{layouts, DecodedKey, HandleControl, Keyboard, ScancodeSet1}; use spin::Mutex; use x86_64::instructions::port::Port; -use pc_keyboard::{Keyboard, ScancodeSet1, DecodedKey, layouts, HandleControl}; -use lazy_static::lazy_static; pub fn init() { use crate::arch::interrupt::consts; use crate::arch::interrupt::enable_irq; - enable_irq(consts::Keyboard); + enable_irq(consts::Keyboard); } /// Receive character from keyboard /// Should be called on every interrupt pub fn receive() -> Option { lazy_static! { - static ref KEYBOARD: Mutex> = - Mutex::new(Keyboard::new(layouts::Us104Key, ScancodeSet1, HandleControl::Ignore)); + static ref KEYBOARD: Mutex> = Mutex::new( + Keyboard::new(layouts::Us104Key, ScancodeSet1, HandleControl::Ignore) + ); } let mut keyboard = KEYBOARD.lock(); @@ -29,4 +30,4 @@ pub fn receive() -> Option { } } None -} \ No newline at end of file +} diff --git a/kernel/src/arch/x86_64/driver/mod.rs b/kernel/src/arch/x86_64/driver/mod.rs index d370c5f..02158ed 100644 --- a/kernel/src/arch/x86_64/driver/mod.rs +++ b/kernel/src/arch/x86_64/driver/mod.rs @@ -1,12 +1,12 @@ use once::*; -pub mod vga; -pub mod serial; -pub mod pic; +pub mod ide; pub mod keyboard; +pub mod pic; pub mod pit; -pub mod ide; pub mod rtc_cmos; +pub mod serial; +pub mod vga; pub fn init() { assert_has_not_been_called!(); @@ -33,4 +33,4 @@ pub fn init() { enable_irq(consts::PIRQG); enable_irq(consts::PIRQH); */ -} \ No newline at end of file +} diff --git a/kernel/src/arch/x86_64/driver/pic.rs b/kernel/src/arch/x86_64/driver/pic.rs index 860ae79..7a67a3c 100644 --- a/kernel/src/arch/x86_64/driver/pic.rs +++ b/kernel/src/arch/x86_64/driver/pic.rs @@ -1,9 +1,9 @@ // Copy from Redox -use x86_64::instructions::port::Port; -use spin::Mutex; -use once::*; use log::*; +use once::*; +use spin::Mutex; +use x86_64::instructions::port::Port; static MASTER: Mutex = Mutex::new(Pic::new(0x20)); static SLAVE: Mutex = Mutex::new(Pic::new(0xA0)); @@ -19,7 +19,7 @@ pub fn disable() { pub unsafe fn init() { assert_has_not_been_called!("pic::init must be called only once"); - + let mut master = MASTER.lock(); let mut slave = SLAVE.lock(); @@ -53,7 +53,7 @@ pub unsafe fn init() { pub fn enable_irq(irq: u8) { match irq { _ if irq < 8 => MASTER.lock().mask_set(irq), - _ if irq < 16 => SLAVE.lock().mask_set(irq-8), + _ if irq < 16 => SLAVE.lock().mask_set(irq - 8), _ => panic!("irq not in 0..16"), } } @@ -80,7 +80,9 @@ impl Pic { } fn ack(&mut self) { - unsafe { self.cmd.write(0x20); } + unsafe { + self.cmd.write(0x20); + } } fn mask_set(&mut self, irq: u8) { diff --git a/kernel/src/arch/x86_64/driver/pit.rs b/kernel/src/arch/x86_64/driver/pit.rs index 282921a..655ce8a 100644 --- a/kernel/src/arch/x86_64/driver/pit.rs +++ b/kernel/src/arch/x86_64/driver/pit.rs @@ -1,6 +1,6 @@ -use x86_64::instructions::port::Port; use log::*; use once::*; +use x86_64::instructions::port::Port; pub fn init() { assert_has_not_been_called!("pit::init must be called only once"); @@ -39,7 +39,7 @@ impl Pit { } } -const TIMER_FREQ : u32 = 1193182; -const TIMER_SEL0 : u8 = 0x00; // select counter 0 -const TIMER_RATEGEN : u8 = 0x04; // mode 2, rate generator -const TIMER_16BIT : u8 = 0x30; // r/w counter 16 bits, LSB first \ No newline at end of file +const TIMER_FREQ: u32 = 1193182; +const TIMER_SEL0: u8 = 0x00; // select counter 0 +const TIMER_RATEGEN: u8 = 0x04; // mode 2, rate generator +const TIMER_16BIT: u8 = 0x30; // r/w counter 16 bits, LSB first diff --git a/kernel/src/arch/x86_64/driver/rtc_cmos.rs b/kernel/src/arch/x86_64/driver/rtc_cmos.rs index 58645d0..de01c7c 100644 --- a/kernel/src/arch/x86_64/driver/rtc_cmos.rs +++ b/kernel/src/arch/x86_64/driver/rtc_cmos.rs @@ -61,7 +61,8 @@ pub fn read_epoch() -> u64 { month = month - 2; } - let result = ((((year / 4 - year / 100 + year / 400 + 367 * month / 12 + day) + year * 365 + let result = ((((year / 4 - year / 100 + year / 400 + 367 * month / 12 + day) + + year * 365 - 719499) * 24 + hour) diff --git a/kernel/src/arch/x86_64/driver/vga.rs b/kernel/src/arch/x86_64/driver/vga.rs index 1227f89..7055661 100644 --- a/kernel/src/arch/x86_64/driver/vga.rs +++ b/kernel/src/arch/x86_64/driver/vga.rs @@ -51,10 +51,14 @@ pub struct ScreenChar { } impl ScreenChar { - pub fn new(ascii_char: u8, foreground_color: ConsoleColor, background_color: ConsoleColor) -> Self { + pub fn new( + ascii_char: u8, + foreground_color: ConsoleColor, + background_color: ConsoleColor, + ) -> Self { ScreenChar { ascii_char, - color_code: ColorCode::new(foreground_color, background_color) + color_code: ColorCode::new(foreground_color, background_color), } } } @@ -69,7 +73,7 @@ pub struct VgaBuffer { impl VgaBuffer { pub fn clear(&mut self) { let blank = ScreenChar::new(b' ', ConsoleColor::White, ConsoleColor::Black); - for row in 0 .. BUFFER_HEIGHT { + for row in 0..BUFFER_HEIGHT { for col in 0..BUFFER_WIDTH { self.chars[row][col].write(blank); } @@ -95,10 +99,10 @@ impl VgaBuffer { } lazy_static! { - pub static ref VGA_WRITER: Mutex = Mutex::new( - // VGA virtual address is specified at bootloader - VgaWriter::new(unsafe{ &mut *((KERNEL_OFFSET + 0xf0000000) as *mut VgaBuffer) }) - ); + pub static ref VGA_WRITER: Mutex = Mutex::new( + // VGA virtual address is specified at bootloader + VgaWriter::new(unsafe{ &mut *((KERNEL_OFFSET + 0xf0000000) as *mut VgaBuffer) }) + ); } pub struct VgaWriter { @@ -135,7 +139,8 @@ impl BaseConsole for VgaWriter { pos.row.bound(self.get_height()); pos.col.bound(self.get_width()); self.pos = pos; - self.buffer.set_cursor_at(pos.row.0 as usize, pos.col.0 as usize); + self.buffer + .set_cursor_at(pos.row.0 as usize, pos.col.0 as usize); Ok(()) } @@ -180,7 +185,8 @@ impl AsciiConsole for VgaWriter { ascii_char: ch, color_code: self.color_code, }; - self.buffer.write(pos.row.0 as usize, pos.col.0 as usize, screen_char); + self.buffer + .write(pos.row.0 as usize, pos.col.0 as usize, screen_char); Ok(()) } @@ -221,8 +227,7 @@ impl AsciiConsole for VgaWriter { 0x1b => Some(SpecialChar::Escape), 0x7f => Some(SpecialChar::Delete), 0x08 => Some(SpecialChar::Backspace), - _ if !(ch.is_ascii_graphic() || ch == b' ') - => Some(SpecialChar::Delete), // ignore non-graphic ascii + _ if !(ch.is_ascii_graphic() || ch == b' ') => Some(SpecialChar::Delete), // ignore non-graphic ascii _ => None, }, _ => None, @@ -246,7 +251,6 @@ impl VgaWriter { impl fmt::Write for VgaWriter { fn write_str(&mut self, s: &str) -> fmt::Result { - self.write_string(s.as_bytes()) - .map_err(|_| fmt::Error) + self.write_string(s.as_bytes()).map_err(|_| fmt::Error) } } diff --git a/kernel/src/arch/x86_64/gdt.rs b/kernel/src/arch/x86_64/gdt.rs index 8d50d0c..b6cfca5 100644 --- a/kernel/src/arch/x86_64/gdt.rs +++ b/kernel/src/arch/x86_64/gdt.rs @@ -1,9 +1,9 @@ use alloc::boxed::Box; -use x86_64::{PrivilegeLevel, VirtAddr}; +use x86_64::registers::model_specific::Msr; use x86_64::structures::gdt::*; use x86_64::structures::tss::TaskStateSegment; -use x86_64::registers::model_specific::Msr; +use x86_64::{PrivilegeLevel, VirtAddr}; use crate::consts::MAX_CPU_NUM; @@ -17,8 +17,7 @@ pub fn init() { static mut CPUS: [Option; MAX_CPU_NUM] = [ // TODO: More elegant ? - None, None, None, None, - None, None, None, None, + None, None, None, None, None, None, None, None, ]; pub struct Cpu { @@ -41,7 +40,7 @@ impl Cpu { } unsafe fn init(&'static mut self) { - use x86_64::instructions::segmentation::{set_cs, load_fs}; + use x86_64::instructions::segmentation::{load_fs, set_cs}; use x86_64::instructions::tables::load_tss; // Set the stack when DoubleFault occurs @@ -79,13 +78,13 @@ impl Cpu { pub const DOUBLE_FAULT_IST_INDEX: usize = 0; // Copied from xv6 x86_64 -const KCODE: Descriptor = Descriptor::UserSegment(0x0020980000000000); // EXECUTABLE | USER_SEGMENT | PRESENT | LONG_MODE -const UCODE: Descriptor = Descriptor::UserSegment(0x0020F80000000000); // EXECUTABLE | USER_SEGMENT | USER_MODE | PRESENT | LONG_MODE -const KDATA: Descriptor = Descriptor::UserSegment(0x0000920000000000); // DATA_WRITABLE | USER_SEGMENT | PRESENT -const UDATA: Descriptor = Descriptor::UserSegment(0x0000F20000000000); // DATA_WRITABLE | USER_SEGMENT | USER_MODE | PRESENT -// Copied from xv6 -const UCODE32: Descriptor = Descriptor::UserSegment(0x00cffa00_0000ffff); // EXECUTABLE | USER_SEGMENT | USER_MODE | PRESENT -const UDATA32: Descriptor = Descriptor::UserSegment(0x00cff200_0000ffff); // EXECUTABLE | USER_SEGMENT | USER_MODE | PRESENT +const KCODE: Descriptor = Descriptor::UserSegment(0x0020980000000000); // EXECUTABLE | USER_SEGMENT | PRESENT | LONG_MODE +const UCODE: Descriptor = Descriptor::UserSegment(0x0020F80000000000); // EXECUTABLE | USER_SEGMENT | USER_MODE | PRESENT | LONG_MODE +const KDATA: Descriptor = Descriptor::UserSegment(0x0000920000000000); // DATA_WRITABLE | USER_SEGMENT | PRESENT +const UDATA: Descriptor = Descriptor::UserSegment(0x0000F20000000000); // DATA_WRITABLE | USER_SEGMENT | USER_MODE | PRESENT + // Copied from xv6 +const UCODE32: Descriptor = Descriptor::UserSegment(0x00cffa00_0000ffff); // EXECUTABLE | USER_SEGMENT | USER_MODE | PRESENT +const UDATA32: Descriptor = Descriptor::UserSegment(0x00cff200_0000ffff); // EXECUTABLE | USER_SEGMENT | USER_MODE | PRESENT // NOTICE: for fast syscall: // STAR[47:32] = K_CS = K_SS - 8 @@ -95,4 +94,4 @@ pub const KDATA_SELECTOR: SegmentSelector = SegmentSelector::new(2, PrivilegeLev pub const UCODE32_SELECTOR: SegmentSelector = SegmentSelector::new(3, PrivilegeLevel::Ring3); pub const UDATA32_SELECTOR: SegmentSelector = SegmentSelector::new(4, PrivilegeLevel::Ring3); pub const UCODE_SELECTOR: SegmentSelector = SegmentSelector::new(5, PrivilegeLevel::Ring3); -pub const TSS_SELECTOR: SegmentSelector = SegmentSelector::new(6, PrivilegeLevel::Ring0); \ No newline at end of file +pub const TSS_SELECTOR: SegmentSelector = SegmentSelector::new(6, PrivilegeLevel::Ring0); diff --git a/kernel/src/arch/x86_64/idt.rs b/kernel/src/arch/x86_64/idt.rs index 2679dc7..3e08dc8 100644 --- a/kernel/src/arch/x86_64/idt.rs +++ b/kernel/src/arch/x86_64/idt.rs @@ -1,5 +1,5 @@ -use x86_64::structures::idt::*; use lazy_static::lazy_static; +use x86_64::structures::idt::*; pub fn init() { IDT.load(); @@ -8,7 +8,7 @@ pub fn init() { lazy_static! { static ref IDT: InterruptDescriptorTable = { use crate::arch::interrupt::consts::*; - use crate::arch::gdt::DOUBLE_FAULT_IST_INDEX; + use crate::arch::gdt::DOUBLE_FAULT_IST_INDEX; use x86_64::PrivilegeLevel; use core::mem::transmute; @@ -37,9 +37,9 @@ lazy_static! { }; } -extern { +extern "C" { /// 中断向量表 /// 符号定义在 [trap.asm](boot/trap.asm) //noinspection RsStaticConstNaming - static __vectors: [extern fn(); 256]; + static __vectors: [extern "C" fn(); 256]; } diff --git a/kernel/src/arch/x86_64/interrupt/consts.rs b/kernel/src/arch/x86_64/interrupt/consts.rs index d9b7f7e..ccf0956 100644 --- a/kernel/src/arch/x86_64/interrupt/consts.rs +++ b/kernel/src/arch/x86_64/interrupt/consts.rs @@ -36,7 +36,7 @@ pub const Error: u8 = 19; pub const Spurious: u8 = 31; // PCI Interrupts -// See https://gist.github.com/mcastelino/4acda7c2407f1c51e68f3f994d8ffc98 +// See https://gist.github.com/mcastelino/4acda7c2407f1c51e68f3f994d8ffc98 pub const PIRQA: u8 = 16; pub const PIRQB: u8 = 17; pub const PIRQC: u8 = 18; diff --git a/kernel/src/arch/x86_64/interrupt/fast_syscall.rs b/kernel/src/arch/x86_64/interrupt/fast_syscall.rs index 6536384..69170ac 100644 --- a/kernel/src/arch/x86_64/interrupt/fast_syscall.rs +++ b/kernel/src/arch/x86_64/interrupt/fast_syscall.rs @@ -1,9 +1,8 @@ -/// `syscall` instruction - -use x86_64::registers::model_specific::*; -use core::mem::transmute; use super::super::gdt; use super::TrapFrame; +use core::mem::transmute; +/// `syscall` instruction +use x86_64::registers::model_specific::*; pub fn init() { unsafe { @@ -26,7 +25,7 @@ pub fn init() { } } -extern { +extern "C" { fn syscall_entry(); } diff --git a/kernel/src/arch/x86_64/interrupt/handler.rs b/kernel/src/arch/x86_64/interrupt/handler.rs index 434f0c6..230ee18 100644 --- a/kernel/src/arch/x86_64/interrupt/handler.rs +++ b/kernel/src/arch/x86_64/interrupt/handler.rs @@ -66,17 +66,21 @@ use super::consts::*; use super::TrapFrame; -use log::*; -use bitflags::*; use crate::drivers::DRIVERS; +use bitflags::*; +use log::*; global_asm!(include_str!("trap.asm")); global_asm!(include_str!("vector.asm")); #[allow(non_upper_case_globals)] #[no_mangle] -pub extern fn rust_trap(tf: &mut TrapFrame) { - trace!("Interrupt: {:#x} @ CPU{}", tf.trap_num, super::super::cpu::id()); +pub extern "C" fn rust_trap(tf: &mut TrapFrame) { + trace!( + "Interrupt: {:#x} @ CPU{}", + tf.trap_num, + super::super::cpu::id() + ); // Dispatch match tf.trap_num as u8 { Breakpoint => breakpoint(), @@ -99,7 +103,7 @@ pub extern fn rust_trap(tf: &mut TrapFrame) { } } warn!("unhandled external IRQ number: {}", irq); - }, + } } } Syscall32 => syscall32(tf), @@ -120,7 +124,9 @@ fn double_fault(tf: &TrapFrame) { fn page_fault(tf: &mut TrapFrame) { let addr: usize; - unsafe { asm!("mov %cr2, $0" : "=r" (addr)); } + unsafe { + asm!("mov %cr2, $0" : "=r" (addr)); + } bitflags! { struct PageError: u8 { @@ -197,7 +203,7 @@ fn invalid_opcode(tf: &mut TrapFrame) { let opcode = unsafe { (tf.rip as *mut u16).read() }; const SYSCALL_OPCODE: u16 = 0x05_0f; if opcode == SYSCALL_OPCODE { - tf.rip += 2; // must before syscall + tf.rip += 2; // must before syscall syscall(tf); } else { crate::trap::error(tf); @@ -209,7 +215,7 @@ fn error(tf: &TrapFrame) { } #[no_mangle] -pub unsafe extern fn set_return_rsp(tf: *const TrapFrame) { +pub unsafe extern "C" fn set_return_rsp(tf: *const TrapFrame) { use crate::arch::gdt::Cpu; Cpu::current().set_ring0_rsp(tf.add(1) as usize); } diff --git a/kernel/src/arch/x86_64/interrupt/mod.rs b/kernel/src/arch/x86_64/interrupt/mod.rs index e87657a..01f65b4 100644 --- a/kernel/src/arch/x86_64/interrupt/mod.rs +++ b/kernel/src/arch/x86_64/interrupt/mod.rs @@ -1,12 +1,12 @@ pub mod consts; +pub mod fast_syscall; mod handler; mod trapframe; -pub mod fast_syscall; -pub use self::trapframe::*; pub use self::handler::*; -use apic::*; +pub use self::trapframe::*; use crate::consts::KERNEL_OFFSET; +use apic::*; #[inline(always)] pub unsafe fn enable() { @@ -47,4 +47,4 @@ pub fn enable_irq(irq: u8) { pub fn ack(_irq: u8) { let mut lapic = unsafe { XApic::new(KERNEL_OFFSET + LAPIC_ADDR) }; lapic.eoi(); -} \ No newline at end of file +} diff --git a/kernel/src/arch/x86_64/interrupt/trapframe.rs b/kernel/src/arch/x86_64/interrupt/trapframe.rs index 1863286..03f4c32 100644 --- a/kernel/src/arch/x86_64/interrupt/trapframe.rs +++ b/kernel/src/arch/x86_64/interrupt/trapframe.rs @@ -1,9 +1,9 @@ -use core::fmt; use core::default::Default; +use core::fmt; #[derive(Clone)] #[repr(C)] -pub struct FpState([u8; 16+512]); +pub struct FpState([u8; 16 + 512]); impl fmt::Debug for FpState { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -13,11 +13,10 @@ impl fmt::Debug for FpState { impl Default for FpState { fn default() -> Self { - FpState([0u8; 16+512]) + FpState([0u8; 16 + 512]) } } - #[derive(Debug, Clone, Default)] #[repr(C)] pub struct TrapFrame { @@ -62,7 +61,7 @@ pub struct TrapFrame { /// 用于在内核栈中构造新线程的中断帧 impl TrapFrame { - fn new_kernel_thread(entry: extern fn(usize) -> !, arg: usize, rsp: usize) -> Self { + fn new_kernel_thread(entry: extern "C" fn(usize) -> !, arg: usize, rsp: usize) -> Self { use crate::arch::gdt; let mut tf = TrapFrame::default(); tf.rdi = arg; @@ -77,7 +76,11 @@ impl TrapFrame { fn new_user_thread(entry_addr: usize, rsp: usize, is32: bool) -> Self { use crate::arch::gdt; let mut tf = TrapFrame::default(); - tf.cs = if is32 { gdt::UCODE32_SELECTOR.0 } else { gdt::UCODE_SELECTOR.0 } as usize; + tf.cs = if is32 { + gdt::UCODE32_SELECTOR.0 + } else { + gdt::UCODE_SELECTOR.0 + } as usize; tf.rip = entry_addr; tf.ss = gdt::UDATA32_SELECTOR.0 as usize; tf.rsp = rsp; @@ -105,7 +108,11 @@ struct ContextData { impl ContextData { fn new(cr3: usize) -> Self { - ContextData { rip: trap_ret as usize, cr3, ..ContextData::default() } + ContextData { + rip: trap_ret as usize, + cr3, + ..ContextData::default() + } } } @@ -125,7 +132,7 @@ impl InitStack { } } -extern { +extern "C" { fn trap_ret(); } @@ -142,7 +149,7 @@ impl Context { /// Pop all callee-saved registers, then return to the target. #[naked] #[inline(never)] - pub unsafe extern fn switch(&mut self, _target: &mut Self) { + pub unsafe extern "C" fn switch(&mut self, _target: &mut Self) { asm!( " // push rip (by caller) @@ -180,17 +187,30 @@ impl Context { Context(0) } - pub unsafe fn new_kernel_thread(entry: extern fn(usize) -> !, arg: usize, kstack_top: usize, cr3: usize) -> Self { + pub unsafe fn new_kernel_thread( + entry: extern "C" fn(usize) -> !, + arg: usize, + kstack_top: usize, + cr3: usize, + ) -> Self { InitStack { context: ContextData::new(cr3), tf: TrapFrame::new_kernel_thread(entry, arg, kstack_top), - }.push_at(kstack_top) + } + .push_at(kstack_top) } - pub unsafe fn new_user_thread(entry_addr: usize, ustack_top: usize, kstack_top: usize, is32: bool, cr3: usize) -> Self { + pub unsafe fn new_user_thread( + entry_addr: usize, + ustack_top: usize, + kstack_top: usize, + is32: bool, + cr3: usize, + ) -> Self { InitStack { context: ContextData::new(cr3), tf: TrapFrame::new_user_thread(entry_addr, ustack_top, is32), - }.push_at(kstack_top) + } + .push_at(kstack_top) } pub unsafe fn new_fork(tf: &TrapFrame, kstack_top: usize, cr3: usize) -> Self { InitStack { @@ -200,9 +220,16 @@ impl Context { tf.rax = 0; tf }, - }.push_at(kstack_top) + } + .push_at(kstack_top) } - pub unsafe fn new_clone(tf: &TrapFrame, ustack_top: usize, kstack_top: usize, cr3: usize, tls: usize) -> Self { + pub unsafe fn new_clone( + tf: &TrapFrame, + ustack_top: usize, + kstack_top: usize, + cr3: usize, + tls: usize, + ) -> Self { InitStack { context: ContextData::new(cr3), tf: { @@ -212,7 +239,8 @@ impl Context { tf.rax = 0; tf }, - }.push_at(kstack_top) + } + .push_at(kstack_top) } /// Called at a new user context /// To get the init TrapFrame in sys_exec diff --git a/kernel/src/arch/x86_64/io.rs b/kernel/src/arch/x86_64/io.rs index 9927d5a..c78b014 100644 --- a/kernel/src/arch/x86_64/io.rs +++ b/kernel/src/arch/x86_64/io.rs @@ -3,19 +3,25 @@ use super::driver::vga::VGA_WRITER; use core::fmt::{Arguments, Write}; pub fn getchar() -> char { - unsafe { COM1.force_unlock(); } + unsafe { + COM1.force_unlock(); + } COM1.lock().receive() as char } pub fn putfmt(fmt: Arguments) { #[cfg(feature = "nographic")] { - unsafe { COM1.force_unlock(); } + unsafe { + COM1.force_unlock(); + } COM1.lock().write_fmt(fmt).unwrap(); } #[cfg(not(feature = "nographic"))] { - unsafe { VGA_WRITER.force_unlock(); } + unsafe { + VGA_WRITER.force_unlock(); + } VGA_WRITER.lock().write_fmt(fmt).unwrap(); } -} \ No newline at end of file +} diff --git a/kernel/src/arch/x86_64/memory.rs b/kernel/src/arch/x86_64/memory.rs index 5184d7a..822624f 100644 --- a/kernel/src/arch/x86_64/memory.rs +++ b/kernel/src/arch/x86_64/memory.rs @@ -1,11 +1,11 @@ -use bit_allocator::BitAlloc; use crate::consts::KERNEL_OFFSET; +use bit_allocator::BitAlloc; // Depends on kernel -use crate::memory::{FRAME_ALLOCATOR, init_heap, active_table}; use super::{BootInfo, MemoryRegionType}; -use rcore_memory::paging::*; -use once::*; +use crate::memory::{active_table, init_heap, FRAME_ALLOCATOR}; use log::*; +use once::*; +use rcore_memory::paging::*; pub fn init(boot_info: &BootInfo) { assert_has_not_been_called!("memory::init must be called only once"); @@ -20,7 +20,9 @@ fn init_frame_allocator(boot_info: &BootInfo) { let mut ba = FRAME_ALLOCATOR.lock(); for region in boot_info.memory_map.iter() { if region.region_type == MemoryRegionType::Usable { - ba.insert(region.range.start_frame_number as usize..region.range.end_frame_number as usize); + ba.insert( + region.range.start_frame_number as usize..region.range.end_frame_number as usize, + ); } } } @@ -28,7 +30,11 @@ fn init_frame_allocator(boot_info: &BootInfo) { fn init_device_vm_map() { let mut page_table = active_table(); // IOAPIC - page_table.map(KERNEL_OFFSET + 0xfec00000, 0xfec00000).update(); + page_table + .map(KERNEL_OFFSET + 0xfec00000, 0xfec00000) + .update(); // LocalAPIC - page_table.map(KERNEL_OFFSET + 0xfee00000, 0xfee00000).update(); + page_table + .map(KERNEL_OFFSET + 0xfee00000, 0xfee00000) + .update(); } diff --git a/kernel/src/arch/x86_64/mod.rs b/kernel/src/arch/x86_64/mod.rs index 2aef93c..4b5f56c 100644 --- a/kernel/src/arch/x86_64/mod.rs +++ b/kernel/src/arch/x86_64/mod.rs @@ -2,18 +2,18 @@ use bootloader::bootinfo::{BootInfo, MemoryRegionType}; use core::sync::atomic::*; use log::*; -pub mod driver; +pub mod consts; pub mod cpu; -pub mod interrupt; -pub mod paging; +pub mod driver; pub mod gdt; pub mod idt; -pub mod memory; +pub mod interrupt; pub mod io; -pub mod consts; -pub mod timer; -pub mod syscall; +pub mod memory; +pub mod paging; pub mod rand; +pub mod syscall; +pub mod timer; static AP_CAN_INIT: AtomicBool = ATOMIC_BOOL_INIT; @@ -62,4 +62,4 @@ fn other_start() -> ! { cpu::init(); interrupt::fast_syscall::init(); crate::kmain(); -} \ No newline at end of file +} diff --git a/kernel/src/arch/x86_64/paging.rs b/kernel/src/arch/x86_64/paging.rs index 261dc23..47a4058 100644 --- a/kernel/src/arch/x86_64/paging.rs +++ b/kernel/src/arch/x86_64/paging.rs @@ -1,18 +1,18 @@ // Depends on kernel +use crate::consts::KERNEL_OFFSET; use crate::memory::{active_table, alloc_frame, dealloc_frame}; +use log::*; use rcore_memory::paging::*; use x86_64::instructions::tlb; -use x86_64::PhysAddr; use x86_64::registers::control::{Cr3, Cr3Flags}; use x86_64::structures::paging::{ - page_table::{PageTable as x86PageTable, PageTableEntry, PageTableFlags as EF}, + frame::PhysFrame as Frame, mapper::{Mapper, RecursivePageTable}, page::{Page, PageRange, Size4KiB}, - frame::PhysFrame as Frame, - FrameAllocator, FrameDeallocator + page_table::{PageTable as x86PageTable, PageTableEntry, PageTableFlags as EF}, + FrameAllocator, FrameDeallocator, }; -use crate::consts::KERNEL_OFFSET; -use log::*; +use x86_64::PhysAddr; pub trait PageExt { fn of_addr(address: usize) -> Self; @@ -47,7 +47,12 @@ impl PageTable for ActivePageTable { fn map(&mut self, addr: usize, target: usize) -> &mut Entry { let flags = EF::PRESENT | EF::WRITABLE | EF::NO_EXECUTE; unsafe { - if let Ok(flush) = self.0.map_to(Page::of_addr(addr), Frame::of_addr(target), flags, &mut FrameAllocatorForX86) { + if let Ok(flush) = self.0.map_to( + Page::of_addr(addr), + Frame::of_addr(target), + flags, + &mut FrameAllocatorForX86, + ) { flush.flush(); } } @@ -64,7 +69,9 @@ impl PageTable for ActivePageTable { fn get_entry(&mut self, addr: usize) -> Option<&mut Entry> { for level in 0..3 { let entry = get_entry_ptr(addr, 4 - level); - if unsafe { !(*entry).present() } { return None; } + if unsafe { !(*entry).present() } { + return None; + } } unsafe { Some(&mut *(get_entry_ptr(addr, 1))) } } @@ -82,34 +89,64 @@ impl ActivePageTable { impl Entry for PageEntry { fn update(&mut self) { - use x86_64::{VirtAddr, instructions::tlb::flush}; + use x86_64::{instructions::tlb::flush, VirtAddr}; let addr = VirtAddr::new_unchecked((self as *const _ as u64) << 9); flush(addr); } - fn accessed(&self) -> bool { self.0.flags().contains(EF::ACCESSED) } - fn dirty(&self) -> bool { self.0.flags().contains(EF::DIRTY) } - fn writable(&self) -> bool { self.0.flags().contains(EF::WRITABLE) } - fn present(&self) -> bool { self.0.flags().contains(EF::PRESENT) } - fn clear_accessed(&mut self) { self.as_flags().remove(EF::ACCESSED); } - fn clear_dirty(&mut self) { self.as_flags().remove(EF::DIRTY); } - fn set_writable(&mut self, value: bool) { self.as_flags().set(EF::WRITABLE, value); } - fn set_present(&mut self, value: bool) { self.as_flags().set(EF::PRESENT, value); } - fn target(&self) -> usize { self.0.addr().as_u64() as usize } + fn accessed(&self) -> bool { + self.0.flags().contains(EF::ACCESSED) + } + fn dirty(&self) -> bool { + self.0.flags().contains(EF::DIRTY) + } + fn writable(&self) -> bool { + self.0.flags().contains(EF::WRITABLE) + } + fn present(&self) -> bool { + self.0.flags().contains(EF::PRESENT) + } + fn clear_accessed(&mut self) { + self.as_flags().remove(EF::ACCESSED); + } + fn clear_dirty(&mut self) { + self.as_flags().remove(EF::DIRTY); + } + fn set_writable(&mut self, value: bool) { + self.as_flags().set(EF::WRITABLE, value); + } + fn set_present(&mut self, value: bool) { + self.as_flags().set(EF::PRESENT, value); + } + fn target(&self) -> usize { + self.0.addr().as_u64() as usize + } fn set_target(&mut self, target: usize) { let flags = self.0.flags(); self.0.set_addr(PhysAddr::new(target as u64), flags); } - fn writable_shared(&self) -> bool { self.0.flags().contains(EF::BIT_10) } - fn readonly_shared(&self) -> bool { self.0.flags().contains(EF::BIT_9) } + fn writable_shared(&self) -> bool { + self.0.flags().contains(EF::BIT_10) + } + fn readonly_shared(&self) -> bool { + self.0.flags().contains(EF::BIT_9) + } fn set_shared(&mut self, writable: bool) { let flags = self.as_flags(); flags.set(EF::BIT_10, writable); flags.set(EF::BIT_9, !writable); } - fn clear_shared(&mut self) { self.as_flags().remove(EF::BIT_9 | EF::BIT_10); } - fn swapped(&self) -> bool { self.0.flags().contains(EF::BIT_11) } - fn set_swapped(&mut self, value: bool) { self.as_flags().set(EF::BIT_11, value); } - fn user(&self) -> bool { self.0.flags().contains(EF::USER_ACCESSIBLE) } + fn clear_shared(&mut self) { + self.as_flags().remove(EF::BIT_9 | EF::BIT_10); + } + fn swapped(&self) -> bool { + self.0.flags().contains(EF::BIT_11) + } + fn set_swapped(&mut self, value: bool) { + self.as_flags().set(EF::BIT_11, value); + } + fn user(&self) -> bool { + self.0.flags().contains(EF::USER_ACCESSIBLE) + } fn set_user(&mut self, value: bool) { self.as_flags().set(EF::USER_ACCESSIBLE, value); if value { @@ -122,10 +159,16 @@ impl Entry for PageEntry { } } } - fn execute(&self) -> bool { !self.0.flags().contains(EF::NO_EXECUTE) } - fn set_execute(&mut self, value: bool) { self.as_flags().set(EF::NO_EXECUTE, !value); } - fn mmio(&self) -> u8 { 0 } - fn set_mmio(&mut self, _value: u8) { } + fn execute(&self) -> bool { + !self.0.flags().contains(EF::NO_EXECUTE) + } + fn set_execute(&mut self, value: bool) { + self.as_flags().set(EF::NO_EXECUTE, !value); + } + fn mmio(&self) -> u8 { + 0 + } + fn set_mmio(&mut self, _value: u8) {} } fn get_entry_ptr(addr: usize, level: u8) -> *mut PageEntry { @@ -176,7 +219,10 @@ impl InactivePageTable for InactivePageTable0 { } unsafe fn set_token(token: usize) { - Cr3::write(Frame::containing_address(PhysAddr::new(token as u64)), Cr3Flags::empty()); + Cr3::write( + Frame::containing_address(PhysAddr::new(token as u64)), + Cr3Flags::empty(), + ); } fn active_token() -> usize { diff --git a/kernel/src/arch/x86_64/timer.rs b/kernel/src/arch/x86_64/timer.rs index 3eac8cc..80146c3 100644 --- a/kernel/src/arch/x86_64/timer.rs +++ b/kernel/src/arch/x86_64/timer.rs @@ -1,3 +1,3 @@ pub fn read_epoch() -> u64 { super::driver::rtc_cmos::read_epoch() -} \ No newline at end of file +} diff --git a/kernel/src/backtrace.rs b/kernel/src/backtrace.rs index 631d9ea..a4b4ecf 100644 --- a/kernel/src/backtrace.rs +++ b/kernel/src/backtrace.rs @@ -52,8 +52,16 @@ pub fn backtrace() { let mut current_pc = lr(); let mut current_fp = fp(); let mut stack_num = 0; - while current_pc >= stext as usize && current_pc <= etext as usize && current_fp as usize != 0 { - println!("#{} {:#018X} fp {:#018X}", stack_num, current_pc - size_of::(), current_fp); + while current_pc >= stext as usize + && current_pc <= etext as usize + && current_fp as usize != 0 + { + println!( + "#{} {:#018X} fp {:#018X}", + stack_num, + current_pc - size_of::(), + current_fp + ); stack_num = stack_num + 1; #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] { @@ -72,8 +80,9 @@ pub fn backtrace() { // Kernel stack at 0x0000_57ac_0000_0000 (defined in bootloader crate) // size = 512 pages current_fp = *(current_fp as *const usize).offset(0); - if current_fp >= 0x0000_57ac_0000_0000 + 512 * PAGE_SIZE - size_of::() && - current_fp <= 0xffff_ff00_0000_0000 { + if current_fp >= 0x0000_57ac_0000_0000 + 512 * PAGE_SIZE - size_of::() + && current_fp <= 0xffff_ff00_0000_0000 + { break; } current_pc = *(current_fp as *const usize).offset(1); diff --git a/kernel/src/drivers/device_tree.rs b/kernel/src/drivers/device_tree.rs index f2e7255..c983e17 100644 --- a/kernel/src/drivers/device_tree.rs +++ b/kernel/src/drivers/device_tree.rs @@ -1,5 +1,5 @@ -use core::slice; use alloc::string::String; +use core::slice; use device_tree::{DeviceTree, Node}; diff --git a/kernel/src/drivers/mod.rs b/kernel/src/drivers/mod.rs index 243d240..9a1f3e0 100644 --- a/kernel/src/drivers/mod.rs +++ b/kernel/src/drivers/mod.rs @@ -90,4 +90,4 @@ pub fn init() { lazy_static! { // Write only once at boot pub static ref CMDLINE: RwLock = RwLock::new(String::new()); -} \ No newline at end of file +} diff --git a/kernel/src/fs/device.rs b/kernel/src/fs/device.rs index 2758b3f..dc33ed8 100644 --- a/kernel/src/fs/device.rs +++ b/kernel/src/fs/device.rs @@ -1,7 +1,7 @@ //! Implement Device -use spin::RwLock; use rcore_fs::dev::*; +use spin::RwLock; #[cfg(target_arch = "x86_64")] use crate::arch::driver::ide; @@ -9,9 +9,12 @@ use crate::arch::driver::ide; pub struct MemBuf(RwLock<&'static mut [u8]>); impl MemBuf { - pub unsafe fn new(begin: unsafe extern fn(), end: unsafe extern fn()) -> Self { + pub unsafe fn new(begin: unsafe extern "C" fn(), end: unsafe extern "C" fn()) -> Self { use core::slice; - MemBuf(RwLock::new(slice::from_raw_parts_mut(begin as *mut u8, end as usize - begin as usize))) + MemBuf(RwLock::new(slice::from_raw_parts_mut( + begin as *mut u8, + end as usize - begin as usize, + ))) } } @@ -36,7 +39,8 @@ impl BlockDevice for ide::IDE { fn read_at(&self, block_id: usize, buf: &mut [u8]) -> bool { use core::slice; assert!(buf.len() >= ide::BLOCK_SIZE); - let buf = unsafe { slice::from_raw_parts_mut(buf.as_ptr() as *mut u32, ide::BLOCK_SIZE / 4) }; + let buf = + unsafe { slice::from_raw_parts_mut(buf.as_ptr() as *mut u32, ide::BLOCK_SIZE / 4) }; self.read(block_id as u64, 1, buf).is_ok() } fn write_at(&self, block_id: usize, buf: &[u8]) -> bool { @@ -45,4 +49,4 @@ impl BlockDevice for ide::IDE { let buf = unsafe { slice::from_raw_parts(buf.as_ptr() as *mut u32, ide::BLOCK_SIZE / 4) }; self.write(block_id as u64, 1, buf).is_ok() } -} \ No newline at end of file +} diff --git a/kernel/src/fs/file.rs b/kernel/src/fs/file.rs index 76c55a8..ecddfff 100644 --- a/kernel/src/fs/file.rs +++ b/kernel/src/fs/file.rs @@ -2,7 +2,7 @@ use alloc::{string::String, sync::Arc}; -use rcore_fs::vfs::{Metadata, INode, Result, FsError}; +use rcore_fs::vfs::{FsError, INode, Metadata, Result}; #[derive(Clone)] pub struct FileHandle { @@ -43,7 +43,7 @@ impl FileHandle { pub fn read_at(&mut self, offset: usize, buf: &mut [u8]) -> Result { if !self.options.read { - return Err(FsError::InvalidParam); // FIXME: => EBADF + return Err(FsError::InvalidParam); // FIXME: => EBADF } let len = self.inode.read_at(offset, buf)?; Ok(len) @@ -61,7 +61,7 @@ impl FileHandle { pub fn write_at(&mut self, offset: usize, buf: &[u8]) -> Result { if !self.options.write { - return Err(FsError::InvalidParam); // FIXME: => EBADF + return Err(FsError::InvalidParam); // FIXME: => EBADF } let len = self.inode.write_at(offset, buf)?; Ok(len) @@ -78,7 +78,7 @@ impl FileHandle { pub fn set_len(&mut self, len: u64) -> Result<()> { if !self.options.write { - return Err(FsError::InvalidParam); // FIXME: => EBADF + return Err(FsError::InvalidParam); // FIXME: => EBADF } self.inode.resize(len as usize)?; Ok(()) @@ -102,10 +102,10 @@ impl FileHandle { pub fn read_entry(&mut self) -> Result { if !self.options.read { - return Err(FsError::InvalidParam); // FIXME: => EBADF + return Err(FsError::InvalidParam); // FIXME: => EBADF } let name = self.inode.get_entry(self.offset as usize)?; self.offset += 1; Ok(name) } -} \ No newline at end of file +} diff --git a/kernel/src/fs/mod.rs b/kernel/src/fs/mod.rs index 0fad557..cfcafaf 100644 --- a/kernel/src/fs/mod.rs +++ b/kernel/src/fs/mod.rs @@ -7,24 +7,28 @@ use rcore_fs_sfs::SimpleFileSystem; use crate::arch::driver::ide; pub use self::file::*; -pub use self::stdio::{STDIN, STDOUT}; pub use self::pipe::Pipe; +pub use self::stdio::{STDIN, STDOUT}; -mod file; -mod stdio; mod device; +mod file; mod pipe; +mod stdio; /// Hard link user programs #[cfg(feature = "link_user")] -global_asm!(concat!(r#" +global_asm!(concat!( + r#" .section .data .global _user_img_start .global _user_img_end _user_img_start: - .incbin ""#, env!("SFSIMG"), r#"" + .incbin ""#, + env!("SFSIMG"), + r#"" _user_img_end: -"#)); +"# +)); lazy_static! { /// The root of file system @@ -66,7 +70,9 @@ impl INodeExt for INode { fn read_as_vec(&self) -> Result> { let size = self.metadata()?.size; let mut buf = Vec::with_capacity(size); - unsafe { buf.set_len(size); } + unsafe { + buf.set_len(size); + } self.read_at(0, buf.as_mut_slice())?; Ok(buf) } diff --git a/kernel/src/fs/stdio.rs b/kernel/src/fs/stdio.rs index 55b2dca..37da693 100644 --- a/kernel/src/fs/stdio.rs +++ b/kernel/src/fs/stdio.rs @@ -67,18 +67,22 @@ impl INode for Stdin { buf[0] = self.pop() as u8; Ok(1) } - fn write_at(&self, _offset: usize, _buf: &[u8]) -> Result { unimplemented!() } + fn write_at(&self, _offset: usize, _buf: &[u8]) -> Result { + unimplemented!() + } impl_inode!(); } impl INode for Stdout { - fn read_at(&self, _offset: usize, _buf: &mut [u8]) -> Result { unimplemented!() } + fn read_at(&self, _offset: usize, _buf: &mut [u8]) -> Result { + unimplemented!() + } fn write_at(&self, _offset: usize, buf: &[u8]) -> Result { use core::str; //we do not care the utf-8 things, we just want to print it! - let s = unsafe{ str::from_utf8_unchecked(buf) }; + let s = unsafe { str::from_utf8_unchecked(buf) }; print!("{}", s); Ok(buf.len()) } impl_inode!(); -} \ No newline at end of file +} diff --git a/kernel/src/lang.rs b/kernel/src/lang.rs index d86210c..2079e07 100644 --- a/kernel/src/lang.rs +++ b/kernel/src/lang.rs @@ -1,19 +1,20 @@ // Rust language features implementations -use core::panic::PanicInfo; +use crate::backtrace; use core::alloc::Layout; +use core::panic::PanicInfo; use log::*; -use crate::backtrace; -#[lang = "eh_personality"] -extern fn eh_personality() { -} +#[lang = "eh_personality"] +extern "C" fn eh_personality() {} #[panic_handler] fn panic(info: &PanicInfo) -> ! { error!("\n\n{}", info); backtrace::backtrace(); - loop { crate::arch::cpu::halt() } + loop { + crate::arch::cpu::halt() + } } #[lang = "oom"] diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index 4a2487d..20ff71a 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -16,25 +16,25 @@ extern crate log; #[macro_use] extern crate lazy_static; -pub use crate::process::{processor, new_kernel_context}; -use rcore_thread::std_thread as thread; +pub use crate::process::{new_kernel_context, processor}; use buddy_system_allocator::LockedHeap; +use rcore_thread::std_thread as thread; -#[macro_use] // print! +#[macro_use] // print! mod logging; -mod memory; -mod lang; -mod util; +mod backtrace; mod consts; -mod process; -mod syscall; +mod drivers; mod fs; +mod lang; +mod memory; +mod net; +mod process; +mod shell; mod sync; +mod syscall; mod trap; -mod shell; -mod drivers; -mod net; -mod backtrace; +mod util; #[allow(dead_code)] #[cfg(target_arch = "x86_64")] diff --git a/kernel/src/logging.rs b/kernel/src/logging.rs index ba7c595..b832d50 100644 --- a/kernel/src/logging.rs +++ b/kernel/src/logging.rs @@ -61,15 +61,17 @@ struct SimpleLogger; impl Log for SimpleLogger { fn enabled(&self, _metadata: &Metadata) -> bool { - true + true } fn log(&self, record: &Record) { - static DISABLED_TARGET: &[&str] = &[ - ]; + static DISABLED_TARGET: &[&str] = &[]; if self.enabled(record.metadata()) && !DISABLED_TARGET.contains(&record.target()) { -// let target = record.target(); -// let begin = target.as_bytes().iter().rposition(|&c| c == b':').map(|i| i + 1).unwrap_or(0); - print_in_color(format_args!("[{:>5}] {}\n", record.level(), record.args()), ConsoleColor::from(record.level())); + // let target = record.target(); + // let begin = target.as_bytes().iter().rposition(|&c| c == b':').map(|i| i + 1).unwrap_or(0); + print_in_color( + format_args!("[{:>5}] {}\n", record.level(), record.args()), + ConsoleColor::from(record.level()), + ); } } fn flush(&self) {} diff --git a/kernel/src/main.rs b/kernel/src/main.rs index d4205aa..0ce3725 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -3,4 +3,4 @@ #![cfg_attr(test, allow(dead_code, unused_macros, unused_imports))] #[allow(unused_imports)] -use rcore; \ No newline at end of file +use rcore; diff --git a/kernel/src/memory.rs b/kernel/src/memory.rs index 63d8fc6..f48a625 100644 --- a/kernel/src/memory.rs +++ b/kernel/src/memory.rs @@ -1,14 +1,14 @@ +use super::HEAP_ALLOCATOR; pub use crate::arch::paging::*; -use bit_allocator::BitAlloc; use crate::consts::MEMORY_OFFSET; -use super::HEAP_ALLOCATOR; -use rcore_memory::*; -pub use rcore_memory::memory_set::{MemoryArea, MemoryAttr, handler::*}; use crate::process::process_unsafe; use crate::sync::SpinNoIrqLock; +use bit_allocator::BitAlloc; +use buddy_system_allocator::LockedHeap; use lazy_static::*; use log::*; -use buddy_system_allocator::LockedHeap; +pub use rcore_memory::memory_set::{handler::*, MemoryArea, MemoryAttr}; +use rcore_memory::*; pub type MemorySet = rcore_memory::memory_set::MemorySet; @@ -25,7 +25,8 @@ pub type FrameAlloc = bit_allocator::BitAlloc4K; pub type FrameAlloc = bit_allocator::BitAlloc1M; lazy_static! { - pub static ref FRAME_ALLOCATOR: SpinNoIrqLock = SpinNoIrqLock::new(FrameAlloc::default()); + pub static ref FRAME_ALLOCATOR: SpinNoIrqLock = + SpinNoIrqLock::new(FrameAlloc::default()); } /// The only way to get active page table @@ -46,21 +47,25 @@ pub fn active_table() -> ActivePageTable { unsafe { ActivePageTable::new() } } - #[derive(Debug, Clone, Copy)] pub struct GlobalFrameAlloc; impl FrameAllocator for GlobalFrameAlloc { fn alloc(&self) -> Option { // get the real address of the alloc frame - let ret = FRAME_ALLOCATOR.lock().alloc().map(|id| id * PAGE_SIZE + MEMORY_OFFSET); + let ret = FRAME_ALLOCATOR + .lock() + .alloc() + .map(|id| id * PAGE_SIZE + MEMORY_OFFSET); trace!("Allocate frame: {:x?}", ret); ret // TODO: try to swap out when alloc failed } fn dealloc(&self, target: usize) { trace!("Deallocate frame: {:x}", target); - FRAME_ALLOCATOR.lock().dealloc((target - MEMORY_OFFSET) / PAGE_SIZE); + FRAME_ALLOCATOR + .lock() + .dealloc((target - MEMORY_OFFSET) / PAGE_SIZE); } } @@ -77,7 +82,8 @@ const STACK_SIZE: usize = 0x8000; impl KernelStack { pub fn new() -> Self { use alloc::alloc::{alloc, Layout}; - let bottom = unsafe{ alloc(Layout::from_size_align(STACK_SIZE, STACK_SIZE).unwrap()) } as usize; + let bottom = + unsafe { alloc(Layout::from_size_align(STACK_SIZE, STACK_SIZE).unwrap()) } as usize; KernelStack(bottom) } pub fn top(&self) -> usize { @@ -88,28 +94,34 @@ impl KernelStack { impl Drop for KernelStack { fn drop(&mut self) { use alloc::alloc::{dealloc, Layout}; - unsafe{ dealloc(self.0 as _, Layout::from_size_align(STACK_SIZE, STACK_SIZE).unwrap()); } + unsafe { + dealloc( + self.0 as _, + Layout::from_size_align(STACK_SIZE, STACK_SIZE).unwrap(), + ); + } } } - /// Handle page fault at `addr`. /// Return true to continue, false to halt. pub fn handle_page_fault(addr: usize) -> bool { debug!("page fault @ {:#x}", addr); // This is safe as long as page fault never happens in page fault handler - unsafe { - process_unsafe().vm.handle_page_fault(addr) - } + unsafe { process_unsafe().vm.handle_page_fault(addr) } } pub fn init_heap() { use crate::consts::KERNEL_HEAP_SIZE; static mut HEAP: [u8; KERNEL_HEAP_SIZE] = [0; KERNEL_HEAP_SIZE]; - unsafe { HEAP_ALLOCATOR.lock().init(HEAP.as_ptr() as usize, KERNEL_HEAP_SIZE); } + unsafe { + HEAP_ALLOCATOR + .lock() + .init(HEAP.as_ptr() as usize, KERNEL_HEAP_SIZE); + } info!("heap init end"); } /// Allocator for the rest memory space on NO-MMU case. -pub static MEMORY_ALLOCATOR: LockedHeap = LockedHeap::empty(); \ No newline at end of file +pub static MEMORY_ALLOCATOR: LockedHeap = LockedHeap::empty(); diff --git a/kernel/src/net/structs.rs b/kernel/src/net/structs.rs index d24abe4..0295e54 100644 --- a/kernel/src/net/structs.rs +++ b/kernel/src/net/structs.rs @@ -1,8 +1,8 @@ -use alloc::sync::Arc; use crate::arch::rand; use crate::drivers::{NET_DRIVERS, SOCKET_ACTIVITY}; use crate::sync::SpinNoIrqLock as Mutex; use crate::syscall::*; +use alloc::sync::Arc; use smoltcp::socket::*; use smoltcp::wire::*; diff --git a/kernel/src/process/abi.rs b/kernel/src/process/abi.rs index 4cbe1d2..913fb1a 100644 --- a/kernel/src/process/abi.rs +++ b/kernel/src/process/abi.rs @@ -1,6 +1,6 @@ +use alloc::collections::btree_map::BTreeMap; use alloc::string::String; use alloc::vec::Vec; -use alloc::collections::btree_map::BTreeMap; use core::ptr::null; pub struct ProcInitInfo { @@ -16,17 +16,25 @@ impl ProcInitInfo { // program name writer.push_str(&self.args[0]); // environment strings - let envs: Vec<_> = self.envs.iter().map(|(key, value)| { - writer.push_str(value.as_str()); - writer.push_slice(&[b"="]); - writer.push_slice(key.as_bytes()); - writer.sp - }).collect(); + let envs: Vec<_> = self + .envs + .iter() + .map(|(key, value)| { + writer.push_str(value.as_str()); + writer.push_slice(&[b"="]); + writer.push_slice(key.as_bytes()); + writer.sp + }) + .collect(); // argv strings - let argv: Vec<_> = self.args.iter().map(|arg| { - writer.push_str(arg.as_str()); - writer.sp - }).collect(); + let argv: Vec<_> = self + .args + .iter() + .map(|arg| { + writer.push_str(arg.as_str()); + writer.sp + }) + .collect(); // auxiliary vector entries writer.push_slice(&[null::(), null::()]); for (&type_, &value) in self.auxv.iter() { @@ -50,11 +58,13 @@ struct StackWriter { impl StackWriter { fn push_slice(&mut self, vs: &[T]) { - use core::{mem::{size_of, align_of}, slice}; + use core::{ + mem::{align_of, size_of}, + slice, + }; self.sp -= vs.len() * size_of::(); self.sp -= self.sp % align_of::(); - unsafe { slice::from_raw_parts_mut(self.sp as *mut T, vs.len()) } - .copy_from_slice(vs); + unsafe { slice::from_raw_parts_mut(self.sp as *mut T, vs.len()) }.copy_from_slice(vs); } fn push_str(&mut self, s: &str) { self.push_slice(&[b'\0']); diff --git a/kernel/src/process/mod.rs b/kernel/src/process/mod.rs index 64348dc..e476fd4 100644 --- a/kernel/src/process/mod.rs +++ b/kernel/src/process/mod.rs @@ -1,13 +1,13 @@ pub use self::structs::*; -pub use rcore_thread::*; -use crate::consts::{MAX_CPU_NUM, MAX_PROCESS_NUM}; use crate::arch::cpu; +use crate::consts::{MAX_CPU_NUM, MAX_PROCESS_NUM}; use alloc::{boxed::Box, sync::Arc}; -use spin::MutexGuard; use log::*; +pub use rcore_thread::*; +use spin::MutexGuard; -pub mod structs; mod abi; +pub mod structs; pub fn init() { // NOTE: max_time_slice <= 5 to ensure 'priority' test pass @@ -25,7 +25,16 @@ pub fn init() { info!("process: init end"); } -static PROCESSORS: [Processor; MAX_CPU_NUM] = [Processor::new(), Processor::new(), Processor::new(), Processor::new(), Processor::new(), Processor::new(), Processor::new(), Processor::new()]; +static PROCESSORS: [Processor; MAX_CPU_NUM] = [ + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), + Processor::new(), +]; /// Get current process pub fn process() -> MutexGuard<'static, Process> { @@ -45,13 +54,10 @@ pub unsafe fn process_unsafe() -> MutexGuard<'static, Process> { /// FIXME: It's obviously unsafe to get &mut ! pub fn current_thread() -> &'static mut Thread { use core::mem::transmute; - let (process, _): (&mut Thread, *const ()) = unsafe { - transmute(processor().context()) - }; + let (process, _): (&mut Thread, *const ()) = unsafe { transmute(processor().context()) }; process } - // Implement dependencies for std::thread #[no_mangle] @@ -60,6 +66,6 @@ pub fn processor() -> &'static Processor { } #[no_mangle] -pub fn new_kernel_context(entry: extern fn(usize) -> !, arg: usize) -> Box { +pub fn new_kernel_context(entry: extern "C" fn(usize) -> !, arg: usize) -> Box { Thread::new_kernel(entry, arg) } diff --git a/kernel/src/process/structs.rs b/kernel/src/process/structs.rs index 646e0c7..038eee0 100644 --- a/kernel/src/process/structs.rs +++ b/kernel/src/process/structs.rs @@ -1,18 +1,22 @@ -use alloc::{boxed::Box, collections::BTreeMap, string::String, sync::Arc, vec::Vec, sync::Weak}; +use alloc::{boxed::Box, collections::BTreeMap, string::String, sync::Arc, sync::Weak, vec::Vec}; use core::fmt; +use core::str; use log::*; -use spin::{Mutex, RwLock}; -use xmas_elf::{ElfFile, header, program::{Flags, Type, SegmentData}}; use rcore_memory::PAGE_SIZE; use rcore_thread::Tid; -use core::str; +use spin::{Mutex, RwLock}; +use xmas_elf::{ + header, + program::{Flags, SegmentData, Type}, + ElfFile, +}; use crate::arch::interrupt::{Context, TrapFrame}; +use crate::fs::{FileHandle, INodeExt, OpenOptions, FOLLOW_MAX_DEPTH}; use crate::memory::{ByFrame, GlobalFrameAlloc, KernelStack, MemoryAttr, MemorySet}; -use crate::fs::{FileHandle, OpenOptions, INodeExt, FOLLOW_MAX_DEPTH}; -use crate::sync::Condvar; use crate::net::{SocketWrapper, SOCKETS}; +use crate::sync::Condvar; use super::abi::{self, ProcInitInfo}; @@ -26,20 +30,17 @@ pub struct Thread { pub proc: Arc>, } - #[derive(Clone)] pub enum FileLike { File(FileHandle), - Socket(SocketWrapper) + Socket(SocketWrapper), } impl fmt::Debug for FileLike { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { FileLike::File(_) => write!(f, "File"), - FileLike::Socket(wrapper) => { - write!(f, "{:?}", wrapper) - }, + FileLike::Socket(wrapper) => write!(f, "{:?}", wrapper), } } } @@ -104,7 +105,8 @@ pub struct Process { /// Records the mapping between pid and Process struct. lazy_static! { - pub static ref PROCESSES: RwLock>>> = RwLock::new(BTreeMap::new()); + pub static ref PROCESSES: RwLock>>> = + RwLock::new(BTreeMap::new()); } /// Let `rcore_thread` can switch between our `Thread` @@ -128,7 +130,9 @@ impl rcore_thread::Context for Thread { } // add it to threads proc.threads.push(tid); - PROCESSES.write().insert(proc.pid.get(), Arc::downgrade(&self.proc)); + PROCESSES + .write() + .insert(proc.pid.get(), Arc::downgrade(&self.proc)); } } @@ -156,7 +160,7 @@ impl Thread { } /// Make a new kernel thread starting from `entry` with `arg` - pub fn new_kernel(entry: extern fn(usize) -> !, arg: usize) -> Box { + pub fn new_kernel(entry: extern "C" fn(usize) -> !, arg: usize) -> Box { let vm = MemorySet::new(); let kstack = KernelStack::new(); Box::new(Thread { @@ -174,14 +178,15 @@ impl Thread { children: Vec::new(), threads: Vec::new(), child_exit: Arc::new(Condvar::new()), - child_exit_code: BTreeMap::new() + child_exit_code: BTreeMap::new(), })), }) } /// Make a new user process from ELF `data` pub fn new_user<'a, Iter>(data: &[u8], args: Iter) -> Box - where Iter: Iterator + where + Iter: Iterator, { // Parse ELF let elf = ElfFile::new(data).expect("failed to read elf"); @@ -192,8 +197,8 @@ impl Thread { // Check ELF type match elf.header.pt2.type_().as_type() { - header::Type::Executable => {}, - header::Type::SharedObject => {}, + header::Type::Executable => {} + header::Type::SharedObject => {} _ => panic!("ELF is not executable or shared object"), } @@ -220,13 +225,19 @@ impl Thread { let mut vm = elf.make_memory_set(); // User stack - use crate::consts::{USER_STACK_OFFSET, USER_STACK_SIZE, USER32_STACK_OFFSET}; + use crate::consts::{USER32_STACK_OFFSET, USER_STACK_OFFSET, USER_STACK_SIZE}; let mut ustack_top = { let (ustack_buttom, ustack_top) = match is32 { true => (USER32_STACK_OFFSET, USER32_STACK_OFFSET + USER_STACK_SIZE), false => (USER_STACK_OFFSET, USER_STACK_OFFSET + USER_STACK_SIZE), }; - vm.push(ustack_buttom, ustack_top, MemoryAttr::default().user(), ByFrame::new(GlobalFrameAlloc), "user_stack"); + vm.push( + ustack_buttom, + ustack_top, + MemoryAttr::default().user(), + ByFrame::new(GlobalFrameAlloc), + "user_stack", + ); ustack_top }; @@ -246,7 +257,7 @@ impl Thread { }, }; unsafe { - vm.with(|| { ustack_top = init_info.push_at(ustack_top) }); + vm.with(|| ustack_top = init_info.push_at(ustack_top)); } trace!("{:#x?}", vm); @@ -254,16 +265,45 @@ impl Thread { let kstack = KernelStack::new(); let mut files = BTreeMap::new(); - files.insert(0, FileLike::File(FileHandle::new(crate::fs::STDIN.clone(), OpenOptions { read: true, write: false, append: false }))); - files.insert(1, FileLike::File(FileHandle::new(crate::fs::STDOUT.clone(), OpenOptions { read: false, write: true, append: false }))); - files.insert(2, FileLike::File(FileHandle::new(crate::fs::STDOUT.clone(), OpenOptions { read: false, write: true, append: false }))); + files.insert( + 0, + FileLike::File(FileHandle::new( + crate::fs::STDIN.clone(), + OpenOptions { + read: true, + write: false, + append: false, + }, + )), + ); + files.insert( + 1, + FileLike::File(FileHandle::new( + crate::fs::STDOUT.clone(), + OpenOptions { + read: false, + write: true, + append: false, + }, + )), + ); + files.insert( + 2, + FileLike::File(FileHandle::new( + crate::fs::STDOUT.clone(), + OpenOptions { + read: false, + write: true, + append: false, + }, + )), + ); let entry_addr = elf.header.pt2.entry_point() as usize; Box::new(Thread { context: unsafe { - Context::new_user_thread( - entry_addr, ustack_top, kstack.top(), is32, vm.token()) + Context::new_user_thread(entry_addr, ustack_top, kstack.top(), is32, vm.token()) }, kstack, clear_child_tid: 0, @@ -277,7 +317,7 @@ impl Thread { children: Vec::new(), threads: Vec::new(), child_exit: Arc::new(Condvar::new()), - child_exit_code: BTreeMap::new() + child_exit_code: BTreeMap::new(), })), }) } @@ -297,9 +337,7 @@ impl Thread { // NoMMU: coping data has been done in `vm.clone()` for area in vm.iter() { let data = Vec::::from(unsafe { area.as_slice() }); - unsafe { vm.with(|| { - area.as_slice_mut().copy_from_slice(data.as_slice()) - }) } + unsafe { vm.with(|| area.as_slice_mut().copy_from_slice(data.as_slice())) } } debug!("fork: temporary copy data!"); @@ -326,13 +364,19 @@ impl Thread { children: Vec::new(), threads: Vec::new(), child_exit: Arc::new(Condvar::new()), - child_exit_code: BTreeMap::new() + child_exit_code: BTreeMap::new(), })), }) } /// Create a new thread in the same process. - pub fn clone(&self, tf: &TrapFrame, stack_top: usize, tls: usize, clear_child_tid: usize) -> Box { + pub fn clone( + &self, + tf: &TrapFrame, + stack_top: usize, + tls: usize, + clear_child_tid: usize, + ) -> Box { let kstack = KernelStack::new(); let token = self.proc.lock().vm.token(); Box::new(Thread { @@ -371,7 +415,9 @@ impl ToMemoryAttr for Flags { fn to_attr(&self) -> MemoryAttr { let mut flags = MemoryAttr::default().user(); // FIXME: handle readonly - if self.is_execute() { flags = flags.execute(); } + if self.is_execute() { + flags = flags.execute(); + } flags } } @@ -406,7 +452,13 @@ impl ElfExt for ElfFile<'_> { // Get target slice let target = { - ms.push(virt_addr, virt_addr + mem_size, ph.flags().to_attr(), ByFrame::new(GlobalFrameAlloc), ""); + ms.push( + virt_addr, + virt_addr + mem_size, + ph.flags().to_attr(), + ByFrame::new(GlobalFrameAlloc), + "", + ); unsafe { ::core::slice::from_raw_parts_mut(virt_addr as *mut u8, mem_size) } }; // Copy data @@ -423,29 +475,34 @@ impl ElfExt for ElfFile<'_> { } fn get_interpreter(&self) -> Result<&str, &str> { - let header = self.program_iter() + let header = self + .program_iter() .filter(|ph| ph.get_type() == Ok(Type::Interp)) - .next().ok_or("no interp header")?; + .next() + .ok_or("no interp header")?; let mut data = match header.get_data(self)? { SegmentData::Undefined(data) => data, _ => unreachable!(), }; // skip NULL while let Some(0) = data.last() { - data = &data[..data.len()-1]; + data = &data[..data.len() - 1]; } - let path = str::from_utf8(data) - .map_err(|_| "failed to convert to utf8")?; + let path = str::from_utf8(data).map_err(|_| "failed to convert to utf8")?; Ok(path) } fn get_phdr_vaddr(&self) -> Option { - if let Some(phdr) = self.program_iter() - .find(|ph| ph.get_type() == Ok(Type::Phdr)) { + if let Some(phdr) = self + .program_iter() + .find(|ph| ph.get_type() == Ok(Type::Phdr)) + { // if phdr exists in program header, use it Some(phdr.virtual_addr()) - } else if let Some(elf_addr) = self.program_iter() - .find(|ph| ph.get_type() == Ok(Type::Load) && ph.offset() == 0) { + } else if let Some(elf_addr) = self + .program_iter() + .find(|ph| ph.get_type() == Ok(Type::Load) && ph.offset() == 0) + { // otherwise, check if elf is loaded from the beginning, then phdr can be inferred. Some(elf_addr.virtual_addr() + self.header.pt2.ph_offset()) } else { diff --git a/kernel/src/shell.rs b/kernel/src/shell.rs index 0402a3e..ce0f156 100644 --- a/kernel/src/shell.rs +++ b/kernel/src/shell.rs @@ -1,16 +1,18 @@ //! Kernel shell +use crate::drivers::CMDLINE; +use crate::fs::{INodeExt, ROOT_INODE}; +use crate::process::*; use alloc::string::String; use alloc::vec::Vec; -use crate::fs::{ROOT_INODE, INodeExt}; -use crate::process::*; -use crate::drivers::CMDLINE; #[cfg(not(feature = "run_cmdline"))] pub fn run_user_shell() { if let Ok(inode) = ROOT_INODE.lookup("rust/sh") { let data = inode.read_as_vec().unwrap(); - processor().manager().add(Thread::new_user(data.as_slice(), "sh".split(' '))); + processor() + .manager() + .add(Thread::new_user(data.as_slice(), "sh".split(' '))); } else { processor().manager().add(Thread::new_kernel(shell, 0)); } @@ -21,10 +23,12 @@ pub fn run_user_shell() { let cmdline = CMDLINE.read(); let inode = ROOT_INODE.lookup(&cmdline).unwrap(); let data = inode.read_as_vec().unwrap(); - processor().manager().add(Thread::new_user(data.as_slice(), cmdline.split(' '))); + processor() + .manager() + .add(Thread::new_user(data.as_slice(), cmdline.split(' '))); } -pub extern fn shell(_arg: usize) -> ! { +pub extern "C" fn shell(_arg: usize) -> ! { let files = ROOT_INODE.list().unwrap(); println!("Available programs: {:?}", files); let mut history = Vec::new(); @@ -38,9 +42,11 @@ pub extern fn shell(_arg: usize) -> ! { let name = cmd.trim().split(' ').next().unwrap(); if let Ok(file) = ROOT_INODE.lookup(name) { let data = file.read_as_vec().unwrap(); - let _pid = processor().manager().add(Thread::new_user(data.as_slice(), cmd.split(' '))); - // TODO: wait until process exits, or use user land shell completely - //unsafe { thread::JoinHandle::<()>::_of(pid) }.join().unwrap(); + let _pid = processor() + .manager() + .add(Thread::new_user(data.as_slice(), cmd.split(' '))); + // TODO: wait until process exits, or use user land shell completely + //unsafe { thread::JoinHandle::<()>::_of(pid) }.join().unwrap(); } else { println!("Program not exist"); } diff --git a/kernel/src/sync/condvar.rs b/kernel/src/sync/condvar.rs index f04196b..a03f107 100644 --- a/kernel/src/sync/condvar.rs +++ b/kernel/src/sync/condvar.rs @@ -1,6 +1,6 @@ -use alloc::collections::VecDeque; use super::*; use crate::thread; +use alloc::collections::VecDeque; use alloc::sync::Arc; use alloc::vec::Vec; @@ -47,7 +47,8 @@ impl Condvar { } pub fn wait<'a, T, S>(&self, guard: MutexGuard<'a, T, S>) -> MutexGuard<'a, T, S> - where S: MutexSupport + where + S: MutexSupport, { let mutex = guard.mutex; drop(guard); @@ -68,7 +69,7 @@ impl Condvar { /// Notify up to `n` waiters. /// Return the number of waiters that were woken up. pub fn notify_n(&self, n: usize) -> usize { - let mut count = 0; + let mut count = 0; while count < n { if let Some(t) = self.wait_queue.lock().pop_front() { t.unpark(); @@ -82,4 +83,4 @@ impl Condvar { pub fn _clear(&self) { self.wait_queue.lock().clear(); } -} \ No newline at end of file +} diff --git a/kernel/src/sync/mod.rs b/kernel/src/sync/mod.rs index 17de3ed..7e16fe0 100644 --- a/kernel/src/sync/mod.rs +++ b/kernel/src/sync/mod.rs @@ -54,8 +54,8 @@ pub use self::condvar::*; pub use self::mutex::*; pub use self::semaphore::*; -mod mutex; mod condvar; -mod semaphore; pub mod mpsc; +mod mutex; +mod semaphore; pub mod test; diff --git a/kernel/src/sync/mpsc.rs b/kernel/src/sync/mpsc.rs index 1c76226..0a9159e 100644 --- a/kernel/src/sync/mpsc.rs +++ b/kernel/src/sync/mpsc.rs @@ -1,6 +1,6 @@ -use alloc::{sync::Arc, sync::Weak, collections::VecDeque}; use super::Condvar; use super::SpinLock as Mutex; +use alloc::{collections::VecDeque, sync::Arc, sync::Weak}; struct Channel { deque: Mutex>, @@ -26,7 +26,7 @@ pub struct Receiver { unsafe impl Send for Receiver {} -impl ! Sync for Receiver {} +impl !Sync for Receiver {} #[derive(Debug)] pub struct RecvError; @@ -54,7 +54,7 @@ pub struct Sender { unsafe impl Send for Sender {} -impl ! Sync for Sender {} +impl !Sync for Sender {} #[derive(Debug)] pub struct SendError(pub T); @@ -78,7 +78,9 @@ impl Sender { /// Creates a new asynchronous channel, returning the sender/receiver halves. pub fn channel() -> (Sender, Receiver) { let channel = Arc::new(Channel::::default()); - let sender = Sender { inner: Arc::downgrade(&channel) }; + let sender = Sender { + inner: Arc::downgrade(&channel), + }; let receiver = Receiver { inner: channel }; (sender, receiver) } @@ -86,9 +88,9 @@ pub fn channel() -> (Sender, Receiver) { pub mod test { //! Copied from std::mpsc::test - use alloc::boxed::Box; use super::*; use crate::thread; + use alloc::boxed::Box; fn smoke() { let (tx, rx) = channel::(); @@ -140,4 +142,4 @@ pub mod test { smoke_port_gone(); println!("mpsc test end"); } -} \ No newline at end of file +} diff --git a/kernel/src/sync/mutex.rs b/kernel/src/sync/mutex.rs index dc0158e..e319fde 100644 --- a/kernel/src/sync/mutex.rs +++ b/kernel/src/sync/mutex.rs @@ -26,19 +26,18 @@ //! `MutexSupport`提供了若干接口,它们会在操作锁的不同时间点被调用。 //! 注意这个接口实际是取了几种实现的并集,并不是很通用。 +use super::Condvar; use crate::arch::interrupt; use core::cell::UnsafeCell; use core::fmt; use core::ops::{Deref, DerefMut}; use core::sync::atomic::{AtomicBool, Ordering}; -use super::Condvar; pub type SpinLock = Mutex; pub type SpinNoIrqLock = Mutex; pub type ThreadLock = Mutex; -pub struct Mutex -{ +pub struct Mutex { lock: AtomicBool, support: S, data: UnsafeCell, @@ -47,8 +46,7 @@ pub struct Mutex /// A guard to which the protected data can be accessed /// /// When the guard falls out of scope it will release the lock. -pub struct MutexGuard<'a, T: ?Sized + 'a, S: MutexSupport + 'a> -{ +pub struct MutexGuard<'a, T: ?Sized + 'a, S: MutexSupport + 'a> { pub(super) mutex: &'a Mutex, support_guard: S::GuardData, } @@ -58,8 +56,7 @@ unsafe impl Sync for Mutex {} unsafe impl Send for Mutex {} -impl Mutex -{ +impl Mutex { /// Creates a new spinlock wrapping the supplied data. /// /// May be used statically: @@ -93,8 +90,7 @@ impl Mutex } } -impl Mutex -{ +impl Mutex { fn obtain_lock(&self) { while self.lock.compare_and_swap(false, true, Ordering::Acquire) != false { // Wait until the lock looks unlocked before retrying @@ -119,8 +115,7 @@ impl Mutex /// } /// /// ``` - pub fn lock(&self) -> MutexGuard - { + pub fn lock(&self) -> MutexGuard { let support_guard = S::before_lock(); self.obtain_lock(); MutexGuard { @@ -155,11 +150,14 @@ impl Mutex } } -impl fmt::Debug for Mutex -{ +impl fmt::Debug for Mutex { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.try_lock() { - Some(guard) => write!(f, "Mutex {{ data: {:?}, support: {:?} }}", &*guard, self.support), + Some(guard) => write!( + f, + "Mutex {{ data: {:?}, support: {:?} }}", + &*guard, self.support + ), None => write!(f, "Mutex {{ , support: {:?} }}", self.support), } } @@ -171,19 +169,20 @@ impl Default for Mutex { } } -impl<'a, T: ?Sized, S: MutexSupport> Deref for MutexGuard<'a, T, S> -{ +impl<'a, T: ?Sized, S: MutexSupport> Deref for MutexGuard<'a, T, S> { type Target = T; - fn deref(&self) -> &T { unsafe { &*self.mutex.data.get() } } + fn deref(&self) -> &T { + unsafe { &*self.mutex.data.get() } + } } -impl<'a, T: ?Sized, S: MutexSupport> DerefMut for MutexGuard<'a, T, S> -{ - fn deref_mut(&mut self) -> &mut T { unsafe { &mut *self.mutex.data.get() } } +impl<'a, T: ?Sized, S: MutexSupport> DerefMut for MutexGuard<'a, T, S> { + fn deref_mut(&mut self) -> &mut T { + unsafe { &mut *self.mutex.data.get() } + } } -impl<'a, T: ?Sized, S: MutexSupport> Drop for MutexGuard<'a, T, S> -{ +impl<'a, T: ?Sized, S: MutexSupport> Drop for MutexGuard<'a, T, S> { /// The dropping of the MutexGuard will release the lock it was created from. fn drop(&mut self) { self.mutex.lock.store(false, Ordering::Release); @@ -210,15 +209,17 @@ pub struct Spin; impl MutexSupport for Spin { type GuardData = (); - fn new() -> Self { Spin } + fn new() -> Self { + Spin + } fn cpu_relax(&self) { unsafe { #[cfg(target_arch = "x86_64")] - asm!("pause" :::: "volatile"); + asm!("pause" :::: "volatile"); #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] - asm!("nop" :::: "volatile"); + asm!("nop" :::: "volatile"); #[cfg(target_arch = "aarch64")] - asm!("yield" :::: "volatile"); + asm!("yield" :::: "volatile"); } } fn before_lock() -> Self::GuardData {} @@ -252,11 +253,11 @@ impl MutexSupport for SpinNoIrq { fn cpu_relax(&self) { unsafe { #[cfg(target_arch = "x86_64")] - asm!("pause" :::: "volatile"); + asm!("pause" :::: "volatile"); #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] - asm!("nop" :::: "volatile"); + asm!("nop" :::: "volatile"); #[cfg(target_arch = "aarch64")] - asm!("yield" :::: "volatile"); + asm!("yield" :::: "volatile"); } } fn before_lock() -> Self::GuardData { diff --git a/kernel/src/sync/semaphore.rs b/kernel/src/sync/semaphore.rs index b89e5fe..0f6bef7 100644 --- a/kernel/src/sync/semaphore.rs +++ b/kernel/src/sync/semaphore.rs @@ -67,4 +67,4 @@ impl<'a> Drop for SemaphoreGuard<'a> { fn drop(&mut self) { self.sem.release(); } -} \ No newline at end of file +} diff --git a/kernel/src/sync/test.rs b/kernel/src/sync/test.rs index b328048..3b7e1c7 100644 --- a/kernel/src/sync/test.rs +++ b/kernel/src/sync/test.rs @@ -2,12 +2,12 @@ //! //! The code is borrowed from [RustDoc - Dining Philosophers](https://doc.rust-lang.org/1.6.0/book/dining-philosophers.html) -use alloc::{sync::Arc, vec::Vec}; -use core::time::Duration; use crate::sync::Condvar; use crate::sync::ThreadLock as Mutex; use crate::thread; use alloc::vec; +use alloc::{sync::Arc, vec::Vec}; +use core::time::Duration; use log::*; struct Philosopher { @@ -18,11 +18,7 @@ struct Philosopher { impl Philosopher { fn new(name: &'static str, left: usize, right: usize) -> Philosopher { - Philosopher { - name, - left, - right, - } + Philosopher { name, left, right } } fn eat(&self, table: &Arc) { @@ -92,18 +88,21 @@ fn philosopher(table: Arc
) { Philosopher::new("5", 0, 4), ]; - let handles: Vec<_> = philosophers.into_iter().map(|p| { - let table = table.clone(); - trace!("philosopher start"); - - thread::spawn(move || { - for i in 0..5 { - p.think(); - p.eat(&table); - println!("{} iter {} end.", p.name, i); - } + let handles: Vec<_> = philosophers + .into_iter() + .map(|p| { + let table = table.clone(); + trace!("philosopher start"); + + thread::spawn(move || { + for i in 0..5 { + p.think(); + p.eat(&table); + println!("{} iter {} end.", p.name, i); + } + }) }) - }).collect(); + .collect(); trace!("philosopher starting finish"); for h in handles { @@ -116,7 +115,13 @@ pub fn philosopher_using_mutex() { println!("philosophers using mutex"); let table = Arc::new(MutexTable { - forks: vec![Mutex::new(()), Mutex::new(()), Mutex::new(()), Mutex::new(()), Mutex::new(())] + forks: vec![ + Mutex::new(()), + Mutex::new(()), + Mutex::new(()), + Mutex::new(()), + Mutex::new(()), + ], }); philosopher(table); } @@ -126,7 +131,13 @@ pub fn philosopher_using_monitor() { let table = Arc::new(MonitorTable { fork_status: Mutex::new(vec![false; 5]), - fork_condvar: vec![Condvar::new(), Condvar::new(), Condvar::new(), Condvar::new(), Condvar::new()], + fork_condvar: vec![ + Condvar::new(), + Condvar::new(), + Condvar::new(), + Condvar::new(), + Condvar::new(), + ], }); philosopher(table); -} \ No newline at end of file +} diff --git a/kernel/src/syscall/custom.rs b/kernel/src/syscall/custom.rs index 2894f00..94ef99a 100644 --- a/kernel/src/syscall/custom.rs +++ b/kernel/src/syscall/custom.rs @@ -1,7 +1,7 @@ //! Custom nonstandard syscalls +use super::*; use rcore_memory::memory_set::handler::Linear; use rcore_memory::memory_set::MemoryAttr; -use super::*; /// Allocate this PCI device to user space /// The kernel driver using the PCI device will be unloaded @@ -13,15 +13,13 @@ pub fn sys_map_pci_device(vendor: usize, product: usize) -> SysResult { vendor, product ); - let tag = pci::find_device(vendor as u32, product as u32) - .ok_or(SysError::ENOENT)?; + let tag = pci::find_device(vendor as u32, product as u32).ok_or(SysError::ENOENT)?; if pci::detach_driver(&tag) { info!("Kernel driver detached"); } // Get BAR0 memory - let (base, len) = unsafe { tag.get_bar_mem(0) } - .ok_or(SysError::ENOENT)?; + let (base, len) = unsafe { tag.get_bar_mem(0) }.ok_or(SysError::ENOENT)?; let mut proc = process(); let virt_addr = proc.vm.find_free_area(0, len); diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index 130fd19..37187c5 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -1,14 +1,14 @@ //! Syscalls for file system -use core::mem::size_of; -use core::cmp::min; use core::cell::UnsafeCell; +use core::cmp::min; +use core::mem::size_of; use rcore_fs::vfs::Timespec; +use crate::drivers::SOCKET_ACTIVITY; use crate::fs::*; use crate::memory::MemorySet; use crate::sync::Condvar; -use crate::drivers::SOCKET_ACTIVITY; use super::*; @@ -22,7 +22,7 @@ pub fn sys_read(fd: usize, base: *mut u8, len: usize) -> SysResult { match proc.files.get(&fd) { Some(FileLike::File(_)) => sys_read_file(&mut proc, fd, base, len), Some(FileLike::Socket(_)) => sys_read_socket(&mut proc, fd, base, len), - None => Err(SysError::EINVAL) + None => Err(SysError::EINVAL), } } @@ -37,12 +37,15 @@ pub fn sys_write(fd: usize, base: *const u8, len: usize) -> SysResult { match proc.files.get(&fd) { Some(FileLike::File(_)) => sys_write_file(&mut proc, fd, base, len), Some(FileLike::Socket(_)) => sys_write_socket(&mut proc, fd, base, len), - None => Err(SysError::EINVAL) + None => Err(SysError::EINVAL), } } pub fn sys_pread(fd: usize, base: *mut u8, len: usize, offset: usize) -> SysResult { - info!("pread: fd: {}, base: {:?}, len: {}, offset: {}", fd, base, len, offset); + info!( + "pread: fd: {}, base: {:?}, len: {}, offset: {}", + fd, base, len, offset + ); let mut proc = process(); proc.vm.check_write_array(base, len)?; @@ -52,7 +55,10 @@ pub fn sys_pread(fd: usize, base: *mut u8, len: usize, offset: usize) -> SysResu } pub fn sys_pwrite(fd: usize, base: *const u8, len: usize, offset: usize) -> SysResult { - info!("pwrite: fd: {}, base: {:?}, len: {}, offset: {}", fd, base, len, offset); + info!( + "pwrite: fd: {}, base: {:?}, len: {}, offset: {}", + fd, base, len, offset + ); let mut proc = process(); proc.vm.check_read_array(base, len)?; @@ -74,7 +80,10 @@ pub fn sys_write_file(proc: &mut Process, fd: usize, base: *const u8, len: usize } pub fn sys_poll(ufds: *mut PollFd, nfds: usize, timeout_msecs: usize) -> SysResult { - info!("poll: ufds: {:?}, nfds: {}, timeout_msecs: {:#x}", ufds, nfds, timeout_msecs); + info!( + "poll: ufds: {:?}, nfds: {}, timeout_msecs: {:#x}", + ufds, nfds, timeout_msecs + ); let proc = process(); proc.vm.check_write_array(ufds, nfds)?; @@ -100,7 +109,7 @@ pub fn sys_poll(ufds: *mut PollFd, nfds: usize, timeout_msecs: usize) -> SysResu poll.revents = poll.revents | PE::IN; events = events + 1; } - }, + } Some(FileLike::Socket(wrapper)) => { let (input, output, err) = poll_socket(&wrapper); if err { @@ -143,7 +152,7 @@ const MAX_FDSET_SIZE: usize = 1024 / FD_PER_ITEM; struct FdSet { addr: *mut u32, nfds: usize, - saved: [u32; MAX_FDSET_SIZE] + saved: [u32; MAX_FDSET_SIZE], } impl FdSet { @@ -157,7 +166,7 @@ impl FdSet { if len > MAX_FDSET_SIZE { return Err(SysError::EINVAL); } - let slice = unsafe {slice::from_raw_parts_mut(addr, len)}; + let slice = unsafe { slice::from_raw_parts_mut(addr, len) }; // save the fdset, and clear it for i in 0..len { @@ -166,11 +175,7 @@ impl FdSet { } } - Ok(FdSet { - addr, - nfds, - saved - }) + Ok(FdSet { addr, nfds, saved }) } /// Try to set fd in `FdSet` @@ -196,8 +201,17 @@ impl FdSet { } } -pub fn sys_select(nfds: usize, read: *mut u32, write: *mut u32, err: *mut u32, timeout: *const TimeVal) -> SysResult { - info!("select: nfds: {}, read: {:?}, write: {:?}, err: {:?}, timeout: {:?}", nfds, read, write, err, timeout); +pub fn sys_select( + nfds: usize, + read: *mut u32, + write: *mut u32, + err: *mut u32, + timeout: *const TimeVal, +) -> SysResult { + info!( + "select: nfds: {}, read: {:?}, write: {:?}, err: {:?}, timeout: {:?}", + nfds, read, write, err, timeout + ); let proc = process(); let mut read_fds = FdSet::new(&proc.vm, read, nfds)?; @@ -222,23 +236,23 @@ pub fn sys_select(nfds: usize, read: *mut u32, write: *mut u32, err: *mut u32, t FileLike::File(_) => { // FIXME: assume it is stdin for now if STDIN.can_read() { - if read_fds.is_set(*fd){ + if read_fds.is_set(*fd) { read_fds.set(*fd); events = events + 1; } } - }, + } FileLike::Socket(wrapper) => { let (input, output, err) = poll_socket(&wrapper); - if err && err_fds.is_set(*fd){ + if err && err_fds.is_set(*fd) { err_fds.set(*fd); events = events + 1; } - if input && read_fds.is_set(*fd){ + if input && read_fds.is_set(*fd) { read_fds.set(*fd); events = events + 1; } - if output && write_fds.is_set(*fd){ + if output && write_fds.is_set(*fd) { write_fds.set(*fd); events = events + 1; } @@ -268,7 +282,10 @@ pub fn sys_select(nfds: usize, read: *mut u32, write: *mut u32, err: *mut u32, t } pub fn sys_readv(fd: usize, iov_ptr: *const IoVec, iov_count: usize) -> SysResult { - info!("readv: fd: {}, iov: {:?}, count: {}", fd, iov_ptr, iov_count); + info!( + "readv: fd: {}, iov: {:?}, count: {}", + fd, iov_ptr, iov_count + ); let mut proc = process(); let mut iovs = IoVecs::check_and_new(iov_ptr, iov_count, &proc.vm, true)?; @@ -282,7 +299,10 @@ pub fn sys_readv(fd: usize, iov_ptr: *const IoVec, iov_count: usize) -> SysResul } pub fn sys_writev(fd: usize, iov_ptr: *const IoVec, iov_count: usize) -> SysResult { - info!("writev: fd: {}, iov: {:?}, count: {}", fd, iov_ptr, iov_count); + info!( + "writev: fd: {}, iov: {:?}, count: {}", + fd, iov_ptr, iov_count + ); let mut proc = process(); let iovs = IoVecs::check_and_new(iov_ptr, iov_count, &proc.vm, false)?; @@ -292,7 +312,7 @@ pub fn sys_writev(fd: usize, iov_ptr: *const IoVec, iov_count: usize) -> SysResu match proc.files.get(&fd) { Some(FileLike::File(_)) => sys_write_file(&mut proc, fd, buf.as_ptr(), len), Some(FileLike::Socket(_)) => sys_write_socket(&mut proc, fd, buf.as_ptr(), len), - None => Err(SysError::EINVAL) + None => Err(SysError::EINVAL), } } @@ -306,53 +326,55 @@ pub fn sys_openat(dir_fd: usize, path: *const u8, flags: usize, mode: usize) -> let mut proc = process(); let path = unsafe { proc.vm.check_and_clone_cstr(path)? }; let flags = OpenFlags::from_bits_truncate(flags); - info!("openat: dir_fd: {}, path: {:?}, flags: {:?}, mode: {:#o}", dir_fd as isize, path, flags, mode); - - let inode = - if dir_fd == AT_FDCWD { - // from process cwd - if flags.contains(OpenFlags::CREATE) { - let (dir_path, file_name) = split_path(&path); - // relative to cwd - let dir_inode = proc.lookup_inode(dir_path)?; - match dir_inode.find(file_name) { - Ok(file_inode) => { - if flags.contains(OpenFlags::EXCLUSIVE) { - return Err(SysError::EEXIST); - } - file_inode - }, - Err(FsError::EntryNotFound) => { - dir_inode.create(file_name, FileType::File, mode as u32)? - } - Err(e) => return Err(SysError::from(e)), + info!( + "openat: dir_fd: {}, path: {:?}, flags: {:?}, mode: {:#o}", + dir_fd as isize, path, flags, mode + ); + + let inode = if dir_fd == AT_FDCWD { + // from process cwd + if flags.contains(OpenFlags::CREATE) { + let (dir_path, file_name) = split_path(&path); + // relative to cwd + let dir_inode = proc.lookup_inode(dir_path)?; + match dir_inode.find(file_name) { + Ok(file_inode) => { + if flags.contains(OpenFlags::EXCLUSIVE) { + return Err(SysError::EEXIST); } - } else { - proc.lookup_inode(&path)? + file_inode + } + Err(FsError::EntryNotFound) => { + dir_inode.create(file_name, FileType::File, mode as u32)? + } + Err(e) => return Err(SysError::from(e)), } } else { - // relative to dir_fd - let dir_file = proc.get_file(dir_fd)?; - if flags.contains(OpenFlags::CREATE) { - let (dir_path, file_name) = split_path(&path); - // relative to cwd - let dir_inode = dir_file.lookup_follow(dir_path, FOLLOW_MAX_DEPTH)?; - match dir_inode.find(file_name) { - Ok(file_inode) => { - if flags.contains(OpenFlags::EXCLUSIVE) { - return Err(SysError::EEXIST); - } - file_inode - }, - Err(FsError::EntryNotFound) => { - dir_inode.create(file_name, FileType::File, mode as u32)? - } - Err(e) => return Err(SysError::from(e)), + proc.lookup_inode(&path)? + } + } else { + // relative to dir_fd + let dir_file = proc.get_file(dir_fd)?; + if flags.contains(OpenFlags::CREATE) { + let (dir_path, file_name) = split_path(&path); + // relative to cwd + let dir_inode = dir_file.lookup_follow(dir_path, FOLLOW_MAX_DEPTH)?; + match dir_inode.find(file_name) { + Ok(file_inode) => { + if flags.contains(OpenFlags::EXCLUSIVE) { + return Err(SysError::EEXIST); } - } else { - dir_file.lookup_follow(&path, FOLLOW_MAX_DEPTH)? + file_inode + } + Err(FsError::EntryNotFound) => { + dir_inode.create(file_name, FileType::File, mode as u32)? + } + Err(e) => return Err(SysError::from(e)), } - }; + } else { + dir_file.lookup_follow(&path, FOLLOW_MAX_DEPTH)? + } + }; let fd = proc.get_free_fd(); @@ -390,9 +412,7 @@ pub fn sys_getcwd(buf: *mut u8, len: usize) -> SysResult { if proc.cwd.len() + 1 > len { return Err(SysError::ERANGE); } - unsafe { - util::write_cstr(buf, &proc.cwd) - } + unsafe { util::write_cstr(buf, &proc.cwd) } Ok(buf as usize) } @@ -408,7 +428,9 @@ pub fn sys_fstat(fd: usize, stat_ptr: *mut Stat) -> SysResult { let file = proc.get_file(fd)?; let stat = Stat::from(file.metadata()?); // TODO: handle symlink - unsafe { stat_ptr.write(stat); } + unsafe { + stat_ptr.write(stat); + } Ok(0) } @@ -420,7 +442,9 @@ pub fn sys_lstat(path: *const u8, stat_ptr: *mut Stat) -> SysResult { let inode = proc.lookup_inode(&path)?; let stat = Stat::from(inode.metadata()?); - unsafe { stat_ptr.write(stat); } + unsafe { + stat_ptr.write(stat); + } Ok(0) } @@ -483,7 +507,10 @@ pub fn sys_ftruncate(fd: usize, len: usize) -> SysResult { } pub fn sys_getdents64(fd: usize, buf: *mut LinuxDirent64, buf_size: usize) -> SysResult { - info!("getdents64: fd: {}, ptr: {:?}, buf_size: {}", fd, buf, buf_size); + info!( + "getdents64: fd: {}, ptr: {:?}, buf_size: {}", + fd, buf, buf_size + ); let mut proc = process(); proc.vm.check_write_array(buf as *mut u8, buf_size)?; let file = proc.get_file(fd)?; @@ -499,7 +526,9 @@ pub fn sys_getdents64(fd: usize, buf: *mut LinuxDirent64, buf_size: usize) -> Sy }?; // TODO: get ino from dirent let ok = writer.try_write(0, DirentType::from_type(&info.type_).bits(), &name); - if !ok { break; } + if !ok { + break; + } } Ok(writer.written_size) } @@ -515,12 +544,12 @@ pub fn sys_dup2(fd1: usize, fd2: usize) -> SysResult { let new_file = FileLike::File(file.clone()); proc.files.insert(fd2, new_file); Ok(fd2) - }, + } Some(FileLike::Socket(wrapper)) => { let new_wrapper = wrapper.clone(); sys_dup2_socket(&mut proc, new_wrapper, fd2) - }, - None => Err(SysError::EINVAL) + } + None => Err(SysError::EINVAL), } } @@ -552,23 +581,33 @@ pub fn sys_rename(oldpath: *const u8, newpath: *const u8) -> SysResult { sys_renameat(AT_FDCWD, oldpath, AT_FDCWD, newpath) } -pub fn sys_renameat(olddirfd: usize, oldpath: *const u8, newdirfd: usize, newpath: *const u8) -> SysResult { +pub fn sys_renameat( + olddirfd: usize, + oldpath: *const u8, + newdirfd: usize, + newpath: *const u8, +) -> SysResult { let mut proc = process(); let oldpath = unsafe { proc.vm.check_and_clone_cstr(oldpath)? }; let newpath = unsafe { proc.vm.check_and_clone_cstr(newpath)? }; - info!("renameat: olddirfd: {}, oldpath: {:?}, newdirfd: {}, newpath: {:?}", olddirfd, oldpath, newdirfd, newpath); + info!( + "renameat: olddirfd: {}, oldpath: {:?}, newdirfd: {}, newpath: {:?}", + olddirfd, oldpath, newdirfd, newpath + ); let (old_dir_path, old_file_name) = split_path(&oldpath); let (new_dir_path, new_file_name) = split_path(&newpath); let old_dir_inode = if olddirfd == AT_FDCWD { proc.lookup_inode(old_dir_path)? } else { - proc.get_file(olddirfd)?.lookup_follow(old_dir_path, FOLLOW_MAX_DEPTH)? + proc.get_file(olddirfd)? + .lookup_follow(old_dir_path, FOLLOW_MAX_DEPTH)? }; let new_dir_inode = if newdirfd == AT_FDCWD { proc.lookup_inode(new_dir_path)? } else { - proc.get_file(newdirfd)?.lookup_follow(new_dir_path, FOLLOW_MAX_DEPTH)? + proc.get_file(newdirfd)? + .lookup_follow(new_dir_path, FOLLOW_MAX_DEPTH)? }; old_dir_inode.move_(old_file_name, &new_dir_inode, new_file_name)?; Ok(0) @@ -640,10 +679,30 @@ pub fn sys_pipe(fds: *mut u32) -> SysResult { let (read, write) = Pipe::create_pair(); let read_fd = proc.get_free_fd(); - proc.files.insert(read_fd, FileLike::File(FileHandle::new(Arc::new(read), OpenOptions { read: true, write: false, append: false }))); + proc.files.insert( + read_fd, + FileLike::File(FileHandle::new( + Arc::new(read), + OpenOptions { + read: true, + write: false, + append: false, + }, + )), + ); let write_fd = proc.get_free_fd(); - proc.files.insert(write_fd, FileLike::File(FileHandle::new(Arc::new(write), OpenOptions { read: false, write: true, append: false }))); + proc.files.insert( + write_fd, + FileLike::File(FileHandle::new( + Arc::new(write), + OpenOptions { + read: false, + write: true, + append: false, + }, + )), + ); unsafe { *fds = read_fd as u32; @@ -661,12 +720,15 @@ pub fn sys_sync() -> SysResult { } pub fn sys_sendfile(out_fd: usize, in_fd: usize, offset: *mut usize, count: usize) -> SysResult { - info!("sendfile: out: {}, in: {}, offset: {:?}, count: {}", out_fd, in_fd, offset, count); + info!( + "sendfile: out: {}, in: {}, offset: {:?}, count: {}", + out_fd, in_fd, offset, count + ); let proc = process(); // We know it's save, pacify the borrow checker let proc_cell = UnsafeCell::new(proc); - let proc_in = unsafe {&mut *proc_cell.get()}; - let proc_out = unsafe {&mut *proc_cell.get()}; + let proc_in = unsafe { &mut *proc_cell.get() }; + let proc_out = unsafe { &mut *proc_cell.get() }; //let in_file: &mut FileHandle = unsafe { &mut *UnsafeCell::new(proc.get_file(in_fd)?).get() }; //let out_file: &mut FileHandle = unsafe { &mut *UnsafeCell::new(proc.get_file(out_fd)?).get() }; let in_file = proc_in.get_file(in_fd)?; @@ -693,11 +755,9 @@ pub fn sys_sendfile(out_fd: usize, in_fd: usize, offset: *mut usize, count: usiz } return Ok(bytes_read); } else { - let proc_mem = unsafe {&mut *proc_cell.get()}; + let proc_mem = unsafe { &mut *proc_cell.get() }; proc_mem.vm.check_read_ptr(offset)?; - let mut read_offset = unsafe { - *offset - }; + let mut read_offset = unsafe { *offset }; // read from specified offset and write new offset back let mut bytes_read = 0; while bytes_read < count { @@ -726,16 +786,19 @@ pub fn sys_sendfile(out_fd: usize, in_fd: usize, offset: *mut usize, count: usiz impl Process { pub fn get_file(&mut self, fd: usize) -> Result<&mut FileHandle, SysError> { - self.files.get_mut(&fd).ok_or(SysError::EBADF).and_then(|f| { - match f { + self.files + .get_mut(&fd) + .ok_or(SysError::EBADF) + .and_then(|f| match f { FileLike::File(file) => Ok(file), - _ => Err(SysError::EBADF) - } - }) + _ => Err(SysError::EBADF), + }) } pub fn lookup_inode(&self, path: &str) -> Result, SysError> { debug!("lookup_inode: cwd {} path {}", self.cwd, path); - Ok(ROOT_INODE.lookup(&self.cwd)?.lookup_follow(path, FOLLOW_MAX_DEPTH)?) + Ok(ROOT_INODE + .lookup(&self.cwd)? + .lookup_follow(path, FOLLOW_MAX_DEPTH)?) } } @@ -1058,7 +1121,7 @@ impl From for Stat { atime: info.atime, mtime: info.mtime, ctime: info.ctime, - _pad0: 0 + _pad0: 0, } } @@ -1079,7 +1142,7 @@ impl From for Stat { mtime: info.mtime, ctime: info.ctime, __pad: 0, - __pad2: 0 + __pad2: 0, } } } @@ -1102,7 +1165,12 @@ pub struct IoVec { struct IoVecs(Vec<&'static mut [u8]>); impl IoVecs { - fn check_and_new(iov_ptr: *const IoVec, iov_count: usize, vm: &MemorySet, readv: bool) -> Result { + fn check_and_new( + iov_ptr: *const IoVec, + iov_count: usize, + vm: &MemorySet, + readv: bool, + ) -> Result { vm.check_read_array(iov_ptr, iov_count)?; let iovs = unsafe { slice::from_raw_parts(iov_ptr, iov_count) }.to_vec(); // check all bufs in iov @@ -1116,7 +1184,10 @@ impl IoVecs { } } } - let slices = iovs.iter().map(|iov| unsafe { slice::from_raw_parts_mut(iov.base, iov.len as usize) }).collect(); + let slices = iovs + .iter() + .map(|iov| unsafe { slice::from_raw_parts_mut(iov.base, iov.len as usize) }) + .collect(); Ok(IoVecs(slices)) } @@ -1148,7 +1219,9 @@ impl IoVecs { let total_len = self.0.iter().map(|slice| slice.len()).sum::(); let mut buf = Vec::with_capacity(total_len); if set_len { - unsafe { buf.set_len(total_len); } + unsafe { + buf.set_len(total_len); + } } buf } diff --git a/kernel/src/syscall/mem.rs b/kernel/src/syscall/mem.rs index 2566995..1c5bee9 100644 --- a/kernel/src/syscall/mem.rs +++ b/kernel/src/syscall/mem.rs @@ -1,4 +1,4 @@ -use rcore_memory::memory_set::handler::{Delay, ByFrame}; +use rcore_memory::memory_set::handler::{ByFrame, Delay}; use rcore_memory::memory_set::MemoryAttr; use rcore_memory::paging::PageTable; use rcore_memory::Page; @@ -85,7 +85,10 @@ pub fn sys_mprotect(addr: usize, len: usize, prot: usize) -> SysResult { // FIXME: properly set the attribute of the area // now some mut ptr check is fault - let memory_area = proc.vm.iter().find(|area| area.is_overlap_with(addr, addr + len)); + let memory_area = proc + .vm + .iter() + .find(|area| area.is_overlap_with(addr, addr + len)); if memory_area.is_none() { return Err(SysError::ENOMEM); } diff --git a/kernel/src/syscall/misc.rs b/kernel/src/syscall/misc.rs index cb8df7d..a3924ed 100644 --- a/kernel/src/syscall/misc.rs +++ b/kernel/src/syscall/misc.rs @@ -1,7 +1,7 @@ use super::*; +use crate::arch::cpu; use core::mem::size_of; use core::sync::atomic::{AtomicI32, Ordering}; -use crate::arch::cpu; pub fn sys_arch_prctl(code: i32, addr: usize, tf: &mut TrapFrame) -> SysResult { const ARCH_SET_FS: i32 = 0x1002; @@ -22,8 +22,7 @@ pub fn sys_uname(buf: *mut u8) -> SysResult { let offset = 65; let strings = ["rCore", "orz", "0.1.0", "1", "machine", "domain"]; let proc = process(); - proc.vm - .check_write_array(buf, strings.len() * offset)?; + proc.vm.check_write_array(buf, strings.len() * offset)?; for i in 0..strings.len() { unsafe { @@ -39,8 +38,7 @@ pub fn sys_sched_getaffinity(pid: usize, size: usize, mask: *mut u32) -> SysResu pid, size, mask ); let proc = process(); - proc.vm - .check_write_array(mask, size / size_of::())?; + proc.vm.check_write_array(mask, size / size_of::())?; // we only have 4 cpu at most. // so just set it. @@ -75,9 +73,7 @@ pub fn sys_futex(uaddr: usize, op: u32, val: i32, timeout: *const TimeSpec) -> S if uaddr % size_of::() != 0 { return Err(SysError::EINVAL); } - process() - .vm - .check_write_ptr(uaddr as *mut AtomicI32)?; + process().vm.check_write_ptr(uaddr as *mut AtomicI32)?; let atomic = unsafe { &mut *(uaddr as *mut AtomicI32) }; let _timeout = if timeout.is_null() { None @@ -112,7 +108,6 @@ pub fn sys_futex(uaddr: usize, op: u32, val: i32, timeout: *const TimeSpec) -> S } } - const LINUX_REBOOT_CMD_HALT: u32 = 0xcdef0123; pub fn sys_reboot(_magic: u32, magic2: u32, cmd: u32, _arg: *const u8) -> SysResult { // we will skip verifying magic diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 4bfe201..cfd6b3a 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -1,35 +1,35 @@ //! System call use alloc::{string::String, sync::Arc, vec::Vec}; -use core::{slice, str, fmt}; +use core::{fmt, slice, str}; use bitflags::bitflags; -use rcore_memory::VMError; use rcore_fs::vfs::{FileType, FsError, INode, Metadata}; +use rcore_memory::VMError; +use crate::arch::cpu; use crate::arch::interrupt::TrapFrame; -use crate::sync::Condvar; +use crate::arch::syscall::*; use crate::process::*; +use crate::sync::Condvar; use crate::thread; use crate::util; -use crate::arch::cpu; -use crate::arch::syscall::*; +use self::custom::*; use self::fs::*; use self::mem::*; +use self::misc::*; +use self::net::*; use self::proc::*; use self::time::*; -use self::net::*; -use self::misc::*; -use self::custom::*; +mod custom; mod fs; mod mem; +mod misc; +mod net; mod proc; mod time; -mod net; -mod misc; -mod custom; /// System call dispatcher // This #[deny(unreachable_patterns)] checks if each match arm is defined @@ -37,9 +37,7 @@ mod custom; #[deny(unreachable_patterns)] pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { let cid = cpu::id(); - let pid = { - process().pid.clone() - }; + let pid = { process().pid.clone() }; let tid = processor().tid(); if !pid.is_init() { // we trust pid 0 process @@ -97,10 +95,24 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { SYS_SOCKET => sys_socket(args[0], args[1], args[2]), SYS_CONNECT => sys_connect(args[0], args[1] as *const SockAddr, args[2]), SYS_ACCEPT => sys_accept(args[0], args[1] as *mut SockAddr, args[2] as *mut u32), - SYS_SENDTO => sys_sendto(args[0], args[1] as *const u8, args[2], args[3], args[4] as *const SockAddr, args[5]), - SYS_RECVFROM => sys_recvfrom(args[0], args[1] as *mut u8, args[2], args[3], args[4] as *mut SockAddr, args[5] as *mut u32), -// SYS_SENDMSG => sys_sendmsg(), -// SYS_RECVMSG => sys_recvmsg(), + SYS_SENDTO => sys_sendto( + args[0], + args[1] as *const u8, + args[2], + args[3], + args[4] as *const SockAddr, + args[5], + ), + SYS_RECVFROM => sys_recvfrom( + args[0], + args[1] as *mut u8, + args[2], + args[3], + args[4] as *mut SockAddr, + args[5] as *mut u32, + ), + // SYS_SENDMSG => sys_sendmsg(), + // SYS_RECVMSG => sys_recvmsg(), SYS_SHUTDOWN => sys_shutdown(args[0], args[1]), SYS_BIND => sys_bind(args[0], args[1] as *const SockAddr, args[2]), // 50 @@ -108,9 +120,27 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { SYS_GETSOCKNAME => sys_getsockname(args[0], args[1] as *mut SockAddr, args[2] as *mut u32), SYS_GETPEERNAME => sys_getpeername(args[0], args[1] as *mut SockAddr, args[2] as *mut u32), SYS_SETSOCKOPT => sys_setsockopt(args[0], args[1], args[2], args[3] as *const u8, args[4]), - SYS_GETSOCKOPT => sys_getsockopt(args[0], args[1], args[2], args[3] as *mut u8, args[4] as *mut u32), - SYS_CLONE => sys_clone(args[0], args[1], args[2] as *mut u32, args[3] as *mut u32, args[4], tf), - SYS_EXECVE => sys_exec(args[0] as *const u8, args[1] as *const *const u8, args[2] as *const *const u8, tf), + SYS_GETSOCKOPT => sys_getsockopt( + args[0], + args[1], + args[2], + args[3] as *mut u8, + args[4] as *mut u32, + ), + SYS_CLONE => sys_clone( + args[0], + args[1], + args[2] as *mut u32, + args[3] as *mut u32, + args[4], + tf, + ), + SYS_EXECVE => sys_exec( + args[0] as *const u8, + args[1] as *const *const u8, + args[2] as *const *const u8, + tf, + ), // 60 SYS_EXIT => sys_exit(args[0] as usize), SYS_WAIT4 => sys_wait4(args[0] as isize, args[1] as *mut i32), // TODO: wait4 @@ -140,7 +170,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { Ok(0o777) } SYS_GETTIMEOFDAY => sys_gettimeofday(args[0] as *mut TimeVal, args[1] as *const u8), -// SYS_GETRLIMIT => sys_getrlimit(), + // SYS_GETRLIMIT => sys_getrlimit(), SYS_GETRUSAGE => sys_getrusage(args[0], args[1] as *mut RUsage), SYS_SYSINFO => sys_sysinfo(args[0] as *mut SysInfo), SYS_GETUID => { @@ -182,7 +212,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { Err(SysError::EACCES) } SYS_SETPRIORITY => sys_set_priority(args[0]), -// SYS_SETRLIMIT => sys_setrlimit(), + // SYS_SETRLIMIT => sys_setrlimit(), SYS_SYNC => sys_sync(), SYS_MOUNT => { warn!("mount is unimplemented"); @@ -192,9 +222,19 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { warn!("umount2 is unimplemented"); Err(SysError::EACCES) } - SYS_REBOOT => sys_reboot(args[0] as u32, args[1] as u32, args[2] as u32, args[3] as *const u8), + SYS_REBOOT => sys_reboot( + args[0] as u32, + args[1] as u32, + args[2] as u32, + args[3] as *const u8, + ), SYS_GETTID => sys_gettid(), - SYS_FUTEX => sys_futex(args[0], args[1] as u32, args[2] as i32, args[3] as *const TimeSpec), + SYS_FUTEX => sys_futex( + args[0], + args[1] as u32, + args[2] as i32, + args[3] as *const TimeSpec, + ), SYS_SCHED_GETAFFINITY => sys_sched_getaffinity(args[0], args[1], args[2] as *mut u32), SYS_GETDENTS64 => sys_getdents64(args[0], args[1] as *mut LinuxDirent64, args[2]), SYS_SET_TID_ADDRESS => { @@ -205,12 +245,12 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { SYS_EXIT_GROUP => sys_exit_group(args[0]), SYS_OPENAT => sys_openat(args[0], args[1] as *const u8, args[2], args[3]), // TODO: handle `dfd` SYS_MKDIRAT => sys_mkdir(args[1] as *const u8, args[2]), // TODO: handle `dfd` -// SYS_MKNODAT => sys_mknod(), + // SYS_MKNODAT => sys_mknod(), // 260 SYS_FCHOWNAT => { warn!("sys_fchownat is unimplemented"); Ok(0) - }, + } SYS_NEWFSTATAT => sys_stat(args[1] as *const u8, args[2] as *mut Stat), // TODO: handle `dfd`, `flag` SYS_UNLINKAT => sys_unlink(args[1] as *const u8), // TODO: handle `dfd`, `flag` SYS_RENAMEAT => sys_renameat(args[0], args[1] as *const u8, args[2], args[3] as *const u8), // TODO: handle `olddfd`, `newdfd` @@ -253,7 +293,10 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { }; if !pid.is_init() { // we trust pid 0 process - debug!("{}:{}:{} syscall id {} ret with {:x?}", cid, pid, tid, id, ret); + debug!( + "{}:{}:{} syscall id {} ret with {:x?}", + cid, pid, tid, id, ret + ); } match ret { Ok(code) => code as isize, @@ -270,9 +313,15 @@ fn x86_64_syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> Option sys_poll(args[0] as *mut PollFd, args[1], args[2]), SYS_ACCESS => sys_access(args[0] as *const u8, args[1]), SYS_PIPE => sys_pipe(args[0] as *mut u32), - SYS_SELECT => sys_select(args[0], args[1] as *mut u32, args[2] as *mut u32, args[3] as *mut u32, args[4] as *const TimeVal), + SYS_SELECT => sys_select( + args[0], + args[1] as *mut u32, + args[2] as *mut u32, + args[3] as *mut u32, + args[4] as *const TimeVal, + ), SYS_DUP2 => sys_dup2(args[0], args[1]), -// SYS_PAUSE => sys_pause(), + // SYS_PAUSE => sys_pause(), SYS_FORK => sys_fork(tf), // use fork for vfork SYS_VFORK => sys_fork(tf), @@ -363,7 +412,9 @@ pub enum SysError { impl fmt::Display for SysError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use self::SysError::*; - write!(f, "{}", + write!( + f, + "{}", match self { EPERM => "Operation not permitted", ENOENT => "No such file or directory", @@ -424,7 +475,6 @@ impl From for SysError { } } - const SPIN_WAIT_TIMES: usize = 100; pub fn spin_and_wait(condvars: &[&Condvar], mut action: impl FnMut() -> Option) -> T { @@ -440,4 +490,3 @@ pub fn spin_and_wait(condvars: &[&Condvar], mut action: impl FnMut() -> Optio Condvar::wait_any(&condvars); } } - diff --git a/kernel/src/syscall/proc.rs b/kernel/src/syscall/proc.rs index 7182150..2c4b909 100644 --- a/kernel/src/syscall/proc.rs +++ b/kernel/src/syscall/proc.rs @@ -16,9 +16,18 @@ pub fn sys_fork(tf: &TrapFrame) -> SysResult { /// and thread pointer will be set to `newtls`. /// The child tid will be stored at both `parent_tid` and `child_tid`. /// This is partially implemented for musl only. -pub fn sys_clone(flags: usize, newsp: usize, parent_tid: *mut u32, child_tid: *mut u32, newtls: usize, tf: &TrapFrame) -> SysResult { - info!("clone: flags: {:#x}, newsp: {:#x}, parent_tid: {:?}, child_tid: {:?}, newtls: {:#x}", - flags, newsp, parent_tid, child_tid, newtls); +pub fn sys_clone( + flags: usize, + newsp: usize, + parent_tid: *mut u32, + child_tid: *mut u32, + newtls: usize, + tf: &TrapFrame, +) -> SysResult { + info!( + "clone: flags: {:#x}, newsp: {:#x}, parent_tid: {:?}, child_tid: {:?}, newtls: {:#x}", + flags, newsp, parent_tid, child_tid, newtls + ); if flags == 0x4111 { warn!("sys_clone is calling sys_fork instead, ignoring other args"); return sys_fork(tf); @@ -64,41 +73,61 @@ pub fn sys_wait4(pid: isize, wstatus: *mut i32) -> SysResult { let mut proc = process(); // check child_exit_code let find = match target { - WaitFor::AnyChild => proc.child_exit_code - .iter().next().map(|(&pid, &code)| (pid, code)), - WaitFor::Pid(pid) => proc.child_exit_code - .get(&pid).map(|&code| (pid, code)), + WaitFor::AnyChild => proc + .child_exit_code + .iter() + .next() + .map(|(&pid, &code)| (pid, code)), + WaitFor::Pid(pid) => proc.child_exit_code.get(&pid).map(|&code| (pid, code)), }; // if found, return if let Some((pid, exit_code)) = find { proc.child_exit_code.remove(&pid); if !wstatus.is_null() { - unsafe { wstatus.write(exit_code as i32); } + unsafe { + wstatus.write(exit_code as i32); + } } return Ok(pid); } // if not, check pid - let children: Vec<_> = proc.children.iter() + let children: Vec<_> = proc + .children + .iter() .filter_map(|weak| weak.upgrade()) .collect(); let invalid = match target { WaitFor::AnyChild => children.len() == 0, - WaitFor::Pid(pid) => children.iter().find(|p| p.lock().pid.get() == pid).is_none(), + WaitFor::Pid(pid) => children + .iter() + .find(|p| p.lock().pid.get() == pid) + .is_none(), }; if invalid { return Err(SysError::ECHILD); } - info!("wait: thread {} -> {:?}, sleep", thread::current().id(), target); + info!( + "wait: thread {} -> {:?}, sleep", + thread::current().id(), + target + ); let condvar = proc.child_exit.clone(); drop(proc); // must release lock of current process condvar._wait(); } } -pub fn sys_exec(name: *const u8, argv: *const *const u8, envp: *const *const u8, tf: &mut TrapFrame) -> SysResult { +pub fn sys_exec( + name: *const u8, + argv: *const *const u8, + envp: *const *const u8, + tf: &mut TrapFrame, +) -> SysResult { info!("exec: name: {:?}, argv: {:?} envp: {:?}", name, argv, envp); let proc = process(); - let _name = if name.is_null() { String::from("") } else { + let _name = if name.is_null() { + String::from("") + } else { unsafe { proc.vm.check_and_clone_cstr(name)? } }; @@ -129,7 +158,9 @@ pub fn sys_exec(name: *const u8, argv: *const *const u8, envp: *const *const u8, thread.proc.lock().clone_for_exec(&proc); // Activate new page table - unsafe { thread.proc.lock().vm.activate(); } + unsafe { + thread.proc.lock().vm.activate(); + } // Modify the TrapFrame *tf = unsafe { thread.context.get_init_tf() }; @@ -148,7 +179,12 @@ pub fn sys_yield() -> SysResult { /// Kill the process pub fn sys_kill(pid: usize, sig: usize) -> SysResult { - info!("kill: {} killed: {} with sig {}", thread::current().id(), pid, sig); + info!( + "kill: {} killed: {} with sig {}", + thread::current().id(), + pid, + sig + ); let current_pid = process().pid.get().clone(); if current_pid == pid { // killing myself @@ -223,7 +259,9 @@ pub fn sys_exit(exit_code: usize) -> ! { // it has memory access so we can't move it to Thread::drop? let clear_child_tid = current_thread().clear_child_tid; if clear_child_tid != 0 { - unsafe { (clear_child_tid as *mut u32).write(0); } + unsafe { + (clear_child_tid as *mut u32).write(0); + } let queue = process().get_futex(clear_child_tid); queue.notify_one(); } diff --git a/kernel/src/syscall/time.rs b/kernel/src/syscall/time.rs index 51d9666..2ae76d4 100644 --- a/kernel/src/syscall/time.rs +++ b/kernel/src/syscall/time.rs @@ -116,7 +116,7 @@ pub fn sys_time(time: *mut u64) -> SysResult { #[repr(C)] pub struct RUsage { utime: TimeVal, - stime: TimeVal + stime: TimeVal, } pub fn sys_getrusage(who: usize, rusage: *mut RUsage) -> SysResult { @@ -136,10 +136,8 @@ pub fn sys_getrusage(who: usize, rusage: *mut RUsage) -> SysResult { stime: TimeVal { sec: usec / USEC_PER_SEC, usec: usec % USEC_PER_SEC, - } - }; - unsafe { - *rusage = new_rusage + }, }; + unsafe { *rusage = new_rusage }; Ok(0) } diff --git a/kernel/src/trap.rs b/kernel/src/trap.rs index 6079eb5..037827a 100644 --- a/kernel/src/trap.rs +++ b/kernel/src/trap.rs @@ -1,17 +1,19 @@ -use crate::process::*; -use crate::arch::interrupt::TrapFrame; use crate::arch::cpu; +use crate::arch::interrupt::TrapFrame; +use crate::process::*; use log::*; pub static mut TICK: usize = 0; pub fn uptime_msec() -> usize { - unsafe {crate::trap::TICK / crate::consts::USEC_PER_TICK / 1000} + unsafe { crate::trap::TICK / crate::consts::USEC_PER_TICK / 1000 } } pub fn timer() { if cpu::id() == 0 { - unsafe { TICK += 1; } + unsafe { + TICK += 1; + } } processor().tick(); } @@ -33,4 +35,4 @@ pub fn serial(c: char) { } else { crate::fs::STDIN.push(c); } -} \ No newline at end of file +} diff --git a/kernel/src/util/escape_parser.rs b/kernel/src/util/escape_parser.rs index 5157237..0c42a97 100644 --- a/kernel/src/util/escape_parser.rs +++ b/kernel/src/util/escape_parser.rs @@ -1,9 +1,9 @@ //! ANSI escape sequences parser //! (ref: https://en.wikipedia.org/wiki/ANSI_escape_code) -use heapless::Vec; -use heapless::consts::U8; use super::color::ConsoleColor; +use heapless::consts::U8; +use heapless::Vec; #[repr(C)] #[derive(Debug, Clone, Copy, PartialEq)] @@ -44,7 +44,9 @@ impl CharacterAttribute { 27 => self.reverse = false, 29 => self.strikethrough = false, 30...37 | 90...97 => self.foreground = ConsoleColor::from_console_code(code).unwrap(), - 40...47 | 100...107 => self.background = ConsoleColor::from_console_code(code - 10).unwrap(), + 40...47 | 100...107 => { + self.background = ConsoleColor::from_console_code(code - 10).unwrap() + } _ => { /* unimplemented!() */ } } } diff --git a/kernel/src/util/mod.rs b/kernel/src/util/mod.rs index c36dc88..0c6df60 100644 --- a/kernel/src/util/mod.rs +++ b/kernel/src/util/mod.rs @@ -3,7 +3,7 @@ pub mod escape_parser; /// Convert C string to Rust string pub unsafe fn from_cstr(s: *const u8) -> &'static str { - use core::{str, slice}; + use core::{slice, str}; let len = (0usize..).find(|&i| *s.add(i) == 0).unwrap(); str::from_utf8(slice::from_raw_parts(s, len)).unwrap() } From c2a90e2ab163812c727a5de397a47c7cb93c9576 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Wed, 27 Mar 2019 18:43:59 +0800 Subject: [PATCH 3/8] update dependencies --- crate/thread/Cargo.toml | 2 +- kernel/Cargo.lock | 30 +++++++++++++++--------------- kernel/Cargo.toml | 4 ++-- user | 2 +- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/crate/thread/Cargo.toml b/crate/thread/Cargo.toml index 20a00a0..e8aa1c3 100644 --- a/crate/thread/Cargo.toml +++ b/crate/thread/Cargo.toml @@ -8,4 +8,4 @@ edition = "2018" [dependencies] log = "0.4" spin = "0.5" -deque = { git = "https://github.com/wangrunji0408/deque.git", branch = "no_std" } \ No newline at end of file +deque = { git = "https://github.com/rcore-os/deque.git", branch = "no_std" } \ No newline at end of file diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index 33aa5a6..acfcfd6 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -109,7 +109,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cc" -version = "1.0.31" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -125,7 +125,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "deque" version = "0.3.2" -source = "git+https://github.com/wangrunji0408/deque.git?branch=no_std#907d03935b9badde1902d9c84d138872f34c6763" +source = "git+https://github.com/rcore-os/deque.git?branch=no_std#907d03935b9badde1902d9c84d138872f34c6763" [[package]] name = "device_tree" @@ -186,7 +186,7 @@ dependencies = [ [[package]] name = "isomorphic_drivers" version = "0.1.0" -source = "git+https://github.com/rcore-os/isomorphic_drivers#a564ac855887a823dac80529ec4138194583905d" +source = "git+https://github.com/rcore-os/isomorphic_drivers#836e91fca59e4f4eb86a1f10c246d9c8cb5d1fad" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -286,7 +286,7 @@ version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -302,7 +302,7 @@ dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "bootloader 0.4.0 (git+https://github.com/rcore-os/bootloader)", "buddy_system_allocator 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", "console-traits 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "device_tree 1.0.3 (git+https://github.com/rcore-os/device_tree-rs)", "heapless 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -312,8 +312,8 @@ dependencies = [ "once 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "pc-keyboard 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "raw-cpuid 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rcore-fs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?branch=sefs)", - "rcore-fs-sfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?branch=sefs)", + "rcore-fs 0.1.0 (git+https://github.com/rcore-os/rcore-fs)", + "rcore-fs-sfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs)", "rcore-memory 0.1.0", "rcore-thread 0.1.0", "riscv 0.5.0 (git+https://github.com/rcore-os/riscv)", @@ -328,16 +328,16 @@ dependencies = [ [[package]] name = "rcore-fs" version = "0.1.0" -source = "git+https://github.com/rcore-os/rcore-fs?branch=sefs#166616e5ade1a5c929f705fd1564ef0ea337ba72" +source = "git+https://github.com/rcore-os/rcore-fs#ff3dd7d157bfdfaa05f8228ebb80456799fe6b4d" [[package]] name = "rcore-fs-sfs" version = "0.1.0" -source = "git+https://github.com/rcore-os/rcore-fs?branch=sefs#166616e5ade1a5c929f705fd1564ef0ea337ba72" +source = "git+https://github.com/rcore-os/rcore-fs#ff3dd7d157bfdfaa05f8228ebb80456799fe6b4d" dependencies = [ "bitvec 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rcore-fs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?branch=sefs)", + "rcore-fs 0.1.0 (git+https://github.com/rcore-os/rcore-fs)", "spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "static_assertions 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -353,7 +353,7 @@ dependencies = [ name = "rcore-thread" version = "0.1.0" dependencies = [ - "deque 0.3.2 (git+https://github.com/wangrunji0408/deque.git?branch=no_std)", + "deque 0.3.2 (git+https://github.com/rcore-os/deque.git?branch=no_std)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -589,10 +589,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum bootloader 0.4.0 (git+https://github.com/rcore-os/bootloader)" = "" "checksum buddy_system_allocator 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2ed828f1e227d6e32b998d6375b67fd63ac5389d50b23f258ce151d22b6cc595" "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" -"checksum cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "c9ce8bb087aacff865633f0bd5aeaed910fe2fe55b55f4739527f2e023a2e53d" +"checksum cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ad0daef304fa0b4238f5f7ed7178774b43b06f6a9b6509f6642bef4ff1f7b9b2" "checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" "checksum console-traits 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f711b3d1d5c3f7ae7d6428901c0f3e5d5f5c800fcfac86bf0252e96373a2cec6" -"checksum deque 0.3.2 (git+https://github.com/wangrunji0408/deque.git?branch=no_std)" = "" +"checksum deque 0.3.2 (git+https://github.com/rcore-os/deque.git?branch=no_std)" = "" "checksum device_tree 1.0.3 (git+https://github.com/rcore-os/device_tree-rs)" = "" "checksum fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6c16d316ccdac21a4dd648e314e76facbbaf316e83ca137d0857a9c07419d0" "checksum font8x8 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b81d84c3c978af7d05d31a2198af4b9ba956d819d15d8f6d58fc150e33f8dc1f" @@ -616,8 +616,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" "checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" "checksum raw-cpuid 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "30a9d219c32c9132f7be513c18be77c9881c7107d2ab5569d205a6a0f0e6dc7d" -"checksum rcore-fs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?branch=sefs)" = "" -"checksum rcore-fs-sfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs?branch=sefs)" = "" +"checksum rcore-fs 0.1.0 (git+https://github.com/rcore-os/rcore-fs)" = "" +"checksum rcore-fs-sfs 0.1.0 (git+https://github.com/rcore-os/rcore-fs)" = "" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" "checksum register 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e10f31b6d2299e5620986ad9fcdd66463e125ad72af4f403f9aedf7592d5ccdb" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index aa60642..853fda1 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -51,8 +51,8 @@ smoltcp = { version = "0.5.0", default-features = false, features = ["alloc", "l bit-allocator = { path = "../crate/bit-allocator" } rcore-memory = { path = "../crate/memory" } rcore-thread = { path = "../crate/thread" } -rcore-fs = { git = "https://github.com/rcore-os/rcore-fs", branch = "sefs" } -rcore-fs-sfs = { git = "https://github.com/rcore-os/rcore-fs", branch = "sefs" } +rcore-fs = { git = "https://github.com/rcore-os/rcore-fs" } +rcore-fs-sfs = { git = "https://github.com/rcore-os/rcore-fs" } [target.'cfg(target_arch = "x86_64")'.dependencies] bootloader = { git = "https://github.com/rcore-os/bootloader" } diff --git a/user b/user index 96548d0..bf70c66 160000 --- a/user +++ b/user @@ -1 +1 @@ -Subproject commit 96548d046474f6ae0ba66da6cd832e1a52d12997 +Subproject commit bf70c66685de6c99e302ed10965e5c05fb8ae0e6 From 524865ebd8a265e502374a04dd8ff636d769c267 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Wed, 27 Mar 2019 21:39:44 +0800 Subject: [PATCH 4/8] Implement sys_prlimit64 for nginx --- kernel/src/syscall/misc.rs | 37 +++++++++++++++++++++++++++++++++++++ kernel/src/syscall/mod.rs | 11 ++++++----- user | 2 +- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/kernel/src/syscall/misc.rs b/kernel/src/syscall/misc.rs index a3924ed..110b041 100644 --- a/kernel/src/syscall/misc.rs +++ b/kernel/src/syscall/misc.rs @@ -135,3 +135,40 @@ pub struct SysInfo { freehigh: u64, mem_unit: u32, } + +const RLIMIT_NOFILE: usize = 7; + +pub fn sys_prlimit64( + pid: usize, + resource: usize, + new_limit: *const RLimit, + old_limit: *mut RLimit, +) -> SysResult { + let proc = process(); + info!( + "prlimit64: pid: {}, resource: {}, new_limit: {:x?}, old_limit: {:x?}", + pid, resource, new_limit, old_limit + ); + match resource { + RLIMIT_NOFILE => { + if !old_limit.is_null() { + proc.vm.check_write_ptr(old_limit)?; + unsafe { + *old_limit = RLimit { + cur: 1024, + max: 1024, + }; + } + } + Ok(0) + } + _ => Err(SysError::ENOSYS), + } +} + +#[repr(C)] +#[derive(Debug, Default)] +pub struct RLimit { + cur: u64, // soft limit + max: u64, // hard limit +} diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index cfd6b3a..b818fc1 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -269,11 +269,12 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { } SYS_DUP3 => sys_dup2(args[0], args[1]), // TODO: handle `flags` SYS_PIPE2 => sys_pipe(args[0] as *mut u32), // TODO: handle `flags` - SYS_PRLIMIT64 => { - warn!("sys_prlimit64 is unimplemented"); - Ok(0) - } - + SYS_PRLIMIT64 => sys_prlimit64( + args[0], + args[1], + args[2] as *const RLimit, + args[3] as *mut RLimit, + ), // custom temporary syscall SYS_MAP_PCI_DEVICE => sys_map_pci_device(args[0], args[1]), SYS_GET_PADDR => sys_get_paddr(args[0] as *const u64, args[1] as *mut u64, args[2]), diff --git a/user b/user index bf70c66..69febc9 160000 --- a/user +++ b/user @@ -1 +1 @@ -Subproject commit bf70c66685de6c99e302ed10965e5c05fb8ae0e6 +Subproject commit 69febc9fcc64df60329687b4f24b9b5309c99adf From 311cf104f9feb1d3ebc88e40e6027d1fd9241123 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Fri, 29 Mar 2019 13:14:08 +0800 Subject: [PATCH 5/8] Many minor fixes to allow gcc to run inside rCore. Add some syscalls, fix SEEK_* and enlarge the heap --- kernel/Cargo.lock | 4 ++-- kernel/Cargo.toml | 4 ++-- kernel/Makefile | 3 ++- kernel/src/arch/x86_64/memory.rs | 35 +++++++++++++++++++++++++++++++- kernel/src/arch/x86_64/paging.rs | 5 ++++- kernel/src/syscall/fs.rs | 6 +++--- kernel/src/syscall/misc.rs | 29 ++++++++++++++++++++++++++ kernel/src/syscall/mod.rs | 9 ++++++++ tools/addr2line.py | 3 ++- 9 files changed, 87 insertions(+), 11 deletions(-) diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index acfcfd6..1d22c8d 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -328,12 +328,12 @@ dependencies = [ [[package]] name = "rcore-fs" version = "0.1.0" -source = "git+https://github.com/rcore-os/rcore-fs#ff3dd7d157bfdfaa05f8228ebb80456799fe6b4d" +source = "git+https://github.com/rcore-os/rcore-fs#f8d7b06727b0a66091419b2dd6a15f620a7152af" [[package]] name = "rcore-fs-sfs" version = "0.1.0" -source = "git+https://github.com/rcore-os/rcore-fs#ff3dd7d157bfdfaa05f8228ebb80456799fe6b4d" +source = "git+https://github.com/rcore-os/rcore-fs#f8d7b06727b0a66091419b2dd6a15f620a7152af" dependencies = [ "bitvec 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 853fda1..63f4969 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -30,8 +30,8 @@ link_user = [] run_cmdline = [] [profile.dev] -# MUST >= 1 : Enable RVO to avoid stack overflow -opt-level = 1 +# MUST >= 2 : Enable RVO to avoid stack overflow +opt-level = 2 [dependencies] log = "0.4" diff --git a/kernel/Makefile b/kernel/Makefile index 6a82f38..f1c3281 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -68,6 +68,7 @@ qemu_opts += \ -drive format=raw,file=$(bootimage) \ -drive format=qcow2,file=$(SFSIMG),media=disk,cache=writeback \ -serial mon:stdio \ + -m 4G \ -device isa-debug-exit ifeq ($(pci_passthru), ) qemu_net_opts += \ @@ -307,4 +308,4 @@ endif .PHONY: addr2line: - @python3 ../tools/addr2line.py $(prefix)addr2line $(arch) + @python3 ../tools/addr2line.py $(prefix)addr2line $(arch) $(mode) diff --git a/kernel/src/arch/x86_64/memory.rs b/kernel/src/arch/x86_64/memory.rs index 822624f..b2570a9 100644 --- a/kernel/src/arch/x86_64/memory.rs +++ b/kernel/src/arch/x86_64/memory.rs @@ -2,7 +2,10 @@ use crate::consts::KERNEL_OFFSET; use bit_allocator::BitAlloc; // Depends on kernel use super::{BootInfo, MemoryRegionType}; -use crate::memory::{active_table, init_heap, FRAME_ALLOCATOR}; +use crate::memory::{active_table, init_heap, FRAME_ALLOCATOR, alloc_frame}; +use crate::HEAP_ALLOCATOR; +use rcore_memory::PAGE_SIZE; +use alloc::vec::Vec; use log::*; use once::*; use rcore_memory::paging::*; @@ -12,6 +15,7 @@ pub fn init(boot_info: &BootInfo) { init_frame_allocator(boot_info); init_device_vm_map(); init_heap(); + enlarge_heap(); info!("memory: init end"); } @@ -38,3 +42,32 @@ fn init_device_vm_map() { .map(KERNEL_OFFSET + 0xfee00000, 0xfee00000) .update(); } + +fn enlarge_heap() { + let mut page_table = active_table(); + let mut addrs = Vec::new(); + let va_offset = KERNEL_OFFSET + 0xe0000000; + for i in 0..16384 { + let page = alloc_frame().unwrap(); + let va = KERNEL_OFFSET + 0xe0000000 + page; + if let Some((ref mut addr, ref mut len)) = addrs.last_mut() { + if *addr - PAGE_SIZE == va { + *len += PAGE_SIZE; + *addr -= PAGE_SIZE; + continue; + } + } + addrs.push((va, PAGE_SIZE)); + } + for (addr, len) in addrs.into_iter() { + for va in (addr..(addr+len)).step_by(PAGE_SIZE) { + page_table.map(va, va - va_offset).update(); + } + info!("Adding {:#X} {:#X} to heap", addr, len); + unsafe { + HEAP_ALLOCATOR + .lock() + .init(addr, len); + } + } +} diff --git a/kernel/src/arch/x86_64/paging.rs b/kernel/src/arch/x86_64/paging.rs index 47a4058..fb45522 100644 --- a/kernel/src/arch/x86_64/paging.rs +++ b/kernel/src/arch/x86_64/paging.rs @@ -78,7 +78,10 @@ impl PageTable for ActivePageTable { } impl PageTableExt for ActivePageTable { - const TEMP_PAGE_ADDR: usize = KERNEL_OFFSET | 0xcafeb000; + // FIXME: the default value 0xcafebe000 is so low that allocation might overwrite it sometimes. + // However, putting it to KERNEL_OFFSET | 0xcafeb000 has unintended effects. + // Someone needs to reconsider this and use an ultimate solution. + // const TEMP_PAGE_ADDR: usize = KERNEL_OFFSET | 0xcafeb000; } impl ActivePageTable { diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index 37187c5..6f9ca29 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -1147,9 +1147,9 @@ impl From for Stat { } } -const SEEK_SET: u8 = 1; -const SEEK_CUR: u8 = 2; -const SEEK_END: u8 = 4; +const SEEK_SET: u8 = 0; +const SEEK_CUR: u8 = 1; +const SEEK_END: u8 = 2; #[derive(Debug, Copy, Clone)] #[repr(C)] diff --git a/kernel/src/syscall/misc.rs b/kernel/src/syscall/misc.rs index 110b041..fc6779f 100644 --- a/kernel/src/syscall/misc.rs +++ b/kernel/src/syscall/misc.rs @@ -2,6 +2,7 @@ use super::*; use crate::arch::cpu; use core::mem::size_of; use core::sync::atomic::{AtomicI32, Ordering}; +use crate::consts::USER_STACK_SIZE; pub fn sys_arch_prctl(code: i32, addr: usize, tf: &mut TrapFrame) -> SysResult { const ARCH_SET_FS: i32 = 0x1002; @@ -136,7 +137,10 @@ pub struct SysInfo { mem_unit: u32, } +const RLIMIT_STACK: usize = 3; +const RLIMIT_RSS: usize = 5; const RLIMIT_NOFILE: usize = 7; +const RLIMIT_AS: usize = 9; pub fn sys_prlimit64( pid: usize, @@ -150,6 +154,18 @@ pub fn sys_prlimit64( pid, resource, new_limit, old_limit ); match resource { + RLIMIT_STACK => { + if !old_limit.is_null() { + proc.vm.check_write_ptr(old_limit)?; + unsafe { + *old_limit = RLimit { + cur: USER_STACK_SIZE as u64, + max: USER_STACK_SIZE as u64, + }; + } + } + Ok(0) + } RLIMIT_NOFILE => { if !old_limit.is_null() { proc.vm.check_write_ptr(old_limit)?; @@ -161,6 +177,19 @@ pub fn sys_prlimit64( } } Ok(0) + }, + RLIMIT_RSS | RLIMIT_AS => { + if !old_limit.is_null() { + proc.vm.check_write_ptr(old_limit)?; + unsafe { + // 1GB + *old_limit = RLimit { + cur: 1024 * 1024 * 1024, + max: 1024 * 1024 * 1024, + }; + } + } + Ok(0) } _ => Err(SysError::ENOSYS), } diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index b818fc1..23e047d 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -161,6 +161,15 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { SYS_GETCWD => sys_getcwd(args[0] as *mut u8, args[1]), // 80 SYS_CHDIR => sys_chdir(args[0] as *const u8), + // 90 + SYS_CHMOD => { + warn!("sys_chmod is unimplemented"); + Ok(0) + } + SYS_FCHMOD => { + warn!("sys_fchmod is unimplemented"); + Ok(0) + } SYS_FCHOWN => { warn!("sys_fchown is unimplemented"); Ok(0) diff --git a/tools/addr2line.py b/tools/addr2line.py index fa84228..a7a1e79 100644 --- a/tools/addr2line.py +++ b/tools/addr2line.py @@ -7,12 +7,13 @@ print('Paste backtrace here, and then input EOF(Ctrl-D or Ctrl-Z) to get annotat lines = sys.stdin.readlines() addrline = sys.argv[1] arch = sys.argv[2] +mode = sys.argv[3] print('--------------------------------------') for line in lines: match = re.search('(#[0-9]+ )(0x[0-9A-F]+)( fp 0x[0-9A-F]+)', line) if match: addr = match.group(2) - process = subprocess.run([addrline, '-e', 'target/{0}/debug/rcore'.format(arch), '-f', '-C', addr], capture_output=True) + process = subprocess.run([addrline, '-e', 'target/{0}/{1}/rcore'.format(arch, mode), '-f', '-C', addr], capture_output=True) res = process.stdout.decode('utf-8') print('{0}{1}{3} {2}'.format(match.group(1), match.group(2), res.strip(), match.group(3))) else: From 1ffd44cde0b5193b10dcc57acd61d98738529dc4 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Fri, 29 Mar 2019 13:23:49 +0800 Subject: [PATCH 6/8] HUGE REFACTOR net module --- kernel/src/fs/file_like.rs | 40 ++ kernel/src/fs/mod.rs | 2 + kernel/src/net/structs.rs | 669 +++++++++++++++++++++++++--------- kernel/src/process/mod.rs | 6 +- kernel/src/process/structs.rs | 30 +- kernel/src/syscall/fs.rs | 198 +++++----- kernel/src/syscall/net.rs | 509 ++++---------------------- tools/.gitignore | 1 - 8 files changed, 716 insertions(+), 739 deletions(-) create mode 100644 kernel/src/fs/file_like.rs delete mode 100644 tools/.gitignore diff --git a/kernel/src/fs/file_like.rs b/kernel/src/fs/file_like.rs new file mode 100644 index 0000000..d765f2c --- /dev/null +++ b/kernel/src/fs/file_like.rs @@ -0,0 +1,40 @@ +use core::fmt; + +use super::FileHandle; +use crate::net::Socket; +use crate::syscall::SysResult; +use alloc::boxed::Box; + +// TODO: merge FileLike to FileHandle ? +// TODO: fix dup and remove Clone +#[derive(Clone)] +pub enum FileLike { + File(FileHandle), + Socket(Box), +} + +impl FileLike { + pub fn read(&mut self, buf: &mut [u8]) -> SysResult { + let len = match self { + FileLike::File(file) => file.read(buf)?, + FileLike::Socket(socket) => socket.read(buf).0?, + }; + Ok(len) + } + pub fn write(&mut self, buf: &[u8]) -> SysResult { + let len = match self { + FileLike::File(file) => file.write(buf)?, + FileLike::Socket(socket) => socket.write(buf, None)?, + }; + Ok(len) + } +} + +impl fmt::Debug for FileLike { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + FileLike::File(_) => write!(f, "File"), + FileLike::Socket(_) => write!(f, "Socket"), + } + } +} diff --git a/kernel/src/fs/mod.rs b/kernel/src/fs/mod.rs index cfcafaf..488dcb2 100644 --- a/kernel/src/fs/mod.rs +++ b/kernel/src/fs/mod.rs @@ -7,11 +7,13 @@ use rcore_fs_sfs::SimpleFileSystem; use crate::arch::driver::ide; pub use self::file::*; +pub use self::file_like::*; pub use self::pipe::Pipe; pub use self::stdio::{STDIN, STDOUT}; mod device; mod file; +mod file_like; mod pipe; mod stdio; diff --git a/kernel/src/net/structs.rs b/kernel/src/net/structs.rs index 0295e54..bc076fb 100644 --- a/kernel/src/net/structs.rs +++ b/kernel/src/net/structs.rs @@ -2,68 +2,87 @@ use crate::arch::rand; use crate::drivers::{NET_DRIVERS, SOCKET_ACTIVITY}; use crate::sync::SpinNoIrqLock as Mutex; use crate::syscall::*; -use alloc::sync::Arc; +use alloc::boxed::Box; use smoltcp::socket::*; use smoltcp::wire::*; +/// +pub trait Socket: Send + Sync { + fn read(&self, data: &mut [u8]) -> (SysResult, IpEndpoint); + fn write(&self, data: &[u8], sendto_endpoint: Option) -> SysResult; + fn poll(&self) -> (bool, bool, bool); // (in, out, err) + fn connect(&mut self, endpoint: IpEndpoint) -> SysResult; + fn bind(&mut self, endpoint: IpEndpoint) -> SysResult { + Err(SysError::EINVAL) + } + fn listen(&mut self) -> SysResult { + Err(SysError::EINVAL) + } + fn shutdown(&self) -> SysResult { + Err(SysError::EINVAL) + } + fn accept(&mut self) -> Result<(Box, IpEndpoint), SysError> { + Err(SysError::EINVAL) + } + fn endpoint(&self) -> Option { + None + } + fn remote_endpoint(&self) -> Option { + None + } + fn box_clone(&self) -> Box; +} + +impl Clone for Box { + fn clone(&self) -> Self { + self.box_clone() + } +} + lazy_static! { - pub static ref SOCKETS: Arc>> = - Arc::new(Mutex::new(SocketSet::new(vec![]))); + /// Global SocketSet in smoltcp. + /// + /// Because smoltcp is a single thread network stack, + /// every socket operation needs to lock this. + pub static ref SOCKETS: Mutex> = + Mutex::new(SocketSet::new(vec![])); } -#[derive(Clone, Debug)] +#[derive(Debug, Clone)] pub struct TcpSocketState { - pub local_endpoint: Option, // save local endpoint for bind() - pub is_listening: bool, + handle: GlobalSocketHandle, + local_endpoint: Option, // save local endpoint for bind() + is_listening: bool, } -#[derive(Clone, Debug)] +#[derive(Debug, Clone)] pub struct UdpSocketState { - pub remote_endpoint: Option, // remember remote endpoint for connect() + handle: GlobalSocketHandle, + remote_endpoint: Option, // remember remote endpoint for connect() } -#[derive(Clone, Debug)] -pub enum SocketType { - Raw, - Tcp(TcpSocketState), - Udp(UdpSocketState), - Icmp, +#[derive(Debug, Clone)] +pub struct RawSocketState { + handle: GlobalSocketHandle, } +/// A wrapper for `SocketHandle`. +/// Auto increase and decrease reference count on Clone and Drop. #[derive(Debug)] -pub struct SocketWrapper { - pub handle: SocketHandle, - pub socket_type: SocketType, -} - -pub fn get_ephemeral_port() -> u16 { - // TODO selects non-conflict high port - static mut EPHEMERAL_PORT: u16 = 0; - unsafe { - if EPHEMERAL_PORT == 0 { - EPHEMERAL_PORT = (49152 + rand::rand() % (65536 - 49152)) as u16; - } - if EPHEMERAL_PORT == 65535 { - EPHEMERAL_PORT = 49152; - } else { - EPHEMERAL_PORT = EPHEMERAL_PORT + 1; - } - EPHEMERAL_PORT - } -} +struct GlobalSocketHandle(SocketHandle); -/// Safety: call this without SOCKETS locked -pub fn poll_ifaces() { - for iface in NET_DRIVERS.read().iter() { - iface.poll(); +impl Clone for GlobalSocketHandle { + fn clone(&self) -> Self { + SOCKETS.lock().retain(self.0); + Self(self.0) } } -impl Drop for SocketWrapper { +impl Drop for GlobalSocketHandle { fn drop(&mut self) { let mut sockets = SOCKETS.lock(); - sockets.release(self.handle); + sockets.release(self.0); sockets.prune(); // send FIN immediately when applicable @@ -72,97 +91,61 @@ impl Drop for SocketWrapper { } } -impl SocketWrapper { - pub fn write(&self, data: &[u8], sendto_endpoint: Option) -> SysResult { - if let SocketType::Raw = self.socket_type { - if let Some(endpoint) = sendto_endpoint { - // temporary solution - let iface = &*(NET_DRIVERS.read()[0]); - let v4_src = iface.ipv4_address().unwrap(); - let mut sockets = SOCKETS.lock(); - let mut socket = sockets.get::(self.handle); - - if let IpAddress::Ipv4(v4_dst) = endpoint.addr { - let len = data.len(); - // using 20-byte IPv4 header - let mut buffer = vec![0u8; len + 20]; - let mut packet = Ipv4Packet::new_unchecked(&mut buffer); - packet.set_version(4); - packet.set_header_len(20); - packet.set_total_len((20 + len) as u16); - packet.set_protocol(socket.ip_protocol().into()); - packet.set_src_addr(v4_src); - packet.set_dst_addr(v4_dst); - let payload = packet.payload_mut(); - payload.copy_from_slice(data); - packet.fill_checksum(); - - socket.send_slice(&buffer).unwrap(); +impl TcpSocketState { + pub fn new() -> Self { + let rx_buffer = TcpSocketBuffer::new(vec![0; TCP_RECVBUF]); + let tx_buffer = TcpSocketBuffer::new(vec![0; TCP_SENDBUF]); + let socket = TcpSocket::new(rx_buffer, tx_buffer); + let handle = GlobalSocketHandle(SOCKETS.lock().add(socket)); - // avoid deadlock - drop(socket); - drop(sockets); - iface.poll(); + TcpSocketState { + handle, + local_endpoint: None, + is_listening: false, + } + } +} - Ok(len) - } else { - unimplemented!("ip type") - } - } else { - Err(SysError::ENOTCONN) - } - } else if let SocketType::Tcp(_) = self.socket_type { +impl Socket for TcpSocketState { + fn read(&self, data: &mut [u8]) -> (SysResult, IpEndpoint) { + spin_and_wait(&[&SOCKET_ACTIVITY], move || { + poll_ifaces(); let mut sockets = SOCKETS.lock(); - let mut socket = sockets.get::(self.handle); + let mut socket = sockets.get::(self.handle.0); if socket.is_open() { - if socket.can_send() { - match socket.send_slice(&data) { - Ok(size) => { - // avoid deadlock - drop(socket); - drop(sockets); + if let Ok(size) = socket.recv_slice(data) { + if size > 0 { + let endpoint = socket.remote_endpoint(); + // avoid deadlock + drop(socket); + drop(sockets); - poll_ifaces(); - Ok(size) - } - Err(err) => Err(SysError::ENOBUFS), + poll_ifaces(); + return Some((Ok(size), endpoint)); } - } else { - Err(SysError::ENOBUFS) } } else { - Err(SysError::ENOTCONN) + return Some((Err(SysError::ENOTCONN), IpEndpoint::UNSPECIFIED)); } - } else if let SocketType::Udp(ref state) = self.socket_type { - let remote_endpoint = { - if let Some(ref endpoint) = sendto_endpoint { - endpoint - } else if let Some(ref endpoint) = state.remote_endpoint { - endpoint - } else { - return Err(SysError::ENOTCONN); - } - }; - let mut sockets = SOCKETS.lock(); - let mut socket = sockets.get::(self.handle); + None + }) + } - if socket.endpoint().port == 0 { - let temp_port = get_ephemeral_port(); - socket - .bind(IpEndpoint::new(IpAddress::Unspecified, temp_port)) - .unwrap(); - } + fn write(&self, data: &[u8], sendto_endpoint: Option) -> SysResult { + let mut sockets = SOCKETS.lock(); + let mut socket = sockets.get::(self.handle.0); + if socket.is_open() { if socket.can_send() { - match socket.send_slice(&data, *remote_endpoint) { - Ok(()) => { + match socket.send_slice(&data) { + Ok(size) => { // avoid deadlock drop(socket); drop(sockets); poll_ifaces(); - Ok(data.len()) + Ok(size) } Err(err) => Err(SysError::ENOBUFS), } @@ -170,81 +153,433 @@ impl SocketWrapper { Err(SysError::ENOBUFS) } } else { - unimplemented!("socket type") + Err(SysError::ENOTCONN) } } - pub fn read(&self, data: &mut [u8]) -> (SysResult, IpEndpoint) { - if let SocketType::Raw = self.socket_type { - loop { - let mut sockets = SOCKETS.lock(); - let mut socket = sockets.get::(self.handle); + fn poll(&self) -> (bool, bool, bool) { + let mut sockets = SOCKETS.lock(); + let socket = sockets.get::(self.handle.0); - if let Ok(size) = socket.recv_slice(data) { - let packet = Ipv4Packet::new_unchecked(data); - - return ( - Ok(size), - IpEndpoint { - addr: IpAddress::Ipv4(packet.src_addr()), - port: 0, - }, - ); - } + let (mut input, mut output, mut err) = (false, false, false); + if self.is_listening && socket.is_active() { + // a new connection + input = true; + } else if !socket.is_open() { + err = true; + } else { + if socket.can_recv() { + input = true; + } + if socket.can_send() { + output = true; + } + } + (input, output, err) + } + + fn connect(&mut self, endpoint: IpEndpoint) -> SysResult { + let mut sockets = SOCKETS.lock(); + let mut socket = sockets.get::(self.handle.0); + let temp_port = get_ephemeral_port(); + + match socket.connect(endpoint, temp_port) { + Ok(()) => { // avoid deadlock drop(socket); drop(sockets); - SOCKET_ACTIVITY._wait() - } - } else if let SocketType::Tcp(_) = self.socket_type { - spin_and_wait(&[&SOCKET_ACTIVITY], move || { - poll_ifaces(); - let mut sockets = SOCKETS.lock(); - let mut socket = sockets.get::(self.handle); - - if socket.is_open() { - if let Ok(size) = socket.recv_slice(data) { - if size > 0 { - let endpoint = socket.remote_endpoint(); - // avoid deadlock + + // wait for connection result + loop { + poll_ifaces(); + + let mut sockets = SOCKETS.lock(); + let socket = sockets.get::(self.handle.0); + match socket.state() { + TcpState::SynSent => { + // still connecting drop(socket); drop(sockets); - - poll_ifaces(); - return Some((Ok(size), endpoint)); + debug!("poll for connection wait"); + SOCKET_ACTIVITY._wait(); + } + TcpState::Established => { + break Ok(0); + } + _ => { + break Err(SysError::ECONNREFUSED); } } - } else { - return Some((Err(SysError::ENOTCONN), IpEndpoint::UNSPECIFIED)); } + } + Err(_) => Err(SysError::ENOBUFS), + } + } + + fn bind(&mut self, mut endpoint: IpEndpoint) -> SysResult { + if endpoint.port == 0 { + endpoint.port = get_ephemeral_port(); + } + self.local_endpoint = Some(endpoint); + self.is_listening = false; + Ok(0) + } + + fn listen(&mut self) -> SysResult { + if self.is_listening { + // it is ok to listen twice + return Ok(0); + } + let local_endpoint = self.local_endpoint.ok_or(SysError::EINVAL)?; + let mut sockets = SOCKETS.lock(); + let mut socket = sockets.get::(self.handle.0); + + info!("socket listening on {:?}", local_endpoint); + if socket.is_listening() { + return Ok(0); + } + match socket.listen(local_endpoint) { + Ok(()) => { + self.is_listening = true; + Ok(0) + } + Err(_) => Err(SysError::EINVAL), + } + } + + fn shutdown(&self) -> SysResult { + let mut sockets = SOCKETS.lock(); + let mut socket = sockets.get::(self.handle.0); + socket.close(); + Ok(0) + } + + fn accept(&mut self) -> Result<(Box, IpEndpoint), SysError> { + let endpoint = self.local_endpoint.ok_or(SysError::EINVAL)?; + loop { + let mut sockets = SOCKETS.lock(); + let socket = sockets.get::(self.handle.0); + + if socket.is_active() { + let remote_endpoint = socket.remote_endpoint(); + drop(socket); + + let new_socket = { + let rx_buffer = TcpSocketBuffer::new(vec![0; TCP_RECVBUF]); + let tx_buffer = TcpSocketBuffer::new(vec![0; TCP_SENDBUF]); + let mut socket = TcpSocket::new(rx_buffer, tx_buffer); + socket.listen(endpoint).unwrap(); + let new_handle = GlobalSocketHandle(sockets.add(socket)); + let old_handle = ::core::mem::replace(&mut self.handle, new_handle); + + Box::new(TcpSocketState { + handle: old_handle, + local_endpoint: self.local_endpoint, + is_listening: false, + }) + }; + + drop(sockets); + poll_ifaces(); + return Ok((new_socket, remote_endpoint)); + } + + // avoid deadlock + drop(socket); + drop(sockets); + SOCKET_ACTIVITY._wait(); + } + } + + fn endpoint(&self) -> Option { + self.local_endpoint.clone().or_else(|| { + let mut sockets = SOCKETS.lock(); + let socket = sockets.get::(self.handle.0); + let endpoint = socket.local_endpoint(); + if endpoint.port != 0 { + Some(endpoint) + } else { None - }) - } else if let SocketType::Udp(ref state) = self.socket_type { - loop { - let mut sockets = SOCKETS.lock(); - let mut socket = sockets.get::(self.handle); - - if socket.is_open() { - if let Ok((size, remote_endpoint)) = socket.recv_slice(data) { - let endpoint = remote_endpoint; - // avoid deadlock - drop(socket); - drop(sockets); + } + }) + } - poll_ifaces(); - return (Ok(size), endpoint); - } - } else { - return (Err(SysError::ENOTCONN), IpEndpoint::UNSPECIFIED); + fn remote_endpoint(&self) -> Option { + let mut sockets = SOCKETS.lock(); + let socket = sockets.get::(self.handle.0); + if socket.is_open() { + Some(socket.remote_endpoint()) + } else { + None + } + } + + fn box_clone(&self) -> Box { + Box::new(self.clone()) + } +} + +impl UdpSocketState { + pub fn new() -> Self { + let rx_buffer = UdpSocketBuffer::new( + vec![UdpPacketMetadata::EMPTY; UDP_METADATA_BUF], + vec![0; UDP_RECVBUF], + ); + let tx_buffer = UdpSocketBuffer::new( + vec![UdpPacketMetadata::EMPTY; UDP_METADATA_BUF], + vec![0; UDP_SENDBUF], + ); + let socket = UdpSocket::new(rx_buffer, tx_buffer); + let handle = GlobalSocketHandle(SOCKETS.lock().add(socket)); + + UdpSocketState { + handle, + remote_endpoint: None, + } + } +} + +impl Socket for UdpSocketState { + fn read(&self, data: &mut [u8]) -> (SysResult, IpEndpoint) { + loop { + let mut sockets = SOCKETS.lock(); + let mut socket = sockets.get::(self.handle.0); + + if socket.is_open() { + if let Ok((size, remote_endpoint)) = socket.recv_slice(data) { + let endpoint = remote_endpoint; + // avoid deadlock + drop(socket); + drop(sockets); + + poll_ifaces(); + return (Ok(size), endpoint); + } + } else { + return (Err(SysError::ENOTCONN), IpEndpoint::UNSPECIFIED); + } + + // avoid deadlock + drop(socket); + SOCKET_ACTIVITY._wait() + } + } + + fn write(&self, data: &[u8], sendto_endpoint: Option) -> SysResult { + let remote_endpoint = { + if let Some(ref endpoint) = sendto_endpoint { + endpoint + } else if let Some(ref endpoint) = self.remote_endpoint { + endpoint + } else { + return Err(SysError::ENOTCONN); + } + }; + let mut sockets = SOCKETS.lock(); + let mut socket = sockets.get::(self.handle.0); + + if socket.endpoint().port == 0 { + let temp_port = get_ephemeral_port(); + socket + .bind(IpEndpoint::new(IpAddress::Unspecified, temp_port)) + .unwrap(); + } + + if socket.can_send() { + match socket.send_slice(&data, *remote_endpoint) { + Ok(()) => { + // avoid deadlock + drop(socket); + drop(sockets); + + poll_ifaces(); + Ok(data.len()) } + Err(err) => Err(SysError::ENOBUFS), + } + } else { + Err(SysError::ENOBUFS) + } + } + + fn poll(&self) -> (bool, bool, bool) { + let mut sockets = SOCKETS.lock(); + let socket = sockets.get::(self.handle.0); + + let (mut input, mut output, err) = (false, false, false); + if socket.can_recv() { + input = true; + } + if socket.can_send() { + output = true; + } + (input, output, err) + } + + fn connect(&mut self, endpoint: IpEndpoint) -> SysResult { + self.remote_endpoint = Some(endpoint); + Ok(0) + } + + fn bind(&mut self, endpoint: IpEndpoint) -> SysResult { + let mut sockets = SOCKETS.lock(); + let mut socket = sockets.get::(self.handle.0); + match socket.bind(endpoint) { + Ok(()) => Ok(0), + Err(_) => Err(SysError::EINVAL), + } + } + + fn endpoint(&self) -> Option { + let mut sockets = SOCKETS.lock(); + let socket = sockets.get::(self.handle.0); + let endpoint = socket.endpoint(); + if endpoint.port != 0 { + Some(endpoint) + } else { + None + } + } + + fn remote_endpoint(&self) -> Option { + self.remote_endpoint.clone() + } + + fn box_clone(&self) -> Box { + Box::new(self.clone()) + } +} + +impl RawSocketState { + pub fn new(protocol: u8) -> Self { + let rx_buffer = RawSocketBuffer::new( + vec![RawPacketMetadata::EMPTY; RAW_METADATA_BUF], + vec![0; RAW_RECVBUF], + ); + let tx_buffer = RawSocketBuffer::new( + vec![RawPacketMetadata::EMPTY; RAW_METADATA_BUF], + vec![0; RAW_SENDBUF], + ); + let socket = RawSocket::new( + IpVersion::Ipv4, + IpProtocol::from(protocol), + rx_buffer, + tx_buffer, + ); + let handle = GlobalSocketHandle(SOCKETS.lock().add(socket)); + + RawSocketState { handle } + } +} + +impl Socket for RawSocketState { + fn read(&self, data: &mut [u8]) -> (SysResult, IpEndpoint) { + loop { + let mut sockets = SOCKETS.lock(); + let mut socket = sockets.get::(self.handle.0); + + if let Ok(size) = socket.recv_slice(data) { + let packet = Ipv4Packet::new_unchecked(data); + + return ( + Ok(size), + IpEndpoint { + addr: IpAddress::Ipv4(packet.src_addr()), + port: 0, + }, + ); + } + + // avoid deadlock + drop(socket); + drop(sockets); + SOCKET_ACTIVITY._wait() + } + } + + fn write(&self, data: &[u8], sendto_endpoint: Option) -> SysResult { + if let Some(endpoint) = sendto_endpoint { + // temporary solution + let iface = &*(NET_DRIVERS.read()[0]); + let v4_src = iface.ipv4_address().unwrap(); + let mut sockets = SOCKETS.lock(); + let mut socket = sockets.get::(self.handle.0); + + if let IpAddress::Ipv4(v4_dst) = endpoint.addr { + let len = data.len(); + // using 20-byte IPv4 header + let mut buffer = vec![0u8; len + 20]; + let mut packet = Ipv4Packet::new_unchecked(&mut buffer); + packet.set_version(4); + packet.set_header_len(20); + packet.set_total_len((20 + len) as u16); + packet.set_protocol(socket.ip_protocol().into()); + packet.set_src_addr(v4_src); + packet.set_dst_addr(v4_dst); + let payload = packet.payload_mut(); + payload.copy_from_slice(data); + packet.fill_checksum(); + + socket.send_slice(&buffer).unwrap(); // avoid deadlock drop(socket); - SOCKET_ACTIVITY._wait() + drop(sockets); + iface.poll(); + + Ok(len) + } else { + unimplemented!("ip type") } } else { - unimplemented!("socket type") + Err(SysError::ENOTCONN) } } + + fn poll(&self) -> (bool, bool, bool) { + unimplemented!() + } + + fn connect(&mut self, _endpoint: IpEndpoint) -> SysResult { + unimplemented!() + } + + fn box_clone(&self) -> Box { + Box::new(self.clone()) + } } + +fn get_ephemeral_port() -> u16 { + // TODO selects non-conflict high port + static mut EPHEMERAL_PORT: u16 = 0; + unsafe { + if EPHEMERAL_PORT == 0 { + EPHEMERAL_PORT = (49152 + rand::rand() % (65536 - 49152)) as u16; + } + if EPHEMERAL_PORT == 65535 { + EPHEMERAL_PORT = 49152; + } else { + EPHEMERAL_PORT = EPHEMERAL_PORT + 1; + } + EPHEMERAL_PORT + } +} + +/// Safety: call this without SOCKETS locked +fn poll_ifaces() { + for iface in NET_DRIVERS.read().iter() { + iface.poll(); + } +} + +pub const TCP_SENDBUF: usize = 512 * 1024; // 512K +pub const TCP_RECVBUF: usize = 512 * 1024; // 512K + +const UDP_METADATA_BUF: usize = 1024; +const UDP_SENDBUF: usize = 64 * 1024; // 64K +const UDP_RECVBUF: usize = 64 * 1024; // 64K + +const RAW_METADATA_BUF: usize = 2; +const RAW_SENDBUF: usize = 2 * 1024; // 2K +const RAW_RECVBUF: usize = 2 * 1024; // 2K diff --git a/kernel/src/process/mod.rs b/kernel/src/process/mod.rs index e476fd4..ff69345 100644 --- a/kernel/src/process/mod.rs +++ b/kernel/src/process/mod.rs @@ -1,10 +1,10 @@ pub use self::structs::*; use crate::arch::cpu; use crate::consts::{MAX_CPU_NUM, MAX_PROCESS_NUM}; +use crate::sync::{MutexGuard, SpinNoIrq}; use alloc::{boxed::Box, sync::Arc}; use log::*; pub use rcore_thread::*; -use spin::MutexGuard; mod abi; pub mod structs; @@ -37,13 +37,13 @@ static PROCESSORS: [Processor; MAX_CPU_NUM] = [ ]; /// Get current process -pub fn process() -> MutexGuard<'static, Process> { +pub fn process() -> MutexGuard<'static, Process, SpinNoIrq> { current_thread().proc.lock() } /// Get current process, ignoring its lock /// Only use this when necessary -pub unsafe fn process_unsafe() -> MutexGuard<'static, Process> { +pub unsafe fn process_unsafe() -> MutexGuard<'static, Process, SpinNoIrq> { let thread = current_thread(); thread.proc.force_unlock(); thread.proc.lock() diff --git a/kernel/src/process/structs.rs b/kernel/src/process/structs.rs index 038eee0..93820af 100644 --- a/kernel/src/process/structs.rs +++ b/kernel/src/process/structs.rs @@ -5,7 +5,7 @@ use core::str; use log::*; use rcore_memory::PAGE_SIZE; use rcore_thread::Tid; -use spin::{Mutex, RwLock}; +use spin::RwLock; use xmas_elf::{ header, program::{Flags, SegmentData, Type}, @@ -13,10 +13,10 @@ use xmas_elf::{ }; use crate::arch::interrupt::{Context, TrapFrame}; -use crate::fs::{FileHandle, INodeExt, OpenOptions, FOLLOW_MAX_DEPTH}; +use crate::fs::{FileHandle, FileLike, INodeExt, OpenOptions, FOLLOW_MAX_DEPTH}; use crate::memory::{ByFrame, GlobalFrameAlloc, KernelStack, MemoryAttr, MemorySet}; -use crate::net::{SocketWrapper, SOCKETS}; -use crate::sync::Condvar; +use crate::net::{Socket, SOCKETS}; +use crate::sync::{Condvar, SpinNoIrqLock as Mutex}; use super::abi::{self, ProcInitInfo}; @@ -30,21 +30,6 @@ pub struct Thread { pub proc: Arc>, } -#[derive(Clone)] -pub enum FileLike { - File(FileHandle), - Socket(SocketWrapper), -} - -impl fmt::Debug for FileLike { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - FileLike::File(_) => write!(f, "File"), - FileLike::Socket(wrapper) => write!(f, "{:?}", wrapper), - } - } -} - /// Pid type /// For strong type separation #[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] @@ -343,13 +328,6 @@ impl Thread { debug!("fork: temporary copy data!"); let kstack = KernelStack::new(); - let mut sockets = SOCKETS.lock(); - for (_fd, file) in files.iter() { - if let FileLike::Socket(wrapper) = file { - sockets.retain(wrapper.handle); - } - } - Box::new(Thread { context: unsafe { Context::new_fork(tf, kstack.top(), vm.token()) }, kstack, diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index 37187c5..e0c19da 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -19,11 +19,10 @@ pub fn sys_read(fd: usize, base: *mut u8, len: usize) -> SysResult { info!("read: fd: {}, base: {:?}, len: {:#x}", fd, base, len); } proc.vm.check_write_array(base, len)?; - match proc.files.get(&fd) { - Some(FileLike::File(_)) => sys_read_file(&mut proc, fd, base, len), - Some(FileLike::Socket(_)) => sys_read_socket(&mut proc, fd, base, len), - None => Err(SysError::EINVAL), - } + let slice = unsafe { slice::from_raw_parts_mut(base, len) }; + let file_like = proc.get_file_like(fd)?; + let len = file_like.read(slice)?; + Ok(len) } pub fn sys_write(fd: usize, base: *const u8, len: usize) -> SysResult { @@ -33,12 +32,10 @@ pub fn sys_write(fd: usize, base: *const u8, len: usize) -> SysResult { info!("write: fd: {}, base: {:?}, len: {:#x}", fd, base, len); } proc.vm.check_read_array(base, len)?; - - match proc.files.get(&fd) { - Some(FileLike::File(_)) => sys_write_file(&mut proc, fd, base, len), - Some(FileLike::Socket(_)) => sys_write_socket(&mut proc, fd, base, len), - None => Err(SysError::EINVAL), - } + let slice = unsafe { slice::from_raw_parts(base, len) }; + let file_like = proc.get_file_like(fd)?; + let len = file_like.write(slice)?; + Ok(len) } pub fn sys_pread(fd: usize, base: *mut u8, len: usize, offset: usize) -> SysResult { @@ -67,18 +64,6 @@ pub fn sys_pwrite(fd: usize, base: *const u8, len: usize, offset: usize) -> SysR Ok(len) } -pub fn sys_read_file(proc: &mut Process, fd: usize, base: *mut u8, len: usize) -> SysResult { - let slice = unsafe { slice::from_raw_parts_mut(base, len) }; - let len = proc.get_file(fd)?.read(slice)?; - Ok(len) -} - -pub fn sys_write_file(proc: &mut Process, fd: usize, base: *const u8, len: usize) -> SysResult { - let slice = unsafe { slice::from_raw_parts(base, len) }; - let len = proc.get_file(fd)?.write(slice)?; - Ok(len) -} - pub fn sys_poll(ufds: *mut PollFd, nfds: usize, timeout_msecs: usize) -> SysResult { info!( "poll: ufds: {:?}, nfds: {}, timeout_msecs: {:#x}", @@ -110,8 +95,8 @@ pub fn sys_poll(ufds: *mut PollFd, nfds: usize, timeout_msecs: usize) -> SysResu events = events + 1; } } - Some(FileLike::Socket(wrapper)) => { - let (input, output, err) = poll_socket(&wrapper); + Some(FileLike::Socket(socket)) => { + let (input, output, err) = socket.poll(); if err { poll.revents = poll.revents | PE::HUP; events = events + 1; @@ -146,61 +131,6 @@ pub fn sys_poll(ufds: *mut PollFd, nfds: usize, timeout_msecs: usize) -> SysResu } } -const FD_PER_ITEM: usize = 8 * size_of::(); -const MAX_FDSET_SIZE: usize = 1024 / FD_PER_ITEM; - -struct FdSet { - addr: *mut u32, - nfds: usize, - saved: [u32; MAX_FDSET_SIZE], -} - -impl FdSet { - /// Initialize a `FdSet` from pointer and number of fds - /// Check if the array is large enough - fn new(vm: &MemorySet, addr: *mut u32, nfds: usize) -> Result { - let mut saved = [0u32; MAX_FDSET_SIZE]; - if addr as usize != 0 { - let len = (nfds + FD_PER_ITEM - 1) / FD_PER_ITEM; - vm.check_write_array(addr, len)?; - if len > MAX_FDSET_SIZE { - return Err(SysError::EINVAL); - } - let slice = unsafe { slice::from_raw_parts_mut(addr, len) }; - - // save the fdset, and clear it - for i in 0..len { - saved[i] = slice[i]; - slice[i] = 0; - } - } - - Ok(FdSet { addr, nfds, saved }) - } - - /// Try to set fd in `FdSet` - /// Return true when `FdSet` is valid, and false when `FdSet` is bad (i.e. null pointer) - /// Fd should be less than nfds - fn set(&mut self, fd: usize) -> bool { - if self.addr as usize != 0 { - assert!(fd < self.nfds); - unsafe { - *self.addr.add(fd / 8 / size_of::()) |= 1 << (fd % (8 * size_of::())); - } - true - } else { - false - } - } - - /// Check to see fd is see in original `FdSet` - /// Fd should be less than nfds - fn is_set(&mut self, fd: usize) -> bool { - assert!(fd < self.nfds); - self.saved[fd / 8 / size_of::()] & (1 << (fd % (8 * size_of::()))) != 0 - } -} - pub fn sys_select( nfds: usize, read: *mut u32, @@ -230,9 +160,9 @@ pub fn sys_select( loop { let proc = process(); let mut events = 0; - for (fd, file) in proc.files.iter() { + for (fd, file_like) in proc.files.iter() { if *fd < nfds { - match file { + match file_like { FileLike::File(_) => { // FIXME: assume it is stdin for now if STDIN.can_read() { @@ -242,8 +172,8 @@ pub fn sys_select( } } } - FileLike::Socket(wrapper) => { - let (input, output, err) = poll_socket(&wrapper); + FileLike::Socket(socket) => { + let (input, output, err) = socket.poll(); if err && err_fds.is_set(*fd) { err_fds.set(*fd); events = events + 1; @@ -290,9 +220,9 @@ pub fn sys_readv(fd: usize, iov_ptr: *const IoVec, iov_count: usize) -> SysResul let mut iovs = IoVecs::check_and_new(iov_ptr, iov_count, &proc.vm, true)?; // read all data to a buf - let mut file = proc.get_file(fd)?; + let file_like = proc.get_file_like(fd)?; let mut buf = iovs.new_buf(true); - let len = file.read(buf.as_mut_slice())?; + let len = file_like.read(buf.as_mut_slice())?; // copy data to user iovs.write_all_from_slice(&buf[..len]); Ok(len) @@ -309,15 +239,11 @@ pub fn sys_writev(fd: usize, iov_ptr: *const IoVec, iov_count: usize) -> SysResu let buf = iovs.read_all_to_vec(); let len = buf.len(); - match proc.files.get(&fd) { - Some(FileLike::File(_)) => sys_write_file(&mut proc, fd, buf.as_ptr(), len), - Some(FileLike::Socket(_)) => sys_write_socket(&mut proc, fd, buf.as_ptr(), len), - None => Err(SysError::EINVAL), - } + let file_like = proc.get_file_like(fd)?; + let len = file_like.write(buf.as_slice())?; + Ok(len) } -const AT_FDCWD: usize = -100isize as usize; - pub fn sys_open(path: *const u8, flags: usize, mode: usize) -> SysResult { sys_openat(AT_FDCWD, path, flags, mode) } @@ -539,18 +465,9 @@ pub fn sys_dup2(fd1: usize, fd2: usize) -> SysResult { // close fd2 first if it is opened proc.files.remove(&fd2); - match proc.files.get(&fd1) { - Some(FileLike::File(file)) => { - let new_file = FileLike::File(file.clone()); - proc.files.insert(fd2, new_file); - Ok(fd2) - } - Some(FileLike::Socket(wrapper)) => { - let new_wrapper = wrapper.clone(); - sys_dup2_socket(&mut proc, new_wrapper, fd2) - } - None => Err(SysError::EINVAL), - } + let file_like = proc.get_file_like(fd1)?.clone(); + proc.files.insert(fd2, file_like); + Ok(fd2) } pub fn sys_chdir(path: *const u8) -> SysResult { @@ -785,14 +702,14 @@ pub fn sys_sendfile(out_fd: usize, in_fd: usize, offset: *mut usize, count: usiz } impl Process { + pub fn get_file_like(&mut self, fd: usize) -> Result<&mut FileLike, SysError> { + self.files.get_mut(&fd).ok_or(SysError::EBADF) + } pub fn get_file(&mut self, fd: usize) -> Result<&mut FileHandle, SysError> { - self.files - .get_mut(&fd) - .ok_or(SysError::EBADF) - .and_then(|f| match f { - FileLike::File(file) => Ok(file), - _ => Err(SysError::EBADF), - }) + match self.get_file_like(fd)? { + FileLike::File(file) => Ok(file), + _ => Err(SysError::EBADF), + } } pub fn lookup_inode(&self, path: &str) -> Result, SysError> { debug!("lookup_inode: cwd {} path {}", self.cwd, path); @@ -1250,3 +1167,60 @@ bitflags! { const INVAL = 0x0020; } } + +const FD_PER_ITEM: usize = 8 * size_of::(); +const MAX_FDSET_SIZE: usize = 1024 / FD_PER_ITEM; + +struct FdSet { + addr: *mut u32, + nfds: usize, + saved: [u32; MAX_FDSET_SIZE], +} + +impl FdSet { + /// Initialize a `FdSet` from pointer and number of fds + /// Check if the array is large enough + fn new(vm: &MemorySet, addr: *mut u32, nfds: usize) -> Result { + let mut saved = [0u32; MAX_FDSET_SIZE]; + if addr as usize != 0 { + let len = (nfds + FD_PER_ITEM - 1) / FD_PER_ITEM; + vm.check_write_array(addr, len)?; + if len > MAX_FDSET_SIZE { + return Err(SysError::EINVAL); + } + let slice = unsafe { slice::from_raw_parts_mut(addr, len) }; + + // save the fdset, and clear it + for i in 0..len { + saved[i] = slice[i]; + slice[i] = 0; + } + } + + Ok(FdSet { addr, nfds, saved }) + } + + /// Try to set fd in `FdSet` + /// Return true when `FdSet` is valid, and false when `FdSet` is bad (i.e. null pointer) + /// Fd should be less than nfds + fn set(&mut self, fd: usize) -> bool { + if self.addr as usize != 0 { + assert!(fd < self.nfds); + unsafe { + *self.addr.add(fd / 8 / size_of::()) |= 1 << (fd % (8 * size_of::())); + } + true + } else { + false + } + } + + /// Check to see fd is see in original `FdSet` + /// Fd should be less than nfds + fn is_set(&mut self, fd: usize) -> bool { + assert!(fd < self.nfds); + self.saved[fd / 8 / size_of::()] & (1 << (fd % (8 * size_of::()))) != 0 + } +} + +const AT_FDCWD: usize = -100isize as usize; diff --git a/kernel/src/syscall/net.rs b/kernel/src/syscall/net.rs index a955b9e..2811f12 100644 --- a/kernel/src/syscall/net.rs +++ b/kernel/src/syscall/net.rs @@ -2,116 +2,32 @@ use super::*; use crate::drivers::SOCKET_ACTIVITY; -use crate::net::{ - get_ephemeral_port, poll_ifaces, SocketType, SocketWrapper, TcpSocketState, UdpSocketState, - SOCKETS, -}; +use crate::fs::FileLike; +use crate::net::{RawSocketState, Socket, TcpSocketState, UdpSocketState, SOCKETS}; +use crate::sync::{MutexGuard, SpinNoIrq, SpinNoIrqLock as Mutex}; +use alloc::boxed::Box; use core::cmp::min; use core::mem::size_of; -use smoltcp::socket::*; use smoltcp::wire::*; -const AF_UNIX: usize = 1; -const AF_INET: usize = 2; - -const SOCK_STREAM: usize = 1; -const SOCK_DGRAM: usize = 2; -const SOCK_RAW: usize = 3; -const SOCK_TYPE_MASK: usize = 0xf; - -const IPPROTO_IP: usize = 0; -const IPPROTO_ICMP: usize = 1; -const IPPROTO_TCP: usize = 6; - -const TCP_SENDBUF: usize = 512 * 1024; // 512K -const TCP_RECVBUF: usize = 512 * 1024; // 512K - -const UDP_SENDBUF: usize = 64 * 1024; // 64K -const UDP_RECVBUF: usize = 64 * 1024; // 64K - pub fn sys_socket(domain: usize, socket_type: usize, protocol: usize) -> SysResult { info!( "socket: domain: {}, socket_type: {}, protocol: {}", domain, socket_type, protocol ); let mut proc = process(); - match domain { + let socket: Box = match domain { AF_INET | AF_UNIX => match socket_type & SOCK_TYPE_MASK { - SOCK_STREAM => { - let fd = proc.get_free_fd(); - - let tcp_rx_buffer = TcpSocketBuffer::new(vec![0; TCP_RECVBUF]); - let tcp_tx_buffer = TcpSocketBuffer::new(vec![0; TCP_SENDBUF]); - let tcp_socket = TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer); - - let tcp_handle = SOCKETS.lock().add(tcp_socket); - proc.files.insert( - fd, - FileLike::Socket(SocketWrapper { - handle: tcp_handle, - socket_type: SocketType::Tcp(TcpSocketState { - local_endpoint: None, - is_listening: false, - }), - }), - ); - - Ok(fd) - } - SOCK_DGRAM => { - let fd = proc.get_free_fd(); - - let udp_rx_buffer = UdpSocketBuffer::new( - vec![UdpPacketMetadata::EMPTY; 1024], - vec![0; UDP_RECVBUF], - ); - let udp_tx_buffer = UdpSocketBuffer::new( - vec![UdpPacketMetadata::EMPTY; 1024], - vec![0; UDP_SENDBUF], - ); - let udp_socket = UdpSocket::new(udp_rx_buffer, udp_tx_buffer); - - let udp_handle = SOCKETS.lock().add(udp_socket); - proc.files.insert( - fd, - FileLike::Socket(SocketWrapper { - handle: udp_handle, - socket_type: SocketType::Udp(UdpSocketState { - remote_endpoint: None, - }), - }), - ); - - Ok(fd) - } - SOCK_RAW => { - let fd = proc.get_free_fd(); - - let raw_rx_buffer = - RawSocketBuffer::new(vec![RawPacketMetadata::EMPTY; 2], vec![0; 2048]); - let raw_tx_buffer = - RawSocketBuffer::new(vec![RawPacketMetadata::EMPTY; 2], vec![0; 2048]); - let raw_socket = RawSocket::new( - IpVersion::Ipv4, - IpProtocol::from(protocol as u8), - raw_rx_buffer, - raw_tx_buffer, - ); - - let raw_handle = SOCKETS.lock().add(raw_socket); - proc.files.insert( - fd, - FileLike::Socket(SocketWrapper { - handle: raw_handle, - socket_type: SocketType::Raw, - }), - ); - Ok(fd) - } - _ => Err(SysError::EINVAL), + SOCK_STREAM => Box::new(TcpSocketState::new()), + SOCK_DGRAM => Box::new(UdpSocketState::new()), + SOCK_RAW => Box::new(RawSocketState::new(protocol as u8)), + _ => return Err(SysError::EINVAL), }, - _ => Err(SysError::EAFNOSUPPORT), - } + _ => return Err(SysError::EAFNOSUPPORT), + }; + let fd = proc.get_free_fd(); + proc.files.insert(fd, FileLike::Socket(socket)); + Ok(fd) } pub fn sys_setsockopt( @@ -129,13 +45,6 @@ pub fn sys_setsockopt( Ok(0) } -const SOL_SOCKET: usize = 1; -const SO_SNDBUF: usize = 7; -const SO_RCVBUF: usize = 8; -const SO_LINGER: usize = 13; - -const TCP_CONGESTION: usize = 13; - pub fn sys_getsockopt( fd: usize, level: usize, @@ -154,7 +63,7 @@ pub fn sys_getsockopt( SO_SNDBUF => { proc.vm.check_write_array(optval, 4)?; unsafe { - *(optval as *mut u32) = TCP_SENDBUF as u32; + *(optval as *mut u32) = crate::net::TCP_SENDBUF as u32; *optlen = 4; } Ok(0) @@ -162,7 +71,7 @@ pub fn sys_getsockopt( SO_RCVBUF => { proc.vm.check_write_array(optval, 4)?; unsafe { - *(optval as *mut u32) = TCP_RECVBUF as u32; + *(optval as *mut u32) = crate::net::TCP_RECVBUF as u32; *optlen = 4; } Ok(0) @@ -177,24 +86,6 @@ pub fn sys_getsockopt( } } -impl Process { - fn get_socket(&mut self, fd: usize) -> Result { - let file = self.files.get_mut(&fd).ok_or(SysError::EBADF)?; - match file { - FileLike::Socket(wrapper) => Ok(wrapper.clone()), - _ => Err(SysError::ENOTSOCK), - } - } - - fn get_socket_mut(&mut self, fd: usize) -> Result<&mut SocketWrapper, SysError> { - let file = self.files.get_mut(&fd).ok_or(SysError::EBADF)?; - match file { - FileLike::Socket(ref mut wrapper) => Ok(wrapper), - _ => Err(SysError::ENOTSOCK), - } - } -} - pub fn sys_connect(fd: usize, addr: *const SockAddr, addr_len: usize) -> SysResult { info!( "sys_connect: fd: {}, addr: {:?}, addr_len: {}", @@ -202,64 +93,10 @@ pub fn sys_connect(fd: usize, addr: *const SockAddr, addr_len: usize) -> SysResu ); let mut proc = process(); - let endpoint = sockaddr_to_endpoint(&mut proc, addr, addr_len)?; - - let wrapper = &mut proc.get_socket_mut(fd)?; - if let SocketType::Tcp(_) = wrapper.socket_type { - let mut sockets = SOCKETS.lock(); - let mut socket = sockets.get::(wrapper.handle); - - let temp_port = get_ephemeral_port(); - - match socket.connect(endpoint, temp_port) { - Ok(()) => { - // avoid deadlock - drop(socket); - drop(sockets); - - // wait for connection result - loop { - poll_ifaces(); - - let mut sockets = SOCKETS.lock(); - let socket = sockets.get::(wrapper.handle); - if socket.state() == TcpState::SynSent { - // still connecting - drop(socket); - drop(sockets); - debug!("poll for connection wait"); - SOCKET_ACTIVITY._wait(); - } else if socket.state() == TcpState::Established { - break Ok(0); - } else { - break Err(SysError::ECONNREFUSED); - } - } - } - Err(_) => Err(SysError::ENOBUFS), - } - } else if let SocketType::Udp(_) = wrapper.socket_type { - wrapper.socket_type = SocketType::Udp(UdpSocketState { - remote_endpoint: Some(endpoint), - }); - Ok(0) - } else { - unimplemented!("socket type") - } -} - -pub fn sys_write_socket(proc: &mut Process, fd: usize, base: *const u8, len: usize) -> SysResult { - let wrapper = proc.get_socket(fd)?; - let slice = unsafe { slice::from_raw_parts(base, len) }; - wrapper.write(&slice, None) -} - -pub fn sys_read_socket(proc: &mut Process, fd: usize, base: *mut u8, len: usize) -> SysResult { - let wrapper = proc.get_socket(fd)?; - let mut slice = unsafe { slice::from_raw_parts_mut(base, len) }; - let (result, _) = wrapper.read(&mut slice); - result + let socket = proc.get_socket(fd)?; + socket.connect(endpoint)?; + Ok(0) } pub fn sys_sendto( @@ -278,15 +115,16 @@ pub fn sys_sendto( let mut proc = process(); proc.vm.check_read_array(base, len)?; - let wrapper = proc.get_socket(fd)?; let slice = unsafe { slice::from_raw_parts(base, len) }; - if addr.is_null() { - wrapper.write(&slice, None) + let endpoint = if addr.is_null() { + None } else { let endpoint = sockaddr_to_endpoint(&mut proc, addr, addr_len)?; info!("sys_sendto: sending to endpoint {:?}", endpoint); - wrapper.write(&slice, Some(endpoint)) - } + Some(endpoint) + }; + let socket = proc.get_socket(fd)?; + socket.write(&slice, endpoint) } pub fn sys_recvfrom( @@ -305,9 +143,9 @@ pub fn sys_recvfrom( let mut proc = process(); proc.vm.check_write_array(base, len)?; - let wrapper = proc.get_socket(fd)?; + let socket = proc.get_socket(fd)?; let mut slice = unsafe { slice::from_raw_parts_mut(base, len) }; - let (result, endpoint) = wrapper.read(&mut slice); + let (result, endpoint) = socket.read(&mut slice); if result.is_ok() && !addr.is_null() { let sockaddr_in = SockAddr::from(endpoint); @@ -319,45 +157,15 @@ pub fn sys_recvfrom( result } -impl Clone for SocketWrapper { - fn clone(&self) -> Self { - let mut sockets = SOCKETS.lock(); - sockets.retain(self.handle); - - SocketWrapper { - handle: self.handle.clone(), - socket_type: self.socket_type.clone(), - } - } -} - pub fn sys_bind(fd: usize, addr: *const SockAddr, addr_len: usize) -> SysResult { info!("sys_bind: fd: {} addr: {:?} len: {}", fd, addr, addr_len); let mut proc = process(); let mut endpoint = sockaddr_to_endpoint(&mut proc, addr, addr_len)?; - if endpoint.port == 0 { - endpoint.port = get_ephemeral_port(); - } info!("sys_bind: fd: {} bind to {}", fd, endpoint); - let wrapper = &mut proc.get_socket_mut(fd)?; - if let SocketType::Tcp(_) = wrapper.socket_type { - wrapper.socket_type = SocketType::Tcp(TcpSocketState { - local_endpoint: Some(endpoint), - is_listening: false, - }); - Ok(0) - } else if let SocketType::Udp(_) = wrapper.socket_type { - let mut sockets = SOCKETS.lock(); - let mut socket = sockets.get::(wrapper.handle); - match socket.bind(endpoint) { - Ok(()) => Ok(0), - Err(_) => Err(SysError::EINVAL), - } - } else { - Err(SysError::EINVAL) - } + let socket = proc.get_socket(fd)?; + socket.bind(endpoint) } pub fn sys_listen(fd: usize, backlog: usize) -> SysResult { @@ -366,48 +174,16 @@ pub fn sys_listen(fd: usize, backlog: usize) -> SysResult { // open multiple sockets for each connection let mut proc = process(); - let wrapper = proc.get_socket_mut(fd)?; - if let SocketType::Tcp(ref mut tcp_state) = wrapper.socket_type { - if tcp_state.is_listening { - // it is ok to listen twice - Ok(0) - } else if let Some(local_endpoint) = tcp_state.local_endpoint { - let mut sockets = SOCKETS.lock(); - let mut socket = sockets.get::(wrapper.handle); - - info!("socket {} listening on {:?}", fd, local_endpoint); - if !socket.is_listening() { - match socket.listen(local_endpoint) { - Ok(()) => { - tcp_state.is_listening = true; - Ok(0) - } - Err(_err) => Err(SysError::EINVAL), - } - } else { - Ok(0) - } - } else { - Err(SysError::EINVAL) - } - } else { - Err(SysError::EINVAL) - } + let socket = proc.get_socket(fd)?; + socket.listen() } pub fn sys_shutdown(fd: usize, how: usize) -> SysResult { info!("sys_shutdown: fd: {} how: {}", fd, how); let mut proc = process(); - let wrapper = proc.get_socket_mut(fd)?; - if let SocketType::Tcp(_) = wrapper.socket_type { - let mut sockets = SOCKETS.lock(); - let mut socket = sockets.get::(wrapper.handle); - socket.close(); - Ok(0) - } else { - Err(SysError::EINVAL) - } + let socket = proc.get_socket(fd)?; + socket.shutdown() } pub fn sys_accept(fd: usize, addr: *mut SockAddr, addr_len: *mut u32) -> SysResult { @@ -419,75 +195,19 @@ pub fn sys_accept(fd: usize, addr: *mut SockAddr, addr_len: *mut u32) -> SysResu // open multiple sockets for each connection let mut proc = process(); - let wrapper = proc.get_socket_mut(fd)?; - if let SocketType::Tcp(tcp_state) = wrapper.socket_type.clone() { - if let Some(endpoint) = tcp_state.local_endpoint { - loop { - let mut sockets = SOCKETS.lock(); - let socket = sockets.get::(wrapper.handle); - - if socket.is_active() { - let remote_endpoint = socket.remote_endpoint(); - drop(socket); - - // move the current one to new_fd - // create a new one in fd - let new_fd = proc.get_free_fd(); - - let tcp_rx_buffer = TcpSocketBuffer::new(vec![0; TCP_RECVBUF]); - let tcp_tx_buffer = TcpSocketBuffer::new(vec![0; TCP_SENDBUF]); - let mut tcp_socket = TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer); - tcp_socket.listen(endpoint).unwrap(); - - let tcp_handle = sockets.add(tcp_socket); - - let mut orig_socket = proc - .files - .insert( - fd, - FileLike::Socket(SocketWrapper { - handle: tcp_handle, - socket_type: SocketType::Tcp(tcp_state), - }), - ) - .unwrap(); - - if let FileLike::Socket(ref mut wrapper) = orig_socket { - if let SocketType::Tcp(ref mut state) = wrapper.socket_type { - state.is_listening = false; - } else { - panic!("impossible"); - } - } else { - panic!("impossible"); - } - proc.files.insert(new_fd, orig_socket); - - if !addr.is_null() { - let sockaddr_in = SockAddr::from(remote_endpoint); - unsafe { - sockaddr_in.write_to(&mut proc, addr, addr_len)?; - } - } - - drop(sockets); - drop(proc); - poll_ifaces(); - return Ok(new_fd); - } + let socket = proc.get_socket(fd)?; + let (new_socket, remote_endpoint) = socket.accept()?; - // avoid deadlock - drop(socket); - drop(sockets); - SOCKET_ACTIVITY._wait() - } - } else { - Err(SysError::EINVAL) + let new_fd = proc.get_free_fd(); + proc.files.insert(new_fd, FileLike::Socket(new_socket)); + + if !addr.is_null() { + let sockaddr_in = SockAddr::from(remote_endpoint); + unsafe { + sockaddr_in.write_to(&mut proc, addr, addr_len)?; } - } else { - debug!("bad socket type {:?}", wrapper); - Err(SysError::EINVAL) } + Ok(new_fd) } pub fn sys_getsockname(fd: usize, addr: *mut SockAddr, addr_len: *mut u32) -> SysResult { @@ -502,44 +222,13 @@ pub fn sys_getsockname(fd: usize, addr: *mut SockAddr, addr_len: *mut u32) -> Sy return Err(SysError::EINVAL); } - let wrapper = proc.get_socket_mut(fd)?; - if let SocketType::Tcp(state) = &wrapper.socket_type { - if let Some(endpoint) = state.local_endpoint { - let sockaddr_in = SockAddr::from(endpoint); - unsafe { - sockaddr_in.write_to(&mut proc, addr, addr_len)?; - } - Ok(0) - } else { - let mut sockets = SOCKETS.lock(); - let socket = sockets.get::(wrapper.handle); - let endpoint = socket.local_endpoint(); - if endpoint.port != 0 { - let sockaddr_in = SockAddr::from(socket.local_endpoint()); - unsafe { - sockaddr_in.write_to(&mut proc, addr, addr_len)?; - } - Ok(0) - } else { - Err(SysError::EINVAL) - } - } - } else if let SocketType::Udp(_) = &wrapper.socket_type { - let mut sockets = SOCKETS.lock(); - let socket = sockets.get::(wrapper.handle); - let endpoint = socket.endpoint(); - if endpoint.port != 0 { - let sockaddr_in = SockAddr::from(endpoint); - unsafe { - sockaddr_in.write_to(&mut proc, addr, addr_len)?; - } - Ok(0) - } else { - Err(SysError::EINVAL) - } - } else { - Err(SysError::EINVAL) + let socket = proc.get_socket(fd)?; + let endpoint = socket.endpoint().ok_or(SysError::EINVAL)?; + let sockaddr_in = SockAddr::from(endpoint); + unsafe { + sockaddr_in.write_to(&mut proc, addr, addr_len)?; } + Ok(0) } pub fn sys_getpeername(fd: usize, addr: *mut SockAddr, addr_len: *mut u32) -> SysResult { @@ -556,81 +245,22 @@ pub fn sys_getpeername(fd: usize, addr: *mut SockAddr, addr_len: *mut u32) -> Sy return Err(SysError::EINVAL); } - let wrapper = proc.get_socket_mut(fd)?; - if let SocketType::Tcp(_) = wrapper.socket_type { - let mut sockets = SOCKETS.lock(); - let socket = sockets.get::(wrapper.handle); - - if socket.is_open() { - let remote_endpoint = socket.remote_endpoint(); - let sockaddr_in = SockAddr::from(remote_endpoint); - unsafe { - sockaddr_in.write_to(&mut proc, addr, addr_len)?; - } - Ok(0) - } else { - Err(SysError::EINVAL) - } - } else if let SocketType::Udp(state) = &wrapper.socket_type { - if let Some(endpoint) = state.remote_endpoint { - let sockaddr_in = SockAddr::from(endpoint); - unsafe { - sockaddr_in.write_to(&mut proc, addr, addr_len)?; - } - Ok(0) - } else { - Err(SysError::EINVAL) - } - } else { - Err(SysError::EINVAL) + let socket = proc.get_socket(fd)?; + let remote_endpoint = socket.remote_endpoint().ok_or(SysError::EINVAL)?; + let sockaddr_in = SockAddr::from(remote_endpoint); + unsafe { + sockaddr_in.write_to(&mut proc, addr, addr_len)?; } + Ok(0) } -/// Check socket state -/// return (in, out, err) -pub fn poll_socket(wrapper: &SocketWrapper) -> (bool, bool, bool) { - let mut input = false; - let mut output = false; - let mut err = false; - if let SocketType::Tcp(state) = wrapper.socket_type.clone() { - let mut sockets = SOCKETS.lock(); - let socket = sockets.get::(wrapper.handle); - - if state.is_listening && socket.is_active() { - // a new connection - input = true; - } else if !socket.is_open() { - err = true; - } else { - if socket.can_recv() { - input = true; - } - - if socket.can_send() { - output = true; - } - } - } else if let SocketType::Udp(_) = wrapper.socket_type { - let mut sockets = SOCKETS.lock(); - let socket = sockets.get::(wrapper.handle); - - if socket.can_recv() { - input = true; - } - - if socket.can_send() { - output = true; +impl Process { + fn get_socket(&mut self, fd: usize) -> Result<&mut Box, SysError> { + match self.get_file_like(fd)? { + FileLike::Socket(socket) => Ok(socket), + _ => Err(SysError::EBADF), } - } else { - unimplemented!() } - - (input, output, err) -} - -pub fn sys_dup2_socket(proc: &mut Process, wrapper: SocketWrapper, fd: usize) -> SysResult { - proc.files.insert(fd, FileLike::Socket(wrapper)); - Ok(fd) } // cancel alignment @@ -738,3 +368,22 @@ impl SockAddr { return Ok(0); } } + +const AF_UNIX: usize = 1; +const AF_INET: usize = 2; + +const SOCK_STREAM: usize = 1; +const SOCK_DGRAM: usize = 2; +const SOCK_RAW: usize = 3; +const SOCK_TYPE_MASK: usize = 0xf; + +const IPPROTO_IP: usize = 0; +const IPPROTO_ICMP: usize = 1; +const IPPROTO_TCP: usize = 6; + +const SOL_SOCKET: usize = 1; +const SO_SNDBUF: usize = 7; +const SO_RCVBUF: usize = 8; +const SO_LINGER: usize = 13; + +const TCP_CONGESTION: usize = 13; diff --git a/tools/.gitignore b/tools/.gitignore deleted file mode 100644 index 816158a..0000000 --- a/tools/.gitignore +++ /dev/null @@ -1 +0,0 @@ -llc From 236ddd08274fbc05a915f3c651edffe351f2d78f Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Fri, 29 Mar 2019 13:51:31 +0800 Subject: [PATCH 7/8] Move chmod to x86 specific syscall --- kernel/src/syscall/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 23e047d..d8fc481 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -161,11 +161,6 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { SYS_GETCWD => sys_getcwd(args[0] as *mut u8, args[1]), // 80 SYS_CHDIR => sys_chdir(args[0] as *const u8), - // 90 - SYS_CHMOD => { - warn!("sys_chmod is unimplemented"); - Ok(0) - } SYS_FCHMOD => { warn!("sys_fchmod is unimplemented"); Ok(0) @@ -341,6 +336,11 @@ fn x86_64_syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> Option sys_link(args[0] as *const u8, args[1] as *const u8), SYS_UNLINK => sys_unlink(args[0] as *const u8), SYS_READLINK => sys_readlink(args[0] as *const u8, args[1] as *mut u8, args[2]), + // 90 + SYS_CHMOD => { + warn!("sys_chmod is unimplemented"); + Ok(0) + } SYS_ARCH_PRCTL => sys_arch_prctl(args[0] as i32, args[1], tf), SYS_TIME => sys_time(args[0] as *mut u64), SYS_ALARM => { From b8d91965e7e6fea55174162852c1b5b339597b3e Mon Sep 17 00:00:00 2001 From: equation314 Date: Fri, 29 Mar 2019 19:57:01 +0800 Subject: [PATCH 8/8] aarch64: fix `A1` field in `TCR_EL1` register --- bootloader/src/arch/aarch64/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootloader/src/arch/aarch64/mod.rs b/bootloader/src/arch/aarch64/mod.rs index 3aa3762..4a03460 100644 --- a/bootloader/src/arch/aarch64/mod.rs +++ b/bootloader/src/arch/aarch64/mod.rs @@ -75,7 +75,7 @@ fn enable_mmu() { TCR_EL1::ORGN1::WriteBack_ReadAlloc_WriteAlloc_Cacheable + TCR_EL1::IRGN1::WriteBack_ReadAlloc_WriteAlloc_Cacheable + TCR_EL1::EPD1::EnableTTBR1Walks + - TCR_EL1::A1::UseTTBR1ASID + + TCR_EL1::A1::UseTTBR0ASID + TCR_EL1::T1SZ.val(16) + TCR_EL1::TG0::KiB_4 +