yggdrasil/kernel/src/init.rs

90 lines
2.4 KiB
Rust

//! Kernel main process implementation: filesystem initialization and userspace init start
use abi::error::Error;
use libk::{
device::display::console,
fs::devfs,
random,
task::{binary::LoadOptions, process::Process, runtime, thread::Thread},
vfs::{impls::fn_hardlink, IoContext, NodeRef, OwnedFilename},
};
use memfs::MemoryFilesystem;
use crate::{
fs::{FileBlockAllocator, INITRD_DATA},
proc,
};
fn setup_root() -> Result<NodeRef, Error> {
let initrd_data = INITRD_DATA.try_get().ok_or(Error::DoesNotExist)?;
let fs = MemoryFilesystem::<FileBlockAllocator>::from_slice(initrd_data.data)?;
fs.root()
}
/// Kernel's "main" process function.
///
/// # Note
///
/// This function is meant to be used as a kernel-space process after all the platform-specific
/// initialization has finished.
pub fn kinit() -> Result<(), Error> {
log::info!("In main");
runtime::spawn(ygg_driver_usb::bus::bus_handler())?;
runtime::spawn(console::flush_consoles_task()).ok();
devfs::root()
.add_child(
OwnedFilename::new("tty").unwrap(),
fn_hardlink(|| {
let thread = Thread::current();
let process = thread.process();
process.session_terminal().ok_or(Error::InvalidOperation)
}),
)
.ok();
ygg_driver_net_loopback::init();
ygg_driver_net_core::start_network_tasks()?;
random::init();
let root = setup_root().inspect_err(|error| {
log::error!("Cannot setup root filesystem: {error:?}");
})?;
let mut ioctx = IoContext::new(root);
// TODO move this to userspace so it doesn't block the init process, maybe lazy-load on first
// attempt to load a module?
#[cfg(all(not(target_arch = "aarch64"), not(target_arch = "riscv64")))]
{
use libk::module::load_kernel_symbol_table;
load_kernel_symbol_table(&mut ioctx, "/kernel.sym")?;
}
{
let group_id = Process::create_group();
let options = LoadOptions {
group_id,
parent: None,
path: "/init",
args: &["/init", "xxx"],
envs: &[],
single_step: false,
disable_aslr: false,
};
let (user_init, user_init_main) = proc::load_binary(&mut ioctx, &options)?;
let mut io = user_init.io.lock();
io.set_ioctx(ioctx);
drop(io);
user_init_main.enqueue();
}
Ok(())
}