add: chapter4 user applications

This commit is contained in:
jackfiled 2024-08-01 13:39:46 +08:00
parent 615a4b763c
commit 2bac1464a1
8 changed files with 108 additions and 46 deletions

23
user/Makefile Normal file
View File

@ -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

View File

@ -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

View File

@ -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::<u8>());
}
0
}

56
user/src/bin/set_break.rs Normal file
View File

@ -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
}

View File

@ -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)
}

View File

@ -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)

View File

@ -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])
}

View File

@ -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();