diff --git a/.github/workflows/doc-and-test.yml b/.github/workflows/doc-and-test.yml index 9fee30e..0a05371 100644 --- a/.github/workflows/doc-and-test.yml +++ b/.github/workflows/doc-and-test.yml @@ -4,7 +4,7 @@ on: [push] env: CARGO_TERM_COLOR: always - rust_toolchain: nightly-2025-02-18 + rust_toolchain: nightly-2024-01-18 jobs: build-doc: @@ -49,10 +49,7 @@ jobs: - name: Install QEMU run: | sudo apt-get update - sudo apt-get install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev \ - gawk build-essential bison flex texinfo gperf libtool patchutils bc \ - zlib1g-dev libexpat-dev pkg-config libglib2.0-dev libpixman-1-dev libsdl2-dev libslirp-dev \ - python3 python3-pip ninja-build -y + sudo apt-get install ninja-build -y if [ ! -d qemu-7.0.0 ]; then wget https://download.qemu.org/qemu-7.0.0.tar.xz tar -xf qemu-7.0.0.tar.xz diff --git a/easy-fs-fuse/src/main.rs b/easy-fs-fuse/src/main.rs index 39b9eaf..09016c3 100644 --- a/easy-fs-fuse/src/main.rs +++ b/easy-fs-fuse/src/main.rs @@ -149,59 +149,3 @@ fn efs_test() -> std::io::Result<()> { Ok(()) } - -#[test] -fn mac_test() -> std::io::Result<()> { - const BLOCK_SZ: usize = 512; - - let block_file = Arc::new(BlockFile(Mutex::new({ - let f = OpenOptions::new() - .read(true) - .write(true) - .create(true) - .open("target/fs_mac.img")?; - f.set_len(8192 * BLOCK_SZ).unwrap(); - f - }))); - - EasyFileSystem::create(block_file.clone(), 4096, 1); - let efs = EasyFileSystem::open(block_file.clone()); - let root_inode = EasyFileSystem::root_inode(&efs); - - root_inode.create("root_file"); - root_inode.create("public_file"); - - let secret_inode = root_inode.find("root_file").unwrap(); - secret_inode.write_at(0, b"TOP SECRET: root only!"); - let public_inode = root_inode.find("public_file").unwrap(); - public_inode.write_at(0, b"This file is public."); - - let check_permission = |user: &str, filename: &str| -> bool { - if filename == "root_file" && user != "root" { - false - } else { - true - } - }; - - let users = ["root", "nonroot"]; - for user in users.iter() { - println!("{} task:", user); - - for filename in ["root_file", "public_file"].iter() { - if check_permission(user, filename) { - let inode = root_inode.find(filename).unwrap(); - let mut buf = [0u8; 128]; - let len = inode.read_at(0, &mut buf); - let content = core::str::from_utf8(&buf[..len]).unwrap(); - println!("{}: Opened successfully"); - } else { - println!("{}: Permission denied"); - } - } - - println!(); - } - - Ok(()) -} diff --git a/easy-fs/src/block_cache.rs b/easy-fs/src/block_cache.rs index 786f9e0..c9bfa26 100644 --- a/easy-fs/src/block_cache.rs +++ b/easy-fs/src/block_cache.rs @@ -1,56 +1,12 @@ use super::{BlockDevice, BLOCK_SZ}; -use alloc::boxed::Box; use alloc::collections::VecDeque; use alloc::sync::Arc; -use core::alloc::Layout; -use core::mem::ManuallyDrop; -use core::ptr::{addr_of, addr_of_mut}; -use core::slice; use lazy_static::*; use spin::Mutex; - -/// Use `ManuallyDrop` to ensure data is deallocated with an alignment of `BLOCK_SZ` -struct CacheData(ManuallyDrop>); - -impl CacheData { - pub fn new() -> Self { - let data = unsafe { - let raw = alloc::alloc::alloc(Self::layout()); - Box::from_raw(raw as *mut [u8; BLOCK_SZ]) - }; - Self(ManuallyDrop::new(data)) - } - - fn layout() -> Layout { - Layout::from_size_align(BLOCK_SZ, BLOCK_SZ).unwrap() - } -} - -impl Drop for CacheData { - fn drop(&mut self) { - let ptr = self.0.as_mut_ptr(); - unsafe { alloc::alloc::dealloc(ptr, Self::layout()) }; - } -} - -impl AsRef<[u8]> for CacheData { - fn as_ref(&self) -> &[u8] { - let ptr = self.0.as_ptr() as *const u8; - unsafe { slice::from_raw_parts(ptr, BLOCK_SZ) } - } -} - -impl AsMut<[u8]> for CacheData { - fn as_mut(&mut self) -> &mut [u8] { - let ptr = self.0.as_mut_ptr() as *mut u8; - unsafe { slice::from_raw_parts_mut(ptr, BLOCK_SZ) } - } -} - /// Cached block inside memory pub struct BlockCache { /// cached block data - cache: CacheData, + cache: [u8; BLOCK_SZ], /// underlying block id block_id: usize, /// underlying block device @@ -62,9 +18,8 @@ pub struct BlockCache { impl BlockCache { /// Load a new BlockCache from disk. pub fn new(block_id: usize, block_device: Arc) -> Self { - // for alignment and move effciency - let mut cache = CacheData::new(); - block_device.read_block(block_id, cache.as_mut()); + let mut cache = [0u8; BLOCK_SZ]; + block_device.read_block(block_id, &mut cache); Self { cache, block_id, @@ -73,12 +28,8 @@ impl BlockCache { } } /// Get the address of an offset inside the cached block data - fn addr_of_offset(&self, offset: usize) -> *const u8 { - addr_of!(self.cache.as_ref()[offset]) - } - - fn addr_of_offset_mut(&mut self, offset: usize) -> *mut u8 { - addr_of_mut!(self.cache.as_mut()[offset]) + fn addr_of_offset(&self, offset: usize) -> usize { + &self.cache[offset] as *const _ as usize } pub fn get_ref(&self, offset: usize) -> &T @@ -87,8 +38,8 @@ impl BlockCache { { let type_size = core::mem::size_of::(); assert!(offset + type_size <= BLOCK_SZ); - let addr = self.addr_of_offset(offset) as *const T; - unsafe { &*addr } + let addr = self.addr_of_offset(offset); + unsafe { &*(addr as *const T) } } pub fn get_mut(&mut self, offset: usize) -> &mut T @@ -98,8 +49,8 @@ impl BlockCache { let type_size = core::mem::size_of::(); assert!(offset + type_size <= BLOCK_SZ); self.modified = true; - let addr = self.addr_of_offset_mut(offset) as *mut T; - unsafe { &mut *addr } + let addr = self.addr_of_offset(offset); + unsafe { &mut *(addr as *mut T) } } pub fn read(&self, offset: usize, f: impl FnOnce(&T) -> V) -> V { @@ -113,8 +64,7 @@ impl BlockCache { pub fn sync(&mut self) { if self.modified { self.modified = false; - self.block_device - .write_block(self.block_id, self.cache.as_ref()); + self.block_device.write_block(self.block_id, &self.cache); } } } diff --git a/easy-fs/src/efs.rs b/easy-fs/src/efs.rs index e28f6b2..202b9eb 100644 --- a/easy-fs/src/efs.rs +++ b/easy-fs/src/efs.rs @@ -36,7 +36,7 @@ impl EasyFileSystem { let data_bitmap_blocks = (data_total_blocks + 4096) / 4097; let data_area_blocks = data_total_blocks - data_bitmap_blocks; let data_bitmap = Bitmap::new( - (1 + inode_total_blocks) as usize, + (1 + inode_bitmap_blocks + inode_area_blocks) as usize, data_bitmap_blocks as usize, ); let mut efs = Self { diff --git a/os/Cargo.toml b/os/Cargo.toml index d621557..b65ed6e 100644 --- a/os/Cargo.toml +++ b/os/Cargo.toml @@ -2,7 +2,7 @@ name = "os" version = "0.1.0" authors = ["Yifan Wu "] -edition = "2024" +edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/os/Makefile b/os/Makefile index ff109f0..9815cee 100644 --- a/os/Makefile +++ b/os/Makefile @@ -74,23 +74,20 @@ QEMU_ARGS := -machine virt \ -drive file=$(FS_IMG),if=none,format=raw,id=x0 \ -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0 -QEMU_NAME := qemu-system-riscv64 -qemu-version-check: - @sh scripts/qemu-ver-check.sh $(QEMU_NAME) - -run-inner: qemu-version-check build +run-inner: build @qemu-system-riscv64 $(QEMU_ARGS) -debug: qemu-version-check build +debug: build @tmux new-session -d \ "qemu-system-riscv64 $(QEMU_ARGS) -s -S" && \ tmux split-window -h "riscv64-unknown-elf-gdb -ex 'file $(KERNEL_ELF)' -ex 'set arch riscv:rv64' -ex 'target remote localhost:1234'" && \ tmux -2 attach-session -d -gdbserver: qemu-version-check build + +gdbserver: build @qemu-system-riscv64 $(QEMU_ARGS) -s -S gdbclient: @riscv64-unknown-elf-gdb -ex 'file $(KERNEL_ELF)' -ex 'set arch riscv:rv64' -ex 'target remote localhost:1234' -.PHONY: build env kernel clean disasm disasm-vim run-inner fs-img gdbserver gdbclient qemu-version-check +.PHONY: build env kernel clean disasm disasm-vim run-inner fs-img gdbserver gdbclient diff --git a/os/scripts/qemu-ver-check.sh b/os/scripts/qemu-ver-check.sh deleted file mode 100755 index 40ef766..0000000 --- a/os/scripts/qemu-ver-check.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh - -# Argument1: The filename of qemu executable, e.g. qemu-system-riscv64 -QEMU_PATH=$(which $1) -RET=$? -MINIMUM_MAJOR_VERSION=7 -RED='\033[0;31m' -GREEN='\033[0;32m' -NC='\033[0m' -if [ $RET != 0 ] -then - echo "$1 not found" - exit 1 -else - QEMU_VERSION=$($1 --version|head -n 1|awk '{print $4}') - MAJOR_VERSION=$(echo $QEMU_VERSION | awk -F '.' '{print $1}') - if [ $MAJOR_VERSION -lt $MINIMUM_MAJOR_VERSION ] - then - echo "${RED}Error: Required major version of QEMU is ${MINIMUM_MAJOR_VERSION}, " \ - "but current is ${QEMU_VERSION}.${NC}" - exit 1 - else - echo "${GREEN}QEMU version is ${QEMU_VERSION}(>=${MINIMUM_MAJOR_VERSION}), OK!${NC}" - exit 0 - fi -fi diff --git a/os/src/drivers/block/virtio_blk.rs b/os/src/drivers/block/virtio_blk.rs index 5097831..9755250 100644 --- a/os/src/drivers/block/virtio_blk.rs +++ b/os/src/drivers/block/virtio_blk.rs @@ -1,7 +1,7 @@ use super::BlockDevice; use crate::mm::{ - FrameTracker, PageTable, PhysAddr, PhysPageNum, StepByOne, VirtAddr, frame_alloc, - frame_dealloc, kernel_token, + frame_alloc, frame_dealloc, kernel_token, FrameTracker, PageTable, PhysAddr, PhysPageNum, + StepByOne, VirtAddr, }; use crate::sync::UPSafeCell; use alloc::vec::Vec; diff --git a/os/src/fs/mod.rs b/os/src/fs/mod.rs index c3cc1e7..6c790fe 100644 --- a/os/src/fs/mod.rs +++ b/os/src/fs/mod.rs @@ -15,5 +15,5 @@ pub trait File: Send + Sync { fn write(&self, buf: UserBuffer) -> usize; } -pub use inode::{OSInode, OpenFlags, list_apps, open_file}; +pub use inode::{list_apps, open_file, OSInode, OpenFlags}; pub use stdio::{Stdin, Stdout}; diff --git a/os/src/lang_items.rs b/os/src/lang_items.rs index 79cd51e..26951f8 100644 --- a/os/src/lang_items.rs +++ b/os/src/lang_items.rs @@ -10,10 +10,10 @@ fn panic(info: &PanicInfo) -> ! { "[kernel] Panicked at {}:{} {}", location.file(), location.line(), - info.message() + info.message().unwrap() ); } else { - error!("[kernel] Panicked: {}", info.message()); + error!("[kernel] Panicked: {}", info.message().unwrap()); } shutdown(true) } diff --git a/os/src/logging.rs b/os/src/logging.rs deleted file mode 100644 index b5421f1..0000000 --- a/os/src/logging.rs +++ /dev/null @@ -1,47 +0,0 @@ -/*! - -本模块利用 log crate 为你提供了日志功能,使用方式见 main.rs. - -*/ - -use log::{self, Level, LevelFilter, Log, Metadata, Record}; - -struct SimpleLogger; - -impl Log for SimpleLogger { - fn enabled(&self, _metadata: &Metadata) -> bool { - true - } - fn log(&self, record: &Record) { - if !self.enabled(record.metadata()) { - return; - } - let color = match record.level() { - Level::Error => 31, // Red - Level::Warn => 93, // BrightYellow - Level::Info => 34, // Blue - Level::Debug => 32, // Green - Level::Trace => 90, // BrightBlack - }; - println!( - "\u{1B}[{}m[{:>5}] {}\u{1B}[0m", - color, - record.level(), - record.args(), - ); - } - fn flush(&self) {} -} - -pub fn init() { - static LOGGER: SimpleLogger = SimpleLogger; - log::set_logger(&LOGGER).unwrap(); - log::set_max_level(match option_env!("LOG") { - Some("ERROR") => LevelFilter::Error, - Some("WARN") => LevelFilter::Warn, - Some("INFO") => LevelFilter::Info, - Some("DEBUG") => LevelFilter::Debug, - Some("TRACE") => LevelFilter::Trace, - _ => LevelFilter::Info, - }); -} diff --git a/os/src/main.rs b/os/src/main.rs index 46161de..cc58958 100644 --- a/os/src/main.rs +++ b/os/src/main.rs @@ -23,6 +23,7 @@ #![allow(unused_imports)] #![no_std] #![no_main] +#![feature(panic_info_message)] #![feature(alloc_error_handler)] extern crate alloc; @@ -30,8 +31,6 @@ extern crate alloc; #[macro_use] extern crate bitflags; -use log::*; - #[path = "boards/qemu.rs"] mod board; @@ -41,7 +40,6 @@ mod config; mod drivers; pub mod fs; pub mod lang_items; -mod logging; pub mod mm; pub mod sbi; pub mod sync; @@ -55,9 +53,9 @@ use core::arch::global_asm; global_asm!(include_str!("entry.asm")); /// clear BSS segment fn clear_bss() { - unsafe extern "C" { - safe fn sbss(); - safe fn ebss(); + extern "C" { + fn sbss(); + fn ebss(); } unsafe { core::slice::from_raw_parts_mut(sbss as usize as *mut u8, ebss as usize - sbss as usize) @@ -65,12 +63,11 @@ fn clear_bss() { } } +#[no_mangle] /// the rust entry-point of os -#[unsafe(no_mangle)] pub fn rust_main() -> ! { clear_bss(); - logging::init(); - info!("[kernel] Hello, world!"); + println!("[kernel] Hello, world!"); mm::init(); mm::remap_test(); trap::init(); diff --git a/os/src/mm/frame_allocator.rs b/os/src/mm/frame_allocator.rs index 28b519c..f3d18ea 100644 --- a/os/src/mm/frame_allocator.rs +++ b/os/src/mm/frame_allocator.rs @@ -94,8 +94,8 @@ lazy_static! { } /// initiate the frame allocator using `ekernel` and `MEMORY_END` pub fn init_frame_allocator() { - unsafe extern "C" { - safe fn ekernel(); + extern "C" { + fn ekernel(); } FRAME_ALLOCATOR.exclusive_access().init( PhysAddr::from(ekernel as usize).ceil(), diff --git a/os/src/mm/heap_allocator.rs b/os/src/mm/heap_allocator.rs index a6b413b..e5f8b30 100644 --- a/os/src/mm/heap_allocator.rs +++ b/os/src/mm/heap_allocator.rs @@ -1,7 +1,6 @@ //! The global allocator use crate::config::KERNEL_HEAP_SIZE; use buddy_system_allocator::LockedHeap; -use core::ptr::addr_of_mut; #[global_allocator] /// heap allocator instance @@ -19,7 +18,7 @@ pub fn init_heap() { unsafe { HEAP_ALLOCATOR .lock() - .init(addr_of_mut!(HEAP_SPACE) as usize, KERNEL_HEAP_SIZE); + .init(HEAP_SPACE.as_ptr() as usize, KERNEL_HEAP_SIZE); } } @@ -27,9 +26,9 @@ pub fn init_heap() { pub fn heap_test() { use alloc::boxed::Box; use alloc::vec::Vec; - unsafe extern "C" { - safe fn sbss(); - safe fn ebss(); + extern "C" { + fn sbss(); + fn ebss(); } let bss_range = sbss as usize..ebss as usize; let a = Box::new(5); diff --git a/os/src/mm/memory_set.rs b/os/src/mm/memory_set.rs index b1e5072..a2c31cd 100644 --- a/os/src/mm/memory_set.rs +++ b/os/src/mm/memory_set.rs @@ -1,6 +1,5 @@ //! Implementation of [`MapArea`] and [`MemorySet`]. - -use super::{FrameTracker, frame_alloc}; +use super::{frame_alloc, FrameTracker}; use super::{PTEFlags, PageTable, PageTableEntry}; use super::{PhysAddr, PhysPageNum, VirtAddr, VirtPageNum}; use super::{StepByOne, VPNRange}; @@ -13,17 +12,17 @@ use core::arch::asm; use lazy_static::*; use riscv::register::satp; -unsafe extern "C" { - safe fn stext(); - safe fn etext(); - safe fn srodata(); - safe fn erodata(); - safe fn sdata(); - safe fn edata(); - safe fn sbss_with_stack(); - safe fn ebss(); - safe fn ekernel(); - safe fn strampoline(); +extern "C" { + fn stext(); + fn etext(); + fn srodata(); + fn erodata(); + fn sdata(); + fn edata(); + fn sbss_with_stack(); + fn ebss(); + fn ekernel(); + fn strampoline(); } lazy_static! { @@ -390,26 +389,20 @@ pub fn remap_test() { let mid_text: VirtAddr = ((stext as usize + etext as usize) / 2).into(); let mid_rodata: VirtAddr = ((srodata as usize + erodata as usize) / 2).into(); let mid_data: VirtAddr = ((sdata as usize + edata as usize) / 2).into(); - assert!( - !kernel_space - .page_table - .translate(mid_text.floor()) - .unwrap() - .writable(), - ); - assert!( - !kernel_space - .page_table - .translate(mid_rodata.floor()) - .unwrap() - .writable(), - ); - assert!( - !kernel_space - .page_table - .translate(mid_data.floor()) - .unwrap() - .executable(), - ); + assert!(!kernel_space + .page_table + .translate(mid_text.floor()) + .unwrap() + .writable(),); + assert!(!kernel_space + .page_table + .translate(mid_rodata.floor()) + .unwrap() + .writable(),); + assert!(!kernel_space + .page_table + .translate(mid_data.floor()) + .unwrap() + .executable(),); println!("remap_test passed!"); } diff --git a/os/src/mm/mod.rs b/os/src/mm/mod.rs index 3255725..65f1e9a 100644 --- a/os/src/mm/mod.rs +++ b/os/src/mm/mod.rs @@ -13,13 +13,13 @@ mod page_table; use address::VPNRange; pub use address::{PhysAddr, PhysPageNum, StepByOne, VirtAddr, VirtPageNum}; -pub use frame_allocator::{FrameTracker, frame_alloc, frame_dealloc}; +pub use frame_allocator::{frame_alloc, frame_dealloc, FrameTracker}; pub use memory_set::remap_test; -pub use memory_set::{KERNEL_SPACE, MapPermission, MemorySet, kernel_token}; +pub use memory_set::{kernel_token, MapPermission, MemorySet, KERNEL_SPACE}; use page_table::PTEFlags; pub use page_table::{ - PageTable, PageTableEntry, UserBuffer, UserBufferIterator, translated_byte_buffer, - translated_ref, translated_refmut, translated_str, + translated_byte_buffer, translated_ref, translated_refmut, translated_str, PageTable, + PageTableEntry, UserBuffer, UserBufferIterator, }; /// initiate heap allocator, frame allocator and kernel space pub fn init() { diff --git a/os/src/mm/page_table.rs b/os/src/mm/page_table.rs index f5fdf2b..9fbd21b 100644 --- a/os/src/mm/page_table.rs +++ b/os/src/mm/page_table.rs @@ -1,6 +1,5 @@ //! Implementation of [`PageTableEntry`] and [`PageTable`]. - -use super::{FrameTracker, PhysAddr, PhysPageNum, StepByOne, VirtAddr, VirtPageNum, frame_alloc}; +use super::{frame_alloc, FrameTracker, PhysAddr, PhysPageNum, StepByOne, VirtAddr, VirtPageNum}; use alloc::string::String; use alloc::vec; use alloc::vec::Vec; diff --git a/os/src/sbi.rs b/os/src/sbi.rs index a73476f..eb79f67 100644 --- a/os/src/sbi.rs +++ b/os/src/sbi.rs @@ -20,7 +20,7 @@ pub fn set_timer(timer: usize) { /// use sbi call to shutdown the kernel pub fn shutdown(failure: bool) -> ! { - use sbi_rt::{NoReason, Shutdown, SystemFailure, system_reset}; + use sbi_rt::{system_reset, NoReason, Shutdown, SystemFailure}; if !failure { system_reset(Shutdown, NoReason); } else { diff --git a/os/src/syscall/fs.rs b/os/src/syscall/fs.rs index 8d46fad..aecc790 100644 --- a/os/src/syscall/fs.rs +++ b/os/src/syscall/fs.rs @@ -1,6 +1,6 @@ //! File and filesystem-related syscalls -use crate::fs::{OpenFlags, open_file}; -use crate::mm::{UserBuffer, translated_byte_buffer, translated_str}; +use crate::fs::{open_file, OpenFlags}; +use crate::mm::{translated_byte_buffer, translated_str, UserBuffer}; use crate::task::{current_task, current_user_token}; pub fn sys_write(fd: usize, buf: *const u8, len: usize) -> isize { @@ -47,13 +47,6 @@ pub fn sys_open(path: *const u8, flags: u32) -> isize { let task = current_task().unwrap(); let token = current_user_token(); let path = translated_str(token, path); - - // 简单用户检查示例:非 root 用户不能打开 /root 下文件 - let username = task.inner_exclusive_access().user.clone(); - if path.starts_with("/root") && username != "root" { - return -1; // Permission denied - } - if let Some(inode) = open_file(path.as_str(), OpenFlags::from_bits(flags).unwrap()) { let mut inner = task.inner_exclusive_access(); let fd = inner.alloc_fd(); @@ -64,7 +57,6 @@ pub fn sys_open(path: *const u8, flags: u32) -> isize { } } - pub fn sys_close(fd: usize) -> isize { let task = current_task().unwrap(); let mut inner = task.inner_exclusive_access(); diff --git a/os/src/syscall/process.rs b/os/src/syscall/process.rs index 61e78d6..3d62cbb 100644 --- a/os/src/syscall/process.rs +++ b/os/src/syscall/process.rs @@ -1,4 +1,4 @@ -use crate::fs::{OpenFlags, open_file}; +use crate::fs::{open_file, OpenFlags}; use crate::mm::{translated_refmut, translated_str}; use crate::task::{ add_task, current_task, current_user_token, exit_current_and_run_next, diff --git a/os/src/task/mod.rs b/os/src/task/mod.rs index 47c13cd..e4837cb 100644 --- a/os/src/task/mod.rs +++ b/os/src/task/mod.rs @@ -23,20 +23,20 @@ mod switch; #[allow(rustdoc::private_intra_doc_links)] mod task; -use crate::fs::{OpenFlags, open_file}; +use crate::fs::{open_file, OpenFlags}; use crate::sbi::shutdown; use alloc::sync::Arc; pub use context::TaskContext; use lazy_static::*; -pub use manager::{TaskManager, fetch_task}; +pub use manager::{fetch_task, TaskManager}; use switch::__switch; use task::{TaskControlBlock, TaskStatus}; pub use manager::add_task; -pub use pid::{KernelStack, PidAllocator, PidHandle, pid_alloc}; +pub use pid::{pid_alloc, KernelStack, PidAllocator, PidHandle}; pub use processor::{ - Processor, current_task, current_trap_cx, current_user_token, run_tasks, schedule, - take_current_task, + current_task, current_trap_cx, current_user_token, run_tasks, schedule, take_current_task, + Processor, }; /// Suspend the current 'Running' task and run the next task in task list. pub fn suspend_current_and_run_next() { diff --git a/os/src/task/pid.rs b/os/src/task/pid.rs index f0a5e2a..a7bdea9 100644 --- a/os/src/task/pid.rs +++ b/os/src/task/pid.rs @@ -1,6 +1,6 @@ //!Implementation of [`PidAllocator`] use crate::config::{KERNEL_STACK_SIZE, PAGE_SIZE, TRAMPOLINE}; -use crate::mm::{KERNEL_SPACE, MapPermission, VirtAddr}; +use crate::mm::{MapPermission, VirtAddr, KERNEL_SPACE}; use crate::sync::UPSafeCell; use alloc::vec::Vec; use lazy_static::*; diff --git a/os/src/task/processor.rs b/os/src/task/processor.rs index 7c05a21..1d9c0f2 100644 --- a/os/src/task/processor.rs +++ b/os/src/task/processor.rs @@ -1,7 +1,7 @@ //!Implementation of [`Processor`] and Intersection of control flow use super::__switch; +use super::{fetch_task, TaskStatus}; use super::{TaskContext, TaskControlBlock}; -use super::{TaskStatus, fetch_task}; use crate::sync::UPSafeCell; use crate::trap::TrapContext; use alloc::sync::Arc; diff --git a/os/src/task/switch.rs b/os/src/task/switch.rs index 8f69fdf..7d194f5 100644 --- a/os/src/task/switch.rs +++ b/os/src/task/switch.rs @@ -4,11 +4,6 @@ use core::arch::global_asm; global_asm!(include_str!("switch.S")); -unsafe extern "C" { - /// Switch to the context of `next_task_cx_ptr`, saving the current context - /// in `current_task_cx_ptr`. - pub unsafe fn __switch( - current_task_cx_ptr: *mut TaskContext, - next_task_cx_ptr: *const TaskContext, - ); +extern "C" { + pub fn __switch(current_task_cx_ptr: *mut TaskContext, next_task_cx_ptr: *const TaskContext); } diff --git a/os/src/task/task.rs b/os/src/task/task.rs index 87d287a..6e38b92 100644 --- a/os/src/task/task.rs +++ b/os/src/task/task.rs @@ -1,11 +1,11 @@ //!Implementation of [`TaskControlBlock`] use super::TaskContext; -use super::{KernelStack, PidHandle, pid_alloc}; +use super::{pid_alloc, KernelStack, PidHandle}; use crate::config::TRAP_CONTEXT; use crate::fs::{File, Stdin, Stdout}; -use crate::mm::{KERNEL_SPACE, MemorySet, PhysPageNum, VirtAddr}; +use crate::mm::{MemorySet, PhysPageNum, VirtAddr, KERNEL_SPACE}; use crate::sync::UPSafeCell; -use crate::trap::{TrapContext, trap_handler}; +use crate::trap::{trap_handler, TrapContext}; use alloc::sync::{Arc, Weak}; use alloc::vec; use alloc::vec::Vec; @@ -30,9 +30,6 @@ pub struct TaskControlBlockInner { pub children: Vec>, pub exit_code: i32, pub fd_table: Vec>>, - - // New: User - pub user: String, } impl TaskControlBlockInner { @@ -169,7 +166,6 @@ impl TaskControlBlock { children: Vec::new(), exit_code: 0, fd_table: new_fd_table, - user: username.to_string(), // Init User name }) }, }); diff --git a/os/src/trap/context.rs b/os/src/trap/context.rs index 5f968e5..0cae492 100644 --- a/os/src/trap/context.rs +++ b/os/src/trap/context.rs @@ -1,5 +1,5 @@ //! Implementation of [`TrapContext`] -use riscv::register::sstatus::{self, SPP, Sstatus}; +use riscv::register::sstatus::{self, Sstatus, SPP}; #[repr(C)] #[derive(Debug)] diff --git a/os/src/trap/mod.rs b/os/src/trap/mod.rs index 26e7895..49b85ec 100644 --- a/os/src/trap/mod.rs +++ b/os/src/trap/mod.rs @@ -50,7 +50,7 @@ pub fn enable_timer_interrupt() { } } -#[unsafe(no_mangle)] +#[no_mangle] /// handle an interrupt, exception, or system call from user space pub fn trap_handler() -> ! { set_kernel_trap_entry(); @@ -103,7 +103,7 @@ pub fn trap_handler() -> ! { trap_return(); } -#[unsafe(no_mangle)] +#[no_mangle] /// set the new addr of __restore asm function in TRAMPOLINE page, /// set the reg a0 = trap_cx_ptr, reg a1 = phy addr of usr page table, /// finally, jump to new addr of __restore asm function @@ -111,9 +111,9 @@ pub fn trap_return() -> ! { set_user_trap_entry(); let trap_cx_ptr = TRAP_CONTEXT; let user_satp = current_user_token(); - unsafe extern "C" { - unsafe fn __alltraps(); - unsafe fn __restore(); + extern "C" { + fn __alltraps(); + fn __restore(); } let restore_va = __restore as usize - __alltraps as usize + TRAMPOLINE; unsafe { @@ -128,7 +128,7 @@ pub fn trap_return() -> ! { } } -#[unsafe(no_mangle)] +#[no_mangle] /// Unimplement: traps/interrupts/exceptions from kernel mode /// Todo: Chapter 9: I/O device pub fn trap_from_kernel() -> ! { diff --git a/rust-toolchain.toml b/rust-toolchain.toml index e6f10a1..c65d258 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,6 +1,6 @@ [toolchain] profile = "minimal" # use the nightly version of the last stable toolchain, see -channel = "nightly-2025-02-18" +channel = "nightly-2024-05-01" components = ["rust-src", "llvm-tools", "rustfmt", "clippy"] targets = ["riscv64gc-unknown-none-elf"] diff --git a/user/Cargo.toml b/user/Cargo.toml index 92f3f7e..3bc82dc 100644 --- a/user/Cargo.toml +++ b/user/Cargo.toml @@ -2,7 +2,7 @@ name = "user_lib" version = "0.1.0" authors = ["Yifan Wu "] -edition = "2024" +edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/user/src/bin/cat_filea.rs b/user/src/bin/cat_filea.rs index 20daf77..6307ecd 100644 --- a/user/src/bin/cat_filea.rs +++ b/user/src/bin/cat_filea.rs @@ -5,9 +5,9 @@ extern crate user_lib; extern crate alloc; -use user_lib::{OpenFlags, close, open, read}; +use user_lib::{close, open, read, OpenFlags}; -#[unsafe(no_mangle)] +#[no_mangle] pub fn main() -> i32 { let fd = open("filea\0", OpenFlags::RDONLY); if fd == -1 { diff --git a/user/src/bin/exit.rs b/user/src/bin/exit.rs index 8e19542..60510c9 100644 --- a/user/src/bin/exit.rs +++ b/user/src/bin/exit.rs @@ -7,7 +7,7 @@ use user_lib::{exit, fork, wait, waitpid, yield_}; const MAGIC: i32 = -0x10384; -#[unsafe(no_mangle)] +#[no_mangle] pub fn main() -> i32 { println!("I am the parent. Forking the child..."); let pid = fork(); diff --git a/user/src/bin/fantastic_text.rs b/user/src/bin/fantastic_text.rs index 0850162..a3402ff 100644 --- a/user/src/bin/fantastic_text.rs +++ b/user/src/bin/fantastic_text.rs @@ -5,12 +5,12 @@ extern crate user_lib; macro_rules! color_text { - ($text:expr, $color:expr) => { + ($text:expr, $color:expr) => {{ format_args!("\x1b[{}m{}\x1b[0m", $color, $text) - }; + }}; } -#[unsafe(no_mangle)] +#[no_mangle] pub fn main() -> i32 { println!( "{}{}{}{}{} {}{}{}{} {}{}{}{}{}{}", diff --git a/user/src/bin/filetest_simple.rs b/user/src/bin/filetest_simple.rs index b192156..3406d55 100644 --- a/user/src/bin/filetest_simple.rs +++ b/user/src/bin/filetest_simple.rs @@ -4,9 +4,9 @@ #[macro_use] extern crate user_lib; -use user_lib::{OpenFlags, close, open, read, write}; +use user_lib::{close, open, read, write, OpenFlags}; -#[unsafe(no_mangle)] +#[no_mangle] pub fn main() -> i32 { let test_str = "Hello, world!"; let filea = "filea\0"; diff --git a/user/src/bin/forktest.rs b/user/src/bin/forktest.rs index f6003c5..5374a56 100644 --- a/user/src/bin/forktest.rs +++ b/user/src/bin/forktest.rs @@ -8,7 +8,7 @@ use user_lib::{exit, fork, wait}; const MAX_CHILD: usize = 30; -#[unsafe(no_mangle)] +#[no_mangle] pub fn main() -> i32 { for i in 0..MAX_CHILD { let pid = fork(); diff --git a/user/src/bin/forktest2.rs b/user/src/bin/forktest2.rs index ee452cc..c91ce15 100644 --- a/user/src/bin/forktest2.rs +++ b/user/src/bin/forktest2.rs @@ -8,7 +8,7 @@ use user_lib::{exit, fork, get_time, getpid, sleep, wait}; static NUM: usize = 30; -#[unsafe(no_mangle)] +#[no_mangle] pub fn main() -> i32 { for _ in 0..NUM { let pid = fork(); diff --git a/user/src/bin/forktest_simple.rs b/user/src/bin/forktest_simple.rs index b9cf587..29a624b 100644 --- a/user/src/bin/forktest_simple.rs +++ b/user/src/bin/forktest_simple.rs @@ -6,7 +6,7 @@ extern crate user_lib; use user_lib::{fork, getpid, wait}; -#[unsafe(no_mangle)] +#[no_mangle] pub fn main() -> i32 { assert_eq!(wait(&mut 0i32), -1); println!("sys_wait without child process test passed!"); diff --git a/user/src/bin/forktree.rs b/user/src/bin/forktree.rs index bcca4e6..bfcfc4c 100644 --- a/user/src/bin/forktree.rs +++ b/user/src/bin/forktree.rs @@ -29,7 +29,7 @@ fn fork_tree(cur: &str) { fork_child(cur, '1'); } -#[unsafe(no_mangle)] +#[no_mangle] pub fn main() -> i32 { fork_tree(""); sleep(3000); diff --git a/user/src/bin/hello_world.rs b/user/src/bin/hello_world.rs index cc651e7..10d3f26 100644 --- a/user/src/bin/hello_world.rs +++ b/user/src/bin/hello_world.rs @@ -4,7 +4,7 @@ #[macro_use] extern crate user_lib; -#[unsafe(no_mangle)] +#[no_mangle] pub fn main() -> i32 { println!("Hello world from user mode program!"); 0 diff --git a/user/src/bin/huge_write.rs b/user/src/bin/huge_write.rs index 9327261..e93f8b8 100644 --- a/user/src/bin/huge_write.rs +++ b/user/src/bin/huge_write.rs @@ -4,9 +4,9 @@ #[macro_use] extern crate user_lib; -use user_lib::{OpenFlags, close, get_time, open, write}; +use user_lib::{close, get_time, open, write, OpenFlags}; -#[unsafe(no_mangle)] +#[no_mangle] pub fn main() -> i32 { let mut buffer = [0u8; 1024]; // 1KiB for (i, ch) in buffer.iter_mut().enumerate() { diff --git a/user/src/bin/initproc.rs b/user/src/bin/initproc.rs index d522b77..71bed27 100644 --- a/user/src/bin/initproc.rs +++ b/user/src/bin/initproc.rs @@ -6,7 +6,7 @@ extern crate user_lib; use user_lib::{exec, fork, wait, yield_}; -#[unsafe(no_mangle)] +#[no_mangle] fn main() -> i32 { if fork() == 0 { exec("user_shell\0"); diff --git a/user/src/bin/matrix.rs b/user/src/bin/matrix.rs index 846f4c6..9ebf48f 100644 --- a/user/src/bin/matrix.rs +++ b/user/src/bin/matrix.rs @@ -44,7 +44,7 @@ fn work(times: isize) { exit(0); } -#[unsafe(no_mangle)] +#[no_mangle] pub fn main() -> i32 { for _ in 0..NUM { let pid = fork(); diff --git a/user/src/bin/sleep.rs b/user/src/bin/sleep.rs index e02b3ed..641a4f9 100644 --- a/user/src/bin/sleep.rs +++ b/user/src/bin/sleep.rs @@ -15,7 +15,7 @@ fn sleepy() { exit(0); } -#[unsafe(no_mangle)] +#[no_mangle] pub fn main() -> i32 { let current_time = get_time(); let pid = fork(); diff --git a/user/src/bin/sleep_simple.rs b/user/src/bin/sleep_simple.rs index 9f6e2e4..7015a3d 100644 --- a/user/src/bin/sleep_simple.rs +++ b/user/src/bin/sleep_simple.rs @@ -6,7 +6,7 @@ extern crate user_lib; use user_lib::{get_time, sleep}; -#[unsafe(no_mangle)] +#[no_mangle] pub fn main() -> i32 { println!("into sleep test!"); let start = get_time(); diff --git a/user/src/bin/stack_overflow.rs b/user/src/bin/stack_overflow.rs index 731982a..3bec557 100644 --- a/user/src/bin/stack_overflow.rs +++ b/user/src/bin/stack_overflow.rs @@ -12,7 +12,7 @@ fn f(depth: usize) { f(depth + 1); } -#[unsafe(no_mangle)] +#[no_mangle] pub fn main() -> i32 { println!("It should trigger segmentation fault!"); f(0); diff --git a/user/src/bin/user_shell.rs b/user/src/bin/user_shell.rs index 1ca120b..cdcb972 100644 --- a/user/src/bin/user_shell.rs +++ b/user/src/bin/user_shell.rs @@ -16,7 +16,7 @@ use alloc::string::String; use user_lib::console::getchar; use user_lib::{exec, fork, waitpid}; -#[unsafe(no_mangle)] +#[no_mangle] pub fn main() -> i32 { println!("Rust user shell"); let mut line: String = String::new(); diff --git a/user/src/bin/usertests.rs b/user/src/bin/usertests.rs index d47dc20..20cbbe9 100644 --- a/user/src/bin/usertests.rs +++ b/user/src/bin/usertests.rs @@ -84,7 +84,7 @@ fn run_tests(tests: &[(&str, &str, &str, &str, i32)]) -> i32 { pass_num } -#[unsafe(no_mangle)] +#[no_mangle] pub fn main() -> i32 { let succ_num = run_tests(SUCC_TESTS); let err_num = run_tests(FAIL_TESTS); diff --git a/user/src/bin/usertests_simple.rs b/user/src/bin/usertests_simple.rs index 0a73edd..62bc838 100644 --- a/user/src/bin/usertests_simple.rs +++ b/user/src/bin/usertests_simple.rs @@ -20,7 +20,7 @@ static TESTS: &[&str] = &[ use user_lib::{exec, fork, waitpid}; -#[unsafe(no_mangle)] +#[no_mangle] pub fn main() -> i32 { for test in TESTS { println!("Usertests: Running {}", test); diff --git a/user/src/bin/yield.rs b/user/src/bin/yield.rs index b9558ef..78b1468 100644 --- a/user/src/bin/yield.rs +++ b/user/src/bin/yield.rs @@ -5,7 +5,7 @@ extern crate user_lib; use user_lib::{getpid, yield_}; -#[unsafe(no_mangle)] +#[no_mangle] pub fn main() -> i32 { println!("Hello, I am process {}.", getpid()); for i in 0..5 { diff --git a/user/src/lang_items.rs b/user/src/lang_items.rs index b03e8eb..c65aa42 100644 --- a/user/src/lang_items.rs +++ b/user/src/lang_items.rs @@ -2,7 +2,7 @@ use super::exit; #[panic_handler] fn panic_handler(panic_info: &core::panic::PanicInfo) -> ! { - let err = panic_info.message(); + let err = panic_info.message().unwrap(); if let Some(location) = panic_info.location() { println!( "Panicked at {}:{}, {}", diff --git a/user/src/lib.rs b/user/src/lib.rs index a5584c2..c3b2cb9 100644 --- a/user/src/lib.rs +++ b/user/src/lib.rs @@ -1,5 +1,6 @@ #![no_std] #![feature(linkage)] +#![feature(panic_info_message)] #![feature(alloc_error_handler)] #[macro_use] @@ -12,7 +13,6 @@ extern crate alloc; extern crate bitflags; use buddy_system_allocator::LockedHeap; -use core::ptr::addr_of_mut; use syscall::*; const USER_HEAP_SIZE: usize = 32768; @@ -27,18 +27,18 @@ pub fn handle_alloc_error(layout: core::alloc::Layout) -> ! { panic!("Heap allocation error, layout = {:?}", layout); } -#[unsafe(no_mangle)] -#[unsafe(link_section = ".text.entry")] +#[no_mangle] +#[link_section = ".text.entry"] pub extern "C" fn _start() -> ! { unsafe { HEAP.lock() - .init(addr_of_mut!(HEAP_SPACE) as usize, USER_HEAP_SIZE); + .init(HEAP_SPACE.as_ptr() as usize, USER_HEAP_SIZE); } exit(main()); } #[linkage = "weak"] -#[unsafe(no_mangle)] +#[no_mangle] fn main() -> i32 { panic!("Cannot find main!"); }