From 95dbf4f4f2d12560feff59f057911fc96ba2ab23 Mon Sep 17 00:00:00 2001 From: Matthew Leach Date: Wed, 25 Feb 2026 20:30:07 +0000 Subject: [PATCH] drviers: chrdev: random: new Add a new chardev which implements /dev/random. --- src/drivers/chrdev/mod.rs | 3 ++ src/drivers/{ => chrdev}/null.rs | 0 src/drivers/chrdev/random.rs | 90 ++++++++++++++++++++++++++++++++ src/drivers/{ => chrdev}/zero.rs | 0 src/drivers/mod.rs | 4 +- 5 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 src/drivers/chrdev/mod.rs rename src/drivers/{ => chrdev}/null.rs (100%) create mode 100644 src/drivers/chrdev/random.rs rename src/drivers/{ => chrdev}/zero.rs (100%) diff --git a/src/drivers/chrdev/mod.rs b/src/drivers/chrdev/mod.rs new file mode 100644 index 0000000..b355282 --- /dev/null +++ b/src/drivers/chrdev/mod.rs @@ -0,0 +1,3 @@ +pub mod null; +pub mod random; +pub mod zero; diff --git a/src/drivers/null.rs b/src/drivers/chrdev/null.rs similarity index 100% rename from src/drivers/null.rs rename to src/drivers/chrdev/null.rs diff --git a/src/drivers/chrdev/random.rs b/src/drivers/chrdev/random.rs new file mode 100644 index 0000000..0474f90 --- /dev/null +++ b/src/drivers/chrdev/random.rs @@ -0,0 +1,90 @@ +use crate::{ + drivers::{ + CharDriver, DriverManager, OpenableDevice, ReservedMajors, fs::dev::devfs, + init::PlatformBus, + }, + fs::{ + fops::FileOps, + open_file::{FileCtx, OpenFile}, + }, + kernel::rand::sys_getrandom, + kernel_driver, +}; +use alloc::{boxed::Box, string::ToString, sync::Arc}; +use async_trait::async_trait; +use core::{future::Future, pin::Pin}; +use libkernel::{ + driver::CharDevDescriptor, + error::Result, + fs::{OpenFlags, attr::FilePermissions}, + memory::address::UA, +}; + +struct RandomFileOps; + +#[async_trait] +impl FileOps for RandomFileOps { + async fn read(&mut self, _ctx: &mut FileCtx, buf: UA, count: usize) -> Result { + self.readat(buf, count, 0).await + } + + async fn writeat(&mut self, _buf: UA, count: usize, _offset: u64) -> Result { + // Just consume the write. + Ok(count) + } + + async fn readat(&mut self, buf: UA, count: usize, _offset: u64) -> Result { + sys_getrandom(buf.cast(), count as _, 0).await + } + + fn poll_read_ready(&self) -> Pin> + Send>> { + Box::pin(async { Ok(()) }) + } +} + +struct RandomDev; + +impl OpenableDevice for RandomDev { + fn open(&self, flags: OpenFlags) -> Result> { + Ok(Arc::new(OpenFile::new(Box::new(RandomFileOps), flags))) + } +} + +struct RandomCharDev { + random_dev: Arc, +} + +impl RandomCharDev { + fn new() -> Result { + devfs().mknod( + "random".to_string(), + CharDevDescriptor { + major: ReservedMajors::Random as _, + minor: 0, + }, + FilePermissions::from_bits_retain(0o666), + )?; + + Ok(Self { + random_dev: Arc::new(RandomDev), + }) + } +} + +impl CharDriver for RandomCharDev { + fn get_device(&self, minor: u64) -> Option> { + if minor == 0 { + Some(self.random_dev.clone()) + } else { + None + } + } +} + +/// Driver initialisation entry point invoked during kernel boot. +pub fn random_chardev_init(_bus: &mut PlatformBus, dm: &mut DriverManager) -> Result<()> { + let cdev = RandomCharDev::new()?; + dm.register_char_driver(ReservedMajors::Random as _, Arc::new(cdev)) +} + +kernel_driver!(random_chardev_init); diff --git a/src/drivers/zero.rs b/src/drivers/chrdev/zero.rs similarity index 100% rename from src/drivers/zero.rs rename to src/drivers/chrdev/zero.rs diff --git a/src/drivers/mod.rs b/src/drivers/mod.rs index 25f3ff5..c4342db 100644 --- a/src/drivers/mod.rs +++ b/src/drivers/mod.rs @@ -20,20 +20,20 @@ use crate::{ sync::SpinLock, }; +pub mod chrdev; pub mod fdt_prober; pub mod fs; pub mod init; pub mod interrupts; -pub mod null; pub mod probe; pub mod timer; pub mod uart; -pub mod zero; #[repr(u64)] pub enum ReservedMajors { Null = 1, Zero = 2, + Random = 3, Console = 5, Uart = 10, End = 11,