diff --git a/.vscode/settings.json b/.vscode/settings.json index 4dd0a018..add4214d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,10 @@ { - "files.associations": { - "unistd.h": "c", - "time.h": "c" - }, - "rust-analyzer.cargo.target": "riscv64gc-unknown-none-elf", + // Prevent "can't find crate for `test`" error on no_std + // Ref: https://github.com/rust-lang/vscode-rust/issues/729 + // For vscode-rust plugin users: + "rust.target": "riscv64imac-unknown-none-elf", + "rust.all_targets": false, + // For Rust Analyzer plugin users: + "rust-analyzer.cargo.target": "riscv64imac-unknown-none-elf", + "rust-analyzer.checkOnSave.allTargets": false } diff --git a/Makefile b/Makefile index 5fbb923d..98706c85 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ ARCH ?= x86_64 -.PHONY: help setup rootfs libc-test image test-image check doc clean +.PHONY: help setup update rootfs libc-test other-test image check doc clean # print top level help help: @@ -40,6 +40,7 @@ check: doc: cargo doc --open +# clean targets clean: cargo clean rm -rf rootfs diff --git a/docs/Manual.md b/docs/Manual.md index ca4a5e28..fc1cf7a4 100644 --- a/docs/Manual.md +++ b/docs/Manual.md @@ -14,8 +14,8 @@ 1. 先决条件 - 目前受关注的开发环境为较新版本的 Ubuntu,建议使用 Ubuntu20.04 或 Ubuntu22.04。 - 本文假设读者使用二者之一。 + 目前已测试的开发环境包括 Ubuntu20.04、Ubuntu22.04 和 Debian11, + Ubuntu22.04 不能正确编译 x86_64 的 libc 测试。 若不需要烧写到物理硬件,使用 WSL2 或其他虚拟机的操作与真机并无不同之处。 在开始之前,确保你的计算机上安装了 git 和 rustup。要在虚拟环境开发或测试,需要 QEMU。 @@ -44,6 +44,12 @@ make help ``` +6. 推到仓库前,现在本机执行测试 + + ```bash + make check # CI/build 的一部分,未来会实现更多快速测试指令 + ``` + ## Linux 模式 zCore 根据向用户提供的系统调用的不同,可分为 zircon 模式和 linux 模式。 @@ -67,6 +73,12 @@ make rootfs ARCH=riscv64 make libc-test ``` +要执行 CI 的其他测试,需要向文件系统中添加相应测试集: + +```bash +make other-test +``` + 要以裸机模式启动 zCore,需要构造将放到设备或虚拟环境中的镜像文件: ```bash diff --git a/kernel-hal/src/libos/vm.rs b/kernel-hal/src/libos/vm.rs index 581fbd83..d5bca5f8 100644 --- a/kernel-hal/src/libos/vm.rs +++ b/kernel-hal/src/libos/vm.rs @@ -69,7 +69,7 @@ impl GenericPageTable for PageTable { fn query(&self, vaddr: VirtAddr) -> PagingResult<(PhysAddr, MMUFlags, PageSize)> { debug_assert!(is_aligned(vaddr)); - if PMEM_MAP_VADDR <= vaddr && vaddr < PMEM_MAP_VADDR + PMEM_SIZE { + if (PMEM_MAP_VADDR..PMEM_MAP_VADDR + PMEM_SIZE).contains(&vaddr) { Ok(( vaddr - PMEM_MAP_VADDR, MMUFlags::READ | MMUFlags::WRITE, diff --git a/linux-object/src/sync/semaphore.rs b/linux-object/src/sync/semaphore.rs index 599fa1bc..8d468e31 100644 --- a/linux-object/src/sync/semaphore.rs +++ b/linux-object/src/sync/semaphore.rs @@ -72,7 +72,7 @@ impl Semaphore { inner: Arc>, } - impl<'a> Future for SemaphoreFuture { + impl Future for SemaphoreFuture { type Output = Result<(), LxError>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { @@ -157,13 +157,13 @@ impl Semaphore { } } -impl<'a> Drop for SemaphoreGuard<'a> { +impl Drop for SemaphoreGuard<'_> { fn drop(&mut self) { self.sem.release(); } } -impl<'a> Deref for SemaphoreGuard<'a> { +impl Deref for SemaphoreGuard<'_> { type Target = Semaphore; fn deref(&self) -> &Self::Target { diff --git a/linux-syscall/src/ipc.rs b/linux-syscall/src/ipc.rs index fe915a46..262dd722 100644 --- a/linux-syscall/src/ipc.rs +++ b/linux-syscall/src/ipc.rs @@ -112,11 +112,11 @@ impl Syscall<'_> { } let sem = &sem_array[num as usize]; - let _result = match op { + match op { 1 => sem.release(), -1 => sem.acquire().await?, _ => unimplemented!("Semaphore: semop.(Not 1/-1)"), - }; + } sem.set_pid(self.zircon_process().id() as usize); if flags.contains(SemFlags::SEM_UNDO) { self.linux_process().semaphores_add_undo(id, num, op); diff --git a/xtask/CHANGLOG.md b/xtask/CHANGLOG.md index 6cb30a24..2a163fd8 100644 --- a/xtask/CHANGLOG.md +++ b/xtask/CHANGLOG.md @@ -2,6 +2,10 @@ 最新的更新将出现在最上方。 +## 20220512(YdrMaster) + +`cargo check-style` 现在会依 CI/build 的方式工作。 + ## 20220511(YdrMaster) ### 目录结构定义 @@ -23,3 +27,17 @@ ### 实现变更 - 使用 `std::os::unix::fs::symlink` 建立符号链接,不再依赖 `ln` 应用程序; + +## 20220506(YdrMaster) + +顶层的 Makefile 已经尽量迁移到 rust,并在子项目 README.md 中更新了子命令说明。 + +计划提起一次 PR。 + +## 20220504(YdrMaster) + +初步的计划是先尽量将 Makefile 转化为类型安全且更有可能工程化结构化的 Rust xtask。 +尤其是要将 zCore 目录内外的两个 Makefile 合并。 + +目前已经架空了外面 Makefile 的 rootfs 指令,这个指令是用于将加载到内存的最小系统的。 +外面的 Makefile 还剩打包镜像、启动某些测试集的功能,但目前命令之间不正交,还需要进一步梳理。 diff --git a/xtask/README.md b/xtask/README.md index f0713fa8..3799fbf0 100644 --- a/xtask/README.md +++ b/xtask/README.md @@ -34,19 +34,3 @@ - [x] 打包可烧写到其他存储介质的 zCore 镜像 - [ ] 启动与 Qemu 关联的 GDB 以支持内核调试 - [ ] 自动化测试:实现与 CI 的逻辑一致性 - -## 进度日志 - -- 2022/05/06 - - 顶层的 Makefile 已经尽量迁移到 rust,并在子项目 README.md 中更新了子命令说明。 - - 计划提起一次 PR。 - -- 2022/05/04 - - 初步的计划是先尽量将 Makefile 转化为类型安全且更有可能工程化结构化的 Rust xtask。 - 尤其是要将 zCore 目录内外的两个 Makefile 合并。 - - 目前已经架空了外面 Makefile 的 rootfs 指令,这个指令是用于将加载到内存的最小系统的。 - 外面的 Makefile 还剩打包镜像、启动某些测试集的功能,但目前命令之间不正交,还需要进一步梳理。 diff --git a/xtask/src/arch.rs b/xtask/src/arch.rs index d4c9a08b..cf5cd069 100644 --- a/xtask/src/arch.rs +++ b/xtask/src/arch.rs @@ -1,6 +1,6 @@ //! 平台相关的操作。 -use crate::{dir, download::wget, CommandExt, ALPINE_ROOTFS_VERSION, ALPINE_WEBSITE}; +use crate::{dir, download::wget, make::Make, CommandExt, ALPINE_ROOTFS_VERSION, ALPINE_WEBSITE}; use dircpy::copy_dir; use std::{ ffi::{OsStr, OsString}, @@ -239,38 +239,6 @@ impl Arch { } } -struct Make(Command); - -impl AsRef for Make { - fn as_ref(&self) -> &Command { - &self.0 - } -} - -impl AsMut for Make { - fn as_mut(&mut self) -> &mut Command { - &mut self.0 - } -} - -impl CommandExt for Make {} - -impl Make { - fn new(j: Option) -> Self { - let mut make = Self(Command::new("make")); - match j { - Some(0) => {} - Some(j) => { - make.arg(format!("-j{j}")); - } - None => { - make.arg("-j"); - } - } - make - } -} - struct Tar(Command); impl AsRef for Tar { diff --git a/xtask/src/cargo.rs b/xtask/src/cargo.rs index 67e76de5..1bc6c200 100644 --- a/xtask/src/cargo.rs +++ b/xtask/src/cargo.rs @@ -40,6 +40,10 @@ impl Cargo { Self::new("clippy") } + pub fn doc() -> Self { + Self::new("doc") + } + pub fn all_features(&mut self) -> &mut Self { self.arg("--all-features"); self @@ -68,8 +72,14 @@ impl Cargo { self } + #[allow(unused)] pub fn target(&mut self, target: impl AsRef) -> &mut Self { self.arg("--target").arg(target); self } + + pub fn package(&mut self, package: impl AsRef) -> &mut Self { + self.arg("--package").arg(package); + self + } } diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 667521f5..86136755 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -20,10 +20,12 @@ mod dir; mod download; mod dump; mod git; +mod make; use arch::Arch; use cargo::Cargo; use git::Git; +use make::Make; const ALPINE_WEBSITE: &str = "https://dl-cdn.alpinelinux.org/alpine/v3.12/releases"; const ALPINE_ROOTFS_VERSION: &str = "3.12.0"; @@ -179,28 +181,30 @@ fn unset_git_proxy(global: bool) { /// 风格检查。 fn check_style() { - println!("fmt -----------------------------------------"); + println!("Check workspace"); Cargo::fmt().arg("--all").arg("--").arg("--check").invoke(); - println!("clippy --------------------------------------"); Cargo::clippy().all_features().invoke(); - println!("clippy x86_64 zircon smp=1 ------------------"); + Cargo::doc().all_features().arg("--no-deps").invoke(); + println!("Check libos"); Cargo::clippy() - .features(false, &["zircon"]) - .target("x86_64.json") - .args(&["-Z", "build-std=core,alloc"]) - .args(&["-Z", "build-std-features=compiler-builtins-mem"]) - .current_dir("zCore") - .env("SMP", "1") + .package("zcore") + .features(false, &["zircon libos"]) .invoke(); - println!("clippy riscv64 linux smp=4 ------------------"); Cargo::clippy() - .features(false, &["linux", "board-qemu"]) - .target("riscv64.json") - .args(&["-Z", "build-std=core,alloc"]) - .args(&["-Z", "build-std-features=compiler-builtins-mem"]) + .package("zcore") + .features(false, &["linux libos"]) + .invoke(); + println!("Check bare-metal"); + Make::new(None) + .arg("clippy") + .env("ARCH", "x86_64") + .current_dir("zCore") + .invoke(); + Make::new(None) + .arg("clippy") + .env("ARCH", "riscv64") + .env("LINUX", "1") .current_dir("zCore") - .env("SMP", "4") - .env("PLATFORM", "board-qemu") .invoke(); } diff --git a/xtask/src/make.rs b/xtask/src/make.rs new file mode 100644 index 00000000..ca0ae2c6 --- /dev/null +++ b/xtask/src/make.rs @@ -0,0 +1,34 @@ +use crate::CommandExt; +use std::process::Command; + +pub(crate) struct Make(Command); + +impl AsRef for Make { + fn as_ref(&self) -> &Command { + &self.0 + } +} + +impl AsMut for Make { + fn as_mut(&mut self) -> &mut Command { + &mut self.0 + } +} + +impl CommandExt for Make {} + +impl Make { + pub fn new(j: Option) -> Self { + let mut make = Self(Command::new("make")); + match j { + Some(0) => {} + Some(j) => { + make.arg(format!("-j{j}")); + } + None => { + make.arg("-j"); + } + } + make + } +} diff --git a/zCore/Makefile b/zCore/Makefile index 7e718d95..c3e31fa0 100644 --- a/zCore/Makefile +++ b/zCore/Makefile @@ -227,7 +227,7 @@ endif ifeq ($(ARCH), x86_64) gdb := gdb -else +else gdb := riscv64-unknown-elf-gdb endif @@ -289,7 +289,7 @@ ifeq ($(PLATFORM), d1) run_d1: build $(OBJCOPY) ../prebuilt/firmware/d1/fw_payload.elf --strip-all -O binary ./zcore_d1.bin dd if=$(kernel_img) of=zcore_d1.bin bs=512 seek=2048 - xfel ddr ddr3 + xfel ddr d1 xfel write 0x40000000 zcore_d1.bin xfel exec 0x40000000 endif diff --git a/zCore/src/main.rs b/zCore/src/main.rs index 6733a877..a52c0928 100644 --- a/zCore/src/main.rs +++ b/zCore/src/main.rs @@ -59,7 +59,9 @@ fn primary_main(config: kernel_hal::KernelConfig) { #[cfg(not(feature = "libos"))] fn secondary_main() -> ! { - while !STARTED.load(Ordering::SeqCst) {} + while !STARTED.load(Ordering::SeqCst) { + core::hint::spin_loop(); + } // Don't print anything between previous line and next line. // Boot hart has initialized the UART chip, so we will use // UART for output instead of SBI, but the current HART is diff --git a/zCore/src/platform/riscv/boot_page_table.rs b/zCore/src/platform/riscv/boot_page_table.rs index 1f593086..750af629 100644 --- a/zCore/src/platform/riscv/boot_page_table.rs +++ b/zCore/src/platform/riscv/boot_page_table.rs @@ -50,8 +50,8 @@ impl BootPageTable { // 设置线程指针 asm!("mv tp, {}", in(reg) hartid); // 设置内核可访问用户页 - let sstatus: usize; - asm!("csrrsi {}, sstatus, 18", out(reg) sstatus); + let mut sstatus = 1usize << 18; + asm!("csrrs {0}, sstatus, {0}", inlateout(reg) sstatus); sstatus } diff --git a/zircon-syscall/src/channel.rs b/zircon-syscall/src/channel.rs index d21de162..ec838e09 100644 --- a/zircon-syscall/src/channel.rs +++ b/zircon-syscall/src/channel.rs @@ -234,15 +234,12 @@ impl Syscall<'_> { let mut ret: ZxResult = Ok(()); for disposition in dispositions.iter_mut() { if let Ok((object, src_rights)) = proc.get_dyn_object_and_rights(disposition.handle) { - match handle_check(disposition, &object, src_rights, handle) { - Err(e) => { - disposition.result = e as _; - if ret.is_ok() { - ret = Err(e); - } + if let Err(e) = handle_check(disposition, &object, src_rights, handle) { + disposition.result = e as _; + if ret.is_ok() { + ret = Err(e); } - Ok(()) => (), - }; + } let new_rights = if disposition.rights != Rights::SAME_RIGHTS.bits() { Rights::from_bits(disposition.rights).unwrap() } else {