Implement sys_sysinfo (#71)

This commit is contained in:
Ashwin Naren
2025-12-20 15:42:08 -08:00
committed by GitHub
parent b98a54b928
commit 35a6caa541
5 changed files with 108 additions and 1 deletions

View File

@@ -179,7 +179,7 @@
| 0xb0 (176) | getgid | () | __arm64_sys_getgid | true | | 0xb0 (176) | getgid | () | __arm64_sys_getgid | true |
| 0xb1 (177) | getegid | () | __arm64_sys_getegid | true | | 0xb1 (177) | getegid | () | __arm64_sys_getegid | true |
| 0xb2 (178) | gettid | () | __arm64_sys_gettid | true | | 0xb2 (178) | gettid | () | __arm64_sys_gettid | true |
| 0xb3 (179) | sysinfo | (struct sysinfo *info) | __arm64_sys_sysinfo | false | | 0xb3 (179) | sysinfo | (struct sysinfo *info) | __arm64_sys_sysinfo | true |
| 0xb4 (180) | mq_open | (const char *u_name, int oflag, umode_t mode, struct mq_attr *u_attr) | __arm64_sys_mq_open | false | | 0xb4 (180) | mq_open | (const char *u_name, int oflag, umode_t mode, struct mq_attr *u_attr) | __arm64_sys_mq_open | false |
| 0xb5 (181) | mq_unlink | (const char *u_name) | __arm64_sys_mq_unlink | false | | 0xb5 (181) | mq_unlink | (const char *u_name) | __arm64_sys_mq_unlink | false |
| 0xb6 (182) | mq_timedsend | (mqd_t mqdes, const char *u_msg_ptr, size_t msg_len, unsigned int msg_prio, const struct __kernel_timespec *u_abs_timeout) | __arm64_sys_mq_timedsend | false | | 0xb6 (182) | mq_timedsend | (mqd_t mqdes, const char *u_msg_ptr, size_t msg_len, unsigned int msg_prio, const struct __kernel_timespec *u_abs_timeout) | __arm64_sys_mq_timedsend | false |

View File

@@ -331,6 +331,18 @@ impl<CPU: CpuOps> FrameAllocator<CPU> {
} }
} }
/// Returns the total number of pages managed by this allocator.
#[inline]
pub fn total_pages(&self) -> usize {
self.inner.lock_save_irq().total_pages
}
/// Returns the current number of free pages available for allocation.
#[inline]
pub fn free_pages(&self) -> usize {
self.inner.lock_save_irq().free_pages
}
/// Initializes the frame allocator. This is the main bootstrap function. /// Initializes the frame allocator. This is the main bootstrap function.
/// ///
/// # Safety /// # Safety

View File

@@ -28,6 +28,7 @@ use crate::{
sync::sys_sync, sync::sys_sync,
}, },
}, },
kernel::sysinfo::sys_sysinfo,
kernel::uname::sys_uname, kernel::uname::sys_uname,
memory::{ memory::{
brk::sys_brk, brk::sys_brk,
@@ -231,6 +232,7 @@ pub async fn handle_syscall() {
0xb0 => sys_getgid().map_err(|e| match e {}), 0xb0 => sys_getgid().map_err(|e| match e {}),
0xb1 => sys_getegid().map_err(|e| match e {}), 0xb1 => sys_getegid().map_err(|e| match e {}),
0xb2 => sys_gettid().map_err(|e| match e {}), 0xb2 => sys_gettid().map_err(|e| match e {}),
0xb3 => sys_sysinfo(TUA::from_value(arg1 as _)).await,
0xc6 => Err(KernelError::NotSupported), 0xc6 => Err(KernelError::NotSupported),
0xd6 => sys_brk(VA::from_value(arg1 as _)) 0xd6 => sys_brk(VA::from_value(arg1 as _))
.await .await

View File

@@ -1,4 +1,5 @@
pub mod kpipe; pub mod kpipe;
pub mod power; pub mod power;
pub mod rand; pub mod rand;
pub mod sysinfo;
pub mod uname; pub mod uname;

92
src/kernel/sysinfo.rs Normal file
View File

@@ -0,0 +1,92 @@
use crate::drivers::timer::uptime;
use crate::memory::uaccess::{UserCopyable, copy_to_user};
use crate::{memory::PAGE_ALLOC, process::TASK_LIST};
use core::mem::size_of;
use libkernel::memory::PAGE_SIZE;
use libkernel::{error::Result, memory::address::TUA};
#[repr(C)]
#[derive(Copy, Clone)]
pub struct SysInfo {
/// Seconds since boot
pub uptime: u64,
/// 1, 5, and 15 minute load averages
pub loads: [u64; 3],
/// Total usable main memory size
pub total_ram: u64,
/// Available memory size
pub free_ram: u64,
/// Amount of shared memory
pub shared_ram: u64,
/// Memory used by buffers
pub buffer_ram: u64,
/// Total swap space size
pub total_swap: u64,
/// Swap space still available
pub free_swap: u64,
/// Number of current processes
pub procs: u32,
/// Total high memory size
pub total_high: u64,
/// Available high memory size
pub free_high: u64,
/// Memory unit size in bytes
pub mem_unit: u32,
}
impl SysInfo {
pub fn new() -> SysInfo {
// Gather memory statistics from the global page allocator.
let page_alloc = PAGE_ALLOC.get().expect("PAGE_ALLOC must be initialised");
let total_pages = page_alloc.total_pages();
let free_pages = page_alloc.free_pages();
let total_ram = (total_pages * PAGE_SIZE) as u64;
let free_ram = (free_pages * PAGE_SIZE) as u64;
// Count the number of processes currently known to the scheduler.
let procs = TASK_LIST.lock_save_irq().len() as u32;
SysInfo {
uptime: uptime().as_secs(),
loads: [0, 0, 0], // TODO: implement actual load averages
total_ram,
free_ram,
shared_ram: 0,
buffer_ram: 0,
total_swap: 0,
free_swap: 0,
procs,
total_high: 0,
free_high: 0,
mem_unit: 1, // All memory figures are given in bytes
}
}
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PaddedSysInfo {
pub info: SysInfo,
/// Padding to 64 bytes
_f: [u8; 20 - (2 * size_of::<u64>()) - size_of::<u32>()],
}
impl From<SysInfo> for PaddedSysInfo {
fn from(info: SysInfo) -> Self {
Self {
info,
_f: [0; 20 - (2 * size_of::<u64>()) - size_of::<u32>()],
}
}
}
unsafe impl UserCopyable for PaddedSysInfo {}
pub async fn sys_sysinfo(info_ptr: TUA<PaddedSysInfo>) -> Result<usize> {
// Build the structure in kernel memory first
let padded = PaddedSysInfo::from(SysInfo::new());
copy_to_user(info_ptr, padded).await?;
Ok(0)
}