diff --git a/.gitignore b/.gitignore index fe8b1fd..975d0c4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,10 @@ build target /kernel/src/arch/x86_64/interrupt/vector.asm -/crate/bit-allocator/Cargo.lock -/crate/memory/Cargo.lock -/crate/bbl/Cargo.lock -/crate/sync/Cargo.lock -/crate/process/Cargo.lock + +Cargo.lock +!kernel/Cargo.lock +!user/Cargo.lock .DS_Store diff --git a/crate/atags/Cargo.lock b/crate/atags/Cargo.lock deleted file mode 100644 index 42d11eb..0000000 --- a/crate/atags/Cargo.lock +++ /dev/null @@ -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" diff --git a/kernel/Makefile b/kernel/Makefile index ef57cea..3f4f76b 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -12,6 +12,7 @@ # d = int | in_asm | ... QEMU debug info # mode = debug | release # LOG = off | error | warn | info | debug | trace +# SFSIMG = SFS image path of user programs # smp SMP core number # 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+ @@ -31,6 +32,7 @@ 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 +sfsroot := $(user_dir)/build/sfsroot-$(arch) sfsimg := $(user_dir)/build/user-$(arch).img export ARCH = $(arch) @@ -40,7 +42,7 @@ export SFSIMG = $(sfsimg) ifeq ($(arch), x86_64) qemu_opts := \ -drive format=raw,file=$(bootimage) \ - -drive format=raw,file=$(sfsimg),media=disk,cache=writeback \ + -drive format=raw,file=$(SFSIMG),media=disk,cache=writeback \ -smp cores=$(smp) \ -serial mon:stdio \ -device isa-debug-exit \ @@ -176,7 +178,7 @@ endif ### user programs ### -$(sfsimg): +$(sfsimg): $(sfsroot) @cd $(user_dir) && make sfsimg # make user.o from binary files diff --git a/kernel/build.rs b/kernel/build.rs index ec94d4e..e85f6f3 100644 --- a/kernel/build.rs +++ b/kernel/build.rs @@ -1,23 +1,42 @@ extern crate cc; use std::fs::File; -use std::io::{Write, Result}; +use std::path::Path; +use std::io::{Result, Write}; fn main() { - if std::env::var("TARGET").unwrap().find("x86_64").is_some() { -// cc::Build::new() -// .file("src/arch/x86_64/driver/apic/lapic.c") -// .file("src/arch/x86_64/driver/keyboard/keyboard.c") -// .flag("-mcmodel=large") -// .compile("cobj"); - gen_vector_asm().unwrap(); - } - if std::env::var("TARGET").unwrap().find("riscv32").is_some() { - cc::Build::new() - .file("src/arch/riscv32/compiler_rt.c") - .flag("-march=rv32ia") - .flag("-mabi=ilp32") - .compile("atomic_rt"); + println!("cargo:rerun-if-env-changed=LOG"); + + let arch: String = std::env::var("ARCH").unwrap(); + match arch.as_str() { + "x86_64" => { + // cc::Build::new() + // .file("src/arch/x86_64/driver/apic/lapic.c") + // .file("src/arch/x86_64/driver/keyboard/keyboard.c") + // .flag("-mcmodel=large") + // .compile("cobj"); + gen_vector_asm().unwrap(); + } + "riscv32" => { + cc::Build::new() + .file("src/arch/riscv32/compiler_rt.c") + .flag("-march=rv32ia") + .flag("-mabi=ilp32") + .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("cobj"); + } + } + _ => panic!("Unknown arch {}", arch), } } @@ -43,4 +62,28 @@ fn gen_vector_asm() -> Result<()> { writeln!(f, "\t.quad vector{}", i)?; } Ok(()) -} \ No newline at end of file +} + +fn gen_sfsimg_asm() -> Result { + 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) +} diff --git a/kernel/src/fs.rs b/kernel/src/fs.rs index 9fea7d7..a1a52f2 100644 --- a/kernel/src/fs.rs +++ b/kernel/src/fs.rs @@ -10,32 +10,19 @@ use crate::arch::driver::ide; use crate::sync::Condvar; 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/user-riscv.img" -_user_img_end: -"#); - lazy_static! { pub static ref ROOT_INODE: Arc = { - #[cfg(target_arch = "riscv32")] + #[cfg(any(target_arch = "riscv32", target_arch = "aarch64"))] let device = { extern { fn _user_img_start(); fn _user_img_end(); } + // Hard link user program Box::new(unsafe { MemBuf::new(_user_img_start, _user_img_end) }) }; #[cfg(target_arch = "x86_64")] let device = Box::new(ide::IDE::new(1)); - #[cfg(target_arch = "aarch64")] - let device = unimplemented!(); let sfs = SimpleFileSystem::open(device).expect("failed to open SFS"); sfs.root_inode() diff --git a/kernel/src/shell.rs b/kernel/src/shell.rs index 1dcd521..b8443f3 100644 --- a/kernel/src/shell.rs +++ b/kernel/src/shell.rs @@ -6,12 +6,15 @@ use crate::fs::{ROOT_INODE, INodeExt}; use crate::process::*; pub fn run_user_shell() { - let inode = ROOT_INODE.lookup("sh").unwrap(); - let data = inode.read_as_vec().unwrap(); - processor().manager().add(ContextImpl::new_user(data.as_slice(), "sh".split(' ')), 0); + if let Ok(inode) = ROOT_INODE.lookup("sh") { + let data = inode.read_as_vec().unwrap(); + 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(); println!("Available programs: {:?}", files);