diff --git a/.gitignore b/.gitignore index c6561507..f2f0c937 100644 --- a/.gitignore +++ b/.gitignore @@ -36,4 +36,11 @@ tools/redis-3.2.9 tools/sqlite-amalgamation-3410100 alien-* alien.bin -rust \ No newline at end of file +rust + +tests/testsuits-for-oskernel + +subsystems/devices +subsystems/drivers +subsystems/vfs +subsystems/timer \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 7f256a51..b4f5e9a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,6 +13,15 @@ dependencies = [ "talc 2.1.0", ] +[[package]] +name = "aarch64-cpu" +version = "9.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac42a04a61c19fc8196dd728022a784baecc5d63d7e256c01ad1b3fbfab26287" +dependencies = [ + "tock-registers", +] + [[package]] name = "adler" version = "1.0.2" @@ -64,6 +73,14 @@ dependencies = [ "nom 4.2.3", ] +[[package]] +name = "arch" +version = "0.1.0" +dependencies = [ + "config", + "riscv", +] + [[package]] name = "arrayref" version = "0.3.7" @@ -94,15 +111,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "atomic-polyfill" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28" -dependencies = [ - "critical-section", -] - [[package]] name = "atomic-polyfill" version = "1.0.3" @@ -146,7 +154,7 @@ checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" name = "basemachine" version = "0.1.0" dependencies = [ - "fdt", + "fdt 0.1.5", ] [[package]] @@ -206,6 +214,7 @@ dependencies = [ name = "boot" version = "0.1.0" dependencies = [ + "arch", "basemachine", "cfg-if", "kernel", @@ -379,6 +388,10 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[package]] +name = "config" +version = "0.1.0" + [[package]] name = "const-field-offset" version = "0.1.3" @@ -400,6 +413,13 @@ dependencies = [ "syn 2.0.37", ] +[[package]] +name = "constants" +version = "0.1.0" +dependencies = [ + "pconst", +] + [[package]] name = "convert_case" version = "0.4.0" @@ -638,6 +658,32 @@ dependencies = [ "vfscore", ] +[[package]] +name = "device_interface" +version = "0.1.0" +dependencies = [ + "constants", +] + +[[package]] +name = "devices" +version = "0.1.0" +dependencies = [ + "config", + "constants", + "device_interface", + "drivers", + "fdt 0.2.0-alpha1", + "ksync", + "log", + "netcore", + "platform", + "smoltcp", + "spin", + "vfscore", + "virtio-drivers 0.5.0 (git+https://github.com/rcore-os/virtio-drivers?rev=de1c3b1)", +] + [[package]] name = "dispatch" version = "0.2.0" @@ -668,6 +714,27 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +[[package]] +name = "drivers" +version = "0.1.0" +dependencies = [ + "config", + "constants", + "device_interface", + "ksync", + "log", + "loopback", + "lru", + "mem", + "netcore", + "rtc", + "timer", + "uart16550", + "uart8250", + "virtio-drivers 0.5.0 (git+https://github.com/rcore-os/virtio-drivers?rev=de1c3b1)", + "virtio-net", +] + [[package]] name = "drm" version = "0.9.0" @@ -856,6 +923,11 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "784a4df722dc6267a04af36895398f59d21d07dce47232adf31ec0ff2fa45e67" +[[package]] +name = "fdt" +version = "0.2.0-alpha1" +source = "git+https://github.com/repnop/fdt#6fc87b53da0b46166f7bc5029982568e344cc338" + [[package]] name = "field-offset" version = "0.3.6" @@ -1111,11 +1183,11 @@ dependencies = [ [[package]] name = "heapless" -version = "0.7.16" +version = "0.7.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" dependencies = [ - "atomic-polyfill 0.1.11", + "atomic-polyfill", "hash32 0.2.1", "rustc_version", "spin", @@ -1354,6 +1426,18 @@ dependencies = [ "num-traits", ] +[[package]] +name = "interrupt" +version = "0.1.0" +dependencies = [ + "arch", + "config", + "device_interface", + "ksync", + "plic", + "spin", +] + [[package]] name = "inventory" version = "0.3.12" @@ -1416,25 +1500,26 @@ dependencies = [ name = "kernel" version = "0.1.0" dependencies = [ + "arch", "basemachine", "bit_field", "bitflags 1.3.2", "buddy_system_allocator", "cfg-if", + "constants", "devfs", "downcast-rs", "dynfs", "fat-vfs", - "fdt", + "fdt 0.1.5", "gmanager", - "kernel-sync", + "ksync", "log", "loopback", "lru", "netcore", "page-table", "pager", - "pconst", "plic", "preprint", "ramfs", @@ -1465,6 +1550,15 @@ dependencies = [ "lock_api", ] +[[package]] +name = "ksync" +version = "0.1.0" +dependencies = [ + "arch", + "config", + "kernel-sync", +] + [[package]] name = "kurbo" version = "0.9.5" @@ -1639,6 +1733,25 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d" +[[package]] +name = "mem" +version = "0.1.0" +dependencies = [ + "arch", + "buddy_system_allocator", + "config", + "ksync", + "log", + "memory_addr", + "page-table", + "page_table", + "pager", + "platform", + "rslab", + "spin", + "talc 1.0.0", +] + [[package]] name = "memchr" version = "2.3.4" @@ -1703,6 +1816,11 @@ dependencies = [ "virt2slint", ] +[[package]] +name = "memory_addr" +version = "0.1.0" +source = "git+https://github.com/rcore-os/arceos?rev=7eeebc5#7eeebc5581f3d1d6e8b03c6177c6cb34543ae50f" + [[package]] name = "micromath" version = "1.1.1" @@ -1983,7 +2101,7 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" dependencies = [ - "atomic-polyfill 1.0.3", + "atomic-polyfill", "critical-section", ] @@ -2012,6 +2130,27 @@ dependencies = [ "log", ] +[[package]] +name = "page_table" +version = "0.1.0" +source = "git+https://github.com/rcore-os/arceos?rev=7eeebc5#7eeebc5581f3d1d6e8b03c6177c6cb34543ae50f" +dependencies = [ + "log", + "memory_addr", + "page_table_entry", +] + +[[package]] +name = "page_table_entry" +version = "0.1.0" +source = "git+https://github.com/rcore-os/arceos?rev=7eeebc5#7eeebc5581f3d1d6e8b03c6177c6cb34543ae50f" +dependencies = [ + "aarch64-cpu", + "bitflags 2.4.0", + "memory_addr", + "x86_64", +] + [[package]] name = "pager" version = "0.1.0" @@ -2094,6 +2233,16 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +[[package]] +name = "platform" +version = "0.1.0" +dependencies = [ + "arch", + "config", + "ksync", + "log", +] + [[package]] name = "plic" version = "0.1.0" @@ -2623,7 +2772,7 @@ dependencies = [ "byteorder", "cfg-if", "defmt", - "heapless 0.7.16", + "heapless 0.7.17", "log", "managed", ] @@ -2895,6 +3044,14 @@ dependencies = [ "time-core", ] +[[package]] +name = "timer" +version = "0.1.0" +dependencies = [ + "arch", + "config", +] + [[package]] name = "tiny-skia" version = "0.10.0" @@ -2958,6 +3115,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tock-registers" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "696941a0aee7e276a165a978b37918fd5d22c55c3d6bda197813070ca9c0f21c" + [[package]] name = "todo" version = "0.1.0" @@ -3222,6 +3385,24 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "vfs" +version = "0.1.0" +dependencies = [ + "arch", + "constants", + "devfs", + "dynfs", + "fat-vfs", + "interrupt", + "ksync", + "log", + "platform", + "ramfs", + "spin", + "vfscore", +] + [[package]] name = "vfscore" version = "0.1.0" @@ -3697,6 +3878,18 @@ dependencies = [ "nix", ] +[[package]] +name = "x86_64" +version = "0.14.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b835097a84e4457323331ec5d6eb23d096066cbfb215d54096dcb4b2e85f500" +dependencies = [ + "bit_field", + "bitflags 2.4.0", + "rustversion", + "volatile", +] + [[package]] name = "xmas-elf" version = "0.9.0" diff --git a/Cargo.toml b/Cargo.toml index 46501212..c26eb0ae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,11 @@ members = [ "apps/memory-game", "apps/print", "apps/final_test", -] + "subsystems/arch", + "subsystems/config", + "subsystems/ksync", + "subsystems/constants" +, "subsystems/mem", "subsystems/vfs", "subsystems/devices", "subsystems/drivers", "subsystems/interrupt", "subsystems/device_interface", "subsystems/timer"] [profile.release] diff --git a/apps/egui/src/main.rs b/apps/egui/src/main.rs index 43707663..74cba48f 100644 --- a/apps/egui/src/main.rs +++ b/apps/egui/src/main.rs @@ -23,7 +23,7 @@ impl GpuDevice { } } -impl GPUDevice for GpuDevice{ +impl GPUDevice for GpuDevice { fn flush(&self) { flush_frame_buffer(); } @@ -38,7 +38,6 @@ impl GPUDevice for GpuDevice{ } } - #[no_mangle] fn main() { println!("embedded graphics demo"); diff --git a/apps/ls/src/main.rs b/apps/ls/src/main.rs index 2b4b8e4a..1bcf9c86 100644 --- a/apps/ls/src/main.rs +++ b/apps/ls/src/main.rs @@ -20,7 +20,7 @@ fn main(_: usize, argv: Vec) -> isize { } 0 } -const BUF_SIZE:usize = 512; +const BUF_SIZE: usize = 512; fn parse_args(path: &str) { let fd = open(path, OpenFlags::O_RDONLY); assert!(fd >= 0, "open failed"); diff --git a/apps/memory-game/src/main.rs b/apps/memory-game/src/main.rs index 2aaea6a7..31efdf7b 100644 --- a/apps/memory-game/src/main.rs +++ b/apps/memory-game/src/main.rs @@ -13,8 +13,8 @@ use rand::prelude::{SliceRandom, SmallRng}; use rand::SeedableRng; use slint::platform::WindowEvent; use slint::{Model, VecModel}; -use virt2slint::Converter; use slint_helper::{MyPlatform, SwapBuffer}; +use virt2slint::Converter; use Mstd::io::{keyboard_or_mouse_event, VIRTGPU_XRES, VIRTGPU_YRES}; use Mstd::time::get_time_ms; @@ -86,7 +86,7 @@ fn main() { loop { // Let Slint run the timer hooks and update animations. slint::platform::update_timers_and_animations(); - let events = checkout_event(&mut converter,&mut x, &mut y); + let events = checkout_event(&mut converter, &mut x, &mut y); events.iter().for_each(|event| { window.dispatch_event(event.clone()); }); @@ -99,7 +99,7 @@ fn main() { }); } } -fn checkout_event(converter: &mut Converter,x: &mut isize, y: &mut isize) -> Vec { +fn checkout_event(converter: &mut Converter, x: &mut isize, y: &mut isize) -> Vec { let mut events = [0; 100]; let event_num = keyboard_or_mouse_event(&mut events); let mut res = Vec::new(); @@ -107,9 +107,9 @@ fn checkout_event(converter: &mut Converter,x: &mut isize, y: &mut isize) -> Vec let event = events[i]; // let window_event = input2event(event, x, y); let window_event = converter.convert(event, x, y); - window_event.map(|e|{ + window_event.map(|e| { res.push(e); }); } res -} \ No newline at end of file +} diff --git a/apps/printdemo/src/main.rs b/apps/printdemo/src/main.rs index 4f24bce1..663f7ee6 100644 --- a/apps/printdemo/src/main.rs +++ b/apps/printdemo/src/main.rs @@ -11,8 +11,8 @@ use alloc::vec::Vec; use slint::platform::WindowEvent; use slint::Model; -use virt2slint::Converter; use slint_helper::{MyPlatform, SwapBuffer}; +use virt2slint::Converter; use Mstd::io::{keyboard_or_mouse_event, VIRTGPU_XRES, VIRTGPU_YRES}; #[no_mangle] @@ -142,7 +142,7 @@ fn main() -> ! { loop { // Let Slint run the timer hooks and update animations. slint::platform::update_timers_and_animations(); - let events = checkout_event(&mut converter,&mut x, &mut y); + let events = checkout_event(&mut converter, &mut x, &mut y); events.iter().for_each(|event| { window.dispatch_event(event.clone()); }); @@ -156,7 +156,7 @@ fn main() -> ! { } } -fn checkout_event(converter: &mut Converter,x: &mut isize, y: &mut isize) -> Vec { +fn checkout_event(converter: &mut Converter, x: &mut isize, y: &mut isize) -> Vec { let mut events = [0; 100]; let event_num = keyboard_or_mouse_event(&mut events); let mut res = Vec::new(); @@ -164,9 +164,9 @@ fn checkout_event(converter: &mut Converter,x: &mut isize, y: &mut isize) -> Vec let event = events[i]; // let window_event = input2event(event, x, y); let window_event = converter.convert(event, x, y); - window_event.map(|e|{ + window_event.map(|e| { res.push(e); }); } res -} \ No newline at end of file +} diff --git a/apps/slint/src/main.rs b/apps/slint/src/main.rs index 0312d923..10f0d3e7 100644 --- a/apps/slint/src/main.rs +++ b/apps/slint/src/main.rs @@ -41,7 +41,7 @@ fn main() { loop { // Let Slint run the timer hooks and update animations. slint::platform::update_timers_and_animations(); - let events = checkout_event(&mut converter,&mut x, &mut y); + let events = checkout_event(&mut converter, &mut x, &mut y); events.iter().for_each(|event| { window.dispatch_event(event.clone()); }); @@ -55,7 +55,7 @@ fn main() { } } -fn checkout_event(converter: &mut Converter,x: &mut isize, y: &mut isize) -> Vec { +fn checkout_event(converter: &mut Converter, x: &mut isize, y: &mut isize) -> Vec { let mut events = [0; 100]; let event_num = keyboard_or_mouse_event(&mut events); let mut res = Vec::new(); @@ -63,7 +63,7 @@ fn checkout_event(converter: &mut Converter,x: &mut isize, y: &mut isize) -> Vec let event = events[i]; // let window_event = input2event(event, x, y); let window_event = converter.convert(event, x, y); - window_event.map(|e|{ + window_event.map(|e| { res.push(e); }); } diff --git a/apps/sysinfo/src/main.rs b/apps/sysinfo/src/main.rs index 00c2e9b3..f1b92563 100644 --- a/apps/sysinfo/src/main.rs +++ b/apps/sysinfo/src/main.rs @@ -11,8 +11,8 @@ use alloc::vec::Vec; use slint::platform::WindowEvent; use slint::SharedString; -use virt2slint::Converter; use slint_helper::{MyPlatform, SwapBuffer}; +use virt2slint::Converter; use Mstd::io::{keyboard_or_mouse_event, VIRTGPU_XRES, VIRTGPU_YRES}; slint::include_modules!(); @@ -62,7 +62,7 @@ fn main() { loop { // Let Slint run the timer hooks and update animations. slint::platform::update_timers_and_animations(); - let events = checkout_event(&mut converter,&mut x, &mut y); + let events = checkout_event(&mut converter, &mut x, &mut y); events.iter().for_each(|event| { window.dispatch_event(event.clone()); }); @@ -76,8 +76,7 @@ fn main() { } } - -fn checkout_event(converter: &mut Converter,x: &mut isize, y: &mut isize) -> Vec { +fn checkout_event(converter: &mut Converter, x: &mut isize, y: &mut isize) -> Vec { let mut events = [0; 100]; let event_num = keyboard_or_mouse_event(&mut events); let mut res = Vec::new(); @@ -85,9 +84,9 @@ fn checkout_event(converter: &mut Converter,x: &mut isize, y: &mut isize) -> Vec let event = events[i]; // let window_event = input2event(event, x, y); let window_event = converter.convert(event, x, y); - window_event.map(|e|{ + window_event.map(|e| { res.push(e); }); } res -} \ No newline at end of file +} diff --git a/apps/todo/src/main.rs b/apps/todo/src/main.rs index 31722e53..2cf3e9b6 100644 --- a/apps/todo/src/main.rs +++ b/apps/todo/src/main.rs @@ -12,8 +12,8 @@ use core::default::Default; use core::iter::Iterator; use slint::platform::WindowEvent; use slint::{FilterModel, Model, SortModel}; -use virt2slint::Converter; use slint_helper::{MyPlatform, SwapBuffer}; +use virt2slint::Converter; use Mstd::io::{keyboard_or_mouse_event, VIRTGPU_XRES, VIRTGPU_YRES}; slint::include_modules!(); @@ -147,7 +147,7 @@ fn main() { loop { // Let Slint run the timer hooks and update animations. slint::platform::update_timers_and_animations(); - let events = checkout_event(&mut converter,&mut x, &mut y); + let events = checkout_event(&mut converter, &mut x, &mut y); events.iter().for_each(|event| { window.dispatch_event(event.clone()); }); @@ -161,7 +161,7 @@ fn main() { } } -fn checkout_event(converter: &mut Converter,x: &mut isize, y: &mut isize) -> Vec { +fn checkout_event(converter: &mut Converter, x: &mut isize, y: &mut isize) -> Vec { let mut events = [0; 100]; let event_num = keyboard_or_mouse_event(&mut events); let mut res = Vec::new(); @@ -169,7 +169,7 @@ fn checkout_event(converter: &mut Converter,x: &mut isize, y: &mut isize) -> Vec let event = events[i]; // let window_event = input2event(event, x, y); let window_event = converter.convert(event, x, y); - window_event.map(|e|{ + window_event.map(|e| { res.push(e); }); } diff --git a/boot/Cargo.toml b/boot/Cargo.toml index 410ca4e2..9781b1b3 100644 --- a/boot/Cargo.toml +++ b/boot/Cargo.toml @@ -13,6 +13,8 @@ basemachine = { path = "../dep/basemachine" } kernel = { version = "0.1.0", path = "../kernel" } +arch = { path = "../subsystems/arch" } + [features] default = [] vf2 = ["kernel/vf2"] diff --git a/boot/src/main.rs b/boot/src/main.rs index 5c75d044..dfe8f47a 100644 --- a/boot/src/main.rs +++ b/boot/src/main.rs @@ -25,8 +25,8 @@ use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use cfg_if::cfg_if; use kernel::init_init_array; +use arch::hart_id; use basemachine::machine_info_from_dtb; -use kernel::arch::hart_id; #[cfg(not(feature = "qemu"))] use kernel::board; #[cfg(any( @@ -43,7 +43,7 @@ use kernel::interrupt::init_plic; use kernel::memory::{init_memory_system, kernel_info}; use kernel::print::init_print; use kernel::sbi::hart_start; -use kernel::{config, init_machine_info, println, task, thread_local_init, timer, trap}; +use kernel::{config, init_machine_info, println, task, timer, trap}; mod entry; @@ -92,7 +92,7 @@ pub fn main(_: usize, _: usize) -> ! { init_machine_info(machine_info.clone()); kernel_info(machine_info.memory.end); init_memory_system(machine_info.memory.end, true); - thread_local_init(); + arch::allow_access_user_memory(); // init device tree #[cfg(feature = "qemu")] init_dtb(Some(device_tree_addr)); @@ -114,7 +114,7 @@ pub fn main(_: usize, _: usize) -> ! { while !STARTED.load(Ordering::Relaxed) { spin_loop(); } - thread_local_init(); + arch::allow_access_user_memory(); println!("hart {:#x} start", hart_id()); init_memory_system(0, false); trap::init_trap_subsystem(); diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index a4e8a836..5ef36955 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -7,7 +7,7 @@ authors = ["chen linfeng"] [dependencies] log = "0.4.14" spin = "0.9.2" -riscv = "0.10.0" +riscv = "0.10" bit_field = "0.10.1" xmas-elf = "0.9.0" bitflags = "1.3.2" @@ -27,10 +27,6 @@ rslab = { version = "0.2.1", optional = true } syscall-table = { git = "https://github.com/os-module/syscall-table.git" } plic = { git = "https://github.com/os-module/plic" } pager = { git = "https://github.com/os-module/pager", default-features = false, optional = true } -kernel-sync = { git = "https://github.com/os-module/kernel-sync.git"} -pconst = { git = "https://github.com/os-module/pconst.git", features = [ - "trick", -] } gmanager = { path = "../dep/gmanager" } basemachine = { path = "../dep/basemachine" } uart16550 = { version = "0.0.1", optional = true } @@ -48,10 +44,17 @@ devfs = { git = "https://github.com/os-module/rvfs.git" } dynfs = { git = "https://github.com/os-module/rvfs.git" } ramfs = { git = "https://github.com/os-module/rvfs.git" } fat-vfs = { git = "https://github.com/os-module/rvfs.git" } + + loopback = {git = "https://github.com/os-module/simple-net",optional = true} virtio-net = {git = "https://github.com/os-module/simple-net"} netcore = {git = "https://github.com/os-module/simple-net"} +arch = { path = "../subsystems/arch"} +ksync = {path = "../subsystems/ksync"} +constants = {path = "../subsystems/constants" } + + [dependencies.smoltcp] git = "https://github.com/rcore-os/smoltcp.git" rev = "2ade274" diff --git a/kernel/src/arch/riscv.rs b/kernel/src/arch/riscv.rs deleted file mode 100644 index eee8ab02..00000000 --- a/kernel/src/arch/riscv.rs +++ /dev/null @@ -1,45 +0,0 @@ -pub use riscv::*; - -pub mod sstatus { - use core::arch::asm; - - use bit_field::BitField; - pub use riscv::register::sstatus::*; - - #[derive(Copy, Clone, Debug, Default)] - pub struct Sstatus(pub usize); - - impl Sstatus { - pub fn set_value(&mut self, val: usize) { - self.0 = val; - } - pub fn set_spp(&mut self, spp: SPP) { - self.0.set_bit(8, spp as usize != 0); - } - pub fn spp(&self) -> SPP { - let v = self.0.get_bit(8); - if v { - SPP::Supervisor - } else { - SPP::User - } - } - pub fn set_spie(&mut self) { - self.0.set_bit(5, true); - } - pub fn sie(&self) -> bool { - self.0.get_bit(1) - } - pub fn set_sie(&mut self, value: bool) { - self.0.set_bit(1, value); - } - } - - pub fn read() -> Sstatus { - let val: usize; - unsafe { - asm!("csrr {},sstatus", out(reg)val); - } - Sstatus(val) - } -} diff --git a/kernel/src/board/common.rs b/kernel/src/board/common.rs index 9b26c8d6..59dd7e55 100644 --- a/kernel/src/board/common.rs +++ b/kernel/src/board/common.rs @@ -1,7 +1,6 @@ use fdt::node::FdtNode; use fdt::Fdt; -#[allow(unused)] pub fn get_device_info(fdt: &Fdt, device_name: &str) -> Option<(usize, usize)> { let res = fdt .all_nodes() diff --git a/kernel/src/board/cv1811.rs b/kernel/src/board/cv1811.rs deleted file mode 100644 index 664416d8..00000000 --- a/kernel/src/board/cv1811.rs +++ /dev/null @@ -1,49 +0,0 @@ -use fdt::Fdt; -use spin::Once; - -use crate::board::common::get_device_info; - -#[repr(align(4))] -struct _Wrapper(T); - -pub const FDT: &[u8] = &_Wrapper(*include_bytes!("../../../tools/cv1811h.dtb")).0; - -pub static DTB: Once = Once::new(); - -pub fn init_dtb(dtb: Option) { - let fdt = if dtb.is_some() { - unsafe { Fdt::from_ptr(dtb as *const u8).unwrap() } - } else { - unsafe { Fdt::from_ptr(FDT.as_ptr()).unwrap() } - }; - DTB.call_once(|| fdt); -} - -/// Get the base address and irq number of the uart device from the device tree. -pub fn probe_devices_from_dtb() { - if let Some(rtc) = probe_rtc() { - BOARD_DEVICES.lock().insert(DeviceType::Rtc, rtc); - } - if let Some(uart) = probe_uart() { - BOARD_DEVICES.lock().insert(DeviceType::Uart, uart); - } -} - -/// Get the base address and irq number of the uart device from the device tree. -pub fn probe_rtc() -> Option { - let fdt = DTB.get().unwrap(); - let res = get_device_info(fdt, "rtc"); - if res.is_none() { - return None; - } - let (base_addr, irq) = res.unwrap(); - Some(DeviceInfo::new(base_addr, irq)) -} - -pub fn probe_uart() -> Option { - let fdt = DTB.get().unwrap(); - if let Some((base_addr, irq)) = get_device_info(fdt, "serial0") { - return Some(DeviceInfo::new(base_addr, irq)); - } - None -} diff --git a/kernel/src/board/mod.rs b/kernel/src/board/mod.rs index 562684f8..399a874b 100644 --- a/kernel/src/board/mod.rs +++ b/kernel/src/board/mod.rs @@ -2,7 +2,7 @@ use alloc::collections::BTreeMap; use cfg_if::cfg_if; -use crate::ksync::Mutex; +use ksync::Mutex; use crate::device::{DeviceInfo, DeviceType}; @@ -63,9 +63,6 @@ cfg_if! { if #[cfg(feature="qemu")]{ mod qemu; pub use qemu::*; - }else if #[cfg(feature="cv1811")]{ - mod cv1811; - pub use cv1811::*; }else if #[cfg(feature="hifive")]{ mod unmatched; pub use unmatched::*; diff --git a/kernel/src/board/qemu.rs b/kernel/src/board/qemu.rs index 3f31ec60..0d21b187 100644 --- a/kernel/src/board/qemu.rs +++ b/kernel/src/board/qemu.rs @@ -38,11 +38,7 @@ pub fn probe_devices_from_dtb() { pub fn probe_rtc() -> Option { let fdt = DTB.get().unwrap(); let res = get_device_info(fdt, "rtc"); - if res.is_none() { - return None; - } - let (base_addr, irq) = res.unwrap(); - Some(DeviceInfo::new(base_addr, irq)) + res.map(|(base_addr, irq)| DeviceInfo::new(base_addr, irq)) } /// Get the base address and irq number of the uart device from the device tree. @@ -100,7 +96,7 @@ fn virtio_probe(node: &FdtNode) -> Option<(DeviceType, DeviceInfo)> { transport.read_device_features(), ); info!("Probe virtio device: {:?}", transport.device_type()); - match transport.device_type() { + return match transport.device_type() { VirtDeviceType::Input => { let device_info = DeviceInfo::new(paddr, irq); let res = if paddr == VIRTIO5 { @@ -110,22 +106,22 @@ fn virtio_probe(node: &FdtNode) -> Option<(DeviceType, DeviceInfo)> { } else { None }; - return res; + res } VirtDeviceType::Block => { let device_info = DeviceInfo::new(paddr, irq); - return Some((DeviceType::Block, device_info)); + Some((DeviceType::Block, device_info)) } VirtDeviceType::GPU => { let device_info = DeviceInfo::new(paddr, irq); - return Some((DeviceType::GPU, device_info)); + Some((DeviceType::GPU, device_info)) } VirtDeviceType::Network => { let device_info = DeviceInfo::new(paddr, irq); - return Some((DeviceType::Network, device_info)); + Some((DeviceType::Network, device_info)) } - _ => return None, - } + _ => None, + }; } } } diff --git a/kernel/src/device/block.rs b/kernel/src/device/block.rs index e52b3c82..d3a99d84 100644 --- a/kernel/src/device/block.rs +++ b/kernel/src/device/block.rs @@ -1,8 +1,8 @@ use alloc::sync::Arc; use crate::driver::GenericBlockDevice; -use crate::error::AlienResult; use crate::fs::dev::DeviceId; +use constants::AlienResult; use spin::Once; use vfscore::error::VfsError; use vfscore::file::VfsFile; @@ -52,10 +52,10 @@ impl VfsFile for BLKDevice { .map_err(|_| VfsError::IoError) } fn poll(&self, _event: VfsPollEvents) -> VfsResult { - todo!() + unimplemented!() } fn ioctl(&self, _cmd: u32, _arg: usize) -> VfsResult { - todo!() + unimplemented!() } fn flush(&self) -> VfsResult<()> { Ok(()) diff --git a/kernel/src/device/input.rs b/kernel/src/device/input.rs index 3da763a0..918097c7 100644 --- a/kernel/src/device/input.rs +++ b/kernel/src/device/input.rs @@ -42,7 +42,7 @@ impl INPUTDevice { impl VfsFile for INPUTDevice { fn read_at(&self, _offset: u64, buf: &mut [u8]) -> VfsResult { - if buf.len() != 8{ + if buf.len() != 8 { return Err(VfsError::Invalid); } let buf = unsafe { core::slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut u64, 1) }; @@ -85,12 +85,10 @@ impl VfsInode for INPUTDevice { pub static KEYBOARD_INPUT_DEVICE: Once> = Once::new(); pub static MOUSE_INPUT_DEVICE: Once> = Once::new(); - pub fn init_keyboard_input_device(input_device: Arc) { KEYBOARD_INPUT_DEVICE.call_once(|| input_device); } - pub fn init_mouse_input_device(input_device: Arc) { MOUSE_INPUT_DEVICE.call_once(|| input_device); } diff --git a/kernel/src/device/mod.rs b/kernel/src/device/mod.rs index 89738ebd..f165fd55 100644 --- a/kernel/src/device/mod.rs +++ b/kernel/src/device/mod.rs @@ -9,11 +9,11 @@ use alloc::boxed::Box; use alloc::sync::Arc; pub use block::{BLKDevice, BlockDevice, BLOCK_DEVICE}; use core::sync::atomic::Ordering; -use smoltcp::wire::IpAddress; pub use gpu::{GPUDevice, GpuDevice, GPU_DEVICE}; pub use input::{ sys_event_get, INPUTDevice, InputDevice, KEYBOARD_INPUT_DEVICE, MOUSE_INPUT_DEVICE, }; +use smoltcp::wire::IpAddress; mod block; mod gpu; @@ -67,11 +67,11 @@ fn init_rtc() { #[cfg(feature = "qemu")] { use crate::driver::rtc::GoldFishRtc; - use ::rtc::{LowRtcDeviceExt}; + use ::rtc::LowRtcDeviceExt; let rtc = Arc::new(GoldFishRtc::new(base_addr)); let current_time = rtc.read_time_fmt(); rtc::init_rtc(rtc.clone()); - register_device_to_plic(irq, rtc.clone()); + register_device_to_plic(irq, rtc); println!("Init rtc success, current time: {:?}", current_time); } #[cfg(feature = "vf2")] @@ -150,7 +150,6 @@ fn init_fake_disk() { block::init_block_device(device.clone()); } - fn init_gpu() { let res = crate::board::get_gpu_info(); if res.is_none() { @@ -237,15 +236,15 @@ fn init_net() { use crate::device::net::NetNeedFunc; use crate::driver::net::make_virtio_net_device; let virtio_net = make_virtio_net_device(base_addr); - use core::str::FromStr; use crate::config::{QEMU_GATEWAY, QEMU_IP}; + use core::str::FromStr; let device = Box::new(virtio_net); netcore::init_net( device, Arc::new(NetNeedFunc), IpAddress::from_str(QEMU_IP).unwrap(), - IpAddress::from_str(QEMU_GATEWAY).unwrap(), - true + IpAddress::from_str(QEMU_GATEWAY).unwrap(), + true, ); println!("Init net device success"); #[cfg(feature = "net_test")] @@ -261,16 +260,9 @@ fn init_loop_device() { use crate::device::net::NetNeedFunc; use loopback::LoopbackDev; // use default ip and gateway for qemu - let ip = IpAddress::v4(127,0,0,1); - let gate_way = IpAddress::v4(127,0,0,1); + let ip = IpAddress::v4(127, 0, 0, 1); + let gate_way = IpAddress::v4(127, 0, 0, 1); let loopback = Box::new(LoopbackDev::new()); - netcore::init_net( - loopback, - Arc::new(NetNeedFunc), - ip, - gate_way, - false, - ); + netcore::init_net(loopback, Arc::new(NetNeedFunc), ip, gate_way, false); println!("Init net device success"); } - diff --git a/kernel/src/device/net.rs b/kernel/src/device/net.rs index befb6bdc..2d2a6af7 100644 --- a/kernel/src/device/net.rs +++ b/kernel/src/device/net.rs @@ -8,11 +8,11 @@ pub trait NetDevice: DeviceBase {} #[cfg(feature = "net_test")] pub mod nettest { + use crate::net::port::neterror2alien; use alloc::vec::Vec; + use constants::AlienResult; use core::net::{IpAddr, SocketAddr}; use netcore::tcp::TcpSocket; - use crate::error::{AlienResult}; - use crate::net::port::neterror2alien; /// A TCP stream between a local and a remote socket. pub struct TcpStream(TcpSocket); @@ -68,16 +68,12 @@ pub mod nettest { if n == 0 { return Ok(()); } - stream - .write_all(reverse(&buf[..n]).as_slice()).unwrap(); + stream.write_all(reverse(&buf[..n]).as_slice()).unwrap(); } } pub fn accept_loop() { - let local_addr = SocketAddr::new( - IpAddr::V4(LOCAL_IP.parse().unwrap()), - LOCAL_PORT, - ); + let local_addr = SocketAddr::new(IpAddr::V4(LOCAL_IP.parse().unwrap()), LOCAL_PORT); let listener = TcpListener::bind(local_addr).unwrap(); println!("listen on: {}", listener.local_addr().unwrap()); let mut i = 0; diff --git a/kernel/src/device/rtc.rs b/kernel/src/device/rtc.rs index 485be920..44d488b8 100644 --- a/kernel/src/device/rtc.rs +++ b/kernel/src/device/rtc.rs @@ -1,7 +1,7 @@ use alloc::format; use alloc::sync::Arc; +use constants::io::TeletypeCommand; use core::cmp::min; -use pconst::io::TeletypeCommand; use rtc::RtcTime; use crate::fs::dev::DeviceId; @@ -62,7 +62,7 @@ impl VfsFile for RTCDevice { match cmd { TeletypeCommand::RTC_RD_TIME => { let time = self.device.read_time_fmt(); - let c_rtc_time = pconst::io::RtcTime{ + let c_rtc_time = constants::io::RtcTime { sec: time.second as u32, min: time.minute as u32, hour: time.hour as u32, @@ -73,7 +73,7 @@ impl VfsFile for RTCDevice { yday: 0, isdst: 0, }; - task_inner.copy_to_user(&c_rtc_time, arg as *mut pconst::io::RtcTime); + task_inner.copy_to_user(&c_rtc_time, arg as *mut constants::io::RtcTime); } _ => return Err(VfsError::Invalid), } diff --git a/kernel/src/device/uart.rs b/kernel/src/device/uart.rs index 5a8c552d..9b511b1f 100644 --- a/kernel/src/device/uart.rs +++ b/kernel/src/device/uart.rs @@ -1,6 +1,6 @@ use crate::fs::dev::DeviceId; use alloc::sync::Arc; -use pconst::io::{LocalModes, TeletypeCommand, Termios, WinSize}; +use constants::io::{LocalModes, TeletypeCommand, Termios, WinSize}; use spin::Once; use vfscore::error::VfsError; use vfscore::file::VfsFile; @@ -10,8 +10,8 @@ use vfscore::utils::{VfsFileStat, VfsNodeType, VfsPollEvents}; use vfscore::VfsResult; use crate::interrupt::DeviceBase; -use crate::ksync::Mutex; use crate::task::current_task; +use ksync::Mutex; pub trait UartDevice: Send + Sync + DeviceBase { fn put(&self, c: u8); diff --git a/kernel/src/driver/block_device.rs b/kernel/src/driver/block_device.rs index 8c525dc7..0c0c6f0c 100644 --- a/kernel/src/driver/block_device.rs +++ b/kernel/src/driver/block_device.rs @@ -1,17 +1,17 @@ use alloc::boxed::Box; use alloc::vec::Vec; +use constants::LinuxErrno; use core::cmp::min; use core::fmt::{Debug, Formatter}; use core::num::NonZeroUsize; use core::ptr::NonNull; -use pconst::LinuxErrno; use lru::LruCache; use virtio_drivers::device::blk::VirtIOBlk; use virtio_drivers::transport::mmio::{MmioTransport, VirtIOHeader}; -use crate::error::AlienResult; -use crate::ksync::Mutex; +use constants::AlienResult; +use ksync::Mutex; use crate::config::BLOCK_CACHE_FRAMES; use crate::config::FRAME_SIZE; diff --git a/kernel/src/driver/gpu.rs b/kernel/src/driver/gpu.rs index b678d98d..61dbb485 100644 --- a/kernel/src/driver/gpu.rs +++ b/kernel/src/driver/gpu.rs @@ -2,7 +2,7 @@ use core::ptr::NonNull; use virtio_drivers::device::gpu::VirtIOGpu; use virtio_drivers::transport::mmio::{MmioTransport, VirtIOHeader}; -use crate::ksync::Mutex; +use ksync::Mutex; use crate::device::GpuDevice; use crate::driver::hal::HalImpl; @@ -35,7 +35,7 @@ impl VirtIOGpuWrapper { Self { gpu: Mutex::new(gpu), fb, - resolution + resolution, } } } diff --git a/kernel/src/driver/input.rs b/kernel/src/driver/input.rs index a556a896..5f1d8d15 100644 --- a/kernel/src/driver/input.rs +++ b/kernel/src/driver/input.rs @@ -5,7 +5,7 @@ use core::ptr::NonNull; use virtio_drivers::device::input::VirtIOInput; use virtio_drivers::transport::mmio::{MmioTransport, VirtIOHeader}; -use crate::ksync::Mutex; +use ksync::Mutex; use smpscheduler::FifoTask; use crate::device::InputDevice; diff --git a/kernel/src/driver/net.rs b/kernel/src/driver/net.rs index e10c93bd..a776a543 100644 --- a/kernel/src/driver/net.rs +++ b/kernel/src/driver/net.rs @@ -8,9 +8,11 @@ use crate::driver::hal::HalImpl; pub const NET_BUFFER_LEN: usize = 4096; pub const NET_QUEUE_SIZE: usize = 128; -pub fn make_virtio_net_device(addr:usize) -> VirtIONetDeviceWrapper { +pub fn make_virtio_net_device( + addr: usize, +) -> VirtIONetDeviceWrapper { let header = NonNull::new(addr as *mut VirtIOHeader).unwrap(); let transport = unsafe { MmioTransport::new(header) }.unwrap(); let device = VirtIONetDeviceWrapper::new(transport, NET_BUFFER_LEN); device -} \ No newline at end of file +} diff --git a/kernel/src/driver/uart.rs b/kernel/src/driver/uart.rs index 61971ef0..a1e7cc38 100644 --- a/kernel/src/driver/uart.rs +++ b/kernel/src/driver/uart.rs @@ -1,7 +1,7 @@ -use crate::ksync::Mutex; use alloc::boxed::Box; use alloc::collections::VecDeque; use alloc::sync::Arc; +use ksync::Mutex; use smpscheduler::FifoTask; #[cfg(not(feature = "vf2"))] diff --git a/kernel/src/error.rs b/kernel/src/error.rs deleted file mode 100644 index b656d979..00000000 --- a/kernel/src/error.rs +++ /dev/null @@ -1,7 +0,0 @@ -//! alien os中error定义 -//! -//! 后续需要将其与linux的error等价转换 -use pconst::LinuxErrno; - -pub type AlienError = LinuxErrno; -pub type AlienResult = Result; diff --git a/kernel/src/fs/basic.rs b/kernel/src/fs/basic.rs index 417e53a3..9d88776d 100644 --- a/kernel/src/fs/basic.rs +++ b/kernel/src/fs/basic.rs @@ -1,18 +1,18 @@ use super::im2vim; use crate::config::AT_FDCWD; -use crate::error::AlienResult; use crate::fs::file::KernelFile; use crate::fs::{syscontext_for_vfs, user_path_at, FS, SYSTEM_ROOT_FS}; use crate::task::current_task; use alloc::sync::Arc; use alloc::vec; +use constants::io::{ + FileStat, FsStat, InodeMode, IoVec, MountFlags, OpenFlags, Renameat2Flags, SeekFrom, StatFlags, +}; +use constants::AlienResult; +use constants::LinuxErrno; use core::cmp::min; use core::ops::Index; use gmanager::ManagerError; -use pconst::io::{ - FileStat, FsStat, InodeMode, IoVec, MountFlags, OpenFlags, Renameat2Flags, SeekFrom, StatFlags, -}; -use pconst::LinuxErrno; use syscall_table::syscall_func; use vfscore::path::VfsPath; use vfscore::utils::{VfsFileStat, VfsFsStat, VfsNodeType, VfsRenameFlag}; diff --git a/kernel/src/fs/control.rs b/kernel/src/fs/control.rs index db28c4db..337a55fb 100644 --- a/kernel/src/fs/control.rs +++ b/kernel/src/fs/control.rs @@ -1,10 +1,10 @@ use crate::config::AT_FDCWD; -use crate::error::AlienResult; use crate::fs::user_path_at; use crate::task::current_task; use crate::timer::TimeSpec; -use pconst::io::{FaccessatFlags, FaccessatMode, Fcntl64Cmd, OpenFlags, TeletypeCommand}; -use pconst::LinuxErrno; +use constants::io::{FaccessatFlags, FaccessatMode, Fcntl64Cmd, OpenFlags, TeletypeCommand}; +use constants::AlienResult; +use constants::LinuxErrno; use syscall_table::syscall_func; use vfscore::utils::*; diff --git a/kernel/src/fs/dev/mod.rs b/kernel/src/fs/dev/mod.rs index 4a3b88af..2da04bea 100644 --- a/kernel/src/fs/dev/mod.rs +++ b/kernel/src/fs/dev/mod.rs @@ -4,10 +4,10 @@ use crate::device::{ }; use crate::fs::dev::null::NullDevice; use crate::fs::dev::random::RandomDevice; -use crate::ksync::Mutex; use alloc::collections::BTreeMap; use alloc::sync::Arc; use devfs::DevKernelProvider; +use ksync::Mutex; use spin::Lazy; use vfscore::dentry::VfsDentry; use vfscore::fstype::VfsFsType; @@ -186,7 +186,10 @@ pub fn init_devfs(devfs: Arc) -> Arc { fn scan_system_devices(root: Arc) { BLOCK_DEVICE.get().map(|blk| { - let block_device = Arc::new(BLKDevice::new(alloc_device_id(VfsNodeType::BlockDevice), blk.clone())); + let block_device = Arc::new(BLKDevice::new( + alloc_device_id(VfsNodeType::BlockDevice), + blk.clone(), + )); root.create( "sda", VfsNodeType::BlockDevice, @@ -197,7 +200,10 @@ fn scan_system_devices(root: Arc) { register_device(block_device); }); GPU_DEVICE.get().map(|gpu| { - let gpu_device = Arc::new(GPUDevice::new(alloc_device_id(VfsNodeType::CharDevice), gpu.clone())); + let gpu_device = Arc::new(GPUDevice::new( + alloc_device_id(VfsNodeType::CharDevice), + gpu.clone(), + )); root.create( "gpu", VfsNodeType::BlockDevice, @@ -238,7 +244,10 @@ fn scan_system_devices(root: Arc) { register_device(input_device); }); RTC_DEVICE.get().map(|rtc| { - let rtc_device = Arc::new(RTCDevice::new(alloc_device_id(VfsNodeType::CharDevice), rtc.clone())); + let rtc_device = Arc::new(RTCDevice::new( + alloc_device_id(VfsNodeType::CharDevice), + rtc.clone(), + )); root.create( "rtc", VfsNodeType::BlockDevice, @@ -249,7 +258,10 @@ fn scan_system_devices(root: Arc) { register_device(rtc_device); }); UART_DEVICE.get().map(|uart| { - let uart_device = Arc::new(UARTDevice::new(alloc_device_id(VfsNodeType::CharDevice), uart.clone())); + let uart_device = Arc::new(UARTDevice::new( + alloc_device_id(VfsNodeType::CharDevice), + uart.clone(), + )); root.create( "tty", VfsNodeType::BlockDevice, diff --git a/kernel/src/fs/ext.rs b/kernel/src/fs/ext.rs index a3ba61e9..a1219ce8 100644 --- a/kernel/src/fs/ext.rs +++ b/kernel/src/fs/ext.rs @@ -1,9 +1,9 @@ +use constants::LinuxErrno; use core::cmp::min; -use pconst::LinuxErrno; use vfscore::path::VfsPath; -use crate::{config::AT_FDCWD, error::AlienResult, fs::user_path_at, task::current_task}; - +use crate::{config::AT_FDCWD, fs::user_path_at, task::current_task}; +use constants::AlienResult; /// 一个系统调用,用于设置文件的 扩展属性(xattrs, Extended Attributes)。 /// /// 扩展属性(xattrs)提供了一个机制用来将一个(键, 值)对永久地关联到文件,让现有的文件系统得以支持在原始设计中未提供的功能。扩展属性是文件系统不可知论者, diff --git a/kernel/src/fs/file.rs b/kernel/src/fs/file.rs index 340ac3e7..f6f01bbe 100644 --- a/kernel/src/fs/file.rs +++ b/kernel/src/fs/file.rs @@ -1,16 +1,16 @@ +use constants::io::DirentType; pub use kernel_file::{File, KernelFile}; -use pconst::io::DirentType; use vfscore::utils::VfsNodeType; mod kernel_file { use super::vfsnodetype2dirent64; - use crate::error::AlienResult; - use crate::ksync::Mutex; use alloc::sync::Arc; + use constants::io::{Dirent64, OpenFlags, PollEvents, SeekFrom}; + use constants::AlienResult; + use constants::LinuxErrno; use core::fmt::{Debug, Formatter}; use downcast_rs::{impl_downcast, DowncastSync}; - use pconst::io::{Dirent64, OpenFlags, PollEvents, SeekFrom}; - use pconst::LinuxErrno; + use ksync::Mutex; use vfscore::dentry::VfsDentry; use vfscore::error::VfsError; use vfscore::inode::VfsInode; @@ -117,7 +117,7 @@ mod kernel_file { return Ok(0); } let open_flag = self.open_flag.lock(); - if !open_flag.contains(OpenFlags::O_RDONLY)&& !open_flag.contains(OpenFlags::O_RDWR) { + if !open_flag.contains(OpenFlags::O_RDONLY) && !open_flag.contains(OpenFlags::O_RDWR) { return Err(LinuxErrno::EPERM); } drop(open_flag); @@ -151,7 +151,7 @@ mod kernel_file { fn fsync(&self) -> AlienResult<()> { let open_flag = self.open_flag.lock(); - if !open_flag.contains(OpenFlags::O_WRONLY)&& !open_flag.contains(OpenFlags::O_RDWR) { + if !open_flag.contains(OpenFlags::O_WRONLY) && !open_flag.contains(OpenFlags::O_RDWR) { return Err(LinuxErrno::EPERM); } let inode = self.dentry.inode()?; @@ -213,7 +213,7 @@ mod kernel_file { if count + dirent64.len() <= buf.len() { let dirent_ptr = unsafe { &mut *(ptr as *mut Dirent64) }; *dirent_ptr = dirent64; - let name_ptr = dirent_ptr.name.as_mut_ptr(); + let name_ptr = dirent_ptr.name.as_mut_ptr(); unsafe { let mut name = d.name.clone(); name.push('\0'); @@ -236,9 +236,7 @@ mod kernel_file { } fn truncate(&self, len: u64) -> AlienResult<()> { let open_flag = self.open_flag.lock(); - if !open_flag - .contains(OpenFlags::O_WRONLY) & !open_flag.contains(OpenFlags::O_RDWR) - { + if !open_flag.contains(OpenFlags::O_WRONLY) & !open_flag.contains(OpenFlags::O_RDWR) { return Err(LinuxErrno::EINVAL); } let dt = self.dentry(); diff --git a/kernel/src/fs/link.rs b/kernel/src/fs/link.rs index 882c72bc..0e71bb61 100644 --- a/kernel/src/fs/link.rs +++ b/kernel/src/fs/link.rs @@ -1,9 +1,9 @@ use alloc::vec; -use pconst::io::{LinkFlags, UnlinkatFlags}; +use constants::io::{LinkFlags, UnlinkatFlags}; use syscall_table::syscall_func; -use crate::{error::AlienResult, fs::user_path_at, task::current_task}; - +use crate::{fs::user_path_at, task::current_task}; +use constants::AlienResult; /// 一个系统调用,用于创建相对于一个目录某位置处的一个文件的(硬)链接。 /// /// 当传入的 `old_name` 是一个相对地址时,那么 `old_name` 会被解析成基于文件描述符 `old_fd` @@ -85,9 +85,9 @@ pub fn sys_unlinkat(fd: isize, path: *const u8, flag: usize) -> AlienResult String { let mut res = String::new(); let fs = FS.lock(); - for (_,fs) in fs.iter() { + for (_, fs) in fs.iter() { let flag = fs.fs_flag(); if !flag.contains(FileSystemFlags::REQUIRES_DEV) { res.push_str("nodev ") @@ -36,7 +36,7 @@ impl SystemSupportFS { impl VfsFile for SystemSupportFS { fn read_at(&self, offset: u64, buf: &mut [u8]) -> VfsResult { let info = self.serialize(); - let min_len = min(buf.len(), info.as_bytes().len()-offset as usize); + let min_len = min(buf.len(), info.as_bytes().len() - offset as usize); buf[..min_len].copy_from_slice(&info.as_bytes()[..min_len]); Ok(min_len) } diff --git a/kernel/src/fs/proc/interrupt.rs b/kernel/src/fs/proc/interrupt.rs index 5d5ce8dc..83332a7a 100644 --- a/kernel/src/fs/proc/interrupt.rs +++ b/kernel/src/fs/proc/interrupt.rs @@ -13,7 +13,7 @@ pub struct InterruptRecord; impl VfsFile for InterruptRecord { fn read_at(&self, offset: u64, buf: &mut [u8]) -> VfsResult { let info = interrupts_info(); - let min_len = min(buf.len(), info.as_bytes().len()-offset as usize); + let min_len = min(buf.len(), info.as_bytes().len() - offset as usize); buf[..min_len].copy_from_slice(&info.as_bytes()[..min_len]); Ok(min_len) } diff --git a/kernel/src/fs/proc/mem.rs b/kernel/src/fs/proc/mem.rs index c66539e4..4a777ee6 100644 --- a/kernel/src/fs/proc/mem.rs +++ b/kernel/src/fs/proc/mem.rs @@ -12,7 +12,7 @@ pub struct MemInfo; impl VfsFile for MemInfo { fn read_at(&self, offset: u64, buf: &mut [u8]) -> VfsResult { - let min_len = min(buf.len(), MEMINFO.as_bytes().len()-offset as usize); + let min_len = min(buf.len(), MEMINFO.as_bytes().len() - offset as usize); buf[..min_len].copy_from_slice(&MEMINFO.as_bytes()[..min_len]); Ok(min_len) } diff --git a/kernel/src/fs/proc/mod.rs b/kernel/src/fs/proc/mod.rs index b14c16a9..55b83f28 100644 --- a/kernel/src/fs/proc/mod.rs +++ b/kernel/src/fs/proc/mod.rs @@ -7,10 +7,10 @@ mod process; use crate::fs::proc::filesystem::SystemSupportFS; use crate::fs::proc::interrupt::InterruptRecord; use crate::fs::proc::mounts::MountInfo; -use crate::fs::{CommonFsProviderImpl}; -use crate::ksync::Mutex; +use crate::fs::CommonFsProviderImpl; use alloc::sync::Arc; use dynfs::DynFsDirInode; +use ksync::Mutex; use mem::MemInfo; use vfscore::dentry::VfsDentry; use vfscore::error::VfsError; diff --git a/kernel/src/fs/proc/mounts.rs b/kernel/src/fs/proc/mounts.rs index a266101e..ac0d76fe 100644 --- a/kernel/src/fs/proc/mounts.rs +++ b/kernel/src/fs/proc/mounts.rs @@ -1,47 +1,47 @@ -use alloc::sync::Arc; -use core::cmp::min; -use vfscore::error::VfsError; -use vfscore::file::VfsFile; -use vfscore::inode::{InodeAttr, VfsInode}; -use vfscore::superblock::VfsSuperBlock; -use vfscore::utils::{VfsFileStat, VfsNodePerm, VfsNodeType}; -use vfscore::VfsResult; - -// todo!(dynamic mount info) -const MOUNT_INFO: &str = r" - rootfs / rootfs rw 0 0 - devfs /dev devfs rw 0 0 - fat32 / fat rw 0 0 -"; -pub struct MountInfo; - -impl VfsFile for MountInfo { - fn read_at(&self, offset: u64, buf: &mut [u8]) -> VfsResult { - let min_len = min(buf.len(), MOUNT_INFO.as_bytes().len()-offset as usize); - buf[..min_len].copy_from_slice(&MOUNT_INFO.as_bytes()[..min_len]); - Ok(min_len) - } -} - -impl VfsInode for MountInfo { - fn get_super_block(&self) -> VfsResult> { - Err(VfsError::NoSys) - } - fn node_perm(&self) -> VfsNodePerm { - VfsNodePerm::empty() - } - fn set_attr(&self, _attr: InodeAttr) -> VfsResult<()> { - Ok(()) - } - - fn get_attr(&self) -> VfsResult { - Ok(VfsFileStat { - st_size: MOUNT_INFO.as_bytes().len() as u64, - ..Default::default() - }) - } - - fn inode_type(&self) -> VfsNodeType { - VfsNodeType::File - } -} +use alloc::sync::Arc; +use core::cmp::min; +use vfscore::error::VfsError; +use vfscore::file::VfsFile; +use vfscore::inode::{InodeAttr, VfsInode}; +use vfscore::superblock::VfsSuperBlock; +use vfscore::utils::{VfsFileStat, VfsNodePerm, VfsNodeType}; +use vfscore::VfsResult; + +// todo!(dynamic mount info) +const MOUNT_INFO: &str = r" + rootfs / rootfs rw 0 0 + devfs /dev devfs rw 0 0 + fat32 / fat rw 0 0 +"; +pub struct MountInfo; + +impl VfsFile for MountInfo { + fn read_at(&self, offset: u64, buf: &mut [u8]) -> VfsResult { + let min_len = min(buf.len(), MOUNT_INFO.as_bytes().len() - offset as usize); + buf[..min_len].copy_from_slice(&MOUNT_INFO.as_bytes()[..min_len]); + Ok(min_len) + } +} + +impl VfsInode for MountInfo { + fn get_super_block(&self) -> VfsResult> { + Err(VfsError::NoSys) + } + fn node_perm(&self) -> VfsNodePerm { + VfsNodePerm::empty() + } + fn set_attr(&self, _attr: InodeAttr) -> VfsResult<()> { + Ok(()) + } + + fn get_attr(&self) -> VfsResult { + Ok(VfsFileStat { + st_size: MOUNT_INFO.as_bytes().len() as u64, + ..Default::default() + }) + } + + fn inode_type(&self) -> VfsNodeType { + VfsNodeType::File + } +} diff --git a/kernel/src/fs/proc/process.rs b/kernel/src/fs/proc/process.rs index 43e2033c..36259558 100644 --- a/kernel/src/fs/proc/process.rs +++ b/kernel/src/fs/proc/process.rs @@ -1,8 +1,8 @@ -use crate::error::AlienResult; use crate::task::current_task; use crate::timer::TimeFromFreq; -use pconst::sys::{Rusage, RusageFlag, TimeVal}; -use pconst::LinuxErrno; +use constants::sys::{Rusage, RusageFlag, TimeVal}; +use constants::AlienResult; +use constants::LinuxErrno; /// (待完善)一个系统调用,用于获取对系统资源的使用量信息。获取的信息将保存到`usage`所指向的[`Rusage`]结构中。 /// diff --git a/kernel/src/fs/ram/mod.rs b/kernel/src/fs/ram/mod.rs index b466db95..b1b71834 100644 --- a/kernel/src/fs/ram/mod.rs +++ b/kernel/src/fs/ram/mod.rs @@ -73,7 +73,8 @@ pub fn init_ramfs(ramfs: Arc) -> Arc { .create("tmp", VfsNodeType::Dir, "rwxrwxrwx".into(), None) .unwrap(); - let _bashrc = root.create(".bashrc", VfsNodeType::File, "rwxrwxrwx".into(), None) + let _bashrc = root + .create(".bashrc", VfsNodeType::File, "rwxrwxrwx".into(), None) .unwrap(); println!("ramfs init success"); diff --git a/kernel/src/fs/select.rs b/kernel/src/fs/select.rs index 4aff56a5..bd30ee51 100644 --- a/kernel/src/fs/select.rs +++ b/kernel/src/fs/select.rs @@ -1,13 +1,13 @@ use crate::config::MAX_FD_NUM; -use crate::error::AlienResult; use crate::task::{current_task, do_suspend}; use crate::timer::TimeSpec; use alloc::vec::Vec; use bit_field::BitField; +use constants::io::PollEvents; +use constants::signal::{SignalNumber, SimpleBitSet}; +use constants::AlienResult; +use constants::LinuxErrno; use core::cmp::min; -use pconst::io::PollEvents; -use pconst::signal::{SignalNumber, SimpleBitSet}; -use pconst::LinuxErrno; use syscall_table::syscall_func; /// 一个系统调用,实现 IO 端口的复用。一般用于用户程序的一段循环体中, diff --git a/kernel/src/fs/stdio.rs b/kernel/src/fs/stdio.rs index aa2a7ce0..4e90fc3a 100644 --- a/kernel/src/fs/stdio.rs +++ b/kernel/src/fs/stdio.rs @@ -1,7 +1,7 @@ use crate::fs::file::KernelFile; use crate::fs::SYSTEM_ROOT_FS; use alloc::sync::Arc; -use pconst::io::OpenFlags; +use constants::io::OpenFlags; use spin::Lazy; use vfscore::path::VfsPath; diff --git a/kernel/src/fs/sys/info.rs b/kernel/src/fs/sys/info.rs index 40acfcec..277b80a9 100644 --- a/kernel/src/fs/sys/info.rs +++ b/kernel/src/fs/sys/info.rs @@ -1,87 +1,87 @@ -use crate::task::current_task; -use crate::timer::get_time_ms; -use crate::MACHINE_INFO; -use core::cmp::min; -use pconst::sys::{Sysinfo, SyslogAction}; -use pconst::LinuxErrno; - -const LOG_BUF_LEN: usize = 4096; -const LOG: &str = r" -[ 0.000000] Linux version 5.10.0-7-riscv64 (debian-kernel@lists.debian.org) (gcc-10 (Debian 10.2.1-6) 10.2.1 20210110, GNU ld (GNU Binutils for Debian) 2.35.2) #1 SMP Debian 5.10.40-1 (2021-05-28) -"; - -/// (待完善)一个系统调用函数,用于对内核消息环状缓冲区进行操作。 -/// -/// + `log_type`: 指明操作的类型,具体值可见[`SyslogAction`]; -/// + `buf`: 指明读取消息时,消息要保存到的位置; -/// + `len`: 指明具体操作时,对于消息读取的长度限制。真正的读取消息的长度将取决于就传入的`len`和`LOG_BUF_LEN`的最小值。 -/// -/// 当`log_type`为`READ`、`ReadAll`、`ReadClear`三种flag,正确执行后返回读取消息的长度; -/// 当`log_type`为`Unknown`时,会返回`EINVAL`;当`log_type`为`OPEN`或`CLOSE`时,函数不进行任何操作后返回0。 -/// 目前Alien仅支持上述`log_type`值,其余值都将不进行任何操作后返回0。 -/// -/// Reference: [syslog](https://man7.org/linux/man-pages/man2/syslog.2.html) -#[syscall_func(116)] -pub fn syslog(log_type: u32, buf: usize, len: usize) -> isize { - let log_type = SyslogAction::try_from(log_type); - if log_type.is_err() { - return LinuxErrno::EINVAL as isize; - } - match log_type.unwrap() { - SyslogAction::OPEN | SyslogAction::CLOSE => 0, - SyslogAction::READ | SyslogAction::ReadAll | SyslogAction::ReadClear => { - let min_len = min(len, LOG_BUF_LEN); - let task = current_task().unwrap(); - // the buf may be not valid, so we need to check it -- > sbrk heap - let mut buf = task.transfer_buffer(buf as *mut u8, min_len); - let log = LOG.as_bytes(); - let mut offset = 0; - buf.iter_mut().for_each(|buf| { - let copy_len = min(log.len() - offset, buf.len()); - buf[..copy_len].copy_from_slice(&log[offset..offset + copy_len]); - offset += copy_len; - }); - offset as isize - } - SyslogAction::Unknown => LinuxErrno::EINVAL as isize, - _ => 0, - } -} - -extern "C" { - fn ekernel(); -} - -/// 一个系统调用函数,用于获取系统相关信息。信息包括系统的自启动经过的时间、对于内存的使用情况、共享存储区的大小、 -/// 缓冲区与交换区的大小、当前进程数目等,具体可见[`Sysinfo`]。获取到的信息将保存到`dst_info`所指向的[`Sysinfo`]结构处。 -/// -/// 目前功能还有待完善。正确执行后返回0。 -#[syscall_func(179)] -pub fn sys_info(dst_info: usize) -> isize { - const LINUX_SYSINFO_LOADS_SCALE: usize = 65536; - let task = current_task().unwrap(); - // calculate the task number - let task_number = 10; // fake task number - let memory_info = MACHINE_INFO.get().as_ref().unwrap().memory.clone(); - let info = Sysinfo { - uptime: (get_time_ms() / 1000) as usize, - loads: [ - task_number * LINUX_SYSINFO_LOADS_SCALE / 60, - task_number * LINUX_SYSINFO_LOADS_SCALE / 300, - task_number * LINUX_SYSINFO_LOADS_SCALE / 900, - ], - totalram: memory_info.end - memory_info.start, - freeram: memory_info.end - ekernel as usize, - sharedram: 0, - bufferram: 0, - totalswap: 0, - freeswap: 0, - procs: task_number as u16, - totalhigh: 0, - freehigh: 0, - mem_unit: 1, - }; - task.access_inner() - .copy_to_user(&info, dst_info as *mut Sysinfo); - 0 -} +use crate::task::current_task; +use crate::timer::get_time_ms; +use crate::MACHINE_INFO; +use constants::sys::{Sysinfo, SyslogAction}; +use constants::LinuxErrno; +use core::cmp::min; + +const LOG_BUF_LEN: usize = 4096; +const LOG: &str = r" +[ 0.000000] Linux version 5.10.0-7-riscv64 (debian-kernel@lists.debian.org) (gcc-10 (Debian 10.2.1-6) 10.2.1 20210110, GNU ld (GNU Binutils for Debian) 2.35.2) #1 SMP Debian 5.10.40-1 (2021-05-28) +"; + +/// (待完善)一个系统调用函数,用于对内核消息环状缓冲区进行操作。 +/// +/// + `log_type`: 指明操作的类型,具体值可见[`SyslogAction`]; +/// + `buf`: 指明读取消息时,消息要保存到的位置; +/// + `len`: 指明具体操作时,对于消息读取的长度限制。真正的读取消息的长度将取决于就传入的`len`和`LOG_BUF_LEN`的最小值。 +/// +/// 当`log_type`为`READ`、`ReadAll`、`ReadClear`三种flag,正确执行后返回读取消息的长度; +/// 当`log_type`为`Unknown`时,会返回`EINVAL`;当`log_type`为`OPEN`或`CLOSE`时,函数不进行任何操作后返回0。 +/// 目前Alien仅支持上述`log_type`值,其余值都将不进行任何操作后返回0。 +/// +/// Reference: [syslog](https://man7.org/linux/man-pages/man2/syslog.2.html) +#[syscall_func(116)] +pub fn syslog(log_type: u32, buf: usize, len: usize) -> isize { + let log_type = SyslogAction::try_from(log_type); + if log_type.is_err() { + return LinuxErrno::EINVAL as isize; + } + match log_type.unwrap() { + SyslogAction::OPEN | SyslogAction::CLOSE => 0, + SyslogAction::READ | SyslogAction::ReadAll | SyslogAction::ReadClear => { + let min_len = min(len, LOG_BUF_LEN); + let task = current_task().unwrap(); + // the buf may be not valid, so we need to check it -- > sbrk heap + let mut buf = task.transfer_buffer(buf as *mut u8, min_len); + let log = LOG.as_bytes(); + let mut offset = 0; + buf.iter_mut().for_each(|buf| { + let copy_len = min(log.len() - offset, buf.len()); + buf[..copy_len].copy_from_slice(&log[offset..offset + copy_len]); + offset += copy_len; + }); + offset as isize + } + SyslogAction::Unknown => LinuxErrno::EINVAL as isize, + _ => 0, + } +} + +extern "C" { + fn ekernel(); +} + +/// 一个系统调用函数,用于获取系统相关信息。信息包括系统的自启动经过的时间、对于内存的使用情况、共享存储区的大小、 +/// 缓冲区与交换区的大小、当前进程数目等,具体可见[`Sysinfo`]。获取到的信息将保存到`dst_info`所指向的[`Sysinfo`]结构处。 +/// +/// 目前功能还有待完善。正确执行后返回0。 +#[syscall_func(179)] +pub fn sys_info(dst_info: usize) -> isize { + const LINUX_SYSINFO_LOADS_SCALE: usize = 65536; + let task = current_task().unwrap(); + // calculate the task number + let task_number = 10; // fake task number + let memory_info = MACHINE_INFO.get().as_ref().unwrap().memory.clone(); + let info = Sysinfo { + uptime: (get_time_ms() / 1000) as usize, + loads: [ + task_number * LINUX_SYSINFO_LOADS_SCALE / 60, + task_number * LINUX_SYSINFO_LOADS_SCALE / 300, + task_number * LINUX_SYSINFO_LOADS_SCALE / 900, + ], + totalram: memory_info.end - memory_info.start, + freeram: memory_info.end - ekernel as usize, + sharedram: 0, + bufferram: 0, + totalswap: 0, + freeswap: 0, + procs: task_number as u16, + totalhigh: 0, + freehigh: 0, + mem_unit: 1, + }; + task.access_inner() + .copy_to_user(&info, dst_info as *mut Sysinfo); + 0 +} diff --git a/kernel/src/fs/sys/mod.rs b/kernel/src/fs/sys/mod.rs index de12de20..5cd608a1 100644 --- a/kernel/src/fs/sys/mod.rs +++ b/kernel/src/fs/sys/mod.rs @@ -1,7 +1,7 @@ use crate::fs::CommonFsProviderImpl; -use crate::ksync::Mutex; use alloc::sync::Arc; use dynfs::DynFsDirInode; +use ksync::Mutex; use vfscore::dentry::VfsDentry; use vfscore::fstype::VfsFsType; diff --git a/kernel/src/interrupt/ext_interrupt.rs b/kernel/src/interrupt/ext_interrupt.rs index 7433e486..7e0d06ef 100644 --- a/kernel/src/interrupt/ext_interrupt.rs +++ b/kernel/src/interrupt/ext_interrupt.rs @@ -1,7 +1,7 @@ use plic::Mode; -use crate::arch::hart_id; use crate::interrupt::{DEVICE_TABLE, PLIC}; +use arch::hart_id; pub fn external_interrupt_handler() { let plic = PLIC.get().unwrap(); diff --git a/kernel/src/interrupt/mod.rs b/kernel/src/interrupt/mod.rs index e5f58411..93e1240c 100644 --- a/kernel/src/interrupt/mod.rs +++ b/kernel/src/interrupt/mod.rs @@ -3,13 +3,13 @@ use alloc::sync::Arc; use cfg_if::cfg_if; use spin::Once; -use crate::ksync::Mutex; pub use ext_interrupt::external_interrupt_handler; +use ksync::Mutex; use plic::{Mode, PLIC}; -use crate::arch::hart_id; use crate::config::CPU_NUM; use crate::MACHINE_INFO; +use arch::hart_id; mod ext_interrupt; pub mod record; diff --git a/kernel/src/interrupt/record.rs b/kernel/src/interrupt/record.rs index 4f2e89b2..5d576b92 100644 --- a/kernel/src/interrupt/record.rs +++ b/kernel/src/interrupt/record.rs @@ -1,8 +1,8 @@ use alloc::collections::BTreeMap; use alloc::format; use alloc::string::String; -use spin::{Lazy}; -use crate::ksync::Mutex; +use ksync::Mutex; +use spin::Lazy; /// Record the number of interrupts pub static INTERRUPT_RECORD: Lazy>> = Lazy::new(|| { diff --git a/kernel/src/ipc/futex.rs b/kernel/src/ipc/futex.rs index 095be7ac..184b2a34 100644 --- a/kernel/src/ipc/futex.rs +++ b/kernel/src/ipc/futex.rs @@ -18,12 +18,12 @@ use alloc::vec; use alloc::vec::Vec; use core::cmp::min; -use crate::ksync::Mutex; +use ksync::Mutex; use smpscheduler::FifoTask; -use crate::error::{AlienError, AlienResult}; use crate::task::{Task, GLOBAL_TASK_MANAGER}; use crate::timer::read_timer; +use constants::{AlienError, AlienResult}; /// 用于记录一个进程等待一个 futex 的相关信息 pub struct FutexWaiter { diff --git a/kernel/src/ipc/mod.rs b/kernel/src/ipc/mod.rs index 31b9409f..c4ac1946 100644 --- a/kernel/src/ipc/mod.rs +++ b/kernel/src/ipc/mod.rs @@ -9,10 +9,10 @@ use alloc::sync::Arc; use core::sync::atomic::{AtomicI32, Ordering}; use spin::Lazy; -use crate::error::AlienResult; -use crate::ksync::Mutex; -use pconst::ipc::{FutexOp, RobustList}; -use pconst::LinuxErrno; +use constants::ipc::{FutexOp, RobustList}; +use constants::AlienResult; +use constants::LinuxErrno; +use ksync::Mutex; pub use pipe::*; pub use shm::*; pub use signal::*; diff --git a/kernel/src/ipc/pipe.rs b/kernel/src/ipc/pipe.rs index 54db94f8..75784b1a 100644 --- a/kernel/src/ipc/pipe.rs +++ b/kernel/src/ipc/pipe.rs @@ -11,19 +11,19 @@ //! 符表中。 use crate::config::PIPE_BUF; -use crate::error::AlienResult; use crate::fs::file::File; use crate::fs::CommonFsProviderImpl; -use crate::ksync::Mutex; use crate::task::{current_task, do_suspend}; use alloc::string::{String, ToString}; use alloc::sync::{Arc, Weak}; use alloc::vec::Vec; +use constants::io::{MountFlags, OpenFlags, PollEvents, SeekFrom}; +use constants::AlienResult; +use constants::LinuxErrno; use core::fmt::{Debug, Formatter}; use core::sync::atomic::AtomicUsize; use dynfs::DynFsDirInode; -use pconst::io::{MountFlags, OpenFlags, PollEvents, SeekFrom}; -use pconst::LinuxErrno; +use ksync::Mutex; use spin::Once; use vfscore::dentry::VfsDentry; use vfscore::error::VfsError; @@ -105,13 +105,13 @@ pub fn make_pipe_file() -> VfsResult<(Arc, Arc)> { impl File for PipeFile { fn read(&self, buf: &mut [u8]) -> AlienResult { if buf.len() == 0 { - return Ok(0) + return Ok(0); } self.dentry.inode()?.read_at(0, buf).map_err(|e| e.into()) } fn write(&self, buf: &[u8]) -> AlienResult { if buf.len() == 0 { - return Ok(0) + return Ok(0); } self.dentry.inode()?.write_at(0, buf).map_err(|e| e.into()) } diff --git a/kernel/src/ipc/shm.rs b/kernel/src/ipc/shm.rs index 319a067c..3baca29c 100644 --- a/kernel/src/ipc/shm.rs +++ b/kernel/src/ipc/shm.rs @@ -11,9 +11,9 @@ use alloc::vec::Vec; use page_table::addr::{align_down_4k, PhysAddr, VirtAddr}; use page_table::table::PageSize; -use crate::ksync::{Mutex, MutexGuard}; -use pconst::ipc::{ShmAtFlags, ShmCtlCmd, ShmGetFlags, IPC_PRIVATE}; -use pconst::LinuxErrno; +use constants::ipc::{ShmAtFlags, ShmCtlCmd, ShmGetFlags, IPC_PRIVATE}; +use constants::LinuxErrno; +use ksync::{Mutex, MutexGuard}; use syscall_table::syscall_func; use crate::config::FRAME_SIZE; diff --git a/kernel/src/ipc/signal.rs b/kernel/src/ipc/signal.rs index 6478d87d..6769a6e7 100644 --- a/kernel/src/ipc/signal.rs +++ b/kernel/src/ipc/signal.rs @@ -7,12 +7,12 @@ use alloc::sync::Arc; use alloc::vec::Vec; use core::mem::size_of; -use crate::ksync::Mutex; -use pconst::signal::{ +use constants::signal::{ SigAction, SigActionDefault, SigActionFlags, SigInfo, SigProcMaskHow, SignalNumber, SignalReceivers, SignalUserContext, SimpleBitSet, }; -use pconst::LinuxErrno; +use constants::LinuxErrno; +use ksync::Mutex; use syscall_table::syscall_func; use crate::task::{current_task, do_exit, do_suspend}; diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index 116435c1..523a8f7b 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -13,24 +13,20 @@ extern crate alloc; #[macro_use] extern crate log; - use spin::Once; use basemachine::MachineInfo; #[macro_use] pub mod print; -pub mod arch; pub mod board; pub mod config; pub mod device; pub mod driver; -pub mod error; pub mod fs; pub mod gui; pub mod interrupt; pub mod ipc; -pub mod ksync; pub mod memory; pub mod net; pub mod panic; @@ -55,11 +51,3 @@ pub static MACHINE_INFO: Once = Once::new(); pub fn init_machine_info(machine_info: MachineInfo) { MACHINE_INFO.call_once(|| machine_info); } - -/// 允许内核读写用户态内存。 -/// 取决于 CPU 的 RISC-V 规范版本就行处理 -pub fn thread_local_init() { - unsafe { - riscv::register::sstatus::set_sum(); - } -} diff --git a/kernel/src/memory/elf.rs b/kernel/src/memory/elf.rs index eb430b00..0f14e224 100644 --- a/kernel/src/memory/elf.rs +++ b/kernel/src/memory/elf.rs @@ -133,3 +133,18 @@ impl ELFReader for ElfFile<'_> { Ok(res) } } +// /* RISC-V relocations. */ +// #define R_RISCV_NONE 0 +// #define R_RISCV_32 1 +// #define R_RISCV_64 2 +// #define R_RISCV_RELATIVE 3 +// #define R_RISCV_COPY 4 +// #define R_RISCV_JUMP_SLOT 5 +// #define R_RISCV_TLS_DTPMOD32 6 +// #define R_RISCV_TLS_DTPMOD64 7 +// #define R_RISCV_TLS_DTPREL32 8 +// #define R_RISCV_TLS_DTPREL64 9 +// #define R_RISCV_TLS_TPREL32 10 +// #define R_RISCV_TLS_TPREL64 11 +// #define R_RISCV_BRANCH 16 +// #define R_RISCV_JAL 17 diff --git a/kernel/src/memory/frame.rs b/kernel/src/memory/frame.rs index f4b180c2..aad1d187 100644 --- a/kernel/src/memory/frame.rs +++ b/kernel/src/memory/frame.rs @@ -1,9 +1,9 @@ use super::manager::FrameRefManager; use crate::config::{FRAME_BITS, FRAME_SIZE}; -use crate::ksync::Mutex; use alloc::format; use alloc::vec::Vec; use core::ops::{Deref, DerefMut}; +use ksync::Mutex; use pager::{PageAllocator, PageAllocatorExt}; use spin::Lazy; diff --git a/kernel/src/memory/map.rs b/kernel/src/memory/map.rs index 05197109..11fa4d1a 100644 --- a/kernel/src/memory/map.rs +++ b/kernel/src/memory/map.rs @@ -6,14 +6,14 @@ use bitflags::bitflags; use page_table::addr::{align_up_4k, VirtAddr}; use page_table::pte::MappingFlags; -use pconst::io::MapFlags; -use pconst::LinuxErrno; +use constants::io::MapFlags; +use constants::LinuxErrno; use syscall_table::syscall_func; use crate::config::{FRAME_SIZE, PROCESS_HEAP_MAX}; -use crate::error::AlienResult; use crate::fs::file::File; use crate::task::current_task; +use constants::AlienResult; bitflags! { pub struct ProtFlags: u32 { @@ -183,7 +183,14 @@ pub fn do_munmap(start: usize, len: usize) -> isize { /// 函数成功执行后将返回所创建的内存映射区的首地址;否则返回错误类型。 /// Reference: [do_mmap](https://man7.org/linux/man-pages/man2/mmap.2.html) #[syscall_func(222)] -pub fn do_mmap(start: usize, len: usize, prot: u32, flags: u32, fd: usize, offset: usize) -> AlienResult { +pub fn do_mmap( + start: usize, + len: usize, + prot: u32, + flags: u32, + fd: usize, + offset: usize, +) -> AlienResult { let process = current_task().unwrap(); let mut process_inner = process.access_inner(); let prot = ProtFlags::from_bits_truncate(prot); @@ -192,7 +199,9 @@ pub fn do_mmap(start: usize, len: usize, prot: u32, flags: u32, fd: usize, offse "mmap: start: {:#x}, len: {:#x}, prot: {:?}, flags: {:?}, fd: {}, offset: {:#x}", start, len, prot, flags, fd, offset ); - process_inner.add_mmap(start, len, prot, flags, fd, offset).map(|addr| addr as isize) + process_inner + .add_mmap(start, len, prot, flags, fd, offset) + .map(|addr| addr as isize) } /// 一个系统调用,用于修改内存映射的保护位,从而修改对内存映射的访问权限。 diff --git a/kernel/src/memory/mod.rs b/kernel/src/memory/mod.rs index 13240c92..5da7e00d 100644 --- a/kernel/src/memory/mod.rs +++ b/kernel/src/memory/mod.rs @@ -3,21 +3,19 @@ use core::alloc::GlobalAlloc; #[cfg(feature = "buddy")] use buddy_system_allocator::LockedHeap; use cfg_if::cfg_if; -use riscv::asm::sfence_vma_all; -use riscv::register::satp; #[cfg(feature = "talloc")] use talc::{Talc, Talck}; -use crate::ksync::Mutex; pub use frame::*; +use ksync::Mutex; pub use map::*; use syscall_table::syscall_func; pub use vmm::*; -use crate::arch::hart_id; use crate::config::FRAME_SIZE; #[cfg(any(feature = "talloc", feature = "buddy"))] use crate::config::KERNEL_HEAP_SIZE; +use arch::{activate_paging_mode, hart_id}; mod elf; mod frame; @@ -49,24 +47,10 @@ pub fn init_memory_system(memory_end: usize, is_first_cpu: bool) { } build_kernel_address_space(memory_end); println!("build kernel address space success"); - activate_paging_mode(); + activate_paging_mode(kernel_space_root_ppn()); println!("activate paging mode success"); } else { - activate_paging_mode(); - } -} - -/// 激活页表模式 -pub fn activate_paging_mode() { - // let ppn = KERNEL_SPACE.read().root_ppn().unwrap().0; - unsafe { - sfence_vma_all(); - satp::set( - satp::Mode::Sv39, - 0, - KERNEL_SPACE.read().root_paddr().as_usize() >> 12, - ); - sfence_vma_all(); + activate_paging_mode(kernel_space_root_ppn()); } } diff --git a/kernel/src/memory/vmm.rs b/kernel/src/memory/vmm.rs index bb4c9b2b..2f2d2a01 100644 --- a/kernel/src/memory/vmm.rs +++ b/kernel/src/memory/vmm.rs @@ -1,7 +1,6 @@ use crate::config::*; use crate::fs; use crate::ipc::ShmInfo; -use crate::ksync::RwLock; use crate::memory::elf::{ELFError, ELFInfo, ELFReader}; use crate::memory::frame::{addr_to_frame, frame_alloc}; use crate::memory::{frame_alloc_contiguous, FRAME_REF_MANAGER}; @@ -14,6 +13,7 @@ use alloc::vec::Vec; use core::cmp::min; use core::fmt::Debug; use core::mem::forget; +use ksync::RwLock; use page_table::addr::{align_up_4k, PhysAddr, VirtAddr}; use page_table::pte::MappingFlags; use page_table::table::{PagingIf, Sv39PageTable}; @@ -26,6 +26,10 @@ pub static KERNEL_SPACE: Lazy>>> = Lazy: )) }); +pub fn kernel_space_root_ppn() -> usize { + KERNEL_SPACE.read().root_paddr().as_usize() >> FRAME_BITS +} + #[allow(unused)] extern "C" { fn stext(); @@ -381,8 +385,6 @@ pub fn build_elf_address_space( .for_each(|ph| { let start_addr = ph.virtual_addr() as usize + bias; let end_addr = start_addr + ph.mem_size() as usize; - // 记录程序地址空间的最大地址 - break_addr = end_addr; let mut permission: MappingFlags = "UVAD".into(); let ph_flags = ph.flags(); if ph_flags.is_read() { @@ -396,6 +398,8 @@ pub fn build_elf_address_space( } let vaddr = VirtAddr::from(start_addr).align_down_4k(); let end_vaddr = VirtAddr::from(end_addr).align_up_4k(); + // 记录程序地址空间的最大地址 + break_addr = end_addr; let len = end_vaddr.as_usize() - vaddr.as_usize(); warn!( "load segment: {:#x} - {:#x} -> {:#x}-{:#x}, permission: {:?}", @@ -412,24 +416,30 @@ pub fn build_elf_address_space( .unwrap(); // copy data let mut page_offset = start_addr & (FRAME_SIZE - 1); + let mut count = 0; map_info .into_iter() - .for_each(|(vir, phy, page_size)| unsafe { - trace!("{:#x} {:#x} {:#x?}", vir, phy, page_size); + .for_each(|(_vir, phy, page_size)| unsafe { let size: usize = page_size.into(); let min = min(size - page_offset, data.len()); let dst = (phy.as_usize() + page_offset) as *mut u8; core::ptr::copy(data.as_ptr(), dst, min); data = &data[min..]; - page_offset = (page_offset + min) & (FRAME_SIZE - 1); + count += min; + page_offset = 0; }); + assert_eq!(count, ph.file_size() as usize); }); // 地址向上取整对齐4 - let ceil_addr = align_up_4k(break_addr+FRAME_SIZE); + let ceil_addr = align_up_4k(break_addr + FRAME_SIZE); // 留出一个用户栈的位置+隔离页 let top = ceil_addr + USER_STACK_SIZE + FRAME_SIZE; - warn!("user stack: {:#x} - {:#x}", top - USER_STACK_SIZE - FRAME_SIZE, top-FRAME_SIZE); + warn!( + "user stack: {:#x} - {:#x}", + top - USER_STACK_SIZE - FRAME_SIZE, + top - FRAME_SIZE + ); // map user stack address_space .map_region_no_target( @@ -442,7 +452,7 @@ pub fn build_elf_address_space( .unwrap(); // 初始化一个有效页 address_space - .validate(VirtAddr::from(top - FRAME_SIZE * 2 ), "RWUVAD".into()) + .validate(VirtAddr::from(top - FRAME_SIZE * 2), "RWUVAD".into()) .unwrap(); let heap_bottom = top; // align to 4k diff --git a/kernel/src/net/addr.rs b/kernel/src/net/addr.rs index cde85cbb..db9deb7e 100644 --- a/kernel/src/net/addr.rs +++ b/kernel/src/net/addr.rs @@ -15,10 +15,10 @@ use alloc::vec; use core::fmt::Debug; use core::net::{IpAddr, Ipv4Addr, SocketAddr}; -use crate::error::AlienResult; use crate::task::current_task; -use pconst::net::Domain; -use pconst::LinuxErrno; +use constants::net::Domain; +use constants::AlienResult; +use constants::LinuxErrno; /// 用于存储套接字通信地址的结构,分为本地路径地址和网络套接字地址。 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)] diff --git a/kernel/src/net/mod.rs b/kernel/src/net/mod.rs index a49f96a8..992d1a26 100644 --- a/kernel/src/net/mod.rs +++ b/kernel/src/net/mod.rs @@ -5,7 +5,6 @@ //! [`socket`] 子模块指明了Alien 内核中使用的套接字。 //! [`unix`] 子模块指明了有关 Unix 协议族下的套接字结构。(目前有关的功能有待支持) //! -use crate::error::AlienResult; use crate::fs::file::File; use crate::net::addr::{socket_addr_resolution, RawIpV4Addr}; use crate::net::socket::{SocketData, SocketFile, SocketFileExt}; @@ -13,9 +12,10 @@ use crate::task::{current_task, do_suspend}; use alloc::sync::Arc; use alloc::vec; use alloc::vec::Vec; -use pconst::io::OpenFlags; -use pconst::net::*; -use pconst::LinuxErrno; +use constants::io::OpenFlags; +use constants::net::*; +use constants::AlienResult; +use constants::LinuxErrno; use syscall_table::syscall_func; pub mod addr; diff --git a/kernel/src/net/port.rs b/kernel/src/net/port.rs index aeab125b..3183d585 100644 --- a/kernel/src/net/port.rs +++ b/kernel/src/net/port.rs @@ -1,7 +1,7 @@ //! 现为将网络异常类型 [`NetError`] 转为 系统异常类型 [`LinuxErrno`]的模块。原为定义端口全局变量和操作的模块。 -use crate::error::AlienError; -use pconst::LinuxErrno; +use constants::AlienError; +use constants::LinuxErrno; use netcore::common::NetError; /// 现为将网络异常类型 [`NetError`] 转为 系统异常类型 [`LinuxErrno`]。 diff --git a/kernel/src/net/socket.rs b/kernel/src/net/socket.rs index 74be92ce..5518bdd6 100644 --- a/kernel/src/net/socket.rs +++ b/kernel/src/net/socket.rs @@ -8,20 +8,20 @@ //! [`socket_ready_to_read`]、[`socket_ready_to_write`] 几个操作函数,即可快速的创建套接字文件,并将其放入进程的文件描述 //! 符表中,具体有关套接字文件的创建,可见 [`SocketData::new`] 的实现。 use super::ShutdownFlag; -use crate::error::AlienResult; use crate::fs::file::File; -use crate::ksync::{Mutex, MutexGuard}; use crate::net::addr::SocketAddrExt; use crate::net::port::neterror2alien; use crate::net::unix::UnixSocket; +use constants::AlienResult; +use ksync::{Mutex, MutexGuard}; // use crate::task::do_suspend; use alloc::boxed::Box; use alloc::sync::Arc; +use constants::io::{OpenFlags, PollEvents, SeekFrom}; +use constants::net::{Domain, SocketType}; +use constants::LinuxErrno; use core::fmt::{Debug, Formatter}; use core::net::SocketAddr; -use pconst::io::{OpenFlags, PollEvents, SeekFrom}; -use pconst::net::{Domain, SocketType}; -use pconst::LinuxErrno; use netcore::tcp::TcpSocket; use netcore::udp::UdpSocket; use vfscore::dentry::VfsDentry; @@ -69,8 +69,8 @@ impl SocketFileExt for SocketFile { impl File for SocketFile { fn read(&self, buf: &mut [u8]) -> AlienResult { - if buf.len()==0{ - return Ok(0) + if buf.len() == 0 { + return Ok(0); } netcore::poll_interfaces(); let socket = self.get_socketdata().unwrap(); @@ -83,8 +83,8 @@ impl File for SocketFile { } fn write(&self, buf: &[u8]) -> AlienResult { - if buf.len()==0{ - return Ok(0) + if buf.len() == 0 { + return Ok(0); } info!("socket_file_write: buf_len:{:?}", buf.len()); netcore::poll_interfaces(); diff --git a/kernel/src/net/unix.rs b/kernel/src/net/unix.rs index e1188c33..5ff469d9 100644 --- a/kernel/src/net/unix.rs +++ b/kernel/src/net/unix.rs @@ -1,10 +1,10 @@ //! 有关 Unix 协议族下的套接字结构。(目前有关的功能有待支持) use alloc::string::String; use alloc::sync::Arc; -use pconst::LinuxErrno; +use constants::LinuxErrno; use crate::fs::file::File; -use crate::ksync::Mutex; +use ksync::Mutex; /// Unix 协议族下的套接字结构 #[allow(unused)] diff --git a/kernel/src/panic.rs b/kernel/src/panic.rs index 3d6d2601..e2c2a26b 100644 --- a/kernel/src/panic.rs +++ b/kernel/src/panic.rs @@ -1,15 +1,15 @@ //! panic 处理 -use crate::sbi::{system_shutdown}; +use crate::sbi::system_shutdown; use crate::trace::find_symbol_with_addr; use core::panic::PanicInfo; use core::sync::atomic::AtomicBool; -use tracer::{Tracer, TracerProvider}; #[cfg(all(not(feature = "debug-eh-frame"), not(feature = "debug-frame-point")))] use tracer::CompilerTracer; -#[cfg(feature = "debug-frame-point")] -use tracer::FramePointTracer; #[cfg(feature = "debug-eh-frame")] use tracer::DwarfTracer; +#[cfg(feature = "debug-frame-point")] +use tracer::FramePointTracer; +use tracer::{Tracer, TracerProvider}; /// 递归标志 static RECURSION: AtomicBool = AtomicBool::new(false); @@ -45,7 +45,6 @@ impl TracerProvider for TracerProviderImpl { } } - #[cfg(feature = "debug-eh-frame")] extern "C" { fn kernel_eh_frame(); @@ -84,7 +83,7 @@ fn back_trace() { #[cfg(feature = "debug-frame-point")] let tracer = FramePointTracer::new(TracerProviderImpl); #[cfg(feature = "debug-eh-frame")] - let tracer = DwarfTracer::new(DwarfProviderImpl,TracerProviderImpl); + let tracer = DwarfTracer::new(DwarfProviderImpl, TracerProviderImpl); for x in tracer.trace() { println!("[{:#x}] (+{:0>4x}) {}", x.func_addr, x.bias, x.func_name); } diff --git a/kernel/src/print/console.rs b/kernel/src/print/console.rs index 1960beea..91272e0d 100644 --- a/kernel/src/print/console.rs +++ b/kernel/src/print/console.rs @@ -3,7 +3,7 @@ use core::sync::atomic::{AtomicBool, Ordering}; use preprint::Print; -use crate::ksync::Mutex; +use ksync::Mutex; use crate::device::UART_DEVICE; use crate::sbi::console_putchar; @@ -11,7 +11,7 @@ use crate::sbi::console_putchar; #[macro_export] macro_rules! print { ($($arg:tt)*) => { - let hard_id = $crate::arch::hart_id(); + let hard_id = arch::hart_id(); // [hart_id] xxx $crate::print::console::__print(format_args!("[{}] {}", hard_id, format_args!($($arg)*))) }; @@ -77,7 +77,7 @@ impl Write for Stdout { } struct MStdout; -impl Write for MStdout{ +impl Write for MStdout { fn write_str(&mut self, s: &str) -> Result { s.as_bytes().iter().for_each(|x| { console_putchar(*x); @@ -93,7 +93,7 @@ pub fn __mprint(args: Arguments) { #[macro_export] macro_rules! mprint { ($($arg:tt)*) => { - let hard_id = $crate::arch::hart_id(); + let hard_id = arch::hart_id(); // [hart_id] xxx $crate::print::console::__mprint(format_args!("[{}] {}", hard_id, format_args!($($arg)*))) }; @@ -107,7 +107,6 @@ macro_rules! mprintln { concat!($fmt, "\n"), $($arg)*)); } - /// 输出函数 /// 对参数进行输出 主要使用在输出相关的宏中 如println pub fn __print(args: Arguments) { diff --git a/kernel/src/task/cpu.rs b/kernel/src/task/cpu.rs index 8108e9ab..bd84d41a 100644 --- a/kernel/src/task/cpu.rs +++ b/kernel/src/task/cpu.rs @@ -2,20 +2,20 @@ use alloc::string::{String, ToString}; use alloc::sync::Arc; use alloc::vec::Vec; -use core::cell::{UnsafeCell}; +use core::cell::UnsafeCell; use smpscheduler::{FifoSmpScheduler, FifoTask, ScheduleHart}; use spin::Lazy; -use crate::error::{AlienError, AlienResult}; -use crate::ksync::Mutex; -use pconst::ipc::FutexOp; -use pconst::signal::SignalNumber; -use pconst::task::{CloneFlags, WaitOptions}; -use pconst::{PrLimit, PrLimitRes}; +use constants::ipc::FutexOp; +use constants::signal::SignalNumber; +use constants::task::{CloneFlags, WaitOptions}; +use constants::{AlienError, AlienResult}; +use constants::{PrLimit, PrLimitRes}; +use ksync::Mutex; use syscall_table::syscall_func; -use crate::arch::hart_id; use crate::config::CPU_NUM; +use crate::fs; use crate::ipc::{futex, global_logoff_signals}; use crate::sbi::system_shutdown; use crate::task::context::Context; @@ -23,7 +23,7 @@ use crate::task::schedule::schedule; use crate::task::task::{Task, TaskState}; use crate::task::INIT_PROCESS; use crate::trap::{check_task_timer_expired, TrapFrame}; -use crate::{arch, fs}; +use arch::hart_id; /// 记录当前 CPU 上正在执行的线程 和 线程上下文 #[derive(Debug, Clone)] diff --git a/kernel/src/task/mod.rs b/kernel/src/task/mod.rs index 77e5e576..37b2f6c7 100644 --- a/kernel/src/task/mod.rs +++ b/kernel/src/task/mod.rs @@ -30,7 +30,7 @@ pub static INIT_PROCESS: Lazy> = Lazy::new(|| { let mut data = Vec::new(); read_all("/bin/init", &mut data); // let data = INIT; - assert!(data.len()>0); + assert!(data.len() > 0); let task = Task::from_elf("/bin/init", data.as_slice()).unwrap(); Arc::new(task) }); diff --git a/kernel/src/task/schedule.rs b/kernel/src/task/schedule.rs index 0bc67b99..bead11fe 100644 --- a/kernel/src/task/schedule.rs +++ b/kernel/src/task/schedule.rs @@ -3,7 +3,7 @@ use alloc::sync::Arc; use core::arch::asm; use smpscheduler::FifoTask; -use pconst::signal::SignalNumber; +use constants::signal::SignalNumber; use crate::ipc::send_signal; use crate::task::context::switch; diff --git a/kernel/src/task/stack.rs b/kernel/src/task/stack.rs index 1ce8dee2..c5c8b676 100644 --- a/kernel/src/task/stack.rs +++ b/kernel/src/task/stack.rs @@ -1,7 +1,7 @@ //! 进程内核栈空间 use alloc::vec::Vec; -use crate::ksync::Mutex; +use ksync::Mutex; use crate::config::FRAME_BITS; use crate::memory::{frame_alloc_contiguous, FrameTracker}; diff --git a/kernel/src/task/task.rs b/kernel/src/task/task.rs index 3bb53a91..2c8d5473 100644 --- a/kernel/src/task/task.rs +++ b/kernel/src/task/task.rs @@ -4,11 +4,9 @@ //! 使用 `clone` 创建新的进程(线程)时,会根据 flag 指明父子进程之间资源共享的程度。 //! tid 是标识不同任务的唯一标识。 use crate::config::*; -use crate::error::{AlienError, AlienResult}; use crate::fs::file::File; use crate::fs::{STDIN, STDOUT, SYSTEM_ROOT_FS}; use crate::ipc::{global_register_signals, ShmInfo}; -use crate::ksync::{Mutex, MutexGuard}; use crate::memory::*; use crate::task::context::Context; use crate::task::heap::HeapInfo; @@ -21,20 +19,22 @@ use alloc::sync::{Arc, Weak}; use alloc::vec::Vec; use alloc::{format, vec}; use bit_field::BitField; +use constants::aux::*; +use constants::io::MapFlags; +use constants::ipc::RobustList; +use constants::signal::{SignalHandlers, SignalNumber, SignalReceivers, SignalUserContext}; +use constants::sys::TimeVal; +use constants::task::CloneFlags; +use constants::time::TimerType; +use constants::{AlienError, AlienResult}; +use constants::{LinuxErrno, PrLimit, PrLimitRes}; use core::fmt::{Debug, Formatter}; use core::ops::Range; use gmanager::MinimalManager; +use ksync::{Mutex, MutexGuard}; use page_table::addr::{align_down_4k, align_up_4k, VirtAddr}; use page_table::pte::MappingFlags; use page_table::table::Sv39PageTable; -use pconst::aux::*; -use pconst::io::MapFlags; -use pconst::ipc::RobustList; -use pconst::signal::{SignalHandlers, SignalNumber, SignalReceivers, SignalUserContext}; -use pconst::sys::TimeVal; -use pconst::task::CloneFlags; -use pconst::time::TimerType; -use pconst::{LinuxErrno, PrLimit, PrLimitRes}; use spin::Lazy; use vfscore::dentry::VfsDentry; @@ -1085,7 +1085,10 @@ impl TaskInner { let fd = if flags.contains(MapFlags::MAP_ANONYMOUS) { None } else { - let file = self.fd_table.lock().get(fd) + let file = self + .fd_table + .lock() + .get(fd) .map_err(|_| LinuxErrno::EBADF)? .ok_or(LinuxErrno::EBADF)?; // EBADF Some(file) @@ -1512,7 +1515,7 @@ impl Task { let argc_ptr = user_stack.push(0).unwrap(); let trap_frame = process.trap_frame(); - *trap_frame = TrapFrame::from_app_info( + *trap_frame = TrapFrame::init_for_task( elf_info.entry, argc_ptr, kernel_satp(), @@ -1850,7 +1853,7 @@ impl Task { .query(VirtAddr::from(TRAP_CONTEXT_BASE)) .unwrap(); let trap_frame = TrapFrame::from_raw_ptr(physical.as_usize() as *mut TrapFrame); - *trap_frame = TrapFrame::from_app_info( + *trap_frame = TrapFrame::init_for_task( elf_info.entry, user_sp, kernel_satp(), diff --git a/kernel/src/timer/mod.rs b/kernel/src/timer/mod.rs index 0c5b05da..1e2fcdc6 100644 --- a/kernel/src/timer/mod.rs +++ b/kernel/src/timer/mod.rs @@ -14,19 +14,17 @@ use alloc::collections::BinaryHeap; use alloc::sync::Arc; use core::cmp::Ordering; -use crate::ksync::Mutex; -use pconst::sys::TimeVal; -use pconst::time::{ClockId, TimerType}; -use pconst::LinuxErrno; +use crate::config::CLOCK_FREQ; +use crate::task::{current_task, do_suspend, StatisticalData, Task, GLOBAL_TASK_MANAGER}; +use constants::sys::TimeVal; +use constants::time::{ClockId, TimerType}; +use constants::LinuxErrno; +use ksync::Mutex; use smpscheduler::FifoTask; use spin::Lazy; use syscall_table::syscall_func; use vfscore::utils::VfsTimeSpec; -use crate::arch; -use crate::config::CLOCK_FREQ; -use crate::task::{current_task, do_suspend, StatisticalData, Task, GLOBAL_TASK_MANAGER}; - /// 每秒包含的 时间片 数,每隔一个时间片,就会产生一个时钟中断 const TICKS_PER_SEC: usize = 10; // const TICKS_PER_SEC_IN_KERNEL: usize = 1000; @@ -376,7 +374,7 @@ pub fn getitimer(_which: usize, current_value: usize) -> isize { pub fn setitimer(which: usize, current_value: usize, old_value: usize) -> isize { let which = TimerType::try_from(which).unwrap(); assert_ne!(which, TimerType::NONE); - warn!( + info!( "setitimer: which {:?} ,curret_value {:#x}, old_value {:#x}", which, current_value, old_value ); @@ -394,7 +392,7 @@ pub fn setitimer(which: usize, current_value: usize, old_value: usize) -> isize let mut itimer = ITimerVal::default(); task.access_inner() .copy_from_user(current_value as *const ITimerVal, &mut itimer); - error!("setitimer: itimer {:x?}", itimer); + info!("setitimer: itimer {:x?}", itimer); task.access_inner().set_timer(itimer, which); 0 } @@ -406,7 +404,7 @@ pub fn setitimer(which: usize, current_value: usize, old_value: usize) -> isize #[syscall_func(114)] pub fn clock_getres(id: usize, res: usize) -> isize { let id = ClockId::from_raw(id).unwrap(); - warn!("clock_getres: id {:?} ,res {:#x}", id, res); + info!("clock_getres: id {:?} ,res {:#x}", id, res); let task = current_task().unwrap(); let time_res = match id { ClockId::Monotonic => { @@ -434,7 +432,7 @@ pub fn clock_getres(id: usize, res: usize) -> isize { pub fn clock_nanosleep(clock_id: usize, flags: usize, req: usize, remain: usize) -> isize { const TIMER_ABSTIME: usize = 1; let id = ClockId::from_raw(clock_id).unwrap(); - warn!( + info!( "clock_nanosleep: id {:?} ,flags {:#x}, req {:#x}, remain {:#x}", id, flags, req, remain ); diff --git a/kernel/src/trap/context.rs b/kernel/src/trap/context.rs index b56b2089..b8534fb2 100644 --- a/kernel/src/trap/context.rs +++ b/kernel/src/trap/context.rs @@ -1,7 +1,6 @@ //! Trap 上下文 (Trap帧) 的定义和相关操作 -use bit_field::BitField; - -use crate::arch::riscv::sstatus::{self, Sstatus, SPP}; +use arch::ExtSstatus; +use riscv::register::sstatus::SPP; #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -19,7 +18,7 @@ pub struct TrapFrame { /// 记录所在的核 hart_id: usize, /// 给出 Trap 发生之前 CPU 处在哪个特权级等信息 - sstatus: Sstatus, + sstatus: ExtSstatus, fg: [usize; 2], } @@ -32,13 +31,13 @@ impl TrapFrame { k_sp: 0, trap_handler: 0, hart_id: 0, - sstatus: Sstatus::default(), + sstatus: ExtSstatus::default(), fg: [0; 2], } } /// 获取当前的 Trap 帧下的 sstatus 寄存器的值 - pub fn get_status(&self) -> Sstatus { + pub fn get_status(&self) -> ExtSstatus { self.sstatus } @@ -47,9 +46,8 @@ impl TrapFrame { self.sepc += 4; } - /// pub fn from_raw_ptr(ptr: *mut TrapFrame) -> &'static mut Self { - unsafe { &mut *(ptr as *mut Self) } + unsafe { &mut *(ptr) } } /// 更新 Trap 帧中的内核栈地址 @@ -68,16 +66,16 @@ impl TrapFrame { } /// 用一个从文件系统中读取到的相关app数据,初始化一个 Trap 帧,使通过其创建的进程在初次进入用户态时能正常运行 - pub fn from_app_info( + pub fn init_for_task( entry: usize, sp: usize, k_satp: usize, k_sp: usize, trap_handler: usize, ) -> Self { - let mut sstatus = sstatus::read(); + let mut sstatus = ExtSstatus::read(); sstatus.set_spie(); - assert!(sstatus.0.get_bit(5)); //spie == 1 + // assert!(sstatus.0.get_bit(5)); //spie == 1 sstatus.set_spp(SPP::User); sstatus.set_sie(false); let mut res = Self { diff --git a/kernel/src/trap/exception.rs b/kernel/src/trap/exception.rs index 03d7448f..6f768f58 100644 --- a/kernel/src/trap/exception.rs +++ b/kernel/src/trap/exception.rs @@ -3,11 +3,11 @@ //! 目前包括系统调用异常处理 [`syscall_exception_handler`]、页错误异常处理 [`page_exception_handler`] (包括 //! 指令页错误异常处理 [`instruction_page_fault_exception_handler`]、 加载页错误异常处理[`load_page_fault_exception_handler`]、 //! 储存页错误异常处理 [`store_page_fault_exception_handler`]) 和 文件读入异常处理 [`trap_common_read_file`]。 -use crate::arch::{interrupt_enable}; -use crate::error::{AlienError, AlienResult}; use crate::fs::file::File; use crate::task::{current_task, current_trap_frame}; use alloc::sync::Arc; +use arch::interrupt_enable; +use constants::{AlienError, AlienResult}; use riscv::register::scause::{Exception, Trap}; /// 系统调用异常处理 @@ -19,7 +19,7 @@ pub fn syscall_exception_handler() { cx.update_sepc(); // get system call return value let parameters = cx.parameters(); - let syscall_name = pconst::syscall_name(parameters[0]); + let syscall_name = constants::syscall_name(parameters[0]); let p_name = current_task().unwrap().get_name(); let tid = current_task().unwrap().get_tid(); diff --git a/kernel/src/trap/mod.rs b/kernel/src/trap/mod.rs index a4c27151..ae42a8c4 100644 --- a/kernel/src/trap/mod.rs +++ b/kernel/src/trap/mod.rs @@ -3,30 +3,28 @@ use core::arch::{asm, global_asm}; use bit_field::BitField; use page_table::addr::VirtAddr; use riscv::register::sstatus::SPP; -use riscv::register::{sepc, sscratch, stval}; +use riscv::register::{sepc, sscratch, sstatus, stval, stvec}; +use constants::signal::SignalNumber; +use constants::signal::SIGNAL_RETURN_TRAP; +use constants::time::TimerType; pub use context::TrapFrame; pub use exception::trap_common_read_file; -use pconst::signal::SignalNumber; -use pconst::signal::SIGNAL_RETURN_TRAP; -use pconst::time::TimerType; -use crate::arch::riscv::register::scause::{Exception, Interrupt, Trap}; -use crate::arch::riscv::register::stvec; -use crate::arch::riscv::register::stvec::TrapMode; -use crate::arch::riscv::sstatus; -use crate::arch::{ - external_interrupt_enable, hart_id, interrupt_disable, interrupt_enable, is_interrupt_enable, - timer_interrupt_enable, -}; use crate::config::TRAMPOLINE; -use crate::error::AlienError; use crate::interrupt::external_interrupt_handler; use crate::interrupt::record::write_irq_info; use crate::ipc::{send_signal, signal_handler, signal_return, solve_futex_wait}; use crate::memory::KERNEL_SPACE; use crate::task::{current_task, current_trap_frame, current_user_token, do_exit, do_suspend}; use crate::timer::{check_timer_queue, set_next_trigger, set_next_trigger_in_kernel}; +use arch::{ + external_interrupt_enable, hart_id, interrupt_disable, interrupt_enable, is_interrupt_enable, + timer_interrupt_enable, +}; +use constants::AlienError; +use riscv::register::scause::{Exception, Interrupt, Trap}; +use riscv::register::stvec::TrapMode; mod context; mod exception; @@ -102,7 +100,7 @@ pub fn init_trap_subsystem() { pub trait TrapHandler { fn do_user_handle(&self); - fn do_kernel_handle(&self,sp:usize); + fn do_kernel_handle(&self, sp: usize); } impl TrapHandler for Trap { @@ -193,7 +191,7 @@ impl TrapHandler for Trap { } /// 内核态下的 trap 例程 - fn do_kernel_handle(&self,sp:usize) { + fn do_kernel_handle(&self, sp: usize) { let stval = stval::read(); let sepc = sepc::read(); match self { @@ -219,7 +217,7 @@ impl TrapHandler for Trap { Trap::Exception(_) => { panic!( "unhandled trap: {:?}, stval: {:#x?}, sepc: {:#x}, sp: {:#x}", - self, stval, sepc,sp + self, stval, sepc, sp ) } Trap::Interrupt(Interrupt::SupervisorExternal) => { @@ -305,7 +303,7 @@ pub fn check_task_timer_expired() { /// 只有在内核态下才能进入这个函数 /// 避免嵌套中断发生这里不会再开启中断 #[no_mangle] -pub fn kernel_trap_vector(sp:usize) { +pub fn kernel_trap_vector(sp: usize) { let sstatus = sstatus::read(); let spp = sstatus.spp(); if spp == SPP::User { diff --git a/rust-toolchain.toml b/rust-toolchain.toml index f22d9b34..34757309 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2023-11-02" +channel = "nightly-2023-11-05" components = ["rust-src", "llvm-tools-preview", "rustfmt", "clippy"] targets = ["riscv64gc-unknown-none-elf"] diff --git a/subsystems/arch/Cargo.toml b/subsystems/arch/Cargo.toml new file mode 100644 index 00000000..717d3789 --- /dev/null +++ b/subsystems/arch/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "arch" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +config = { path = "../config" } + + +#[target.'cfg(target_arch = "riscv64")'.dependencies] +riscv = { version = "0.10" } \ No newline at end of file diff --git a/subsystems/arch/src/lib.rs b/subsystems/arch/src/lib.rs new file mode 100644 index 00000000..a4c2b0c8 --- /dev/null +++ b/subsystems/arch/src/lib.rs @@ -0,0 +1,5 @@ +#![no_std] + +mod riscv; + +pub use riscv::*; diff --git a/kernel/src/arch/mod.rs b/subsystems/arch/src/riscv/mod.rs similarity index 53% rename from kernel/src/arch/mod.rs rename to subsystems/arch/src/riscv/mod.rs index 5f2a2506..d91145d8 100644 --- a/kernel/src/arch/mod.rs +++ b/subsystems/arch/src/riscv/mod.rs @@ -1,9 +1,10 @@ -use core::arch::asm; +mod regs; -use self::riscv::register::sie; -use self::riscv::sstatus; +pub use regs::*; -pub mod riscv; +use core::arch::asm; +use riscv::asm::sfence_vma_all; +use riscv::register::satp; /// 获取当前的 hart id pub fn hart_id() -> usize { @@ -18,48 +19,48 @@ pub fn hart_id() -> usize { /// 检查全局中断是否开启 pub fn is_interrupt_enable() -> bool { - sstatus::read().sie() + riscv::register::sstatus::read().sie() } /// 关闭全局中断 pub fn interrupt_disable() { unsafe { - sstatus::clear_sie(); + riscv::register::sstatus::clear_sie(); } } /// 开启全局中断 pub fn interrupt_enable() { unsafe { - sstatus::set_sie(); + riscv::register::sstatus::set_sie(); } } /// 开启外部中断 pub fn external_interrupt_enable() { unsafe { - sie::set_sext(); + riscv::register::sie::set_sext(); } } /// 开启软件中断 pub fn software_interrupt_enable() { unsafe { - sie::set_ssoft(); + riscv::register::sie::set_ssoft(); } } /// 关闭外部中断 pub fn external_interrupt_disable() { unsafe { - sie::clear_sext(); + riscv::register::sie::clear_sext(); } } /// 开启时钟中断 pub fn timer_interrupt_enable() { unsafe { - sie::set_stimer(); + riscv::register::sie::set_stimer(); } } @@ -68,11 +69,18 @@ pub fn read_timer() -> usize { riscv::register::time::read() } -#[macro_export] -macro_rules! write_csr { - ($csr:ident, $val:expr) => { - unsafe { - asm!(concat!("csrw ", stringify!($csr), ", {}"), in(reg) $val); - } - }; +/// 激活页表模式 +pub fn activate_paging_mode(root_ppn: usize) { + unsafe { + sfence_vma_all(); + satp::set(satp::Mode::Sv39, 0, root_ppn); + sfence_vma_all(); + } +} + +/// Permit Supervisor User Memory access +pub fn allow_access_user_memory() { + unsafe { + riscv::register::sstatus::set_sum(); + } } diff --git a/subsystems/arch/src/riscv/regs.rs b/subsystems/arch/src/riscv/regs.rs new file mode 100644 index 00000000..ab3d9dc5 --- /dev/null +++ b/subsystems/arch/src/riscv/regs.rs @@ -0,0 +1,39 @@ +use core::arch::asm; +use riscv::register::sstatus::SPP; + +#[derive(Debug, Default, Copy, Clone)] +pub struct ExtSstatus(pub usize); + +impl ExtSstatus { + pub fn read() -> Self { + let val: usize; + unsafe { + asm!("csrr {},sstatus", out(reg)val); + } + ExtSstatus(val) + } + pub fn set_value(&mut self, val: usize) { + self.0 = val; + } + pub fn set_spp(&mut self, spp: SPP) { + // self.0.set_bit(8, spp as usize != 0); + self.0 = self.0 & !(1 << 8) | ((spp as usize) << 8); + } + pub fn spp(&self) -> SPP { + let v = (self.0 >> 8) & 1; + if v == 1 { + SPP::Supervisor + } else { + SPP::User + } + } + pub fn set_spie(&mut self) { + self.0 |= 1 << 5; + } + pub fn sie(&self) -> bool { + (self.0 & (1 << 1)) != 0 + } + pub fn set_sie(&mut self, value: bool) { + self.0 = self.0 & !(1 << 1) | ((value as usize) << 1); + } +} diff --git a/subsystems/config/Cargo.toml b/subsystems/config/Cargo.toml new file mode 100644 index 00000000..c1c81a8a --- /dev/null +++ b/subsystems/config/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "config" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] + + +[features] +default = ["qemu"] +vf2 = [] +cv1811h = [] +hifive = [] +qemu = [] \ No newline at end of file diff --git a/subsystems/config/src/lib.rs b/subsystems/config/src/lib.rs new file mode 100644 index 00000000..91891f10 --- /dev/null +++ b/subsystems/config/src/lib.rs @@ -0,0 +1,118 @@ +#![no_std] +//! 配置文件 + +/// Alien os的标志 +pub const FLAG: &str = r" + _ _ _ + / \ | | (_) ___ _ __ + / _ \ | | | | / _ \ | '_ \ + / ___ \ | | | | | __/ | | | | + /_/ \_\ |_| |_| \___| |_| |_| +"; + +/// qemu时钟频率 +#[cfg(feature = "qemu")] +pub const CLOCK_FREQ: usize = 1250_0000; +/// vf2时钟频率 +#[cfg(feature = "vf2")] +pub const CLOCK_FREQ: usize = 400_0000; + +/// unmatched时钟频率 +#[cfg(feature = "hifive")] +pub const CLOCK_FREQ: usize = 100_0000; + +/// cv1811h时钟频率 +#[cfg(feature = "cv1811h")] +pub const CLOCK_FREQ: usize = 0x17d7840; + +/// 物理页大小 +pub const FRAME_SIZE: usize = 0x1000; +/// 物理页大小的位数 +pub const FRAME_BITS: usize = 12; +/// 内核启动栈大小 +pub const STACK_SIZE: usize = 1024 * 64; +/// 内核启动栈大小的位数 +pub const STACK_SIZE_BITS: usize = 16; + +/// equal to CLOCK_FREQ +pub const TIMER_FREQ: usize = CLOCK_FREQ; +/// 可配置的启动cpu数量 +pub const CPU_NUM: usize = 1; + +pub const AT_FDCWD: isize = -100isize; + +///qemu的设备地址空间 +#[cfg(feature = "qemu")] +pub const MMIO: &[(usize, usize)] = &[ + (0x0010_0000, 0x00_2000), // VIRT_TEST/RTC in virt machine + (0x2000000, 0x10000), + (0xc00_0000, 0x21_0000), // VIRT_PLIC in virt machine + (0x1000_0000, 0x9000), // VIRT_UART0 with GPU in virt machine + (0x3000_0000, 0x1000_0000), +]; + +/// vf2的设备地址空间 +#[cfg(feature = "vf2")] +pub const MMIO: &[(usize, usize)] = &[ + (0x17040000, 0x10000), // RTC + (0xc000000, 0x4000000), //PLIC + (0x00_1000_0000, 0x10000), // UART +]; + +/// hifive的设备地址空间 +#[cfg(feature = "hifive")] +pub const MMIO: &[(usize, usize)] = &[ + (0xc000000, 0x4000000), //PLIC +]; + +// todo!(if the app linker script changed, this should be changed too) +/// 进程的堆空间上限 +pub const PROCESS_HEAP_MAX: usize = u32::MAX as usize + 1; +/// 跳板页的虚拟地址 +pub const TRAMPOLINE: usize = usize::MAX - 2 * FRAME_SIZE + 1; +/// trap context的虚拟地址 +pub const TRAP_CONTEXT_BASE: usize = TRAMPOLINE - FRAME_SIZE; + +/// app内核栈大小 +pub const USER_KERNEL_STACK_SIZE: usize = 0x1000 * 2; +/// app用户栈大小 +pub const USER_STACK_SIZE: usize = 0x50_000; + +/// vf2/unmatched 的块缓存大小 +#[cfg(any(feature = "vf2", feature = "hifive"))] +pub const BLOCK_CACHE_FRAMES: usize = 1024 * 4 * 4; + +/// qemu 的块缓存大小 +#[cfg(feature = "qemu")] +pub const BLOCK_CACHE_FRAMES: usize = 1024 * 4 * 4; + +/// vf2/unmatched 的堆空间大小 +#[cfg(any(feature = "vf2", feature = "hifive"))] +pub const HEAP_SIZE: usize = 0x40_00000; + +/// qemu 的堆空间大小 +#[cfg(feature = "qemu")] +pub const HEAP_SIZE: usize = 0x26_00000; // (32+6)MB + +/// equal to HEAP_SIZe +pub const KERNEL_HEAP_SIZE: usize = HEAP_SIZE; + +/// pipe缓冲区大小 +pub const PIPE_BUF: usize = 65536; + +/// 线程数量大小限制 +pub const MAX_THREAD_NUM: usize = 65536; +/// 描述符数量大小限制 +pub const MAX_FD_NUM: usize = 4096; + +/// 最大的输入事件数量 +pub const MAX_INPUT_EVENT_NUM: usize = 1024; + +/// 如果 elf 的 phdr 指示 base 是 0(如 libc-test 的 libc.so),则需要找一个非0的位置放置 +/// 我们将其从 0x4000_0000 开始放置。主要用于动态链接库使用 +pub const ELF_BASE_RELOCATE: usize = 0x400_0000; + +// QEMU user networking default IP +pub const QEMU_IP: &str = "10.0.2.15"; +// QEMU user networking gateway +pub const QEMU_GATEWAY: &str = "10.0.2.2"; diff --git a/subsystems/constants/Cargo.toml b/subsystems/constants/Cargo.toml new file mode 100644 index 00000000..6d53e5ad --- /dev/null +++ b/subsystems/constants/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "constants" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +pconst = { git = "https://github.com/os-module/pconst.git", features = ["trick"] } \ No newline at end of file diff --git a/subsystems/constants/src/lib.rs b/subsystems/constants/src/lib.rs new file mode 100644 index 00000000..2d3efe92 --- /dev/null +++ b/subsystems/constants/src/lib.rs @@ -0,0 +1,36 @@ +#![no_std] +//! 导出 `pconst` 中的常量和数据结构, 定义Alien OS的错误类型 + +pub use pconst::*; +pub type AlienError = LinuxErrno; +pub type AlienResult = Result; + +#[derive(Copy, Clone, Debug, Eq, PartialOrd, PartialEq, Hash, Ord)] +pub struct DeviceId { + major: u32, + minor: u32, +} + +impl DeviceId { + pub fn new(major: u32, minor: u32) -> Self { + Self { major, minor } + } + pub fn major(&self) -> u32 { + self.major + } + pub fn minor(&self) -> u32 { + self.minor + } + pub fn id(&self) -> u64 { + ((self.major as u64) << 32) | (self.minor as u64) + } +} + +impl From for DeviceId { + fn from(id: u64) -> Self { + Self { + major: (id >> 32) as u32, + minor: (id & 0xffffffff) as u32, + } + } +} diff --git a/subsystems/device_interface/Cargo.toml b/subsystems/device_interface/Cargo.toml new file mode 100644 index 00000000..50e61212 --- /dev/null +++ b/subsystems/device_interface/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "device_interface" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +constants = { path = "../constants" } \ No newline at end of file diff --git a/subsystems/device_interface/src/lib.rs b/subsystems/device_interface/src/lib.rs new file mode 100644 index 00000000..1ee339fd --- /dev/null +++ b/subsystems/device_interface/src/lib.rs @@ -0,0 +1,48 @@ +#![no_std] + +use constants::io::RtcTime; +use constants::AlienResult; +use core::any::Any; + +pub trait DeviceBase: Sync + Send { + fn hand_irq(&self); +} + +pub trait BlockDevice: Send + Sync + DeviceBase { + fn read(&self, buf: &mut [u8], offset: usize) -> AlienResult; + fn write(&self, buf: &[u8], offset: usize) -> AlienResult; + fn size(&self) -> usize; + fn flush(&self) -> AlienResult<()>; +} +pub trait LowBlockDevice { + fn read_block(&mut self, block_id: usize, buf: &mut [u8]) -> AlienResult<()>; + fn write_block(&mut self, block_id: usize, buf: &[u8]) -> AlienResult<()>; + fn capacity(&self) -> usize; + fn flush(&mut self) {} +} + +pub trait GpuDevice: Send + Sync + Any + DeviceBase { + fn update_cursor(&self); + fn get_framebuffer(&self) -> &mut [u8]; + fn flush(&self); +} + +pub trait InputDevice: Send + Sync + DeviceBase { + fn is_empty(&self) -> bool; + fn read_event_with_block(&self) -> u64; + fn read_event_without_block(&self) -> Option; +} + +pub trait RtcDevice: Send + Sync + DeviceBase { + fn read_time(&self) -> RtcTime; +} + +pub trait UartDevice: Send + Sync + DeviceBase { + fn put(&self, c: u8); + fn get(&self) -> Option; + fn put_bytes(&self, bytes: &[u8]); + fn have_data_to_get(&self) -> bool; + fn have_space_to_put(&self) -> bool; +} + +pub trait NetDevice: DeviceBase {} diff --git a/subsystems/interrupt/Cargo.toml b/subsystems/interrupt/Cargo.toml new file mode 100644 index 00000000..0010297f --- /dev/null +++ b/subsystems/interrupt/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "interrupt" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +plic = { git = "https://github.com/os-module/plic" } +spin = "0" +ksync = { path = "../ksync" } +arch = { path = "../arch" } +config = { path = "../config" } +device_interface = { path = "../device_interface" } + + +[features] +default = [ "qemu" ] + +vf2 = [] +hifive = [] +qemu = [] diff --git a/subsystems/interrupt/src/ext_interrupt.rs b/subsystems/interrupt/src/ext_interrupt.rs new file mode 100644 index 00000000..44541293 --- /dev/null +++ b/subsystems/interrupt/src/ext_interrupt.rs @@ -0,0 +1,17 @@ +use plic::Mode; + +use crate::{DEVICE_TABLE, PLIC}; +use arch::hart_id; + +pub fn external_interrupt_handler() { + let plic = PLIC.get().unwrap(); + let hart_id = hart_id(); + let irq = plic.claim(hart_id as u32, Mode::Supervisor); + let table = DEVICE_TABLE.lock(); + let device = table + .get(&(irq as usize)) + .or_else(|| panic!("no device for irq {}", irq)) + .unwrap(); + device.hand_irq(); + plic.complete(hart_id as u32, Mode::Supervisor, irq); +} diff --git a/subsystems/interrupt/src/lib.rs b/subsystems/interrupt/src/lib.rs new file mode 100644 index 00000000..1498f198 --- /dev/null +++ b/subsystems/interrupt/src/lib.rs @@ -0,0 +1,58 @@ +#![no_std] +extern crate alloc; + +use alloc::collections::BTreeMap; +use alloc::sync::Arc; +use spin::Once; + +pub use ext_interrupt::external_interrupt_handler; +use ksync::Mutex; +use plic::{Mode, PLIC}; + +use arch::hart_id; +use config::CPU_NUM; +use device_interface::DeviceBase; + +mod ext_interrupt; +pub mod record; + +pub static PLIC: Once> = Once::new(); + +pub static DEVICE_TABLE: Mutex>> = Mutex::new(BTreeMap::new()); + +pub fn init_plic(addr: usize) { + #[cfg(feature = "qemu")] + { + let privileges = [2; CPU_NUM]; + let plic = PLIC::new(addr, privileges); + PLIC.call_once(|| plic); + println!("Init qemu plic success"); + } + #[cfg(any(feature = "vf2", feature = "hifive"))] + { + let mut privileges = [2; CPU_NUM]; + // core 0 don't have S mode + privileges[0] = 1; + println!("PLIC context: {:?}", privileges); + let plic = PLIC::new(addr, privileges); + PLIC.call_once(|| plic); + println!("Init hifive or vf2 plic success"); + } +} + +/// Register a device to PLIC. +pub fn register_device_to_plic(irq: usize, device: Arc) { + let mut table = DEVICE_TABLE.lock(); + table.insert(irq, device); + let hard_id = hart_id(); + println!( + "plic enable irq {} for hart {}, priority {}", + irq, hard_id, 1 + ); + let plic = PLIC.get().unwrap(); + plic.set_threshold(hard_id as u32, Mode::Machine, 1); + plic.set_threshold(hard_id as u32, Mode::Supervisor, 0); + plic.complete(hard_id as u32, Mode::Supervisor, irq as u32); + plic.set_priority(irq as u32, 1); + plic.enable(hard_id as u32, Mode::Supervisor, irq as u32); +} diff --git a/subsystems/interrupt/src/record.rs b/subsystems/interrupt/src/record.rs new file mode 100644 index 00000000..5d576b92 --- /dev/null +++ b/subsystems/interrupt/src/record.rs @@ -0,0 +1,33 @@ +use alloc::collections::BTreeMap; +use alloc::format; +use alloc::string::String; +use ksync::Mutex; +use spin::Lazy; + +/// Record the number of interrupts +pub static INTERRUPT_RECORD: Lazy>> = Lazy::new(|| { + let mut tree = BTreeMap::new(); + tree.insert(1, 0); // timer + tree.insert(10, 0); // uart + Mutex::new(tree) +}); + +/// Increase the number of interrupts +pub fn write_irq_info(irq: usize) { + let mut interrupts = INTERRUPT_RECORD.lock(); + let value = interrupts.get_mut(&irq).unwrap().clone(); + interrupts.insert(irq, value + 1); +} + +/// Serializes the number of interrupts +/// +/// # Return +/// irq{}: number +pub fn interrupts_info() -> String { + let interrupts = INTERRUPT_RECORD.lock(); + let mut res = String::new(); + interrupts.iter().for_each(|(irq, value)| { + res.push_str(&format!("{}: {}\r\n", irq, value)); + }); + res +} diff --git a/subsystems/ksync/Cargo.toml b/subsystems/ksync/Cargo.toml new file mode 100644 index 00000000..6a9a9f08 --- /dev/null +++ b/subsystems/ksync/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "ksync" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +config = { path = "../config" } +arch = { path = "../arch" } +kernel-sync = { git = "https://github.com/os-module/kernel-sync.git" } diff --git a/kernel/src/ksync.rs b/subsystems/ksync/src/lib.rs similarity index 83% rename from kernel/src/ksync.rs rename to subsystems/ksync/src/lib.rs index 8583dd43..464839b7 100644 --- a/kernel/src/ksync.rs +++ b/subsystems/ksync/src/lib.rs @@ -1,84 +1,85 @@ -use kernel_sync::{LockAction, ticket::TicketMutexGuard}; -use core::cell::{RefCell, RefMut}; -use crate::arch::{hart_id, interrupt_disable, interrupt_enable, is_interrupt_enable}; -use crate::config::CPU_NUM; - - -pub type SpinMutex = kernel_sync::spin::SpinMutex; -pub type TicketMutex = kernel_sync::ticket::TicketMutex; -pub type RwLock = kernel_sync::RwLock; -pub type Mutex = TicketMutex; -pub type MutexGuard<'a, T> = TicketMutexGuard<'a, T, KernelLockAction>; - -#[derive(Debug, Default, Clone, Copy)] -#[repr(align(64))] -pub struct Cpu { - pub noff: i32, // Depth of push_off() nesting. - pub interrupt_enable: bool, // Were interrupts enabled before push_off()? -} - -impl Cpu { - const fn new() -> Self { - Self { - noff: 0, - interrupt_enable: false, - } - } -} - -pub struct SafeRefCell(RefCell); - -/// # Safety: Only the corresponding cpu will access it. -unsafe impl Sync for SafeRefCell {} - -impl SafeRefCell { - const fn new(t: T) -> Self { - Self(RefCell::new(t)) - } -} - -#[allow(clippy::declare_interior_mutable_const)] -const DEFAULT_CPU: SafeRefCell = SafeRefCell::new(Cpu::new()); - -static CPUS: [SafeRefCell; CPU_NUM] = [DEFAULT_CPU; CPU_NUM]; - -pub fn mycpu() -> RefMut<'static, Cpu> { - CPUS[hart_id()].0.borrow_mut() -} - -// push_off/pop_off are like intr_off()/intr_on() except that they are matched: -// it takes two pop_off()s to undo two push_off()s. Also, if interrupts -// are initially off, then push_off, pop_off leaves them off. -pub(crate) fn push_off() { - let old = is_interrupt_enable(); - interrupt_disable(); - let mut cpu = mycpu(); - if cpu.noff == 0 { - cpu.interrupt_enable = old; - } - cpu.noff += 1; -} - -pub(crate) fn pop_off() { - let mut cpu = mycpu(); - if is_interrupt_enable() || cpu.noff < 1 { - panic!("pop_off"); - } - cpu.noff -= 1; - let should_enable = cpu.noff == 0 && cpu.interrupt_enable; - drop(cpu); - // NOTICE: intr_on() may lead to an immediate inerrupt, so we *MUST* drop(cpu) in advance. - if should_enable { - interrupt_enable(); - } -} - -pub struct KernelLockAction; -impl LockAction for KernelLockAction { - fn before_lock() { - push_off(); - } - fn after_lock() { - pop_off(); - } -} +#![no_std] + +use arch::{hart_id, interrupt_disable, interrupt_enable, is_interrupt_enable}; +use config::CPU_NUM; +use core::cell::{RefCell, RefMut}; +use kernel_sync::{ticket::TicketMutexGuard, LockAction}; + +pub type SpinMutex = kernel_sync::spin::SpinMutex; +pub type TicketMutex = kernel_sync::ticket::TicketMutex; +pub type RwLock = kernel_sync::RwLock; +pub type Mutex = TicketMutex; +pub type MutexGuard<'a, T> = TicketMutexGuard<'a, T, KernelLockAction>; + +#[derive(Debug, Default, Clone, Copy)] +#[repr(align(64))] +pub struct Cpu { + pub noff: i32, // Depth of push_off() nesting. + pub interrupt_enable: bool, // Were interrupts enabled before push_off()? +} + +impl Cpu { + const fn new() -> Self { + Self { + noff: 0, + interrupt_enable: false, + } + } +} + +pub struct SafeRefCell(RefCell); + +/// # Safety: Only the corresponding cpu will access it. +unsafe impl Sync for SafeRefCell {} + +impl SafeRefCell { + const fn new(t: T) -> Self { + Self(RefCell::new(t)) + } +} + +#[allow(clippy::declare_interior_mutable_const)] +const DEFAULT_CPU: SafeRefCell = SafeRefCell::new(Cpu::new()); + +static CPUS: [SafeRefCell; CPU_NUM] = [DEFAULT_CPU; CPU_NUM]; + +pub fn mycpu() -> RefMut<'static, Cpu> { + CPUS[hart_id()].0.borrow_mut() +} + +// push_off/pop_off are like intr_off()/intr_on() except that they are matched: +// it takes two pop_off()s to undo two push_off()s. Also, if interrupts +// are initially off, then push_off, pop_off leaves them off. +pub(crate) fn push_off() { + let old = is_interrupt_enable(); + interrupt_disable(); + let mut cpu = mycpu(); + if cpu.noff == 0 { + cpu.interrupt_enable = old; + } + cpu.noff += 1; +} + +pub(crate) fn pop_off() { + let mut cpu = mycpu(); + if is_interrupt_enable() || cpu.noff < 1 { + panic!("pop_off"); + } + cpu.noff -= 1; + let should_enable = cpu.noff == 0 && cpu.interrupt_enable; + drop(cpu); + // NOTICE: intr_on() may lead to an immediate inerrupt, so we *MUST* drop(cpu) in advance. + if should_enable { + interrupt_enable(); + } +} + +pub struct KernelLockAction; +impl LockAction for KernelLockAction { + fn before_lock() { + push_off(); + } + fn after_lock() { + pop_off(); + } +} diff --git a/subsystems/mem/Cargo.toml b/subsystems/mem/Cargo.toml new file mode 100644 index 00000000..fe5ff36e --- /dev/null +++ b/subsystems/mem/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "mem" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +config = {path = "../config" } +arch = {path = "../arch" } +ksync = { path = "../ksync" } +pager = { git = "https://github.com/os-module/pager", default-features = false, optional = true } +platform = { path = "../platform" } +log = "0" +talc = { version = "1.0", optional = true } +buddy_system_allocator = { version = "0.9.0", optional = true } +rslab = { version = "0.2.1", optional = true } + +spin = "0" + +page-table = { git = "https://github.com/os-module/page-table.git", branch = "dev" } + +page_table = { git = "https://github.com/rcore-os/arceos",rev = "7eeebc5" } +memory_addr = { git = "https://github.com/rcore-os/arceos",rev = "7eeebc5" } + + + +[features] +default = ["pager_buddy","talloc"] +pager_buddy = ["pager/buddy"] +pager_bitmap = ["pager/bitmap"] +slab = ["rslab"] +talloc = ["talc"] +buddy = ["buddy_system_allocator"] \ No newline at end of file diff --git a/subsystems/mem/src/frame.rs b/subsystems/mem/src/frame.rs new file mode 100644 index 00000000..58576bc7 --- /dev/null +++ b/subsystems/mem/src/frame.rs @@ -0,0 +1,63 @@ +use alloc::format; +use config::{FRAME_BITS, FRAME_SIZE}; +use ksync::Mutex; +use page_table::PagingIf; +use pager::{PageAllocator, PageAllocatorExt}; +use platform::println; + +#[cfg(feature = "pager_bitmap")] +pub static FRAME_ALLOCATOR: Mutex> = Mutex::new(pager::Bitmap::new()); +#[cfg(feature = "pager_buddy")] +pub static FRAME_ALLOCATOR: Mutex> = Mutex::new(pager::Zone::new()); + +pub fn init_frame_allocator(start: usize, end: usize) { + let page_start = start / FRAME_SIZE; + let page_end = end / FRAME_SIZE; + let page_count = page_end - page_start; + println!( + "Page start:{:#x},end:{:#x},count:{:#x}", + page_start, page_end, page_count + ); + FRAME_ALLOCATOR + .lock() + .init(start..end) + .expect("init frame allocator failed"); +} + +#[no_mangle] +pub fn alloc_frames(num: usize) -> *mut u8 { + assert_eq!(num.next_power_of_two(), num); + let start_page = FRAME_ALLOCATOR + .lock() + .alloc_pages(num, FRAME_SIZE) + .expect(format!("alloc {} frame failed", num).as_str()); + let start_addr = start_page << FRAME_BITS; + start_addr as *mut u8 +} + +#[no_mangle] +pub fn free_frames(addr: *mut u8, num: usize) { + assert_eq!(num.next_power_of_two(), num); + let start = addr as usize >> FRAME_BITS; + FRAME_ALLOCATOR + .lock() + .free_pages(start, num) + .expect(format!("free frame start:{:#x},num:{} failed", start, num).as_str()); +} + +pub struct VmmPageAllocator; + +impl PagingIf for VmmPageAllocator { + fn alloc_frame() -> Option { + let start_addr = alloc_frames(1); + Some(memory_addr::PhysAddr::from(start_addr as usize)) + } + + fn dealloc_frame(paddr: memory_addr::PhysAddr) { + free_frames(paddr.as_usize() as *mut u8, 1); + } + + fn phys_to_virt(paddr: memory_addr::PhysAddr) -> memory_addr::VirtAddr { + memory_addr::VirtAddr::from(paddr.as_usize()) + } +} diff --git a/subsystems/mem/src/heap.rs b/subsystems/mem/src/heap.rs new file mode 100644 index 00000000..8aa2c719 --- /dev/null +++ b/subsystems/mem/src/heap.rs @@ -0,0 +1,71 @@ +use crate::frame::{alloc_frames, free_frames}; +#[cfg(feature = "buddy")] +use buddy_system_allocator::LockedHeap; +use config::FRAME_SIZE; +use core::alloc::GlobalAlloc; +use ksync::Mutex; +use log::trace; +#[cfg(feature = "rslab")] +use rslab::{init_slab_system, SlabAllocator}; +#[cfg(feature = "talloc")] +use talc::{Talc, Talck}; + +pub struct HeapAllocator { + #[cfg(feature = "talloc")] + allocator: Mutex, + #[cfg(feature = "buddy")] + allocator: Mutex>, + #[cfg(feature = "slab")] + allocator: Mutex, +} + +unsafe impl GlobalAlloc for HeapAllocator { + unsafe fn alloc(&self, layout: core::alloc::Layout) -> *mut u8 { + if layout.size() >= 5 * 1024 * 1024 { + let need_page = (layout.size() + FRAME_SIZE - 1) / FRAME_SIZE; + trace!("alloc big page: {:#x}", layout.size()); + alloc_frames(need_page) + } else { + self.allocator.lock().alloc(layout) + } + } + unsafe fn dealloc(&self, ptr: *mut u8, layout: core::alloc::Layout) { + if layout.size() >= 5 * 1024 * 1024 { + let need_page = (layout.size() + FRAME_SIZE - 1) / FRAME_SIZE; + trace!("free big page: {:#x}", layout.size()); + free_frames(ptr, need_page); + } else { + self.allocator.lock().dealloc(ptr, layout); + } + } +} + +impl HeapAllocator { + pub const fn new() -> Self { + Self { + #[cfg(feature = "talloc")] + allocator: Mutex::new(Talc::new().spin_lock()), + #[cfg(feature = "buddy")] + allocator: Mutex::new(LockedHeap::<32>::new()), + #[cfg(feature = "slab")] + allocator: Mutex::new(SlabAllocator), + } + } + pub fn init(&self, heap: &mut [u8]) { + #[cfg(feature = "talloc")] + unsafe { + self.allocator.lock().talc().init(heap.into()) + } + #[cfg(feature = "buddy")] + unsafe { + self.allocator + .lock() + .lock() + .init(heap.as_mut_ptr() as usize, heap.len()) + } + #[cfg(feature = "slab")] + unsafe { + init_slab_system(FRAME_SIZE, 64); + } + } +} diff --git a/subsystems/mem/src/lib.rs b/subsystems/mem/src/lib.rs new file mode 100644 index 00000000..2ce23641 --- /dev/null +++ b/subsystems/mem/src/lib.rs @@ -0,0 +1,45 @@ +#![no_std] + +extern crate alloc; + +use arch::activate_paging_mode; +use config::{FRAME_BITS, KERNEL_HEAP_SIZE}; +use heap::HeapAllocator; + +mod frame; +mod heap; +mod vmm; + +pub use frame::{alloc_frames, free_frames}; + +#[global_allocator] +static HEAP_ALLOCATOR: HeapAllocator = HeapAllocator::new(); + +#[cfg(any(feature = "talloc", feature = "buddy"))] +static mut KERNEL_HEAP: [u8; KERNEL_HEAP_SIZE] = [0; KERNEL_HEAP_SIZE]; + +pub fn init_memory_system(memory_start: usize, memory_end: usize, is_first_cpu: bool) { + if is_first_cpu { + frame::init_frame_allocator(memory_start, memory_end); + println!("Frame allocator init success"); + HEAP_ALLOCATOR.init(unsafe { &mut KERNEL_HEAP }); + #[cfg(feature = "talloc")] + { + println!("Talloc allocator init success"); + } + #[cfg(feature = "slab")] + { + println!("Slab allocator init success"); + } + #[cfg(feature = "buddy")] + { + println!("Buddy allocator init success"); + } + vmm::build_kernel_address_space(memory_end); + println!("Build kernel address space success"); + activate_paging_mode(vmm::kernel_pgd() >> FRAME_BITS); + println!("Activate paging mode success"); + } else { + activate_paging_mode(vmm::kernel_pgd() >> FRAME_BITS); + } +} diff --git a/subsystems/mem/src/vmm.rs b/subsystems/mem/src/vmm.rs new file mode 100644 index 00000000..42cf671f --- /dev/null +++ b/subsystems/mem/src/vmm.rs @@ -0,0 +1,18 @@ +#[allow(unused)] +extern "C" { + fn stext(); + fn srodata(); + fn sdata(); + fn sbss(); + fn ekernel(); + fn strampoline(); + fn sinit(); + fn einit(); + + // fn kernel_eh_frame(); + // fn kernel_eh_frame_end(); + // fn kernel_eh_frame_hdr(); + // fn kernel_eh_frame_hdr_end(); +} + +pub fn build_kernel_address_space(memory_end: usize) {} diff --git a/subsystems/platform/Cargo.toml b/subsystems/platform/Cargo.toml new file mode 100644 index 00000000..e0ff57b5 --- /dev/null +++ b/subsystems/platform/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "platform" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +log = "0" +arch = { path = "../arch" } +config = { path = "../config" } +ksync = { path = "../ksync" } + + + +[features] +default = ["qemu_riscv"] + +qemu_riscv = [] +starfive2_riscv = [] +hifive_riscv = [] \ No newline at end of file diff --git a/subsystems/platform/src/common_riscv/boot.rs b/subsystems/platform/src/common_riscv/boot.rs new file mode 100644 index 00000000..86f2ab50 --- /dev/null +++ b/subsystems/platform/src/common_riscv/boot.rs @@ -0,0 +1,45 @@ +use config::{CPU_NUM, STACK_SIZE}; +use core::arch::asm; + +#[link_section = ".bss.stack"] +static mut STACK: [u8; STACK_SIZE * CPU_NUM] = [0; STACK_SIZE * CPU_NUM]; + +/// 内核入口 +/// +/// 用于初始化内核的栈空间,并关闭中断 +#[naked] +#[no_mangle] +#[link_section = ".text.entry"] +extern "C" fn _start() { + unsafe { + asm!("\ + mv tp, a0 + mv gp, a1 + add t0, a0, 1 + slli t0, t0, 16 + la sp, {boot_stack} + add sp, sp, t0 + call clear_bss + mv a0, tp + mv a1, gp + call main + ", + boot_stack = sym STACK, + options(noreturn) + ); + } +} + +extern "C" { + fn sbss(); + fn ebss(); +} + +/// 清空.bss段 +#[no_mangle] +fn clear_bss() { + unsafe { + core::slice::from_raw_parts_mut(sbss as usize as *mut u8, ebss as usize - sbss as usize) + .fill(0); + } +} diff --git a/subsystems/platform/src/common_riscv/mod.rs b/subsystems/platform/src/common_riscv/mod.rs new file mode 100644 index 00000000..6823140c --- /dev/null +++ b/subsystems/platform/src/common_riscv/mod.rs @@ -0,0 +1,2 @@ +pub mod boot; +pub mod sbi; diff --git a/subsystems/platform/src/common_riscv/sbi.rs b/subsystems/platform/src/common_riscv/sbi.rs new file mode 100644 index 00000000..39458c76 --- /dev/null +++ b/subsystems/platform/src/common_riscv/sbi.rs @@ -0,0 +1,123 @@ +//! SBI 调用接口 +use core::arch::asm; + +/// 设置定时器 +const SBI_SET_TIMER: usize = 0; +/// 控制台输出 +const SBI_CONSOLE_PUT_CHAR: usize = 1; +/// 控制台输入 +const SBI_CONSOLE_GET_CHAR: usize = 2; +// const SBI_CLEAR_IPI: usize = 3; +/// 发送 IPI +const SBI_SEND_IPI: usize = 4; +// const SBI_REMOTE_FENCE_I: usize = 5; +// const SBI_REMOTE_SFENCE_VMA: usize = 6; +// const SBI_REMOTE_SFENCE_VMA_ASID: usize = 7; +/// 关闭机器 +const SBI_SHUTDOWN: usize = 8; + +/// SBI 调用 +/// +/// sbi规范定义了调用的参数传递方法 +fn sbi_call(which: usize, arg0: usize, arg1: usize, arg2: usize) -> i32 { + let mut ret; + unsafe { + asm!("ecall", + in("a7") which, + inlateout("a0") arg0 as i32 => ret, + in("a1") arg1, + in("a2") arg2); + } + ret +} + +/// 设置定时器 +pub fn set_timer(time: usize) { + sbi_call(SBI_SET_TIMER, time, 0, 0); +} + +pub fn system_shutdown() -> ! { + sbi_call(SBI_SHUTDOWN, 0, 0, 0); + loop {} +} + +/// Warp sbi SBI_CONSOLE_PUT_CHAR call +pub fn console_putchar(ch: u8) { + sbi_call(SBI_CONSOLE_PUT_CHAR, ch as usize, 0, 0); +} + +/// Warp sbi SBI_CONSOLE_GET_CHAR call +#[allow(unused)] +pub fn console_getchar() -> char { + sbi_call(SBI_CONSOLE_GET_CHAR, 0, 0, 0) as u8 as char +} + +/// sbi调用返回值 +#[repr(C)] +#[derive(Debug)] +pub struct SbiRet { + /// Error number + pub error: isize, + /// Result value + pub value: isize, +} + +/// SBI 基本扩展 +pub const EXTENSION_BASE: usize = 0x10; +/// SBI 时钟扩展 +pub const EXTENSION_TIMER: usize = 0x54494D45; +// pub const EXTENSION_IPI: usize = 0x735049; +// pub const EXTENSION_RFENCE: usize = 0x52464E43; +/// SBI HSM 扩展 +pub const EXTENSION_HSM: usize = 0x48534D; +// pub const EXTENSION_SRST: usize = 0x53525354; + +/// SBI HSM扩展的启动cpu功能 +const FUNCTION_HSM_HART_START: usize = 0x0; +// const FUNCTION_HSM_HART_STOP: usize = 0x1; +// const FUNCTION_HSM_HART_GET_STATUS: usize = 0x2; +const FUNCTION_HSM_HART_SUSPEND: usize = 0x3; + +/// 第三种类型的SBI调用 +/// +/// 可以传递更多参数 +#[inline(always)] +fn sbi_call_3(extension: usize, function: usize, arg0: usize, arg1: usize, arg2: usize) -> SbiRet { + let (error, value); + unsafe { + asm!( + "ecall", + in("a0") arg0, in("a1") arg1, in("a2") arg2, + in("a6") function, in("a7") extension, + lateout("a0") error, lateout("a1") value, + ) + } + SbiRet { error, value } +} + +pub fn hart_suspend(suspend_type: u32, resume_addr: usize, opaque: usize) -> SbiRet { + sbi_call_3( + EXTENSION_HSM, + FUNCTION_HSM_HART_SUSPEND, + suspend_type as usize, + resume_addr, + opaque, + ) +} + +/// wrap sbi FUNCTION_HSM_HART_START call +pub fn hart_start(hart_id: usize, start_addr: usize, opaque: usize) -> SbiRet { + sbi_call_3( + EXTENSION_HSM, + FUNCTION_HSM_HART_START, + hart_id, + start_addr, + opaque, + ) +} + +/// wrap sbi SBI_SEND_IPI call +#[allow(unused)] +pub fn send_ipi(ptr: usize) { + sbi_call(SBI_SEND_IPI, ptr, 0, 0); +} diff --git a/subsystems/platform/src/console.rs b/subsystems/platform/src/console.rs new file mode 100644 index 00000000..7161e341 --- /dev/null +++ b/subsystems/platform/src/console.rs @@ -0,0 +1,42 @@ +use core::fmt::{Arguments, Result, Write}; +#[macro_export] +macro_rules! xprint { + ($($arg:tt)*) => { + let hard_id = arch::hart_id(); + $crate::console::__print(format_args!("[{}] {}", hard_id, format_args!($($arg)*))) + }; +} + +#[macro_export] +macro_rules! xprintln { + () => ($crate::print!("\n")); + ($fmt:expr) => ($crate::print!(concat!($fmt, "\n"))); + ($fmt:expr, $($arg:tt)*) => ($crate::print!( + concat!($fmt, "\n"), $($arg)*)); +} + +pub struct Stdout; + +/// 对`Stdout`实现输出的Trait +impl Write for Stdout { + fn write_str(&mut self, s: &str) -> Result { + s.as_bytes().iter().for_each(|x| { + crate::console_putchar(*x); + }); + Ok(()) + } +} + +/// 输出函数 +/// 对参数进行输出 主要使用在输出相关的宏中 如println +#[doc(hidden)] +pub fn __print(args: Arguments) { + Stdout.write_fmt(args).unwrap(); +} + +/// 系统启动初期使用的输出函数 +/// +/// 在riscv平台上,由于没有实现串口驱动,所以在系统启动初期使用SBI进行输出 +pub fn early_console_write(s: &str) { + Stdout.write_str(s).unwrap(); +} diff --git a/subsystems/platform/src/hifive_riscv/mod.rs b/subsystems/platform/src/hifive_riscv/mod.rs new file mode 100644 index 00000000..5493eea0 --- /dev/null +++ b/subsystems/platform/src/hifive_riscv/mod.rs @@ -0,0 +1,37 @@ +use core::iter::Once; + +#[repr(align(4))] +struct Wrapper(T); + +const FDT: &[u8] = &Wrapper(*include_bytes!( + "../../../../tools/hifive-unmatched-a00.dtb" +)) +.0; + +pub static DTB: Once = Once::new(); + +pub fn init_dtb(dtb: Option) { + let dtb_ptr = dtb.unwrap_or(FDT.as_ptr() as usize); + DTB.call_once(|| dtb_ptr); +} + +/// 设置定时器 +pub fn set_timer(time: usize) { + crate::common_riscv::sbi::set_timer(time); +} + +pub fn system_shutdown() -> ! { + crate::common_riscv::sbi::system_shutdown(); + loop {} +} + +/// Warp sbi SBI_CONSOLE_PUT_CHAR call +pub fn console_putchar(ch: u8) { + crate::common_riscv::sbi::console_putchar(ch); +} + +/// Warp sbi SBI_CONSOLE_GET_CHAR call +#[allow(unused)] +pub fn console_getchar() -> char { + crate::common_riscv::sbi::console_getchar() +} diff --git a/subsystems/platform/src/lib.rs b/subsystems/platform/src/lib.rs new file mode 100644 index 00000000..a1cfe7a5 --- /dev/null +++ b/subsystems/platform/src/lib.rs @@ -0,0 +1,50 @@ +#![no_std] +#![feature(naked_functions)] + +extern crate alloc; + +#[macro_use] +pub mod console; +mod common_riscv; +#[cfg(feature = "hifive_riscv")] +mod hifive_riscv; +mod logger; +#[cfg(feature = "qemu_riscv")] +mod qemu_riscv; +#[cfg(feature = "starfive2_riscv")] +mod starfive2_riscv; + +#[cfg(feature = "qemu_riscv")] +use qemu_riscv::console_putchar; +#[cfg(feature = "qemu_riscv")] +pub use qemu_riscv::system_shutdown; + +#[cfg(feature = "starfive2_riscv")] +use starfive2_riscv::console_putchar; +#[cfg(feature = "starfive2_riscv")] +pub use starfive2_riscv::system_shutdown; + +#[cfg(feature = "hifive_riscv")] +pub use hifive_riscv::system_shutdown; + +#[cfg(feature = "hifive_riscv")] +pub use hifive_riscv::console_putchar; + +pub fn platform_init(dtb: Option) { + #[cfg(feature = "hifive_riscv")] + hifive_riscv::init_dtb(dtb); + #[cfg(feature = "starfive2_riscv")] + starfive2_riscv::init_dtb(dtb); + #[cfg(feature = "qemu_riscv")] + qemu_riscv::init_dtb(dtb); + logger::init_logger(); +} + +pub fn platform_dtb_ptr() -> usize { + #[cfg(feature = "hifive_riscv")] + return hifive_riscv::DTB.get().unwrap(); + #[cfg(feature = "starfive2_riscv")] + return starfive2_riscv::DTB.get().unwrap(); + #[cfg(feature = "qemu_riscv")] + return qemu_riscv::DTB.get().unwrap(); +} diff --git a/subsystems/platform/src/logger.rs b/subsystems/platform/src/logger.rs new file mode 100644 index 00000000..5be30879 --- /dev/null +++ b/subsystems/platform/src/logger.rs @@ -0,0 +1,41 @@ +use crate::xprintln; +use log::{self, Level, LevelFilter, Log, Metadata, Record}; +struct SimpleLogger; + +impl Log for SimpleLogger { + fn enabled(&self, _metadata: &Metadata) -> bool { + true + } + fn log(&self, record: &Record) { + if !self.enabled(record.metadata()) { + return; + } + let color = match record.level() { + Level::Error => 31, // Red + Level::Warn => 93, // BrightYellow + Level::Info => 35, // Blue + Level::Debug => 32, // Green + Level::Trace => 90, // BrightBlack + }; + xprintln!( + "\u{1B}[{}m[{:>1}] {}\u{1B}[0m", + color, + record.level(), + record.args(), + ); + } + fn flush(&self) {} +} + +pub fn init_logger() { + xprintln!("Init logger {:?}", option_env!("LOG")); + log::set_logger(&SimpleLogger).unwrap(); + log::set_max_level(match option_env!("LOG") { + Some("ERROR") => LevelFilter::Error, + Some("WARN") => LevelFilter::Warn, + Some("INFO") => LevelFilter::Info, + Some("DEBUG") => LevelFilter::Debug, + Some("TRACE") => LevelFilter::Trace, + _ => LevelFilter::Off, + }); +} diff --git a/subsystems/platform/src/qemu_riscv/mod.rs b/subsystems/platform/src/qemu_riscv/mod.rs new file mode 100644 index 00000000..7ba465c1 --- /dev/null +++ b/subsystems/platform/src/qemu_riscv/mod.rs @@ -0,0 +1,29 @@ +use core::iter::Once; + +pub static DTB: Once = Once::new(); + +pub fn init_dtb(dtb: Option) { + let dtb_ptr = dtb.expect("No dtb found"); + DTB.call_once(|| dtb_ptr); +} + +/// 设置定时器 +pub fn set_timer(time: usize) { + crate::common_riscv::sbi::set_timer(time); +} + +pub fn system_shutdown() -> ! { + crate::common_riscv::sbi::system_shutdown(); + loop {} +} + +/// Warp sbi SBI_CONSOLE_PUT_CHAR call +pub fn console_putchar(ch: u8) { + crate::common_riscv::sbi::console_putchar(ch); +} + +/// Warp sbi SBI_CONSOLE_GET_CHAR call +#[allow(unused)] +pub fn console_getchar() -> char { + crate::common_riscv::sbi::console_getchar() +} diff --git a/subsystems/platform/src/starfive2_riscv/mod.rs b/subsystems/platform/src/starfive2_riscv/mod.rs new file mode 100644 index 00000000..f0fab6c2 --- /dev/null +++ b/subsystems/platform/src/starfive2_riscv/mod.rs @@ -0,0 +1,37 @@ +use core::iter::Once; + +#[repr(align(4))] +struct Wrapper(T); + +pub const FDT: &[u8] = &Wrapper(*include_bytes!( + "../../../../tools/jh7110-visionfive-v2.dtb" +)) +.0; + +pub static DTB: Once = Once::new(); + +pub fn init_dtb(dtb: Option) { + let dtb_ptr = dtb.unwrap_or(FDT.as_ptr() as usize); + DTB.call_once(|| dtb_ptr); +} + +/// 设置定时器 +pub fn set_timer(time: usize) { + crate::common_riscv::sbi::set_timer(time); +} + +pub fn system_shutdown() -> ! { + crate::common_riscv::sbi::system_shutdown(); + loop {} +} + +/// Warp sbi SBI_CONSOLE_PUT_CHAR call +pub fn console_putchar(ch: u8) { + crate::common_riscv::sbi::console_putchar(ch); +} + +/// Warp sbi SBI_CONSOLE_GET_CHAR call +#[allow(unused)] +pub fn console_getchar() -> char { + crate::common_riscv::sbi::console_getchar() +}