Skip to main content

starry_kernel/
entry.rs

1use alloc::{
2    string::{String, ToString},
3    sync::Arc,
4};
5
6use ax_fs::FS_CONTEXT;
7use ax_hal::uspace::UserContext;
8use ax_sync::Mutex;
9use ax_task::{AxTaskExt, spawn_task};
10use starry_process::{Pid, Process};
11
12use crate::{
13    file::FD_TABLE,
14    mm::{copy_from_kernel, load_user_app, new_user_aspace_empty},
15    pseudofs::{self, dev::tty::N_TTY},
16    task::{ProcessData, Thread, add_task_to_table, new_user_task, spawn_alarm_task},
17};
18
19/// Initialize and run initproc.
20pub fn init(args: &[String], envs: &[String]) {
21    static_keys::global_init();
22    pseudofs::mount_all().expect("Failed to mount pseudofs");
23    spawn_alarm_task();
24
25    let loc = FS_CONTEXT
26        .lock()
27        .resolve(&args[0])
28        .expect("Failed to resolve executable path");
29    let path = loc
30        .absolute_path()
31        .expect("Failed to get executable absolute path");
32    let name = loc.name().into_owned();
33
34    let mut uspace = new_user_aspace_empty()
35        .and_then(|mut it| {
36            copy_from_kernel(&mut it)?;
37            Ok(it)
38        })
39        .expect("Failed to create user address space");
40
41    let (entry_vaddr, ustack_top) = load_user_app(&mut uspace, None, args, envs)
42        .unwrap_or_else(|e| panic!("Failed to load user app: {}", e));
43
44    let uctx = UserContext::new(entry_vaddr.into(), ustack_top, 0);
45    let mut task = new_user_task(&name, uctx, 0);
46    task.ctx_mut().set_page_table_root(uspace.page_table_root());
47
48    let pid = task.id().as_u64() as Pid;
49    let proc = Process::new_init(pid);
50    proc.add_thread(pid);
51
52    N_TTY.bind_to(&proc).expect("Failed to bind ntty");
53
54    let proc = ProcessData::new(
55        proc,
56        path.to_string(),
57        Arc::new(args.to_vec()),
58        Arc::new(Mutex::new(uspace)),
59        Arc::default(),
60        None,
61    );
62
63    {
64        let mut scope = proc.scope.write();
65        crate::file::add_stdio(&mut FD_TABLE.scope_mut(&mut scope).write())
66            .expect("Failed to add stdio");
67    }
68
69    let thr = Thread::new(pid, proc, None);
70    *task.task_ext_mut() = Some(AxTaskExt::from_impl(thr));
71
72    let task = spawn_task(task);
73    add_task_to_table(&task);
74
75    // TODO: wait for all processes to finish
76    let exit_code = task.join();
77    info!("Init process exited with code: {exit_code:?}");
78
79    let cx = FS_CONTEXT.lock();
80    cx.root_dir()
81        .unmount_all()
82        .expect("Failed to unmount all filesystems");
83    cx.root_dir()
84        .filesystem()
85        .flush()
86        .expect("Failed to flush rootfs");
87}