From f05307f98aae78c1134494f5bf2d547ae952c115 Mon Sep 17 00:00:00 2001 From: ssy <879650736@qq.com> Date: Sat, 28 Jun 2025 05:11:29 +0000 Subject: [PATCH 1/4] add urandom --- axfs_devfs/src/lib.rs | 2 ++ axfs_devfs/src/urandom.rs | 68 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 axfs_devfs/src/urandom.rs diff --git a/axfs_devfs/src/lib.rs b/axfs_devfs/src/lib.rs index 1e91629..4cf2193 100644 --- a/axfs_devfs/src/lib.rs +++ b/axfs_devfs/src/lib.rs @@ -8,6 +8,7 @@ extern crate alloc; mod dir; mod null; +mod urandom; mod zero; #[cfg(test)] @@ -15,6 +16,7 @@ mod tests; pub use self::dir::DirNode; pub use self::null::NullDev; +pub use self::urandom::UrandomDev; pub use self::zero::ZeroDev; use alloc::sync::Arc; diff --git a/axfs_devfs/src/urandom.rs b/axfs_devfs/src/urandom.rs new file mode 100644 index 0000000..1c35f3e --- /dev/null +++ b/axfs_devfs/src/urandom.rs @@ -0,0 +1,68 @@ +use axfs_vfs::{VfsNodeAttr, VfsNodeOps, VfsNodePerm, VfsNodeType, VfsResult}; +use core::sync::atomic::{AtomicU64, Ordering}; + +/// A urandom device behaves like `/dev/urandom`. +/// +/// It produces random bytes when read. +pub struct UrandomDev { + seed: AtomicU64, +} + +impl UrandomDev { + pub fn new() -> Self { + Self { + seed: AtomicU64::new(0xa2ce_a2ce), + } + } + + /// LCG pseudo-random number generator + fn next_u64(&self) -> u64 { + let new_seed = self + .seed + .load(Ordering::SeqCst) + .wrapping_mul(6364136223846793005) + + 1; + self.seed.store(new_seed, Ordering::SeqCst); + new_seed + } +} + +impl Default for UrandomDev { + fn default() -> Self { + Self::new() + } +} + +impl VfsNodeOps for UrandomDev { + fn get_attr(&self) -> VfsResult { + Ok(VfsNodeAttr::new( + VfsNodePerm::default_file(), + VfsNodeType::CharDevice, + 0, + 0, + )) + } + + fn read_at(&self, _offset: u64, buf: &mut [u8]) -> VfsResult { + for chunk in buf.chunks_mut(8) { + let random_value = self.next_u64(); + let bytes = random_value.to_ne_bytes(); + for (i, byte) in chunk.iter_mut().enumerate() { + if i < bytes.len() { + *byte = bytes[i]; + } + } + } + Ok(buf.len()) + } + + fn write_at(&self, _offset: u64, buf: &[u8]) -> VfsResult { + Ok(buf.len()) + } + + fn truncate(&self, _size: u64) -> VfsResult { + Ok(()) + } + + axfs_vfs::impl_vfs_non_dir_default! {} +} From 73c69620ad4279242a538adee3eb86e8ab1b0aae Mon Sep 17 00:00:00 2001 From: ssy <879650736@qq.com> Date: Sat, 28 Jun 2025 05:15:25 +0000 Subject: [PATCH 2/4] add documentation --- axfs_devfs/src/urandom.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/axfs_devfs/src/urandom.rs b/axfs_devfs/src/urandom.rs index 1c35f3e..74d9e7d 100644 --- a/axfs_devfs/src/urandom.rs +++ b/axfs_devfs/src/urandom.rs @@ -9,6 +9,7 @@ pub struct UrandomDev { } impl UrandomDev { + /// Create a new instance of the urandom device. pub fn new() -> Self { Self { seed: AtomicU64::new(0xa2ce_a2ce), From 8c47106aff41b0acdea0a2cc6b8e860ebda1958f Mon Sep 17 00:00:00 2001 From: ssy <879650736@qq.com> Date: Sat, 28 Jun 2025 06:45:39 +0000 Subject: [PATCH 3/4] Fixed UrandomDev's constructor to accept a seed parameter --- axfs_devfs/src/urandom.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/axfs_devfs/src/urandom.rs b/axfs_devfs/src/urandom.rs index 74d9e7d..e2ca11e 100644 --- a/axfs_devfs/src/urandom.rs +++ b/axfs_devfs/src/urandom.rs @@ -10,12 +10,17 @@ pub struct UrandomDev { impl UrandomDev { /// Create a new instance of the urandom device. - pub fn new() -> Self { + pub fn new(seed: u64) -> Self { Self { - seed: AtomicU64::new(0xa2ce_a2ce), + seed: AtomicU64::new(seed), } } + /// Create a new instance with a default seed. + fn new_with_default_seed() -> Self { + Self::new(0xa2ce_a2ce) + } + /// LCG pseudo-random number generator fn next_u64(&self) -> u64 { let new_seed = self @@ -30,7 +35,7 @@ impl UrandomDev { impl Default for UrandomDev { fn default() -> Self { - Self::new() + Self::new_with_default_seed() } } From 486eccb0e74ab7fd76f316dcd8dfa5dc6dacd151 Mon Sep 17 00:00:00 2001 From: ssy <879650736@qq.com> Date: Sat, 28 Jun 2025 07:43:31 +0000 Subject: [PATCH 4/4] Change the constructor of UrandomDev to a constant function --- axfs_devfs/src/urandom.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/axfs_devfs/src/urandom.rs b/axfs_devfs/src/urandom.rs index e2ca11e..53d180f 100644 --- a/axfs_devfs/src/urandom.rs +++ b/axfs_devfs/src/urandom.rs @@ -10,7 +10,7 @@ pub struct UrandomDev { impl UrandomDev { /// Create a new instance of the urandom device. - pub fn new(seed: u64) -> Self { + pub const fn new(seed: u64) -> Self { Self { seed: AtomicU64::new(seed), }