1 use crate::{ 2 arch::{mm::LockedFrameAllocator, rand::rand}, 3 libs::rand::GRandFlags, 4 mm::allocator::{page_frame::FrameAllocator, slab::slab_usage}, 5 }; 6 use alloc::vec::Vec; 7 use core::cmp; 8 use log::warn; 9 use system_error::SystemError; 10 11 use super::{user_access::UserBufferWriter, Syscall}; 12 13 #[repr(C)] 14 15 /// 系统信息 16 /// 17 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/uapi/linux/sysinfo.h#8 18 #[derive(Debug, Default, Copy, Clone)] 19 pub struct SysInfo { 20 uptime: u64, 21 loads: [u64; 3], 22 totalram: u64, 23 freeram: u64, 24 sharedram: u64, 25 bufferram: u64, 26 totalswap: u64, 27 freeswap: u64, 28 procs: u16, 29 pad: u16, 30 totalhigh: u64, 31 freehigh: u64, 32 mem_unit: u32, 33 // 这后面还有一小段,但是我们不需要 34 } 35 36 impl Syscall { 37 pub fn sysinfo(info: *mut SysInfo) -> Result<usize, SystemError> { 38 let mut writer = UserBufferWriter::new(info, core::mem::size_of::<SysInfo>(), true)?; 39 let mut sysinfo = SysInfo::default(); 40 41 let mem = unsafe { LockedFrameAllocator.usage() }; 42 let slab_usage = unsafe { slab_usage() }; 43 sysinfo.uptime = 0; 44 sysinfo.loads = [0; 3]; 45 sysinfo.totalram = mem.total().bytes() as u64; 46 sysinfo.freeram = mem.free().bytes() as u64 + slab_usage.free(); 47 sysinfo.sharedram = 0; 48 sysinfo.bufferram = 0; 49 sysinfo.totalswap = 0; 50 sysinfo.freeswap = 0; 51 sysinfo.procs = 0; 52 sysinfo.pad = 0; 53 sysinfo.totalhigh = 0; 54 sysinfo.freehigh = 0; 55 sysinfo.mem_unit = 0; 56 57 writer.copy_one_to_user(&sysinfo, 0)?; 58 59 return Ok(0); 60 } 61 62 pub fn umask(_mask: u32) -> Result<usize, SystemError> { 63 warn!("SYS_UMASK has not yet been implemented\n"); 64 return Ok(0o777); 65 } 66 67 /// ## 将随机字节填入buf 68 /// ### 该系统调用与linux不一致,因为目前没有其他随机源 69 pub fn get_random(buf: *mut u8, len: usize, flags: GRandFlags) -> Result<usize, SystemError> { 70 if flags.bits() == (GRandFlags::GRND_INSECURE.bits() | GRandFlags::GRND_RANDOM.bits()) { 71 return Err(SystemError::EINVAL); 72 } 73 74 let mut writer = UserBufferWriter::new(buf, len, true)?; 75 76 let mut ret = Vec::new(); 77 let mut count = 0; 78 while count < len { 79 // 对 len - count 的长度进行判断,remain_len 小于4则循环次数和 remain_len 相等 80 let remain_len = len - count; 81 let step = cmp::min(remain_len, 4); 82 let rand = rand(); 83 for offset in 0..step { 84 ret.push((rand >> (offset * 2)) as u8); 85 count += 1; 86 } 87 } 88 89 writer.copy_to_user(&ret, 0)?; 90 Ok(len) 91 } 92 } 93