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