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]
|
#[no_mangle]
|
||||||
#[link_section = ".text.entry"]
|
#[link_section = ".text.entry"]
|
||||||
pub extern "C" fn _start() -> ! {
|
pub extern "C" fn _start() -> ! {
|
||||||
utils::clear_bss();
|
|
||||||
exit(main());
|
exit(main());
|
||||||
panic!("Unreachable after exit main!");
|
panic!("Unreachable after exit main!");
|
||||||
}
|
}
|
||||||
|
@ -36,3 +35,7 @@ pub fn get_time() -> isize {
|
||||||
pub fn sys_yield() -> isize {
|
pub fn sys_yield() -> isize {
|
||||||
syscall::sys_yield()
|
syscall::sys_yield()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn sys_set_break(size: i32) -> isize {
|
||||||
|
syscall::sys_set_break(size)
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
OUTPUT_ARCH(riscv)
|
OUTPUT_ARCH(riscv)
|
||||||
ENTRY(_start)
|
ENTRY(_start)
|
||||||
|
|
||||||
BASE_ADDRESS = 0x80400000;
|
BASE_ADDRESS = 0x10000;
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
|
@ -10,19 +10,19 @@ SECTIONS
|
||||||
*(.text.entry)
|
*(.text.entry)
|
||||||
*(.text .text.*)
|
*(.text .text.*)
|
||||||
}
|
}
|
||||||
|
. = ALIGN(4K);
|
||||||
.rodata : {
|
.rodata : {
|
||||||
*(.rodata .rodata.*)
|
*(.rodata .rodata.*)
|
||||||
*(.srodata .srodata.*)
|
*(.srodata .srodata.*)
|
||||||
}
|
}
|
||||||
|
. = ALIGN(4K);
|
||||||
.data : {
|
.data : {
|
||||||
*(.data .data.*)
|
*(.data .data.*)
|
||||||
*(.sdata .sdata.*)
|
*(.sdata .sdata.*)
|
||||||
}
|
}
|
||||||
.bss : {
|
.bss : {
|
||||||
start_bss = .;
|
|
||||||
*(.bss .bss.*)
|
*(.bss .bss.*)
|
||||||
*(.sbss .sbss.*)
|
*(.sbss .sbss.*)
|
||||||
end_bss = .;
|
|
||||||
}
|
}
|
||||||
/DISCARD/ : {
|
/DISCARD/ : {
|
||||||
*(.eh_frame)
|
*(.eh_frame)
|
||||||
|
|
|
@ -4,6 +4,7 @@ const SYSCALL_WRITE: usize = 64;
|
||||||
const SYSCALL_EXIT: usize = 93;
|
const SYSCALL_EXIT: usize = 93;
|
||||||
const SYSCALL_YIELD: usize = 124;
|
const SYSCALL_YIELD: usize = 124;
|
||||||
const SYSCALL_GET_TIME: usize = 169;
|
const SYSCALL_GET_TIME: usize = 169;
|
||||||
|
const SYSCALL_SET_BREAK: usize = 214;
|
||||||
|
|
||||||
fn syscall(id: usize, args: [usize; 3]) -> isize {
|
fn syscall(id: usize, args: [usize; 3]) -> isize {
|
||||||
let mut result: isize;
|
let mut result: isize;
|
||||||
|
@ -36,3 +37,7 @@ pub fn sys_yield() -> isize {
|
||||||
pub fn sys_get_time() -> isize {
|
pub fn sys_get_time() -> isize {
|
||||||
syscall(SYSCALL_GET_TIME, [0, 0, 0])
|
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 crate::println;
|
||||||
use core::panic::PanicInfo;
|
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]
|
#[panic_handler]
|
||||||
fn panic_handler(info: &PanicInfo) -> ! {
|
fn panic_handler(info: &PanicInfo) -> ! {
|
||||||
let message = info.message();
|
let message = info.message();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user