running user program.

master
dzy 6 years ago
parent e74f749ff3
commit 4b17055f30

@ -22,15 +22,14 @@ if [[ ${RV32} = 1 ]]; then
COMPILER_RT_CFLAGS="-march=rv32ia -mabi=ilp32 -O3"
SFSIMG_CFLAGS="-march=rv32ia -mabi=ilp32"
RISCV_PK_CONFIGURE_FLAGS="--with-arch=rv32imac --disable-fp-emulation --host=riscv32-unknown-elf"
UCORE_USER_IMAGE="../user/img/ucore-rv32.img"
else
TARGET_ARCH=riscv64
export LOG=warn
COMPILER_RT_CFLAGS="-march=rv64ia -mabi=lp64 -O3"
SFSIMG_CFLAGS="-march=rv64ia -mabi=lp64"
RISCV_PK_CONFIGURE_FLAGS="--with-arch=rv64imac --disable-fp-emulation --host=riscv64-unknown-elf"
UCORE_USER_IMAGE="../user/img/ucore-riscv64.img"
fi
UCORE_USER_IMAGE="../user/hand/user-${TARGET_ARCH}.img"
# UCORE_USER_IMAGE="../user/build/user-${TARGET_ARCH}.img"
LLC=llc
RUST_SRC_PATH=$(rustc --print sysroot)/lib/rustlib/src/rust/src
CARGO_PATH=~/.cargo
@ -490,7 +489,11 @@ _user_img_start:
.incbin "${UCORE_USER_IMAGE}"
_user_img_end:
EOF
${CC} outdir/sfsimg.S ${SFSIMG_CFLAGS} -c -o outdir/sfsimg.o
if ! ${CC} outdir/sfsimg.S ${SFSIMG_CFLAGS} -c -o outdir/sfsimg.o
then
echo "You should manually create sfs image!"
exit 1
fi
${AR} r outdir/libsfsimg.a outdir/sfsimg.o
fi
@ -540,6 +543,7 @@ gen_full_rlib
if [[ ${K210} = 1 ]]; then
export LINK_K210='-L native=kendryte'
fi
echo "rustc crate-type bin to ${TARGET_JSON}"
rustc --edition=2018 --crate-name ucore src/main.rs \
--color always --crate-type bin --emit=link \
-C opt-level=1 \

