From e86229cb71cffe92f007e6e279b2c8ac448425b8 Mon Sep 17 00:00:00 2001 From: equation314 Date: Sun, 2 Dec 2018 19:44:05 +0800 Subject: [PATCH] user: user rust programs are runnable --- kernel/build.rs | 2 +- kernel/src/process/context.rs | 4 +++ kernel/src/syscall.rs | 1 + user/aarch64-ucore.json | 5 +++ user/riscv32-ucore.json | 7 +++- user/src/arch/aarch64/user.ld | 46 ++++++++++++++++++++++++ user/src/arch/riscv32/user.ld | 46 ++++++++++++++++++++++++ user/src/arch/x86_64/user.ld | 46 ++++++++++++++++++++++++ user/src/bin/{hello.rs => hello_rust.rs} | 4 ++- user/ucore-ulib/src/lang_items.rs | 42 +++++++++++++++++++--- user/ucore-ulib/src/syscall.rs | 37 +++++++++++++++++-- user/x86_64-ucore.json | 5 +++ 12 files changed, 234 insertions(+), 11 deletions(-) create mode 100644 user/src/arch/aarch64/user.ld create mode 100644 user/src/arch/riscv32/user.ld create mode 100644 user/src/arch/x86_64/user.ld rename user/src/bin/{hello.rs => hello_rust.rs} (50%) diff --git a/kernel/build.rs b/kernel/build.rs index e85f6f3..73117d7 100644 --- a/kernel/build.rs +++ b/kernel/build.rs @@ -33,7 +33,7 @@ fn main() { } "aarch64" => { if let Ok(file_path) = gen_sfsimg_asm() { - cc::Build::new().file(&file_path).compile("cobj"); + cc::Build::new().file(&file_path).compile("sfsimg"); } } _ => panic!("Unknown arch {}", arch), diff --git a/kernel/src/process/context.rs b/kernel/src/process/context.rs index 14b78b7..e5b5829 100644 --- a/kernel/src/process/context.rs +++ b/kernel/src/process/context.rs @@ -110,6 +110,10 @@ impl ContextImpl { unsafe { memory_set.with(|| { for ph in elf.program_iter() { + if ph.get_type() != Ok(Type::Load) { + continue; + } + let virt_addr = ph.virtual_addr() as usize; let offset = ph.offset() as usize; let file_size = ph.file_size() as usize; diff --git a/kernel/src/syscall.rs b/kernel/src/syscall.rs index 98a0f9e..4935c29 100644 --- a/kernel/src/syscall.rs +++ b/kernel/src/syscall.rs @@ -284,6 +284,7 @@ fn get_file(fd: usize) -> Result<&'static Arc>, SysError> { pub type SysResult = Result; #[repr(i32)] +#[derive(Debug)] pub enum SysError { VfsError, InvalidFile, diff --git a/user/aarch64-ucore.json b/user/aarch64-ucore.json index 357c2e3..7d9e167 100644 --- a/user/aarch64-ucore.json +++ b/user/aarch64-ucore.json @@ -13,6 +13,11 @@ "linker": "rust-lld", "linker-flavor": "ld.lld", "linker-is-gnu": true, + "pre-link-args": { + "ld.lld": [ + "-Tsrc/arch/aarch64/user.ld" + ] + }, "llvm-target": "aarch64-unknown-none", "no-compiler-rt": true, "features": "+a53,+strict-align,-neon", diff --git a/user/riscv32-ucore.json b/user/riscv32-ucore.json index 37dac6f..354279e 100644 --- a/user/riscv32-ucore.json +++ b/user/riscv32-ucore.json @@ -11,6 +11,11 @@ "max-atomic-width": "32", "linker": "rust-lld", "linker-flavor": "ld.lld", + "pre-link-args": { + "ld.lld": [ + "-Tsrc/arch/riscv32/user.ld" + ] + }, "executables": true, "panic-strategy": "abort", "relocation-model": "static", @@ -27,4 +32,4 @@ "msp430-interrupt", "x86-interrupt" ] -} \ No newline at end of file +} diff --git a/user/src/arch/aarch64/user.ld b/user/src/arch/aarch64/user.ld new file mode 100644 index 0000000..b989922 --- /dev/null +++ b/user/src/arch/aarch64/user.ld @@ -0,0 +1,46 @@ +/* Simple linker script for ucore user-level programs. + See the GNU ld 'info' manual ("info ld") to learn the syntax. */ + +OUTPUT_ARCH(aarch64) +ENTRY(_start) + +SECTIONS { + /* Load programs at this address: "." means the current address */ + . = 0xffff000000000000; + + .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) + } +} diff --git a/user/src/arch/riscv32/user.ld b/user/src/arch/riscv32/user.ld new file mode 100644 index 0000000..80ac4e5 --- /dev/null +++ b/user/src/arch/riscv32/user.ld @@ -0,0 +1,46 @@ +/* Simple linker script for ucore user-level programs. + See the GNU ld 'info' manual ("info ld") to learn the syntax. */ + +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) + } +} diff --git a/user/src/arch/x86_64/user.ld b/user/src/arch/x86_64/user.ld new file mode 100644 index 0000000..b135c9f --- /dev/null +++ b/user/src/arch/x86_64/user.ld @@ -0,0 +1,46 @@ +/* Simple linker script for ucore user-level programs. + See the GNU ld 'info' manual ("info ld") to learn the syntax. */ + +OUTPUT_ARCH(x86_64) +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) + } +} diff --git a/user/src/bin/hello.rs b/user/src/bin/hello_rust.rs similarity index 50% rename from user/src/bin/hello.rs rename to user/src/bin/hello_rust.rs index 5a29680..72e3040 100644 --- a/user/src/bin/hello.rs +++ b/user/src/bin/hello_rust.rs @@ -7,5 +7,7 @@ extern crate ucore_ulib; // IMPORTANT: Must define main() like this #[no_mangle] pub fn main() { - println!("Hello uCore!"); + println!("Hello Rust uCore!"); + println!("I am process {}.", ucore_ulib::syscall::sys_getpid()); + println!("hello pass."); } diff --git a/user/ucore-ulib/src/lang_items.rs b/user/ucore-ulib/src/lang_items.rs index 89e5334..29aff8c 100644 --- a/user/ucore-ulib/src/lang_items.rs +++ b/user/ucore-ulib/src/lang_items.rs @@ -1,15 +1,47 @@ -use syscall::sys_exit; +use syscall::{sys_close, sys_dup, sys_exit, sys_open}; +use syscall::{O_RDONLY, O_WRONLY}; use core::alloc::Layout; use core::panic::PanicInfo; +// used for panic +macro_rules! print { + ($($arg:tt)*) => ({ + $crate::syscall::print_putc(format_args!($($arg)*)); + }); +} + #[linkage = "weak"] #[no_mangle] fn main() { panic!("No main() linked"); } +fn initfd(fd2: usize, path: &str, open_flags: usize) -> i32 { + let fd1 = sys_open(path, open_flags); + if fd1 < 0 { + return fd1; + } + let mut ret = fd1; + let fd1 = fd1 as usize; + if fd1 != fd2 { + sys_close(fd2); + ret = sys_dup(fd1, fd2); + sys_close(fd1); + } + return ret; +} + #[no_mangle] -pub extern fn _start(_argc: isize, _argv: *const *const u8) -> ! { +pub extern "C" fn _start(_argc: isize, _argv: *const *const u8) -> ! { + let fd = initfd(0, "stdin:", O_RDONLY); + if fd < 0 { + panic!("open failed: {}.", fd); + } + let fd = initfd(1, "stdout:", O_WRONLY); + if fd < 0 { + panic!("open failed: {}.", fd); + } + main(); sys_exit(0) } @@ -31,12 +63,12 @@ fn oom(_: Layout) -> ! { } #[no_mangle] -pub extern fn abort() -> ! { +pub extern "C" fn abort() -> ! { sys_exit(2) } #[no_mangle] -pub extern fn __mulsi3(mut a: u32, mut b: u32) -> u32 { +pub extern "C" fn __mulsi3(mut a: u32, mut b: u32) -> u32 { let mut r: u32 = 0; while a > 0 { @@ -48,4 +80,4 @@ pub extern fn __mulsi3(mut a: u32, mut b: u32) -> u32 { } r -} \ No newline at end of file +} diff --git a/user/ucore-ulib/src/syscall.rs b/user/ucore-ulib/src/syscall.rs index f707142..1a75785 100644 --- a/user/ucore-ulib/src/syscall.rs +++ b/user/ucore-ulib/src/syscall.rs @@ -17,14 +17,29 @@ pub fn print(args: fmt::Arguments) { StdOut.write_fmt(args).unwrap(); } +pub fn print_putc(args: fmt::Arguments) { + SysPutc.write_fmt(args).unwrap(); +} + struct StdOut; +struct SysPutc; impl fmt::Write for StdOut { fn write_str(&mut self, s: &str) -> fmt::Result { - match sys_write(0, s.as_ptr(), s.len()) { - 0 => Ok(()), - _ => Err(fmt::Error::default()), + if sys_write(1, s.as_ptr(), s.len()) >= 0 { + Ok(()) + } else { + Err(fmt::Error::default()) + } + } +} + +impl fmt::Write for SysPutc { + fn write_str(&mut self, s: &str) -> fmt::Result { + for c in s.bytes() { + sys_putc(c as char); } + Ok(()) } } @@ -77,6 +92,10 @@ pub fn sys_close(fd: usize) -> i32 { sys_call(SYS_CLOSE, fd, 0, 0, 0, 0, 0) } +pub fn sys_dup(fd1: usize, fd2: usize) -> i32 { + sys_call(SYS_DUP, fd1, fd2, 0, 0, 0, 0) +} + /// Fork the current process. Return the child's PID. pub fn sys_fork() -> i32 { sys_call(SYS_FORK, 0, 0, 0, 0, 0, 0) @@ -144,3 +163,15 @@ const SYS_GETCWD: usize = 121; const SYS_GETDIRENTRY: usize = 128; const SYS_DUP: usize = 130; const SYS_LAB6_SET_PRIORITY: usize = 255; + +/* VFS flags */ +// TODO: use bitflags +// flags for open: choose one of these +pub const O_RDONLY: usize = 0; // open for reading only +pub const O_WRONLY: usize = 1; // open for writing only +pub const O_RDWR: usize = 2; // open for reading and writing +// then or in any of these: +pub const O_CREAT: usize = 0x00000004; // create file if it does not exist +pub const O_EXCL: usize = 0x00000008; // error if O_CREAT and the file exists +pub const O_TRUNC: usize = 0x00000010; // truncate file upon open +pub const O_APPEND: usize = 0x00000020; // append on each write diff --git a/user/x86_64-ucore.json b/user/x86_64-ucore.json index 6510efa..a8ace2c 100644 --- a/user/x86_64-ucore.json +++ b/user/x86_64-ucore.json @@ -9,6 +9,11 @@ "executables": true, "linker": "rust-lld", "linker-flavor": "ld.lld", + "pre-link-args": { + "ld.lld": [ + "-Tsrc/arch/x86_64/user.ld" + ] + }, "panic-strategy": "abort", "disable-redzone": true, "features": "-mmx,-sse,+soft-float"