asterinas/kernel/src/device/mod.rs

104 lines
2.9 KiB
Rust

// SPDX-License-Identifier: MPL-2.0
mod full;
mod null;
mod pty;
mod random;
mod shm;
pub mod tty;
mod urandom;
mod zero;
#[cfg(all(target_arch = "x86_64", feature = "cvm_guest"))]
pub mod tdxguest;
use alloc::format;
use device_id::DeviceId;
pub use pty::{new_pty_pair, PtyMaster, PtySlave};
pub use random::Random;
pub use urandom::Urandom;
use crate::{
fs::{
device::{add_node, Device},
fs_resolver::FsPath,
path::PerMountFlags,
ramfs::RamFs,
},
prelude::*,
};
/// Init the device node in fs, must be called after mounting rootfs.
pub fn init_in_first_process(ctx: &Context) -> Result<()> {
let fs = ctx.thread_local.borrow_fs();
let fs_resolver = fs.resolver().read();
// Mount DevFS
let dev_path = fs_resolver.lookup(&FsPath::try_from("/dev")?)?;
dev_path.mount(RamFs::new(), PerMountFlags::default(), ctx)?;
let null = Arc::new(null::Null);
add_node(null, "null", &fs_resolver)?;
let zero = Arc::new(zero::Zero);
add_node(zero, "zero", &fs_resolver)?;
tty::init();
let tty = Arc::new(tty::TtyDevice);
add_node(tty, "tty", &fs_resolver)?;
let console = tty::system_console().clone();
add_node(console, "console", &fs_resolver)?;
for (index, tty) in tty::iter_n_tty().enumerate() {
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", &fs_resolver)?;
});
let random = Arc::new(random::Random);
add_node(random, "random", &fs_resolver)?;
let urandom = Arc::new(urandom::Urandom);
add_node(urandom, "urandom", &fs_resolver)?;
let full = Arc::new(full::Full);
add_node(full, "full", &fs_resolver)?;
pty::init_in_first_process(&fs_resolver, ctx)?;
shm::init_in_first_process(&fs_resolver, ctx)?;
Ok(())
}
// TODO: Implement a more scalable solution for ID-to-device mapping.
// Instead of hardcoding every device numbers in this function,
// a registration mechanism should be used to allow each driver to
// allocate device IDs either statically or dynamically.
pub fn get_device(devid: DeviceId) -> Result<Arc<dyn Device>> {
let major = devid.major();
let minor = devid.minor();
match (major, minor) {
(1, 3) => Ok(Arc::new(null::Null)),
(1, 5) => Ok(Arc::new(zero::Zero)),
(1, 7) => Ok(Arc::new(full::Full)),
(1, 8) => Ok(Arc::new(random::Random)),
(1, 9) => Ok(Arc::new(urandom::Urandom)),
(4, minor) => {
let Some(tty) = tty::iter_n_tty().nth(minor as usize) else {
return_errno_with_message!(Errno::EINVAL, "the TTY minor ID is invalid");
};
Ok(tty.clone())
}
(5, 0) => Ok(Arc::new(tty::TtyDevice)),
_ => return_errno_with_message!(Errno::EINVAL, "the device ID is invalid or unsupported"),
}
}