From 66a8ffbc7a89956ce6cf828282846c718f0c7100 Mon Sep 17 00:00:00 2001 From: miiyakumo Date: Fri, 15 May 2026 23:05:05 +0800 Subject: [PATCH 1/4] =?UTF-8?q?refactor:=20=E6=B8=85=E7=90=86=E4=B8=8D?= =?UTF-8?q?=E5=BF=85=E8=A6=81=E7=9A=84=E5=AF=BC=E5=85=A5=E5=92=8C=E7=AE=80?= =?UTF-8?q?=E5=8C=96=E4=BB=A3=E7=A0=81=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- os/src/arch/memory_impl.rs | 10 +++++----- os/src/device/block/virtio_blk.rs | 1 - os/src/fs/proc/inode.rs | 8 ++++---- os/src/fs/tests/ext4/ext4_basic.rs | 1 - os/src/fs/tests/ext4/ext4_integration.rs | 1 - os/src/fs/tests/ext4/ext4_io.rs | 1 - os/src/fs/tests/ext4/mod.rs | 3 --- os/src/fs/tests/tmpfs/tmpfs_io.rs | 1 - os/src/fs/tests/tmpfs/tmpfs_metadata.rs | 4 ++-- os/src/kernel/boot.rs | 1 + os/src/kernel/cpu.rs | 1 - os/src/kernel/syscall/io.rs | 12 ++++++++---- os/src/kernel/task/exec_loader.rs | 6 +++--- os/src/mm/memory_space/space/tests.rs | 9 +-------- os/src/sync/raw_spin_lock.rs | 2 +- os/src/vfs/impls/mod.rs | 2 +- os/src/vfs/mod.rs | 2 +- os/src/vfs/tests/devno.rs | 1 - 18 files changed, 27 insertions(+), 39 deletions(-) diff --git a/os/src/arch/memory_impl.rs b/os/src/arch/memory_impl.rs index ede40a25..9ccbb448 100644 --- a/os/src/arch/memory_impl.rs +++ b/os/src/arch/memory_impl.rs @@ -11,17 +11,17 @@ macro_rules! impl_virtual_memory { ($process_type:ident, $kernel_type:ident) => { use alloc::vec::Vec; - use crate::arch::virtual_memory::{ - KernAddressSpace, PageFrame, PageInfo, PhysMemoryRegion, PtePermissions, - UserAddressSpace, VirtMemoryRegion, - }; - use crate::config::PAGE_SIZE; use crate::mm::address::{ ConvertablePA, PA, PageNum, Ppn, UsizeConvert, VA, Vpn, VpnRange, }; use crate::mm::memory_space::{MemorySpace, with_kernel_space}; use crate::mm::page_table::PageTableInner; use crate::mm::page_table::{PageSize, UniversalPTEFlag}; + use $crate::arch::virtual_memory::{ + KernAddressSpace, PageFrame, PageInfo, PhysMemoryRegion, PtePermissions, + UserAddressSpace, VirtMemoryRegion, + }; + use $crate::config::PAGE_SIZE; pub struct $process_type { #[allow(dead_code)] diff --git a/os/src/device/block/virtio_blk.rs b/os/src/device/block/virtio_blk.rs index 2643d250..55d91d95 100644 --- a/os/src/device/block/virtio_blk.rs +++ b/os/src/device/block/virtio_blk.rs @@ -155,7 +155,6 @@ mod tests { use super::*; use crate::device::BLK_DRIVERS; use crate::{kassert, test_case}; - use alloc::string::ToString; /// 通用校验:Driver 接口的基本行为 fn check_common_driver_behavior(d: &dyn Driver) { diff --git a/os/src/fs/proc/inode.rs b/os/src/fs/proc/inode.rs index e0337c14..78b87d4c 100644 --- a/os/src/fs/proc/inode.rs +++ b/os/src/fs/proc/inode.rs @@ -307,10 +307,10 @@ impl Inode for ProcInode { fn metadata(&self) -> Result { let mut meta = self.metadata.lock().clone(); // 对静态符号链接,返回目标路径长度;动态符号链接的 size 保持创建时的值(动态解析需要 task 上下文) - if meta.inode_type == InodeType::Symlink { - if let ProcInodeContent::Symlink(target) = &self.content { - meta.size = target.len(); - } + if meta.inode_type == InodeType::Symlink + && let ProcInodeContent::Symlink(target) = &self.content + { + meta.size = target.len(); } Ok(meta) } diff --git a/os/src/fs/tests/ext4/ext4_basic.rs b/os/src/fs/tests/ext4/ext4_basic.rs index 465e99bd..faa78fdd 100644 --- a/os/src/fs/tests/ext4/ext4_basic.rs +++ b/os/src/fs/tests/ext4/ext4_basic.rs @@ -2,7 +2,6 @@ use super::*; use crate::vfs::file_system::FileSystem; use crate::{kassert, test_case}; use alloc::vec; -use alloc::vec::Vec; // P0 核心功能测试 diff --git a/os/src/fs/tests/ext4/ext4_integration.rs b/os/src/fs/tests/ext4/ext4_integration.rs index f3867192..d3e39a81 100644 --- a/os/src/fs/tests/ext4/ext4_integration.rs +++ b/os/src/fs/tests/ext4/ext4_integration.rs @@ -1,6 +1,5 @@ use super::*; use crate::vfs::file_system::FileSystem; -use crate::vfs::inode::InodeType; use crate::{kassert, test_case}; use alloc::vec; diff --git a/os/src/fs/tests/ext4/ext4_io.rs b/os/src/fs/tests/ext4/ext4_io.rs index 6cd16533..fae39233 100644 --- a/os/src/fs/tests/ext4/ext4_io.rs +++ b/os/src/fs/tests/ext4/ext4_io.rs @@ -2,7 +2,6 @@ use super::*; use crate::vfs::file_system::FileSystem; use crate::{kassert, test_case}; use alloc::vec; -use alloc::vec::Vec; // P1 重要功能测试 diff --git a/os/src/fs/tests/ext4/mod.rs b/os/src/fs/tests/ext4/mod.rs index f9d1635d..64970eb9 100644 --- a/os/src/fs/tests/ext4/mod.rs +++ b/os/src/fs/tests/ext4/mod.rs @@ -6,7 +6,6 @@ use crate::vfs::dentry::{Dentry, DentryCache}; use crate::vfs::error::FsError; use crate::vfs::file_system::FileSystem; use crate::vfs::inode::{FileMode, Inode}; -use alloc::string::String; use alloc::sync::Arc; use lazy_static::lazy_static; @@ -34,8 +33,6 @@ fn get_ext4_image() -> &'static [u8] { /// # Returns /// RamDisk instance with valid ext4 filesystem pub fn create_test_ramdisk() -> Arc { - use crate::config::VIRTIO_BLK_SECTOR_SIZE; - // 使用 512 字节扇区大小,与 VirtIO 块设备保持一致 const SECTOR_SIZE: usize = 512; // Same as VIRTIO_BLK_SECTOR_SIZE const DEVICE_ID: usize = 0; diff --git a/os/src/fs/tests/tmpfs/tmpfs_io.rs b/os/src/fs/tests/tmpfs/tmpfs_io.rs index b62a2664..b4ed2a5f 100644 --- a/os/src/fs/tests/tmpfs/tmpfs_io.rs +++ b/os/src/fs/tests/tmpfs/tmpfs_io.rs @@ -3,7 +3,6 @@ use super::*; use crate::{kassert, test_case}; use alloc::vec; -use alloc::vec::Vec; test_case!(test_tmpfs_large_write, { let fs = create_test_tmpfs(); diff --git a/os/src/fs/tests/tmpfs/tmpfs_metadata.rs b/os/src/fs/tests/tmpfs/tmpfs_metadata.rs index 4779fae8..49a4189c 100644 --- a/os/src/fs/tests/tmpfs/tmpfs_metadata.rs +++ b/os/src/fs/tests/tmpfs/tmpfs_metadata.rs @@ -103,7 +103,7 @@ test_case!(test_tmpfs_metadata_timestamps_file, { let meta1 = file.metadata().unwrap(); let ctime1 = meta1.ctime; let mtime1 = meta1.mtime; - let atime1 = meta1.atime; + let _atime1 = meta1.atime; // 时间戳应该非零 kassert!(ctime1.tv_sec > 0 || ctime1.tv_nsec > 0); @@ -155,7 +155,7 @@ test_case!(test_tmpfs_metadata_nlinks, { kassert!(meta.nlinks >= 2); // . 和父目录 // 在目录中创建子目录 - let subdir = dir + let _subdir = dir .mkdir("subdir", FileMode::from_bits_truncate(0o755)) .unwrap(); let meta = dir.metadata().unwrap(); diff --git a/os/src/kernel/boot.rs b/os/src/kernel/boot.rs index f3d8b15f..7d8a0fa1 100644 --- a/os/src/kernel/boot.rs +++ b/os/src/kernel/boot.rs @@ -111,6 +111,7 @@ pub fn run_primary_boot(hartid: usize, ops: PrimaryBootOps) -> ! { /// /// 确保中断开启后持续等待中断,唤醒后立即重新等待。 /// 使用 `ArchImpl::halt()` 执行具体的 halt 指令(wfi / idle 0)。 +#[allow(clippy::never_loop)] pub fn idle_loop() -> ! { if !crate::arch::interrupts_enabled() { crate::arch::enable_interrupts(); diff --git a/os/src/kernel/cpu.rs b/os/src/kernel/cpu.rs index 1af916fb..1b987436 100644 --- a/os/src/kernel/cpu.rs +++ b/os/src/kernel/cpu.rs @@ -131,7 +131,6 @@ mod tests { /// 测试 cpu_id() 函数 test_case!(test_cpu_id, { - use crate::arch::ArchImpl; use crate::sync::PreemptGuard; let _guard = PreemptGuard::new(); diff --git a/os/src/kernel/syscall/io.rs b/os/src/kernel/syscall/io.rs index 641ee58a..489b1b0e 100644 --- a/os/src/kernel/syscall/io.rs +++ b/os/src/kernel/syscall/io.rs @@ -1,5 +1,9 @@ //! IO 相关的系统调用实现 +// set_len 后立即通过 copy_from_user / copy_from_user_mut 从用户空间填充数据, +// 在第一次读取前已完全初始化,符合安全语义。 +#![allow(clippy::uninit_vec)] + use crate::arch::Arch; use crate::kernel::current_task; use crate::uapi::errno::EFAULT; @@ -949,10 +953,10 @@ fn select_common( // 被唤醒后再推进一次网络栈,并分发 UDP crate::net::socket::poll_network_and_dispatch(); - if let Some(trigger) = timeout_trigger { - if crate::arch::get_time() >= trigger { - return 0; - } + if let Some(trigger) = timeout_trigger + && crate::arch::get_time() >= trigger + { + return 0; } } } diff --git a/os/src/kernel/task/exec_loader.rs b/os/src/kernel/task/exec_loader.rs index 884f0f53..3eeb0099 100644 --- a/os/src/kernel/task/exec_loader.rs +++ b/os/src/kernel/task/exec_loader.rs @@ -410,10 +410,10 @@ fn apply_static_pie_relocs( return Err(ExecImageError::InvalidElf); } let sym_addr = load_bias + dt_symtab + r_sym * dt_syment; - let st_value = space + + space .read_u64_at(sym_addr + 8) - .map_err(ExecImageError::Paging)? as usize; - st_value + .map_err(ExecImageError::Paging)? as usize } }; let value = resolve_relocation_value(kind, load_bias, symbol_value, r_addend); diff --git a/os/src/mm/memory_space/space/tests.rs b/os/src/mm/memory_space/space/tests.rs index a429f48d..51784b08 100644 --- a/os/src/mm/memory_space/space/tests.rs +++ b/os/src/mm/memory_space/space/tests.rs @@ -73,8 +73,6 @@ mod memory_space_tests { // 6. 测试 MMIO 地址翻译 - 使用独立的 MemorySpace 实例 test_case!(test_mmio_translation, { - use crate::arch::ArchImpl; - // 使用独立的 MemorySpace 实例,避免与其他测试或全局状态冲突 let mut ms = MemorySpace::new(); @@ -172,8 +170,6 @@ mod memory_space_tests { // 8. 测试动态添加 MMIO 映射 test_case!(test_dynamic_mmio_mapping, { - use crate::arch::ArchImpl; - let mut ms = MemorySpace::new(); // 尝试映射一个自定义的 MMIO 区域(使用未占用的地址) @@ -269,8 +265,6 @@ mod memory_space_tests { // 11. 测试 map_mmio 函数 - 冲突检测 test_case!(test_map_mmio_conflict, { - use crate::arch::ArchImpl; - let mut ms = MemorySpace::new(); // 使用一个合理的物理地址 @@ -445,9 +439,8 @@ mod memory_space_tests { // 16. 测试 mmap 文件映射基本功能 test_case!(test_mmap_file_basic, { use crate::fs::tmpfs::TmpFs; - use crate::uapi::mm::{MapFlags, ProtFlags}; + use crate::vfs::{File, FileMode, FileSystem}; - use alloc::sync::Arc; println!("Testing mmap file mapping basic functionality"); diff --git a/os/src/sync/raw_spin_lock.rs b/os/src/sync/raw_spin_lock.rs index 9c1ac90b..6a11abc8 100644 --- a/os/src/sync/raw_spin_lock.rs +++ b/os/src/sync/raw_spin_lock.rs @@ -193,7 +193,7 @@ mod tests { drop(guard1); let guard2 = lock.lock(); - let second_lock_failed = if lock.is_locked() { false } else { true }; + let second_lock_failed = !lock.is_locked(); kassert!(!second_lock_failed); drop(guard2); diff --git a/os/src/vfs/impls/mod.rs b/os/src/vfs/impls/mod.rs index 2979e331..582abb2c 100644 --- a/os/src/vfs/impls/mod.rs +++ b/os/src/vfs/impls/mod.rs @@ -8,4 +8,4 @@ pub use blk_dev_file::BlockDeviceFile; pub use char_dev_file::CharDeviceFile; pub use pipe_file::PipeFile; pub use reg_file::RegFile; -pub use stdio_file::{StderrFile, StdinFile, StdoutFile, create_stdio_files}; +pub use stdio_file::create_stdio_files; diff --git a/os/src/vfs/mod.rs b/os/src/vfs/mod.rs index 909939ff..86eed4f0 100644 --- a/os/src/vfs/mod.rs +++ b/os/src/vfs/mod.rs @@ -173,7 +173,7 @@ pub use impls::{PipeFile, RegFile, create_stdio_files}; pub use inode::{DirEntry, FileMode, Inode, InodeMetadata, InodeType}; pub use mount::{MOUNT_TABLE, MountFlags, get_root_dentry}; pub use path::{ - normalize_path, parse_path, split_path, vfs_lookup, vfs_lookup_from, vfs_lookup_no_follow, + normalize_path, split_path, vfs_lookup, vfs_lookup_from, vfs_lookup_no_follow, vfs_lookup_no_follow_from, }; diff --git a/os/src/vfs/tests/devno.rs b/os/src/vfs/tests/devno.rs index 42c05cf8..55333ae9 100644 --- a/os/src/vfs/tests/devno.rs +++ b/os/src/vfs/tests/devno.rs @@ -1,6 +1,5 @@ //! 设备号管理测试 -use super::*; use crate::vfs::{dev::*, devno::*}; use crate::{kassert, test_case}; From 960c7b8628bd47f0cc8480d5ef52d82b6aa39714 Mon Sep 17 00:00:00 2001 From: miiyakumo Date: Thu, 28 May 2026 00:42:58 +0800 Subject: [PATCH 2/4] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E6=9E=B6?= =?UTF-8?q?=E6=9E=84=E7=9B=B8=E5=85=B3=E4=BB=A3=E7=A0=81=EF=BC=8C=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E7=A1=AC=E4=BB=B6=E9=99=B7=E9=98=B1=E5=B8=A7=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E5=B9=B6=E7=AE=80=E5=8C=96=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- os/src/arch/arch.rs | 41 ++++++- os/src/arch/arch_impl.rs | 1 + os/src/arch/loongarch/trap/trap_frame.rs | 76 +++++++++++++ os/src/arch/mock/arch.rs | 1 + os/src/arch/mock/trap.rs | 76 +++++++++++++ os/src/arch/mod.rs | 103 +++++++++++++++++- os/src/arch/riscv/trap/trap_frame.rs | 76 +++++++++++++ os/src/device/irq/mod.rs | 2 +- os/src/ipc/signal.rs | 21 ++-- os/src/kernel/boot.rs | 6 +- os/src/kernel/syscall/signal.rs | 8 +- os/src/kernel/syscall/task/clone_ops.rs | 9 +- os/src/kernel/syscall/task/exec_ops.rs | 2 +- os/src/kernel/syscall/task/mod.rs | 2 +- os/src/kernel/task/ktask.rs | 9 +- os/src/kernel/task/mod.rs | 2 +- os/src/kernel/task/task_struct.rs | 7 +- os/src/mm/memory_space/space/address_space.rs | 2 +- os/src/sync/intr_guard.rs | 8 +- os/src/sync/raw_spin_lock.rs | 2 +- os/src/sync/rwlock.rs | 2 +- os/src/test/mod.rs | 10 +- os/src/uapi/signal.rs | 4 +- 23 files changed, 421 insertions(+), 49 deletions(-) diff --git a/os/src/arch/arch.rs b/os/src/arch/arch.rs index b0bf1950..df80b49b 100644 --- a/os/src/arch/arch.rs +++ b/os/src/arch/arch.rs @@ -8,7 +8,43 @@ //! 注意:此 trait 使用关联类型来避免直接引用内核数据结构, //! 确保架构层与内核其余部分的解耦。 -use crate::arch::{address::UA, cpu_ops::CpuOps, virtual_memory::VirtualMemory}; +use core::fmt::Debug; + +use crate::{ + arch::{address::UA, cpu_ops::CpuOps, task::ExecStackLayout, virtual_memory::VirtualMemory}, + kernel::syscall::syscall_frame::SyscallFrame, + uapi::signal::MContextT, +}; + +/// 架构陷阱帧的统一接口。 +pub trait HwTrapFrame: Copy + Debug + Send + Sync + SyscallFrame + 'static { + fn zero_init() -> Self; + fn set_kernel_trap_frame(&mut self, entry: usize, terminal: usize, kernel_sp: usize); + fn set_exec_trap_frame_from_layout( + &mut self, + entry: usize, + kernel_sp: usize, + layout: &ExecStackLayout, + ); + unsafe fn set_clone_trap_frame( + &mut self, + parent_frame: &Self, + kernel_sp: usize, + user_sp: usize, + ); + unsafe fn set_fork_trap_frame(&mut self, parent_frame: &Self); + fn get_sp(&self) -> usize; + fn set_sp(&mut self, val: usize); + fn set_a0(&mut self, val: usize); + fn set_a1(&mut self, val: usize); + fn set_a2(&mut self, val: usize); + fn set_ra(&mut self, val: usize); + fn set_sepc(&mut self, pc: usize); + fn get_sepc(&self) -> usize; + fn set_tls(&mut self, tls: usize); + fn to_mcontext(&self) -> MContextT; + fn restore_from_mcontext(&mut self, mcontext: &MContextT); +} /// 顶层架构抽象 trait。 /// @@ -25,6 +61,9 @@ pub trait Arch: CpuOps + VirtualMemory { /// 用户上下文类型(保存/恢复寄存器状态) type UserContext: Sized + Send + Sync + Clone; + /// 硬件陷阱帧类型。 + type TrapFrame: HwTrapFrame; + // ---- 进程 / 上下文切换 ---- /// 创建新的用户上下文(设置入口点和栈顶) diff --git a/os/src/arch/arch_impl.rs b/os/src/arch/arch_impl.rs index bf1615a0..1e10b015 100644 --- a/os/src/arch/arch_impl.rs +++ b/os/src/arch/arch_impl.rs @@ -31,6 +31,7 @@ macro_rules! impl_arch { impl $crate::arch::arch::Arch for $arch { type UserContext = kernel::context::Context; + type TrapFrame = trap::TrapFrame; fn new_user_context(entry_point: usize, stack_top: usize) -> Self::UserContext { let mut ctx = kernel::context::Context::zero_init(); diff --git a/os/src/arch/loongarch/trap/trap_frame.rs b/os/src/arch/loongarch/trap/trap_frame.rs index bf40e9c3..c238db29 100644 --- a/os/src/arch/loongarch/trap/trap_frame.rs +++ b/os/src/arch/loongarch/trap/trap_frame.rs @@ -293,3 +293,79 @@ impl crate::kernel::syscall::syscall_frame::SyscallFrame for TrapFrame { self.regs[4] = val; } } + +impl crate::arch::HwTrapFrame for TrapFrame { + fn zero_init() -> Self { + TrapFrame::zero_init() + } + + fn set_kernel_trap_frame(&mut self, entry: usize, terminal: usize, kernel_sp: usize) { + TrapFrame::set_kernel_trap_frame(self, entry, terminal, kernel_sp) + } + + fn set_exec_trap_frame_from_layout( + &mut self, + entry: usize, + kernel_sp: usize, + layout: &crate::arch::task::ExecStackLayout, + ) { + TrapFrame::set_exec_trap_frame_from_layout(self, entry, kernel_sp, layout) + } + + unsafe fn set_clone_trap_frame( + &mut self, + parent_frame: &Self, + kernel_sp: usize, + user_sp: usize, + ) { + unsafe { TrapFrame::set_clone_trap_frame(self, parent_frame, kernel_sp, user_sp) } + } + + unsafe fn set_fork_trap_frame(&mut self, parent_frame: &Self) { + unsafe { TrapFrame::set_fork_trap_frame(self, parent_frame) } + } + + fn get_sp(&self) -> usize { + TrapFrame::get_sp(self) + } + + fn set_sp(&mut self, val: usize) { + TrapFrame::set_sp(self, val) + } + + fn set_a0(&mut self, val: usize) { + TrapFrame::set_a0(self, val) + } + + fn set_a1(&mut self, val: usize) { + TrapFrame::set_a1(self, val) + } + + fn set_a2(&mut self, val: usize) { + TrapFrame::set_a2(self, val) + } + + fn set_ra(&mut self, val: usize) { + TrapFrame::set_ra(self, val) + } + + fn set_sepc(&mut self, pc: usize) { + TrapFrame::set_sepc(self, pc) + } + + fn get_sepc(&self) -> usize { + TrapFrame::get_sepc(self) + } + + fn set_tls(&mut self, tls: usize) { + TrapFrame::set_tls(self, tls) + } + + fn to_mcontext(&self) -> MContextT { + TrapFrame::to_mcontext(self) + } + + fn restore_from_mcontext(&mut self, mcontext: &MContextT) { + TrapFrame::restore_from_mcontext(self, mcontext) + } +} diff --git a/os/src/arch/mock/arch.rs b/os/src/arch/mock/arch.rs index 8d10658b..e4550c9e 100644 --- a/os/src/arch/mock/arch.rs +++ b/os/src/arch/mock/arch.rs @@ -204,6 +204,7 @@ mod mock_arch_impl { impl Arch for MockArch { type UserContext = MockUserContext; + type TrapFrame = crate::arch::mock::trap::TrapFrame; fn new_user_context(entry_point: usize, stack_top: usize) -> Self::UserContext { let mut ctx = MockUserContext::zero_init(); diff --git a/os/src/arch/mock/trap.rs b/os/src/arch/mock/trap.rs index 544f8e3e..20a92955 100644 --- a/os/src/arch/mock/trap.rs +++ b/os/src/arch/mock/trap.rs @@ -225,6 +225,82 @@ impl crate::kernel::syscall::syscall_frame::SyscallFrame for TrapFrame { } } +impl crate::arch::HwTrapFrame for TrapFrame { + fn zero_init() -> Self { + TrapFrame::zero_init() + } + + fn set_kernel_trap_frame(&mut self, entry: usize, terminal: usize, kernel_sp: usize) { + TrapFrame::set_kernel_trap_frame(self, entry, terminal, kernel_sp) + } + + fn set_exec_trap_frame_from_layout( + &mut self, + entry: usize, + kernel_sp: usize, + layout: &crate::arch::task::ExecStackLayout, + ) { + TrapFrame::set_exec_trap_frame_from_layout(self, entry, kernel_sp, layout) + } + + unsafe fn set_clone_trap_frame( + &mut self, + parent_frame: &Self, + kernel_sp: usize, + user_sp: usize, + ) { + unsafe { TrapFrame::set_clone_trap_frame(self, parent_frame, kernel_sp, user_sp) } + } + + unsafe fn set_fork_trap_frame(&mut self, parent_frame: &Self) { + unsafe { TrapFrame::set_fork_trap_frame(self, parent_frame) } + } + + fn get_sp(&self) -> usize { + TrapFrame::get_sp(self) + } + + fn set_sp(&mut self, val: usize) { + TrapFrame::set_sp(self, val) + } + + fn set_a0(&mut self, val: usize) { + TrapFrame::set_a0(self, val) + } + + fn set_a1(&mut self, val: usize) { + TrapFrame::set_a1(self, val) + } + + fn set_a2(&mut self, val: usize) { + TrapFrame::set_a2(self, val) + } + + fn set_ra(&mut self, val: usize) { + TrapFrame::set_ra(self, val) + } + + fn set_sepc(&mut self, pc: usize) { + TrapFrame::set_sepc(self, pc) + } + + fn get_sepc(&self) -> usize { + TrapFrame::get_sepc(self) + } + + fn set_tls(&mut self, tls: usize) { + TrapFrame::set_tls(self, tls) + } + + fn to_mcontext(&self) -> MContextT { + TrapFrame::to_mcontext(self) + } + + fn restore_from_mcontext(&mut self, mcontext: &MContextT) { + TrapFrame::restore_from_mcontext(self, mcontext) + } +} + pub struct SumGuard; impl SumGuard { pub fn new() -> Self { diff --git a/os/src/arch/mod.rs b/os/src/arch/mod.rs index 5f447b35..6071d2a7 100644 --- a/os/src/arch/mod.rs +++ b/os/src/arch/mod.rs @@ -20,7 +20,7 @@ pub mod plat; pub mod task; pub mod virtual_memory; -pub use arch::Arch; +pub use arch::{Arch, HwTrapFrame}; pub use cpu_ops::CpuOps; pub use plat::Platform; @@ -38,10 +38,18 @@ mod loongarch; mod riscv; #[cfg(target_arch = "loongarch64")] -pub use loongarch::*; +#[allow(unused_imports)] +pub use loongarch::{ + boot, compiler_builtins, constant, cpu_ops as target_cpu_ops, intr, ipi, kernel, lib, memory, + mm, platform, timer, trap, +}; #[cfg(target_arch = "riscv64")] -pub use riscv::*; +#[allow(unused_imports)] +pub use riscv::{ + boot, constant, cpu_ops as target_cpu_ops, intr, ipi, kernel, lib, memory, mm, platform, timer, + trap, +}; // ---- 非目标架构(宿主测试):Mock Stubs ---- @@ -49,8 +57,13 @@ pub use riscv::*; mod mock; #[cfg(not(any(target_arch = "riscv64", target_arch = "loongarch64")))] -pub use mock::*; +#[allow(unused_imports)] +pub use mock::{ + MockAddressSpace, MockArch, MockCpuOps, boot, constant, intr, ipi, kernel, lib, mm, platform, + timer, trap, +}; +pub type TrapFrame = ::TrapFrame; pub use constant::SUPERVISOR_EXTERNAL; // ---- ArchImpl 类型别名 ---- @@ -98,12 +111,37 @@ pub fn disable_interrupts() -> usize { ArchImpl::disable_interrupts() } +#[inline] +pub unsafe fn read_and_disable_interrupts() -> usize { + ArchImpl::disable_interrupts() +} + /// 恢复中断状态 #[inline] pub fn restore_interrupt_state(flags: usize) { ArchImpl::restore_interrupt_state(flags) } +#[inline] +pub unsafe fn restore_interrupts(flags: usize) { + ArchImpl::restore_interrupt_state(flags) +} + +#[inline] +pub fn interrupt_was_enabled(flags: usize) -> bool { + ArchImpl::interrupt_was_enabled(flags) +} + +#[inline] +pub fn are_interrupts_enabled() -> bool { + intr::are_interrupts_enabled() +} + +#[inline] +pub fn enable_irq(irq: usize) { + intr::enable_irq(irq) +} + /// 获取当前 CPU ID #[inline] pub fn cpu_id() -> usize { @@ -146,6 +184,63 @@ pub fn send_reschedule_ipi(target: usize) { ArchImpl::send_reschedule_ipi(target) } +#[inline] +pub unsafe fn restore_trap_frame(trap_frame: &TrapFrame) { + unsafe { trap::restore(trap_frame) } +} + +#[inline] +pub unsafe fn set_trap_frame_cpu_ptr(trap_frame_ptr: *mut TrapFrame, cpu_ptr: usize) { + unsafe { trap::set_trap_frame_cpu_ptr(trap_frame_ptr, cpu_ptr) } +} + +#[inline] +pub unsafe fn init_kernel_trap_frame( + trap_frame_ptr: *mut TrapFrame, + entry: usize, + terminal: usize, + kernel_sp: usize, +) { + unsafe { + core::ptr::write(trap_frame_ptr, ::zero_init()); + ::set_kernel_trap_frame( + &mut *trap_frame_ptr, + entry, + terminal, + kernel_sp, + ); + let cpu_ptr = { + let _guard = crate::sync::PreemptGuard::new(); + crate::kernel::current_cpu() as *const _ as usize + }; + set_trap_frame_cpu_ptr(trap_frame_ptr, cpu_ptr); + } +} + +#[inline] +pub fn sigreturn_trampoline_address() -> usize { + trap::sigreturn_trampoline_address() +} + +#[inline] +pub fn kernel_sigreturn_trampoline_bytes() -> &'static [u8] { + trap::kernel_sigreturn_trampoline_bytes() +} + +#[inline] +pub unsafe fn forkret_restore(tf_ptr: *mut TrapFrame, is_kernel_thread: bool) { + unsafe { kernel::task::forkret_restore(tf_ptr, is_kernel_thread) } +} + +#[inline] +pub unsafe fn prepare_user_restore( + tfp: *mut TrapFrame, + user_pc: address::VA, + user_sp: address::VA, +) { + unsafe { kernel::task::prepare_user_restore(tfp, user_pc, user_sp) } +} + /// 物理地址 → 虚拟地址(直接映射) #[inline] pub fn pa_to_va(pa: address::PA) -> address::VA { diff --git a/os/src/arch/riscv/trap/trap_frame.rs b/os/src/arch/riscv/trap/trap_frame.rs index ee16e5d1..90d24277 100644 --- a/os/src/arch/riscv/trap/trap_frame.rs +++ b/os/src/arch/riscv/trap/trap_frame.rs @@ -420,3 +420,79 @@ impl crate::kernel::syscall::syscall_frame::SyscallFrame for TrapFrame { self.x10_a0 = val; } } + +impl crate::arch::HwTrapFrame for TrapFrame { + fn zero_init() -> Self { + TrapFrame::zero_init() + } + + fn set_kernel_trap_frame(&mut self, entry: usize, terminal: usize, kernel_sp: usize) { + TrapFrame::set_kernel_trap_frame(self, entry, terminal, kernel_sp) + } + + fn set_exec_trap_frame_from_layout( + &mut self, + entry: usize, + kernel_sp: usize, + layout: &crate::arch::task::ExecStackLayout, + ) { + TrapFrame::set_exec_trap_frame_from_layout(self, entry, kernel_sp, layout) + } + + unsafe fn set_clone_trap_frame( + &mut self, + parent_frame: &Self, + kernel_sp: usize, + user_sp: usize, + ) { + unsafe { TrapFrame::set_clone_trap_frame(self, parent_frame, kernel_sp, user_sp) } + } + + unsafe fn set_fork_trap_frame(&mut self, parent_frame: &Self) { + unsafe { TrapFrame::set_fork_trap_frame(self, parent_frame) } + } + + fn get_sp(&self) -> usize { + TrapFrame::get_sp(self) + } + + fn set_sp(&mut self, val: usize) { + TrapFrame::set_sp(self, val) + } + + fn set_a0(&mut self, val: usize) { + TrapFrame::set_a0(self, val) + } + + fn set_a1(&mut self, val: usize) { + TrapFrame::set_a1(self, val) + } + + fn set_a2(&mut self, val: usize) { + TrapFrame::set_a2(self, val) + } + + fn set_ra(&mut self, val: usize) { + TrapFrame::set_ra(self, val) + } + + fn set_sepc(&mut self, pc: usize) { + TrapFrame::set_sepc(self, pc) + } + + fn get_sepc(&self) -> usize { + TrapFrame::get_sepc(self) + } + + fn set_tls(&mut self, tls: usize) { + TrapFrame::set_tls(self, tls) + } + + fn to_mcontext(&self) -> MContextT { + TrapFrame::to_mcontext(self) + } + + fn restore_from_mcontext(&mut self, mcontext: &MContextT) { + TrapFrame::restore_from_mcontext(self, mcontext) + } +} diff --git a/os/src/device/irq/mod.rs b/os/src/device/irq/mod.rs index fee4f4cb..690186c4 100644 --- a/os/src/device/irq/mod.rs +++ b/os/src/device/irq/mod.rs @@ -10,7 +10,7 @@ use alloc::{ pub mod plic; -use crate::{arch::intr::enable_irq, device::Driver}; +use crate::{arch::enable_irq, device::Driver}; /// 中断管理器结构体 pub struct IrqManager { diff --git a/os/src/ipc/signal.rs b/os/src/ipc/signal.rs index f9a34a18..fbe5cdcc 100644 --- a/os/src/ipc/signal.rs +++ b/os/src/ipc/signal.rs @@ -12,10 +12,7 @@ use bitflags::bitflags; use crate::{ - arch::{ - kernel::cpu, - trap::{TrapFrame, sigreturn_trampoline_address}, - }, + arch::{HwTrapFrame, TrapFrame}, kernel::{ SharedTask, TASK_MANAGER, TaskManagerTrait, TaskState, current_cpu, current_task, exit_process, exit_task, sleep_task, wake_up_task, yield_task, @@ -188,7 +185,7 @@ fn install_user_signal_trap_frame( ); // Linux ABI: build rt_sigframe { siginfo, ucontext } on the user stack. let frame_size = core::mem::size_of::(); - let mut sp = align_down(tf.get_sp(), 16); + let mut sp = align_down(::get_sp(tf), 16); sp = align_down(sp - frame_size, 16); let sig_info_addr = sp + core::mem::offset_of!(RtSigFrame, info); @@ -211,16 +208,16 @@ fn install_user_signal_trap_frame( let restorer = if sa_flags.contains(SaFlags::RESTORER) && !action.sa_restorer.is_null() { action.sa_restorer as usize } else { - sigreturn_trampoline_address() + crate::arch::sigreturn_trampoline_address() }; - tf.set_ra(restorer); + ::set_ra(tf, restorer); // 设置用户处理器入口 - tf.set_sepc(entry as usize); - tf.set_a0(sig_num); - tf.set_a1(sig_info_addr); - tf.set_a2(ucontext_addr); - tf.set_sp(sp); + ::set_sepc(tf, entry as usize); + ::set_a0(tf, sig_num); + ::set_a1(tf, sig_info_addr); + ::set_a2(tf, ucontext_addr); + ::set_sp(tf, sp); } } diff --git a/os/src/kernel/boot.rs b/os/src/kernel/boot.rs index 7d8a0fa1..2697dc79 100644 --- a/os/src/kernel/boot.rs +++ b/os/src/kernel/boot.rs @@ -181,7 +181,7 @@ pub fn rest_init() { .trap_frame_ptr .load(core::sync::atomic::Ordering::SeqCst); unsafe { - crate::arch::kernel::task::init_kernel_trap_frame( + crate::arch::init_kernel_trap_frame( task_frame, init as usize, 0, @@ -268,7 +268,7 @@ fn create_kthreadd() { .trap_frame_ptr .load(core::sync::atomic::Ordering::SeqCst); unsafe { - crate::arch::kernel::task::init_kernel_trap_frame( + crate::arch::init_kernel_trap_frame( task_frame, kthreadd as usize, 0, @@ -310,7 +310,7 @@ pub fn create_idle_task(cpu_id: usize, idle_fn: fn() -> !) -> crate::kernel::Sha .trap_frame_ptr .load(core::sync::atomic::Ordering::SeqCst); unsafe { - crate::arch::kernel::task::init_kernel_trap_frame( + crate::arch::init_kernel_trap_frame( task_frame, idle_fn as usize, 0, diff --git a/os/src/kernel/syscall/signal.rs b/os/src/kernel/syscall/signal.rs index 75b4f0b5..173db2ec 100644 --- a/os/src/kernel/syscall/signal.rs +++ b/os/src/kernel/syscall/signal.rs @@ -8,7 +8,7 @@ use core::{ use alloc::{sync::Arc, vec::Vec}; use crate::{ - arch::{timer::clock_freq, trap::restore}, + arch::{HwTrapFrame, TrapFrame, timer::clock_freq}, ipc::{create_siginfo_for_signal, do_sigpending}, kernel::{ SharedTask, TASK_MANAGER, TIMER_QUEUE, TaskManagerTrait, current_task, sleep_task_prepare, @@ -228,7 +228,7 @@ pub fn rt_sigreturn() -> ! { let tfp = current_task().lock().trap_frame_ptr.load(Ordering::SeqCst); let tf = unsafe { &mut *tfp }; // Linux ABI: SP points to rt_sigframe { siginfo, ucontext }. - let frame_addr = tf.get_sp(); + let frame_addr = ::get_sp(tf); let ucontext_addr = frame_addr + core::mem::offset_of!(RtSigFrame, uc); let ucontext: UContextT = unsafe { read_from_user(ucontext_addr as *const UContextT) }; @@ -239,8 +239,8 @@ pub fn rt_sigreturn() -> ! { t.blocked = SignalFlags::from_bits_truncate(ucontext.uc_sigmask as usize); } - tf.restore_from_mcontext(&ucontext.uc_mcontext); - unsafe { restore(tf) } + ::restore_from_mcontext(tf, &ucontext.uc_mcontext); + unsafe { crate::arch::restore_trap_frame(tf) } unreachable!("rt_sigreturn should not return"); } diff --git a/os/src/kernel/syscall/task/clone_ops.rs b/os/src/kernel/syscall/task/clone_ops.rs index dda34811..ea98d235 100644 --- a/os/src/kernel/syscall/task/clone_ops.rs +++ b/os/src/kernel/syscall/task/clone_ops.rs @@ -146,9 +146,14 @@ pub fn clone( let tf = child_task.trap_frame_ptr.load(Ordering::SeqCst); unsafe { - (*tf).set_clone_trap_frame(&*ptf, child_task.kstack_base.as_usize(), stack as usize); + ::set_clone_trap_frame( + &mut *tf, + &*ptf, + child_task.kstack_base.as_usize(), + stack as usize, + ); if requested_flags.contains(CloneFlags::SETTLS) { - (*tf).set_tls(tls as usize); + ::set_tls(&mut *tf, tls as usize); } } if requested_flags.contains(CloneFlags::CHILD_SETTID) { diff --git a/os/src/kernel/syscall/task/exec_ops.rs b/os/src/kernel/syscall/task/exec_ops.rs index 93d62714..0fdd0765 100644 --- a/os/src/kernel/syscall/task/exec_ops.rs +++ b/os/src/kernel/syscall/task/exec_ops.rs @@ -240,7 +240,7 @@ fn do_execve_switch( // SAFETY: tfp 指向的内存已经被分配且由当前任务拥有 // 直接按 trapframe 状态恢复并 sret 到用户态 unsafe { - restore(&*tfp); + crate::arch::restore_trap_frame(&*tfp); } -1 } diff --git a/os/src/kernel/syscall/task/mod.rs b/os/src/kernel/syscall/task/mod.rs index 56553c8d..05459fe4 100644 --- a/os/src/kernel/syscall/task/mod.rs +++ b/os/src/kernel/syscall/task/mod.rs @@ -9,9 +9,9 @@ use alloc::{string::ToString, sync::Arc, vec::Vec}; use crate::{ arch::{ + HwTrapFrame, TrapFrame, address::UA, timer::{clock_freq, get_time}, - trap::restore, }, ipc::{SignalHandlerTable, SignalPending, signal_pending}, kernel::{ diff --git a/os/src/kernel/task/ktask.rs b/os/src/kernel/task/ktask.rs index b26d4c3b..4e7d2e48 100644 --- a/os/src/kernel/task/ktask.rs +++ b/os/src/kernel/task/ktask.rs @@ -9,7 +9,6 @@ use alloc::string::ToString; use alloc::sync::Arc; use crate::{ - arch::{disable_interrupts, trap::restore}, kernel::{ TaskState, cpu::current_cpu, @@ -78,7 +77,7 @@ pub fn kthread_spawn(entry_point: fn()) -> u32 { let tf = task.trap_frame_ptr.load(Ordering::SeqCst); // SAFETY: 此时 trap_frame_tracker 已经分配完毕且不可变更,所有权在 task 中,指针有效 unsafe { - crate::arch::kernel::task::init_kernel_trap_frame( + crate::arch::init_kernel_trap_frame( tf, entry_point as usize, super::terminate_task as usize, @@ -185,7 +184,7 @@ pub fn kernel_execve(path: &str, argv: &[&str], envp: &[&str]) -> ! { // execve伪造进程上下文用的trapframe和当前进程的是同一个 // 这时候发生中断会破坏创建到一半/创建好的的上下文 // 不必显式恢复中断,它会在restore中由sret指令自动恢复 - disable_interrupts(); + crate::arch::disable_interrupts(); { let mut t = task.lock(); t.exe_path = Some(path.to_string()); @@ -207,7 +206,7 @@ pub fn kernel_execve(path: &str, argv: &[&str], envp: &[&str]) -> ! { let tfp = task.lock().trap_frame_ptr.load(Ordering::SeqCst); unsafe { - crate::arch::kernel::task::prepare_user_restore( + crate::arch::prepare_user_restore( tfp, prepared.initial_pc, prepared.user_sp_high, @@ -216,7 +215,7 @@ pub fn kernel_execve(path: &str, argv: &[&str], envp: &[&str]) -> ! { // SAFETY: tfp 指向的内存已经被分配且由当前任务拥有 // 直接按 trapframe 状态恢复并 sret 到用户态 unsafe { - restore(&*tfp); + crate::arch::restore_trap_frame(&*tfp); } unreachable!("kernel_execve: should not return"); } diff --git a/os/src/kernel/task/mod.rs b/os/src/kernel/task/mod.rs index 53c2bc69..c9cc19fb 100644 --- a/os/src/kernel/task/mod.rs +++ b/os/src/kernel/task/mod.rs @@ -59,7 +59,7 @@ pub(crate) fn forkret() { t.memory_space.is_none(), ) }; - unsafe { crate::arch::kernel::task::forkret_restore(tf_ptr, is_kernel_thread) }; + unsafe { crate::arch::forkret_restore(tf_ptr, is_kernel_thread) }; } /// 在任务结束时调用的函数 diff --git a/os/src/kernel/task/task_struct.rs b/os/src/kernel/task/task_struct.rs index 5360520a..ccadd6a6 100644 --- a/os/src/kernel/task/task_struct.rs +++ b/os/src/kernel/task/task_struct.rs @@ -8,8 +8,8 @@ use alloc::{string::String, sync::Arc, vec::Vec}; use crate::{ arch::{ + HwTrapFrame, TrapFrame, kernel::{context::Context, task::setup_exec_stack_layout}, - trap::TrapFrame, }, ipc::{SignalHandlerTable, SignalPending}, kernel::{ @@ -308,7 +308,8 @@ impl Task { unsafe { // 清零整个 TrapFrame,避免旧值泄漏到用户态 core::ptr::write_bytes(tf_ptr, 0, 1); - (*tf_ptr).set_exec_trap_frame_from_layout( + ::set_exec_trap_frame_from_layout( + &mut *tf_ptr, initial_pc.as_usize(), self.kstack_base.as_usize(), &stack_layout, @@ -317,7 +318,7 @@ impl Task { let _guard = crate::sync::PreemptGuard::new(); crate::kernel::current_cpu() as *const _ as usize }; - crate::arch::trap::set_trap_frame_cpu_ptr(tf_ptr, cpu_ptr); + crate::arch::set_trap_frame_cpu_ptr(tf_ptr, cpu_ptr); } } diff --git a/os/src/mm/memory_space/space/address_space.rs b/os/src/mm/memory_space/space/address_space.rs index a6d6c21d..4e3183c3 100644 --- a/os/src/mm/memory_space/space/address_space.rs +++ b/os/src/mm/memory_space/space/address_space.rs @@ -108,7 +108,7 @@ impl MemorySpace { return Ok(()); } - let code = crate::arch::trap::kernel_sigreturn_trampoline_bytes(); + let code = crate::arch::kernel_sigreturn_trampoline_bytes(); self.insert_framed_area( vpn_range, AreaType::UserMmap, diff --git a/os/src/sync/intr_guard.rs b/os/src/sync/intr_guard.rs index 03e119e0..cc021d16 100644 --- a/os/src/sync/intr_guard.rs +++ b/os/src/sync/intr_guard.rs @@ -97,7 +97,13 @@ impl Drop for IntrGuard { #[cfg(test)] mod tests { use super::*; - use crate::{arch::intr::*, kassert, println, test_case}; + use crate::{ + arch::{ + are_interrupts_enabled, enable_interrupts, read_and_disable_interrupts, + restore_interrupts, + }, + kassert, println, test_case, + }; test_case!(test_guard_disables_interrupts, { println!("Testing: test_guard_disables_interrupts"); diff --git a/os/src/sync/raw_spin_lock.rs b/os/src/sync/raw_spin_lock.rs index 6a11abc8..20089312 100644 --- a/os/src/sync/raw_spin_lock.rs +++ b/os/src/sync/raw_spin_lock.rs @@ -156,7 +156,7 @@ unsafe impl Sync for RawSpinLock {} mod tests { use super::*; use crate::{ - arch::intr::{are_interrupts_enabled, read_and_disable_interrupts, restore_interrupts}, + arch::{are_interrupts_enabled, read_and_disable_interrupts, restore_interrupts}, kassert, test_case, }; diff --git a/os/src/sync/rwlock.rs b/os/src/sync/rwlock.rs index fbdc5586..60b52ab8 100644 --- a/os/src/sync/rwlock.rs +++ b/os/src/sync/rwlock.rs @@ -190,7 +190,7 @@ unsafe impl Sync for RwLock {} #[cfg(test)] mod tests { use super::*; - use crate::{arch::intr::are_interrupts_enabled, kassert, test_case}; + use crate::{arch::are_interrupts_enabled, kassert, test_case}; test_case!(test_rwlock_read_basic, { let lock: RwLock = RwLock::new(42); diff --git a/os/src/test/mod.rs b/os/src/test/mod.rs index 201a140b..df9fe402 100644 --- a/os/src/test/mod.rs +++ b/os/src/test/mod.rs @@ -2,7 +2,7 @@ mod guard; pub mod macros; pub mod net_test; use crate::{ - arch::intr::{are_interrupts_enabled, disable_interrupts, enable_interrupts}, + arch::{are_interrupts_enabled, disable_interrupts, enable_interrupts}, earlyprintln, }; @@ -133,7 +133,7 @@ mod tests { // test_case!(verify_interrupt_environment, (Interrupt), { // // 在这个代码块内部,中断应该已经被宏自动启用了。 // // 我们断言这一点来验证宏的行为。 - // kassert!(crate::arch::intr::are_interrupts_enabled()); + // kassert!(crate::arch::are_interrupts_enabled()); // println!(" -> Assertion passed: Interrupts are enabled."); @@ -141,10 +141,10 @@ mod tests { // // 然后验证 RAII 守卫是否会在测试结束时恢复它们。 // println!(" -> Manually disabling interrupts for demonstration..."); // unsafe { - // crate::arch::intr::disable_interrupts(); + // crate::arch::disable_interrupts(); // } - // kassert!(!crate::arch::intr::are_interrupts_enabled()); + // kassert!(!crate::arch::are_interrupts_enabled()); // println!(" -> Assertion passed: Interrupts are now disabled manually."); // println!(" -> Leaving test block, the guard should now restore the state..."); @@ -155,7 +155,7 @@ mod tests { // test_case!(verify_interrupts_restored_after_test, { // // 默认情况下,我们的测试运行器是在中断禁用的环境下运行的。 // // 如果前一个测试的 RAII 守卫工作正常,那么中断现在应该是禁用的。 - // kassert!(!crate::arch::intr::are_interrupts_enabled()); + // kassert!(!crate::arch::are_interrupts_enabled()); // println!(" -> Assertion passed: Interrupts were correctly restored to disabled state."); // }); diff --git a/os/src/uapi/signal.rs b/os/src/uapi/signal.rs index 2ef20440..3ba98bc8 100644 --- a/os/src/uapi/signal.rs +++ b/os/src/uapi/signal.rs @@ -11,7 +11,7 @@ use core::{ use bitflags::bitflags; use crate::{ - arch::trap::TrapFrame, + arch::{HwTrapFrame, TrapFrame}, uapi::types::{ClockT, PidT, SigSetT, SizeT, UidT}, }; @@ -556,7 +556,7 @@ impl MContextT { /// 从 TrapFrame 创建 MContextT 实例 pub fn from_trap_frame(tf: &TrapFrame) -> Self { - tf.to_mcontext() + ::to_mcontext(tf) } } From 0cee387b46d47ab5e3ca5aa363b01489a3a18085 Mon Sep 17 00:00:00 2001 From: miiyakumo Date: Thu, 28 May 2026 01:01:21 +0800 Subject: [PATCH 3/4] =?UTF-8?q?refactor:=20=E7=BB=9F=E4=B8=80=E4=B8=AD?= =?UTF-8?q?=E6=96=AD=E5=A4=84=E7=90=86=E6=8E=A5=E5=8F=A3=EF=BC=8C=E7=AE=80?= =?UTF-8?q?=E5=8C=96=E4=B8=AD=E6=96=AD=E7=8A=B6=E6=80=81=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- os/src/arch/mod.rs | 2 +- os/src/sync/intr_guard.rs | 46 ++++++++++++++--------------- os/src/sync/raw_spin_lock.rs | 57 ++++++++++++++++-------------------- os/src/sync/rwlock.rs | 18 ++++++++---- 4 files changed, 62 insertions(+), 61 deletions(-) diff --git a/os/src/arch/mod.rs b/os/src/arch/mod.rs index 6071d2a7..6102ac2d 100644 --- a/os/src/arch/mod.rs +++ b/os/src/arch/mod.rs @@ -134,7 +134,7 @@ pub fn interrupt_was_enabled(flags: usize) -> bool { #[inline] pub fn are_interrupts_enabled() -> bool { - intr::are_interrupts_enabled() + ArchImpl::interrupts_enabled() } #[inline] diff --git a/os/src/sync/intr_guard.rs b/os/src/sync/intr_guard.rs index cc021d16..0a851daf 100644 --- a/os/src/sync/intr_guard.rs +++ b/os/src/sync/intr_guard.rs @@ -98,70 +98,70 @@ impl Drop for IntrGuard { mod tests { use super::*; use crate::{ - arch::{ - are_interrupts_enabled, enable_interrupts, read_and_disable_interrupts, - restore_interrupts, - }, + arch::{ArchImpl, CpuOps}, kassert, println, test_case, }; test_case!(test_guard_disables_interrupts, { println!("Testing: test_guard_disables_interrupts"); - unsafe { enable_interrupts() }; - kassert!(are_interrupts_enabled()); + let initial_flags = ArchImpl::disable_interrupts(); + ArchImpl::enable_interrupts(); + kassert!(ArchImpl::interrupts_enabled()); let guard = IntrGuard::::new(); kassert!(guard.was_enabled()); - kassert!(!are_interrupts_enabled()); + kassert!(!ArchImpl::interrupts_enabled()); drop(guard); - kassert!(are_interrupts_enabled()); + kassert!(ArchImpl::interrupts_enabled()); + + ArchImpl::restore_interrupt_state(initial_flags); }); test_case!(test_guard_restores_on_drop, { println!("Testing: test_guard_restores_on_drop"); - let initial_flags: usize = { - let flags = unsafe { read_and_disable_interrupts() }; - unsafe { enable_interrupts() }; - flags - }; + let initial_flags = ArchImpl::disable_interrupts(); + ArchImpl::enable_interrupts(); - kassert!(are_interrupts_enabled()); + kassert!(ArchImpl::interrupts_enabled()); { let guard = IntrGuard::::new(); - kassert!(!are_interrupts_enabled()); + kassert!(!ArchImpl::interrupts_enabled()); kassert!(guard.was_enabled()); } - kassert!(are_interrupts_enabled()); + kassert!(ArchImpl::interrupts_enabled()); - unsafe { restore_interrupts(initial_flags) }; + ArchImpl::restore_interrupt_state(initial_flags); }); test_case!(test_nested_intr_guard, { println!("Testing: test_nested_intr_guard"); - unsafe { enable_interrupts() }; - kassert!(are_interrupts_enabled()); + let initial_flags = ArchImpl::disable_interrupts(); + ArchImpl::enable_interrupts(); + kassert!(ArchImpl::interrupts_enabled()); { let outer = IntrGuard::::new(); - kassert!(!are_interrupts_enabled()); + kassert!(!ArchImpl::interrupts_enabled()); kassert!(outer.was_enabled()); { let inner = IntrGuard::::new(); - kassert!(!are_interrupts_enabled()); + kassert!(!ArchImpl::interrupts_enabled()); // 内层守卫: 进入时中断已禁用, 所以 was_enabled 应该是 false kassert!(!inner.was_enabled()); } // 内层 drop 后中断仍应禁用 (因为外层还持有) - kassert!(!are_interrupts_enabled()); + kassert!(!ArchImpl::interrupts_enabled()); } // 外层 drop 后中断应恢复 - kassert!(are_interrupts_enabled()); + kassert!(ArchImpl::interrupts_enabled()); + + ArchImpl::restore_interrupt_state(initial_flags); }); } diff --git a/os/src/sync/raw_spin_lock.rs b/os/src/sync/raw_spin_lock.rs index 20089312..9fa797e6 100644 --- a/os/src/sync/raw_spin_lock.rs +++ b/os/src/sync/raw_spin_lock.rs @@ -40,12 +40,7 @@ impl RawSpinLock { } } - /// 尝试获取自旋锁,并返回一个 RAII 保护器。 - /// - /// 内部原子地获取锁,并在当前 CPU 禁用本地中断。 - pub fn lock(&self) -> RawSpinLockGuard<'_, CPU> { - let guard = IntrGuard::::new(); - + fn acquire(&self) { while self .lock .compare_exchange_weak(false, true, Ordering::Acquire, Ordering::Relaxed) @@ -53,6 +48,20 @@ impl RawSpinLock { { hint::spin_loop(); } + } + + fn try_acquire(&self) -> bool { + self.lock + .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) + .is_ok() + } + + /// 尝试获取自旋锁,并返回一个 RAII 保护器。 + /// + /// 内部原子地获取锁,并在当前 CPU 禁用本地中断。 + pub fn lock(&self) -> RawSpinLockGuard<'_, CPU> { + let guard = IntrGuard::::new(); + self.acquire(); RawSpinLockGuard { lock: self, @@ -66,11 +75,7 @@ impl RawSpinLock { pub fn try_lock(&self) -> Option> { let guard = IntrGuard::::new(); - if self - .lock - .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) - .is_ok() - { + if self.try_acquire() { Some(RawSpinLockGuard { lock: self, intr_guard: guard, @@ -114,26 +119,14 @@ unsafe impl lock_api::RawMutex for RawSpinLock { fn lock(&self) { let flags = CPU::disable_interrupts(); - - while self - .lock - .compare_exchange_weak(false, true, Ordering::Acquire, Ordering::Relaxed) - .is_err() - { - core::hint::spin_loop(); - } - + self.acquire(); self.saved_intr_flags.store(flags, Ordering::Release); } fn try_lock(&self) -> bool { let flags = CPU::disable_interrupts(); - if self - .lock - .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) - .is_ok() - { + if self.try_acquire() { self.saved_intr_flags.store(flags, Ordering::Release); true } else { @@ -156,7 +149,7 @@ unsafe impl Sync for RawSpinLock {} mod tests { use super::*; use crate::{ - arch::{are_interrupts_enabled, read_and_disable_interrupts, restore_interrupts}, + arch::{ArchImpl, CpuOps}, kassert, test_case, }; @@ -200,19 +193,19 @@ mod tests { }); test_case!(test_interrupt_disable, { - let initial_flags = unsafe { read_and_disable_interrupts() }; - unsafe { restore_interrupts(initial_flags | (1 << 1)) }; - kassert!(are_interrupts_enabled()); + let initial_flags = ArchImpl::disable_interrupts(); + ArchImpl::enable_interrupts(); + kassert!(ArchImpl::interrupts_enabled()); let lock = RawSpinLock::::new(); let guard = lock.lock(); - kassert!(!are_interrupts_enabled()); + kassert!(!ArchImpl::interrupts_enabled()); kassert!(guard.intr_guard.was_enabled()); drop(guard); - kassert!(are_interrupts_enabled()); + kassert!(ArchImpl::interrupts_enabled()); - unsafe { restore_interrupts(initial_flags) }; + ArchImpl::restore_interrupt_state(initial_flags); }); } diff --git a/os/src/sync/rwlock.rs b/os/src/sync/rwlock.rs index 60b52ab8..b774cba2 100644 --- a/os/src/sync/rwlock.rs +++ b/os/src/sync/rwlock.rs @@ -190,7 +190,10 @@ unsafe impl Sync for RwLock {} #[cfg(test)] mod tests { use super::*; - use crate::{arch::are_interrupts_enabled, kassert, test_case}; + use crate::{ + arch::{ArchImpl, CpuOps}, + kassert, test_case, + }; test_case!(test_rwlock_read_basic, { let lock: RwLock = RwLock::new(42); @@ -263,17 +266,22 @@ mod tests { }); test_case!(test_rwlock_interrupt_disable, { + let initial_flags = ArchImpl::disable_interrupts(); + ArchImpl::enable_interrupts(); + let lock: RwLock = RwLock::new(0); let guard = lock.read(); - kassert!(!are_interrupts_enabled()); + kassert!(!ArchImpl::interrupts_enabled()); drop(guard); - kassert!(are_interrupts_enabled()); + kassert!(ArchImpl::interrupts_enabled()); let guard = lock.write(); - kassert!(!are_interrupts_enabled()); + kassert!(!ArchImpl::interrupts_enabled()); drop(guard); - kassert!(are_interrupts_enabled()); + kassert!(ArchImpl::interrupts_enabled()); + + ArchImpl::restore_interrupt_state(initial_flags); }); test_case!(test_rwlock_try_read, { From 4ae20894ff652b0d69e4c03625e5f849c42dd190 Mon Sep 17 00:00:00 2001 From: miiyakumo Date: Thu, 28 May 2026 02:00:15 +0800 Subject: [PATCH 4/4] Refactor console output handling and improve error reporting - Replace earlyprintln! macro with emergency_println! for better error handling in trap handlers. - Update console_putchar to accept u8 instead of usize for consistency across architectures. - Modify RISC-V boot and trap handlers to use println! instead of earlyprintln!. - Introduce a BootConsoleBuffer to temporarily store console output during early boot before switching to runtime console. - Enhance the Console trait to include a write_bytes method for raw byte output. - Update various modules to utilize the new println! macro for logging and error messages. - Remove deprecated print and println macros from stdio.rs to streamline output handling. - Ensure that panic messages are printed using the new emergency_print method. --- os/src/arch/arch_impl.rs | 2 +- os/src/arch/loongarch/constant.rs | 3 + os/src/arch/loongarch/lib.rs | 12 +- os/src/arch/loongarch/timer.rs | 6 +- os/src/arch/loongarch/trap/trap_handler.rs | 23 ++-- os/src/arch/mock/lib.rs | 2 +- os/src/arch/riscv/boot/mod.rs | 5 +- os/src/arch/riscv/lib.rs | 4 +- os/src/arch/riscv/trap/trap_handler.rs | 145 +++++++++++---------- os/src/console.rs | 135 +++++++++++++------ os/src/device/console/mod.rs | 14 +- os/src/device/console/uart_console.rs | 4 + os/src/kernel/boot.rs | 7 +- os/src/kernel/task/ktask.rs | 6 +- os/src/log/log_core.rs | 26 ++++ os/src/log/mod.rs | 9 ++ os/src/main.rs | 8 +- os/src/mm/global_allocator/talc_alloc.rs | 6 +- os/src/mm/mod.rs | 3 +- os/src/net/config.rs | 33 +++-- os/src/test/mod.rs | 33 +++-- os/src/util/stdio.rs | 76 +---------- 22 files changed, 298 insertions(+), 264 deletions(-) diff --git a/os/src/arch/arch_impl.rs b/os/src/arch/arch_impl.rs index 1e10b015..d96aeec7 100644 --- a/os/src/arch/arch_impl.rs +++ b/os/src/arch/arch_impl.rs @@ -189,7 +189,7 @@ macro_rules! impl_platform { ($arch:ty) => { impl $crate::arch::plat::Platform for $arch { fn console_putchar(c: u8) { - lib::console_putchar(c as usize); + lib::console_putchar(c); } fn console_getchar() -> Option { diff --git a/os/src/arch/loongarch/constant.rs b/os/src/arch/loongarch/constant.rs index cbfc3676..f42d4b7e 100644 --- a/os/src/arch/loongarch/constant.rs +++ b/os/src/arch/loongarch/constant.rs @@ -17,6 +17,9 @@ pub const USER_BASE: usize = 0x0000_0000_0000_0000; pub const USER_TOP: usize = 0x0000_003f_ffff_ffff; pub const KERNEL_BASE: usize = 0x9000_0000_0000_0000; +/// Direct mapped uncached window for MMIO. +pub const DMW0_BASE: usize = 0x8000_0000_0000_0000; + /// 兼容 RISC-V 的地址空间常量 /// 用于与架构无关代码的兼容 pub const SV39_TOP_HALF_TOP: usize = 0xffff_ffff_ffff_ffff; diff --git a/os/src/arch/loongarch/lib.rs b/os/src/arch/loongarch/lib.rs index 3aa75e2d..5ed4cef4 100644 --- a/os/src/arch/loongarch/lib.rs +++ b/os/src/arch/loongarch/lib.rs @@ -6,19 +6,19 @@ //! 兼容性别名 `sbi` 模块用于共享代码调用路径的过渡, //! 待 HAL trait 覆盖这些功能后可移除。 -use super::platform::UART_BASE; +use super::{constant::DMW0_BASE, platform::UART_BASE}; /// 通过 DMW0 映射的 UART 虚拟地址 /// DMW0: 0x8000_xxxx_xxxx_xxxx -> 物理地址 (uncached, 用于 MMIO) -const UART_VADDR: usize = UART_BASE | 0x8000_0000_0000_0000; +const UART_VADDR: usize = UART_BASE | DMW0_BASE; /// 输出字符到控制台 -pub fn console_putchar(c: usize) { +pub fn console_putchar(c: u8) { unsafe { // 等待 UART 发送缓冲区空闲 (LSR bit 5) let ptr = UART_VADDR as *mut u8; while ptr.add(5).read_volatile() & (1 << 5) == 0 {} - ptr.write_volatile(c as u8); + ptr.write_volatile(c); } } @@ -51,7 +51,7 @@ const ACPI_GED_VALUE_REBOOT: u8 = 0x42; // reboot { value = <0x42> } /// 关机实现 pub fn shutdown(_failure: bool) -> ! { // 映射到 LoongArch 的虚地址 (DMW0: 0x8000...) - let base_vaddr = VIRT_GED_REG_ADDR | 0x8000_0000_0000_0000; + let base_vaddr = VIRT_GED_REG_ADDR | DMW0_BASE; unsafe { let ptr = base_vaddr as *mut u8; @@ -77,7 +77,7 @@ pub fn shutdown(_failure: bool) -> ! { /// 重启实现 pub fn restart() -> ! { - let base_vaddr = VIRT_GED_REG_ADDR | 0x8000_0000_0000_0000; + let base_vaddr = VIRT_GED_REG_ADDR | DMW0_BASE; unsafe { let ptr = base_vaddr as *mut u8; diff --git a/os/src/arch/loongarch/timer.rs b/os/src/arch/loongarch/timer.rs index 12a61d5a..2bd769a1 100644 --- a/os/src/arch/loongarch/timer.rs +++ b/os/src/arch/loongarch/timer.rs @@ -2,7 +2,7 @@ use core::sync::atomic::{AtomicUsize, Ordering}; -use crate::{arch::intr::enable_timer_interrupt, earlyprintln}; +use crate::arch::intr::enable_timer_interrupt; /// 定时器滴答计数 pub static TIMER_TICKS: AtomicUsize = AtomicUsize::new(0); @@ -19,10 +19,10 @@ const CSR_TICLR: u32 = 0x44; /// 初始化定时器 pub fn init() { - earlyprintln!("[Timer] Initializing timer"); + crate::println!("[Timer] Initializing timer"); // 允许外部在平台层设置真实频率;此处仅开启本地定时器中断 unsafe { enable_timer_interrupt() }; - earlyprintln!("[Timer] Timer interrupt enabled"); + crate::println!("[Timer] Timer interrupt enabled"); set_next_trigger(); } diff --git a/os/src/arch/loongarch/trap/trap_handler.rs b/os/src/arch/loongarch/trap/trap_handler.rs index c3915f28..039a1629 100644 --- a/os/src/arch/loongarch/trap/trap_handler.rs +++ b/os/src/arch/loongarch/trap/trap_handler.rs @@ -9,13 +9,18 @@ use crate::arch::timer::{ TIMER_TICKS, ack_timer_interrupt, clock_freq, get_time, set_next_trigger, }; use crate::arch::trap::restore; -use crate::earlyprintln; use crate::ipc::check_signal; use crate::kernel::syscall::dispatch::dispatch_syscall; use crate::kernel::{TIMER, TIMER_QUEUE, schedule, send_signal_process, wake_up_task}; use super::TrapFrame; +macro_rules! emergency_println { + ($fmt: literal $(, $($arg: tt)+)?) => { + crate::console::emergency_print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?)) + }; +} + /// 仅在单核环境下使用的默认 TrapFrame;后续可由调度器替换为 per-CPU/任务帧 #[unsafe(no_mangle)] pub static mut BOOT_TRAP_FRAME: TrapFrame = TrapFrame::empty(); @@ -237,14 +242,14 @@ fn user_panic(estat: usize, era: usize, trap_frame: &TrapFrame) { core::arch::asm!("csrrd {0}, {csr}", out(reg) badv, csr = const CSR_BADV, options(nostack, preserves_flags)); core::arch::asm!("csrrd {0}, {csr}", out(reg) badi, csr = const CSR_BADI, options(nostack, preserves_flags)); } - earlyprintln!("\n==============================================="); - earlyprintln!(" UNEXPECTED TRAP IN USER MODE (PLV>0)"); - earlyprintln!("==============================================="); - earlyprintln!("estat: {:#x}", estat); - earlyprintln!("era : {:#x}", era); - earlyprintln!("badv : {:#x}", badv); - earlyprintln!("badi : {:#x}", badi); - earlyprintln!("regs : {:#x?}", trap_frame.regs); + emergency_println!("\n==============================================="); + emergency_println!(" UNEXPECTED TRAP IN USER MODE (PLV>0)"); + emergency_println!("==============================================="); + emergency_println!("estat: {:#x}", estat); + emergency_println!("era : {:#x}", era); + emergency_println!("badv : {:#x}", badv); + emergency_println!("badi : {:#x}", badi); + emergency_println!("regs : {:#x?}", trap_frame.regs); panic!( "Unexpected trap in user mode: estat={:#x}, era={:#x}, badv={:#x}, badi={:#x}", estat, era, badv, badi diff --git a/os/src/arch/mock/lib.rs b/os/src/arch/mock/lib.rs index 8a937b58..2a1e015a 100644 --- a/os/src/arch/mock/lib.rs +++ b/os/src/arch/mock/lib.rs @@ -10,7 +10,7 @@ pub fn restart() -> ! { } } -pub fn console_putchar(_c: usize) {} +pub fn console_putchar(_c: u8) {} pub fn console_getchar() -> usize { usize::MAX diff --git a/os/src/arch/riscv/boot/mod.rs b/os/src/arch/riscv/boot/mod.rs index 5392bb84..0b9a37ed 100644 --- a/os/src/arch/riscv/boot/mod.rs +++ b/os/src/arch/riscv/boot/mod.rs @@ -8,7 +8,6 @@ global_asm!(include_str!("entry.S")); use crate::mm::address::UsizeConvert; use crate::{ arch::{timer, trap}, - earlyprintln, kernel::{self, NUM_CPU, current_cpu}, pr_debug, pr_err, pr_info, pr_warn, sync::PreemptGuard, @@ -25,7 +24,7 @@ unsafe extern "C" { /// 从核调试入口 #[unsafe(no_mangle)] pub extern "C" fn secondary_debug_entry(hartid: usize) { - crate::earlyprintln!("[DEBUG] Hart {} reached secondary_wait_high", hartid); + crate::println!("[DEBUG] Hart {} reached secondary_wait_high", hartid); } /// RISC-V 主核启动入口 @@ -53,7 +52,7 @@ fn setup_boot_cpu(_hartid: usize) { unsafe { core::arch::asm!("mv tp, {}", in(reg) cpu_ptr); } - earlyprintln!("[Boot] Initialized CPUS, tp = 0x{:x}", cpu_ptr); + crate::println!("[Boot] Initialized CPUS, tp = 0x{:x}", cpu_ptr); } } diff --git a/os/src/arch/riscv/lib.rs b/os/src/arch/riscv/lib.rs index eae09379..36e73ee9 100644 --- a/os/src/arch/riscv/lib.rs +++ b/os/src/arch/riscv/lib.rs @@ -1,7 +1,7 @@ /// use sbi call to putchar to console (qemu uart handler) -pub fn console_putchar(c: usize) { +pub fn console_putchar(c: u8) { #[allow(deprecated)] - sbi_rt::legacy::console_putchar(c); + sbi_rt::legacy::console_putchar(c as usize); } /// 使用 sbi 调用从控制台获取字符(qemu uart handler) diff --git a/os/src/arch/riscv/trap/trap_handler.rs b/os/src/arch/riscv/trap/trap_handler.rs index 5036ece4..8e6d92ac 100644 --- a/os/src/arch/riscv/trap/trap_handler.rs +++ b/os/src/arch/riscv/trap/trap_handler.rs @@ -4,7 +4,6 @@ use core::sync::atomic::Ordering; -use crate::earlyprintln; use crate::ipc::check_signal; use riscv::register::scause::{self, Trap}; use riscv::register::sstatus::SPP; @@ -17,6 +16,12 @@ use crate::device::IRQ_MANAGER; use crate::kernel::syscall::dispatch::dispatch_syscall; use crate::kernel::{TIMER, TIMER_QUEUE, schedule, send_signal_process, wake_up_task}; +macro_rules! emergency_println { + ($fmt: literal $(, $($arg: tt)+)?) => { + crate::console::emergency_print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?)) + }; +} + /// 陷阱处理程序 /// 从中断处理入口跳转到这里时, /// 陷阱帧的地址(sp)被隐式地作为参数 a0 传递给了 trap_handler 函数。 @@ -103,138 +108,138 @@ pub fn user_trap( let sscratch_val = sscratch::read(); // 打印详细的异常信息 - crate::earlyprintln!("\n"); - crate::earlyprintln!("==============================================="); - crate::earlyprintln!(" UNEXPECTED TRAP IN USER MODE (U-Mode)"); - crate::earlyprintln!("==============================================="); - crate::earlyprintln!(""); - crate::earlyprintln!("[!] Exception Type:"); - crate::earlyprintln!(" Trap: {:?}", scause.cause()); - crate::earlyprintln!(" Raw scause: {:#x}", scause_val); - crate::earlyprintln!(""); - crate::earlyprintln!("[!] Exception Location:"); - crate::earlyprintln!(" sepc (fault PC): {:#x}", sepc_old); - crate::earlyprintln!(" stval (fault VA): {:#x}", stval_val); - crate::earlyprintln!(""); - crate::earlyprintln!("[!] Register State:"); - crate::earlyprintln!(" sstatus: {:#x}", sstatus_old.bits()); - crate::earlyprintln!(" sscratch: {:#x}", sscratch_val); - crate::earlyprintln!(""); - crate::earlyprintln!("[!] TrapFrame Details:"); - crate::earlyprintln!(" Stack Pointers:"); - crate::earlyprintln!(" x2_sp (user stack): {:#x} <===", trap_frame.x2_sp); - crate::earlyprintln!(" kernel_sp: {:#x}", trap_frame.kernel_sp); - crate::earlyprintln!(""); - crate::earlyprintln!(" General Registers:"); - crate::earlyprintln!( + emergency_println!("\n"); + emergency_println!("==============================================="); + emergency_println!(" UNEXPECTED TRAP IN USER MODE (U-Mode)"); + emergency_println!("==============================================="); + emergency_println!(""); + emergency_println!("[!] Exception Type:"); + emergency_println!(" Trap: {:?}", scause.cause()); + emergency_println!(" Raw scause: {:#x}", scause_val); + emergency_println!(""); + emergency_println!("[!] Exception Location:"); + emergency_println!(" sepc (fault PC): {:#x}", sepc_old); + emergency_println!(" stval (fault VA): {:#x}", stval_val); + emergency_println!(""); + emergency_println!("[!] Register State:"); + emergency_println!(" sstatus: {:#x}", sstatus_old.bits()); + emergency_println!(" sscratch: {:#x}", sscratch_val); + emergency_println!(""); + emergency_println!("[!] TrapFrame Details:"); + emergency_println!(" Stack Pointers:"); + emergency_println!(" x2_sp (user stack): {:#x} <===", trap_frame.x2_sp); + emergency_println!(" kernel_sp: {:#x}", trap_frame.kernel_sp); + emergency_println!(""); + emergency_println!(" General Registers:"); + emergency_println!( " x1_ra: {:#x} x3_gp: {:#x} x4_tp: {:#x}", trap_frame.x1_ra, trap_frame.x3_gp, trap_frame.x4_tp ); - crate::earlyprintln!( + emergency_println!( " x5_t0: {:#x} x6_t1: {:#x} x7_t2: {:#x}", trap_frame.x5_t0, trap_frame.x6_t1, trap_frame.x7_t2 ); - crate::earlyprintln!(""); - crate::earlyprintln!(" Argument Registers:"); - crate::earlyprintln!( + emergency_println!(""); + emergency_println!(" Argument Registers:"); + emergency_println!( " x10_a0: {:#x} x11_a1: {:#x} x12_a2: {:#x}", trap_frame.x10_a0, trap_frame.x11_a1, trap_frame.x12_a2 ); - crate::earlyprintln!( + emergency_println!( " x13_a3: {:#x} x14_a4: {:#x} x15_a5: {:#x}", trap_frame.x13_a3, trap_frame.x14_a4, trap_frame.x15_a5 ); - crate::earlyprintln!( + emergency_println!( " x16_a6: {:#x} x17_a7: {:#x}", trap_frame.x16_a6, trap_frame.x17_a7 ); - crate::earlyprintln!(""); - crate::earlyprintln!(" Saved Registers:"); - crate::earlyprintln!( + emergency_println!(""); + emergency_println!(" Saved Registers:"); + emergency_println!( " x8_s0: {:#x} x9_s1: {:#x}", trap_frame.x8_s0, trap_frame.x9_s1 ); - crate::earlyprintln!( + emergency_println!( " x18_s2: {:#x} x19_s3: {:#x}", trap_frame.x18_s2, trap_frame.x19_s3 ); - crate::earlyprintln!(""); + emergency_println!(""); // 解释常见的异常类型 - crate::earlyprintln!("[!] Exception Explanation:"); + emergency_println!("[!] Exception Explanation:"); match scause.cause() { Trap::Exception(0) => { - crate::earlyprintln!(" Instruction Address Misaligned"); - crate::earlyprintln!(" -> PC address {:#x} is not 2-byte aligned", sepc_old); + emergency_println!(" Instruction Address Misaligned"); + emergency_println!(" -> PC address {:#x} is not 2-byte aligned", sepc_old); } Trap::Exception(1) => { - crate::earlyprintln!(" Instruction Access Fault"); - crate::earlyprintln!(" -> Cannot fetch instruction from {:#x}", sepc_old); + emergency_println!(" Instruction Access Fault"); + emergency_println!(" -> Cannot fetch instruction from {:#x}", sepc_old); } Trap::Exception(2) => { - crate::earlyprintln!(" Illegal Instruction"); - crate::earlyprintln!(" -> Illegal instruction at {:#x}", sepc_old); + emergency_println!(" Illegal Instruction"); + emergency_println!(" -> Illegal instruction at {:#x}", sepc_old); } Trap::Exception(4) => { - crate::earlyprintln!(" Load Address Misaligned"); - crate::earlyprintln!( + emergency_println!(" Load Address Misaligned"); + emergency_println!( " -> Tried to load from misaligned address {:#x}", stval_val ); } Trap::Exception(5) => { - crate::earlyprintln!(" Load Access Fault"); - crate::earlyprintln!(" -> Cannot read from address {:#x}", stval_val); + emergency_println!(" Load Access Fault"); + emergency_println!(" -> Cannot read from address {:#x}", stval_val); } Trap::Exception(6) => { - crate::earlyprintln!(" Store/AMO Address Misaligned"); - crate::earlyprintln!( + emergency_println!(" Store/AMO Address Misaligned"); + emergency_println!( " -> Tried to store to misaligned address {:#x}", stval_val ); } Trap::Exception(7) => { - crate::earlyprintln!(" Store/AMO Access Fault"); - crate::earlyprintln!(" -> Cannot write to address {:#x}", stval_val); + emergency_println!(" Store/AMO Access Fault"); + emergency_println!(" -> Cannot write to address {:#x}", stval_val); } Trap::Exception(12) => { - crate::earlyprintln!(" Instruction Page Fault"); - crate::earlyprintln!( + emergency_println!(" Instruction Page Fault"); + emergency_println!( " -> Page table entry invalid or no permission at {:#x}", sepc_old ); } Trap::Exception(13) => { - crate::earlyprintln!(" Load Page Fault"); - crate::earlyprintln!( + emergency_println!(" Load Page Fault"); + emergency_println!( " -> Page table entry invalid or no read permission at {:#x}", stval_val ); } Trap::Exception(15) => { - crate::earlyprintln!(" Store Page Fault"); - crate::earlyprintln!( + emergency_println!(" Store Page Fault"); + emergency_println!( " -> Page table entry invalid or no write permission at {:#x}", stval_val ); } _ => { - crate::earlyprintln!(" Unknown exception type"); + emergency_println!(" Unknown exception type"); } } - crate::earlyprintln!(""); - crate::earlyprintln!("==============================================="); + emergency_println!(""); + emergency_println!("==============================================="); // 不要因为用户态异常让内核 panic;仿照 Linux 行为,终止当前任务即可。 // TODO: 进一步完善为向进程投递对应信号(SIGILL/SIGSEGV/...),并支持 core dump 等。 let sig = match scause.cause() { @@ -304,16 +309,16 @@ pub fn kernel_trap(scause: scause::Scause, sepc_old: usize, sstatus_old: sstatus let scause_val = scause.bits(); // 先直接打印到控制台,避免panic格式化时再次触发异常 - earlyprintln!("\n"); - earlyprintln!("================ KERNEL PANIC ================"); - earlyprintln!("Unexpected exception in S-Mode (Kernel)!"); - earlyprintln!("----------------------------------------------"); - earlyprintln!(" Exception: {:?} (Raw scause: {:#x})", e, scause_val); - earlyprintln!(" Faulting VA (stval): {:#x}", stval_val); - earlyprintln!(" Faulting PC (sepc): {:#x}", sepc_old); - earlyprintln!(" sstatus: {:#x}", sstatus_old.bits()); - earlyprintln!(" sscratch: {:#x}", sscratch_val); - earlyprintln!("=============================================="); + emergency_println!("\n"); + emergency_println!("================ KERNEL PANIC ================"); + emergency_println!("Unexpected exception in S-Mode (Kernel)!"); + emergency_println!("----------------------------------------------"); + emergency_println!(" Exception: {:?} (Raw scause: {:#x})", e, scause_val); + emergency_println!(" Faulting VA (stval): {:#x}", stval_val); + emergency_println!(" Faulting PC (sepc): {:#x}", sepc_old); + emergency_println!(" sstatus: {:#x}", sstatus_old.bits()); + emergency_println!(" sscratch: {:#x}", sscratch_val); + emergency_println!("=============================================="); // sbi::shutdown(true); panic!("Kernel exception in S-Mode"); } diff --git a/os/src/console.rs b/os/src/console.rs index 3145384a..665d5d5c 100644 --- a/os/src/console.rs +++ b/os/src/console.rs @@ -4,8 +4,9 @@ //! - 早期阶段:使用 arch::sbi 直接输出 //! - 运行时阶段:使用 device::console::MAIN_CONSOLE +use core::cell::UnsafeCell; use core::fmt::{self, Write}; -use core::sync::atomic::{AtomicBool, Ordering}; +use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use crate::arch::Platform; use crate::sync::SpinLock; @@ -16,9 +17,59 @@ static CONSOLE_RUNTIME: AtomicBool = AtomicBool::new(false); /// 控制台锁(保护输出的原子性) static CONSOLE_LOCK: SpinLock<()> = SpinLock::new(()); +const BOOT_CONSOLE_BUFFER_SIZE: usize = 16 * 1024; + +struct BootConsoleBuffer { + write_seq: AtomicUsize, + replayed_seq: AtomicUsize, + bytes: [UnsafeCell; BOOT_CONSOLE_BUFFER_SIZE], +} + +unsafe impl Sync for BootConsoleBuffer {} + +impl BootConsoleBuffer { + const fn new() -> Self { + Self { + write_seq: AtomicUsize::new(0), + replayed_seq: AtomicUsize::new(0), + bytes: [const { UnsafeCell::new(0) }; BOOT_CONSOLE_BUFFER_SIZE], + } + } + + fn push(&self, byte: u8) { + let seq = self.write_seq.fetch_add(1, Ordering::Relaxed); + unsafe { + *self.bytes[seq % BOOT_CONSOLE_BUFFER_SIZE].get() = byte; + } + } + + fn replay_to_runtime_console(&self) { + #[cfg(feature = "device")] + if let Some(console) = crate::device::console::MAIN_CONSOLE.read().as_ref() { + let write_seq = self.write_seq.load(Ordering::Acquire); + let oldest = write_seq.saturating_sub(BOOT_CONSOLE_BUFFER_SIZE); + let start = self.replayed_seq.load(Ordering::Acquire).max(oldest); + + for seq in start..write_seq { + let byte = unsafe { *self.bytes[seq % BOOT_CONSOLE_BUFFER_SIZE].get() }; + console.write_bytes(&[byte]); + } + + self.replayed_seq.store(write_seq, Ordering::Release); + } + } +} + +static BOOT_CONSOLE_BUFFER: BootConsoleBuffer = BootConsoleBuffer::new(); + /// 切换到运行时控制台(设备初始化完成后调用) pub fn init() { CONSOLE_RUNTIME.store(true, Ordering::Release); + BOOT_CONSOLE_BUFFER.replay_to_runtime_console(); +} + +pub fn is_runtime() -> bool { + CONSOLE_RUNTIME.load(Ordering::Acquire) } #[inline] @@ -32,6 +83,7 @@ fn write_str_unlocked(s: &str) { } for b in s.bytes() { + BOOT_CONSOLE_BUFFER.push(b); crate::arch::ArchImpl::console_putchar(b); } } @@ -43,15 +95,7 @@ fn putchar_unlocked(c: u8) { if CONSOLE_RUNTIME.load(Ordering::Acquire) { // 运行时:使用 device console if let Some(console) = crate::device::console::MAIN_CONSOLE.read().as_ref() { - // `Console::write_str` 只接受 UTF-8 字符串,因此这里只对 ASCII 走 runtime console; - // 对于非 ASCII 字节,直接降级到 SBI,避免破坏 UTF-8 多字节序列。 - if c.is_ascii() { - let buf = [c]; - let s = core::str::from_utf8(&buf).unwrap(); - console.write_str(s); - } else { - crate::arch::ArchImpl::console_putchar(c); - } + console.write_bytes(&[c]); } else { // 降级到 SBI crate::arch::ArchImpl::console_putchar(c); @@ -59,6 +103,7 @@ fn putchar_unlocked(c: u8) { return; } // 早期或无 device 功能:使用 arch console + BOOT_CONSOLE_BUFFER.push(c); crate::arch::ArchImpl::console_putchar(c); } @@ -80,22 +125,36 @@ fn getchar_unlocked() -> Option { crate::arch::ArchImpl::console_getchar() } +fn with_console_lock_or_fallback(f: impl FnOnce()) { + if let Some(_guard) = CONSOLE_LOCK.try_lock() { + f(); + } else { + f(); + } +} + /// 带锁的字符串输出(公开接口) pub fn write_str(s: &str) { - let _guard = CONSOLE_LOCK.lock(); - write_str_unlocked(s); + with_console_lock_or_fallback(|| write_str_unlocked(s)); } /// 带锁的单字符输出(公开接口,用于兼容性) pub fn putchar(c: u8) { - let _guard = CONSOLE_LOCK.lock(); - putchar_unlocked(c); + with_console_lock_or_fallback(|| putchar_unlocked(c)); } /// 带锁的单字符输入(公开接口) pub fn getchar() -> Option { - let _guard = CONSOLE_LOCK.lock(); - getchar_unlocked() + if let Some(_guard) = CONSOLE_LOCK.try_lock() { + getchar_unlocked() + } else { + None + } +} + +#[doc(hidden)] +pub fn _print(args: fmt::Arguments) { + Stdout.write_fmt(args).unwrap(); } /// 控制台输出结构体(实现 Write trait,供日志系统使用) @@ -110,50 +169,48 @@ impl Write for Stdout { fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result { // 重写 write_fmt 以确保整个格式化输出在一个锁内完成 // 这样可以防止多个 CPU 的日志输出交错 - let _guard = CONSOLE_LOCK.lock(); - - // 创建一个临时的 writer,它使用 putchar_unlocked(不加锁) - struct UnlockedWriter; - impl Write for UnlockedWriter { - fn write_str(&mut self, s: &str) -> fmt::Result { - write_str_unlocked(s); - Ok(()) - } + if let Some(_guard) = CONSOLE_LOCK.try_lock() { + UnlockedWriter.write_fmt(args) + } else { + UnlockedWriter.write_fmt(args) } + } +} - // 在持有锁的情况下格式化并输出 - UnlockedWriter.write_fmt(args) +// 创建一个临时的 writer,它使用 write_str_unlocked(不加锁) +struct UnlockedWriter; +impl Write for UnlockedWriter { + fn write_str(&mut self, s: &str) -> fmt::Result { + write_str_unlocked(s); + Ok(()) } } -/// 早期打印:逐字节通过 arch 的 console_putchar 输出。 -/// 不使用锁,适用于内核初始化早期阶段。 +/// Emergency print: no console lock; runtime uses MAIN_CONSOLE, otherwise boot buffer + arch mirror. #[doc(hidden)] -pub fn _early_print(args: core::fmt::Arguments) { +pub fn emergency_print(args: core::fmt::Arguments) { struct EarlyWriter; impl core::fmt::Write for EarlyWriter { fn write_str(&mut self, s: &str) -> core::fmt::Result { - for b in s.bytes() { - crate::arch::ArchImpl::console_putchar(b); - } + write_str_unlocked(s); Ok(()) } } EarlyWriter.write_fmt(args).unwrap(); } -/// 早期打印宏 (不含换行) +/// 打印格式化文本到控制台并写入日志缓冲区。 #[macro_export] -macro_rules! earlyprint { +macro_rules! print { ($fmt: literal $(, $($arg: tt)+)?) => { - $crate::console::_early_print(format_args!($fmt $(, $($arg)+)?)) + $crate::log::print_impl(format_args!($fmt $(, $($arg)+)?)) } } -/// 早期打印宏 (含换行) +/// 打印格式化文本到控制台并添加换行,同时写入日志缓冲区。 #[macro_export] -macro_rules! earlyprintln { +macro_rules! println { ($fmt: literal $(, $($arg: tt)+)?) => { - $crate::console::_early_print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?)) + $crate::log::print_impl(format_args!(concat!($fmt, "\n") $(, $($arg)+)?)) } } diff --git a/os/src/device/console/mod.rs b/os/src/device/console/mod.rs index d9adc46f..7138158e 100644 --- a/os/src/device/console/mod.rs +++ b/os/src/device/console/mod.rs @@ -17,6 +17,13 @@ pub trait Console: Send + Sync { /// 向控制台写入字符串 fn write_str(&self, s: &str); + /// 向控制台写入原始字节 + fn write_bytes(&self, bytes: &[u8]) { + if let Ok(s) = core::str::from_utf8(bytes) { + self.write_str(s); + } + } + /// 从控制台读取一个字符 fn read_char(&self) -> char; @@ -29,7 +36,12 @@ pub trait Console: Send + Sync { /// 初始化控制台设备 pub fn init() { - MAIN_CONSOLE.write().replace(CONSOLES.read()[0].clone()); + let Some(console) = CONSOLES.read().first().cloned() else { + crate::println!("[Console] No runtime console registered, keeping early console"); + return; + }; + + MAIN_CONSOLE.write().replace(console); // frame_console::init(); // 切换到运行时控制台 diff --git a/os/src/device/console/uart_console.rs b/os/src/device/console/uart_console.rs index 3ca65508..7f9a90f6 100644 --- a/os/src/device/console/uart_console.rs +++ b/os/src/device/console/uart_console.rs @@ -16,6 +16,10 @@ impl Console for UARTConsole { self.uart.write(s.as_bytes()); } + fn write_bytes(&self, bytes: &[u8]) { + self.uart.write(bytes); + } + fn read_char(&self) -> char { let byte = self.uart.read(); self.uart.write(&[byte]); // 回显 diff --git a/os/src/kernel/boot.rs b/os/src/kernel/boot.rs index 2697dc79..0d3d8828 100644 --- a/os/src/kernel/boot.rs +++ b/os/src/kernel/boot.rs @@ -7,7 +7,6 @@ use alloc::sync::Arc; use crate::{ arch::{CpuOps, platform, timer, trap}, - earlyprintln, ipc::{SignalHandlerTable, SignalPending}, kernel::{ FsStruct, Scheduler, TASK_MANAGER, TaskManagerTrait, TaskStruct, current_cpu, @@ -64,8 +63,8 @@ pub fn run_primary_boot(hartid: usize, ops: PrimaryBootOps) -> ! { run_early_tests(); - earlyprintln!("[Boot] Hello, world!"); - earlyprintln!( + crate::println!("[Boot] Hello, world!"); + crate::println!( "[Boot] {} {} {} is up!", ops.arch_name, ops.cpu_label, @@ -79,7 +78,7 @@ pub fn run_primary_boot(hartid: usize, ops: PrimaryBootOps) -> ! { { let _guard = PreemptGuard::new(); current_cpu().switch_space(kernel_space); - earlyprintln!("[Boot] Activated kernel address space"); + crate::println!("[Boot] Activated kernel address space"); } #[cfg(test)] diff --git a/os/src/kernel/task/ktask.rs b/os/src/kernel/task/ktask.rs index 4e7d2e48..976306ba 100644 --- a/os/src/kernel/task/ktask.rs +++ b/os/src/kernel/task/ktask.rs @@ -206,11 +206,7 @@ pub fn kernel_execve(path: &str, argv: &[&str], envp: &[&str]) -> ! { let tfp = task.lock().trap_frame_ptr.load(Ordering::SeqCst); unsafe { - crate::arch::prepare_user_restore( - tfp, - prepared.initial_pc, - prepared.user_sp_high, - ); + crate::arch::prepare_user_restore(tfp, prepared.initial_pc, prepared.user_sp_high); } // SAFETY: tfp 指向的内存已经被分配且由当前任务拥有 // 直接按 trapframe 状态恢复并 sret 到用户态 diff --git a/os/src/log/log_core.rs b/os/src/log/log_core.rs index e9a38697..6d5f058a 100644 --- a/os/src/log/log_core.rs +++ b/os/src/log/log_core.rs @@ -128,6 +128,32 @@ impl LogCore { } } + /// 记录裸 `print!`/`println!` 输出。 + /// + /// 控制台保持原始文本输出,日志缓冲区以 Info 级别保存,避免普通 + /// `println!` 信息绕过 syslog。 + pub fn _print(&self, args: fmt::Arguments) { + let log_context = if crate::console::is_runtime() { + context::collect_context() + } else { + context::LogContext { + cpu_id: crate::arch::cpu_id(), + task_id: 0, + timestamp: crate::arch::get_time(), + } + }; + let entry = LogEntry::from_args( + LogLevel::Info, + log_context.cpu_id, + log_context.task_id, + log_context.timestamp, + args, + ); + + self.buffer.write(&entry); + crate::console::_print(args); + } + /// 从缓冲区读取下一个日志条目 /// /// 如果没有可用条目,则返回 `None`。这是一个**无锁**的 diff --git a/os/src/log/mod.rs b/os/src/log/mod.rs index 734a4d25..52057a12 100644 --- a/os/src/log/mod.rs +++ b/os/src/log/mod.rs @@ -89,6 +89,15 @@ pub fn log_impl(level: LogLevel, args: core::fmt::Arguments) { GLOBAL_LOG._log(level, args); } +/// Raw print implementation used by `print!`/`println!`. +/// +/// Unlike `pr_*`, this keeps the console output unadorned while still storing +/// the message in the log ring buffer so syslog can retrieve it. +#[doc(hidden)] +pub fn print_impl(args: core::fmt::Arguments) { + GLOBAL_LOG._print(args); +} + /// 检查日志级别是否启用(由宏调用) #[doc(hidden)] pub fn is_level_enabled(level: LogLevel) -> bool { diff --git a/os/src/main.rs b/os/src/main.rs index 203bccd1..e2d42ab3 100644 --- a/os/src/main.rs +++ b/os/src/main.rs @@ -59,14 +59,14 @@ pub extern "C" fn rust_main(_hartid: usize) -> ! { #[panic_handler] fn panic(info: &PanicInfo) -> ! { if let Some(location) = info.location() { - earlyprintln!( - "Panicked at {}:{} {}", + crate::console::emergency_print(format_args!( + "Panicked at {}:{} {}\n", location.file(), location.line(), info.message() - ); + )); } else { - earlyprintln!("Panicked: {}", info.message()); + crate::console::emergency_print(format_args!("Panicked: {}\n", info.message())); } crate::arch::ArchImpl::power_off() diff --git a/os/src/mm/global_allocator/talc_alloc.rs b/os/src/mm/global_allocator/talc_alloc.rs index d5156538..95d41c8b 100644 --- a/os/src/mm/global_allocator/talc_alloc.rs +++ b/os/src/mm/global_allocator/talc_alloc.rs @@ -8,7 +8,7 @@ //! - 由链接器符号定义的堆内存区域。 //! - 用于设置堆的初始化函数。 -use crate::{earlyprintln, sync::RawSpinLock}; +use crate::sync::RawSpinLock; use talc::{Span, Talc, Talck}; /// 全局堆分配器实例 @@ -42,7 +42,7 @@ pub fn init_heap() { let heap_end = eheap as usize; let heap_size = heap_end - heap_start; - earlyprintln!( + crate::println!( "Initializing heap: start={:#x}, end={:#x}, size={:#x} ({} MB)", heap_start, heap_end, @@ -57,5 +57,5 @@ pub fn init_heap() { .expect("Failed to initialize heap allocator"); } - earlyprintln!("Heap allocator initialized successfully"); + crate::println!("Heap allocator initialized successfully"); } diff --git a/os/src/mm/mod.rs b/os/src/mm/mod.rs index d5b41227..22c2aada 100644 --- a/os/src/mm/mod.rs +++ b/os/src/mm/mod.rs @@ -23,7 +23,6 @@ pub use global_allocator::init_heap; use crate::arch::platform::MEMORY_END; use crate::config::PAGE_SIZE; -use crate::earlyprintln; use crate::mm::address::PA; use crate::mm::address::{Ppn, UsizeConvert}; use crate::sync::SpinLock; @@ -70,7 +69,7 @@ pub fn init() -> alloc::sync::Arc Result<(), NetworkConfigError> { - earlyprintln!("Initializing default network configuration..."); + crate::println!("Initializing default network configuration..."); let loopback_interface = Self::ensure_loopback_interface(); - earlyprintln!("Ensured loopback interface: {}", loopback_interface.name()); + crate::println!("Ensured loopback interface: {}", loopback_interface.name()); // 先获取接口的Arc,然后释放全局锁 // 避免在持有 NETWORK_INTERFACE_MANAGER 锁时操作接口字段锁 @@ -134,7 +131,7 @@ impl NetworkConfigManager { use crate::device::net::loopback::LoopbackNetDevice; use alloc::sync::Arc; - earlyprintln!("No net interfaces found; creating explicit loopback interface"); + crate::println!("No net interfaces found; creating explicit loopback interface"); let dev = LoopbackNetDevice::new(0); let iface = Arc::new(NetworkInterface::new(String::from("lo"), dev)); @@ -145,31 +142,31 @@ impl NetworkConfigManager { }; { - earlyprintln!("Configuring interface: {}", interface.name()); + crate::println!("Configuring interface: {}", interface.name()); if is_null_loopback_only { // Loopback-only 场景不要配置非 127/8 的地址和网关, // 否则 smoltcp 可能会为 127.0.0.1 选择错误的源地址/路由,导致 UDP/TCP 行为异常。 let loopback_cidr = IpCidr::new(IpAddress::v4(127, 0, 0, 1), 8); interface.add_ip_address(loopback_cidr); - earlyprintln!("Set loopback address: 127.0.0.1/8"); + crate::println!("Set loopback address: 127.0.0.1/8"); interface.set_ipv4_gateway(None); - earlyprintln!("No default gateway (loopback-only)"); + crate::println!("No default gateway (loopback-only)"); } else { // 设置默认IP地址 let ip_cidr = IpCidr::new(IpAddress::v4(192, 168, 1, 100), 24); interface.add_ip_address(ip_cidr); - earlyprintln!("Set IP address: 192.168.1.100/24"); + crate::println!("Set IP address: 192.168.1.100/24"); // 添加loopback地址到同一接口 let loopback_cidr = IpCidr::new(IpAddress::v4(127, 0, 0, 1), 8); interface.add_ip_address(loopback_cidr); - earlyprintln!("Set loopback address: 127.0.0.1/8"); + crate::println!("Set loopback address: 127.0.0.1/8"); // 设置默认网关 let gateway = Ipv4Address::new(192, 168, 1, 1); interface.set_ipv4_gateway(Some(gateway)); - earlyprintln!("Set default gateway: 192.168.1.1"); + crate::println!("Set default gateway: 192.168.1.1"); } // Initialize global interface for socket operations @@ -177,7 +174,7 @@ impl NetworkConfigManager { { use smoltcp::phy::Device as _; let caps = smoltcp_iface.device_adapter_mut().capabilities(); - earlyprintln!( + crate::println!( "smoltcp caps: medium={:?}, max_transmission_unit={}, ip_mtu={}", caps.medium, caps.max_transmission_unit, @@ -186,7 +183,7 @@ impl NetworkConfigManager { } use crate::net::socket::init_network; init_network(smoltcp_iface); - earlyprintln!("Initialized global network interface"); + crate::println!("Initialized global network interface"); Ok(()) } @@ -210,7 +207,7 @@ impl NetworkConfigManager { Ok(ipv4) => { let ip_cidr = IpCidr::new(IpAddress::Ipv4(ipv4), prefix); interface.add_ip_address(ip_cidr); - earlyprintln!("Set IP address for {}: {}/{}", interface_name, ip, prefix); + crate::println!("Set IP address for {}: {}/{}", interface_name, ip, prefix); Ok(()) } Err(_) => Err(NetworkConfigError::InvalidAddress), @@ -236,7 +233,7 @@ impl NetworkConfigManager { match gateway.parse::() { Ok(gateway_ipv4) => { interface.set_ipv4_gateway(Some(gateway_ipv4)); - earlyprintln!("Set default gateway for {}: {}", interface_name, gateway); + crate::println!("Set default gateway for {}: {}", interface_name, gateway); Ok(()) } Err(_) => Err(NetworkConfigError::InvalidGateway), @@ -321,7 +318,7 @@ impl NetworkConfigManager { // 设置网关 interface.set_ipv4_gateway(Some(gateway_address)); - earlyprintln!( + crate::println!( "Set interface config for {}: IP={}/{}, Gateway={}", interface_name, ip, diff --git a/os/src/test/mod.rs b/os/src/test/mod.rs index df9fe402..06e47391 100644 --- a/os/src/test/mod.rs +++ b/os/src/test/mod.rs @@ -1,18 +1,15 @@ mod guard; pub mod macros; pub mod net_test; -use crate::{ - arch::{are_interrupts_enabled, disable_interrupts, enable_interrupts}, - earlyprintln, -}; +use crate::arch::{are_interrupts_enabled, disable_interrupts, enable_interrupts}; /// 测试运行器。它由测试框架自动调用,并传入一个包含所有测试的切片。 #[cfg(test)] pub fn test_runner(tests: &[&dyn Fn()]) { use crate::arch::Platform; - use crate::{earlyprintln, test::macros::TEST_FAILED}; + use crate::test::macros::TEST_FAILED; use core::sync::atomic::Ordering; - earlyprintln!("\n\x1b[33m--- Running {} tests ---\x1b[0m", tests.len()); + crate::println!("\n\x1b[33m--- Running {} tests ---\x1b[0m", tests.len()); // 重置失败计数器 TEST_FAILED.store(0, Ordering::SeqCst); @@ -23,8 +20,8 @@ pub fn test_runner(tests: &[&dyn Fn()]) { } let failed = TEST_FAILED.load(Ordering::SeqCst); - earlyprintln!("\x1b[33m\n--- Test Summary ---\x1b[0m"); - earlyprintln!( + crate::println!("\x1b[33m\n--- Test Summary ---\x1b[0m"); + crate::println!( "\x1b[33mTotal: {}\x1b[0m, \x1b[32mPassed: {}\x1b[0m, \x1b[91mFailed: {}\x1b[0m, \x1b[33mTests Finished\x1b[0m", tests.len(), tests.len() - failed, @@ -32,9 +29,9 @@ pub fn test_runner(tests: &[&dyn Fn()]) { ); if failed > 0 { - earlyprintln!("\x1b[91mSome tests failed!\x1b[0m"); + crate::println!("\x1b[91mSome tests failed!\x1b[0m"); } else { - earlyprintln!("\x1b[32mAll tests passed!\x1b[0m"); + crate::println!("\x1b[32mAll tests passed!\x1b[0m"); } crate::arch::ArchImpl::power_off(); } @@ -55,11 +52,11 @@ pub fn run_early_tests() { // 计算测试数量 let count = unsafe { end.offset_from(start) } as usize; if count == 0 { - earlyprintln!("\x1b[36m[early_test] No early tests to run.\x1b[0m"); + crate::println!("\x1b[36m[early_test] No early tests to run.\x1b[0m"); return; } - earlyprintln!( + crate::println!( "\n\x1b[36m--- Running {} early tests (pre-mm) ---\x1b[0m", count ); @@ -70,7 +67,7 @@ pub fn run_early_tests() { test_fn(); } - earlyprintln!("\x1b[36m--- Early tests finished ---\x1b[0m\n"); + crate::println!("\x1b[36m--- Early tests finished ---\x1b[0m\n"); } /// 一个 RAII 守卫,用于在作用域内启用中断,并在离开作用域时恢复之前的状态。 @@ -135,19 +132,19 @@ mod tests { // // 我们断言这一点来验证宏的行为。 // kassert!(crate::arch::are_interrupts_enabled()); - // println!(" -> Assertion passed: Interrupts are enabled."); + // crate::println!(" -> Assertion passed: Interrupts are enabled."); // // 为了让测试更有意义,我们可以手动禁用中断, // // 然后验证 RAII 守卫是否会在测试结束时恢复它们。 - // println!(" -> Manually disabling interrupts for demonstration..."); + // crate::println!(" -> Manually disabling interrupts for demonstration..."); // unsafe { // crate::arch::disable_interrupts(); // } // kassert!(!crate::arch::are_interrupts_enabled()); - // println!(" -> Assertion passed: Interrupts are now disabled manually."); - // println!(" -> Leaving test block, the guard should now restore the state..."); + // crate::println!(" -> Assertion passed: Interrupts are now disabled manually."); + // crate::println!(" -> Leaving test block, the guard should now restore the state..."); // }); // 一个配套的测试,在 `(Interrupts)` 测试之后运行, @@ -157,6 +154,6 @@ mod tests { // // 如果前一个测试的 RAII 守卫工作正常,那么中断现在应该是禁用的。 // kassert!(!crate::arch::are_interrupts_enabled()); - // println!(" -> Assertion passed: Interrupts were correctly restored to disabled state."); + // crate::println!(" -> Assertion passed: Interrupts were correctly restored to disabled state."); // }); } diff --git a/os/src/util/stdio.rs b/os/src/util/stdio.rs index 476fa974..81efd777 100644 --- a/os/src/util/stdio.rs +++ b/os/src/util/stdio.rs @@ -1,30 +1,16 @@ -//! 标准输入输出工具模块 - -use core::fmt::{self, Write}; +//! 标准输入工具模块 use alloc::string::String; use alloc::vec::Vec; -pub struct Stdout; pub struct Stdin; -pub fn console_putchar(c: usize) { - crate::console::putchar(c as u8); -} - /// 使用 sbi 调用从控制台获取字符(qemu uart handler) /// 返回值:字符的 ASCII 码 pub fn console_getchar() -> usize { crate::console::getchar().map_or(usize::MAX, |c| c as usize) } -impl Write for Stdout { - fn write_str(&mut self, s: &str) -> fmt::Result { - crate::console::write_str(s); - Ok(()) - } -} - impl Stdin { pub fn read_char(&mut self) -> Option { crate::console::getchar().map(|c| c as char) @@ -42,66 +28,6 @@ impl Stdin { } } -pub(crate) fn print(args: fmt::Arguments) { - Stdout.write_fmt(args).unwrap(); -} - pub fn stdin() -> Stdin { Stdin } - -/// 打印格式化文本到控制台 -/// -/// 这个宏类似于标准库的 `print!` 宏,但使用 SBI 调用将文本输出到控制台。 -/// 它不会在末尾添加换行符。 -/// -/// # Examples -/// -/// ```ignore -/// print!("Hello, world!"); -/// print!("The answer is {}", 42); -/// ``` -#[cfg(not(test))] -#[macro_export] -macro_rules! print { - ($fmt: literal $(, $($arg: tt)+)?) => { - $crate::util::stdio::print(format_args!($fmt $(, $($arg)+)?)) - } -} - -/// 打印格式化文本到控制台并添加换行符 -/// -/// 这个宏类似于标准库的 `println!` 宏,但使用 SBI 调用将文本输出到控制台。 -/// 它会在末尾自动添加换行符。 -/// -/// # Examples -/// -/// ```ignore -/// println!("Hello, world!"); -/// println!("The answer is {}", 42); -/// ``` -#[cfg(not(test))] -#[macro_export] -macro_rules! println { - ($fmt: literal $(, $($arg: tt)+)?) => { - $crate::util::stdio::print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?)) - } -} - -#[cfg(test)] -#[macro_export] -/// 测试环境下的打印宏 -macro_rules! println { - ($fmt: literal $(, $($arg: tt)+)?) => { - $crate::console::_early_print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?)) - } -} - -#[cfg(test)] -#[macro_export] -/// 测试环境下的打印宏 -macro_rules! print { - ($fmt: literal $(, $($arg: tt)+)?) => { - $crate::console::_early_print(format_args!($fmt $(, $($arg)+)?)) - } -}