diff --git a/.vscode/settings.json b/.vscode/settings.json index 5609d81ae..4dd0a0183 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,5 +2,6 @@ "files.associations": { "unistd.h": "c", "time.h": "c" - } -} \ No newline at end of file + }, + "rust-analyzer.cargo.target": "riscv64gc-unknown-none-elf", +} diff --git a/drivers/Cargo.toml b/drivers/Cargo.toml index c9db75a06..fbd96ea21 100644 --- a/drivers/Cargo.toml +++ b/drivers/Cargo.toml @@ -24,9 +24,20 @@ bitmap-allocator = { git = "https://github.com/rcore-os/bitmap-allocator", rev = pci = { git = "https://github.com/rcore-os/pci-rs", rev = "a4e7cea6" } virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "2aaf7d6", optional = true } rcore-console = { git = "https://github.com/rcore-os/rcore-console", default-features = false, rev = "ca5b1bc", optional = true } -lock = { git = "https://github.com/DeathWish5/kernel-sync" } +lock = { git = "https://github.com/DeathWish5/kernel-sync", rev = "01b2e70" } # smoltcp = { git = "https://github.com/smoltcp-rs/smoltcp", rev = "35e833e3", default-features = false, features = ["log", "alloc", "verbose", "proto-ipv4", "proto-ipv6", "proto-igmp", "medium-ip", "medium-ethernet", "socket-raw", "socket-udp", "socket-tcp", "socket-icmp"] } -smoltcp = { git = "https://gitee.com/gcyyfun/smoltcp", rev="043eb60", default-features = false, features = ["alloc","log", "async", "medium-ethernet","proto-ipv4", "proto-igmp", "socket-icmp", "socket-udp", "socket-tcp", "socket-raw"] } +smoltcp = { git = "https://gitee.com/gcyyfun/smoltcp", rev = "043eb60", default-features = false, features = [ + "alloc", + "log", + "async", + "medium-ethernet", + "proto-ipv4", + "proto-igmp", + "socket-icmp", + "socket-udp", + "socket-tcp", + "socket-raw", +] } # LibOS mode [target.'cfg(not(target_os = "none"))'.dependencies] @@ -43,4 +54,6 @@ x2apic = "0.4" x86_64 = "0.14" [target.'cfg(any(target_arch = "riscv32", target_arch = "riscv64"))'.dependencies] -riscv = { git = "https://github.com/rust-embedded/riscv", rev = "cd31989", features = ["inline-asm"] } \ No newline at end of file +riscv = { git = "https://github.com/rust-embedded/riscv", rev = "cd31989", features = [ + "inline-asm", +] } diff --git a/kernel-hal/Cargo.toml b/kernel-hal/Cargo.toml index 92a0f438e..78c83d8f2 100644 --- a/kernel-hal/Cargo.toml +++ b/kernel-hal/Cargo.toml @@ -1,7 +1,10 @@ [package] name = "kernel-hal" version = "0.1.0" -authors = ["Runji Wang ", "Yuekai Jia "] +authors = [ + "Runji Wang ", + "Yuekai Jia ", +] edition = "2018" description = "Kernel HAL interface definations." @@ -10,7 +13,13 @@ description = "Kernel HAL interface definations." [features] default = ["libos"] smp = [] -libos = ["nix", "tempfile", "async-std", "bitmap-allocator", "zcore-drivers/mock"] +libos = [ + "nix", + "tempfile", + "async-std", + "bitmap-allocator", + "zcore-drivers/mock", +] graphic = ["zcore-drivers/graphic"] loopback = [] @@ -25,8 +34,19 @@ git-version = "0.3" numeric-enum-macro = "0.2" lazy_static = { version = "1.4", features = ["spin_no_std"] } zcore-drivers = { path = "../drivers", features = ["virtio"] } -lock = { git = "https://github.com/DeathWish5/kernel-sync" } -smoltcp = { git = "https://gitee.com/gcyyfun/smoltcp", rev="043eb60", default-features = false, features = ["alloc","log", "async", "medium-ethernet","proto-ipv4", "proto-igmp", "socket-icmp", "socket-udp", "socket-tcp", "socket-raw"] } +lock = { git = "https://github.com/DeathWish5/kernel-sync", rev = "01b2e70" } +smoltcp = { git = "https://gitee.com/gcyyfun/smoltcp", rev = "043eb60", default-features = false, features = [ + "alloc", + "log", + "async", + "medium-ethernet", + "proto-ipv4", + "proto-igmp", + "socket-icmp", + "socket-udp", + "socket-tcp", + "socket-raw", +] } # LibOS mode [target.'cfg(not(target_os = "none"))'.dependencies] @@ -53,4 +73,6 @@ x86-smpboot = { git = "https://github.com/rcore-os/x86-smpboot", rev = "1069df3" # Bare-metal mode on riscv64 [target.'cfg(all(target_os = "none", target_arch = "riscv64"))'.dependencies] -riscv = { git = "https://github.com/rust-embedded/riscv", rev = "cd31989", features = ["inline-asm"] } \ No newline at end of file +riscv = { git = "https://github.com/rust-embedded/riscv", rev = "cd31989", features = [ + "inline-asm", +] } diff --git a/linux-object/Cargo.toml b/linux-object/Cargo.toml index 5ae6eba68..7d7b6b0f2 100644 --- a/linux-object/Cargo.toml +++ b/linux-object/Cargo.toml @@ -38,7 +38,7 @@ smoltcp = { git = "https://gitee.com/gcyyfun/smoltcp", rev = "043eb60", default- "socket-raw", ] } zcore-drivers = { path = "../drivers", features = ["virtio"] } -lock = { git = "https://github.com/DeathWish5/kernel-sync" } +lock = { git = "https://github.com/DeathWish5/kernel-sync", rev = "01b2e70" } # LibOS mode [target.'cfg(not(target_os = "none"))'.dependencies] diff --git a/linux-syscall/Cargo.toml b/linux-syscall/Cargo.toml index 14db88134..2c88602f4 100644 --- a/linux-syscall/Cargo.toml +++ b/linux-syscall/Cargo.toml @@ -19,8 +19,11 @@ kernel-hal = { path = "../kernel-hal", default-features = false } rcore-fs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1a3246b" } lazy_static = { version = "1.4", features = ["spin_no_std"] } bitvec = { version = "0.22", default-features = false, features = ["alloc"] } -lock = { git = "https://github.com/DeathWish5/kernel-sync" } -futures = { version = "0.3", default-features = false, features = ["alloc", "async-await"] } +lock = { git = "https://github.com/DeathWish5/kernel-sync", rev = "01b2e70" } +futures = { version = "0.3", default-features = false, features = [ + "alloc", + "async-await", +] } [dev-dependencies] async-std = { version = "1.10", features = ["unstable"] } @@ -29,4 +32,4 @@ async-std = { version = "1.10", features = ["unstable"] } [target.'cfg(not(target_os = "none"))'.dependencies] # Bare-metal mode -[target.'cfg(target_os = "none")'.dependencies] \ No newline at end of file +[target.'cfg(target_os = "none")'.dependencies] diff --git a/zCore/Cargo.toml b/zCore/Cargo.toml index 99bb60bb7..5615b6af6 100644 --- a/zCore/Cargo.toml +++ b/zCore/Cargo.toml @@ -64,7 +64,7 @@ zircon-object = { path = "../zircon-object" } linux-object = { path = "../linux-object", optional = true } rcore-fs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1a3246b", optional = true } rcore-fs-sfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "1a3246b", optional = true } -lock = { git = "https://github.com/DeathWish5/kernel-sync" } +lock = { git = "https://github.com/DeathWish5/kernel-sync", rev = "01b2e70" } executor = { git = "https://github.com/DeathWish5/PreemptiveScheduler", rev = "56ac2f6" } # LibOS mode @@ -79,6 +79,7 @@ buddy_system_allocator = "0.8" # RISC-V [target.'cfg(any(target_arch = "riscv32", target_arch = "riscv64"))'.dependencies] +r0 = "1" riscv = { git = "https://github.com/rust-embedded/riscv", rev = "cd31989", features = [ "inline-asm", ] } diff --git a/zCore/src/handler.rs b/zCore/src/handler.rs index 11abe6ea0..79fbc7aef 100644 --- a/zCore/src/handler.rs +++ b/zCore/src/handler.rs @@ -18,9 +18,6 @@ impl KernelHandler for ZcoreKernelHandler { } fn handle_page_fault(&self, fault_vaddr: usize, access_flags: MMUFlags) { - panic!( - "page fault from kernel mode @ {:#x}({:?})", - fault_vaddr, access_flags - ); + panic!("page fault from kernel mode @ {fault_vaddr:#x}({access_flags:?})"); } } diff --git a/zCore/src/lang.rs b/zCore/src/lang.rs index c4923a902..6c5878926 100644 --- a/zCore/src/lang.rs +++ b/zCore/src/lang.rs @@ -7,8 +7,8 @@ use log::*; #[panic_handler] fn panic(info: &PanicInfo) -> ! { println!("\n\npanic cpu={}", kernel_hal::cpu::cpu_id()); - println!("\n\n{}", info); - error!("\n\n{}", info); + println!("\n\n{info}"); + error!("\n\n{info}"); if cfg!(feature = "baremetal-test") { kernel_hal::cpu::reset(); diff --git a/zCore/src/logging.rs b/zCore/src/logging.rs index a42ab1595..f769ced2a 100644 --- a/zCore/src/logging.rs +++ b/zCore/src/logging.rs @@ -13,25 +13,24 @@ pub fn set_max_level(level: &str) { log::set_max_level(level.parse().unwrap_or(LevelFilter::Warn)); } +#[inline] pub fn print(args: fmt::Arguments) { kernel_hal::console::console_write_fmt(args); } #[macro_export] macro_rules! print { - ($($arg:tt)*) => ({ - $crate::logging::print(format_args!($($arg)*)); - }); + ($($arg:tt)*) => ($crate::logging::print(core::format_args!($($arg)*))); } #[macro_export] macro_rules! println { - ($fmt:expr) => (print!(concat!($fmt, "\n"))); - ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*)); + () => ($crate::print!("\n")); + ($($arg:tt)*) => ($crate::logging::print(core::format_args_nl!($($arg)*))); } -#[repr(u8)] #[allow(dead_code)] +#[repr(u8)] enum ColorCode { Black = 30, Red = 31, @@ -94,21 +93,21 @@ impl Log for SimpleLogger { }; print(with_color!( ColorCode::White, - "[{} {} {} {}\n", - { + "[{time} {level} {info} {data}\n", + time = { cfg_if! { if #[cfg(feature = "libos")] { use chrono::{TimeZone, Local}; Local.timestamp_nanos(now.as_nanos() as _).format("%Y-%m-%d %H:%M:%S%.6f") } else { let micros = now.as_micros(); - format_args!("{:>3}.{:06}", micros / 1_000_000, micros % 1_000_000) + format_args!("{s:>3}.{us:06}", s = micros / 1_000_000, us = micros % 1_000_000) } } }, - with_color!(level_color, "{:<5}", level), - with_color!(ColorCode::White, "{} {}:{} {}]", cpu_id, pid, tid, target), - with_color!(args_color, "{}", record.args()), + level = with_color!(level_color, "{level:<5}"), + info = with_color!(ColorCode::White, "{cpu_id} {pid}:{tid} {target}]"), + data = with_color!(args_color, "{args}", args = record.args()), )); } diff --git a/zCore/src/main.rs b/zCore/src/main.rs index 214c2d37d..6733a877e 100644 --- a/zCore/src/main.rs +++ b/zCore/src/main.rs @@ -2,6 +2,8 @@ #![cfg_attr(not(feature = "libos"), no_std)] #![feature(lang_items)] #![feature(core_intrinsics)] +#![feature(naked_functions, asm_sym, asm_const)] +#![feature(format_args_nl)] #![deny(warnings)] use core::sync::atomic::{AtomicBool, Ordering}; diff --git a/zCore/src/memory.rs b/zCore/src/memory.rs index 119b9ee53..fff01210c 100644 --- a/zCore/src/memory.rs +++ b/zCore/src/memory.rs @@ -29,7 +29,7 @@ fn frame_idx_to_phys_addr(idx: usize) -> PhysAddr { } pub fn init_frame_allocator(regions: &[Range]) { - debug!("init_frame_allocator regions: {:x?}", regions); + debug!("init_frame_allocator regions: {regions:x?}"); let mut ba = FRAME_ALLOCATOR.lock(); for region in regions { let frame_start = phys_addr_to_frame_idx(region.start); @@ -47,7 +47,7 @@ pub fn init_frame_allocator(regions: &[Range]) { pub fn frame_alloc() -> Option { let ret = FRAME_ALLOCATOR.lock().alloc().map(frame_idx_to_phys_addr); - trace!("frame_alloc(): {:x?}", ret); + trace!("frame_alloc(): {ret:x?}"); ret } @@ -57,16 +57,14 @@ pub fn frame_alloc_contiguous(frame_count: usize, align_log2: usize) -> Option

