proc: add SyscallFunction::GetRandom
This commit is contained in:
parent
e431d49ffb
commit
15d3e38a2d
@ -9,7 +9,10 @@ use vfs::{
|
||||
CharDevice, Node, NodeFlags, NodeRef,
|
||||
};
|
||||
|
||||
use crate::arch::{Architecture, ARCHITECTURE};
|
||||
use crate::{
|
||||
arch::{Architecture, ARCHITECTURE},
|
||||
proc::random,
|
||||
};
|
||||
|
||||
/// Describes the kind of a character device
|
||||
#[derive(Debug)]
|
||||
@ -21,58 +24,6 @@ pub enum CharDeviceType {
|
||||
}
|
||||
|
||||
static DEVFS_ROOT: OneTimeInit<NodeRef> = OneTimeInit::new();
|
||||
|
||||
struct RandomState {
|
||||
data: [u8; 1024],
|
||||
pos: usize,
|
||||
last_state: u32,
|
||||
}
|
||||
|
||||
impl RandomState {
|
||||
fn new(seed: u32) -> Self {
|
||||
Self {
|
||||
data: [0; 1024],
|
||||
pos: 1024,
|
||||
last_state: seed,
|
||||
}
|
||||
}
|
||||
|
||||
fn next(&mut self) -> u32 {
|
||||
let mut x = self.last_state;
|
||||
x ^= x << 13;
|
||||
x ^= x >> 17;
|
||||
x ^= x << 5;
|
||||
self.last_state = x;
|
||||
x
|
||||
}
|
||||
|
||||
fn fill_buf(&mut self) {
|
||||
self.pos = 0;
|
||||
for i in (0..self.data.len()).step_by(4) {
|
||||
let v = self.next();
|
||||
self.data[i..i + 4].copy_from_slice(&v.to_ne_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
fn read_buf(&mut self, buf: &mut [u8]) {
|
||||
let mut rem = buf.len();
|
||||
let mut pos = 0;
|
||||
|
||||
while rem != 0 {
|
||||
if self.pos == 1024 {
|
||||
self.fill_buf();
|
||||
}
|
||||
let count = core::cmp::min(rem, 1024 - self.pos);
|
||||
|
||||
buf[pos..pos + count].copy_from_slice(&self.data[self.pos..self.pos + count]);
|
||||
|
||||
self.pos += count;
|
||||
rem -= count;
|
||||
pos += count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets up the device filesystem
|
||||
pub fn init() {
|
||||
let root = MemoryDirectory::empty();
|
||||
@ -113,17 +64,8 @@ pub fn add_char_device(dev: &'static dyn CharDevice, kind: CharDeviceType) -> Re
|
||||
}
|
||||
|
||||
pub fn add_pseudo_devices() -> Result<(), Error> {
|
||||
let now = ARCHITECTURE
|
||||
.monotonic_timer()
|
||||
.monotonic_timestamp()
|
||||
.unwrap();
|
||||
let random_seed = now.subsec_millis();
|
||||
let mut random_state = RandomState::new(random_seed);
|
||||
random_state.fill_buf();
|
||||
let random_state = IrqSafeSpinlock::new(random_state);
|
||||
|
||||
let random = read_fn_node(move |_, buf| {
|
||||
random_state.lock().read_buf(buf);
|
||||
random::read(buf);
|
||||
Ok(buf.len())
|
||||
});
|
||||
|
||||
|
@ -37,6 +37,7 @@ use crate::{
|
||||
arch::{ArchitectureImpl, ARCHITECTURE},
|
||||
fs::{devfs, sysfs},
|
||||
mem::heap,
|
||||
proc::random,
|
||||
task::{spawn_kernel_closure, Cpu},
|
||||
};
|
||||
|
||||
@ -87,6 +88,8 @@ pub fn kernel_secondary_main() -> ! {
|
||||
pub fn kernel_main() -> ! {
|
||||
debugln!("Heap: {:#x?}", heap::heap_range());
|
||||
|
||||
random::init();
|
||||
|
||||
// Setup the sysfs
|
||||
sysfs::init();
|
||||
devfs::add_pseudo_devices().unwrap();
|
||||
|
@ -3,3 +3,4 @@
|
||||
pub mod elf;
|
||||
pub mod exec;
|
||||
pub mod io;
|
||||
pub mod random;
|
||||
|
74
src/proc/random.rs
Normal file
74
src/proc/random.rs
Normal file
@ -0,0 +1,74 @@
|
||||
use kernel_util::{sync::IrqSafeSpinlock, util::OneTimeInit};
|
||||
|
||||
use crate::arch::{Architecture, ARCHITECTURE};
|
||||
|
||||
struct RandomState {
|
||||
data: [u8; 1024],
|
||||
pos: usize,
|
||||
last_state: u32,
|
||||
}
|
||||
|
||||
impl RandomState {
|
||||
fn new(seed: u32) -> Self {
|
||||
Self {
|
||||
data: [0; 1024],
|
||||
pos: 1024,
|
||||
last_state: seed,
|
||||
}
|
||||
}
|
||||
|
||||
fn next(&mut self) -> u32 {
|
||||
let mut x = self.last_state;
|
||||
x ^= x << 13;
|
||||
x ^= x >> 17;
|
||||
x ^= x << 5;
|
||||
self.last_state = x;
|
||||
x
|
||||
}
|
||||
|
||||
fn fill_buf(&mut self) {
|
||||
self.pos = 0;
|
||||
for i in (0..self.data.len()).step_by(4) {
|
||||
let v = self.next();
|
||||
self.data[i..i + 4].copy_from_slice(&v.to_ne_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
fn read_buf(&mut self, buf: &mut [u8]) {
|
||||
let mut rem = buf.len();
|
||||
let mut pos = 0;
|
||||
|
||||
while rem != 0 {
|
||||
if self.pos == 1024 {
|
||||
self.fill_buf();
|
||||
}
|
||||
let count = core::cmp::min(rem, 1024 - self.pos);
|
||||
|
||||
buf[pos..pos + count].copy_from_slice(&self.data[self.pos..self.pos + count]);
|
||||
|
||||
self.pos += count;
|
||||
rem -= count;
|
||||
pos += count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static RANDOM_STATE: OneTimeInit<IrqSafeSpinlock<RandomState>> = OneTimeInit::new();
|
||||
|
||||
pub fn read(buf: &mut [u8]) {
|
||||
let state = RANDOM_STATE.get();
|
||||
state.lock().read_buf(buf)
|
||||
}
|
||||
|
||||
pub fn init() {
|
||||
let now = ARCHITECTURE
|
||||
.monotonic_timer()
|
||||
.monotonic_timestamp()
|
||||
.unwrap();
|
||||
let random_seed = now.subsec_millis();
|
||||
|
||||
let mut state = RandomState::new(random_seed);
|
||||
state.fill_buf();
|
||||
|
||||
RANDOM_STATE.init(IrqSafeSpinlock::new(state));
|
||||
}
|
@ -22,7 +22,7 @@ use crate::{
|
||||
debug::LogLevel,
|
||||
fs,
|
||||
mem::{phys, table::MapAttributes},
|
||||
proc::{self, io::ProcessIo},
|
||||
proc::{self, io::ProcessIo, random},
|
||||
task::{
|
||||
process::{Process, ProcessId},
|
||||
runtime,
|
||||
@ -72,6 +72,11 @@ fn syscall_handler(func: SyscallFunction, args: &[u64]) -> Result<usize, Error>
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
SyscallFunction::GetRandom => {
|
||||
let buf = arg_buffer_mut(args[0] as _, args[1] as _)?;
|
||||
random::read(buf);
|
||||
Ok(0)
|
||||
}
|
||||
SyscallFunction::Nanosleep => {
|
||||
let seconds = args[0];
|
||||
let nanos = args[1] as u32;
|
||||
|
Loading…
x
Reference in New Issue
Block a user