xref: /DragonOS/kernel/src/syscall/misc.rs (revision c635d8a9cfe25bc11779f323ef0c7d7a0f597d4a)
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