@ -24,7 +24,8 @@ pub fn init() {
extern fn idle(_arg: usize) -> ! {
loop { cpu::halt(); }
}
for i in 0..4 {
// TODO: make #idle_thr equal to #cpu
for i in 0..1 {
manager.add(ContextImpl::new_kernel(idle, i), 0);
}
crate::shell::run_user_shell();

@ -12,7 +12,7 @@ use crate::thread;
use crate::util;
/// System call dispatcher
pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> i32 {
pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
let ret = match id {
// file
100 => sys_open(args[0] as *const u8, args[1]),
@ -28,9 +28,9 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> i32 {
130 => sys_dup(args[0], args[1]),
// process
001 => sys_exit(args[0] as i32),
001 => sys_exit(args[0] as isize),
002 => sys_fork(tf),
003 => sys_wait(args[0], args[1] as *mut i32),
003 => sys_wait(args[0], args[1] as *mut isize),
004 => sys_exec(args[0] as *const u8, args[1] as usize, args[2] as *const *const u8, tf),
// 005 => sys_clone(),
010 => sys_yield(),
@ -62,7 +62,7 @@ fn sys_read(fd: usize, base: *mut u8, len: usize) -> SysResult {
info!("read: fd: {}, base: {:?}, len: {:#x}", fd, base, len);
let slice = unsafe { slice::from_raw_parts_mut(base, len) };
let len = get_file(fd)?.lock().read(slice)?;
Ok(len as i32)
Ok(len as isize)
}
fn sys_write(fd: usize, base: *const u8, len: usize) -> SysResult {
@ -70,7 +70,7 @@ fn sys_write(fd: usize, base: *const u8, len: usize) -> SysResult {
info!("write: fd: {}, base: {:?}, len: {:#x}", fd, base, len);
let slice = unsafe { slice::from_raw_parts(base, len) };
let len = get_file(fd)?.lock().write(slice)?;
Ok(len as i32)
Ok(len as isize)
}
fn sys_open(path: *const u8, flags: usize) -> SysResult {
@ -89,7 +89,7 @@ fn sys_open(path: *const u8, flags: usize) -> SysResult {
};
let file = File::new(inode, flags.contains(VfsFlags::READABLE), flags.contains(VfsFlags::WRITABLE));
process().files.insert(fd, Arc::new(Mutex::new(file)));
Ok(fd as i32)
Ok(fd as isize)
}
fn sys_close(fd: usize) -> SysResult {
@ -146,12 +146,12 @@ fn sys_fork(tf: &TrapFrame) -> SysResult {
let pid = processor().manager().add(context, thread::current().id());
//memory_set_map_swappable(processor.get_context_mut(pid).get_memory_set_mut());
info!("fork: {} -> {}", thread::current().id(), pid);
Ok(pid as i32)
Ok(pid as isize)
}
/// Wait the process exit.
/// Return the PID. Store exit code to `code` if it's not null.
fn sys_wait(pid: usize, code: *mut i32) -> SysResult {
fn sys_wait(pid: usize, code: *mut isize) -> SysResult {
// TODO: check ptr
loop {
use alloc::vec;
@ -166,7 +166,7 @@ fn sys_wait(pid: usize, code: *mut i32) -> SysResult {
match processor().manager().get_status(pid) {
Some(Status::Exited(exit_code)) => {
if !code.is_null() {
unsafe { code.write(exit_code as i32); }
unsafe { code.write(exit_code as isize); }
}
processor().manager().remove(pid);
info!("wait: {} -> {}", thread::current().id(), pid);
@ -240,11 +240,11 @@ fn sys_kill(pid: usize) -> SysResult {
/// Get the current process id
fn sys_getpid() -> SysResult {
Ok(thread::current().id() as i32)
Ok(thread::current().id() as isize)
}
/// Exit the current process
fn sys_exit(exit_code: i32) -> SysResult {
fn sys_exit(exit_code: isize) -> SysResult {
let pid = thread::current().id();
info!("exit: {}, code: {}", pid, exit_code);
processor().manager().exit(pid, exit_code as usize);
@ -263,7 +263,7 @@ fn sys_sleep(time: usize) -> SysResult {
}
fn sys_get_time() -> SysResult {
unsafe { Ok(crate::trap::TICK as i32) }
unsafe { Ok(crate::trap::TICK as isize) }
}
fn sys_lab6_set_priority(priority: usize) -> SysResult {
@ -281,9 +281,9 @@ fn get_file(fd: usize) -> Result<&'static Arc<Mutex<File>>, SysError> {
process().files.get(&fd).ok_or(SysError::InvalidFile)
}
pub type SysResult = Result<i32, SysError>;
pub type SysResult = Result<isize, SysError>;
#[repr(i32)]
#[repr(isize)]
#[derive(Debug)]
pub enum SysError {
VfsError,

@ -0,0 +1,2 @@
output/
*.img

@ -0,0 +1,14 @@
#!/bin/bash
ARCH=riscv64
CC=${ARCH}-unknown-elf-gcc
CFLAGS="-nostartfiles -nostdlib -nodefaultlibs -o output/a.out -T ${ARCH}.ld -fno-builtin"
if ! [[ -d output ]]
then
mkdir output
fi
#CFLAGS="${CFLAGS} -DRISCV_QEMU"
${CC} ${CFLAGS} test.c
mksfs zip output ./user-${ARCH}.img

@ -0,0 +1,43 @@
OUTPUT_ARCH(riscv)
ENTRY(_start)
SECTIONS {
/* Load programs at this address: "." means the current address */
. = 0x00800020;
.text : {
*(.text .stub .text.* .gnu.linkonce.t.*)
}
PROVIDE(etext = .); /* Define the 'etext' symbol to this value */
.rodata : {
*(.rodata .rodata.* .gnu.linkonce.r.*)
}
/* Adjust the address for the data segment to the next page */
. = ALIGN(0x1000);
/* The data segment */
.data : {
*(.data)
*(.data.*)
}
.sdata : {
*(.sdata)
*(.sdata.*)
}
PROVIDE(edata = .);
.bss : {
*(.bss)
}
PROVIDE(end = .);
/DISCARD/ : {
*(.eh_frame .note.GNU-stack .comment)
}
}

@ -0,0 +1,43 @@
OUTPUT_ARCH(riscv)
ENTRY(_start)
SECTIONS {
/* Load programs at this address: "." means the current address */
. = 0x800020;
.text : {
*(.text .stub .text.* .gnu.linkonce.t.*)
}
PROVIDE(etext = .); /* Define the 'etext' symbol to this value */
.rodata : {
*(.rodata .rodata.* .gnu.linkonce.r.*)
}
/* Adjust the address for the data segment to the next page */
. = ALIGN(0x1000);
/* The data segment */
.data : {
*(.data)
*(.data.*)
}
.sdata : {
*(.sdata)
*(.sdata.*)
}
PROVIDE(edata = .);
.bss : {
*(.bss)
}
PROVIDE(end = .);
/DISCARD/ : {
*(.eh_frame .note.GNU-stack .comment)
}
}

@ -0,0 +1,87 @@
#ifdef RISCV_QEMU
# define SYS_write 64
# define SYS_exit 93
long syscall(long a0, long a1, long a2, long a3, long a4, long a5, long a6) {
register long _0 __asm__("a7") = a0;
register long _1 __asm__("a0") = a1;
register long _2 __asm__("a1") = a2;
register long _3 __asm__("a2") = a3;
register long _4 __asm__("a3") = a4;
register long _5 __asm__("a4") = a5;
register long _6 __asm__("a5") = a6;
__asm__ __volatile__("ecall":::);
return _1;
}
#else
# define SYS_write 103
# define SYS_exit 1
# define SYS_fork 2
# define SYS_putc 30
# define SYS_getpid 18
# define SYS_sleep 11
long syscall(long a0, long a1, long a2, long a3, long a4, long a5, long a6) {
register long _0 __asm__("x10") = a0;
register long _1 __asm__("x11") = a1;
register long _2 __asm__("x12") = a2;
register long _3 __asm__("x13") = a3;
register long _4 __asm__("x14") = a4;
register long _5 __asm__("x15") = a5;
register long _6 __asm__("x16") = a6;
__asm__ __volatile__("ecall":::);
return _0;
}
#endif
const char* welcome_msg = "hello world!\n";
const char* hexch = "0123456789ABCDEF";
void putc(char c) {
syscall(SYS_putc, c, 0, 0, 0, 0, 0);
}
void putstr(const char* s) {
for (; *s; s++)
syscall(SYS_putc, *s, 0, 0, 0, 0, 0);
}
void putint_hex(long v) {
char ch[18];
ch[16] = 'H';
ch[17] = 0;
for (int i = 15; i >= 0; i--) {
ch[i] = hexch[v & 15];
v >>= 4;
}
putstr(ch);
}
void _start() {
putstr(welcome_msg);
putc('\n');
putstr("my pid is ");
long v = syscall(SYS_getpid, 0, 0, 0, 0, 0, 0);
putint_hex(v);
putc('\n');
long v1 = syscall(SYS_fork, 0, 0, 0, 0, 0, 0);
putstr("fork returned: ");
putint_hex(v1);
putc('\n');
if (v1 != 0) {
putstr("parent sleeping");
putc('\n');
syscall(SYS_sleep, 200, 0, 0, 0, 0, 0);
}
putstr("my pid is ");
v = syscall(SYS_getpid, 0, 0, 0, 0, 0, 0);
putint_hex(v);
putc('\n');
putint_hex(v);
putstr(" is exiting");
putc('\n');
syscall(SYS_exit, 0, 0, 0, 0, 0, 0);
}

@ -0,0 +1,35 @@
{
"llvm-target": "riscv64",
"data-layout": "e-m:e-p:64:64-i64:64-n64-S128",
"target-endian": "little",
"target-pointer-width": "64",
"target-c-int-width": "32",
"os": "none",
"arch": "riscv64",
"cpu": "generic-rv64",
"features": "",
"max-atomic-width": "32",
"linker": "rust-lld",
"linker-flavor": "ld.lld",
"pre-link-args": {
"ld.lld": [
"-Tsrc/arch/riscv32/boot/linker64.ld"
]
},
"executables": true,
"panic-strategy": "abort",
"relocation-model": "static",
"abi-blacklist": [
"cdecl",
"stdcall",
"fastcall",
"vectorcall",
"thiscall",
"aapcs",
"win64",
"sysv64",
"ptx-kernel",
"msp430-interrupt",
"x86-interrupt"
]
}

@ -45,7 +45,11 @@ impl fmt::Write for SysPutc {
#[inline(always)]
fn sys_call(id: usize, arg0: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) -> i32 {
#[cfg(target_arch = "riscv64")]
let ret: i32 = 0;
#[cfg(target_arch = "riscv32")]
let ret: i32;
unsafe {
#[cfg(target_arch = "riscv32")]
asm!("ecall"

Loading…
Cancel
Save