From 904380e091bd84069d213f79fca7d9f5c7b37520 Mon Sep 17 00:00:00 2001 From: DeathWish5 Date: Wed, 28 Jul 2021 19:49:02 +0800 Subject: [PATCH 1/2] Update toolchain to 2021-7-27, format some code --- .gitignore | 2 + kernel-hal-bare/src/arch/riscv/interrupt.rs | 162 +++++----- kernel-hal-bare/src/arch/riscv/mod.rs | 278 ++++++++++++------ kernel-hal-bare/src/arch/riscv/plic.rs | 133 +++++---- kernel-hal-bare/src/arch/riscv/sbi.rs | 36 +-- kernel-hal-bare/src/arch/riscv/uart.rs | 228 +++++++------- .../src/arch/riscv/virtio/virtio.rs | 12 +- kernel-hal-bare/src/arch/x86_64/mod.rs | 14 +- linux-loader/src/lib.rs | 34 ++- linux-object/src/fs/pipe.rs | 2 +- linux-object/src/fs/stdio.rs | 2 +- linux-object/src/loader/mod.rs | 5 +- linux-syscall/build.rs | 4 +- linux-syscall/src/lib.rs | 7 +- linux-syscall/src/task.rs | 20 +- prebuilt/linux/libc-libos.so | 0 prebuilt/linux/riscv64/busybox | 3 + rboot | 2 +- rust-toolchain | 2 +- zCore/riscv64.json | 2 +- zCore/src/main.rs | 39 ++- zCore/src/memory.rs | 38 ++- zircon-object/src/dev/pci/nodes.rs | 9 +- zircon-object/src/lib.rs | 1 - zircon-object/src/signal/port_packet.rs | 3 +- zircon-object/src/util/elf_loader.rs | 6 +- zircon-object/src/vm/vmar.rs | 2 +- 27 files changed, 615 insertions(+), 431 deletions(-) mode change 100755 => 100644 prebuilt/linux/libc-libos.so create mode 100644 prebuilt/linux/riscv64/busybox diff --git a/.gitignore b/.gitignore index e0bc73660..c825a0837 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ Cargo.lock .idea scripts/linux/test-result.txt rusty-tags.vi +*.img +zCore/src/link_user.S diff --git a/kernel-hal-bare/src/arch/riscv/interrupt.rs b/kernel-hal-bare/src/arch/riscv/interrupt.rs index 328ad4792..fb9710b89 100644 --- a/kernel-hal-bare/src/arch/riscv/interrupt.rs +++ b/kernel-hal-bare/src/arch/riscv/interrupt.rs @@ -1,47 +1,40 @@ +use alloc::boxed::Box; +use alloc::vec::Vec; use riscv::register::{ - scause::{ - self, - Trap, - Exception, - Interrupt, - }, satp, - sie, - stval, - sstatus, + scause::{self, Exception, Interrupt, Trap}, + sie, sstatus, stval, }; -use trapframe::{TrapFrame, UserContext}; -use alloc::boxed::Box; -use alloc::vec::Vec; use spin::Mutex; +use trapframe::{TrapFrame, UserContext}; /* use crate::timer::{ - TICKS, - clock_set_next_event, + TICKS, + clock_set_next_event, clock_close, }; */ //use crate::context::TrapFrame; -use super::sbi; use super::plic; +use super::sbi; use super::uart; -use crate::{putfmt, map_range, phys_to_virt}; use super::consts::PHYSICAL_MEMORY_OFFSET; use super::timer_set_next; +use crate::{map_range, phys_to_virt, putfmt}; //global_asm!(include_str!("trap.asm")); /* #[repr(C)] pub struct TrapFrame{ - pub x: [usize; 32], //General registers - pub sstatus: Sstatus, - pub sepc: usize, - pub stval: usize, - pub scause: Scause, + pub x: [usize; 32], //General registers + pub sstatus: Sstatus, + pub sepc: usize, + pub stval: usize, + pub scause: Scause, } */ @@ -52,27 +45,25 @@ lazy_static! { } fn init_irq() { - init_irq_table(); irq_add_handle(Timer, Box::new(super_timer)); //模拟参照了x86_64,把timer处理函数也放进去了 - //irq_add_handle(Keyboard, Box::new(keyboard)); + //irq_add_handle(Keyboard, Box::new(keyboard)); irq_add_handle(S_PLIC, Box::new(plic::handle_interrupt)); } -pub fn init(){ - unsafe{ - - sstatus::set_sie(); +pub fn init() { + unsafe { + sstatus::set_sie(); init_uart(); sie::set_sext(); init_ext(); - } + } init_irq(); - bare_println!("+++ setup interrupt +++"); + bare_println!("+++ setup interrupt +++"); } #[no_mangle] @@ -83,20 +74,26 @@ pub extern "C" fn trap_handler(tf: &mut TrapFrame) { let is_int = scause.bits() >> 63; let code = scause.bits() & !(1 << 63); - match scause.cause() { - Trap::Exception(Exception::Breakpoint) => breakpoint(&mut tf.sepc), - Trap::Exception(Exception::IllegalInstruction) => panic!("IllegalInstruction: {:#x}->{:#x}", sepc, stval), - Trap::Exception(Exception::LoadFault) => panic!("Load access fault: {:#x}->{:#x}", sepc, stval), - Trap::Exception(Exception::StoreFault) => panic!("Store access fault: {:#x}->{:#x}", sepc, stval), + match scause.cause() { + Trap::Exception(Exception::Breakpoint) => breakpoint(&mut tf.sepc), + Trap::Exception(Exception::IllegalInstruction) => { + panic!("IllegalInstruction: {:#x}->{:#x}", sepc, stval) + } + Trap::Exception(Exception::LoadFault) => { + panic!("Load access fault: {:#x}->{:#x}", sepc, stval) + } + Trap::Exception(Exception::StoreFault) => { + panic!("Store access fault: {:#x}->{:#x}", sepc, stval) + } Trap::Exception(Exception::LoadPageFault) => page_fault(stval, tf), Trap::Exception(Exception::StorePageFault) => page_fault(stval, tf), Trap::Exception(Exception::InstructionPageFault) => page_fault(stval, tf), - Trap::Interrupt(Interrupt::SupervisorTimer) => super_timer(), - Trap::Interrupt(Interrupt::SupervisorSoft) => super_soft(), + Trap::Interrupt(Interrupt::SupervisorTimer) => super_timer(), + Trap::Interrupt(Interrupt::SupervisorSoft) => super_soft(), Trap::Interrupt(Interrupt::SupervisorExternal) => plic::handle_interrupt(), - //Trap::Interrupt(Interrupt::SupervisorExternal) => irq_handle(code as u8), - _ => panic!("Undefined Trap: {:#x} {:#x}", is_int, code) - } + //Trap::Interrupt(Interrupt::SupervisorExternal) => irq_handle(code as u8), + _ => panic!("Undefined Trap: {:#x} {:#x}", is_int, code), + } } fn init_irq_table() { @@ -202,44 +199,47 @@ pub fn overwrite_handler(msi_id: u32, handle: Box) -> bo set } -fn breakpoint(sepc: &mut usize){ - bare_println!("Exception::Breakpoint: A breakpoint set @0x{:x} ", sepc); +fn breakpoint(sepc: &mut usize) { + bare_println!("Exception::Breakpoint: A breakpoint set @0x{:x} ", sepc); - //sepc为触发中断指令ebreak的地址 - //防止无限循环中断,让sret返回时跳转到sepc的下一条指令地址 - *sepc +=2 + //sepc为触发中断指令ebreak的地址 + //防止无限循环中断,让sret返回时跳转到sepc的下一条指令地址 + *sepc += 2 } -fn page_fault(stval: usize, tf: &mut TrapFrame){ +fn page_fault(stval: usize, tf: &mut TrapFrame) { let this_scause = scause::read(); - info!("EXCEPTION Page Fault: {:?} @ {:#x}->{:#x}", this_scause.cause(), tf.sepc, stval); + info!( + "EXCEPTION Page Fault: {:?} @ {:#x}->{:#x}", + this_scause.cause(), + tf.sepc, + stval + ); let vaddr = stval; - use riscv::paging::{Rv39PageTable, PageTableFlags as PTF, *}; - use riscv::addr::{Page, PhysAddr, VirtAddr}; use crate::PageTableImpl; - use kernel_hal::{PageTableTrait, MMUFlags}; + use kernel_hal::{MMUFlags, PageTableTrait}; + use riscv::addr::{Page, PhysAddr, VirtAddr}; + use riscv::paging::{PageTableFlags as PTF, Rv39PageTable, *}; //let mut flags = PTF::VALID; let code = this_scause.code(); - let mut flags = - if code == 15 { - //MMUFlags::WRITE ??? - MMUFlags::READ | MMUFlags::WRITE - }else if code == 12 { - MMUFlags::EXECUTE - }else { - MMUFlags::READ - }; - - let linear_offset = - if stval >= PHYSICAL_MEMORY_OFFSET { - // Kernel - PHYSICAL_MEMORY_OFFSET - }else{ - // User - 0 - }; + let mut flags = if code == 15 { + //MMUFlags::WRITE ??? + MMUFlags::READ | MMUFlags::WRITE + } else if code == 12 { + MMUFlags::EXECUTE + } else { + MMUFlags::READ + }; + + let linear_offset = if stval >= PHYSICAL_MEMORY_OFFSET { + // Kernel + PHYSICAL_MEMORY_OFFSET + } else { + // User + 0 + }; /* let current = @@ -248,16 +248,19 @@ fn page_fault(stval: usize, tf: &mut TrapFrame){ map_range(&mut pt, vaddr, vaddr, linear_offset, flags); */ - let mut pti = - PageTableImpl { - root_paddr: satp::read().frame().start_address().as_usize(), - }; + let mut pti = PageTableImpl { + root_paddr: satp::read().frame().start_address().as_usize(), + }; let page = Page::of_addr(VirtAddr::new(vaddr)); if let Ok(pte) = pti.get().ref_entry(page) { let pte = unsafe { &mut *(pte as *mut PageTableEntry) }; if !pte.is_unused() { - debug!("PageAlreadyMapped -> {:#x?}, {:?}", pte.addr().as_usize(), pte.flags()); + debug!( + "PageAlreadyMapped -> {:#x?}, {:?}", + pte.addr().as_usize(), + pte.flags() + ); //TODO update flags pti.unmap(vaddr).unwrap(); @@ -266,16 +269,16 @@ fn page_fault(stval: usize, tf: &mut TrapFrame){ pti.map(vaddr, vaddr - linear_offset, flags).unwrap(); } -fn super_timer(){ +fn super_timer() { timer_set_next(); super::timer_tick(); //bare_print!("."); - //发生外界中断时,epc的指令还没有执行,故无需修改epc到下一条 + //发生外界中断时,epc的指令还没有执行,故无需修改epc到下一条 } -fn init_uart(){ +fn init_uart() { uart::Uart::new(0x1000_0000 + PHYSICAL_MEMORY_OFFSET).simple_init(); //但当没有SBI_CONSOLE_PUTCHAR时,却为什么不行? @@ -295,7 +298,7 @@ pub fn try_process_serial() -> bool { } } -pub fn init_ext(){ +pub fn init_ext() { // Qemu virt // UART0 = 10 plic::set_priority(10, 7); @@ -305,16 +308,16 @@ pub fn init_ext(){ bare_println!("+++ Setting up PLIC +++"); } -fn super_soft(){ +fn super_soft() { sbi::clear_ipi(); bare_println!("Interrupt::SupervisorSoft!"); } -pub fn init_soft(){ +pub fn init_soft() { unsafe { sie::set_ssoft(); } - bare_println!("+++ setup soft int! +++"); + bare_println!("+++ setup soft int! +++"); } #[export_name = "fetch_trap_num"] @@ -322,7 +325,6 @@ pub fn fetch_trap_num(_context: &UserContext) -> usize { scause::read().bits() } - pub fn wait_for_interrupt() { unsafe { // enable interrupt and disable diff --git a/kernel-hal-bare/src/arch/riscv/mod.rs b/kernel-hal-bare/src/arch/riscv/mod.rs index 93f5e8553..0d801213b 100644 --- a/kernel-hal-bare/src/arch/riscv/mod.rs +++ b/kernel-hal-bare/src/arch/riscv/mod.rs @@ -1,12 +1,12 @@ use super::super::*; use kernel_hal::{PageTableTrait, PhysAddr, VirtAddr}; -use riscv::asm::sfence_vma_all; use riscv::addr::Page; +use riscv::asm::sfence_vma_all; use riscv::paging::{PageTableFlags as PTF, *}; -use riscv::register::{time, satp, sie, stval}; +use riscv::register::{satp, sie, stval, time}; //use crate::sbi; -use core::fmt::{ self, Write }; use alloc::{collections::VecDeque, vec::Vec}; +use core::fmt::{self, Write}; mod sbi; @@ -19,63 +19,145 @@ static mut SATP: usize = 0; /// remap kernel with 4K page pub fn remap_the_kernel(dtb: usize) { - let root_frame = Frame::alloc().expect("failed to alloc frame"); - let root_vaddr = phys_to_virt(root_frame.paddr); - let root = unsafe { &mut *(root_vaddr as *mut PageTable) }; - root.zero(); - let mut pt = Rv39PageTable::new(root, PHYSICAL_MEMORY_OFFSET); - - let linear_offset = PHYSICAL_MEMORY_OFFSET; - //let mut flags = PTF::VALID | PTF::READABLE | PTF::WRITABLE | PTF::EXECUTABLE | PTF::USER; - - map_range(&mut pt, stext as usize, etext as usize - 1, linear_offset, PTF::VALID | PTF::READABLE | PTF::EXECUTABLE).unwrap(); - map_range(&mut pt, srodata as usize, erodata as usize, linear_offset, PTF::VALID | PTF::READABLE).unwrap(); - map_range(&mut pt, sdata as usize, edata as usize, linear_offset, PTF::VALID | PTF::READABLE | PTF::WRITABLE).unwrap(); - - // Stack - map_range(&mut pt, bootstack as usize, bootstacktop as usize - 1, linear_offset, PTF::VALID | PTF::READABLE | PTF::WRITABLE).unwrap(); - - map_range(&mut pt, sbss as usize, ebss as usize - 1, linear_offset, PTF::VALID | PTF::READABLE | PTF::WRITABLE).unwrap(); - - // Heap - map_range(&mut pt, end as usize, end as usize + PAGE_SIZE*512, linear_offset, PTF::VALID | PTF::READABLE | PTF::WRITABLE).unwrap(); - - // Device Tree - map_range(&mut pt, dtb, dtb + consts::MAX_DTB_SIZE, linear_offset, PTF::VALID | PTF::READABLE).unwrap(); - - // CLINT - map_range(&mut pt, 0x2000000 + PHYSICAL_MEMORY_OFFSET, 0x2010000 + PHYSICAL_MEMORY_OFFSET, linear_offset, PTF::VALID | PTF::READABLE | PTF::WRITABLE).unwrap(); - - // PLIC - map_range(&mut pt, 0xc000000 + PHYSICAL_MEMORY_OFFSET, 0xc00f000 + PHYSICAL_MEMORY_OFFSET, linear_offset, PTF::VALID | PTF::READABLE | PTF::WRITABLE).unwrap(); - map_range(&mut pt, 0xc200000 + PHYSICAL_MEMORY_OFFSET, 0xc20f000 + PHYSICAL_MEMORY_OFFSET, linear_offset, PTF::VALID | PTF::READABLE | PTF::WRITABLE).unwrap(); - - // UART0, VIRTIO - map_range(&mut pt, 0x10000000 + PHYSICAL_MEMORY_OFFSET, 0x1000f000 + PHYSICAL_MEMORY_OFFSET, linear_offset, PTF::VALID | PTF::READABLE | PTF::WRITABLE).unwrap(); - - - //写satp - let token = root_frame.paddr; - unsafe { - set_page_table(token); - SATP = token; - } + let root_frame = Frame::alloc().expect("failed to alloc frame"); + let root_vaddr = phys_to_virt(root_frame.paddr); + let root = unsafe { &mut *(root_vaddr as *mut PageTable) }; + root.zero(); + let mut pt = Rv39PageTable::new(root, PHYSICAL_MEMORY_OFFSET); + + let linear_offset = PHYSICAL_MEMORY_OFFSET; + //let mut flags = PTF::VALID | PTF::READABLE | PTF::WRITABLE | PTF::EXECUTABLE | PTF::USER; + + map_range( + &mut pt, + stext as usize, + etext as usize - 1, + linear_offset, + PTF::VALID | PTF::READABLE | PTF::EXECUTABLE, + ) + .unwrap(); + map_range( + &mut pt, + srodata as usize, + erodata as usize, + linear_offset, + PTF::VALID | PTF::READABLE, + ) + .unwrap(); + map_range( + &mut pt, + sdata as usize, + edata as usize, + linear_offset, + PTF::VALID | PTF::READABLE | PTF::WRITABLE, + ) + .unwrap(); + + // Stack + map_range( + &mut pt, + bootstack as usize, + bootstacktop as usize - 1, + linear_offset, + PTF::VALID | PTF::READABLE | PTF::WRITABLE, + ) + .unwrap(); + + map_range( + &mut pt, + sbss as usize, + ebss as usize - 1, + linear_offset, + PTF::VALID | PTF::READABLE | PTF::WRITABLE, + ) + .unwrap(); + + // Heap + map_range( + &mut pt, + end as usize, + end as usize + PAGE_SIZE * 512, + linear_offset, + PTF::VALID | PTF::READABLE | PTF::WRITABLE, + ) + .unwrap(); + + // Device Tree + map_range( + &mut pt, + dtb, + dtb + consts::MAX_DTB_SIZE, + linear_offset, + PTF::VALID | PTF::READABLE, + ) + .unwrap(); + + // CLINT + map_range( + &mut pt, + 0x2000000 + PHYSICAL_MEMORY_OFFSET, + 0x2010000 + PHYSICAL_MEMORY_OFFSET, + linear_offset, + PTF::VALID | PTF::READABLE | PTF::WRITABLE, + ) + .unwrap(); + + // PLIC + map_range( + &mut pt, + 0xc000000 + PHYSICAL_MEMORY_OFFSET, + 0xc00f000 + PHYSICAL_MEMORY_OFFSET, + linear_offset, + PTF::VALID | PTF::READABLE | PTF::WRITABLE, + ) + .unwrap(); + map_range( + &mut pt, + 0xc200000 + PHYSICAL_MEMORY_OFFSET, + 0xc20f000 + PHYSICAL_MEMORY_OFFSET, + linear_offset, + PTF::VALID | PTF::READABLE | PTF::WRITABLE, + ) + .unwrap(); + + // UART0, VIRTIO + map_range( + &mut pt, + 0x10000000 + PHYSICAL_MEMORY_OFFSET, + 0x1000f000 + PHYSICAL_MEMORY_OFFSET, + linear_offset, + PTF::VALID | PTF::READABLE | PTF::WRITABLE, + ) + .unwrap(); + + //写satp + let token = root_frame.paddr; + unsafe { + set_page_table(token); + SATP = token; + } - //use core::mem; - //mem::forget(pt); + //use core::mem; + //mem::forget(pt); - info!("remap the kernel @ {:#x}", token); + info!("remap the kernel @ {:#x}", token); } -pub fn map_range(page_table: &mut Rv39PageTable, mut start_addr: VirtAddr, mut end_addr: VirtAddr, linear_offset: usize, flags: PageTableFlags) -> Result<(),()> { +pub fn map_range( + page_table: &mut Rv39PageTable, + mut start_addr: VirtAddr, + mut end_addr: VirtAddr, + linear_offset: usize, + flags: PageTableFlags, +) -> Result<(), ()> { trace!("Mapping range addr: {:#x} ~ {:#x}", start_addr, end_addr); - start_addr = start_addr & !(PAGE_SIZE -1); + start_addr = start_addr & !(PAGE_SIZE - 1); let mut start_page = start_addr / PAGE_SIZE; //end_addr = (end_addr + PAGE_SIZE - 1) & !(PAGE_SIZE -1); //let end_page = (end_addr - 1) / PAGE_SIZE; - end_addr = end_addr & !(PAGE_SIZE -1); + end_addr = end_addr & !(PAGE_SIZE - 1); let end_page = end_addr / PAGE_SIZE; while start_page <= end_page { @@ -85,12 +167,23 @@ pub fn map_range(page_table: &mut Rv39PageTable, mut start_addr: VirtAddr, mut e start_page += 1; - trace!("map_range: {:#x} -> {:#x}, flags={:?}", vaddr, vaddr - linear_offset, flags); - page_table.map_to(page, frame, flags, &mut FrameAllocatorImpl) + trace!( + "map_range: {:#x} -> {:#x}, flags={:?}", + vaddr, + vaddr - linear_offset, + flags + ); + page_table + .map_to(page, frame, flags, &mut FrameAllocatorImpl) .unwrap() .flush(); } - info!("map range from {:#x} to {:#x}, flags: {:?}", start_addr, end_page * PAGE_SIZE, flags); + info!( + "map range from {:#x} to {:#x}, flags: {:?}", + start_addr, + end_page * PAGE_SIZE, + flags + ); Ok(()) } @@ -165,7 +258,13 @@ impl PageTableTrait for PageTableImpl { .unwrap() .flush(); - trace!("PageTable: {:#X}, map: {:x?} -> {:x?}, flags={:?}", self.table_phys() as usize, vaddr, paddr, flags); + trace!( + "PageTable: {:#X}, map: {:x?} -> {:x?}, flags={:?}", + self.table_phys() as usize, + vaddr, + paddr, + flags + ); Ok(()) } @@ -175,7 +274,11 @@ impl PageTableTrait for PageTableImpl { let mut pt = self.get(); let page = Page::of_addr(riscv::addr::VirtAddr::new(vaddr)); pt.unmap(page).unwrap().1.flush(); - trace!("PageTable: {:#X}, unmap: {:x?}", self.table_phys() as usize, vaddr); + trace!( + "PageTable: {:#X}, unmap: {:x?}", + self.table_phys() as usize, + vaddr + ); Ok(()) } @@ -188,10 +291,15 @@ impl PageTableTrait for PageTableImpl { if vaddr == 0x11b000 { info!("protect 0x11b3c0: {:#X?}", self.query(0x11b3c0)); - }else if vaddr == 0xc4000 { + } else if vaddr == 0xc4000 { info!("protect 0xc44b6: {:#X?}", self.query(0xc44b6)); } - trace!("PageTable: {:#X}, protect: {:x?}, flags={:?}", self.table_phys() as usize, vaddr, flags); + trace!( + "PageTable: {:#X}, protect: {:x?}, flags={:?}", + self.table_phys() as usize, + vaddr, + flags + ); Ok(()) } @@ -216,7 +324,7 @@ impl PageTableTrait for PageTableImpl { /// Activate this page table #[export_name = "hal_pt_activate"] - fn activate(&self){ + fn activate(&self) { let now_token = satp::read().bits(); let new_token = self.table_phys(); if now_token != new_token { @@ -284,7 +392,8 @@ impl FrameDeallocator for FrameAllocatorImpl { lazy_static! { static ref STDIN: Mutex> = Mutex::new(VecDeque::new()); - static ref STDIN_CALLBACK: Mutex bool + Send + Sync>>> = Mutex::new(Vec::new()); + static ref STDIN_CALLBACK: Mutex bool + Send + Sync>>> = + Mutex::new(Vec::new()); } //调用这里 @@ -344,41 +453,46 @@ pub fn getchar_option() -> Option { //////////// -pub fn putchar(ch: char){ - sbi::console_putchar(ch as u8 as usize); +pub fn putchar(ch: char) { + sbi::console_putchar(ch as u8 as usize); } -pub fn puts(s: &str){ - for ch in s.chars(){ - putchar(ch); - } +pub fn puts(s: &str) { + for ch in s.chars() { + putchar(ch); + } } struct Stdout; impl fmt::Write for Stdout { - fn write_str(&mut self, s: &str) -> fmt::Result { - puts(s); - Ok(()) - } + fn write_str(&mut self, s: &str) -> fmt::Result { + puts(s); + Ok(()) + } } pub fn putfmt(fmt: fmt::Arguments) { - Stdout.write_fmt(fmt).unwrap(); + Stdout.write_fmt(fmt).unwrap(); } //////////// struct Stdout1; impl fmt::Write for Stdout1 { - fn write_str(&mut self, s: &str) -> fmt::Result { - //每次都创建一个新的Uart ? 内存位置始终相同 - write!(uart::Uart::new(0x1000_0000 + PHYSICAL_MEMORY_OFFSET), "{}", s).unwrap(); + fn write_str(&mut self, s: &str) -> fmt::Result { + //每次都创建一个新的Uart ? 内存位置始终相同 + write!( + uart::Uart::new(0x1000_0000 + PHYSICAL_MEMORY_OFFSET), + "{}", + s + ) + .unwrap(); - Ok(()) - } + Ok(()) + } } pub fn putfmt_uart(fmt: fmt::Arguments) { - Stdout1.write_fmt(fmt).unwrap(); + Stdout1.write_fmt(fmt).unwrap(); } //////////// @@ -439,15 +553,14 @@ pub fn init(config: Config) { sbi::send_ipi(0); */ - unsafe{ + unsafe { llvm_asm!("ebreak"::::"volatile"); } - bare_println!("Setup virtio @devicetree {:#x}", config.dtb); + bare_println!("Setup virtio @devicetree {:#x}", config.dtb); //virtio::init(config.dtb); virtio::device_tree::init(config.dtb); - } pub struct Config { @@ -460,10 +573,7 @@ pub fn fetch_fault_vaddr() -> VirtAddr { stval::read() as _ } -static mut CONFIG: Config = Config { - mconfig: 0, - dtb: 0, -}; +static mut CONFIG: Config = Config { mconfig: 0, dtb: 0 }; /// This structure represents the information that the bootloader passes to the kernel. #[repr(C)] @@ -480,7 +590,6 @@ pub struct BootInfo { //pub acpi2_rsdp_addr: u64, /// Physical address of SMBIOS, 产品管理信息的结构表 //pub smbios_addr: u64, - pub hartid: u64, pub dtb_addr: u64, @@ -510,4 +619,3 @@ mod plic; mod uart; pub mod virtio; - diff --git a/kernel-hal-bare/src/arch/riscv/plic.rs b/kernel-hal-bare/src/arch/riscv/plic.rs index 89ba2cdb0..c7bbb1956 100644 --- a/kernel-hal-bare/src/arch/riscv/plic.rs +++ b/kernel-hal-bare/src/arch/riscv/plic.rs @@ -1,7 +1,7 @@ -use super::uart; +use super::consts::PHYSICAL_MEMORY_OFFSET; use super::interrupt; +use super::uart; use crate::putfmt; //For bare_println -use super::consts::PHYSICAL_MEMORY_OFFSET; const MMODE: usize = 0; @@ -12,9 +12,9 @@ const MMODE: usize = 0; // //Source 1 priority: 0x0c000004 //Source 2 priority: 0x0c000008 -const PLIC_PRIORITY: usize = 0x0c00_0000 + PHYSICAL_MEMORY_OFFSET; +const PLIC_PRIORITY: usize = 0x0c00_0000 + PHYSICAL_MEMORY_OFFSET; //Pending 32位寄存器,每一位标记一个中断源ID -const PLIC_PENDING: usize = 0x0c00_1000 + PHYSICAL_MEMORY_OFFSET; +const PLIC_PENDING: usize = 0x0c00_1000 + PHYSICAL_MEMORY_OFFSET; //Target 0 threshold: 0x0c200000 //Target 0 claim : 0x0c200004 @@ -22,8 +22,16 @@ const PLIC_PENDING: usize = 0x0c00_1000 + PHYSICAL_MEMORY_OFFSET; //Target 1 threshold: 0x0c201000 * //Target 1 claim : 0x0c201004 * -const PLIC_THRESHOLD: usize = if MMODE == 1 { 0x0c200000 + PHYSICAL_MEMORY_OFFSET }else{ 0x0c201000 + PHYSICAL_MEMORY_OFFSET }; -const PLIC_CLAIM: usize = if MMODE == 1 { 0x0c200004 + PHYSICAL_MEMORY_OFFSET }else{ 0x0c201004 + PHYSICAL_MEMORY_OFFSET }; +const PLIC_THRESHOLD: usize = if MMODE == 1 { + 0x0c200000 + PHYSICAL_MEMORY_OFFSET +} else { + 0x0c201000 + PHYSICAL_MEMORY_OFFSET +}; +const PLIC_CLAIM: usize = if MMODE == 1 { + 0x0c200004 + PHYSICAL_MEMORY_OFFSET +} else { + 0x0c201004 + PHYSICAL_MEMORY_OFFSET +}; //注意一个核的不同权限模式是不同Target //Target: 0 1 2 3 4 5 @@ -31,96 +39,99 @@ const PLIC_CLAIM: usize = if MMODE == 1 { 0x0c200004 + PHYSICAL_MEMORY_OFFS // //target 0 enable: 0x0c002000 //target 1 enable: 0x0c002080 * -const PLIC_INT_ENABLE: usize = if MMODE == 1 { 0x0c002000 + PHYSICAL_MEMORY_OFFSET }else{ 0x0c002080 + PHYSICAL_MEMORY_OFFSET }; //基于opensbi后一般运行于Hart0 S态,故为Target1 +const PLIC_INT_ENABLE: usize = if MMODE == 1 { + 0x0c002000 + PHYSICAL_MEMORY_OFFSET +} else { + 0x0c002080 + PHYSICAL_MEMORY_OFFSET +}; //基于opensbi后一般运行于Hart0 S态,故为Target1 //PLIC是async cause 11 //声明claim会清除中断源上的相应pending位。 //即使mip寄存器的MEIP位没有置位, 也可以claim; 声明不被阀值寄存器的设置影响; //获取按优先级排序后的下一个可用的中断ID pub fn next() -> Option { - let claim_reg = PLIC_CLAIM as *const u32; - let claim_no; - unsafe { - claim_no = claim_reg.read_volatile(); - } - if claim_no == 0 { - None //没有可用中断待定 - }else{ - Some(claim_no) - } + let claim_reg = PLIC_CLAIM as *const u32; + let claim_no; + unsafe { + claim_no = claim_reg.read_volatile(); + } + if claim_no == 0 { + None //没有可用中断待定 + } else { + Some(claim_no) + } } //claim时,PLIC不再从该相同设备监听中断 //写claim寄存器,告诉PLIC处理完成该中断 // id 应该来源于next()函数 pub fn complete(id: u32) { - let complete_reg = PLIC_CLAIM as *mut u32; //和claim相同寄存器,只是读或写的区别 - unsafe { - complete_reg.write_volatile(id); - } + let complete_reg = PLIC_CLAIM as *mut u32; //和claim相同寄存器,只是读或写的区别 + unsafe { + complete_reg.write_volatile(id); + } } //看的中断ID是否pending pub fn is_pending(id: u32) -> bool { - let pend = PLIC_PENDING as *const u32; - let actual_id = 1 << id; - let pend_ids; - unsafe { - pend_ids = pend.read_volatile(); - } - actual_id & pend_ids != 0 + let pend = PLIC_PENDING as *const u32; + let actual_id = 1 << id; + let pend_ids; + unsafe { + pend_ids = pend.read_volatile(); + } + actual_id & pend_ids != 0 } //使能target中某个给定ID的中断 //中断ID可查找qemu/include/hw/riscv/virt.h, 如:UART0_IRQ = 10 pub fn enable(id: u32) { - let enables = PLIC_INT_ENABLE as *mut u32; //32位的寄存器 - let actual_id = 1 << id; - unsafe { - enables.write_volatile(enables.read_volatile() | actual_id); + let enables = PLIC_INT_ENABLE as *mut u32; //32位的寄存器 + let actual_id = 1 << id; + unsafe { + enables.write_volatile(enables.read_volatile() | actual_id); // 0x0c00_2000 <=~ (1 << 10) - } + } } //设置中断源的优先级,分0~7级,7是最高级, eg:这里id=10, 表示第10个中断源的设置, prio=1 pub fn set_priority(id: u32, prio: u8) { - let actual_prio = prio as u32 & 7; - let prio_reg = PLIC_PRIORITY as *mut u32; - unsafe { - prio_reg.add(id as usize).write_volatile(actual_prio); //0x0c000000 + 4 * 10 <= 1 = 1 & 7 - } + let actual_prio = prio as u32 & 7; + let prio_reg = PLIC_PRIORITY as *mut u32; + unsafe { + prio_reg.add(id as usize).write_volatile(actual_prio); //0x0c000000 + 4 * 10 <= 1 = 1 & 7 + } } //设置中断target的全局阀值[0..7], <= threshold会被屏蔽 pub fn set_threshold(tsh: u8) { - let actual_tsh = tsh & 7; //使用0b111保留最后三位 - let tsh_reg = PLIC_THRESHOLD as *mut u32; - unsafe { - tsh_reg.write_volatile(actual_tsh as u32); // 0x0c20_0000 <= 0 = 0 & 7 - } + let actual_tsh = tsh & 7; //使用0b111保留最后三位 + let tsh_reg = PLIC_THRESHOLD as *mut u32; + unsafe { + tsh_reg.write_volatile(actual_tsh as u32); // 0x0c20_0000 <= 0 = 0 & 7 + } } pub fn handle_interrupt() { - if let Some(interrupt) = next() { - match interrupt { - 1..=8 => { - //virtio::handle_interrupt(interrupt); - bare_println!("plic virtio external interrupt: {}", interrupt); - }, - 10 => { //UART中断ID是10 + if let Some(interrupt) = next() { + match interrupt { + 1..=8 => { + //virtio::handle_interrupt(interrupt); + bare_println!("plic virtio external interrupt: {}", interrupt); + } + 10 => { + //UART中断ID是10 uart::handle_interrupt(); //换用sbi的方式获取字符 //interrupt::try_process_serial(); - }, - _ => { - bare_println!("Unknown external interrupt: {}", interrupt); - }, - } - //这将复位pending的中断,允许UART再次中断。 - //否则,UART将被“卡住” - complete(interrupt); - } + } + _ => { + bare_println!("Unknown external interrupt: {}", interrupt); + } + } + //这将复位pending的中断,允许UART再次中断。 + //否则,UART将被“卡住” + complete(interrupt); + } } - - diff --git a/kernel-hal-bare/src/arch/riscv/sbi.rs b/kernel-hal-bare/src/arch/riscv/sbi.rs index f2b2244da..67ce257e7 100644 --- a/kernel-hal-bare/src/arch/riscv/sbi.rs +++ b/kernel-hal-bare/src/arch/riscv/sbi.rs @@ -1,37 +1,37 @@ -pub fn console_putchar(ch: usize){ - sbi_call(SBI_CONSOLE_PUTCHAR, ch, 0, 0); +pub fn console_putchar(ch: usize) { + sbi_call(SBI_CONSOLE_PUTCHAR, ch, 0, 0); } pub fn console_getchar() -> usize { - return sbi_call(SBI_CONSOLE_GETCHAR, 0, 0, 0); + return sbi_call(SBI_CONSOLE_GETCHAR, 0, 0, 0); } -fn sbi_call(which: usize, arg0: usize, arg1: usize, arg2: usize) -> usize{ - let ret: usize; - unsafe{ - llvm_asm!("ecall" +fn sbi_call(which: usize, arg0: usize, arg1: usize, arg2: usize) -> usize { + let ret: usize; + unsafe { + llvm_asm!("ecall" :"={x10}"(ret) :"{x10}"(arg0), "{x11}"(arg1), "{x12}"(arg2), "{x17}"(which) :"memory" :"volatile"); - } - ret + } + ret } -pub fn set_timer(stime_value: u64){ - #[cfg(target_pointer_width = "32")] - sbi_call(SBI_SET_TIMER, stime_value as usize, (stime_value >> 32), 0); +pub fn set_timer(stime_value: u64) { + #[cfg(target_pointer_width = "32")] + sbi_call(SBI_SET_TIMER, stime_value as usize, (stime_value >> 32), 0); - #[cfg(target_pointer_width = "64")] - sbi_call(SBI_SET_TIMER, stime_value as usize, 0, 0); + #[cfg(target_pointer_width = "64")] + sbi_call(SBI_SET_TIMER, stime_value as usize, 0, 0); } -pub fn clear_ipi(){ - sbi_call(SBI_CLEAR_IPI, 0, 0, 0); +pub fn clear_ipi() { + sbi_call(SBI_CLEAR_IPI, 0, 0, 0); } -pub fn send_ipi(sipi_value: usize){ - sbi_call(SBI_SEND_IPI, sipi_value, 0, 0); +pub fn send_ipi(sipi_value: usize) { + sbi_call(SBI_SEND_IPI, sipi_value, 0, 0); } const SBI_SET_TIMER: usize = 0; diff --git a/kernel-hal-bare/src/arch/riscv/uart.rs b/kernel-hal-bare/src/arch/riscv/uart.rs index a3041c4da..f1b4d15ce 100644 --- a/kernel-hal-bare/src/arch/riscv/uart.rs +++ b/kernel-hal-bare/src/arch/riscv/uart.rs @@ -1,157 +1,151 @@ -use core::convert::TryInto; -use core::fmt::{Error, Write}; use super::consts::PHYSICAL_MEMORY_OFFSET; use crate::putfmt; +use core::convert::TryInto; +use core::fmt::{Error, Write}; //use crate::console::push_stdin; pub struct Uart { - base_address: usize, + base_address: usize, } // 结构体Uart的实现块 impl Uart { - pub fn new(base_address: usize) -> Self { - Uart { - base_address - } - } -/* -uart初始化 -设置字长为8-bits (LCR[1:0]) -使能先进先出FIFOs (FCR[0]) -使能接受中断(IER[0]), 在这只使用轮询的方式而不用中断 - -*/ -pub fn init(&mut self) { - let ptr = self.base_address as *mut u8; - unsafe { - // LCR at base_address + 3 - // 置位 bit 0 bit 1 - let lcr = (1 << 0) | (1 << 1); - ptr.add(3).write_volatile(lcr); - - // FCR at offset 2 - ptr.add(2).write_volatile(1 << 0); - - //IER at offset 1 - ptr.add(1).write_volatile(1 << 0); - - // 设置波特率,除子,取整等 - // 2.729 MHz (22,729,000 cycles per second) --> 波特率 2400 (BAUD) - - // 根据NS16550a规格说明书计算出divisor - // divisor = ceil( (clock_hz) / (baud_sps x 16) ) - // divisor = ceil( 22_729_000 / (2400 x 16) ) = ceil( 591.901 ) = 592 - - - // divisor寄存器是16 bits - let divisor: u16 = 592; - //let divisor_least: u8 = divisor & 0xff; - //let divisor_most: u8 = divisor >> 8; - let divisor_least: u8 = (divisor & 0xff).try_into().unwrap(); - let divisor_most: u8 = (divisor >> 8).try_into().unwrap(); - - // DLL和DLM会与其它寄存器共用基地址,需要设置DLAB来切换选择寄存器 - // LCR base_address + 3, DLAB = 1 - ptr.add(3).write_volatile(lcr | 1 << 7); - - //写DLL和DLM来设置波特率, 把频率22.729 MHz的时钟划分为每秒2400个信号 - ptr.add(0).write_volatile(divisor_least); - ptr.add(1).write_volatile(divisor_most); - - // 设置后不需要再动了, 清空DLAB - ptr.add(3).write_volatile(lcr); - } -} + pub fn new(base_address: usize) -> Self { + Uart { base_address } + } + /* + uart初始化 + 设置字长为8-bits (LCR[1:0]) + 使能先进先出FIFOs (FCR[0]) + 使能接受中断(IER[0]), 在这只使用轮询的方式而不用中断 + + */ + pub fn init(&mut self) { + let ptr = self.base_address as *mut u8; + unsafe { + // LCR at base_address + 3 + // 置位 bit 0 bit 1 + let lcr = (1 << 0) | (1 << 1); + ptr.add(3).write_volatile(lcr); + + // FCR at offset 2 + ptr.add(2).write_volatile(1 << 0); + + //IER at offset 1 + ptr.add(1).write_volatile(1 << 0); + + // 设置波特率,除子,取整等 + // 2.729 MHz (22,729,000 cycles per second) --> 波特率 2400 (BAUD) + + // 根据NS16550a规格说明书计算出divisor + // divisor = ceil( (clock_hz) / (baud_sps x 16) ) + // divisor = ceil( 22_729_000 / (2400 x 16) ) = ceil( 591.901 ) = 592 + + // divisor寄存器是16 bits + let divisor: u16 = 592; + //let divisor_least: u8 = divisor & 0xff; + //let divisor_most: u8 = divisor >> 8; + let divisor_least: u8 = (divisor & 0xff).try_into().unwrap(); + let divisor_most: u8 = (divisor >> 8).try_into().unwrap(); + + // DLL和DLM会与其它寄存器共用基地址,需要设置DLAB来切换选择寄存器 + // LCR base_address + 3, DLAB = 1 + ptr.add(3).write_volatile(lcr | 1 << 7); + + //写DLL和DLM来设置波特率, 把频率22.729 MHz的时钟划分为每秒2400个信号 + ptr.add(0).write_volatile(divisor_least); + ptr.add(1).write_volatile(divisor_most); + + // 设置后不需要再动了, 清空DLAB + ptr.add(3).write_volatile(lcr); + } + } -pub fn simple_init(&mut self) { - let ptr = self.base_address as *mut u8; - unsafe { - // Enable FIFO; (base + 2) - ptr.add(2).write_volatile(0xC7); + pub fn simple_init(&mut self) { + let ptr = self.base_address as *mut u8; + unsafe { + // Enable FIFO; (base + 2) + ptr.add(2).write_volatile(0xC7); - // MODEM Ctrl; (base + 4) - ptr.add(4).write_volatile(0x0B); + // MODEM Ctrl; (base + 4) + ptr.add(4).write_volatile(0x0B); - // Enable interrupts; (base + 1) - ptr.add(1).write_volatile(0x01); + // Enable interrupts; (base + 1) + ptr.add(1).write_volatile(0x01); + } } -} - -pub fn get(&mut self) -> Option { - let ptr = self.base_address as *mut u8; - unsafe { - //查看LCR, DR位为1则有数据 - if ptr.add(5).read_volatile() & 0b1 == 0 { - None - } else { - Some(ptr.add(0).read_volatile()) - } - } -} - -pub fn put(&mut self, c: u8) { - let ptr = self.base_address as *mut u8; - unsafe { - //此时transmitter empty - ptr.add(0).write_volatile(c); - } -} + pub fn get(&mut self) -> Option { + let ptr = self.base_address as *mut u8; + unsafe { + //查看LCR, DR位为1则有数据 + if ptr.add(5).read_volatile() & 0b1 == 0 { + None + } else { + Some(ptr.add(0).read_volatile()) + } + } + } + pub fn put(&mut self, c: u8) { + let ptr = self.base_address as *mut u8; + unsafe { + //此时transmitter empty + ptr.add(0).write_volatile(c); + } + } } // 需要实现的write_str()重要函数 impl Write for Uart { - fn write_str(&mut self, out: &str) -> Result<(), Error> { - for c in out.bytes(){ - self.put(c); - } - Ok(()) - } + fn write_str(&mut self, out: &str) -> Result<(), Error> { + for c in out.bytes() { + self.put(c); + } + Ok(()) + } } /* fn unsafe mmio_write(address: usize, offset: usize, value: u8) { - //write_volatile() 是 *mut raw 的成员; - //new_pointer = old_pointer + sizeof(pointer_type) * offset - //也可使用reg.offset + //write_volatile() 是 *mut raw 的成员; + //new_pointer = old_pointer + sizeof(pointer_type) * offset + //也可使用reg.offset - let reg = address as *mut u8; - reg.add(offset).write_volatile(value); + let reg = address as *mut u8; + reg.add(offset).write_volatile(value); } fn unsafe mmio_read(address: usize, offset: usize, value: u8) -> u8 { - let reg = address as *mut u8; + let reg = address as *mut u8; - //读取8 bits - reg.add(offset).read_volatile(value) //无分号可直接返回值 + //读取8 bits + reg.add(offset).read_volatile(value) //无分号可直接返回值 } */ pub fn handle_interrupt() { - let mut my_uart = Uart::new(0x1000_0000 + PHYSICAL_MEMORY_OFFSET); - if let Some(c) = my_uart.get() { - //CONSOLE - //push_stdin(c); + let mut my_uart = Uart::new(0x1000_0000 + PHYSICAL_MEMORY_OFFSET); + if let Some(c) = my_uart.get() { + //CONSOLE + //push_stdin(c); super::serial_put(c); /* * 因serial_write()已可以被回调输出了,这里则不再需要了 - match c { - 0x7f => { //0x8 [backspace] ; 而实际qemu运行,[backspace]键输出0x7f, 表示del - bare_print!("{} {}", 8 as char, 8 as char); - }, - 10 | 13 => { // 新行或回车 - bare_println!(); - }, - _ => { - bare_print!("{}", c as char); - }, - } + match c { + 0x7f => { //0x8 [backspace] ; 而实际qemu运行,[backspace]键输出0x7f, 表示del + bare_print!("{} {}", 8 as char, 8 as char); + }, + 10 | 13 => { // 新行或回车 + bare_println!(); + }, + _ => { + bare_print!("{}", c as char); + }, + } */ - } + } } - diff --git a/kernel-hal-bare/src/arch/riscv/virtio/virtio.rs b/kernel-hal-bare/src/arch/riscv/virtio/virtio.rs index 3bfd6abe4..84249effd 100644 --- a/kernel-hal-bare/src/arch/riscv/virtio/virtio.rs +++ b/kernel-hal-bare/src/arch/riscv/virtio/virtio.rs @@ -1,4 +1,4 @@ -use crate::{hal_frame_alloc_contiguous, frame_dealloc, PAGE_SIZE, phys_to_virt, virt_to_phys}; +use crate::{frame_dealloc, hal_frame_alloc_contiguous, phys_to_virt, virt_to_phys, PAGE_SIZE}; use device_tree::util::SliceRead; use device_tree::Node; use log::*; @@ -16,7 +16,7 @@ pub fn virtio_probe(node: &Node) { let size = reg.as_slice().read_be_u64(8).unwrap(); // assuming one page assert_eq!(size as usize, PAGE_SIZE); - + /* 一一映射 let vaddr = paddr; unsafe{ @@ -47,13 +47,12 @@ pub fn virtio_probe(node: &Node) { /// virtio_mmio ///////// /// virtio_blk - use alloc::string::String; use alloc::sync::Arc; use alloc::format; -use super::{DeviceType, Driver, BlockDriver, BLK_DRIVERS, DRIVERS}; +use super::{BlockDriver, DeviceType, Driver, BLK_DRIVERS, DRIVERS}; //use crate::{sync::SpinNoIrqLock as Mutex}; use spin::Mutex; @@ -76,7 +75,6 @@ impl Driver for VirtIOBlkDriver { fn as_block(&self) -> Option<&dyn BlockDriver> { None } - } impl BlockDriver for VirtIOBlkDriver { @@ -102,7 +100,7 @@ pub fn virtio_blk_init(header: &'static mut VirtIOHeader) { #[no_mangle] extern "C" fn virtio_dma_alloc(pages: usize) -> PhysAddr { - let paddr = unsafe{ hal_frame_alloc_contiguous(pages, 0).unwrap() }; + let paddr = unsafe { hal_frame_alloc_contiguous(pages, 0).unwrap() }; trace!("alloc DMA: paddr={:#x}, pages={}", paddr, pages); paddr } @@ -110,7 +108,7 @@ extern "C" fn virtio_dma_alloc(pages: usize) -> PhysAddr { #[no_mangle] extern "C" fn virtio_dma_dealloc(paddr: PhysAddr, pages: usize) -> i32 { for i in 0..pages { - unsafe{ + unsafe { frame_dealloc(&(paddr + i * PAGE_SIZE)); } } diff --git a/kernel-hal-bare/src/arch/x86_64/mod.rs b/kernel-hal-bare/src/arch/x86_64/mod.rs index e242871e4..2583b4800 100644 --- a/kernel-hal-bare/src/arch/x86_64/mod.rs +++ b/kernel-hal-bare/src/arch/x86_64/mod.rs @@ -105,8 +105,12 @@ impl PageTableTrait for PageTableImpl { trace!("unmap: {:x?} in {:#x?}", vaddr, self.root_paddr); } Err(mapper::UnmapError::PageNotMapped) => { - trace!("unmap not mapped, skip: {:x?} in {:#x?}", vaddr, self.root_paddr); - return Ok(()) + trace!( + "unmap not mapped, skip: {:x?} in {:#x?}", + vaddr, + self.root_paddr + ); + return Ok(()); } Err(err) => { debug!( @@ -138,7 +142,8 @@ impl PageTableTrait for PageTableImpl { let pt = self.get(); let ret = pt .translate_addr(x86_64::VirtAddr::new(vaddr as u64)) - .map(|addr| addr.as_u64() as PhysAddr).ok_or(()); + .map(|addr| addr.as_u64() as PhysAddr) + .ok_or(()); trace!("query: {:x?} => {:x?}", vaddr, ret); ret } @@ -274,7 +279,8 @@ pub fn putfmt(fmt: Arguments) { lazy_static! { static ref STDIN: Mutex> = Mutex::new(VecDeque::new()); - static ref STDIN_CALLBACK: Mutex bool + Send + Sync>>> = Mutex::new(Vec::new()); + static ref STDIN_CALLBACK: Mutex bool + Send + Sync>>> = + Mutex::new(Vec::new()); } /// Put a char by serial interrupt handler. diff --git a/linux-loader/src/lib.rs b/linux-loader/src/lib.rs index c85e7c538..48aaff3ac 100644 --- a/linux-loader/src/lib.rs +++ b/linux-loader/src/lib.rs @@ -12,7 +12,7 @@ extern crate log; use { alloc::{boxed::Box, string::String, sync::Arc, vec::Vec}, core::{future::Future, pin::Pin}, - kernel_hal::{UserContext, MMUFlags}, + kernel_hal::{MMUFlags, UserContext}, linux_object::{ fs::{vfs::FileSystem, INodeExt}, loader::LinuxElfLoader, @@ -20,10 +20,7 @@ use { thread::ThreadExt, }, linux_syscall::Syscall, - zircon_object::{ - task::*, - object::KernelObject, - } + zircon_object::{object::KernelObject, task::*}, }; /// Create and run main Linux process @@ -146,10 +143,12 @@ async fn new_thread(thread: CurrentThread) { //kernel_hal::InterruptManager::handle(trap_num as u8); } - _ => panic!("not supported pid: {} interrupt {} from user mode. {:#x?}", pid, trap_num, cx), + _ => panic!( + "not supported pid: {} interrupt {} from user mode. {:#x?}", + pid, trap_num, cx + ), } - - }else{ + } else { match trap_num { // syscall 8 => handle_syscall(&thread, &mut cx).await, @@ -166,7 +165,10 @@ async fn new_thread(thread: CurrentThread) { MMUFlags::READ }; - info!("page fualt from pid: {} user mode, vaddr:{:#x}, trap:{}", pid, vaddr, trap_num); + info!( + "page fualt from pid: {} user mode, vaddr:{:#x}, trap:{}", + pid, vaddr, trap_num + ); let vmar = thread.proc().vmar(); match vmar.handle_page_fault(vaddr, flags) { Ok(()) => {} @@ -175,7 +177,10 @@ async fn new_thread(thread: CurrentThread) { } } } - _ => panic!("not supported pid: {} exception {} from user mode. {:#x?}", pid, trap_num, cx), + _ => panic!( + "not supported pid: {} exception {} from user mode. {:#x?}", + pid, trap_num, cx + ), } } @@ -209,7 +214,14 @@ async fn handle_syscall(thread: &CurrentThread, regs: &mut GeneralRegs) { async fn handle_syscall(thread: &CurrentThread, cx: &mut UserContext) { trace!("syscall: {:#x?}", cx.general); let num = cx.general.a7 as u32; - let args = [cx.general.a0, cx.general.a1, cx.general.a2, cx.general.a3, cx.general.a4, cx.general.a5]; + let args = [ + cx.general.a0, + cx.general.a1, + cx.general.a2, + cx.general.a3, + cx.general.a4, + cx.general.a5, + ]; // add before fork cx.sepc += 4; diff --git a/linux-object/src/fs/pipe.rs b/linux-object/src/fs/pipe.rs index 3c769ccf3..9fb163542 100644 --- a/linux-object/src/fs/pipe.rs +++ b/linux-object/src/fs/pipe.rs @@ -145,7 +145,7 @@ impl INode for Pipe { #[must_use = "future does nothing unless polled/`await`-ed"] struct PipeFuture<'a> { pipe: &'a Pipe, - }; + } impl<'a> Future for PipeFuture<'a> { type Output = Result; diff --git a/linux-object/src/fs/stdio.rs b/linux-object/src/fs/stdio.rs index cd358d370..308443755 100644 --- a/linux-object/src/fs/stdio.rs +++ b/linux-object/src/fs/stdio.rs @@ -78,7 +78,7 @@ impl INode for Stdin { #[must_use = "future does nothing unless polled/`await`-ed"] struct SerialFuture<'a> { stdin: &'a Stdin, - }; + } impl<'a> Future for SerialFuture<'a> { type Output = Result; diff --git a/linux-object/src/loader/mod.rs b/linux-object/src/loader/mod.rs index 61b2ad406..d010c775e 100644 --- a/linux-object/src/loader/mod.rs +++ b/linux-object/src/loader/mod.rs @@ -88,7 +88,10 @@ impl LinuxElfLoader { stack_vmo.write(self.stack_pages * PAGE_SIZE - init_stack.len(), &init_stack)?; sp -= init_stack.len(); - debug!("ProcInitInfo auxv: {:#x?}\nentry:{:#x}, sp:{:#x}", info.auxv, entry, sp); + debug!( + "ProcInitInfo auxv: {:#x?}\nentry:{:#x}, sp:{:#x}", + info.auxv, entry, sp + ); Ok((entry, sp)) } diff --git a/linux-syscall/build.rs b/linux-syscall/build.rs index 72b2e950b..4eb07bc81 100644 --- a/linux-syscall/build.rs +++ b/linux-syscall/build.rs @@ -4,7 +4,7 @@ fn main() { let target = std::env::var("arch").unwrap(); if target.contains("riscv64") { println!("cargo:rerun-if-changed=src/riscv64_syscall.h.in"); - }else{ + } else { println!("cargo:rerun-if-changed=src/syscall.h.in"); } @@ -19,7 +19,7 @@ fn main() { let data = if target.contains("riscv64") { std::fs::read_to_string("src/riscv64_syscall.h.in").unwrap() - }else{ + } else { std::fs::read_to_string("src/syscall.h.in").unwrap() }; diff --git a/linux-syscall/src/lib.rs b/linux-syscall/src/lib.rs index 491de76b5..611eda866 100644 --- a/linux-syscall/src/lib.rs +++ b/linux-syscall/src/lib.rs @@ -65,7 +65,12 @@ pub struct Syscall<'a> { impl Syscall<'_> { /// syscall entry function pub async fn syscall(&mut self, num: u32, args: [usize; 6]) -> isize { - debug!("pid: {} syscall: num={}, args={:x?}", self.zircon_process().id(), num, args); + debug!( + "pid: {} syscall: num={}, args={:x?}", + self.zircon_process().id(), + num, + args + ); let sys_type = match Sys::try_from(num) { Ok(t) => t, Err(_) => { diff --git a/linux-syscall/src/task.rs b/linux-syscall/src/task.rs index 20fc83f3a..97e3a2635 100644 --- a/linux-syscall/src/task.rs +++ b/linux-syscall/src/task.rs @@ -21,7 +21,7 @@ impl Syscall<'_> { /// Fork the current process. Return the child's PID. pub fn sys_fork(&self) -> SysResult { info!("fork:"); - let new_proc = Process::fork_from(self.zircon_process(), false)?;// old pt NULL here + let new_proc = Process::fork_from(self.zircon_process(), false)?; // old pt NULL here let new_thread = Thread::create_linux(&new_proc)?; #[cfg(not(target_arch = "riscv64"))] @@ -46,7 +46,11 @@ impl Syscall<'_> { new_thread.start_with_context(self.context, self.thread_fn)?; let new_proc: Arc = new_proc; - info!("vfork: {} -> {}. Waiting for execve SIGNALED", self.zircon_process().id(), new_proc.id()); + info!( + "vfork: {} -> {}. Waiting for execve SIGNALED", + self.zircon_process().id(), + new_proc.id() + ); new_proc.wait_signal(Signal::SIGNALED).await; // wait for execve Ok(new_proc.id() as usize) } @@ -211,7 +215,12 @@ impl Syscall<'_> { { self.context.general = GeneralRegs::new_fn(entry, sp, 0, 0); self.context.sepc = entry; - info!("execve: PageTable: {:#x}, entry: {:#x}, sp: {:#x}", self.zircon_process().vmar().table_phys(), self.context.sepc, self.context.general.sp); + info!( + "execve: PageTable: {:#x}, entry: {:#x}, sp: {:#x}", + self.zircon_process().vmar().table_phys(), + self.context.sepc, + self.context.general.sp + ); } Ok(0) @@ -395,7 +404,10 @@ impl RegExt for GeneralRegs { #[cfg(target_arch = "riscv64")] impl RegExt for GeneralRegs { fn new_fn(entry: usize, sp: usize, arg1: usize, arg2: usize) -> Self { - info!("new_fn(), Did NOT save ip:{:#x} register! x_x Saved sp: {:#x}", entry, sp); + info!( + "new_fn(), Did NOT save ip:{:#x} register! x_x Saved sp: {:#x}", + entry, sp + ); GeneralRegs { sp: sp, a0: arg1, diff --git a/prebuilt/linux/libc-libos.so b/prebuilt/linux/libc-libos.so old mode 100755 new mode 100644 diff --git a/prebuilt/linux/riscv64/busybox b/prebuilt/linux/riscv64/busybox new file mode 100644 index 000000000..28109f381 --- /dev/null +++ b/prebuilt/linux/riscv64/busybox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7b523df2daeaadd752d88cd672c1cea2d4253e101790055ae3ac964389ec6b80 +size 1030848 diff --git a/rboot b/rboot index 4c546d56c..00416ef50 160000 --- a/rboot +++ b/rboot @@ -1 +1 @@ -Subproject commit 4c546d56cf3d4ec75e4f52a13d1b6f7edf25940f +Subproject commit 00416ef505784e88e56cf08d6e9f7c7a2a00be16 diff --git a/rust-toolchain b/rust-toolchain index fe5455cb3..bf867e0ae 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -nightly-2020-10-01 +nightly diff --git a/zCore/riscv64.json b/zCore/riscv64.json index f10ec09b4..ee6ffa50b 100644 --- a/zCore/riscv64.json +++ b/zCore/riscv64.json @@ -13,7 +13,7 @@ "emit-debug-gdb-scripts": false, "executables": true, "features": "+m,+a,+c", - "is-builtin": true, + "is-builtin": false, "linker": "rust-lld", "linker-flavor": "ld.lld", "pre-link-args": { diff --git a/zCore/src/main.rs b/zCore/src/main.rs index a59beb81e..aaa352649 100644 --- a/zCore/src/main.rs +++ b/zCore/src/main.rs @@ -28,10 +28,14 @@ mod memory; use rboot::BootInfo; #[cfg(target_arch = "riscv64")] -use kernel_hal_bare::{BootInfo, GraphicInfo, remap_the_kernel, virtio::{BLK_DRIVERS, BlockDriverWrapper},}; +use kernel_hal_bare::{ + remap_the_kernel, + virtio::{BlockDriverWrapper, BLK_DRIVERS}, + BootInfo, GraphicInfo, +}; use alloc::vec::Vec; -pub use memory::{phys_to_virt, write_readonly_test, execute_unexecutable_test, read_invalid_test}; +pub use memory::{execute_unexecutable_test, phys_to_virt, read_invalid_test, write_readonly_test}; #[cfg(target_arch = "riscv64")] global_asm!(include_str!("arch/riscv/boot/entry64.asm")); @@ -56,9 +60,7 @@ pub extern "C" fn _start(boot_info: &BootInfo) -> ! { }); #[cfg(target_arch = "riscv64")] - kernel_hal_bare::init(kernel_hal_bare::Config { - mconfig: 0, - }); + kernel_hal_bare::init(kernel_hal_bare::Config { mconfig: 0 }); let ramfs_data = unsafe { core::slice::from_raw_parts_mut( @@ -90,12 +92,16 @@ pub extern "C" fn rust_main(hartid: usize, device_tree_paddr: usize) -> ! { let boot_info = BootInfo { memory_map: Vec::new(), physical_memory_offset: 0, - graphic_info: GraphicInfo{mode: 0, fb_addr: 0, fb_size: 0}, + graphic_info: GraphicInfo { + mode: 0, + fb_addr: 0, + fb_size: 0, + }, hartid: hartid as u64, dtb_addr: device_tree_paddr as u64, initramfs_addr: 0, initramfs_size: 0, - cmdline: "LOG=debug:TERM=xterm-256color:console.shell=true:virtcon.disable=true", + cmdline: "LOG=warn:TERM=xterm-256color:console.shell=true:virtcon.disable=true", }; unsafe { @@ -123,7 +129,7 @@ pub extern "C" fn rust_main(hartid: usize, device_tree_paddr: usize) -> ! { //execute_unexecutable_test(); //read_invalid_test(); - // 正常由bootloader载入文件系统镜像到内存, 这里不用,而使用后面的virtio + // 正常由bootloader载入文件系统镜像到内存, 这里不用,而使用后面的virtio /* let ramfs_data = unsafe { core::slice::from_raw_parts_mut( @@ -142,9 +148,9 @@ pub extern "C" fn rust_main(hartid: usize, device_tree_paddr: usize) -> ! { //fn main(ramfs_data: &'static mut [u8], _cmdline: &str) { fn main(_cmdline: &str) { use alloc::boxed::Box; + use alloc::string::String; use alloc::sync::Arc; use alloc::vec; - use alloc::string::String; //use linux_object::fs::MemBuf; use linux_object::fs::STDIN; @@ -179,18 +185,23 @@ fn main(_cmdline: &str) { let device = { let driver = BlockDriverWrapper( - BLK_DRIVERS.read().iter() - .next().expect("Block device not found") - .clone()); + BLK_DRIVERS + .read() + .iter() + .next() + .expect("Block device not found") + .clone(), + ); Arc::new(rcore_fs::dev::block_cache::BlockCache::new(driver, 0x100)) }; info!("Opening the rootfs ..."); // 输入类型: Arc - let rootfs = rcore_fs_sfs::SimpleFileSystem::open(device).expect("failed to open device SimpleFS"); + let rootfs = + rcore_fs_sfs::SimpleFileSystem::open(device).expect("failed to open device SimpleFS"); // fat32 - + //let img_file = File::open("fat.img")?; //let fs = fatfs::FileSystem::new(img_file, fatfs::FsOptions::new())?; diff --git a/zCore/src/memory.rs b/zCore/src/memory.rs index 025ecde30..42342aea1 100644 --- a/zCore/src/memory.rs +++ b/zCore/src/memory.rs @@ -1,14 +1,10 @@ //! Define the FrameAllocator for physical memory //! x86_64 -- 64GB -use { - bitmap_allocator::BitAlloc, - buddy_system_allocator::LockedHeap, - spin::Mutex, -}; use core::alloc::Layout; -use core::ptr::NonNull; use core::mem; +use core::ptr::NonNull; +use {bitmap_allocator::BitAlloc, buddy_system_allocator::LockedHeap, spin::Mutex}; #[cfg(target_arch = "x86_64")] use { @@ -17,10 +13,10 @@ use { }; #[cfg(target_arch = "riscv64")] -use riscv::{addr::Frame, - paging::{ - PageTable, PageTableFlags as EF - }}; +use riscv::{ + addr::Frame, + paging::{PageTable, PageTableFlags as EF}, +}; #[cfg(target_arch = "x86_64")] type FrameAlloc = bitmap_allocator::BitAlloc16M; @@ -123,7 +119,9 @@ pub fn init_heap() { pub extern "C" fn hal_heap_alloc(size: &usize, align: &usize) -> usize { let ret = HEAP_ALLOCATOR .lock() - .alloc(Layout::from_size_align(*size, *align).unwrap()).unwrap().as_ptr(); + .alloc(Layout::from_size_align(*size, *align).unwrap()) + .unwrap() + .as_ptr(); trace!("Allocate heap: {:x?}", ret); ret as usize @@ -132,9 +130,10 @@ pub extern "C" fn hal_heap_alloc(size: &usize, align: &usize) -> usize { #[no_mangle] pub extern "C" fn hal_heap_dealloc(ptr: &usize, size: &usize, align: &usize) { trace!("Deallocate heap: {:x}", *ptr); - HEAP_ALLOCATOR - .lock() - .dealloc(NonNull::new(*ptr as *mut u8).unwrap(), Layout::from_size_align(*size, *align).unwrap()); + HEAP_ALLOCATOR.lock().dealloc( + NonNull::new(*ptr as *mut u8).unwrap(), + Layout::from_size_align(*size, *align).unwrap(), + ); } #[no_mangle] @@ -189,8 +188,15 @@ pub extern "C" fn hal_pt_map_kernel(pt: &mut PageTable, current: &PageTable) { let ekernel = current[KERNEL_L2].clone(); //Kernel let ephysical = current[PHYSICAL_MEMORY_L2].clone(); //0xffffffff_00000000 --> 0x00000000 pt[KERNEL_L2].set(Frame::of_addr(ekernel.addr()), ekernel.flags() | EF::GLOBAL); - pt[PHYSICAL_MEMORY_L2].set(Frame::of_addr(ephysical.addr()), ephysical.flags() | EF::GLOBAL); - debug!("KERNEL_L2:{:x?}, PHYSICAL_MEMORY_L2:{:x?}", ekernel.addr(), ephysical.addr()); + pt[PHYSICAL_MEMORY_L2].set( + Frame::of_addr(ephysical.addr()), + ephysical.flags() | EF::GLOBAL, + ); + debug!( + "KERNEL_L2:{:x?}, PHYSICAL_MEMORY_L2:{:x?}", + ekernel.addr(), + ephysical.addr() + ); } // First core stores its SATP here. diff --git a/zircon-object/src/dev/pci/nodes.rs b/zircon-object/src/dev/pci/nodes.rs index 0498e8308..f89b5d76f 100644 --- a/zircon-object/src/dev/pci/nodes.rs +++ b/zircon-object/src/dev/pci/nodes.rs @@ -37,12 +37,19 @@ struct PcieUpstreamInner { } impl PcieUpstream { + #[allow(unsafe_code)] pub fn create(managed_bus_id: usize) -> Arc { Arc::new(PcieUpstream { managed_bus_id, inner: Mutex::new(PcieUpstreamInner { weak_super: Weak::::new(), - downstream: [None; PCI_MAX_FUNCTIONS_PER_BUS], + downstream: unsafe { + core::mem::transmute( + [0u8; core::mem::size_of::>>() + * PCI_MAX_FUNCTIONS_PER_BUS], + ) + }, + // [None; PCI_MAX_FUNCTIONS_PER_BUS], }), }) } diff --git a/zircon-object/src/lib.rs b/zircon-object/src/lib.rs index ff69869b3..9be352b26 100644 --- a/zircon-object/src/lib.rs +++ b/zircon-object/src/lib.rs @@ -13,7 +13,6 @@ #![feature(get_mut_unchecked)] #![feature(naked_functions)] #![feature(new_uninit)] -#![feature(const_in_array_repeat_expressions)] extern crate alloc; diff --git a/zircon-object/src/signal/port_packet.rs b/zircon-object/src/signal/port_packet.rs index d274ae843..0cba1c0e6 100644 --- a/zircon-object/src/signal/port_packet.rs +++ b/zircon-object/src/signal/port_packet.rs @@ -93,8 +93,9 @@ pub struct PacketGuestMem { #[cfg(target_arch = "riscv64")] #[repr(C)] #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)] -pub struct PacketGuestMem { //保持32节的空间 +pub struct PacketGuestMem { pub addr: u64, + //保持32字节的空间 pub _reserved: u64, pub _reserved1: u64, pub _reserved2: u64, diff --git a/zircon-object/src/util/elf_loader.rs b/zircon-object/src/util/elf_loader.rs index d9aee6690..d207caacf 100644 --- a/zircon-object/src/util/elf_loader.rs +++ b/zircon-object/src/util/elf_loader.rs @@ -74,7 +74,11 @@ fn make_vmo(elf: &ElfFile, ph: ProgramHeader) -> ZxResult> { let page_offset = ph.virtual_addr() as usize % PAGE_SIZE; // (VirtAddr余数 + MemSiz)的pages let pages = pages(ph.mem_size() as usize + page_offset); - trace!("VmObject new pages: {:#x}, virtual_addr: {:#x}", pages, page_offset); + trace!( + "VmObject new pages: {:#x}, virtual_addr: {:#x}", + pages, + page_offset + ); let vmo = VmObject::new_paged(pages); let data = match ph.get_data(&elf).unwrap() { SegmentData::Undefined(data) => data, diff --git a/zircon-object/src/vm/vmar.rs b/zircon-object/src/vm/vmar.rs index 5f77ddf14..fcebe3425 100644 --- a/zircon-object/src/vm/vmar.rs +++ b/zircon-object/src/vm/vmar.rs @@ -481,8 +481,8 @@ impl VmAddressRegion { } /// Get information of this VmAddressRegion - pub fn get_info(&self, va: usize) -> VmarInfo { //pub fn get_info(&self) -> VmarInfo { + pub fn get_info(&self, va: usize) -> VmarInfo { let _r = self.page_table.lock().query(va); VmarInfo { base: self.addr(), From 65f787973364f69408e253db9a277170e2af6717 Mon Sep 17 00:00:00 2001 From: DeathWish5 Date: Wed, 28 Jul 2021 20:08:04 +0800 Subject: [PATCH 2/2] Remove an unsafe code --- zircon-object/src/dev/pci/nodes.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/zircon-object/src/dev/pci/nodes.rs b/zircon-object/src/dev/pci/nodes.rs index f89b5d76f..f48ca3204 100644 --- a/zircon-object/src/dev/pci/nodes.rs +++ b/zircon-object/src/dev/pci/nodes.rs @@ -33,23 +33,21 @@ pub struct PcieUpstream { struct PcieUpstreamInner { weak_super: Weak, - downstream: [Option>; PCI_MAX_FUNCTIONS_PER_BUS], + downstream: Box<[Option>]>, } impl PcieUpstream { - #[allow(unsafe_code)] pub fn create(managed_bus_id: usize) -> Arc { Arc::new(PcieUpstream { managed_bus_id, inner: Mutex::new(PcieUpstreamInner { weak_super: Weak::::new(), - downstream: unsafe { - core::mem::transmute( - [0u8; core::mem::size_of::>>() - * PCI_MAX_FUNCTIONS_PER_BUS], - ) + downstream: { + let mut vec = + Vec::>>::with_capacity(PCI_MAX_FUNCTIONS_PER_BUS); + vec.resize(PCI_MAX_FUNCTIONS_PER_BUS, None); + vec.into_boxed_slice() }, - // [None; PCI_MAX_FUNCTIONS_PER_BUS], }), }) }