Optimize the initialization logic during Asterinas init phase
This commit is contained in:
parent
3882eb4000
commit
b1bbd6c3fe
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,19 +19,14 @@ use spin::Once;
|
|||
|
||||
static DEV_PTS: Once<Path> = 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(
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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<dyn Device>, path: &str) -> Result<Path> {
|
||||
let mut dev_path = {
|
||||
let fs_resolver = FsResolver::new();
|
||||
fs_resolver.lookup(&FsPath::try_from("/dev").unwrap())?
|
||||
};
|
||||
pub fn add_node(device: Arc<dyn Device>, path: &str, fs_resolver: &FsResolver) -> Result<Path> {
|
||||
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<dyn Device>, path: &str) -> Result<Path> {
|
|||
/// 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(())
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Arc<dyn BlockDevice>> {
|
|||
}
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<dyn FileSystem>, fs_path: &FsPath) -> Result<()> {
|
||||
let target_path = FsResolver::new().lookup(fs_path)?;
|
||||
pub fn mount_fs_at(
|
||||
fs: Arc<dyn FileSystem>,
|
||||
fs_path: &FsPath,
|
||||
fs_resolver: &FsResolver,
|
||||
) -> Result<()> {
|
||||
let target_path = fs_resolver.lookup(fs_path)?;
|
||||
target_path.mount(fs)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
static ROOT_MOUNT: Once<Arc<Mount>> = Once::new();
|
||||
|
||||
pub fn init_root_mount() {
|
||||
pub(super) fn init() {
|
||||
ROOT_MOUNT.call_once(|| -> Arc<Mount> {
|
||||
let rootfs = RamFS::new();
|
||||
Mount::new_root(rootfs)
|
||||
|
|
|
|||
|
|
@ -97,6 +97,6 @@ impl IpcPermission {
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn init() {
|
||||
semaphore::init();
|
||||
pub(super) fn init_in_first_kthread() {
|
||||
semaphore::init_in_first_kthread();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -354,7 +354,7 @@ static ID_ALLOCATOR: Once<SpinLock<IdAlloc>> = Once::new();
|
|||
/// Semaphore sets in system
|
||||
static SEMAPHORE_SETS: RwLock<BTreeMap<key_t, SemaphoreSet>> = 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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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<ext::BigtcpExt>;
|
||||
pub type BoundPort = aster_bigtcp::iface::BoundPort<ext::BigtcpExt>;
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Task> {
|
||||
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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<dyn Terminal>).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())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<dyn Terminal>)
|
||||
.set_control(ctx.process)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
/// Process stands for a set of threads that shares the same userspace.
|
||||
pub struct Process {
|
||||
// Immutable Part
|
||||
|
|
|
|||
|
|
@ -26,8 +26,9 @@ pub fn create_new_user_task(
|
|||
user_ctx: Box<UserContext>,
|
||||
thread_ref: Arc<Thread>,
|
||||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue