yggdrasil/kernel/src/init.rs

83 lines
2.1 KiB
Rust

//! Kernel main process implementation: filesystem initialization and userspace init start
use abi::error::Error;
use alloc::borrow::ToOwned;
use kernel_fs::devfs;
use libk::runtime;
use libk_thread::thread::Thread;
use memfs::MemoryFilesystem;
use vfs::{impls::FnSymlink, IoContext, NodeRef};
use crate::{
fs::{FileBlockAllocator, INITRD_DATA},
proc::{self, random},
task::process::{ProcessImpl, ProcessManagerImpl},
};
fn setup_root() -> Result<NodeRef, Error> {
let initrd_data = INITRD_DATA.get();
let fs = MemoryFilesystem::<FileBlockAllocator>::from_slice(initrd_data.data).unwrap();
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> {
infoln!("In main");
runtime::spawn(ygg_driver_usb::bus::bus_handler())?;
devfs::root().add_child(
"tty",
FnSymlink::new(|| {
let thread = Thread::current();
let process = thread.process::<ProcessManagerImpl>();
if let Some(tty) = process.session_terminal() {
Ok(tty)
} else {
Err(Error::InvalidFile)
}
}),
)?;
ygg_driver_net_loopback::init();
ygg_driver_net_core::start_network_tasks()?;
#[cfg(feature = "fb_console")]
{
use crate::device::display::console::update_consoles_task;
runtime::spawn(async move {
update_consoles_task().await;
})?;
}
// Add keyboard device
devfs::add_named_char_device(&ygg_driver_input::KEYBOARD_DEVICE, "kbd".to_owned())?;
random::init();
let root = setup_root()?;
let mut ioctx = IoContext::new(root);
{
let group_id = ProcessImpl::create_group();
let (user_init, user_init_main) =
proc::load_binary(&mut ioctx, group_id, None, "/init", &["/init", "xxx"], &[])?;
let mut io = user_init.io.lock();
io.set_ioctx(ioctx);
drop(io);
user_init_main.enqueue();
}
Ok(())
}