starina_api/
start.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
use starina_types::handle::HandleId;
use starina_types::syscall::VsyscallPage;

use crate::allocator;
use crate::environ::Environ;
use crate::syscall::process_exit;
use crate::syscall::{self};
use crate::vmspace::VmSpace;

// TODO: Avoid Mutex.
static APP_VMSPACE: spin::Mutex<Option<VmSpace>> = spin::Mutex::new(None);

pub fn app_vmspace_handle() -> HandleId {
    APP_VMSPACE.lock().as_ref().unwrap().handle().id()
}

fn parse_environ(vsyscall: &VsyscallPage) -> Environ {
    let env_bytes =
        unsafe { ::core::slice::from_raw_parts(vsyscall.environ_ptr, vsyscall.environ_len) };
    let env_str = ::core::str::from_utf8(env_bytes).unwrap();

    Environ::parse(env_str)
}

extern "Rust" {
    fn main(env: Environ);
}

#[no_mangle]
pub unsafe extern "C" fn start_rust(vsyscall_page: *const VsyscallPage) {
    // SAFETY: Vsyscall page will be always available at the same
    //         address.
    let vsyscall = unsafe { &*vsyscall_page };

    syscall::set_vsyscall(vsyscall);
    allocator::init();

    let mut env = parse_environ(vsyscall);

    let vmspace = env.take_vmspace("vmspace").unwrap();
    APP_VMSPACE.lock().replace(vmspace);

    main(env);
    process_exit();
}