From b1bbd6c3fef04d5f0d401f4d805b1c0bae2ff200 Mon Sep 17 00:00:00 2001 From: Chen Chengjun Date: Tue, 26 Aug 2025 03:07:03 +0000 Subject: [PATCH] Optimize the initialization logic during Asterinas init phase --- kernel/src/device/mod.rs | 25 +++++----- kernel/src/device/pty/mod.rs | 19 +++----- kernel/src/device/shm.rs | 7 +-- kernel/src/fs/device.rs | 15 ++---- kernel/src/fs/file_table.rs | 34 +------------- kernel/src/fs/mod.rs | 46 +++++++++++++++++-- kernel/src/fs/rootfs.rs | 22 +++++---- kernel/src/ipc/mod.rs | 4 +- kernel/src/ipc/semaphore/mod.rs | 4 +- kernel/src/ipc/semaphore/system_v/mod.rs | 4 +- kernel/src/ipc/semaphore/system_v/sem_set.rs | 2 +- kernel/src/lib.rs | 48 ++++++++++++-------- kernel/src/net/iface/mod.rs | 2 +- kernel/src/net/iface/poll.rs | 2 +- kernel/src/net/mod.rs | 4 +- kernel/src/process/mod.rs | 6 +++ kernel/src/process/posix_thread/builder.rs | 13 +++++- kernel/src/process/process/init_proc.rs | 8 ++-- kernel/src/process/process/mod.rs | 7 +++ kernel/src/thread/task.rs | 9 +++- kernel/src/thread/work_queue/mod.rs | 2 +- kernel/src/vdso.rs | 2 +- 22 files changed, 159 insertions(+), 126 deletions(-) diff --git a/kernel/src/device/mod.rs b/kernel/src/device/mod.rs index 66b600892..e5a5c7974 100644 --- a/kernel/src/device/mod.rs +++ b/kernel/src/device/mod.rs @@ -23,39 +23,42 @@ use crate::{ }; /// Init the device node in fs, must be called after mounting rootfs. -pub fn init() -> Result<()> { +pub fn init_in_first_process(ctx: &Context) -> Result<()> { + let fs = ctx.thread_local.borrow_fs(); + let fs_resolver = fs.resolver().read(); + let null = Arc::new(null::Null); - add_node(null, "null")?; + add_node(null, "null", &fs_resolver)?; let zero = Arc::new(zero::Zero); - add_node(zero, "zero")?; + add_node(zero, "zero", &fs_resolver)?; tty::init(); let tty = Arc::new(tty::TtyDevice); - add_node(tty, "tty")?; + add_node(tty, "tty", &fs_resolver)?; let console = tty::system_console().clone(); - add_node(console, "console")?; + add_node(console, "console", &fs_resolver)?; for (index, tty) in tty::iter_n_tty().enumerate() { - add_node(tty.clone(), &format!("tty{}", index))?; + add_node(tty.clone(), &format!("tty{}", index), &fs_resolver)?; } #[cfg(target_arch = "x86_64")] ostd::if_tdx_enabled!({ - add_node(Arc::new(tdxguest::TdxGuest), "tdx_guest")?; + add_node(Arc::new(tdxguest::TdxGuest), "tdx_guest", &fs_resolver)?; }); let random = Arc::new(random::Random); - add_node(random, "random")?; + add_node(random, "random", &fs_resolver)?; let urandom = Arc::new(urandom::Urandom); - add_node(urandom, "urandom")?; + add_node(urandom, "urandom", &fs_resolver)?; - pty::init()?; + pty::init_in_first_process(&fs_resolver)?; - shm::init()?; + shm::init_in_first_process(&fs_resolver)?; Ok(()) } diff --git a/kernel/src/device/pty/mod.rs b/kernel/src/device/pty/mod.rs index 8f5c1df70..5481b1c21 100644 --- a/kernel/src/device/pty/mod.rs +++ b/kernel/src/device/pty/mod.rs @@ -19,19 +19,14 @@ use spin::Once; static DEV_PTS: Once = Once::new(); -pub fn init() -> Result<()> { - let fs = FsResolver::new(); +pub fn init_in_first_process(fs_resolver: &FsResolver) -> Result<()> { + let dev = fs_resolver.lookup(&FsPath::try_from("/dev")?)?; + // Create the "pts" directory and mount devpts on it. + let devpts_path = + dev.new_fs_child("pts", InodeType::Dir, InodeMode::from_bits_truncate(0o755))?; + let devpts_mount = devpts_path.mount(DevPts::new())?; - let dev = fs.lookup(&FsPath::try_from("/dev")?)?; - let devpts_path = { - // Create the "pts" directory and mount devpts on it. - let devpts_path = - dev.new_fs_child("pts", InodeType::Dir, InodeMode::from_bits_truncate(0o755))?; - let devpts_mount = devpts_path.mount(DevPts::new())?; - Path::new_fs_root(devpts_mount) - }; - - DEV_PTS.call_once(|| devpts_path); + DEV_PTS.call_once(|| Path::new_fs_root(devpts_mount)); // Create the "ptmx" symlink. let ptmx = dev.new_fs_child( diff --git a/kernel/src/device/shm.rs b/kernel/src/device/shm.rs index bf3d0664d..e44f3d1c7 100644 --- a/kernel/src/device/shm.rs +++ b/kernel/src/device/shm.rs @@ -10,11 +10,8 @@ use crate::{ }; /// Initializes "/dev/shm" for POSIX shared memory usage. -pub fn init() -> Result<()> { - let dev_path = { - let fs = FsResolver::new(); - fs.lookup(&FsPath::try_from("/dev")?)? - }; +pub fn init_in_first_process(fs_resolver: &FsResolver) -> Result<()> { + let dev_path = fs_resolver.lookup(&FsPath::try_from("/dev")?)?; // Create the "shm" directory under "/dev" and mount a ramfs on it. let shm_path = diff --git a/kernel/src/fs/device.rs b/kernel/src/fs/device.rs index 917d20bd4..a54539ea7 100644 --- a/kernel/src/fs/device.rs +++ b/kernel/src/fs/device.rs @@ -102,11 +102,8 @@ impl DeviceId { /// /// If the parent path is not existing, `mkdir -p` the parent path. /// This function is used in registering device. -pub fn add_node(device: Arc, path: &str) -> Result { - let mut dev_path = { - let fs_resolver = FsResolver::new(); - fs_resolver.lookup(&FsPath::try_from("/dev").unwrap())? - }; +pub fn add_node(device: Arc, path: &str, fs_resolver: &FsResolver) -> Result { + let mut dev_path = fs_resolver.lookup(&FsPath::try_from("/dev").unwrap())?; let mut relative_path = { let relative_path = path.trim_start_matches('/'); if relative_path.is_empty() { @@ -157,7 +154,7 @@ pub fn add_node(device: Arc, path: &str) -> Result { /// Delete the device node from FS for the device. /// /// This function is used in unregistering device. -pub fn delete_node(path: &str) -> Result<()> { +pub fn delete_node(path: &str, fs_resolver: &FsResolver) -> Result<()> { let abs_path = { let device_path = path.trim_start_matches('/'); if device_path.is_empty() { @@ -166,10 +163,8 @@ pub fn delete_node(path: &str) -> Result<()> { String::from("/dev") + "/" + device_path }; - let (parent_path, name) = { - let fs_resolver = FsResolver::new(); - fs_resolver.lookup_dir_and_base_name(&FsPath::try_from(abs_path.as_str()).unwrap())? - }; + let (parent_path, name) = + fs_resolver.lookup_dir_and_base_name(&FsPath::try_from(abs_path.as_str()).unwrap())?; parent_path.unlink(&name)?; Ok(()) diff --git a/kernel/src/fs/file_table.rs b/kernel/src/fs/file_table.rs index 5a55c0529..7e81545a8 100644 --- a/kernel/src/fs/file_table.rs +++ b/kernel/src/fs/file_table.rs @@ -4,11 +4,7 @@ use core::sync::atomic::{AtomicU8, Ordering}; use aster_util::slot_vec::SlotVec; -use super::{ - file_handle::FileLike, - fs_resolver::{FsPath, FsResolver, AT_FDCWD}, - utils::{AccessMode, InodeMode}, -}; +use super::file_handle::FileLike; use crate::{ events::{Events, IoEvents, Observer, Subject}, fs::utils::StatusFlags, @@ -35,34 +31,6 @@ impl FileTable { } } - pub fn new_with_stdio() -> Self { - let mut table = SlotVec::new(); - let fs_resolver = FsResolver::new(); - let tty_path = FsPath::new(AT_FDCWD, "/dev/console").expect("cannot find tty"); - let stdin = { - let flags = AccessMode::O_RDONLY as u32; - let mode = InodeMode::S_IRUSR; - fs_resolver.open(&tty_path, flags, mode.bits()).unwrap() - }; - let stdout = { - let flags = AccessMode::O_WRONLY as u32; - let mode = InodeMode::S_IWUSR; - fs_resolver.open(&tty_path, flags, mode.bits()).unwrap() - }; - let stderr = { - let flags = AccessMode::O_WRONLY as u32; - let mode = InodeMode::S_IWUSR; - fs_resolver.open(&tty_path, flags, mode.bits()).unwrap() - }; - table.put(FileTableEntry::new(Arc::new(stdin), FdFlags::empty())); - table.put(FileTableEntry::new(Arc::new(stdout), FdFlags::empty())); - table.put(FileTableEntry::new(Arc::new(stderr), FdFlags::empty())); - Self { - table, - subject: Subject::new(), - } - } - pub fn len(&self) -> usize { self.table.slots_len() } diff --git a/kernel/src/fs/mod.rs b/kernel/src/fs/mod.rs index a61d6e3d4..3ff7c984a 100644 --- a/kernel/src/fs/mod.rs +++ b/kernel/src/fs/mod.rs @@ -29,7 +29,9 @@ use crate::{ fs::{ exfat::{ExfatFS, ExfatMountOptions}, ext2::Ext2, - fs_resolver::FsPath, + file_table::FdFlags, + fs_resolver::{FsPath, FsResolver}, + utils::{AccessMode, InodeMode}, }, prelude::*, }; @@ -51,7 +53,7 @@ fn start_block_device(device_name: &str) -> Result> { } } -pub fn lazy_init() { +pub fn init() { registry::init(); sysfs::init(); @@ -64,21 +66,57 @@ pub fn lazy_init() { exfat::init(); overlayfs::init(); + rootfs::init(); +} + +pub fn init_in_first_kthread(fs_resolver: &FsResolver) { + rootfs::init_in_first_kthread(fs_resolver).unwrap(); +} + +pub fn init_in_first_process(ctx: &Context) { //The device name is specified in qemu args as --serial={device_name} let ext2_device_name = "vext2"; let exfat_device_name = "vexfat"; + let fs = ctx.thread_local.borrow_fs(); + let fs_resolver = fs.resolver().read(); + if let Ok(block_device_ext2) = start_block_device(ext2_device_name) { let ext2_fs = Ext2::open(block_device_ext2).unwrap(); let target_path = FsPath::try_from("/ext2").unwrap(); println!("[kernel] Mount Ext2 fs at {:?} ", target_path); - self::rootfs::mount_fs_at(ext2_fs, &target_path).unwrap(); + self::rootfs::mount_fs_at(ext2_fs, &target_path, &fs_resolver).unwrap(); } if let Ok(block_device_exfat) = start_block_device(exfat_device_name) { let exfat_fs = ExfatFS::open(block_device_exfat, ExfatMountOptions::default()).unwrap(); let target_path = FsPath::try_from("/exfat").unwrap(); println!("[kernel] Mount ExFat fs at {:?} ", target_path); - self::rootfs::mount_fs_at(exfat_fs, &target_path).unwrap(); + self::rootfs::mount_fs_at(exfat_fs, &target_path, &fs_resolver).unwrap(); } + + // Initialize the file table for the first process. + let tty_path = FsPath::new(fs_resolver::AT_FDCWD, "/dev/console").expect("cannot find tty"); + let stdin = { + let flags = AccessMode::O_RDONLY as u32; + let mode = InodeMode::S_IRUSR; + fs_resolver.open(&tty_path, flags, mode.bits()).unwrap() + }; + let stdout = { + let flags = AccessMode::O_WRONLY as u32; + let mode = InodeMode::S_IWUSR; + fs_resolver.open(&tty_path, flags, mode.bits()).unwrap() + }; + let stderr = { + let flags = AccessMode::O_WRONLY as u32; + let mode = InodeMode::S_IWUSR; + fs_resolver.open(&tty_path, flags, mode.bits()).unwrap() + }; + + let mut file_table_ref = ctx.thread_local.borrow_file_table_mut(); + let mut file_table = file_table_ref.unwrap().write(); + + file_table.insert(Arc::new(stdin), FdFlags::empty()); + file_table.insert(Arc::new(stdout), FdFlags::empty()); + file_table.insert(Arc::new(stderr), FdFlags::empty()); } diff --git a/kernel/src/fs/rootfs.rs b/kernel/src/fs/rootfs.rs index 18a13a086..c2be37583 100644 --- a/kernel/src/fs/rootfs.rs +++ b/kernel/src/fs/rootfs.rs @@ -4,6 +4,7 @@ use core2::io::{Cursor, Read}; use cpio_decoder::{CpioDecoder, FileType}; use lending_iterator::LendingIterator; use libflate::gzip::Decoder as GZipDecoder; +use ostd::boot::boot_info; use spin::Once; use super::{ @@ -29,8 +30,8 @@ impl Read for BoxedReader<'_> { } /// Unpack and prepare the rootfs from the initramfs CPIO buffer. -pub fn init(initramfs_buf: &[u8]) -> Result<()> { - init_root_mount(); +pub fn init_in_first_kthread(fs_resolver: &FsResolver) -> Result<()> { + let initramfs_buf = boot_info().initramfs.expect("No initramfs found!"); let reader = { let mut initramfs_suffix = ""; @@ -53,7 +54,6 @@ pub fn init(initramfs_buf: &[u8]) -> Result<()> { reader }; let mut decoder = CpioDecoder::new(reader); - let fs = FsResolver::new(); loop { let Some(entry_result) = decoder.next() else { @@ -76,9 +76,9 @@ pub fn init(initramfs_buf: &[u8]) -> Result<()> { // The mkinitramfs script uses `find` command to ensure that the entries are // sorted that a directory always appears before its child directories and files. let (parent, name) = if let Some((prefix, last)) = entry_name.rsplit_once('/') { - (fs.lookup(&FsPath::try_from(prefix)?)?, last) + (fs_resolver.lookup(&FsPath::try_from(prefix)?)?, last) } else { - (fs.root().clone(), entry_name) + (fs_resolver.root().clone(), entry_name) }; let metadata = entry.metadata(); @@ -106,22 +106,26 @@ pub fn init(initramfs_buf: &[u8]) -> Result<()> { } } // Mount DevFS - let dev_path = fs.lookup(&FsPath::try_from("/dev")?)?; + let dev_path = fs_resolver.lookup(&FsPath::try_from("/dev")?)?; dev_path.mount(RamFS::new())?; println!("[kernel] rootfs is ready"); Ok(()) } -pub fn mount_fs_at(fs: Arc, fs_path: &FsPath) -> Result<()> { - let target_path = FsResolver::new().lookup(fs_path)?; +pub fn mount_fs_at( + fs: Arc, + fs_path: &FsPath, + fs_resolver: &FsResolver, +) -> Result<()> { + let target_path = fs_resolver.lookup(fs_path)?; target_path.mount(fs)?; Ok(()) } static ROOT_MOUNT: Once> = Once::new(); -pub fn init_root_mount() { +pub(super) fn init() { ROOT_MOUNT.call_once(|| -> Arc { let rootfs = RamFS::new(); Mount::new_root(rootfs) diff --git a/kernel/src/ipc/mod.rs b/kernel/src/ipc/mod.rs index 8e02c5115..156b8d240 100644 --- a/kernel/src/ipc/mod.rs +++ b/kernel/src/ipc/mod.rs @@ -97,6 +97,6 @@ impl IpcPermission { } } -pub(super) fn init() { - semaphore::init(); +pub(super) fn init_in_first_kthread() { + semaphore::init_in_first_kthread(); } diff --git a/kernel/src/ipc/semaphore/mod.rs b/kernel/src/ipc/semaphore/mod.rs index 6e9897413..8df065b8e 100644 --- a/kernel/src/ipc/semaphore/mod.rs +++ b/kernel/src/ipc/semaphore/mod.rs @@ -6,6 +6,6 @@ pub mod posix; pub mod system_v; -pub(super) fn init() { - system_v::init(); +pub(super) fn init_in_first_kthread() { + system_v::init_in_first_kthread(); } diff --git a/kernel/src/ipc/semaphore/system_v/mod.rs b/kernel/src/ipc/semaphore/system_v/mod.rs index f2e6e0c7e..89abcdc0a 100644 --- a/kernel/src/ipc/semaphore/system_v/mod.rs +++ b/kernel/src/ipc/semaphore/system_v/mod.rs @@ -15,6 +15,6 @@ bitflags! { } } -pub(super) fn init() { - sem_set::init(); +pub(super) fn init_in_first_kthread() { + sem_set::init_in_first_kthread(); } diff --git a/kernel/src/ipc/semaphore/system_v/sem_set.rs b/kernel/src/ipc/semaphore/system_v/sem_set.rs index cd64ad511..e229d1eed 100644 --- a/kernel/src/ipc/semaphore/system_v/sem_set.rs +++ b/kernel/src/ipc/semaphore/system_v/sem_set.rs @@ -354,7 +354,7 @@ static ID_ALLOCATOR: Once> = Once::new(); /// Semaphore sets in system static SEMAPHORE_SETS: RwLock> = RwLock::new(BTreeMap::new()); -pub(super) fn init() { +pub(super) fn init_in_first_kthread() { ID_ALLOCATOR.call_once(|| { let mut id_alloc = IdAlloc::with_capacity(SEMMNI + 1); // Remove the first index 0 diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index a6d4493c1..fa0d0bae9 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -38,7 +38,7 @@ use ostd::{ use process::{spawn_init_process, Process}; use sched::SchedPolicy; -use crate::{prelude::*, thread::kernel_thread::ThreadOptions}; +use crate::{fs::fs_resolver::FsResolver, prelude::*, thread::kernel_thread::ThreadOptions}; extern crate alloc; extern crate lru; @@ -91,7 +91,7 @@ pub fn main() { // Spawn the first kernel thread on BSP. let mut affinity = CpuSet::new_empty(); affinity.add(CpuId::bsp()); - ThreadOptions::new(init_thread) + ThreadOptions::new(first_kthread) .cpu_affinity(affinity) .sched_policy(SchedPolicy::Idle) .spawn(); @@ -105,12 +105,27 @@ pub fn init() { #[cfg(target_arch = "x86_64")] net::init(); sched::init(); - fs::rootfs::init(boot_info().initramfs.expect("No initramfs found!")).unwrap(); - device::init().unwrap(); syscall::init(); - #[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))] - vdso::init(); process::init(); + fs::init(); +} + +fn init_in_first_kthread(fs_resolver: &FsResolver) { + // Work queue should be initialized before interrupt is enabled, + // in case any irq handler uses work queue as bottom half + thread::work_queue::init_in_first_kthread(); + #[cfg(target_arch = "x86_64")] + net::init_in_first_kthread(); + fs::init_in_first_kthread(fs_resolver); + ipc::init_in_first_kthread(); +} + +fn init_in_first_process(ctx: &Context) { + device::init_in_first_process(ctx).unwrap(); + fs::init_in_first_process(ctx); + process::init_in_first_process(ctx); + #[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))] + vdso::init_in_first_process(); } fn ap_init() { @@ -133,21 +148,14 @@ fn ap_init() { .spawn(); } -fn init_thread() { +fn first_kthread() { println!("[kernel] Spawn init thread"); - // Work queue should be initialized before interrupt is enabled, - // in case any irq handler uses work queue as bottom half - thread::work_queue::init(); - #[cfg(target_arch = "x86_64")] - net::lazy_init(); - fs::lazy_init(); - ipc::init(); - // driver::pci::virtio::block::block_device_test(); - let thread = ThreadOptions::new(|| { - println!("[kernel] Hello world from kernel!"); - }) - .spawn(); - thread.join(); + + // TODO: After introducing the mount namespace, use an initial mount namespace to create + // the `FsResolver`, and the initial mount namespace should be passed to the first process. + let fs_resolver = FsResolver::new(); + + init_in_first_kthread(&fs_resolver); print_banner(); diff --git a/kernel/src/net/iface/mod.rs b/kernel/src/net/iface/mod.rs index 6c9831fe3..e30be2c6c 100644 --- a/kernel/src/net/iface/mod.rs +++ b/kernel/src/net/iface/mod.rs @@ -6,7 +6,7 @@ mod poll; mod sched; pub use init::{init, iter_all_ifaces, loopback_iface, virtio_iface}; -pub use poll::lazy_init; +pub(super) use poll::init_in_first_kthread; pub type Iface = dyn aster_bigtcp::iface::Iface; pub type BoundPort = aster_bigtcp::iface::BoundPort; diff --git a/kernel/src/net/iface/poll.rs b/kernel/src/net/iface/poll.rs index 36fec958b..648b8f4c3 100644 --- a/kernel/src/net/iface/poll.rs +++ b/kernel/src/net/iface/poll.rs @@ -13,7 +13,7 @@ use crate::{ WaitTimeout, }; -pub fn lazy_init() { +pub fn init_in_first_kthread() { for iface in iter_all_ifaces() { spawn_background_poll_thread(iface.clone()); } diff --git a/kernel/src/net/mod.rs b/kernel/src/net/mod.rs index afdb1386f..cabea6831 100644 --- a/kernel/src/net/mod.rs +++ b/kernel/src/net/mod.rs @@ -10,6 +10,6 @@ pub fn init() { } /// Lazy init should be called after spawning init thread. -pub fn lazy_init() { - iface::lazy_init(); +pub fn init_in_first_kthread() { + iface::init_in_first_kthread(); } diff --git a/kernel/src/process/mod.rs b/kernel/src/process/mod.rs index a8ff239b4..c81e20a31 100644 --- a/kernel/src/process/mod.rs +++ b/kernel/src/process/mod.rs @@ -35,7 +35,13 @@ pub use rlimit::ResourceType; pub use term_status::TermStatus; pub use wait::{do_wait, WaitOptions, WaitStatus}; +use crate::context::Context; + pub(super) fn init() { process::init(); posix_thread::futex::init(); } + +pub(super) fn init_in_first_process(ctx: &Context) { + process::init_in_first_process(ctx); +} diff --git a/kernel/src/process/posix_thread/builder.rs b/kernel/src/process/posix_thread/builder.rs index d86e27898..dd701d4bd 100644 --- a/kernel/src/process/posix_thread/builder.rs +++ b/kernel/src/process/posix_thread/builder.rs @@ -43,6 +43,7 @@ pub struct PosixThreadBuilder { sig_queues: SigQueues, sched_policy: SchedPolicy, fpu_context: FpuContext, + is_init_process: bool, } impl PosixThreadBuilder { @@ -61,6 +62,7 @@ impl PosixThreadBuilder { sig_queues: SigQueues::new(), sched_policy: SchedPolicy::Fair(Nice::default()), fpu_context: FpuContext::new(), + is_init_process: false, } } @@ -104,6 +106,12 @@ impl PosixThreadBuilder { self } + #[expect(clippy::wrong_self_convention)] + pub(in crate::process) fn is_init_process(mut self) -> Self { + self.is_init_process = true; + self + } + pub fn build(self) -> Arc { let Self { tid, @@ -119,9 +127,10 @@ impl PosixThreadBuilder { sig_queues, sched_policy, fpu_context, + is_init_process, } = self; - let file_table = file_table.unwrap_or_else(|| RwArc::new(FileTable::new_with_stdio())); + let file_table = file_table.unwrap_or_else(|| RwArc::new(FileTable::new())); let fs = fs.unwrap_or_else(|| Arc::new(ThreadFsInfo::default())); @@ -173,7 +182,7 @@ impl PosixThreadBuilder { ); thread_table::add_thread(tid, thread.clone()); - task::create_new_user_task(user_ctx, thread, thread_local) + task::create_new_user_task(user_ctx, thread, thread_local, is_init_process) }) } } diff --git a/kernel/src/process/process/init_proc.rs b/kernel/src/process/process/init_proc.rs index c8f3500e9..19e0a7d72 100644 --- a/kernel/src/process/process/init_proc.rs +++ b/kernel/src/process/process/init_proc.rs @@ -4,7 +4,7 @@ use ostd::{cpu::context::UserContext, task::Task, user::UserContextApi}; -use super::{Process, Terminal}; +use super::Process; use crate::{ fs::{ fs_resolver::{FsPath, AT_FDCWD}, @@ -36,9 +36,6 @@ pub fn spawn_init_process( set_session_and_group(&process); - // FIXME: This should be done by the userspace init process. - (crate::device::tty::system_console().clone() as Arc).set_control(&process)?; - process.run(); Ok(process) @@ -124,6 +121,7 @@ fn create_init_task( let thread_builder = PosixThreadBuilder::new(tid, Box::new(user_ctx), credentials) .thread_name(thread_name) .process(process) - .fs(Arc::new(fs)); + .fs(Arc::new(fs)) + .is_init_process(); Ok(thread_builder.build()) } diff --git a/kernel/src/process/process/mod.rs b/kernel/src/process/process/mod.rs index 6d753b795..cc4d7d90d 100644 --- a/kernel/src/process/process/mod.rs +++ b/kernel/src/process/process/mod.rs @@ -56,6 +56,13 @@ pub(super) fn init() { timer_manager::init(); } +pub(super) fn init_in_first_process(ctx: &Context) { + // FIXME: This should be done by the userspace init process. + (crate::device::tty::system_console().clone() as Arc) + .set_control(ctx.process) + .unwrap(); +} + /// Process stands for a set of threads that shares the same userspace. pub struct Process { // Immutable Part diff --git a/kernel/src/thread/task.rs b/kernel/src/thread/task.rs index ebc114ecd..c5a4c899c 100644 --- a/kernel/src/thread/task.rs +++ b/kernel/src/thread/task.rs @@ -26,8 +26,9 @@ pub fn create_new_user_task( user_ctx: Box, thread_ref: Arc, thread_local: ThreadLocal, + is_init_process: bool, ) -> Task { - fn user_task_entry(user_ctx: UserContext) { + let user_task_entry = move |user_ctx: UserContext| { let current_task = Task::current().unwrap(); let current_thread = current_task.as_thread().unwrap(); let current_posix_thread = current_thread.as_posix_thread().unwrap(); @@ -70,6 +71,10 @@ pub fn create_new_user_task( task: ¤t_task, }; + if is_init_process { + crate::init_in_first_process(&ctx); + } + while !current_thread.is_exited() { // Execute the user code ctx.thread_local.fpu().activate(); @@ -111,7 +116,7 @@ pub fn create_new_user_task( handle_pending_signal(user_ctx, &ctx, None); } } - } + }; let user_task_func = move || user_task_entry(*user_ctx); diff --git a/kernel/src/thread/work_queue/mod.rs b/kernel/src/thread/work_queue/mod.rs index ed2c18b65..d097b82d3 100644 --- a/kernel/src/thread/work_queue/mod.rs +++ b/kernel/src/thread/work_queue/mod.rs @@ -174,7 +174,7 @@ impl WorkQueue { } /// Initialize global worker pools and work queues. -pub fn init() { +pub fn init_in_first_kthread() { WORKERPOOL_NORMAL.call_once(|| { let cpu_set = CpuSet::new_full(); WorkerPool::new(WorkPriority::Normal, cpu_set) diff --git a/kernel/src/vdso.rs b/kernel/src/vdso.rs index c3ea9f374..404159b4c 100644 --- a/kernel/src/vdso.rs +++ b/kernel/src/vdso.rs @@ -351,7 +351,7 @@ fn init_vdso() { VDSO.call_once(|| Arc::new(vdso)); } -pub(super) fn init() { +pub(super) fn init_in_first_process() { init_start_secs_count(); init_vdso();