Jomo 8d72b68da9
实现内核日志系统 (#489)
* 实现写日志和读取日志,并且能够在用户态下执行dmesg命令查看日志

* 通过klogctl实现dmesg

* 改用ConstGenericRingBuffer作内核缓冲区

* 更改缓冲区容量

* 将能够输出到控制台的日志级别改为日志级别枚举类,使用SpinLock控制KMSG,使用枚举类定义SYSLOG_ACTION,将do_syslog系统调用接口放在syscall.rs

* fix warning

* 完善do_syslog注释

* 将KMSG接入kinfo、kdebug等

* fix warning

* 修复显示的秒数不正确,·以及无法通过CI的问题
2024-01-24 16:13:15 +08:00

995 lines
37 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use core::{
ffi::{c_char, c_int, c_void, CStr},
sync::atomic::{AtomicBool, Ordering},
};
use crate::{
arch::{ipc::signal::SigSet, syscall::nr::*},
driver::base::device::device_number::DeviceNumber,
libs::{futex::constant::FutexFlag, rand::GRandFlags},
process::{
fork::KernelCloneArgs,
resource::{RLimit64, RUsage},
},
};
use num_traits::FromPrimitive;
use system_error::SystemError;
use crate::{
arch::{cpu::cpu_reset, interrupt::TrapFrame, MMArch},
driver::base::block::SeekFrom,
filesystem::vfs::{
fcntl::FcntlCommand,
file::FileMode,
syscall::{ModeType, PosixKstat, SEEK_CUR, SEEK_END, SEEK_MAX, SEEK_SET},
MAX_PATHLEN,
},
include::bindings::bindings::{PAGE_2M_SIZE, PAGE_4K_SIZE},
kinfo,
libs::align::page_align_up,
mm::{verify_area, MemoryManagementArch, VirtAddr},
net::syscall::SockAddr,
process::{fork::CloneFlags, Pid},
time::{
syscall::{PosixTimeZone, PosixTimeval},
TimeSpec,
},
};
use self::{
misc::SysInfo,
user_access::{UserBufferReader, UserBufferWriter},
};
pub mod misc;
pub mod user_access;
// 与linux不一致的调用在linux基础上累加
pub const SYS_PUT_STRING: usize = 100000;
pub const SYS_SBRK: usize = 100001;
/// todo: 该系统调用与Linux不一致将来需要删除该系统调用 删的时候记得改C版本的libc
pub const SYS_CLOCK: usize = 100002;
pub const SYS_SCHED: usize = 100003;
#[derive(Debug)]
pub struct Syscall;
extern "C" {
fn do_put_string(s: *const u8, front_color: u32, back_color: u32) -> usize;
}
#[no_mangle]
pub extern "C" fn syscall_init() -> i32 {
kinfo!("Initializing syscall...");
Syscall::init().expect("syscall init failed");
kinfo!("Syscall init successfully!");
return 0;
}
impl Syscall {
/// 初始化系统调用
pub fn init() -> Result<(), SystemError> {
static INIT_FLAG: AtomicBool = AtomicBool::new(false);
let prev = INIT_FLAG.swap(true, Ordering::SeqCst);
if prev {
panic!("Cannot initialize syscall more than once!");
}
return crate::arch::syscall::arch_syscall_init();
}
/// @brief 系统调用分发器,用于分发系统调用。
///
/// 这个函数内,需要根据系统调用号,调用对应的系统调用处理函数。
/// 并且,对于用户态传入的指针参数,需要在本函数内进行越界检查,防止访问到内核空间。
#[inline(never)]
pub fn handle(
syscall_num: usize,
args: &[usize],
frame: &mut TrapFrame,
) -> Result<usize, SystemError> {
let r = match syscall_num {
SYS_PUT_STRING => {
Self::put_string(args[0] as *const u8, args[1] as u32, args[2] as u32)
}
#[cfg(target_arch = "x86_64")]
SYS_OPEN => {
let path: &CStr = unsafe { CStr::from_ptr(args[0] as *const c_char) };
let path: Result<&str, core::str::Utf8Error> = path.to_str();
let res = if path.is_err() {
Err(SystemError::EINVAL)
} else {
let path: &str = path.unwrap();
let flags = args[1];
let mode = args[2];
let open_flags: FileMode = FileMode::from_bits_truncate(flags as u32);
let mode = ModeType::from_bits(mode as u32).ok_or(SystemError::EINVAL)?;
Self::open(path, open_flags, mode, true)
};
res
}
SYS_OPENAT => {
let dirfd = args[0] as i32;
let path: &CStr = unsafe { CStr::from_ptr(args[1] as *const c_char) };
let flags = args[2];
let mode = args[3];
let path: Result<&str, core::str::Utf8Error> = path.to_str();
let res = if path.is_err() {
Err(SystemError::EINVAL)
} else {
let path: &str = path.unwrap();
let open_flags: FileMode =
FileMode::from_bits(flags as u32).ok_or(SystemError::EINVAL)?;
let mode = ModeType::from_bits(mode as u32).ok_or(SystemError::EINVAL)?;
Self::openat(dirfd, path, open_flags, mode, true)
};
res
}
SYS_CLOSE => {
let fd = args[0];
let res = Self::close(fd);
res
}
SYS_READ => {
let fd = args[0] as i32;
let buf_vaddr = args[1];
let len = args[2];
let from_user = frame.from_user();
let mut user_buffer_writer =
UserBufferWriter::new(buf_vaddr as *mut u8, len, from_user)?;
let user_buf = user_buffer_writer.buffer(0)?;
let res = Self::read(fd, user_buf);
res
}
SYS_WRITE => {
let fd = args[0] as i32;
let buf_vaddr = args[1];
let len = args[2];
let from_user = frame.from_user();
let user_buffer_reader =
UserBufferReader::new(buf_vaddr as *const u8, len, from_user)?;
let user_buf = user_buffer_reader.read_from_user(0)?;
let res = Self::write(fd, user_buf);
res
}
SYS_LSEEK => {
let fd = args[0] as i32;
let offset = args[1] as i64;
let whence = args[2] as u32;
let w = match whence {
SEEK_SET => Ok(SeekFrom::SeekSet(offset)),
SEEK_CUR => Ok(SeekFrom::SeekCurrent(offset)),
SEEK_END => Ok(SeekFrom::SeekEnd(offset)),
SEEK_MAX => Ok(SeekFrom::SeekEnd(0)),
_ => Err(SystemError::EINVAL),
}?;
Self::lseek(fd, w)
}
SYS_IOCTL => {
let fd = args[0];
let cmd = args[1];
let data = args[2];
Self::ioctl(fd, cmd as u32, data)
}
#[cfg(target_arch = "x86_64")]
SYS_FORK => Self::fork(frame),
#[cfg(target_arch = "x86_64")]
SYS_VFORK => Self::vfork(frame),
SYS_BRK => {
let new_brk = VirtAddr::new(args[0]);
Self::brk(new_brk).map(|vaddr| vaddr.data())
}
SYS_SBRK => {
let increment = args[0] as isize;
Self::sbrk(increment).map(|vaddr: VirtAddr| vaddr.data())
}
SYS_REBOOT => Self::reboot(),
SYS_CHDIR => {
// Closure for checking arguments
let chdir_check = |arg0: usize| {
if arg0 == 0 {
return Err(SystemError::EFAULT);
}
let path_ptr = arg0 as *const c_char;
let virt_addr = VirtAddr::new(path_ptr as usize);
// 权限校验
if path_ptr.is_null()
|| (frame.from_user()
&& verify_area(virt_addr, PAGE_2M_SIZE as usize).is_err())
{
return Err(SystemError::EINVAL);
}
let dest_path: &CStr = unsafe { CStr::from_ptr(path_ptr) };
let dest_path: &str = dest_path.to_str().map_err(|_| SystemError::EINVAL)?;
if dest_path.len() == 0 {
return Err(SystemError::EINVAL);
} else if dest_path.len() > MAX_PATHLEN as usize {
return Err(SystemError::ENAMETOOLONG);
}
return Ok(dest_path);
};
let r = chdir_check(args[0])?;
Self::chdir(r)
}
#[allow(unreachable_patterns)]
SYS_GETDENTS64 | SYS_GETDENTS => {
let fd = args[0] as i32;
let buf_vaddr = args[1];
let len = args[2];
let virt_addr: VirtAddr = VirtAddr::new(buf_vaddr);
// 判断缓冲区是否来自用户态,进行权限校验
let res = if frame.from_user() && verify_area(virt_addr, len as usize).is_err() {
// 来自用户态而buffer在内核态这样的操作不被允许
Err(SystemError::EPERM)
} else if buf_vaddr == 0 {
Err(SystemError::EFAULT)
} else {
let buf: &mut [u8] = unsafe {
core::slice::from_raw_parts_mut::<'static, u8>(buf_vaddr as *mut u8, len)
};
Self::getdents(fd, buf)
};
res
}
SYS_EXECVE => {
let path_ptr = args[0];
let argv_ptr = args[1];
let env_ptr = args[2];
let virt_path_ptr = VirtAddr::new(path_ptr);
let virt_argv_ptr = VirtAddr::new(argv_ptr);
let virt_env_ptr = VirtAddr::new(env_ptr);
// 权限校验
if frame.from_user()
&& (verify_area(virt_path_ptr, MAX_PATHLEN as usize).is_err()
|| verify_area(virt_argv_ptr, PAGE_4K_SIZE as usize).is_err())
|| verify_area(virt_env_ptr, PAGE_4K_SIZE as usize).is_err()
{
Err(SystemError::EFAULT)
} else {
Self::execve(
path_ptr as *const u8,
argv_ptr as *const *const u8,
env_ptr as *const *const u8,
frame,
)
.map(|_| 0)
}
}
SYS_WAIT4 => {
let pid = args[0] as i32;
let wstatus = args[1] as *mut i32;
let options = args[2] as c_int;
let rusage = args[3] as *mut c_void;
// 权限校验
// todo: 引入rusage之后更正以下权限校验代码中rusage的大小
Self::wait4(pid.into(), wstatus, options, rusage)
}
SYS_EXIT => {
let exit_code = args[0];
Self::exit(exit_code)
}
#[cfg(target_arch = "x86_64")]
SYS_MKDIR => {
let path_ptr = args[0] as *const c_char;
let mode = args[1];
let virt_path_ptr = VirtAddr::new(path_ptr as usize);
let security_check = || {
if path_ptr.is_null()
|| (frame.from_user()
&& verify_area(virt_path_ptr, PAGE_2M_SIZE as usize).is_err())
{
return Err(SystemError::EINVAL);
}
let path: &CStr = unsafe { CStr::from_ptr(path_ptr) };
let path: &str = path.to_str().map_err(|_| SystemError::EINVAL)?.trim();
if path == "" {
return Err(SystemError::EINVAL);
}
return Ok(path);
};
let path = security_check();
if path.is_err() {
Err(path.unwrap_err())
} else {
Self::mkdir(path.unwrap(), mode)
}
}
SYS_NANOSLEEP => {
let req = args[0] as *const TimeSpec;
let rem = args[1] as *mut TimeSpec;
let virt_req = VirtAddr::new(req as usize);
let virt_rem = VirtAddr::new(rem as usize);
if frame.from_user()
&& (verify_area(virt_req, core::mem::size_of::<TimeSpec>() as usize).is_err()
|| verify_area(virt_rem, core::mem::size_of::<TimeSpec>() as usize)
.is_err())
{
Err(SystemError::EFAULT)
} else {
Self::nanosleep(req, rem)
}
}
SYS_CLOCK => Self::clock(),
#[cfg(target_arch = "x86_64")]
SYS_PIPE => {
let pipefd: *mut i32 = args[0] as *mut c_int;
if pipefd.is_null() {
Err(SystemError::EFAULT)
} else {
Self::pipe2(pipefd, FileMode::empty())
}
}
SYS_PIPE2 => {
let pipefd: *mut i32 = args[0] as *mut c_int;
let arg1 = args[1];
if pipefd.is_null() {
Err(SystemError::EFAULT)
} else {
let flags = FileMode::from_bits_truncate(arg1 as u32);
Self::pipe2(pipefd, flags)
}
}
SYS_UNLINKAT => {
let dirfd = args[0] as i32;
let pathname = args[1] as *const c_char;
let flags = args[2] as u32;
let virt_pathname = VirtAddr::new(pathname as usize);
if frame.from_user() && verify_area(virt_pathname, PAGE_4K_SIZE as usize).is_err() {
Err(SystemError::EFAULT)
} else if pathname.is_null() {
Err(SystemError::EFAULT)
} else {
let get_path = || {
let pathname: &CStr = unsafe { CStr::from_ptr(pathname) };
let pathname: &str = pathname.to_str().map_err(|_| SystemError::EINVAL)?;
if pathname.len() >= MAX_PATHLEN {
return Err(SystemError::ENAMETOOLONG);
}
return Ok(pathname.trim());
};
let pathname = get_path();
if pathname.is_err() {
Err(pathname.unwrap_err())
} else {
// kdebug!("sys unlinkat: dirfd: {}, pathname: {}", dirfd, pathname.as_ref().unwrap());
Self::unlinkat(dirfd, pathname.unwrap(), flags)
}
}
}
#[cfg(target_arch = "x86_64")]
SYS_UNLINK => {
let pathname = args[0] as *const u8;
Self::unlink(pathname)
}
SYS_KILL => {
let pid = Pid::new(args[0]);
let sig = args[1] as c_int;
// kdebug!("KILL SYSCALL RECEIVED");
Self::kill(pid, sig)
}
SYS_RT_SIGACTION => {
let sig = args[0] as c_int;
let act = args[1];
let old_act = args[2];
Self::sigaction(sig, act, old_act, frame.from_user())
}
SYS_GETPID => Self::getpid().map(|pid| pid.into()),
SYS_SCHED => Self::sched(frame.from_user()),
SYS_DUP => {
let oldfd: i32 = args[0] as c_int;
Self::dup(oldfd)
}
#[cfg(target_arch = "x86_64")]
SYS_DUP2 => {
let oldfd: i32 = args[0] as c_int;
let newfd: i32 = args[1] as c_int;
Self::dup2(oldfd, newfd)
}
SYS_SOCKET => Self::socket(args[0], args[1], args[2]),
SYS_SETSOCKOPT => {
let optval = args[3] as *const u8;
let optlen = args[4] as usize;
let virt_optval = VirtAddr::new(optval as usize);
// 验证optval的地址是否合法
if verify_area(virt_optval, optlen as usize).is_err() {
// 地址空间超出了用户空间的范围,不合法
Err(SystemError::EFAULT)
} else {
let data: &[u8] = unsafe { core::slice::from_raw_parts(optval, optlen) };
Self::setsockopt(args[0], args[1], args[2], data)
}
}
SYS_GETSOCKOPT => {
let optval = args[3] as *mut u8;
let optlen = args[4] as *mut usize;
let virt_optval = VirtAddr::new(optval as usize);
let virt_optlen = VirtAddr::new(optlen as usize);
let security_check = || {
// 验证optval的地址是否合法
if verify_area(virt_optval, PAGE_4K_SIZE as usize).is_err() {
// 地址空间超出了用户空间的范围,不合法
return Err(SystemError::EFAULT);
}
// 验证optlen的地址是否合法
if verify_area(virt_optlen, core::mem::size_of::<u32>() as usize).is_err() {
// 地址空间超出了用户空间的范围,不合法
return Err(SystemError::EFAULT);
}
return Ok(());
};
let r = security_check();
if r.is_err() {
Err(r.unwrap_err())
} else {
Self::getsockopt(args[0], args[1], args[2], optval, optlen as *mut u32)
}
}
SYS_CONNECT => {
let addr = args[1] as *const SockAddr;
let addrlen = args[2] as usize;
let virt_addr = VirtAddr::new(addr as usize);
// 验证addr的地址是否合法
if verify_area(virt_addr, addrlen as usize).is_err() {
// 地址空间超出了用户空间的范围,不合法
Err(SystemError::EFAULT)
} else {
Self::connect(args[0], addr, addrlen)
}
}
SYS_BIND => {
let addr = args[1] as *const SockAddr;
let addrlen = args[2] as usize;
let virt_addr = VirtAddr::new(addr as usize);
// 验证addr的地址是否合法
if verify_area(virt_addr, addrlen as usize).is_err() {
// 地址空间超出了用户空间的范围,不合法
Err(SystemError::EFAULT)
} else {
Self::bind(args[0], addr, addrlen)
}
}
SYS_SENDTO => {
let buf = args[1] as *const u8;
let len = args[2] as usize;
let flags = args[3] as u32;
let addr = args[4] as *const SockAddr;
let addrlen = args[5] as usize;
let virt_buf = VirtAddr::new(buf as usize);
let virt_addr = VirtAddr::new(addr as usize);
// 验证buf的地址是否合法
if verify_area(virt_buf, len as usize).is_err() {
// 地址空间超出了用户空间的范围,不合法
Err(SystemError::EFAULT)
} else if verify_area(virt_addr, addrlen as usize).is_err() {
// 地址空间超出了用户空间的范围,不合法
Err(SystemError::EFAULT)
} else {
let data: &[u8] = unsafe { core::slice::from_raw_parts(buf, len) };
Self::sendto(args[0], data, flags, addr, addrlen)
}
}
SYS_RECVFROM => {
let buf = args[1] as *mut u8;
let len = args[2] as usize;
let flags = args[3] as u32;
let addr = args[4] as *mut SockAddr;
let addrlen = args[5] as *mut usize;
let virt_buf = VirtAddr::new(buf as usize);
let virt_addrlen = VirtAddr::new(addrlen as usize);
let virt_addr = VirtAddr::new(addr as usize);
let security_check = || {
// 验证buf的地址是否合法
if verify_area(virt_buf, len as usize).is_err() {
// 地址空间超出了用户空间的范围,不合法
return Err(SystemError::EFAULT);
}
// 验证addrlen的地址是否合法
if verify_area(virt_addrlen, core::mem::size_of::<u32>() as usize).is_err() {
// 地址空间超出了用户空间的范围,不合法
return Err(SystemError::EFAULT);
}
if verify_area(virt_addr, core::mem::size_of::<SockAddr>() as usize).is_err() {
// 地址空间超出了用户空间的范围,不合法
return Err(SystemError::EFAULT);
}
return Ok(());
};
let r = security_check();
if r.is_err() {
Err(r.unwrap_err())
} else {
let buf = unsafe { core::slice::from_raw_parts_mut(buf, len) };
Self::recvfrom(args[0], buf, flags, addr, addrlen as *mut u32)
}
}
SYS_RECVMSG => {
let msg = args[1] as *mut crate::net::syscall::MsgHdr;
let flags = args[2] as u32;
match UserBufferWriter::new(
msg,
core::mem::size_of::<crate::net::syscall::MsgHdr>(),
true,
) {
Err(e) => Err(e),
Ok(mut user_buffer_writer) => {
match user_buffer_writer.buffer::<crate::net::syscall::MsgHdr>(0) {
Err(e) => Err(e),
Ok(buffer) => {
let msg = &mut buffer[0];
Self::recvmsg(args[0], msg, flags)
}
}
}
}
}
SYS_LISTEN => Self::listen(args[0], args[1]),
SYS_SHUTDOWN => Self::shutdown(args[0], args[1]),
SYS_ACCEPT => Self::accept(args[0], args[1] as *mut SockAddr, args[2] as *mut u32),
SYS_ACCEPT4 => Self::accept4(
args[0],
args[1] as *mut SockAddr,
args[2] as *mut u32,
args[3] as u32,
),
SYS_GETSOCKNAME => {
Self::getsockname(args[0], args[1] as *mut SockAddr, args[2] as *mut u32)
}
SYS_GETPEERNAME => {
Self::getpeername(args[0], args[1] as *mut SockAddr, args[2] as *mut u32)
}
SYS_GETTIMEOFDAY => {
let timeval = args[0] as *mut PosixTimeval;
let timezone_ptr = args[1] as *mut PosixTimeZone;
Self::gettimeofday(timeval, timezone_ptr)
}
SYS_MMAP => {
let len = page_align_up(args[1]);
let virt_addr = VirtAddr::new(args[0] as usize);
if verify_area(virt_addr, len as usize).is_err() {
Err(SystemError::EFAULT)
} else {
Self::mmap(
VirtAddr::new(args[0]),
len,
args[2],
args[3],
args[4] as i32,
args[5],
)
}
}
SYS_MUNMAP => {
let addr = args[0];
let len = page_align_up(args[1]);
if addr & (MMArch::PAGE_SIZE - 1) != 0 {
// The addr argument is not a multiple of the page size
Err(SystemError::EINVAL)
} else {
Self::munmap(VirtAddr::new(addr), len)
}
}
SYS_MPROTECT => {
let addr = args[0];
let len = page_align_up(args[1]);
if addr & (MMArch::PAGE_SIZE - 1) != 0 {
// The addr argument is not a multiple of the page size
Err(SystemError::EINVAL)
} else {
Self::mprotect(VirtAddr::new(addr), len, args[2])
}
}
SYS_GETCWD => {
let buf = args[0] as *mut u8;
let size = args[1] as usize;
let security_check = || {
verify_area(VirtAddr::new(buf as usize), size)?;
return Ok(());
};
let r = security_check();
if r.is_err() {
Err(r.unwrap_err())
} else {
let buf = unsafe { core::slice::from_raw_parts_mut(buf, size) };
Self::getcwd(buf).map(|ptr| ptr.data())
}
}
SYS_GETPGID => Self::getpgid(Pid::new(args[0])).map(|pid| pid.into()),
SYS_GETPPID => Self::getppid().map(|pid| pid.into()),
SYS_FSTAT => {
let fd = args[0] as i32;
let kstat = args[1] as *mut PosixKstat;
let vaddr = VirtAddr::new(kstat as usize);
// FIXME 由于c中的verify_area与rust中的verify_area重名所以在引入时加了前缀区分
// TODO 应该将用了c版本的verify_area都改为rust的verify_area
match verify_area(vaddr, core::mem::size_of::<PosixKstat>()) {
Ok(_) => Self::fstat(fd, kstat),
Err(e) => Err(e),
}
}
SYS_FCNTL => {
let fd = args[0] as i32;
let cmd: Option<FcntlCommand> =
<FcntlCommand as FromPrimitive>::from_u32(args[1] as u32);
let arg = args[2] as i32;
let res = if let Some(cmd) = cmd {
Self::fcntl(fd, cmd, arg)
} else {
Err(SystemError::EINVAL)
};
// kdebug!("FCNTL: fd: {}, cmd: {:?}, arg: {}, res: {:?}", fd, cmd, arg, res);
res
}
SYS_FTRUNCATE => {
let fd = args[0] as i32;
let len = args[1] as usize;
let res = Self::ftruncate(fd, len);
// kdebug!("FTRUNCATE: fd: {}, len: {}, res: {:?}", fd, len, res);
res
}
#[cfg(target_arch = "x86_64")]
SYS_MKNOD => {
let path = args[0];
let flags = args[1];
let dev_t = args[2];
let flags: ModeType = ModeType::from_bits_truncate(flags as u32);
Self::mknod(path as *const i8, flags, DeviceNumber::from(dev_t as u32))
}
SYS_CLONE => {
let parent_tid = VirtAddr::new(args[2]);
let child_tid = VirtAddr::new(args[3]);
// 地址校验
verify_area(parent_tid, core::mem::size_of::<i32>())?;
verify_area(child_tid, core::mem::size_of::<i32>())?;
let mut clone_args = KernelCloneArgs::new();
clone_args.flags = CloneFlags::from_bits_truncate(args[0] as u64);
clone_args.stack = args[1];
clone_args.parent_tid = parent_tid;
clone_args.child_tid = child_tid;
clone_args.tls = args[4];
Self::clone(frame, clone_args)
}
SYS_FUTEX => {
let uaddr = VirtAddr::new(args[0]);
let operation = FutexFlag::from_bits(args[1] as u32).ok_or(SystemError::ENOSYS)?;
let val = args[2] as u32;
let utime = args[3];
let uaddr2 = VirtAddr::new(args[4]);
let val3 = args[5] as u32;
verify_area(uaddr, core::mem::size_of::<u32>())?;
verify_area(uaddr2, core::mem::size_of::<u32>())?;
let mut timespec = None;
if utime != 0 && operation.contains(FutexFlag::FLAGS_HAS_TIMEOUT) {
let reader = UserBufferReader::new(
utime as *const TimeSpec,
core::mem::size_of::<TimeSpec>(),
true,
)?;
timespec = Some(reader.read_one_from_user::<TimeSpec>(0)?.clone());
}
Self::do_futex(uaddr, operation, val, timespec, uaddr2, utime as u32, val3)
}
SYS_READV => Self::readv(args[0] as i32, args[1], args[2]),
SYS_WRITEV => Self::writev(args[0] as i32, args[1], args[2]),
SYS_SET_TID_ADDRESS => Self::set_tid_address(args[0]),
#[cfg(target_arch = "x86_64")]
SYS_LSTAT => {
let path: &CStr = unsafe { CStr::from_ptr(args[0] as *const c_char) };
let path: Result<&str, core::str::Utf8Error> = path.to_str();
let res = if path.is_err() {
Err(SystemError::EINVAL)
} else {
let path: &str = path.unwrap();
let kstat = args[1] as *mut PosixKstat;
let vaddr = VirtAddr::new(kstat as usize);
match verify_area(vaddr, core::mem::size_of::<PosixKstat>()) {
Ok(_) => Self::lstat(path, kstat),
Err(e) => Err(e),
}
};
res
}
#[cfg(target_arch = "x86_64")]
SYS_STAT => {
let path: &CStr = unsafe { CStr::from_ptr(args[0] as *const c_char) };
let path: Result<&str, core::str::Utf8Error> = path.to_str();
let res = if path.is_err() {
Err(SystemError::EINVAL)
} else {
let path: &str = path.unwrap();
let kstat = args[1] as *mut PosixKstat;
let vaddr = VirtAddr::new(kstat as usize);
match verify_area(vaddr, core::mem::size_of::<PosixKstat>()) {
Ok(_) => Self::stat(path, kstat),
Err(e) => Err(e),
}
};
res
}
SYS_EPOLL_CREATE => Self::epoll_create(args[0] as i32),
SYS_EPOLL_CREATE1 => Self::epoll_create1(args[0]),
SYS_EPOLL_CTL => Self::epoll_ctl(
args[0] as i32,
args[1],
args[2] as i32,
VirtAddr::new(args[3]),
),
SYS_EPOLL_WAIT => Self::epoll_wait(
args[0] as i32,
VirtAddr::new(args[1]),
args[2] as i32,
args[3] as i32,
),
SYS_EPOLL_PWAIT => {
let epfd = args[0] as i32;
let epoll_event = VirtAddr::new(args[1]);
let max_events = args[2] as i32;
let timespec = args[3] as i32;
let sigmask_addr = args[4] as *mut SigSet;
if sigmask_addr.is_null() {
return Self::epoll_wait(epfd, epoll_event, max_events, timespec);
}
let sigmask_reader =
UserBufferReader::new(sigmask_addr, core::mem::size_of::<SigSet>(), true)?;
let mut sigmask = sigmask_reader.read_one_from_user::<SigSet>(0)?.clone();
Self::epoll_pwait(
args[0] as i32,
VirtAddr::new(args[1]),
args[2] as i32,
args[3] as i32,
&mut sigmask,
)
}
// 目前为了适配musl-libc,以下系统调用先这样写着
SYS_GETRANDOM => {
let flags = GRandFlags::from_bits(args[2] as u8).ok_or(SystemError::EINVAL)?;
Self::get_random(args[0] as *mut u8, args[1], flags)
}
SYS_SOCKETPAIR => {
unimplemented!()
}
#[cfg(target_arch = "x86_64")]
SYS_POLL => {
kwarn!("SYS_POLL has not yet been implemented");
Ok(0)
}
SYS_RT_SIGPROCMASK => {
kwarn!("SYS_RT_SIGPROCMASK has not yet been implemented");
Ok(0)
}
SYS_TKILL => {
kwarn!("SYS_TKILL has not yet been implemented");
Ok(0)
}
SYS_SIGALTSTACK => {
kwarn!("SYS_SIGALTSTACK has not yet been implemented");
Ok(0)
}
SYS_EXIT_GROUP => {
kwarn!("SYS_EXIT_GROUP has not yet been implemented");
Ok(0)
}
SYS_MADVISE => {
// 这个太吵了,总是打印,先注释掉
// kwarn!("SYS_MADVISE has not yet been implemented");
Ok(0)
}
SYS_GETTID => Self::gettid().map(|tid| tid.into()),
SYS_GETUID => Self::getuid().map(|uid| uid.into()),
SYS_SYSLOG => {
let syslog_action_type = args[0] as usize;
let buf_vaddr = args[1];
let len = args[2];
let from_user = frame.from_user();
let mut user_buffer_writer =
UserBufferWriter::new(buf_vaddr as *mut u8, len, from_user)?;
let user_buf = user_buffer_writer.buffer(0)?;
let res = Self::do_syslog(syslog_action_type, user_buf, len);
res
}
SYS_GETGID => Self::getgid().map(|gid| gid.into()),
SYS_SETUID => {
kwarn!("SYS_SETUID has not yet been implemented");
Ok(0)
}
SYS_SETGID => {
kwarn!("SYS_SETGID has not yet been implemented");
Ok(0)
}
SYS_GETEUID => Self::geteuid().map(|euid| euid.into()),
SYS_GETEGID => Self::getegid().map(|egid| egid.into()),
SYS_GETRUSAGE => {
let who = args[0] as c_int;
let rusage = args[1] as *mut RUsage;
Self::get_rusage(who, rusage)
}
#[cfg(target_arch = "x86_64")]
SYS_READLINK => {
let path = args[0] as *const u8;
let buf = args[1] as *mut u8;
let bufsiz = args[2] as usize;
Self::readlink(path, buf, bufsiz)
}
SYS_READLINKAT => {
let dirfd = args[0] as i32;
let pathname = args[1] as *const u8;
let buf = args[2] as *mut u8;
let bufsiz = args[3] as usize;
Self::readlink_at(dirfd, pathname, buf, bufsiz)
}
SYS_PRLIMIT64 => {
let pid = args[0];
let pid = Pid::new(pid);
let resource = args[1];
let new_limit = args[2] as *const RLimit64;
let old_limit = args[3] as *mut RLimit64;
Self::prlimit64(pid, resource, new_limit, old_limit)
}
#[cfg(target_arch = "x86_64")]
SYS_ACCESS => {
let pathname = args[0] as *const u8;
let mode = args[1] as u32;
Self::access(pathname, mode)
}
SYS_FACCESSAT => {
let dirfd = args[0] as i32;
let pathname = args[1] as *const u8;
let mode = args[2] as u32;
Self::faccessat2(dirfd, pathname, mode, 0)
}
SYS_FACCESSAT2 => {
let dirfd = args[0] as i32;
let pathname = args[1] as *const u8;
let mode = args[2] as u32;
let flags = args[3] as u32;
Self::faccessat2(dirfd, pathname, mode, flags)
}
SYS_CLOCK_GETTIME => {
let clockid = args[0] as i32;
let timespec = args[1] as *mut TimeSpec;
Self::clock_gettime(clockid, timespec)
}
SYS_SYSINFO => {
let info = args[0] as *mut SysInfo;
Self::sysinfo(info)
}
SYS_UMASK => {
let mask = args[0] as u32;
Self::umask(mask)
}
#[cfg(target_arch = "x86_64")]
SYS_CHMOD => {
let pathname = args[0] as *const u8;
let mode = args[1] as u32;
Self::chmod(pathname, mode)
}
SYS_FCHMOD => {
let fd = args[0] as i32;
let mode = args[1] as u32;
Self::fchmod(fd, mode)
}
SYS_FCHMODAT => {
let dirfd = args[0] as i32;
let pathname = args[1] as *const u8;
let mode = args[2] as u32;
Self::fchmodat(dirfd, pathname, mode)
}
SYS_SCHED_GETAFFINITY => {
// todo: 这个系统调用还没有实现
Err(SystemError::ENOSYS)
}
SYS_SCHED_YIELD => Self::sched_yield(),
_ => panic!("Unsupported syscall ID: {}", syscall_num),
};
return r;
}
pub fn put_string(
s: *const u8,
front_color: u32,
back_color: u32,
) -> Result<usize, SystemError> {
return Ok(unsafe { do_put_string(s, front_color, back_color) });
}
pub fn reboot() -> Result<usize, SystemError> {
unsafe { cpu_reset() };
}
}