add: chapter4 user applications
This commit is contained in:
parent
615a4b763c
commit
2bac1464a1
23
user/Makefile
Normal file
23
user/Makefile
Normal 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
|
|
@ -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
|
17
user/src/bin/load_fault.rs
Normal file
17
user/src/bin/load_fault.rs
Normal 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
56
user/src/bin/set_break.rs
Normal 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
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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])
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue
Block a user