!; - .global _start -# /// 副核入口 -# fn _secondary_hart_start(hartid: usize) -> !; - .global _secondary_hart_start -# /// 地址空间跃迁 -# fn jump_heigher(offset: usize); - .global _jump_higher - -# 依赖的全局符号 -# ------------------------------- -# /// 主核入口 -# fn primary_rust_main(hartid: usize, device_tree_paddr: usize) -> !; -# -# /// 副核入口 -# fn secondary_rust_main(hartid: usize) -> !; - - .section .text.entry - -# 主核入口 -# 清零 bss 段,构造启动页表,然后跳转到高地址映射的主核主函数 -# ------------------------------- -_start: # fn _start(hartid: usize, device_tree_paddr: usize) -> ! {{ - csrw sie, zero # $sie = 0; // 关中断 - call select_stack # select_stack(hartid); - j primary_rust_main # primary_rust_main(hartid, device_tree_paddr) - # }} -# ------------------------------- - -# 副核入口 -# 构造启动页表,然后跳转到高地址映射的副核主函数 -# ------------------------------- -_secondary_hart_start: # fn _secondary_hart_start(hartid: usize) -> ! {{ - csrw sie, zero # $sie = 0; // 关中断 - call select_stack # select_stack(hartid); - j secondary_rust_main # secondary_rust_main(hartid) - # }} -# ------------------------------- - -# 根据线程号设置启动栈 -# ------------------------------- -select_stack: # fn select_stack(hartid: usize) {{ - mv t0, a0 # $t0 = hartid; - la sp, bootstacktop # $sp = bootstacktop; - beqz t0, 2f # if $t0 != 0 {{ - li t1, -4096*16 # $t1 = -4096*16; - # loop {{ -1: add sp, sp, t1 # $sp += $t1; - addi t0, t0, -1 # $t0 -= 1; - bgtz t0, 1b # if $t0 > 0 {{ continue; }} - # }} - # }} -2: ret # }} -# ------------------------------- - -# 从地址空间的低处跳到地址空间高处对应位置并挪动栈指针 -# ------------------------------- -_jump_higher: # fn jump_heigher(offset: usize) {{ - add ra, ra, a0 # $t0 += offset; - add sp, sp, a0 # $sp += offset; - ret # }} -# ------------------------------- - - .section .bss.bootstack - .align 12 -bootstack: - .space 4096 * 160 -bootstacktop: diff --git a/zCore/src/platform/riscv/boot/linker64.ld b/zCore/src/platform/riscv/boot/linker64.ld index 19073d228..d337f202f 100644 --- a/zCore/src/platform/riscv/boot/linker64.ld +++ b/zCore/src/platform/riscv/boot/linker64.ld @@ -25,15 +25,18 @@ SECTIONS sdata = .; .data : { *(.data .data.*) - } . = ALIGN(4K); - edata = .; - .bss : { + edata = .; + + . = ALIGN(4K); + bootstack = .; *(.bss.bootstack) + bootstacktop = .; + } - . = ALIGN(4K); - sbss = .; + sbss = .; + .bss : { *(.bss .bss.* .sbss) } diff --git a/zCore/src/platform/riscv/boot_page_table.rs b/zCore/src/platform/riscv/boot_page_table.rs new file mode 100644 index 000000000..1f5930864 --- /dev/null +++ b/zCore/src/platform/riscv/boot_page_table.rs @@ -0,0 +1,93 @@ +use super::consts::PHYSICAL_MEMORY_OFFSET; +use consts::*; +use core::arch::asm; + +/// 启动页表。 +#[repr(align(4096))] +pub(super) struct BootPageTable([usize; 512]); + +impl BootPageTable { + /// 初始化为全零的启动页表。 + pub const ZERO: Self = Self([0; 512]); + + /// 根据内核实际位置初始化启动页表。 + pub fn init(&mut self) { + extern "C" { + fn start(); + } + // 内核起始地址 + let kernel_start = start as usize; + // GiB 物理页帧在 GiB 页表中的序号 + let trampoline_pte_index = kernel_start >> GIB_BITS; + // GiB 页物理页号 + let start_ppn = (kernel_start & GIB_MASK) >> KIB_BITS; + // 映射跳板页 + self.0[trampoline_pte_index] = (start_ppn << 10) | DAGXWRV; + // 物理地址 0 映射到内核地址偏移处,并依次映射虚拟地址空间后续所有页 + const OFF_PTE: usize = 1 << (GIB_BITS - KIB_BITS + 10); + const IDX_PTE: usize = (PHYSICAL_MEMORY_OFFSET & SV39_MASK) >> GIB_BITS; + self.0[IDX_PTE..] + .iter_mut() + .enumerate() + .for_each(|(i, pte)| *pte = (i * OFF_PTE) | DAGXWRV); + } + + /// 启动地址转换,跃迁到高地址,并设置线程指针和内核对用户页的访问权限。 + /// + /// # Safety + /// + /// 调用前后位于不同的地址空间,必须内联。 + #[inline(always)] + pub unsafe fn launch(&self, hartid: usize) -> usize { + // 启动页表的页号,将填写到 `satp` + let satp = MODE_SV39 | ((self.0.as_ptr() as usize) >> KIB_BITS); + // 启动地址转换 + riscv::register::satp::write(satp); + // 此时原本的地址空间还在,所以按理说不用刷快表 + // riscv::asm::sfence_vma_all(); + // 跳到高页面对应位置 + Self::jump_higher(PHYSICAL_MEMORY_OFFSET); + // 设置线程指针 + asm!("mv tp, {}", in(reg) hartid); + // 设置内核可访问用户页 + let sstatus: usize; + asm!("csrrsi {}, sstatus, 18", out(reg) sstatus); + sstatus + } + + /// 向上跳到距离为 `offset` 的新地址然后继续执行。 + /// + /// # Safety + /// + /// 裸函数。 + #[naked] + unsafe extern "C" fn jump_higher(offset: usize) { + asm!( + // + "add ra, ra, a0", + "add sp, sp, a0", + "ret", + options(noreturn) + ) + } +} + +#[allow(dead_code)] +mod consts { + // 各级页面容量 + pub const KIB_BITS: usize = 12; // 4KiB + pub const MIB_BITS: usize = KIB_BITS + 9; // 2MiB + pub const GIB_BITS: usize = MIB_BITS + 9; // 1GiB + + // 各级页号遮罩 + pub const KIB_MASK: usize = !((1 << KIB_BITS) - 1); + pub const MIB_MASK: usize = !((1 << MIB_BITS) - 1); + pub const GIB_MASK: usize = !((1 << GIB_BITS) - 1); + pub const SV39_MASK: usize = (1 << (GIB_BITS + 9)) - 1; + + /// 填充 `satp` + pub const MODE_SV39: usize = 8 << 60; + + /// 内核页属性 + pub const DAGXWRV: usize = 0xef; +} diff --git a/zCore/src/platform/riscv/entry.rs b/zCore/src/platform/riscv/entry.rs index 354e40127..6e4ada010 100644 --- a/zCore/src/platform/riscv/entry.rs +++ b/zCore/src/platform/riscv/entry.rs @@ -1,103 +1,77 @@ -use super::consts::PHYSICAL_MEMORY_OFFSET; -use core::{ - arch::{asm, global_asm}, - str::FromStr, -}; +use super::{boot_page_table::BootPageTable, consts::PHYSICAL_MEMORY_OFFSET}; +use core::{arch::asm, str::FromStr}; use kernel_hal::{ sbi::{hart_start, send_ipi, shutdown, SBI_SUCCESS}, KernelConfig, }; -global_asm!(include_str!("boot/entry64.asm")); - -// 启动页表 -#[repr(align(4096))] -struct BootPageTable([usize; 512]); - -static mut BOOT_PAGE_TABLE: BootPageTable = BootPageTable([0; 512]); - -// 各级页面容量 -const KIB_BITS: usize = 12; // 4KiB -const MIB_BITS: usize = KIB_BITS + 9; // 2MiB -const GIB_BITS: usize = MIB_BITS + 9; // 1GiB - -// 各级页号遮罩 -// const KIB_MASK: usize = !((1 << KIB_BITS) - 1); -// const MIB_MASK: usize = !((1 << MIB_BITS) - 1); -const GIB_MASK: usize = !((1 << GIB_BITS) - 1); -const SV39_MASK: usize = (1 << (GIB_BITS + 9)) - 1; - -/// 填充 `satp` -const MODE_SV39: usize = 8 << 60; - -/// 内核页属性 -const DAGXWRV: usize = 0xef; - -// 符号表 -extern "C" { - /// 内核入口 - fn _start(); - /// 副核入口 - fn _secondary_hart_start(); - /// 向上跳到距离为 `offset` 的新地址,继续执行 - fn _jump_higher(offset: usize); - /// bss 段起始地址 - fn sbss(); - /// bss 段结束地址 - fn ebss(); -} - +/// 内核入口。 +/// +/// # Safety +/// +/// 裸函数。 +#[naked] #[no_mangle] -pub extern "C" fn primary_rust_main(hartid: usize, device_tree_paddr: usize) -> ! { - // 清零 bss 段 - let len = (ebss as usize - sbss as usize) / core::mem::size_of::(); - unsafe { core::slice::from_raw_parts_mut(sbss as *mut usize, len) }.fill(0); +#[link_section = ".text.entry"] +unsafe extern "C" fn _start(hartid: usize, device_tree_paddr: usize) -> ! { + asm!( + "csrw sie, zero", // 关中断 + "call {select_stack}", // 设置启动栈 + "j {main}", // 进入 rust + select_stack = sym select_stack, + main = sym primary_rust_main, + options(noreturn) + ) +} - // 内核的 GiB 页物理页号 - let start_ppn = ((_start as usize) & GIB_MASK) >> KIB_BITS; - // 内核 GiB 物理页帧在 GiB 页表中的序号 - let trampoline_pte_index = (_start as usize) >> GIB_BITS; - let mut pte_index = (PHYSICAL_MEMORY_OFFSET & SV39_MASK) >> GIB_BITS; - // 容纳内核的页表项 - let pte = (start_ppn << 10) | DAGXWRV; +/// 副核入口。此前副核被 SBI 阻塞。 +/// +/// # Safety +/// +/// 裸函数。 +#[naked] +unsafe extern "C" fn secondary_hart_start(hartid: usize) -> ! { + asm!( + "csrw sie, zero", // 关中断 + "call {select_stack}", // 设置启动栈 + "j {main}", // 进入 rust + select_stack = sym select_stack, + main = sym secondary_rust_main, + options(noreturn) + ) +} - // 构造启动页表 - // # TODO d1 c906 有扩展 63:59 位的页表项属性 - // #.quad (1 << 62) | (1 << 61) | (1 << 60) | (0x40000 << 10) | 0xef - unsafe { - *BOOT_PAGE_TABLE.0.get_unchecked_mut(trampoline_pte_index) = pte; - let mut page = DAGXWRV; - while pte_index < 512 { - *BOOT_PAGE_TABLE.0.get_unchecked_mut(pte_index) = page; - page += 1 << (GIB_BITS + 10 - KIB_BITS); - pte_index += 1; - } - } +/// 启动页表 +static mut BOOT_PAGE_TABLE: BootPageTable = BootPageTable::ZERO; +/// 主核启动。 +extern "C" fn primary_rust_main(hartid: usize, device_tree_paddr: usize) -> ! { + // 清零 bss 段 + zero_bss(); + // 初始化启动页表 + unsafe { BOOT_PAGE_TABLE.init() }; // 启动副核 for id in 0..usize::from_str(core::env!("SMP")).expect("can't parse SMP as usize.") { if id != hartid { - let err_code = hart_start(id, _secondary_hart_start as _, 0); + let err_code = hart_start(id, secondary_hart_start as _, 0); if err_code != SBI_SUCCESS { - panic!("start hart{} failed. error code={}", id, err_code); + panic!("start hart{id} failed. error code={err_code}"); } let hart_mask = 1usize << id; let err_code = send_ipi(&hart_mask as *const _ as _); if err_code != SBI_SUCCESS { - panic!("send ipi to hart{} failed. error code={}", id, err_code); + panic!("send ipi to hart{id} failed. error code={err_code}"); } } } - // 使能启动页表 let sstatus = unsafe { BOOT_PAGE_TABLE.launch(hartid) }; println!( " -boot hart: zCore rust_main(hartid: {}, device_tree_paddr: {:#x}) -sstatus = {:#x}", - hartid, device_tree_paddr, sstatus +boot hart: zCore rust_main(hartid: {hartid}, device_tree_paddr: {device_tree_paddr:#x}) +sstatus = {sstatus:#x}" ); - + // 转交控制权 crate::primary_main(KernelConfig { phys_to_virt_offset: PHYSICAL_MEMORY_OFFSET, dtb_paddr: device_tree_paddr, @@ -105,32 +79,52 @@ sstatus = {:#x}", shutdown() } -#[no_mangle] -pub extern "C" fn secondary_rust_main(hartid: usize) -> ! { +/// 副核启动。 +extern "C" fn secondary_rust_main(hartid: usize) -> ! { let _ = unsafe { BOOT_PAGE_TABLE.launch(hartid) }; crate::secondary_main() } -impl BootPageTable { - /// 设置启动页表,并跃迁到高地址。 - /// - /// # Safety - /// - /// 内含极度危险的地址空间跃迁操作,必须内联。 - #[inline(always)] - unsafe fn launch(&self, hartid: usize) -> usize { - // 启动页表的页号,将填写到 `satp` - let satp = MODE_SV39 | ((self.0.as_ptr() as usize) >> KIB_BITS); - // 启动地址转换 - riscv::register::satp::write(satp); - riscv::asm::sfence_vma_all(); - // 跳到高页面对应位置 - _jump_higher(PHYSICAL_MEMORY_OFFSET); - // 设置线程指针 - asm!("mv tp, {}", in(reg) hartid); - // 设置内核可访问用户页 - let sstatus: usize; - asm!("csrrsi {}, sstatus, 18", out(reg) sstatus); - sstatus +/// 根据硬件线程号设置启动栈。 +/// +/// # Safety +/// +/// 裸函数。 +#[naked] +unsafe extern "C" fn select_stack(hartid: usize) { + const STACK_PAGES_PER_HART: usize = 16; + const MAX_HART_NUM: usize = 10; + + const STACK_LEN_PER_HART: usize = 4096 * STACK_PAGES_PER_HART; + const STACK_LEN_TOTAL: usize = STACK_LEN_PER_HART * MAX_HART_NUM; + + #[link_section = ".bss.bootstack"] + static mut BOOT_STACK: [u8; STACK_LEN_TOTAL] = [0u8; STACK_LEN_TOTAL]; + + asm!( + " addi t0, a0, 1", + " la sp, {stack}", + " li t1, {len_per_hart}", + "1: add sp, sp, t1", + " addi t0, t0, -1", + " bgtz t0, 1b", + "2: ret", + stack = sym BOOT_STACK, + len_per_hart = const STACK_LEN_PER_HART, + options(noreturn) + ) +} + +/// 清零 bss 段 +#[inline(always)] +fn zero_bss() { + #[cfg(target_arch = "riscv32")] + type Word = u32; + #[cfg(target_arch = "riscv64")] + type Word = u64; + extern "C" { + static mut sbss: Word; + static mut ebss: Word; } + unsafe { r0::zero_bss(&mut sbss, &mut ebss) }; } diff --git a/zCore/src/platform/riscv/mod.rs b/zCore/src/platform/riscv/mod.rs index b99566220..89646b2e8 100644 --- a/zCore/src/platform/riscv/mod.rs +++ b/zCore/src/platform/riscv/mod.rs @@ -1 +1,4 @@ +mod boot_page_table; +mod entry; + pub mod consts; diff --git a/zCore/src/platform/x86/mod.rs b/zCore/src/platform/x86/mod.rs index b99566220..a946b46c4 100644 --- a/zCore/src/platform/x86/mod.rs +++ b/zCore/src/platform/x86/mod.rs @@ -1 +1,3 @@ +mod entry; + pub mod consts; diff --git a/zircon-object/Cargo.toml b/zircon-object/Cargo.toml index 7c9921f95..ad4bc9fbe 100644 --- a/zircon-object/Cargo.toml +++ b/zircon-object/Cargo.toml @@ -1,7 +1,10 @@ [package] name = "zircon-object" version = "0.1.0" -authors = ["Runji Wang ", "Qinglin Pan "] +authors = [ + "Runji Wang ", + "Qinglin Pan ", +] edition = "2018" description = "Zircon kernel objects" @@ -20,13 +23,16 @@ hashbrown = "0.9" downcast-rs = { version = "1.2", default-features = false } kernel-hal = { path = "../kernel-hal", default-features = false } numeric-enum-macro = "0.2" -futures = { version = "0.3", default-features = false, features = ["alloc", "async-await"] } +futures = { version = "0.3", default-features = false, features = [ + "alloc", + "async-await", +] } xmas-elf = { version = "0.7", optional = true } region-alloc = { git = "https://github.com/rzswh/region-allocator", rev = "122c7a71" } -lazy_static = { version = "1.4", features = ["spin_no_std" ] } +lazy_static = { version = "1.4", features = ["spin_no_std"] } cfg-if = "1.0" #rvm = { git = "https://github.com/rcore-os/RVM", rev = "382fc60", optional = true } -lock = { git = "https://github.com/DeathWish5/kernel-sync" } +lock = { git = "https://github.com/DeathWish5/kernel-sync", rev = "01b2e70" } [dev-dependencies] async-std = { version = "1.10", features = ["attributes", "unstable"] } @@ -35,4 +41,4 @@ async-std = { version = "1.10", features = ["attributes", "unstable"] } [target.'cfg(not(target_os = "none"))'.dependencies] # Bare-metal mode -[target.'cfg(target_os = "none")'.dependencies] \ No newline at end of file +[target.'cfg(target_os = "none")'.dependencies] diff --git a/zircon-syscall/Cargo.toml b/zircon-syscall/Cargo.toml index f6a6185e3..b88eb03bb 100644 --- a/zircon-syscall/Cargo.toml +++ b/zircon-syscall/Cargo.toml @@ -18,12 +18,15 @@ bitflags = "1.3" numeric-enum-macro = "0.2" zircon-object = { path = "../zircon-object" } kernel-hal = { path = "../kernel-hal", default-features = false } -futures = { version = "0.3", default-features = false, features = ["alloc", "async-await"] } +futures = { version = "0.3", default-features = false, features = [ + "alloc", + "async-await", +] } cfg-if = "1.0" -lock = { git = "https://github.com/DeathWish5/kernel-sync" } +lock = { git = "https://github.com/DeathWish5/kernel-sync", rev = "01b2e70" } # LibOS mode [target.'cfg(not(target_os = "none"))'.dependencies] # Bare-metal mode -[target.'cfg(target_os = "none")'.dependencies] \ No newline at end of file +[target.'cfg(target_os = "none")'.dependencies]