Merge branch 'master' of https://github.com/wangrunji0408/RustOS into arch-aarch64

master
equation314 6 years ago
commit 28d872064d

9
.gitignore vendored

@ -1,11 +1,10 @@
build build
target target
/kernel/src/arch/x86_64/interrupt/vector.asm /kernel/src/arch/x86_64/interrupt/vector.asm
/crate/bit-allocator/Cargo.lock
/crate/memory/Cargo.lock Cargo.lock
/crate/bbl/Cargo.lock !kernel/Cargo.lock
/crate/sync/Cargo.lock !user/Cargo.lock
/crate/process/Cargo.lock
.DS_Store .DS_Store

@ -1,14 +0,0 @@
[[package]]
name = "atags"
version = "0.1.0"
dependencies = [
"volatile 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "volatile"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum volatile 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d9ca391c55768e479d5c2f8beb40c136df09257292a809ea514e82cfdfc15d00"

@ -63,6 +63,7 @@ minimum-image-size = 0 # The minimum output file size (in MiB)
# (the "{}" will be replaced with the path to the bootable disk image) # (the "{}" will be replaced with the path to the bootable disk image)
run-command = ["qemu-system-x86_64", run-command = ["qemu-system-x86_64",
"-drive", "format=raw,file={}", "-drive", "format=raw,file={}",
# TODO: use SFSIMG environment variable
"-drive", "format=raw,file=../user/img/ucore-i386-pic.img,media=disk,cache=writeback", "-drive", "format=raw,file=../user/img/ucore-i386-pic.img,media=disk,cache=writeback",
"-serial", "mon:stdio", "-serial", "mon:stdio",
"-device", "isa-debug-exit", "-device", "isa-debug-exit",

@ -12,6 +12,7 @@
# d = int | in_asm | ... QEMU debug info # d = int | in_asm | ... QEMU debug info
# mode = debug | release # mode = debug | release
# LOG = off | error | warn | info | debug | trace # LOG = off | error | warn | info | debug | trace
# SFSIMG = SFS image path of user programs
# smp = 1 | 2 | ... SMP core number # smp = 1 | 2 | ... SMP core number
# board = fpga Only available on riscv32, build without bbl, run on board # board = fpga Only available on riscv32, build without bbl, run on board
# | raspi3 Only available on aarch64, run on Raspberry Pi 3 Model B/B+ # | raspi3 Only available on aarch64, run on Raspberry Pi 3 Model B/B+
@ -31,6 +32,14 @@ kernel := target/$(target)/$(mode)/ucore
bin := target/$(target)/$(mode)/kernel.bin bin := target/$(target)/$(mode)/kernel.bin
bootimage := target/$(target)/bootimage.bin bootimage := target/$(target)/bootimage.bin
user_dir := ../user
user_bin_path := $(user_dir)/target/$(arch)-ucore/debug
user_bins := $(patsubst $(user_bin_path)/%.d, $(user_bin_path)/%, $(wildcard $(user_bin_path)/*.d))
user_obj := build/$(arch)/user.o
export ARCH = $(arch)
export SFSIMG = $(user_dir)/build/user-$(arch).img
### qemu options ### ### qemu options ###
qemu_opts := \ qemu_opts := \
-smp cores=$(smp) \ -smp cores=$(smp) \
@ -39,7 +48,7 @@ qemu_opts := \
ifeq ($(arch), x86_64) ifeq ($(arch), x86_64)
qemu_opts += \ qemu_opts += \
-drive format=raw,file=$(bootimage) \ -drive format=raw,file=$(bootimage) \
-drive format=raw,file="../user/img/ucore-i386-pic.img",media=disk,cache=writeback \ -drive format=raw,file=$(SFSIMG),media=disk,cache=writeback \
-serial mon:stdio \ -serial mon:stdio \
-device isa-debug-exit -device isa-debug-exit
@ -101,18 +110,19 @@ cc := $(prefix)gcc
as := $(prefix)as as := $(prefix)as
gdb := $(prefix)gdb gdb := $(prefix)gdb
.PHONY: all clean run build asm doc justrun kernel .PHONY: all clean run build asm doc justrun debug kernel sfsimg install
all: kernel all: kernel
clean: clean:
@cargo clean @cargo clean
@cd $(user_dir) && make clean
@rm -rf ../riscv-pk/build @rm -rf ../riscv-pk/build
doc: doc:
@cargo rustdoc -- --document-private-items @cargo rustdoc -- --document-private-items
run: build justrun run: build sfsimg justrun
justrun: justrun:
@qemu-system-$(arch) $(qemu_opts) || [ $$? -eq 11 ] # run qemu and assert it exit 11 @qemu-system-$(arch) $(qemu_opts) || [ $$? -eq 11 ] # run qemu and assert it exit 11
@ -158,17 +168,30 @@ else ifeq ($(arch), aarch64)
@$(objcopy) $(kernel) --strip-all -O binary $@ @$(objcopy) $(kernel) --strip-all -O binary $@
endif endif
kernel:
ifeq ($(arch), x86_64) ifeq ($(arch), x86_64)
kernel:
@bootimage build $(build_args) @bootimage build $(build_args)
else else
kernel: sfsimg
ifeq ($(arch), riscv32)
@-patch -p0 -N -b \ @-patch -p0 -N -b \
$(shell rustc --print sysroot)/lib/rustlib/src/rust/src/libcore/sync/atomic.rs \ $(shell rustc --print sysroot)/lib/rustlib/src/rust/src/libcore/sync/atomic.rs \
src/arch/riscv32/atomic.patch src/arch/riscv32/atomic.patch
endif
@CC=$(cc) cargo xbuild $(build_args) @CC=$(cc) cargo xbuild $(build_args)
endif endif
### user programs ###
sfsimg:
@cd $(user_dir) && make sfsimg
# make user.o from binary files
$(user_obj): $(user_bins)
@cd $(user_bin_path) && \
$(ld) -o $(abspath $@) $(patsubst %, -b binary %, $(notdir $(user_bins)))
### install ### ### install ###
ifeq ($(board), raspi3) ifeq ($(board), raspi3)
sd_card ?= sd_card ?=

@ -1,10 +1,15 @@
extern crate cc; extern crate cc;
use std::fs::File; use std::fs::File;
use std::io::{Write, Result}; use std::path::Path;
use std::io::{Result, Write};
fn main() { fn main() {
if std::env::var("TARGET").unwrap().find("x86_64").is_some() { println!("cargo:rerun-if-env-changed=LOG");
let arch: String = std::env::var("ARCH").unwrap();
match arch.as_str() {
"x86_64" => {
// cc::Build::new() // cc::Build::new()
// .file("src/arch/x86_64/driver/apic/lapic.c") // .file("src/arch/x86_64/driver/apic/lapic.c")
// .file("src/arch/x86_64/driver/keyboard/keyboard.c") // .file("src/arch/x86_64/driver/keyboard/keyboard.c")
@ -12,12 +17,26 @@ fn main() {
// .compile("cobj"); // .compile("cobj");
gen_vector_asm().unwrap(); gen_vector_asm().unwrap();
} }
if std::env::var("TARGET").unwrap().find("riscv32").is_some() { "riscv32" => {
cc::Build::new() cc::Build::new()
.file("src/arch/riscv32/compiler_rt.c") .file("src/arch/riscv32/compiler_rt.c")
.flag("-march=rv32ia") .flag("-march=rv32ia")
.flag("-mabi=ilp32") .flag("-mabi=ilp32")
.compile("atomic_rt"); .compile("atomic_rt");
if let Ok(file_path) = gen_sfsimg_asm() {
cc::Build::new()
.file(&file_path)
.flag("-march=rv32ia")
.flag("-mabi=ilp32")
.compile("sfsimg");
}
}
"aarch64" => {
if let Ok(file_path) = gen_sfsimg_asm() {
cc::Build::new().file(&file_path).compile("sfsimg");
}
}
_ => panic!("Unknown arch {}", arch),
} }
} }
@ -44,3 +63,27 @@ fn gen_vector_asm() -> Result<()> {
} }
Ok(()) Ok(())
} }
fn gen_sfsimg_asm() -> Result<std::path::PathBuf> {
let out_dir = std::env::var("OUT_DIR").unwrap();
let sfsimg = std::env::var("SFSIMG").unwrap();
let file_path = Path::new(&out_dir).join("sfsimg.S");
let mut f = File::create(&file_path).unwrap();
write!(f, "# generated by build.rs - do not edit")?;
write!(f, r#"
.section .rodata
.align 12
.global _user_img_start
.global _user_img_end
_user_img_start:
.incbin "{}"
_user_img_end:
"#, sfsimg)?;
println!("cargo:rerun-if-changed={}", sfsimg);
println!("cargo:rerun-if-env-changed=SFSIMG");
Ok(file_path)
}

@ -8,30 +8,6 @@ use crate::arch::driver::ide;
use crate::sync::Condvar; use crate::sync::Condvar;
use crate::sync::SpinNoIrqLock as Mutex; use crate::sync::SpinNoIrqLock as Mutex;
// Hard link user program
#[cfg(target_arch = "riscv32")]
global_asm!(r#"
.section .rodata
.align 12
.global _user_img_start
.global _user_img_end
_user_img_start:
.incbin "../user/img/ucore-rv32.img"
_user_img_end:
"#);
// Hard link user program
#[cfg(target_arch = "aarch64")]
global_asm!(r#"
.section .rodata
.align 12
.global _user_img_start
.global _user_img_end
_user_img_start:
.incbin "../user/img/ucore-aarch64.img"
_user_img_end:
"#);
lazy_static! { lazy_static! {
pub static ref ROOT_INODE: Arc<INode> = { pub static ref ROOT_INODE: Arc<INode> = {
#[cfg(any(target_arch = "riscv32", target_arch = "aarch64"))] #[cfg(any(target_arch = "riscv32", target_arch = "aarch64"))]
@ -40,6 +16,7 @@ lazy_static! {
fn _user_img_start(); fn _user_img_start();
fn _user_img_end(); fn _user_img_end();
} }
// Hard link user program
Box::new(unsafe { MemBuf::new(_user_img_start, _user_img_end) }) Box::new(unsafe { MemBuf::new(_user_img_start, _user_img_end) })
}; };
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]

@ -6,12 +6,15 @@ use crate::fs::{ROOT_INODE, INodeExt};
use crate::process::*; use crate::process::*;
pub fn run_user_shell() { pub fn run_user_shell() {
let inode = ROOT_INODE.lookup("sh").unwrap(); if let Ok(inode) = ROOT_INODE.lookup("sh") {
let data = inode.read_as_vec().unwrap(); let data = inode.read_as_vec().unwrap();
processor().manager().add(ContextImpl::new_user(data.as_slice(), "sh".split(' ')), 0); processor().manager().add(ContextImpl::new_user(data.as_slice(), "sh".split(' ')), 0);
} else {
processor().manager().add(ContextImpl::new_kernel(shell, 0), 0);
}
} }
pub fn shell() { pub extern fn shell(_arg: usize) -> ! {
let files = ROOT_INODE.list().unwrap(); let files = ROOT_INODE.list().unwrap();
println!("Available programs: {:?}", files); println!("Available programs: {:?}", files);

@ -284,6 +284,7 @@ fn get_file(fd: usize) -> Result<&'static Arc<Mutex<File>>, SysError> {
pub type SysResult = Result<i32, SysError>; pub type SysResult = Result<i32, SysError>;
#[repr(i32)] #[repr(i32)]
#[derive(Debug)]
pub enum SysError { pub enum SysError {
VfsError, VfsError,
InvalidFile, InvalidFile,

@ -1,5 +1,59 @@
# arch = {riscv32, x86_64, aarch64} # arch = {riscv32, x86_64, aarch64}
arch := riscv32 # mode = {debug, release}
arch ?= riscv32
mode ?= debug
all: rust_src_dir := src/bin
cargo xbuild --target $(arch)-ucore.json rust_bin_path := target/$(arch)-ucore/$(mode)
user_rust_bins := $(patsubst $(rust_src_dir)/%.rs, $(rust_bin_path)/%, $(wildcard $(rust_src_dir)/*.rs))
c_src_dir :=
c_bin_path :=
user_c_bins :=
user_bins := $(user_rust_bins) $(user_c_bins)
build_path := build
sfsroot := $(build_path)/sfsroot-$(arch)
sfsimg := $(build_path)/user-$(arch).img
mksfs := mksfs
build_args := --target $(arch)-ucore.json
ifeq ($(mode), release)
build_args := $(build_args) --release
endif
.PHONY: all clean build-rust build-c build mksfs sfsimg
all: $(sfsimg)
build-rust:
@echo Building user rust programs
@cargo xbuild $(build_args)
build-c:
@echo Building user C programs
build: build-rust build-c
$(user_rust_bins): build-rust
$(user_c_bins): build-c
mksfs:
ifeq ($(shell which $(mksfs)),)
@cargo install --git https://github.com/wangrunji0408/SimpleFileSystem-Rust --features="std"
endif
$(sfsroot): $(user_bins)
@mkdir -p $@
@cp $^ $@/
$(sfsimg): $(user_bins) $(sfsroot) | mksfs
@echo Creating SFS image at $@
@$(mksfs) zip $(sfsroot) $@
sfsimg: $(sfsimg)
clean:
@cargo clean
@rm -rf $(build_path)

@ -13,6 +13,11 @@
"linker": "rust-lld", "linker": "rust-lld",
"linker-flavor": "ld.lld", "linker-flavor": "ld.lld",
"linker-is-gnu": true, "linker-is-gnu": true,
"pre-link-args": {
"ld.lld": [
"-Tsrc/arch/aarch64/user.ld"
]
},
"llvm-target": "aarch64-unknown-none", "llvm-target": "aarch64-unknown-none",
"no-compiler-rt": true, "no-compiler-rt": true,
"features": "+a53,+strict-align,-neon", "features": "+a53,+strict-align,-neon",

@ -11,6 +11,11 @@
"max-atomic-width": "32", "max-atomic-width": "32",
"linker": "rust-lld", "linker": "rust-lld",
"linker-flavor": "ld.lld", "linker-flavor": "ld.lld",
"pre-link-args": {
"ld.lld": [
"-Tsrc/arch/riscv32/user.ld"
]
},
"executables": true, "executables": true,
"panic-strategy": "abort", "panic-strategy": "abort",
"relocation-model": "static", "relocation-model": "static",

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

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

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

@ -7,5 +7,7 @@ extern crate ucore_ulib;
// IMPORTANT: Must define main() like this // IMPORTANT: Must define main() like this
#[no_mangle] #[no_mangle]
pub fn main() { pub fn main() {
println!("Hello uCore!"); println!("Hello Rust uCore!");
println!("I am process {}.", ucore_ulib::syscall::sys_getpid());
println!("hello pass.");
} }

@ -1,15 +1,47 @@
use crate::syscall::sys_exit; use crate::syscall::{sys_close, sys_dup, sys_exit, sys_open};
use crate::syscall::{O_RDONLY, O_WRONLY};
use core::alloc::Layout; use core::alloc::Layout;
use core::panic::PanicInfo; use core::panic::PanicInfo;
// used for panic
macro_rules! print {
($($arg:tt)*) => ({
$crate::syscall::print_putc(format_args!($($arg)*));
});
}
#[linkage = "weak"] #[linkage = "weak"]
#[no_mangle] #[no_mangle]
fn main() { fn main() {
panic!("No main() linked"); 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] #[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 <stdin> failed: {}.", fd);
}
let fd = initfd(1, "stdout:", O_WRONLY);
if fd < 0 {
panic!("open <stdout> failed: {}.", fd);
}
main(); main();
sys_exit(0) sys_exit(0)
} }
@ -31,12 +63,12 @@ fn oom(_: Layout) -> ! {
} }
#[no_mangle] #[no_mangle]
pub extern fn abort() -> ! { pub extern "C" fn abort() -> ! {
sys_exit(2) sys_exit(2)
} }
#[no_mangle] #[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; let mut r: u32 = 0;
while a > 0 { while a > 0 {

@ -17,14 +17,29 @@ pub fn print(args: fmt::Arguments) {
StdOut.write_fmt(args).unwrap(); StdOut.write_fmt(args).unwrap();
} }
pub fn print_putc(args: fmt::Arguments) {
SysPutc.write_fmt(args).unwrap();
}
struct StdOut; struct StdOut;
struct SysPutc;
impl fmt::Write for StdOut { impl fmt::Write for StdOut {
fn write_str(&mut self, s: &str) -> fmt::Result { fn write_str(&mut self, s: &str) -> fmt::Result {
match sys_write(0, s.as_ptr(), s.len()) { if sys_write(1, s.as_ptr(), s.len()) >= 0 {
0 => Ok(()), Ok(())
_ => Err(fmt::Error::default()), } 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) 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. /// Fork the current process. Return the child's PID.
pub fn sys_fork() -> i32 { pub fn sys_fork() -> i32 {
sys_call(SYS_FORK, 0, 0, 0, 0, 0, 0) 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_GETDIRENTRY: usize = 128;
const SYS_DUP: usize = 130; const SYS_DUP: usize = 130;
const SYS_LAB6_SET_PRIORITY: usize = 255; 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

@ -9,6 +9,11 @@
"executables": true, "executables": true,
"linker": "rust-lld", "linker": "rust-lld",
"linker-flavor": "ld.lld", "linker-flavor": "ld.lld",
"pre-link-args": {
"ld.lld": [
"-Tsrc/arch/x86_64/user.ld"
]
},
"panic-strategy": "abort", "panic-strategy": "abort",
"disable-redzone": true, "disable-redzone": true,
"features": "-mmx,-sse,+soft-float" "features": "-mmx,-sse,+soft-float"

Loading…
Cancel
Save