diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index 91d5bfd..b0600da 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -1,3 +1,17 @@ +[[package]] +name = "aarch64" +version = "2.2.2" +source = "git+https://github.com/equation314/aarch64#47bf5439f5a1379f0fef6272853cf684207a4e45" +dependencies = [ + "bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "os_bootinfo 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "register 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "usize_conversions 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ux 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "apic" version = "0.1.0" @@ -302,6 +316,7 @@ dependencies = [ name = "ucore" version = "0.1.0" dependencies = [ + "aarch64 2.2.2 (git+https://github.com/equation314/aarch64)", "apic 0.1.0 (git+https://github.com/wangrunji0408/APIC-Rust)", "atags 0.1.0", "bbl 0.1.0", @@ -311,7 +326,6 @@ dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "bootloader 0.3.4 (git+https://github.com/wangrunji0408/bootloader)", "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "cortex-a 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "linked_list_allocator 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -431,6 +445,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] +"checksum aarch64 2.2.2 (git+https://github.com/equation314/aarch64)" = "" "checksum apic 0.1.0 (git+https://github.com/wangrunji0408/APIC-Rust)" = "" "checksum array-init 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "23589ecb866b460d3a0f1278834750268c607e8e28a1b982c907219f3178cd72" "checksum bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a3caf393d93b2d453e80638d0674597020cef3382ada454faacd43d1a55a735a" diff --git a/kernel/Makefile b/kernel/Makefile index e96afbf..5ab7d19 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -142,7 +142,7 @@ ifeq ($(arch), riscv32) ifeq ($(board), fpga) @cp $(kernel) $@ else - @cd ../tools/riscv-pk && \ + @cd ../riscv-pk && \ mkdir -p build && \ cd build && \ ../configure \ @@ -152,7 +152,7 @@ else --host=riscv64-unknown-elf \ --with-payload=$(abspath $(kernel)) && \ make && \ - cp bbl ../../../kernel/$@ + cp bbl ../../kernel/$@ endif else ifeq ($(arch), aarch64) @$(objcopy) $(kernel) --strip-all -O binary $@ diff --git a/kernel/src/arch/aarch64/board/raspi3/mod.rs b/kernel/src/arch/aarch64/board/raspi3/mod.rs index 26c2ff6..dd1abda 100644 --- a/kernel/src/arch/aarch64/board/raspi3/mod.rs +++ b/kernel/src/arch/aarch64/board/raspi3/mod.rs @@ -1,5 +1,7 @@ //! Raspberry PI 3 Model B/B+ +use once::*; + pub mod irq; pub mod timer; pub mod serial; diff --git a/kernel/src/arch/aarch64/board/raspi3/serial.rs b/kernel/src/arch/aarch64/board/raspi3/serial.rs index a7856b8..6e4fce8 100644 --- a/kernel/src/arch/aarch64/board/raspi3/serial.rs +++ b/kernel/src/arch/aarch64/board/raspi3/serial.rs @@ -1,6 +1,7 @@ use bcm2837::mini_uart::MiniUart; use core::fmt; use spin::Mutex; +use once::*; /// Struct to get a global SerialPort interface pub struct SerialPort { diff --git a/kernel/src/arch/aarch64/consts.rs b/kernel/src/arch/aarch64/consts.rs index 82d472b..af9f49c 100644 --- a/kernel/src/arch/aarch64/consts.rs +++ b/kernel/src/arch/aarch64/consts.rs @@ -1,11 +1,8 @@ -//! TODO: replace unmiplemented consts with real value -const UNIMPLEMENTED: usize = 0; -pub const KERNEL_OFFSET: usize = UNIMPLEMENTED; -pub const KERNEL_PML4: usize = UNIMPLEMENTED; -pub const KERNEL_HEAP_OFFSET: usize = UNIMPLEMENTED; +pub const RECURSIVE_INDEX: usize = 0o777; +pub const KERNEL_OFFSET: usize = 0; +pub const KERNEL_PML4: usize = 0; pub const KERNEL_HEAP_SIZE: usize = 8 * 1024 * 1024; -pub const MEMORY_OFFSET: usize = UNIMPLEMENTED; -pub const MEMORY_END: usize = UNIMPLEMENTED; -pub const USER_STACK_OFFSET: usize = UNIMPLEMENTED; -pub const USER_STACK_SIZE: usize = UNIMPLEMENTED; -pub const USER32_STACK_OFFSET: usize = UNIMPLEMENTED; \ No newline at end of file +pub const MEMORY_OFFSET: usize = 0; +pub const USER_STACK_OFFSET: usize = 0xffff_8000_0000_0000; +pub const USER_STACK_SIZE: usize = 1 * 1024 * 1024; +pub const USER32_STACK_OFFSET: usize = USER_STACK_OFFSET; \ No newline at end of file diff --git a/kernel/src/arch/aarch64/interrupt/context.rs b/kernel/src/arch/aarch64/interrupt/context.rs index f5f4eda..8b231e7 100644 --- a/kernel/src/arch/aarch64/interrupt/context.rs +++ b/kernel/src/arch/aarch64/interrupt/context.rs @@ -1,8 +1,7 @@ //! TrapFrame and context definitions for aarch64. -extern crate aarch64; - -use spin::{Mutex}; +use spin::Mutex; +use lazy_static::lazy_static; use aarch64::barrier; use aarch64::addr::PhysAddr; use aarch64::paging::PhysFrame; @@ -169,7 +168,7 @@ impl Context { /// Called at a new user context /// To get the init TrapFrame in sys_exec pub unsafe fn get_init_tf(&self) -> TrapFrame { - (*(self.0 as *const InitStack)).tf.clone() + (*(self.stack_top as *const InitStack)).tf.clone() } } diff --git a/kernel/src/arch/aarch64/interrupt/handler.rs b/kernel/src/arch/aarch64/interrupt/handler.rs index 2b5adcc..d9b4a20 100644 --- a/kernel/src/arch/aarch64/interrupt/handler.rs +++ b/kernel/src/arch/aarch64/interrupt/handler.rs @@ -55,7 +55,7 @@ pub extern "C" fn rust_trap(info: Info, esr: u32, tf: &mut TrapFrame) { Fault::Translation | Fault::AccessFlag | Fault::Permission => { handle_page_fault(tf) } - _ => ::trap::error(tf), + _ => crate::trap::error(tf), }, _ => crate::trap::error(tf), } @@ -73,7 +73,7 @@ fn handle_break(_num: u16, tf: &mut TrapFrame) { fn handle_syscall(num: u16, tf: &mut TrapFrame) { if num != 0 { - ::trap::error(tf); + crate::trap::error(tf); } // svc instruction has been skipped in syscall (ref: J1.1.2, page 6152) @@ -96,5 +96,5 @@ fn handle_page_fault(tf: &mut TrapFrame) { let addr = FAR_EL1.get(); trace!("\nEXCEPTION: Page Fault @ {:#x}", addr); - ::trap::error(tf); + crate::trap::error(tf); } diff --git a/kernel/src/arch/aarch64/memory.rs b/kernel/src/arch/aarch64/memory.rs index 29f3009..c4a2c5f 100644 --- a/kernel/src/arch/aarch64/memory.rs +++ b/kernel/src/arch/aarch64/memory.rs @@ -1,10 +1,11 @@ //! Memory initialization for aarch64. +use log::*; use ucore_memory::PAGE_SIZE; -use memory::{FRAME_ALLOCATOR, init_heap, MemoryArea, MemoryAttr, MemorySet, Stack}; -use super::atags::atags::Atags; +use atags::atags::Atags; use aarch64::{barrier, regs::*, addr::*}; use aarch64::paging::{PhysFrame as Frame, memory_attribute::*}; +use crate::memory::{FRAME_ALLOCATOR, init_heap, MemoryArea, MemoryAttr, MemorySet}; /// Memory initialization. pub fn init() { @@ -73,7 +74,7 @@ pub fn init_mmu_early() { fn init_frame_allocator() { use bit_allocator::BitAlloc; use core::ops::Range; - use consts::MEMORY_OFFSET; + use crate::consts::MEMORY_OFFSET; let (start, end) = memory_map().expect("failed to find memory map"); let mut ba = FRAME_ALLOCATOR.lock(); @@ -98,20 +99,14 @@ fn init_frame_allocator() { /// remap kernel page table after all initialization. fn remap_the_kernel() { - let (bottom, top) = (0, bootstacktop as usize); - let kstack = Stack { - top, - bottom, - }; - static mut SPACE: [u8; 0x1000] = [0; 0x1000]; - let mut ms = unsafe { MemorySet::new_from_raw_space(&mut SPACE, kstack) }; - ms.push(MemoryArea::new_identity(bottom, top, MemoryAttr::default(), "kstack")); + let mut ms = unsafe { MemorySet::new_bare() }; + ms.push(MemoryArea::new_identity(0, bootstacktop as usize, MemoryAttr::default(), "kstack")); ms.push(MemoryArea::new_identity(stext as usize, etext as usize, MemoryAttr::default().execute().readonly(), "text")); ms.push(MemoryArea::new_identity(sdata as usize, edata as usize, MemoryAttr::default(), "data")); ms.push(MemoryArea::new_identity(srodata as usize, erodata as usize, MemoryAttr::default().readonly(), "rodata")); ms.push(MemoryArea::new_identity(sbss as usize, ebss as usize, MemoryAttr::default(), "bss")); - use arch::board::{IO_REMAP_BASE, IO_REMAP_END}; + use super::board::{IO_REMAP_BASE, IO_REMAP_END}; ms.push(MemoryArea::new_identity(IO_REMAP_BASE, IO_REMAP_END, MemoryAttr::default().mmio(), "io_remap")); unsafe { ms.activate(); } diff --git a/kernel/src/arch/aarch64/mod.rs b/kernel/src/arch/aarch64/mod.rs index dabdc1f..b96f24e 100644 --- a/kernel/src/arch/aarch64/mod.rs +++ b/kernel/src/arch/aarch64/mod.rs @@ -23,30 +23,18 @@ pub extern "C" fn rust_main() -> ! { // Init board to enable serial port. board::init(); + println!("{}", LOGO); crate::logging::init(); interrupt::init(); memory::init(); timer::init(); - use crate::process::{processor, ContextImpl}; crate::process::init(); - processor().manager().add(ContextImpl::new_kernel(kernel_proc2, 2333), 0); - processor().manager().add(ContextImpl::new_user_test(kernel_proc3), 0); crate::kmain(); } -extern fn kernel_proc2(arg: usize) -> ! { - use alloc::format; - test_shell(&format!("proc2-{}>> ", arg)); -} - -extern fn kernel_proc3(arg: usize) -> ! { - use alloc::format; - test_shell(&format!("proc3-{}$ ", arg)); -} - const LOGO: &str = r#" ____ __ ____ _____ / __ \ __ __ _____ / /_ / __ \/ ___/ @@ -54,50 +42,3 @@ const LOGO: &str = r#" / _, _// /_/ /(__ )/ /_ / /_/ /___/ / /_/ |_| \__,_//____/ \__/ \____//____/ "#; - -pub fn show_logo() { - println!("{}", LOGO); -} - -#[inline(always)] -fn sys_call(id: usize, arg0: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) -> i32 { - let ret: i32; - unsafe { - asm!("svc 0" - : "={x0}" (ret) - : "{x8}" (id), "{x0}" (arg0), "{x1}" (arg1), "{x2}" (arg2), "{x3}" (arg3), "{x4}" (arg4), "{x5}" (arg5) - : "memory" - : "volatile"); - } - ret -} - -pub fn test_shell(prefix: &str) -> ! { - show_logo(); - loop { - print!("{}", prefix); - loop { - let c = io::getchar(); - match c { - '\u{7f}' => { - print!("\u{7f}"); - } - 'c' => unsafe { - print!("sys_putc: "); - sys_call(30, 'A' as usize, 0, 0, 0, 0, 0); - }, - 't' => unsafe { - println!("sys_get_time: {}", sys_call(17, 0, 0, 0, 0, 0, 0)); - }, - ' '...'\u{7e}' => { - print!("{}", c); - } - '\n' | '\r' => { - print!("\n"); - break; - } - _ => {} - } - } - } -} diff --git a/kernel/src/arch/aarch64/paging.rs b/kernel/src/arch/aarch64/paging.rs index c429a68..9685bc0 100644 --- a/kernel/src/arch/aarch64/paging.rs +++ b/kernel/src/arch/aarch64/paging.rs @@ -1,7 +1,4 @@ //! Page table implementations for aarch64. -// Depends on kernel -use consts::{KERNEL_PML4, RECURSIVE_INDEX}; -use memory::{active_table, alloc_frame, alloc_stack, dealloc_frame}; use ucore_memory::memory_set::*; use ucore_memory::PAGE_SIZE; use ucore_memory::paging::*; @@ -10,6 +7,10 @@ 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, Size2MiB, Size1GiB}; use aarch64::paging::memory_attribute::*; +use log::*; +// Depends on kernel +use crate::consts::{KERNEL_PML4, RECURSIVE_INDEX}; +use crate::memory::{active_table, alloc_frame, dealloc_frame}; // need 3 page pub fn setup_temp_page_table(frame_lvl4: Frame, frame_lvl3: Frame, frame_lvl2: Frame) { @@ -25,7 +26,7 @@ pub fn setup_temp_page_table(frame_lvl4: Frame, frame_lvl3: Frame, frame_lvl2: F for page in Page::::range_of(start_addr, end_addr) { let paddr = PhysAddr::new(page.start_address().as_u64()); - use arch::board::IO_REMAP_BASE; + use super::board::IO_REMAP_BASE; if paddr.as_u64() >= IO_REMAP_BASE as u64 { p2[page.p2_index()].set_block::(paddr, block_flags | EF::PXN, MairDevice::attr_value()); } else { @@ -55,7 +56,7 @@ impl PageTable for ActivePageTable { let attr = MairNormal::attr_value(); self.0.map_to(Page::of_addr(addr), Frame::of_addr(target), flags, attr, &mut FrameAllocatorForAarch64) .unwrap().flush(); - self.get_entry(addr) + self.get_entry(addr).expect("fail to get entry") } fn unmap(&mut self, addr: usize) { @@ -241,13 +242,14 @@ impl InactivePageTable for InactivePageTable0 { ttbr_el1_write(1, new_frame); tlb_invalidate_all(); } - f(); + let ret = f(); debug!("switch TTBR1 {:?} -> {:?}", new_frame, old_frame); if old_frame != new_frame { ttbr_el1_write(1, old_frame); tlb_invalidate_all(); flush_icache_all(); } + ret } fn token(&self) -> usize { diff --git a/kernel/src/arch/riscv32/paging.rs b/kernel/src/arch/riscv32/paging.rs index 2f2c0f1..6cce3f3 100644 --- a/kernel/src/arch/riscv32/paging.rs +++ b/kernel/src/arch/riscv32/paging.rs @@ -161,10 +161,6 @@ impl ActivePageTable { // Unmap the page self.unmap(0xcafebabe); } - - pub fn token() -> usize { - satp::read().frame().number() | (1 << 31) - } } /// implementation for the Entry trait in /crate/memory/src/paging/mod.rs impl Entry for PageEntry { diff --git a/kernel/src/arch/x86_64/paging.rs b/kernel/src/arch/x86_64/paging.rs index 5c5c896..bdf9a4c 100644 --- a/kernel/src/arch/x86_64/paging.rs +++ b/kernel/src/arch/x86_64/paging.rs @@ -96,9 +96,6 @@ impl ActivePageTable { // Unmap the page self.unmap(0xcafebabe); } - pub fn token() -> usize { - Cr3::read().0.start_address().as_u64() as usize - } } impl Entry for PageEntry { diff --git a/kernel/src/fs.rs b/kernel/src/fs.rs index e0fc3d9..3f5cc22 100644 --- a/kernel/src/fs.rs +++ b/kernel/src/fs.rs @@ -34,7 +34,7 @@ _user_img_end: lazy_static! { pub static ref ROOT_INODE: Arc = { - #[cfg(target_arch = "riscv32")] + #[cfg(any(target_arch = "riscv32", target_arch = "aarch64"))] let device = { extern { fn _user_img_start(); @@ -44,8 +44,6 @@ lazy_static! { }; #[cfg(target_arch = "x86_64")] let device = Box::new(ide::IDE::new(1)); - #[cfg(target_arch = "aarch64")] - let device = unimplemented!(); let sfs = SimpleFileSystem::open(device).expect("failed to open SFS"); sfs.root_inode() diff --git a/kernel/src/memory.rs b/kernel/src/memory.rs index e0a209a..7fdaa13 100644 --- a/kernel/src/memory.rs +++ b/kernel/src/memory.rs @@ -110,7 +110,6 @@ pub fn page_fault_handler(addr: usize) -> bool { info!("start handling swap in/out page fault"); //unsafe { ACTIVE_TABLE_SWAP.force_unlock(); } - info!("active page table token in pg fault is {:x?}", ActivePageTable::token()); /*LAB3 EXERCISE 1: YOUR STUDENT NUMBER * handle the frame deallocated */