diff --git a/src/arch/x86_64/start.rs b/src/arch/x86_64/start.rs index cdf213759a5010fcba5825019cd8d18c1f933e9c..8c70df825d21e5d10d04284dd4336ab0b0e1b042 100644 --- a/src/arch/x86_64/start.rs +++ b/src/arch/x86_64/start.rs @@ -3,6 +3,7 @@ /// It must create the IDT with the correct entries, those entries are /// defined in other files inside of the `arch` module +use core::slice; use core::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; use acpi; @@ -32,31 +33,28 @@ pub static CPU_COUNT: AtomicUsize = ATOMIC_USIZE_INIT; pub static AP_READY: AtomicBool = ATOMIC_BOOL_INIT; static BSP_READY: AtomicBool = ATOMIC_BOOL_INIT; -extern { - /// Kernel main function - fn kmain(cpus: usize) -> !; - /// Kernel main for APs - fn kmain_ap(id: usize) -> !; -} - #[repr(packed)] pub struct KernelArgs { kernel_base: u64, kernel_size: u64, stack_base: u64, stack_size: u64, + env_base: u64, + env_size: u64, } /// The entry to Rust, all things must be initialized #[no_mangle] pub unsafe extern fn kstart(args_ptr: *const KernelArgs) -> ! { - { + let env = { let args = &*args_ptr; let kernel_base = args.kernel_base as usize; let kernel_size = args.kernel_size as usize; let stack_base = args.stack_base as usize; let stack_size = args.stack_size as usize; + let env_base = args.env_base as usize; + let env_size = args.env_size as usize; // BSS should already be zero { @@ -69,6 +67,7 @@ pub unsafe extern fn kstart(args_ptr: *const KernelArgs) -> ! { println!("Kernel: {:X}:{:X}", kernel_base, kernel_base + kernel_size); println!("Stack: {:X}:{:X}", stack_base, stack_base + stack_size); + println!("Env: {:X}:{:X}", env_base, env_base + env_size); // Initialize memory management memory::init(0, kernel_base + ((kernel_size + 4095)/4096) * 4096); @@ -128,9 +127,11 @@ pub unsafe extern fn kstart(args_ptr: *const KernelArgs) -> ! { memory::init_noncore(); BSP_READY.store(true, Ordering::SeqCst); - } - kmain(CPU_COUNT.load(Ordering::SeqCst)); + slice::from_raw_parts(env_base as *const u8, env_size) + }; + + ::kmain(CPU_COUNT.load(Ordering::SeqCst), env); } #[repr(packed)] @@ -184,7 +185,7 @@ pub unsafe extern fn kstart_ap(args_ptr: *const KernelArgsAp) -> ! { interrupt::pause(); } - kmain_ap(cpu_id); + ::kmain_ap(cpu_id); } pub unsafe fn usermode(ip: usize, sp: usize, arg: usize) -> ! { diff --git a/src/lib.rs b/src/lib.rs index a848177bcbc78721edbb888d243bbb9eac1f9ec1..92c2dbbceaf7e072982ea029f26daa778e3a37ce 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,7 +36,10 @@ extern crate bitflags; extern crate goblin; extern crate spin; +use alloc::arc::Arc; use core::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; +use spin::Mutex; + use scheme::FileHandle; pub use consts::*; @@ -129,8 +132,7 @@ pub extern fn userspace_init() { } /// This is the kernel entry point for the primary CPU. The arch crate is responsible for calling this -#[no_mangle] -pub extern fn kmain(cpus: usize) { +pub fn kmain(cpus: usize, env: &[u8]) -> ! { CPU_ID.store(0, Ordering::SeqCst); CPU_COUNT.store(cpus, Ordering::SeqCst); @@ -138,11 +140,25 @@ pub extern fn kmain(cpus: usize) { let pid = syscall::getpid(); println!("BSP: {:?} {}", pid, cpus); + println!("Env: {:?}", ::core::str::from_utf8(env)); match context::contexts_mut().spawn(userspace_init) { Ok(context_lock) => { let mut context = context_lock.write(); context.status = context::Status::Runnable; + + let mut context_env = context.env.lock(); + for line in env.split(|b| *b == b'\n') { + let mut parts = line.splitn(2, |b| *b == b'='); + if let Some(name) = parts.next() { + if let Some(data) = parts.next() { + context_env.insert( + name.to_vec().into_boxed_slice(), + Arc::new(Mutex::new(data.to_vec())) + ); + } + } + } }, Err(err) => { panic!("failed to spawn userspace_init: {:?}", err); @@ -163,21 +179,11 @@ pub extern fn kmain(cpus: usize) { } /// This is the main kernel entry point for secondary CPUs -#[no_mangle] #[allow(unreachable_code, unused_variables)] -pub extern fn kmain_ap(id: usize) { - println!("AP {}: Disabled", id); - - loop { - unsafe { - interrupt::disable(); - interrupt::halt(); - } - } +pub fn kmain_ap(id: usize) -> ! { + CPU_ID.store(id, Ordering::SeqCst); if cfg!(feature = "multi_core"){ - CPU_ID.store(id, Ordering::SeqCst); - context::init(); let pid = syscall::getpid(); @@ -194,8 +200,16 @@ pub extern fn kmain_ap(id: usize) { } } } - } + } else { + println!("AP {}: Disabled", id); + loop { + unsafe { + interrupt::disable(); + interrupt::halt(); + } + } + } } /// Allow exception handlers to send signal to arch-independant kernel