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