diff --git a/user/Makefile b/user/Makefile new file mode 100644 index 0000000..9ec3185 --- /dev/null +++ b/user/Makefile @@ -0,0 +1,23 @@ +TARGET := riscv64gc-unknown-none-elf +MODE := release +APP_DIR := src/bin +TARGET_DIR := target/$(TARGET)/$(MODE) +APPS := $(wildcard $(APP_DIR)/*.rs) +ELFS := $(patsubst $(APP_DIR)/%.rs, $(TARGET_DIR)/%, $(APPS)) +BINS := $(patsubst $(APP_DIR)/%.rs, $(TARGET_DIR)/%.bin, $(APPS)) + +OBJDUMP := rust-objdump --arch-name=riscv64 +OBJCOPY := rust-objcopy --binary-architecture=riscv64 + +elf: $(APPS) + @cargo build --release + +binary: elf + @$(foreach elf, $(ELFS), $(OBJCOPY) $(elf) --strip-all -O binary $(patsubst $(TARGET_DIR)/%, $(TARGET_DIR)/%.bin, $(elf));) + +build: binary + +clean: + @cargo clean + +.PHONY: elf binary build clean \ No newline at end of file diff --git a/user/build.py b/user/build.py deleted file mode 100755 index c82f02e..0000000 --- a/user/build.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/python3 -import os - -base_address = 0x80400000 -step = 0x20000 -linker = 'src/linker.ld' -target_dir = "target/riscv64gc-unknown-none-elf/release/" - -app_id = 0 -apps = os.listdir('src/bin') -apps.sort() -for app in apps: - app = app[:app.find('.')] - lines = [] - lines_before = [] - with open(linker, 'r') as f: - for line in f.readlines(): - lines_before.append(line) - line = line.replace(hex(base_address), hex(base_address+step * app_id)) - lines.append(line) - with open(linker, 'w+') as f: - f.writelines(lines) - os.system('cargo build --bin %s --release' % app) - source_name = target_dir + app - dest_name = target_dir + app + ".bin" - os.system("rust-objcopy %s --binary-architecture=riscv64 --strip-all -O binary %s" %(source_name, dest_name)) - print('[build.py] application %s start with address %s' %(app, hex(base_address+step*app_id))) - with open(linker, 'w+') as f: - f.writelines(lines_before) - app_id = app_id + 1 \ No newline at end of file diff --git a/user/src/bin/load_fault.rs b/user/src/bin/load_fault.rs new file mode 100644 index 0000000..7e66362 --- /dev/null +++ b/user/src/bin/load_fault.rs @@ -0,0 +1,17 @@ +#![no_std] +#![no_main] + +#[macro_use] +extern crate user_lib; + +use core::ptr::{null_mut, read_volatile}; + +#[no_mangle] +fn main() -> i32 { + println!("Application 'load_fault' is running..."); + println!("Kernel should kill this application!"); + unsafe { + let _ = read_volatile(null_mut::()); + } + 0 +} \ No newline at end of file diff --git a/user/src/bin/set_break.rs b/user/src/bin/set_break.rs new file mode 100644 index 0000000..b9238d3 --- /dev/null +++ b/user/src/bin/set_break.rs @@ -0,0 +1,56 @@ +#![no_std] +#![no_main] + +#[macro_use] +extern crate user_lib; + +use core::ptr::slice_from_raw_parts_mut; +use user_lib::sys_set_break; + +#[no_mangle] +fn main() -> i32 { + println!("Test set break start..."); + const PAGE_SIZE: usize = 0x1000; + + let origin_break = sys_set_break(0); + println!("Origin break address is {:x}.", origin_break); + + let break_address = sys_set_break(PAGE_SIZE as i32); + if origin_break != break_address { + return -1; + } + + let break_address = sys_set_break(0); + println!("Now break address is {:x}.", break_address); + + println!("Try to write into allocated page."); + let new_page = unsafe { + &mut *slice_from_raw_parts_mut(origin_break as usize as *const u8 as *mut u8, PAGE_SIZE) + }; + for pos in 0..PAGE_SIZE { + new_page[pos] = 0; + } + println!("Write successfully."); + + sys_set_break(PAGE_SIZE as i32 * 10); + let break_address = sys_set_break(0); + println!("Allocated 10 more pages, break address is {:x}.", break_address); + + sys_set_break(PAGE_SIZE as i32 * -11); + let break_address = sys_set_break(0); + println!("Deallocated all 11 pages, break address is {:x}.", break_address); + + println!("Try to deallocated one more page, which should fail."); + let result = sys_set_break(PAGE_SIZE as i32 * -1); + if result == -1 { + println!("But succeed, exit!"); + return -1; + } + + println!("Try to write into deallocated pages, which should make this application killed by kernel."); + for pos in 0..PAGE_SIZE { + new_page[pos] = 0; + } + + 0 +} \ No newline at end of file diff --git a/user/src/lib.rs b/user/src/lib.rs index dcbfc32..506d0ee 100644 --- a/user/src/lib.rs +++ b/user/src/lib.rs @@ -11,7 +11,6 @@ pub mod console; #[no_mangle] #[link_section = ".text.entry"] pub extern "C" fn _start() -> ! { - utils::clear_bss(); exit(main()); panic!("Unreachable after exit main!"); } @@ -36,3 +35,7 @@ pub fn get_time() -> isize { pub fn sys_yield() -> isize { syscall::sys_yield() } + +pub fn sys_set_break(size: i32) -> isize { + syscall::sys_set_break(size) +} \ No newline at end of file diff --git a/user/src/linker.ld b/user/src/linker.ld index 9d48923..2df883d 100644 --- a/user/src/linker.ld +++ b/user/src/linker.ld @@ -1,7 +1,7 @@ OUTPUT_ARCH(riscv) ENTRY(_start) -BASE_ADDRESS = 0x80400000; +BASE_ADDRESS = 0x10000; SECTIONS { @@ -10,19 +10,19 @@ SECTIONS *(.text.entry) *(.text .text.*) } + . = ALIGN(4K); .rodata : { *(.rodata .rodata.*) *(.srodata .srodata.*) } + . = ALIGN(4K); .data : { *(.data .data.*) *(.sdata .sdata.*) } .bss : { - start_bss = .; *(.bss .bss.*) *(.sbss .sbss.*) - end_bss = .; } /DISCARD/ : { *(.eh_frame) diff --git a/user/src/syscall.rs b/user/src/syscall.rs index 44551fd..ed034e6 100644 --- a/user/src/syscall.rs +++ b/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_SET_BREAK: usize = 214; fn syscall(id: usize, args: [usize; 3]) -> isize { let mut result: isize; @@ -36,3 +37,7 @@ pub fn sys_yield() -> isize { pub fn sys_get_time() -> isize { syscall(SYSCALL_GET_TIME, [0, 0, 0]) } + +pub fn sys_set_break(size: i32) -> isize { + syscall(SYSCALL_SET_BREAK, [size as usize, 0, 0]) +} diff --git a/user/src/utils.rs b/user/src/utils.rs index 2644afe..a49ade0 100644 --- a/user/src/utils.rs +++ b/user/src/utils.rs @@ -1,18 +1,6 @@ use crate::println; use core::panic::PanicInfo; -pub fn clear_bss() { - extern "C" { - fn start_bss(); - - fn end_bss(); - } - - for i in start_bss as usize..end_bss as usize { - unsafe { (i as *mut u8).write_volatile(0) } - } -} - #[panic_handler] fn panic_handler(info: &PanicInfo) -> ! { let message = info.message();