lab-04: mmap, munmap

This commit is contained in:
Tateisi 2025-08-03 13:48:14 +08:00
parent eaacb4fa25
commit cc1a9a4751
14 changed files with 311 additions and 2 deletions

33
user/src/bin/ch4_mmap0.rs Normal file
View file

@ -0,0 +1,33 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
use user_lib::mmap;
/*
Test 04_1 OK!
*/
#[no_mangle]
fn main() -> i32 {
let start: usize = 0x10000000;
let len: usize = 4096;
let prot: usize = 3;
assert_eq!(0, mmap(start, len, prot));
for i in start..(start + len) {
let addr: *mut u8 = i as *mut u8;
unsafe {
*addr = i as u8;
}
}
for i in start..(start + len) {
let addr: *mut u8 = i as *mut u8;
unsafe {
assert_eq!(*addr, i as u8);
}
}
println!("Test 04_1 OK!");
0
}

25
user/src/bin/ch4_mmap1.rs Normal file
View file

@ -0,0 +1,25 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
use user_lib::mmap;
/*
访 error
*/
#[no_mangle]
fn main() -> i32 {
let start: usize = 0x10000000;
let len: usize = 4096;
let prot: usize = 1;
assert_eq!(0, mmap(start, len, prot));
let addr: *mut u8 = start as *mut u8;
unsafe {
*addr = start as u8;
}
println!("Should cause error, Test 04_2 fail!");
0
}

26
user/src/bin/ch4_mmap2.rs Normal file
View file

@ -0,0 +1,26 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
use user_lib::mmap;
/*
访 error
*/
#[no_mangle]
fn main() -> i32 {
let start: usize = 0x10000000;
let len: usize = 4096;
let prot: usize = 2;
assert_eq!(0, mmap(start, len, prot));
let addr: *mut u8 = start as *mut u8;
unsafe {
// *addr = start as u8; // can't write, R == 0 && W == 1 is illegal in riscv
assert!(*addr != 0);
}
println!("Should cause error, Test 04_2 fail!");
0
}

25
user/src/bin/ch4_mmap3.rs Normal file
View file

@ -0,0 +1,25 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
use user_lib::mmap;
/*
mmap -1 Test 04_4 test OK!
*/
#[no_mangle]
fn main() -> i32 {
let start: usize = 0x10000000;
let len: usize = 4096;
let prot: usize = 3;
assert_eq!(0, mmap(start, len, prot));
assert_eq!(mmap(start - len, len + 1, prot), -1);
assert_eq!(mmap(start + len + 1, len, prot), -1);
assert_eq!(mmap(start + len, len, 0), -1);
assert_eq!(mmap(start + len, len, prot | 8), -1);
println!("Test 04_4 test OK!");
0
}

36
user/src/bin/ch4_unmap.rs Normal file
View file

@ -0,0 +1,36 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
use user_lib::{mmap, munmap};
/*
Test 04_5 ummap OK!
*/
#[no_mangle]
fn main() -> i32 {
let start: usize = 0x10000000;
let len: usize = 4096;
let prot: usize = 3;
assert_eq!(0, mmap(start, len, prot));
assert_eq!(mmap(start + len, len * 2, prot), 0);
assert_eq!(munmap(start, len), 0);
assert_eq!(mmap(start - len, len + 1, prot), 0);
for i in (start - len)..(start + len * 3) {
let addr: *mut u8 = i as *mut u8;
unsafe {
*addr = i as u8;
}
}
for i in (start - len)..(start + len * 3) {
let addr: *mut u8 = i as *mut u8;
unsafe {
assert_eq!(*addr, i as u8);
}
}
println!("Test 04_5 ummap OK!");
0
}

View file

@ -0,0 +1,23 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
use user_lib::{mmap, munmap};
/*
Test 04_6 ummap2 OK!
*/
#[no_mangle]
fn main() -> i32 {
let start: usize = 0x10000000;
let len: usize = 4096;
let prot: usize = 3;
assert_eq!(0, mmap(start, len, prot));
assert_eq!(munmap(start, len + 1), -1);
assert_eq!(munmap(start + 1, len - 1), -1);
println!("Test 04_6 ummap2 OK!");
0
}

47
user/src/bin/ch4b_sbrk.rs Normal file
View file

@ -0,0 +1,47 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
use user_lib::sbrk;
use core::ptr::slice_from_raw_parts_mut;
#[no_mangle]
fn main() -> i32 {
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;
}
println!("Test sbrk failed!");
0
}

View file

@ -38,3 +38,11 @@ pub fn get_time() -> isize {
pub fn sbrk(size: i32) -> isize {
sys_sbrk(size)
}
pub fn munmap(start: usize, len: usize) -> isize {
sys_munmap(start, len)
}
pub fn mmap(start: usize, len: usize, prot: usize) -> isize {
sys_mmap(start, len, prot)
}

View file

@ -5,6 +5,8 @@ const SYSCALL_EXIT: usize = 93;
const SYSCALL_YIELD: usize = 124;
const SYSCALL_GET_TIME: usize = 169;
const SYSCALL_SBRK: usize = 214;
pub const SYSCALL_MMAP: usize = 222;
pub const SYSCALL_MUNMAP: usize = 215;
fn syscall(id: usize, args: [usize; 3]) -> isize {
let mut ret: isize;
@ -39,3 +41,11 @@ pub fn sys_get_time() -> isize {
pub fn sys_sbrk(size: i32) -> isize {
syscall(SYSCALL_SBRK, [size as usize, 0, 0])
}
pub fn sys_mmap(start: usize, len: usize, prot: usize) -> isize {
syscall(SYSCALL_MMAP, [start, len, prot])
}
pub fn sys_munmap(start: usize, len: usize) -> isize {
syscall(SYSCALL_MUNMAP, [start, len, 0])
}