重构系统调用模块 (#267)

* 完成系统调用模块重构

* 更新github workflow
This commit is contained in:
login
2023-05-24 17:05:33 +08:00
committed by GitHub
parent 660a04cef8
commit ab5c8ca46d
35 changed files with 1870 additions and 1760 deletions

View File

@ -1,5 +1,23 @@
use core::{
ffi::{c_char, c_int, c_void, CStr},
sync::atomic::{AtomicBool, Ordering},
};
use num_traits::{FromPrimitive, ToPrimitive};
use crate::{
arch::cpu::cpu_reset,
filesystem::vfs::{
file::FileMode,
syscall::{SEEK_CUR, SEEK_END, SEEK_MAX, SEEK_SET},
MAX_PATHLEN,
},
include::bindings::bindings::{mm_stat_t, pid_t, verify_area, PAGE_2M_SIZE, PAGE_4K_SIZE},
io::SeekFrom, kinfo,
net::syscall::SockAddr,
time::TimeSpec,
};
#[repr(i32)]
#[derive(Debug, FromPrimitive, ToPrimitive, PartialEq, Eq, Clone)]
#[allow(dead_code, non_camel_case_types)]
@ -285,3 +303,585 @@ impl SystemError {
return -<Self as ToPrimitive>::to_i32(self).unwrap();
}
}
// 定义系统调用号
pub const SYS_PUT_STRING: usize = 1;
pub const SYS_OPEN: usize = 2;
pub const SYS_CLOSE: usize = 3;
pub const SYS_READ: usize = 4;
pub const SYS_WRITE: usize = 5;
pub const SYS_LSEEK: usize = 6;
pub const SYS_FORK: usize = 7;
pub const SYS_VFORK: usize = 8;
pub const SYS_BRK: usize = 9;
pub const SYS_SBRK: usize = 10;
pub const SYS_REBOOT: usize = 11;
pub const SYS_CHDIR: usize = 12;
pub const SYS_GET_DENTS: usize = 13;
pub const SYS_EXECVE: usize = 14;
pub const SYS_WAIT4: usize = 15;
pub const SYS_EXIT: usize = 16;
pub const SYS_MKDIR: usize = 17;
pub const SYS_NANOSLEEP: usize = 18;
/// todo: 该系统调用与Linux不一致将来需要删除该系统调用 删的时候记得改C版本的libc
pub const SYS_CLOCK: usize = 19;
pub const SYS_PIPE: usize = 20;
/// todo: 该系统调用不是符合POSIX标准的在将来需要删除
pub const SYS_MSTAT: usize = 21;
pub const SYS_UNLINK_AT: usize = 22;
pub const SYS_KILL: usize = 23;
pub const SYS_SIGACTION: usize = 24;
pub const SYS_RT_SIGRETURN: usize = 25;
pub const SYS_GETPID: usize = 26;
pub const SYS_SCHED: usize = 27;
pub const SYS_DUP: usize = 28;
pub const SYS_DUP2: usize = 29;
pub const SYS_SOCKET: usize = 30;
pub const SYS_SETSOCKOPT: usize = 31;
pub const SYS_GETSOCKOPT: usize = 32;
pub const SYS_CONNECT: usize = 33;
pub const SYS_BIND: usize = 34;
pub const SYS_SENDTO: usize = 35;
pub const SYS_RECVFROM: usize = 36;
pub const SYS_RECVMSG: usize = 37;
pub const SYS_LISTEN: usize = 38;
pub const SYS_SHUTDOWN: usize = 39;
pub const SYS_ACCEPT: usize = 40;
pub const SYS_GETSOCKNAME: usize = 41;
pub const SYS_GETPEERNAME: usize = 42;
#[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 系统调用分发器,用于分发系统调用。
///
/// 这个函数内,需要根据系统调用号,调用对应的系统调用处理函数。
/// 并且,对于用户态传入的指针参数,需要在本函数内进行越界检查,防止访问到内核空间。
pub fn handle(syscall_num: usize, args: &[usize], from_user: bool) -> usize {
let r = match syscall_num {
SYS_PUT_STRING => {
Self::put_string(args[0] as *const u8, args[1] as u32, args[2] as u32)
}
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 open_flags: FileMode = FileMode::from_bits_truncate(flags as u32);
Self::open(path, open_flags)
};
// kdebug!("open: {:?}, res: {:?}", path, res);
res
}
SYS_CLOSE => {
let fd = args[0];
Self::close(fd)
}
SYS_READ => {
let fd = args[0] as i32;
let buf_vaddr = args[1];
let len = args[2];
// 判断缓冲区是否来自用户态,进行权限校验
let res = if from_user && unsafe { !verify_area(buf_vaddr as u64, len as u64) } {
// 来自用户态而buffer在内核态这样的操作不被允许
Err(SystemError::EPERM)
} else {
let buf: &mut [u8] = unsafe {
core::slice::from_raw_parts_mut::<'static, u8>(buf_vaddr as *mut u8, len)
};
Self::read(fd, buf)
};
res
}
SYS_WRITE => {
let fd = args[0] as i32;
let buf_vaddr = args[1];
let len = args[2];
// 判断缓冲区是否来自用户态,进行权限校验
let res = if from_user && unsafe { !verify_area(buf_vaddr as u64, len as u64) } {
// 来自用户态而buffer在内核态这样的操作不被允许
Err(SystemError::EPERM)
} else {
let buf: &[u8] = unsafe {
core::slice::from_raw_parts::<'static, u8>(buf_vaddr as *const u8, len)
};
Self::write(fd, 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),
};
let res = if w.is_err() {
Err(w.unwrap_err())
} else {
let w = w.unwrap();
Self::lseek(fd, w)
};
res
}
SYS_BRK => {
let new_brk = args[0];
Self::brk(new_brk)
}
SYS_SBRK => {
let increment = args[0] as isize;
Self::sbrk(increment)
}
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;
// 权限校验
if path_ptr.is_null()
|| (from_user
&& unsafe { !verify_area(path_ptr as u64, PAGE_2M_SIZE as u64) })
{
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() > PAGE_4K_SIZE as usize {
return Err(SystemError::ENAMETOOLONG);
}
return Ok(dest_path);
};
let r: Result<&str, SystemError> = chdir_check(args[0]);
if r.is_err() {
Err(r.unwrap_err())
} else {
Self::chdir(r.unwrap())
}
}
SYS_GET_DENTS => {
let fd = args[0] as i32;
let buf_vaddr = args[1];
let len = args[2];
// 判断缓冲区是否来自用户态,进行权限校验
let res = if from_user && unsafe { !verify_area(buf_vaddr as u64, len as u64) } {
// 来自用户态而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];
// 权限校验
if from_user
&& (unsafe { !verify_area(path_ptr as u64, PAGE_4K_SIZE as u64) }
|| unsafe { !verify_area(argv_ptr as u64, PAGE_4K_SIZE as u64) })
|| unsafe { !verify_area(env_ptr as u64, PAGE_4K_SIZE as u64) }
{
Err(SystemError::EFAULT)
} else {
Self::execve(
path_ptr as *const c_void,
argv_ptr as *const *const c_void,
env_ptr as *const *const c_void,
)
}
}
SYS_WAIT4 => {
let pid = args[0] as pid_t;
let wstatus = args[1] as *mut c_int;
let options = args[2] as c_int;
let rusage = args[3] as *mut c_void;
// 权限校验
// todo: 引入rusage之后更正以下权限校验代码中rusage的大小
if from_user
&& (unsafe {
!verify_area(wstatus as u64, core::mem::size_of::<c_int>() as u64)
} || unsafe { !verify_area(rusage as u64, PAGE_4K_SIZE as u64) })
{
Err(SystemError::EFAULT)
} else {
Self::wait4(pid, wstatus, options, rusage)
}
}
SYS_EXIT => {
let exit_code = args[0];
Self::exit(exit_code)
}
SYS_MKDIR => {
let path_ptr = args[0] as *const c_char;
let mode = args[1];
let security_check = || {
if path_ptr.is_null()
|| (from_user
&& unsafe { !verify_area(path_ptr as u64, PAGE_2M_SIZE as u64) })
{
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;
if from_user
&& (unsafe {
!verify_area(req as u64, core::mem::size_of::<TimeSpec>() as u64)
} || unsafe {
!verify_area(rem as u64, core::mem::size_of::<TimeSpec>() as u64)
})
{
Err(SystemError::EFAULT)
} else {
Self::nanosleep(req, rem)
}
}
SYS_CLOCK => Self::clock(),
SYS_PIPE => {
let pipefd = args[0] as *mut c_int;
if from_user
&& unsafe {
!verify_area(pipefd as u64, core::mem::size_of::<[c_int; 2]>() as u64)
}
{
Err(SystemError::EFAULT)
} else if pipefd.is_null() {
Err(SystemError::EFAULT)
} else {
let pipefd = unsafe { core::slice::from_raw_parts_mut(pipefd, 2) };
Self::pipe(pipefd)
}
}
SYS_MSTAT => {
let dst = args[0] as *mut mm_stat_t;
if from_user
&& unsafe { !verify_area(dst as u64, core::mem::size_of::<mm_stat_t>() as u64) }
{
Err(SystemError::EFAULT)
} else if dst.is_null() {
Err(SystemError::EFAULT)
} else {
Self::mstat(dst, from_user)
}
}
SYS_UNLINK_AT => {
let dirfd = args[0] as i32;
let pathname = args[1] as *const c_char;
let flags = args[2] as u32;
if from_user && unsafe { !verify_area(pathname as u64, PAGE_4K_SIZE as u64) } {
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 {
Self::unlinkat(dirfd, pathname.unwrap(), flags)
}
}
}
SYS_KILL => {
let pid = args[0] as pid_t;
let sig = args[1] as c_int;
Self::kill(pid, sig)
}
SYS_SIGACTION => {
let sig = args[0] as c_int;
let act = args[1];
let old_act = args[2];
Self::sigaction(sig, act, old_act, from_user)
}
SYS_RT_SIGRETURN => {
// 由于目前signal机制的实现与x86_64强关联因此暂时在arch/x86_64/syscall.rs中调用
// todo: 未来需要将signal机制与平台解耦
todo!()
}
SYS_GETPID => Self::getpid(),
SYS_SCHED => Self::sched(from_user),
SYS_DUP => {
let oldfd: i32 = args[0] as c_int;
Self::dup(oldfd)
}
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;
// 验证optval的地址是否合法
if unsafe { verify_area(optval as u64, optlen as u64) } == false {
// 地址空间超出了用户空间的范围,不合法
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 security_check = || {
// 验证optval的地址是否合法
if unsafe { verify_area(optval as u64, PAGE_4K_SIZE as u64) } == false {
// 地址空间超出了用户空间的范围,不合法
return Err(SystemError::EFAULT);
}
// 验证optlen的地址是否合法
if unsafe { verify_area(optlen as u64, core::mem::size_of::<u32>() as u64) }
== false
{
// 地址空间超出了用户空间的范围,不合法
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;
// 验证addr的地址是否合法
if unsafe { verify_area(addr as u64, addrlen as u64) } == false {
// 地址空间超出了用户空间的范围,不合法
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;
// 验证addr的地址是否合法
if unsafe { verify_area(addr as u64, addrlen as u64) } == false {
// 地址空间超出了用户空间的范围,不合法
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;
// 验证buf的地址是否合法
if unsafe { verify_area(buf as u64, len as u64) } == false {
// 地址空间超出了用户空间的范围,不合法
Err(SystemError::EFAULT)
} else if unsafe { verify_area(addr as u64, addrlen as u64) } == false {
// 地址空间超出了用户空间的范围,不合法
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 security_check = || {
// 验证buf的地址是否合法
if unsafe { verify_area(buf as u64, len as u64) } == false {
// 地址空间超出了用户空间的范围,不合法
return Err(SystemError::EFAULT);
}
// 验证addrlen的地址是否合法
if unsafe { verify_area(addrlen as u64, core::mem::size_of::<u32>() as u64) }
== false
{
// 地址空间超出了用户空间的范围,不合法
return Err(SystemError::EFAULT);
}
if unsafe { verify_area(addr as u64, core::mem::size_of::<SockAddr>() as u64) }
== false
{
// 地址空间超出了用户空间的范围,不合法
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;
let security_check = || {
// 验证msg的地址是否合法
if unsafe {
verify_area(
msg as u64,
core::mem::size_of::<crate::net::syscall::MsgHdr>() as u64,
)
} == false
{
// 地址空间超出了用户空间的范围,不合法
return Err(SystemError::EFAULT);
}
let msg = unsafe { msg.as_mut() }.ok_or(SystemError::EFAULT)?;
return Ok(msg);
};
let r = security_check();
if r.is_err() {
Err(r.unwrap_err())
} else {
let msg = r.unwrap();
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_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)
}
_ => panic!("Unsupported syscall ID: {}", syscall_num),
};
let r = r.unwrap_or_else(|e| e.to_posix_errno() as usize);
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> {
cpu_reset();
}
}

View File

@ -13,91 +13,6 @@
// 导出系统调用入口函数定义在entry.S中
extern void syscall_int(void);
extern uint64_t sys_clock(struct pt_regs *regs);
extern uint64_t sys_mstat(struct pt_regs *regs);
extern uint64_t sys_open(struct pt_regs *regs);
extern uint64_t sys_unlink_at(struct pt_regs *regs);
extern uint64_t sys_kill(struct pt_regs *regs);
extern uint64_t sys_sigaction(struct pt_regs *regs);
extern uint64_t sys_rt_sigreturn(struct pt_regs *regs);
extern uint64_t sys_getpid(struct pt_regs *regs);
extern uint64_t sys_sched(struct pt_regs *regs);
extern int sys_dup(int oldfd);
extern int sys_dup2(int oldfd, int newfd);
extern uint64_t sys_socket(struct pt_regs *regs);
extern uint64_t sys_setsockopt(struct pt_regs *regs);
extern uint64_t sys_getsockopt(struct pt_regs *regs);
extern uint64_t sys_connect(struct pt_regs *regs);
extern uint64_t sys_bind(struct pt_regs *regs);
extern uint64_t sys_sendto(struct pt_regs *regs);
extern uint64_t sys_recvfrom(struct pt_regs *regs);
extern uint64_t sys_recvmsg(struct pt_regs *regs);
extern uint64_t sys_listen(struct pt_regs *regs);
extern uint64_t sys_shutdown(struct pt_regs *regs);
extern uint64_t sys_accept(struct pt_regs *regs);
extern uint64_t sys_getsockname(struct pt_regs *regs);
extern uint64_t sys_getpeername(struct pt_regs *regs);
extern uint64_t sys_pipe(struct pt_regs *regs);
extern uint64_t sys_mkdir(struct pt_regs *regs);
/**
* @brief 关闭文件系统调用
*
* @param fd_num 文件描述符号
*
* @param regs
* @return uint64_t
*/
extern uint64_t sys_close(struct pt_regs *regs);
/**
* @brief 从文件中读取数据
*
* @param fd_num regs->r8 文件描述符号
* @param buf regs->r9 输出缓冲区
* @param count regs->r10 要读取的字节数
*
* @return uint64_t
*/
extern uint64_t sys_read(struct pt_regs *regs);
/**
* @brief 向文件写入数据
*
* @param fd_num regs->r8 文件描述符号
* @param buf regs->r9 输入缓冲区
* @param count regs->r10 要写入的字节数
*
* @return uint64_t
*/
extern uint64_t sys_write(struct pt_regs *regs);
/**
* @brief 调整文件的访问位置
*
* @param fd_num 文件描述符号
* @param offset 偏移量
* @param whence 调整模式
* @return uint64_t 调整结束后的文件访问位置
*/
extern uint64_t sys_lseek(struct pt_regs *regs);
/**
* @brief 导出系统调用处理函数的符号
*
*/
/**
* @brief 系统调用不存在时的处理函数
*
* @param regs 进程3特权级下的寄存器
* @return ul
*/
ul system_call_not_exists(struct pt_regs *regs)
{
kerror("System call [ ID #%d ] not exists.", regs->rax);
return ESYSCALL_NOT_EXISTS;
} // 取消前述宏定义
/**
* @brief 重新定义为:把系统调用函数加入系统调用表
* @param syscall_num 系统调用号
@ -105,17 +20,6 @@ ul system_call_not_exists(struct pt_regs *regs)
*/
#define SYSCALL_COMMON(syscall_num, symbol) [syscall_num] = symbol,
/**
* @brief 初始化系统调用模块
*
*/
void syscall_init()
{
kinfo("Initializing syscall...");
set_system_trap_gate(0x80, 0, syscall_int); // 系统调用门
}
/**
* @brief 通过中断进入系统调用
*
@ -162,36 +66,23 @@ long enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg
* @param arg2 背景色
* @return ul 返回值
*/
ul sys_put_string(struct pt_regs *regs)
ul do_put_string(char *s, uint32_t front_color, uint32_t background_color)
{
printk_color(regs->r9, regs->r10, (char *)regs->r8);
// printk_color(BLACK, WHITE, (char *)regs->r8);
printk_color(front_color, background_color, s);
return 0;
}
uint64_t sys_fork(struct pt_regs *regs)
{
return do_fork(regs, 0, regs->rsp, 0);
}
uint64_t sys_vfork(struct pt_regs *regs)
{
return do_fork(regs, CLONE_VM | CLONE_FS | CLONE_SIGNAL, regs->rsp, 0);
}
/**
* @brief 将堆内存调整为arg0
*
* @param arg0 新的堆区域的结束地址
* arg0=-1 ===> 返回堆区域的起始地址
* arg0=-2 ===> 返回堆区域的结束地址
* @return uint64_t 错误码
*
*/
uint64_t sys_brk(struct pt_regs *regs)
uint64_t sys_do_brk(uint64_t newaddr)
{
uint64_t new_brk = PAGE_2M_ALIGN(regs->r8);
uint64_t new_brk = PAGE_2M_ALIGN(newaddr);
// kdebug("sys_brk input= %#010lx , new_brk= %#010lx bytes current_pcb->mm->brk_start=%#018lx
// current->end_brk=%#018lx", regs->r8, new_brk, current_pcb->mm->brk_start, current_pcb->mm->brk_end);
struct mm_struct *mm = current_pcb->mm;
@ -216,16 +107,16 @@ uint64_t sys_brk(struct pt_regs *regs)
/**
* @brief 将堆内存空间加上offset注意该系统调用只应在普通进程中调用而不能是内核线程
*
* @param arg0 offset偏移量
* @param incr offset偏移量
* @return uint64_t the previous program break
*/
uint64_t sys_sbrk(struct pt_regs *regs)
uint64_t sys_do_sbrk(int64_t incr)
{
uint64_t retval = current_pcb->mm->brk_end;
if ((int64_t)regs->r8 > 0)
if ((int64_t)incr > 0)
{
uint64_t new_brk = PAGE_2M_ALIGN(retval + regs->r8);
uint64_t new_brk = PAGE_2M_ALIGN(retval + incr);
if (new_brk > current_pcb->addr_limit) // 堆地址空间超过限制
{
kdebug("exceed mem limit, new_brk = %#018lx", new_brk);
@ -234,58 +125,16 @@ uint64_t sys_sbrk(struct pt_regs *regs)
}
else
{
if ((__int128_t)current_pcb->mm->brk_end + (__int128_t)regs->r8 < current_pcb->mm->brk_start)
if ((__int128_t)current_pcb->mm->brk_end + (__int128_t)incr < current_pcb->mm->brk_start)
return retval;
}
// kdebug("do brk");
uint64_t new_brk = mm_do_brk(current_pcb->mm->brk_end, (int64_t)regs->r8); // 调整堆内存空间
uint64_t new_brk = mm_do_brk(current_pcb->mm->brk_end, (int64_t)incr); // 调整堆内存空间
// kdebug("do brk done, new_brk = %#018lx", new_brk);
current_pcb->mm->brk_end = new_brk;
return retval;
}
/**
* @brief 重启计算机
*
* @return
*/
uint64_t sys_reboot(struct pt_regs *regs)
{
// 重启计算机
io_out8(0x64, 0xfe);
return 0;
}
/**
* @brief 切换工作目录
*
* @param dest_path 目标路径
* @return
+--------------+------------------------+
| 返回码 | 描述 |
+--------------+------------------------+
| 0 | 成功 |
| EACCESS | 权限不足 |
| ELOOP | 解析path时遇到路径循环 |
| ENAMETOOLONG | 路径名过长 |
| ENOENT | 目标文件或目录不存在 |
| ENODIR | 检索期间发现非目录项 |
| ENOMEM | 系统内存不足 |
| EFAULT | 错误的地址 |
| ENAMETOOLONG | 路径过长 |
+--------------+------------------------+
*/
extern uint64_t sys_chdir(struct pt_regs *regs);
/**
* @brief 获取目录中的数据
*
* @param fd 文件描述符号
* @return uint64_t dirent的总大小
*/
extern uint64_t sys_getdents(struct pt_regs *regs);
/**
* @brief 执行新的程序
*
@ -293,12 +142,9 @@ extern uint64_t sys_getdents(struct pt_regs *regs);
* @param argv(r9寄存器) 参数列表
* @return uint64_t
*/
uint64_t sys_execve(struct pt_regs *regs)
uint64_t c_sys_execve(char *user_path, char **argv, char **envp, struct pt_regs *regs)
{
char *user_path = (char *)regs->r8;
char **argv = (char **)regs->r9;
int path_len = strnlen_user(user_path, PAGE_4K_SIZE);
if (path_len >= PAGE_4K_SIZE)
@ -332,12 +178,8 @@ uint64_t sys_execve(struct pt_regs *regs)
* @param rusage
* @return uint64_t
*/
uint64_t sys_wait4(struct pt_regs *regs)
uint64_t c_sys_wait4(pid_t pid, int *status, int options, void *rusage)
{
uint64_t pid = regs->r8;
int *status = (int *)regs->r9;
int options = regs->r10;
void *rusage = (void *)regs->r11;
struct process_control_block *proc = NULL;
struct process_control_block *child_proc = NULL;
@ -369,82 +211,3 @@ uint64_t sys_wait4(struct pt_regs *regs)
process_release_pcb(child_proc);
return 0;
}
/**
* @brief 进程退出
*
* @param exit_code 退出返回码
* @return uint64_t
*/
uint64_t sys_exit(struct pt_regs *regs)
{
return process_do_exit(regs->r8);
}
uint64_t sys_nanosleep(struct pt_regs *regs)
{
const struct timespec *rqtp = (const struct timespec *)regs->r8;
struct timespec *rmtp = (struct timespec *)regs->r9;
return rs_nanosleep(rqtp, rmtp);
}
ul sys_ahci_end_req(struct pt_regs *regs)
{
// ahci_end_request();
return 0;
}
// 系统调用的内核入口程序
void do_syscall_int(struct pt_regs *regs, unsigned long error_code)
{
ul ret = system_call_table[regs->rax](regs);
regs->rax = ret; // 返回码
}
system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] = {
[0] = system_call_not_exists,
[1] = sys_put_string,
[2] = sys_open,
[3] = sys_close,
[4] = sys_read,
[5] = sys_write,
[6] = sys_lseek,
[7] = sys_fork,
[8] = sys_vfork,
[9] = sys_brk,
[10] = sys_sbrk,
[11] = sys_reboot,
[12] = sys_chdir,
[13] = sys_getdents,
[14] = sys_execve,
[15] = sys_wait4,
[16] = sys_exit,
[17] = sys_mkdir,
[18] = sys_nanosleep,
[19] = sys_clock,
[20] = sys_pipe,
[21] = sys_mstat,
[22] = sys_unlink_at,
[23] = sys_kill,
[24] = sys_sigaction,
[25] = sys_rt_sigreturn,
[26] = sys_getpid,
[27] = sys_sched,
[28] = sys_dup,
[29] = sys_dup2,
[30] = sys_socket,
[31] = sys_setsockopt,
[32] = sys_getsockopt,
[33] = sys_connect,
[34] = sys_bind,
[35] = sys_sendto,
[36] = sys_recvfrom,
[37] = sys_recvmsg,
[38] = sys_listen,
[39] = sys_shutdown,
[40] = sys_accept,
[41] = sys_getsockname,
[42] = sys_getpeername,
[43 ... 255] = system_call_not_exists,
};

View File

@ -5,25 +5,11 @@
#include <common/unistd.h>
#include <process/ptrace.h>
// 定义最大系统调用数量
#define MAX_SYSTEM_CALL_NUM 256
#define ESYSCALL_NOT_EXISTS 1
typedef unsigned long (*system_call_t)(struct pt_regs *regs);
extern system_call_t system_call_table[MAX_SYSTEM_CALL_NUM];
// 判断系统调用是否来自用户态
#define SYSCALL_FROM_USER(regs) (user_mode(regs))
// 判断系统调用是否来自内核态
#define SYSCALL_FROM_KERNEL(regs) (!SYSCALL_FROM_USER(regs))
/**
* @brief 初始化系统调用模块
*
*/
void syscall_init();
extern int syscall_init();
/**
* @brief 用户态系统调用入口函数
@ -33,57 +19,3 @@ void syscall_init();
*/
long enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7);
/**
* @brief 系统调用不存在时的处理函数
*
* @param regs 进程3特权级下的寄存器
* @return ul
*/
ul system_call_not_exists(struct pt_regs *regs);
/**
* @brief 打印字符串的系统调用
*
* 当arg1和arg2均为0时打印黑底白字否则按照指定的前景色和背景色来打印
*
* @param regs 寄存器
* @param arg0 要打印的字符串
* @param arg1 前景色
* @param arg2 背景色
* @return ul 返回值
*/
ul sys_printf(struct pt_regs *regs);
/**
* @brief 将堆内存调整为arg0
*
* @param arg0 新的堆区域的结束地址
* arg0=0 ===> 返回堆区域的起始地址
* arg0=-1 ===> 返回堆区域的结束地址
* @return uint64_t 错误码
*
*/
uint64_t sys_brk(struct pt_regs *regs);
/**
* @brief 将堆内存空间加上offset注意该系统调用只应在普通进程中调用而不能是内核线程
*
* @param arg0 offset偏移量
* @return uint64_t the previous program break
*/
uint64_t sys_sbrk(struct pt_regs *regs);
/**
* @brief 创建文件夹
* 在VFS.c中实现
* @param path(r8) 路径
* @param mode(r9) 模式
* @return uint64_t
*/
uint64_t sys_mkdir(struct pt_regs *regs);
ul sys_ahci_end_req(struct pt_regs *regs);
// 系统调用的内核入口程序
void do_syscall_int(struct pt_regs *regs, unsigned long error_code);

View File

@ -1,11 +1,9 @@
#pragma once
/**
* 系统调用说明
* 1 printf
* 请注意由于系统调用模块已经使用Rust重构当修改系统调用号时需要同时修改syscall_num.h和syscall/mod.rs中的系统调用号
* 并且以syscall/mod.rs中的为准
*
*
* 255 AHCI end_request
* TODO在完成系统的重构后删除syscall_num.h
*
*/
@ -43,17 +41,15 @@
#define SYS_DUP2 29
#define SYS_SOCKET 30 // 创建一个socket
#define SYS_SETSOCKOPT 31 // 设置socket的选项
#define SYS_GETSOCKOPT 32 // 获取socket的选项
#define SYS_CONNECT 33 // 连接到一个socket
#define SYS_BIND 34 // 绑定一个socket
#define SYS_SENDTO 35 // 向一个socket发送数据
#define SYS_RECVFROM 36 // 从一个socket接收数据
#define SYS_RECVMSG 37 // 从一个socket接收消息
#define SYS_LISTEN 38 // 监听一个socket
#define SYS_SHUTDOWN 39 // 关闭socket
#define SYS_ACCEPT 40 // 接受一个socket连接
#define SYS_SETSOCKOPT 31 // 设置socket的选项
#define SYS_GETSOCKOPT 32 // 获取socket的选项
#define SYS_CONNECT 33 // 连接到一个socket
#define SYS_BIND 34 // 绑定一个socket
#define SYS_SENDTO 35 // 向一个socket发送数据
#define SYS_RECVFROM 36 // 从一个socket接收数据
#define SYS_RECVMSG 37 // 从一个socket接收消息
#define SYS_LISTEN 38 // 监听一个socket
#define SYS_SHUTDOWN 39 // 关闭socket
#define SYS_ACCEPT 40 // 接受一个socket连接
#define SYS_GETSOCKNAME 41 // 获取socket的名字
#define SYS_GETPEERNAME 42 // 获取socket的对端名字
#define SYS_AHCI_END_REQ 255 // AHCI DMA请求结束end_request的系统调用