diff --git a/ch4/os/src/mm/memory_set.rs b/ch4/os/src/mm/memory_set.rs index ad8b250..b0864ca 100644 --- a/ch4/os/src/mm/memory_set.rs +++ b/ch4/os/src/mm/memory_set.rs @@ -155,8 +155,8 @@ impl MapArea { // 当前段, 缩小到新的结束位置, 即把new_end后面的页, 都还给物理页帧管理器, 并取消映射(通过unmap_one方法即可) pub fn shrink_to(&mut self, page_table: &mut PageTable, new_end: VirtPageNum) { let tmp_vpn_range = VPNRange{ - l: self.vpn_range.l, - r: new_end, + l: new_end, + r: self.vpn_range.r, }; for vpn in tmp_vpn_range { self.unmap_one(page_table, vpn) diff --git a/ch4/os/src/syscall/process.rs b/ch4/os/src/syscall/process.rs index 80706ef..a938295 100644 --- a/ch4/os/src/syscall/process.rs +++ b/ch4/os/src/syscall/process.rs @@ -20,7 +20,7 @@ pub fn sys_get_time() -> isize { get_time_ms() as isize } -// 根据传入的 size 对当前堆进行扩容和缩小 +// 根据传入的 size 对当前堆进行扩容和缩小, 返回值为 失败 或者 申请的空间的起始位置 pub fn sys_sbrk(size: i32) -> isize { if let Some(old_brk) = change_program_brk(size) { old_brk as isize diff --git a/ch4/os/src/task/task.rs b/ch4/os/src/task/task.rs index 4dfb19c..37f87cf 100644 --- a/ch4/os/src/task/task.rs +++ b/ch4/os/src/task/task.rs @@ -1,6 +1,7 @@ use crate::config::{kernel_stack_position, TRAP_CONTEXT}; use crate::mm::address::{PhysPageNum, VirtAddr}; use crate::mm::memory_set::{KERNEL_SPACE, MapPermission, MemorySet}; +use crate::println; use crate::task::context::{TaskContext}; use crate::trap::{trap_handler, TrapContext}; @@ -117,7 +118,7 @@ impl TaskControlBlock { self.memory_set .append_to(VirtAddr(self.heap_bottom), VirtAddr(new_brk as usize)) }; - + println!("size: {}, old_break: {}", size, old_break); // 如果成功就把新的堆顶的地址, 复制到结构提上记录, 并把旧的堆顶返回 if result { self.program_brk = new_brk as usize; diff --git a/ch4/user/src/bin/03load_fault.rs b/ch4/user/src/bin/03load_fault.rs index 811058c..e5a5596 100644 --- a/ch4/user/src/bin/03load_fault.rs +++ b/ch4/user/src/bin/03load_fault.rs @@ -7,12 +7,13 @@ use core::ptr::{null_mut, read_volatile}; #[no_mangle] fn main() -> i32 { - return 0; - // println!("\nload_fault APP running...\n"); - // println!("Into Test load_fault, we will insert an invalid load operation..."); - // println!("Kernel should kill this application!"); - // unsafe { - // let _i = read_volatile(null_mut::()); - // } - // 0 + println!("\nload_fault APP running...\n"); + // 在Test load_fault中,我们将插入一个无效的加载操作 + println!("Into Test load_fault, we will insert an invalid load operation..."); + // 内核应该终止这个应用程序! + println!("Kernel should kill this application!"); + unsafe { + let _i = read_volatile(null_mut::()); + } + 0 } \ No newline at end of file diff --git a/ch4/user/src/bin/05store_fault.rs b/ch4/user/src/bin/05store_fault.rs index 4d702d1..f62412e 100644 --- a/ch4/user/src/bin/05store_fault.rs +++ b/ch4/user/src/bin/05store_fault.rs @@ -5,12 +5,13 @@ use user_lib::*; #[no_mangle] fn main() -> i32 { - return 0; - // println!("\nload_fault APP running...\n"); - // println!("Into Test load_fault, we will insert an invalid load operation..."); - // println!("Kernel should kill this application!"); - // unsafe { - // let _i = read_volatile(null_mut::()); - // } - // 0 + println!("\nstore_fault APP running...\n"); + // 在Test store_fault中,我们将插入一个无效的存储操作… + println!("Into Test store_fault, we will insert an invalid store operation..."); + + println!("Kernel should kill this application!"); + unsafe { + null_mut::().write_volatile(1); + } + 0 } \ No newline at end of file diff --git a/ch4/user/src/bin/06sbrk_test.rs b/ch4/user/src/bin/06sbrk_test.rs index dd75b40..02a4a9e 100644 --- a/ch4/user/src/bin/06sbrk_test.rs +++ b/ch4/user/src/bin/06sbrk_test.rs @@ -3,44 +3,63 @@ use core::ptr::slice_from_raw_parts_mut; use user_lib::*; +use user_lib::syscall::sys_sbrk; #[no_mangle] fn main() -> i32 { - return 0; - // println!("Test sbrk start."); - // const PAGE_SIZE: usize = 0x1000; - // let origin_brk = sbrk(0); - // println!("origin break point = {:x}", origin_brk); - // let brk = sbrk(PAGE_SIZE as i32); - // if brk != origin_brk { - // return -1; - // } - // let brk = sbrk(0); - // println!("one page allocated, break point = {:x}", brk); - // println!("try write to allocated page"); - // let new_page = unsafe { - // &mut *slice_from_raw_parts_mut(origin_brk as usize as *const u8 as *mut u8, PAGE_SIZE) - // }; - // for pos in 0..PAGE_SIZE { - // new_page[pos] = 1; - // } - // println!("write ok"); - // sbrk(PAGE_SIZE as i32 * 10); - // let brk = sbrk(0); - // println!("10 page allocated, break point = {:x}", brk); - // sbrk(PAGE_SIZE as i32 * -11); - // let brk = sbrk(0); - // println!("11 page DEALLOCATED, break point = {:x}", brk); - // println!("try DEALLOCATED more one page, should be failed."); - // let ret = sbrk(PAGE_SIZE as i32 * -1); - // if ret != -1 { - // println!("Test sbrk failed!"); - // return -1; - // } - // println!("Test sbrk almost OK!"); - // println!("now write to deallocated page, should cause page fault."); - // for pos in 0..PAGE_SIZE { - // new_page[pos] = 2; - // } - // 0 + println!("Test sbrk start."); + + // 设置申请颗粒度 + const PAGE_SIZE: usize = 0x1000; + + // 查看当前堆 end + let origin_brk = sys_sbrk(0); + println!("origin break point = {:x}", origin_brk); + + // 申请一页 + let brk = sys_sbrk(PAGE_SIZE as i32); + if brk != origin_brk { + return -1; + } + + // 申请一页之后 查看堆 end + let brk = sys_sbrk(0); + println!("one page allocated, break point = {:x}", brk); + println!("try write to allocated page"); + + // 得到 申请的堆 的字节数组, 并写入为1 + let new_page = unsafe { + &mut *slice_from_raw_parts_mut(origin_brk as usize as *const u8 as *mut u8, PAGE_SIZE) + }; + for pos in 0..PAGE_SIZE { + new_page[pos] = 1; + } + println!("write ok"); + + // 再申请10页内存 并得到当前 堆end + sys_sbrk(PAGE_SIZE as i32 * 10); + let brk = sys_sbrk(0); + println!("10 page allocated, break point = {:x}", brk); + + // 释放 11页(之前已经申请了 1 + 10页了) + sys_sbrk(PAGE_SIZE as i32 * -11); + let brk = sys_sbrk(0); + println!("11 page DEALLOCATED, break point = {:x}", brk); + println!("try DEALLOCATED more one page, should be failed."); + + // 继续释放1页, 非法释放的测试 + let ret = sys_sbrk(PAGE_SIZE as i32 * -1); + if ret != -1 { + println!("Test sbrk failed!"); + return -1; + } + + println!("Test sbrk almost OK!"); + println!("now write to deallocated page, should cause page fault."); + for pos in 0..PAGE_SIZE { + new_page[pos] = 2; + } + println!("{:?}", new_page); + // 不应该走到这里 + 0 } \ No newline at end of file diff --git a/ch4/user/src/syscall.rs b/ch4/user/src/syscall.rs index 831658e..8612fe7 100644 --- a/ch4/user/src/syscall.rs +++ b/ch4/user/src/syscall.rs @@ -4,6 +4,7 @@ const SYSCALL_WRITE: usize = 64; const SYSCALL_EXIT: usize = 93; const SYSCALL_YIELD: usize = 124; const SYSCALL_GET_TIME: usize = 169; +const SYSCALL_SBRK: usize = 214; fn syscall(id: usize, args: [usize; 3]) -> isize { @@ -38,4 +39,8 @@ pub fn sys_get_time() -> isize { syscall(SYSCALL_GET_TIME, [0, 0, 0]) } +pub fn sys_sbrk(size: i32) -> isize { + syscall(SYSCALL_SBRK, [size as usize, 0, 0]) +} +