From 1efacbffc911ecf40db9e99fcb39d0334ccae556 Mon Sep 17 00:00:00 2001 From: YdrMaster Date: Fri, 29 Apr 2022 09:58:04 +0800 Subject: [PATCH] refactor: naked_function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 利用 naked_fuction 内联汇编,减少全局符号表内容,并移除独立的汇编文件 --- .vscode/settings.json | 5 +- drivers/Cargo.toml | 19 +++- kernel-hal/Cargo.toml | 32 +++++- linux-object/Cargo.toml | 2 +- linux-syscall/Cargo.toml | 9 +- zCore/Cargo.toml | 2 +- zCore/src/main.rs | 1 + zCore/src/platform/riscv/boot/entry64.asm | 71 ------------- zCore/src/platform/riscv/entry.rs | 121 ++++++++++++++++++---- zircon-object/Cargo.toml | 16 ++- zircon-syscall/Cargo.toml | 9 +- 11 files changed, 170 insertions(+), 117 deletions(-) delete mode 100644 zCore/src/platform/riscv/boot/entry64.asm diff --git a/.vscode/settings.json b/.vscode/settings.json index 5609d81a..4dd0a018 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 c9db75a0..fbd96ea2 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 92a0f438..78c83d8f 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 5ae6eba6..7d7b6b0f 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 14db8813..2c88602f 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 99bb60bb..9c69271b 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 diff --git a/zCore/src/main.rs b/zCore/src/main.rs index 214c2d37..df54063e 100644 --- a/zCore/src/main.rs +++ b/zCore/src/main.rs @@ -2,6 +2,7 @@ #![cfg_attr(not(feature = "libos"), no_std)] #![feature(lang_items)] #![feature(core_intrinsics)] +#![feature(naked_functions, asm_sym)] #![deny(warnings)] use core::sync::atomic::{AtomicBool, Ordering}; diff --git a/zCore/src/platform/riscv/boot/entry64.asm b/zCore/src/platform/riscv/boot/entry64.asm deleted file mode 100644 index 9302b39c..00000000 --- a/zCore/src/platform/riscv/boot/entry64.asm +++ /dev/null @@ -1,71 +0,0 @@ -# 提供的全局符号 -# ------------------------------- -# /// 主核入口 -# fn _start(hartid: usize, device_tree_paddr: usize) -> !; - .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/entry.rs b/zCore/src/platform/riscv/entry.rs index 354e4012..525977f2 100644 --- a/zCore/src/platform/riscv/entry.rs +++ b/zCore/src/platform/riscv/entry.rs @@ -8,8 +8,6 @@ use kernel_hal::{ KernelConfig, }; -global_asm!(include_str!("boot/entry64.asm")); - // 启动页表 #[repr(align(4096))] struct BootPageTable([usize; 512]); @@ -33,23 +31,85 @@ 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] +#[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) + ) } -#[no_mangle] -pub extern "C" fn primary_rust_main(hartid: usize, device_tree_paddr: usize) -> ! { +/// 副核入口。此前副核被 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) + ) +} + +// 启动栈空间会在 kernel-hal 中重映射,因此必须导出符号 +global_asm!( + "\ + .section .bss.bootstack + .align 12 + .global bootstack +bootstack: + .space 4096 * 16 * 10 + .global bootstacktop +bootstacktop:" +); + +/// 根据硬件线程号设置启动栈。 +/// +/// # Safety +/// +/// 裸函数。 +#[naked] +unsafe extern "C" fn select_stack(hartid: usize) { + extern "C" { + fn bootstacktop(); + } + asm!( + " mv t0, a0", + " la sp, {stack_top}", + " beqz t0, 2f", + " li t1, -4096 * 16", + "1: add sp, sp, t1", + " addi t0, t0, -1", + " bgtz t0, 1b", + "2: ret", + stack_top = sym bootstacktop, + options(noreturn) + ) +} + +/// 主核启动。 +extern "C" fn primary_rust_main(hartid: usize, device_tree_paddr: usize) -> ! { // 清零 bss 段 + extern "C" { + fn sbss(); + fn ebss(); + } 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); @@ -62,8 +122,6 @@ pub extern "C" fn primary_rust_main(hartid: usize, device_tree_paddr: usize) -> let pte = (start_ppn << 10) | DAGXWRV; // 构造启动页表 - // # 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; @@ -105,27 +163,44 @@ 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 { + /// 向上跳到距离为 `offset` 的新地址然后继续执行。 + /// + /// # Safety + /// + /// 裸函数。 + #[naked] + unsafe extern "C" fn jump_higher(offset: usize) { + asm!( + // + "add ra, ra, a0", + "add sp, sp, a0", + "ret", + options(noreturn) + ) + } + /// 设置启动页表,并跃迁到高地址。 /// /// # 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(); + // 此时原本的地址空间还在,所以按理说不用刷快表 + // riscv::asm::sfence_vma_all(); // 跳到高页面对应位置 - _jump_higher(PHYSICAL_MEMORY_OFFSET); + Self::jump_higher(PHYSICAL_MEMORY_OFFSET); // 设置线程指针 asm!("mv tp, {}", in(reg) hartid); // 设置内核可访问用户页 diff --git a/zircon-object/Cargo.toml b/zircon-object/Cargo.toml index 7c9921f9..ad4bc9fb 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 f6a6185e..b88eb03b 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]