mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-18 12:16:31 +00:00
@ -15,3 +15,10 @@ pub fn cpu_relax() {
|
||||
asm!("pause");
|
||||
}
|
||||
}
|
||||
|
||||
/// 重置cpu
|
||||
pub fn cpu_reset() -> ! {
|
||||
// 重启计算机
|
||||
unsafe { x86::io::outb(0x64, 0xfe) };
|
||||
loop {}
|
||||
}
|
||||
|
@ -8,5 +8,6 @@ pub mod mm;
|
||||
pub mod pci;
|
||||
pub mod rand;
|
||||
pub mod sched;
|
||||
pub mod syscall;
|
||||
|
||||
pub use interrupt::X86_64InterruptArch as CurrentIrqArch;
|
||||
|
113
kernel/src/arch/x86_64/syscall.rs
Normal file
113
kernel/src/arch/x86_64/syscall.rs
Normal file
@ -0,0 +1,113 @@
|
||||
use core::ffi::c_void;
|
||||
|
||||
use crate::{
|
||||
include::bindings::bindings::{
|
||||
pt_regs, set_system_trap_gate, verify_area, CLONE_FS, CLONE_SIGNAL, CLONE_VM, PAGE_4K_SIZE,
|
||||
},
|
||||
ipc::signal::sys_rt_sigreturn,
|
||||
kinfo,
|
||||
syscall::{Syscall, SystemError, SYS_EXECVE, SYS_FORK, SYS_RT_SIGRETURN, SYS_VFORK},
|
||||
};
|
||||
|
||||
use super::{
|
||||
asm::{ptrace::user_mode},
|
||||
mm::barrier::mfence,
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
fn do_fork(regs: *mut pt_regs, clone_flags: u64, stack_start: u64, stack_size: u64) -> u64;
|
||||
fn c_sys_execve(
|
||||
path: *const u8,
|
||||
argv: *const *const u8,
|
||||
envp: *const *const u8,
|
||||
regs: &mut pt_regs,
|
||||
) -> u64;
|
||||
|
||||
fn syscall_int();
|
||||
}
|
||||
|
||||
macro_rules! syscall_return {
|
||||
($val:expr, $regs:expr) => {{
|
||||
let ret = $val;
|
||||
$regs.rax = ret as u64;
|
||||
return;
|
||||
}};
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn syscall_handler(regs: &mut pt_regs) -> () {
|
||||
let syscall_num = regs.rax as usize;
|
||||
let args = [
|
||||
regs.r8 as usize,
|
||||
regs.r9 as usize,
|
||||
regs.r10 as usize,
|
||||
regs.r11 as usize,
|
||||
regs.r12 as usize,
|
||||
regs.r13 as usize,
|
||||
regs.r14 as usize,
|
||||
regs.r15 as usize,
|
||||
];
|
||||
mfence();
|
||||
mfence();
|
||||
let from_user = user_mode(regs);
|
||||
|
||||
// 由于进程管理未完成重构,有些系统调用需要在这里临时处理,以后这里的特殊处理要删掉。
|
||||
match syscall_num {
|
||||
SYS_FORK => unsafe {
|
||||
syscall_return!(do_fork(regs, 0, regs.rsp, 0), regs);
|
||||
},
|
||||
SYS_VFORK => unsafe {
|
||||
syscall_return!(
|
||||
do_fork(
|
||||
regs,
|
||||
(CLONE_VM | CLONE_FS | CLONE_SIGNAL) as u64,
|
||||
regs.rsp,
|
||||
0,
|
||||
),
|
||||
regs
|
||||
);
|
||||
},
|
||||
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) }
|
||||
{
|
||||
syscall_return!(SystemError::EFAULT.to_posix_errno() as u64, regs);
|
||||
} else {
|
||||
syscall_return!(
|
||||
unsafe {
|
||||
c_sys_execve(
|
||||
path_ptr as *const u8,
|
||||
argv_ptr as *const *const u8,
|
||||
env_ptr as *const *const u8,
|
||||
regs,
|
||||
)
|
||||
},
|
||||
regs
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SYS_RT_SIGRETURN => {
|
||||
syscall_return!(sys_rt_sigreturn(regs), regs);
|
||||
}
|
||||
// SYS_SCHED => {
|
||||
// syscall_return!(sched(from_user) as u64, regs);
|
||||
// }
|
||||
_ => {}
|
||||
}
|
||||
syscall_return!(Syscall::handle(syscall_num, &args, from_user) as u64, regs);
|
||||
}
|
||||
|
||||
/// 系统调用初始化
|
||||
pub fn arch_syscall_init() -> Result<(), SystemError> {
|
||||
kinfo!("arch_syscall_init\n");
|
||||
unsafe { set_system_trap_gate(0x80, 0, syscall_int as *mut c_void) }; // 系统调用门
|
||||
return Ok(());
|
||||
}
|
@ -118,7 +118,6 @@ impl AhciDisk {
|
||||
buf_ptr = kbuf.as_mut().unwrap().as_mut_ptr() as usize;
|
||||
}
|
||||
|
||||
|
||||
#[allow(unused_unsafe)]
|
||||
let cmdtbl = unsafe {
|
||||
(phys_2_virt(volatile_read!(cmdheader.ctba) as usize) as *mut HbaCmdTable)
|
||||
@ -259,7 +258,7 @@ impl AhciDisk {
|
||||
// 设置数据存放地址
|
||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
let mut buf_ptr = buf as *const [u8] as *mut usize as usize;
|
||||
|
||||
|
||||
// 由于目前的内存管理机制无法把用户空间的内存地址转换为物理地址,所以只能先把数据拷贝到内核空间
|
||||
// TODO:在内存管理重构后,可以直接使用用户空间的内存地址
|
||||
let user_buf = if unsafe { verify_area(buf_ptr as u64, buf.len() as u64) } {
|
||||
|
@ -12,7 +12,7 @@ use crate::{
|
||||
include::bindings::bindings::{textui_putchar, BLACK, WHITE},
|
||||
kerror,
|
||||
libs::rwlock::RwLock,
|
||||
syscall::SystemError, kdebug, arch::asm::current::current_pcb,
|
||||
syscall::SystemError,
|
||||
};
|
||||
|
||||
use super::{TtyCore, TtyError, TtyFileFlag, TtyFilePrivateData};
|
||||
@ -263,7 +263,6 @@ impl IndexNode for TtyDevice {
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl TtyDevicePrivateData {
|
||||
|
@ -284,7 +284,7 @@ ENTRY(virtualization_exception)
|
||||
ENTRY(syscall_int)
|
||||
pushq $0
|
||||
pushq %rax
|
||||
leaq do_syscall_int(%rip), %rax // 获取系统调用服务程序的地址
|
||||
leaq syscall_handler(%rip), %rax // 获取系统调用服务程序的地址
|
||||
xchgq %rax, (%rsp) // 把FUNC的地址换入栈中
|
||||
jmp Err_Code
|
||||
|
||||
|
@ -7,7 +7,6 @@ use core::{
|
||||
use alloc::{boxed::Box, format, string::ToString, sync::Arc};
|
||||
|
||||
use crate::{
|
||||
arch::asm::current::current_pcb,
|
||||
driver::disk::ahci::{self},
|
||||
filesystem::{
|
||||
devfs::DevFS,
|
||||
@ -15,10 +14,9 @@ use crate::{
|
||||
procfs::ProcFS,
|
||||
ramfs::RamFS,
|
||||
sysfs::SysFS,
|
||||
vfs::{file::File, mount::MountFS, FileSystem, FileType},
|
||||
vfs::{mount::MountFS, FileSystem, FileType},
|
||||
},
|
||||
include::bindings::bindings::PAGE_4K_SIZE,
|
||||
io::SeekFrom,
|
||||
kerror, kinfo,
|
||||
syscall::SystemError,
|
||||
};
|
||||
@ -201,113 +199,6 @@ pub extern "C" fn mount_root_fs() -> i32 {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// @brief 为当前进程打开一个文件
|
||||
pub fn do_open(path: &str, mode: FileMode) -> Result<i32, SystemError> {
|
||||
// 文件名过长
|
||||
if path.len() > PAGE_4K_SIZE as usize {
|
||||
return Err(SystemError::ENAMETOOLONG);
|
||||
}
|
||||
|
||||
let inode: Result<Arc<dyn IndexNode>, SystemError> = ROOT_INODE().lookup(path);
|
||||
|
||||
let inode: Arc<dyn IndexNode> = if inode.is_err() {
|
||||
let errno = inode.unwrap_err();
|
||||
// 文件不存在,且需要创建
|
||||
if mode.contains(FileMode::O_CREAT)
|
||||
&& !mode.contains(FileMode::O_DIRECTORY)
|
||||
&& errno == SystemError::ENOENT
|
||||
{
|
||||
let (filename, parent_path) = rsplit_path(path);
|
||||
// 查找父目录
|
||||
let parent_inode: Arc<dyn IndexNode> =
|
||||
ROOT_INODE().lookup(parent_path.unwrap_or("/"))?;
|
||||
// 创建文件
|
||||
let inode: Arc<dyn IndexNode> = parent_inode.create(filename, FileType::File, 0o777)?;
|
||||
inode
|
||||
} else {
|
||||
// 不需要创建文件,因此返回错误码
|
||||
return Err(errno);
|
||||
}
|
||||
} else {
|
||||
inode.unwrap()
|
||||
};
|
||||
|
||||
let file_type: FileType = inode.metadata()?.file_type;
|
||||
// 如果要打开的是文件夹,而目标不是文件夹
|
||||
if mode.contains(FileMode::O_DIRECTORY) && file_type != FileType::Dir {
|
||||
return Err(SystemError::ENOTDIR);
|
||||
}
|
||||
|
||||
// 如果O_TRUNC,并且,打开模式包含O_RDWR或O_WRONLY,清空文件
|
||||
if mode.contains(FileMode::O_TRUNC)
|
||||
&& (mode.contains(FileMode::O_RDWR) || mode.contains(FileMode::O_WRONLY))
|
||||
&& file_type == FileType::File
|
||||
{
|
||||
inode.truncate(0)?;
|
||||
}
|
||||
|
||||
// 创建文件对象
|
||||
let mut file: File = File::new(inode, mode)?;
|
||||
|
||||
// 打开模式为“追加”
|
||||
if mode.contains(FileMode::O_APPEND) {
|
||||
file.lseek(SeekFrom::SeekEnd(0))?;
|
||||
}
|
||||
|
||||
// 把文件对象存入pcb
|
||||
return current_pcb().alloc_fd(file, None);
|
||||
}
|
||||
|
||||
/// @brief 根据文件描述符,读取文件数据。尝试读取的数据长度与buf的长度相同。
|
||||
///
|
||||
/// @param fd 文件描述符编号
|
||||
/// @param buf 输出缓冲区。
|
||||
///
|
||||
/// @return Ok(usize) 成功读取的数据的字节数
|
||||
/// @return Err(SystemError) 读取失败,返回posix错误码
|
||||
pub fn do_read(fd: i32, buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||
let file: Option<&mut File> = current_pcb().get_file_mut_by_fd(fd);
|
||||
if file.is_none() {
|
||||
return Err(SystemError::EBADF);
|
||||
}
|
||||
let file: &mut File = file.unwrap();
|
||||
|
||||
return file.read(buf.len(), buf);
|
||||
}
|
||||
|
||||
/// @brief 根据文件描述符,向文件写入数据。尝试写入的数据长度与buf的长度相同。
|
||||
///
|
||||
/// @param fd 文件描述符编号
|
||||
/// @param buf 输入缓冲区。
|
||||
///
|
||||
/// @return Ok(usize) 成功写入的数据的字节数
|
||||
/// @return Err(SystemError) 写入失败,返回posix错误码
|
||||
pub fn do_write(fd: i32, buf: &[u8]) -> Result<usize, SystemError> {
|
||||
let file: Option<&mut File> = current_pcb().get_file_mut_by_fd(fd);
|
||||
if file.is_none() {
|
||||
return Err(SystemError::EBADF);
|
||||
}
|
||||
let file: &mut File = file.unwrap();
|
||||
|
||||
return file.write(buf.len(), buf);
|
||||
}
|
||||
|
||||
/// @brief 调整文件操作指针的位置
|
||||
///
|
||||
/// @param fd 文件描述符编号
|
||||
/// @param seek 调整的方式
|
||||
///
|
||||
/// @return Ok(usize) 调整后,文件访问指针相对于文件头部的偏移量
|
||||
/// @return Err(SystemError) 调整失败,返回posix错误码
|
||||
pub fn do_lseek(fd: i32, seek: SeekFrom) -> Result<usize, SystemError> {
|
||||
let file: Option<&mut File> = current_pcb().get_file_mut_by_fd(fd);
|
||||
if file.is_none() {
|
||||
return Err(SystemError::EBADF);
|
||||
}
|
||||
let file: &mut File = file.unwrap();
|
||||
return file.lseek(seek);
|
||||
}
|
||||
|
||||
/// @brief 创建文件/文件夹
|
||||
pub fn do_mkdir(path: &str, _mode: FileMode) -> Result<u64, SystemError> {
|
||||
// 文件名过长
|
||||
|
@ -180,7 +180,7 @@ impl File {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
||||
let pos: i64;
|
||||
match origin {
|
||||
SeekFrom::SeekSet(offset) => {
|
||||
|
@ -16,7 +16,7 @@ use self::{core::generate_inode_id, file::FileMode};
|
||||
pub use self::{core::ROOT_INODE, file::FilePrivateData, mount::MountFS};
|
||||
|
||||
/// vfs容许的最大的路径名称长度
|
||||
pub const MAX_PATHLEN: u32 = 1024;
|
||||
pub const MAX_PATHLEN: usize = 1024;
|
||||
|
||||
/// 定义inode号的类型为usize
|
||||
pub type InodeId = usize;
|
||||
|
@ -1,438 +1,350 @@
|
||||
use core::ffi::{c_char, CStr};
|
||||
|
||||
use alloc::{boxed::Box, string::ToString, vec::Vec};
|
||||
use alloc::{boxed::Box, sync::Arc, vec::Vec};
|
||||
|
||||
use crate::{
|
||||
arch::asm::{current::current_pcb, ptrace::user_mode},
|
||||
arch::asm::{current::current_pcb},
|
||||
filesystem::vfs::file::FileDescriptorVec,
|
||||
include::bindings::bindings::{
|
||||
pt_regs, verify_area, AT_REMOVEDIR, PAGE_2M_SIZE, PAGE_4K_SIZE, PROC_MAX_FD_NUM, SEEK_CUR,
|
||||
SEEK_END, SEEK_MAX, SEEK_SET,
|
||||
verify_area, AT_REMOVEDIR, PAGE_4K_SIZE, PROC_MAX_FD_NUM,
|
||||
},
|
||||
io::SeekFrom,
|
||||
kerror,
|
||||
syscall::SystemError,
|
||||
syscall::{Syscall, SystemError},
|
||||
};
|
||||
|
||||
use super::{
|
||||
core::{do_lseek, do_mkdir, do_open, do_read, do_remove_dir, do_unlink_at, do_write},
|
||||
core::{do_mkdir, do_remove_dir, do_unlink_at},
|
||||
file::{File, FileMode},
|
||||
Dirent, FileType, ROOT_INODE,
|
||||
utils::rsplit_path,
|
||||
Dirent, FileType, IndexNode, ROOT_INODE,
|
||||
};
|
||||
|
||||
/// @brief 打开文件
|
||||
///
|
||||
/// @param regs->r8 path 文件路径
|
||||
/// @param regs->r9 o_flags 打开文件的标志位
|
||||
///
|
||||
/// @return u64 文件描述符编号,或者是错误码
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_open(regs: &pt_regs) -> u64 {
|
||||
let path: &CStr = unsafe { CStr::from_ptr(regs.r8 as usize as *const c_char) };
|
||||
let path: Result<&str, core::str::Utf8Error> = path.to_str();
|
||||
if path.is_err() {
|
||||
return SystemError::EINVAL.to_posix_errno() as u64;
|
||||
}
|
||||
let path: &str = path.unwrap();
|
||||
let flags = regs.r9;
|
||||
let open_flags: FileMode = FileMode::from_bits_truncate(flags as u32);
|
||||
let r: Result<i32, SystemError> = do_open(path, open_flags);
|
||||
pub const SEEK_SET: u32 = 0;
|
||||
pub const SEEK_CUR: u32 = 1;
|
||||
pub const SEEK_END: u32 = 2;
|
||||
pub const SEEK_MAX: u32 = 3;
|
||||
|
||||
if r.is_ok() {
|
||||
return r.unwrap() as u64;
|
||||
} else {
|
||||
return r.unwrap_err().to_posix_errno() as u64;
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief 关闭文件的系统调用函数
|
||||
///
|
||||
/// @param regs->r8 fd:文件描述符编号
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_close(regs: &pt_regs) -> u64 {
|
||||
let fd = regs.r8 as i32;
|
||||
let r: Result<(), SystemError> = current_pcb().drop_fd(fd);
|
||||
|
||||
if r.is_ok() {
|
||||
return 0;
|
||||
} else {
|
||||
return r.unwrap_err().to_posix_errno() as u64;
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief 读取文件的系统调用函数
|
||||
///
|
||||
/// @param regs->r8 文件描述符编号
|
||||
/// @param regs->r9 输出缓冲区
|
||||
/// @param regs->r10 要读取的长度
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_read(regs: &pt_regs) -> u64 {
|
||||
let fd = regs.r8 as i32;
|
||||
let buf_vaddr = regs.r9 as usize;
|
||||
let len = regs.r10 as usize;
|
||||
|
||||
// 判断缓冲区是否来自用户态,进行权限校验
|
||||
if user_mode(regs) && unsafe { !verify_area(buf_vaddr as u64, len as u64) } {
|
||||
// 来自用户态,而buffer在内核态,这样的操作不被允许
|
||||
return SystemError::EPERM.to_posix_errno() as u64;
|
||||
}
|
||||
|
||||
let buf: &mut [u8] =
|
||||
unsafe { core::slice::from_raw_parts_mut::<'static, u8>(buf_vaddr as *mut u8, len) };
|
||||
|
||||
let r: Result<usize, SystemError> = do_read(fd, buf);
|
||||
|
||||
if r.is_ok() {
|
||||
return r.unwrap() as u64;
|
||||
} else {
|
||||
return r.unwrap_err().to_posix_errno() as u64;
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief 向文件写入数据的系统调用函数
|
||||
///
|
||||
/// @param regs->r8 文件描述符编号
|
||||
/// @param regs->r9 输入缓冲区
|
||||
/// @param regs->r10 要写入的长度
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_write(regs: &pt_regs) -> u64 {
|
||||
let fd = regs.r8 as i32;
|
||||
let buf_vaddr = regs.r9 as usize;
|
||||
let len = regs.r10 as usize;
|
||||
|
||||
// 判断缓冲区是否来自用户态,进行权限校验
|
||||
if user_mode(regs) && unsafe { !verify_area(buf_vaddr as u64, len as u64) } {
|
||||
// 来自用户态,而buffer在内核态,这样的操作不被允许
|
||||
return SystemError::EPERM.to_posix_errno() as u64;
|
||||
}
|
||||
|
||||
let buf: &[u8] =
|
||||
unsafe { core::slice::from_raw_parts::<'static, u8>(buf_vaddr as *mut u8, len) };
|
||||
|
||||
let r: Result<usize, SystemError> = do_write(fd, buf);
|
||||
|
||||
if r.is_ok() {
|
||||
return r.unwrap() as u64;
|
||||
} else {
|
||||
return r.unwrap_err().to_posix_errno() as u64;
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief 调整文件访问指针位置的系统调用函数
|
||||
///
|
||||
/// @param regs->r8 文件描述符编号
|
||||
/// @param regs->r9 调整偏移量
|
||||
/// @param regs->r10 调整的模式
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_lseek(regs: &pt_regs) -> u64 {
|
||||
let fd = regs.r8 as i32;
|
||||
let offset = regs.r9 as i64;
|
||||
let whence = regs.r10 as u32;
|
||||
|
||||
let w: SeekFrom = match whence {
|
||||
SEEK_SET => SeekFrom::SeekSet(offset),
|
||||
SEEK_CUR => SeekFrom::SeekCurrent(offset),
|
||||
SEEK_END => SeekFrom::SeekEnd(offset),
|
||||
SEEK_MAX => SeekFrom::SeekEnd(0),
|
||||
_ => return SystemError::EINVAL.to_posix_errno() as u64,
|
||||
};
|
||||
|
||||
let r: Result<usize, SystemError> = do_lseek(fd, w);
|
||||
if r.is_ok() {
|
||||
return r.unwrap() as u64;
|
||||
} else {
|
||||
return r.unwrap_err().to_posix_errno() as u64;
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief 切换工作目录
|
||||
///
|
||||
/// @param dest_path 目标路径
|
||||
///
|
||||
/// @return 返回码 描述
|
||||
/// 0 | 成功
|
||||
///
|
||||
/// EACCESS | 权限不足
|
||||
///
|
||||
/// ELOOP | 解析path时遇到路径循环
|
||||
///
|
||||
/// ENAMETOOLONG | 路径名过长
|
||||
///
|
||||
/// ENOENT | 目标文件或目录不存在
|
||||
///
|
||||
/// ENODIR | 检索期间发现非目录项
|
||||
///
|
||||
/// ENOMEM | 系统内存不足
|
||||
///
|
||||
/// EFAULT | 错误的地址
|
||||
///
|
||||
/// ENAMETOOLONG | 路径过长
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_chdir(regs: &pt_regs) -> u64 {
|
||||
if regs.r8 == 0 {
|
||||
return SystemError::EFAULT.to_posix_errno() as u64;
|
||||
}
|
||||
let ptr = regs.r8 as usize as *const c_char;
|
||||
// 权限校验
|
||||
if ptr.is_null()
|
||||
|| (user_mode(regs) && unsafe { !verify_area(ptr as u64, PAGE_2M_SIZE as u64) })
|
||||
{
|
||||
return SystemError::EINVAL.to_posix_errno() as u64;
|
||||
}
|
||||
|
||||
let dest_path: &CStr = unsafe { CStr::from_ptr(ptr) };
|
||||
let dest_path: Result<&str, core::str::Utf8Error> = dest_path.to_str();
|
||||
|
||||
if dest_path.is_err() {
|
||||
return SystemError::EINVAL.to_posix_errno() as u64;
|
||||
}
|
||||
|
||||
let dest_path: &str = dest_path.unwrap();
|
||||
|
||||
if dest_path.len() == 0 {
|
||||
return SystemError::EINVAL.to_posix_errno() as u64;
|
||||
} else if dest_path.len() >= PAGE_4K_SIZE as usize {
|
||||
return SystemError::ENAMETOOLONG.to_posix_errno() as u64;
|
||||
}
|
||||
|
||||
let path = Box::new(dest_path.clone());
|
||||
let inode = match ROOT_INODE().lookup(&path) {
|
||||
Err(e) => {
|
||||
kerror!("Change Directory Failed, Error = {:?}", e);
|
||||
return SystemError::ENOENT.to_posix_errno() as u64;
|
||||
impl Syscall {
|
||||
/// @brief 为当前进程打开一个文件
|
||||
///
|
||||
/// @param path 文件路径
|
||||
/// @param o_flags 打开文件的标志位
|
||||
///
|
||||
/// @return 文件描述符编号,或者是错误码
|
||||
pub fn open(path: &str, mode: FileMode) -> Result<usize, SystemError> {
|
||||
// 文件名过长
|
||||
if path.len() > PAGE_4K_SIZE as usize {
|
||||
return Err(SystemError::ENAMETOOLONG);
|
||||
}
|
||||
Ok(i) => i,
|
||||
};
|
||||
|
||||
match inode.metadata() {
|
||||
Err(e) => {
|
||||
kerror!("INode Get MetaData Failed, Error = {:?}", e);
|
||||
return SystemError::ENOENT.to_posix_errno() as u64;
|
||||
}
|
||||
Ok(i) => {
|
||||
if let FileType::Dir = i.file_type {
|
||||
return 0;
|
||||
let inode: Result<Arc<dyn IndexNode>, SystemError> = ROOT_INODE().lookup(path);
|
||||
|
||||
let inode: Arc<dyn IndexNode> = if inode.is_err() {
|
||||
let errno = inode.unwrap_err();
|
||||
// 文件不存在,且需要创建
|
||||
if mode.contains(FileMode::O_CREAT)
|
||||
&& !mode.contains(FileMode::O_DIRECTORY)
|
||||
&& errno == SystemError::ENOENT
|
||||
{
|
||||
let (filename, parent_path) = rsplit_path(path);
|
||||
// 查找父目录
|
||||
let parent_inode: Arc<dyn IndexNode> =
|
||||
ROOT_INODE().lookup(parent_path.unwrap_or("/"))?;
|
||||
// 创建文件
|
||||
let inode: Arc<dyn IndexNode> =
|
||||
parent_inode.create(filename, FileType::File, 0o777)?;
|
||||
inode
|
||||
} else {
|
||||
return SystemError::ENOTDIR.to_posix_errno() as u64;
|
||||
// 不需要创建文件,因此返回错误码
|
||||
return Err(errno);
|
||||
}
|
||||
} else {
|
||||
inode.unwrap()
|
||||
};
|
||||
|
||||
let file_type: FileType = inode.metadata()?.file_type;
|
||||
// 如果要打开的是文件夹,而目标不是文件夹
|
||||
if mode.contains(FileMode::O_DIRECTORY) && file_type != FileType::Dir {
|
||||
return Err(SystemError::ENOTDIR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief 获取目录中的数据
|
||||
///
|
||||
/// @param fd 文件描述符号
|
||||
/// @return uint64_t dirent的总大小
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_getdents(regs: &pt_regs) -> u64 {
|
||||
let fd = regs.r8 as i32;
|
||||
let count = regs.r10 as i64;
|
||||
let dirent = match unsafe { (regs.r9 as usize as *mut Dirent).as_mut() } {
|
||||
None => {
|
||||
return 0;
|
||||
// 如果O_TRUNC,并且,打开模式包含O_RDWR或O_WRONLY,清空文件
|
||||
if mode.contains(FileMode::O_TRUNC)
|
||||
&& (mode.contains(FileMode::O_RDWR) || mode.contains(FileMode::O_WRONLY))
|
||||
&& file_type == FileType::File
|
||||
{
|
||||
inode.truncate(0)?;
|
||||
}
|
||||
Some(dirent) => dirent,
|
||||
};
|
||||
|
||||
if fd < 0 || fd as u32 > PROC_MAX_FD_NUM {
|
||||
return SystemError::EBADF.to_posix_errno() as u64;
|
||||
}
|
||||
// 创建文件对象
|
||||
let mut file: File = File::new(inode, mode)?;
|
||||
|
||||
if count < 0 {
|
||||
return SystemError::EINVAL.to_posix_errno() as u64;
|
||||
}
|
||||
|
||||
// 获取fd
|
||||
let file: &mut File = match current_pcb().get_file_mut_by_fd(fd) {
|
||||
None => {
|
||||
return SystemError::EBADF.to_posix_errno() as u64;
|
||||
// 打开模式为“追加”
|
||||
if mode.contains(FileMode::O_APPEND) {
|
||||
file.lseek(SeekFrom::SeekEnd(0))?;
|
||||
}
|
||||
Some(file) => file,
|
||||
};
|
||||
// kdebug!("file={file:?}");
|
||||
|
||||
return match file.readdir(dirent) {
|
||||
Err(_) => 0,
|
||||
Ok(len) => len,
|
||||
};
|
||||
}
|
||||
|
||||
/// @brief 创建文件夹
|
||||
///
|
||||
/// @param path(r8) 路径 / mode(r9) 模式
|
||||
///
|
||||
/// @return uint64_t 负数错误码 / 0表示成功
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_mkdir(regs: &pt_regs) -> u64 {
|
||||
let ptr = regs.r8 as usize as *const c_char;
|
||||
if ptr.is_null()
|
||||
|| (user_mode(regs) && unsafe { !verify_area(ptr as u64, PAGE_2M_SIZE as u64) })
|
||||
{
|
||||
return SystemError::EINVAL.to_posix_errno() as u64;
|
||||
}
|
||||
let path: &CStr = unsafe { CStr::from_ptr(ptr) };
|
||||
let path: Result<&str, core::str::Utf8Error> = path.to_str();
|
||||
let mode = regs.r9;
|
||||
|
||||
if path.is_err() {
|
||||
return SystemError::EINVAL.to_posix_errno() as u64;
|
||||
// 把文件对象存入pcb
|
||||
return current_pcb().alloc_fd(file, None).map(|fd| fd as usize);
|
||||
}
|
||||
|
||||
let path = &path.unwrap().to_string();
|
||||
if path.trim() == "" {
|
||||
return SystemError::EINVAL.to_posix_errno() as u64;
|
||||
/// @brief 关闭文件
|
||||
///
|
||||
/// @param fd 文件描述符编号
|
||||
///
|
||||
/// @return 成功返回0,失败返回错误码
|
||||
pub fn close(fd: usize) -> Result<usize, SystemError> {
|
||||
return current_pcb().drop_fd(fd as i32).map(|_| 0);
|
||||
}
|
||||
|
||||
return match do_mkdir(&path.trim(), FileMode::from_bits_truncate(mode as u32)) {
|
||||
Err(err) => {
|
||||
kerror!("Failed in do_mkdir, Error Code = {:#?}", err);
|
||||
err.to_posix_errno() as u64
|
||||
}
|
||||
Ok(_) => 0,
|
||||
};
|
||||
}
|
||||
|
||||
///@brief 删除文件夹、取消文件的链接、删除文件的系统调用
|
||||
///
|
||||
///@param regs->r8 dfd 进程相对路径基准目录的文件描述符(见fcntl.h)
|
||||
///
|
||||
///@param regs->r9 路径名称字符串
|
||||
///
|
||||
///@param regs->r10 flag 预留的标志位,暂时未使用,请置为0。
|
||||
///
|
||||
///@return uint64_t 错误码
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_unlink_at(regs: &pt_regs) -> u64 {
|
||||
let _dfd = regs.r8;
|
||||
let ptr = regs.r9 as usize as *const c_char;
|
||||
if ptr.is_null()
|
||||
|| (user_mode(regs) && unsafe { !verify_area(ptr as u64, PAGE_2M_SIZE as u64) })
|
||||
{
|
||||
return SystemError::EINVAL.to_posix_errno() as u64;
|
||||
}
|
||||
let path: &CStr = unsafe { CStr::from_ptr(ptr) };
|
||||
let path: Result<&str, core::str::Utf8Error> = path.to_str();
|
||||
let flag = regs.r10;
|
||||
if path.is_err() {
|
||||
return SystemError::EINVAL.to_posix_errno() as u64;
|
||||
}
|
||||
|
||||
let path = &path.unwrap().to_string();
|
||||
// kdebug!("sys_unlink_at={path:?}");
|
||||
if (flag & (!(AT_REMOVEDIR as u64))) != 0_u64 {
|
||||
return SystemError::EINVAL.to_posix_errno() as u64;
|
||||
}
|
||||
|
||||
if (flag & (AT_REMOVEDIR as u64)) > 0 {
|
||||
// kdebug!("rmdir");
|
||||
match do_remove_dir(&path) {
|
||||
Err(err) => {
|
||||
kerror!("Failed to Remove Directory, Error Code = {:?}", err);
|
||||
return err.to_posix_errno() as u64;
|
||||
}
|
||||
Ok(_) => {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// kdebug!("rm");
|
||||
match do_unlink_at(&path, FileMode::from_bits_truncate(flag as u32)) {
|
||||
Err(err) => {
|
||||
kerror!("Failed to Remove Directory, Error Code = {:?}", err);
|
||||
return err.to_posix_errno() as u64;
|
||||
}
|
||||
Ok(_) => {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn do_dup(oldfd: i32) -> Result<i32, SystemError> {
|
||||
if let Some(fds) = FileDescriptorVec::from_pcb(current_pcb()) {
|
||||
// 获得当前文件描述符数组
|
||||
// 确认oldfd是否有效
|
||||
if FileDescriptorVec::validate_fd(oldfd) {
|
||||
if let Some(file) = &fds.fds[oldfd as usize] {
|
||||
// 尝试获取对应的文件结构体
|
||||
let file_cp = (file).try_clone();
|
||||
if file_cp.is_none() {
|
||||
return Err(SystemError::EBADF);
|
||||
}
|
||||
let res = current_pcb().alloc_fd(*file_cp.unwrap(), None);
|
||||
// 申请文件描述符,并把文件对象存入其中
|
||||
return res;
|
||||
}
|
||||
// oldfd对应的文件不存在
|
||||
/// @brief 根据文件描述符,读取文件数据。尝试读取的数据长度与buf的长度相同。
|
||||
///
|
||||
/// @param fd 文件描述符编号
|
||||
/// @param buf 输出缓冲区。
|
||||
///
|
||||
/// @return Ok(usize) 成功读取的数据的字节数
|
||||
/// @return Err(SystemError) 读取失败,返回posix错误码
|
||||
pub fn read(fd: i32, buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||
let file: Option<&mut File> = current_pcb().get_file_mut_by_fd(fd);
|
||||
if file.is_none() {
|
||||
return Err(SystemError::EBADF);
|
||||
}
|
||||
return Err(SystemError::EBADF);
|
||||
} else {
|
||||
return Err(SystemError::EMFILE);
|
||||
}
|
||||
}
|
||||
let file: &mut File = file.unwrap();
|
||||
|
||||
#[no_mangle]
|
||||
/// @brief 根据提供的文件描述符的fd,复制对应的文件结构体,并返回新复制的文件结构体对应的fd
|
||||
pub extern "C" fn sys_dup(regs: &pt_regs) -> u64 {
|
||||
let fd: i32 = regs.r8 as i32;
|
||||
let r = do_dup(fd);
|
||||
if r.is_ok() {
|
||||
return r.unwrap() as u64;
|
||||
} else {
|
||||
return r.unwrap_err().to_posix_errno() as u64;
|
||||
return file.read(buf.len(), buf);
|
||||
}
|
||||
}
|
||||
|
||||
fn do_dup2(oldfd: i32, newfd: i32) -> Result<i32, SystemError> {
|
||||
if let Some(fds) = FileDescriptorVec::from_pcb(current_pcb()) {
|
||||
// 获得当前文件描述符数组
|
||||
if FileDescriptorVec::validate_fd(oldfd) && FileDescriptorVec::validate_fd(newfd) {
|
||||
//确认oldfd, newid是否有效
|
||||
if oldfd == newfd {
|
||||
// 若oldfd与newfd相等
|
||||
return Ok(newfd);
|
||||
/// @brief 根据文件描述符,向文件写入数据。尝试写入的数据长度与buf的长度相同。
|
||||
///
|
||||
/// @param fd 文件描述符编号
|
||||
/// @param buf 输入缓冲区。
|
||||
///
|
||||
/// @return Ok(usize) 成功写入的数据的字节数
|
||||
/// @return Err(SystemError) 写入失败,返回posix错误码
|
||||
pub fn write(fd: i32, buf: &[u8]) -> Result<usize, SystemError> {
|
||||
let file: Option<&mut File> = current_pcb().get_file_mut_by_fd(fd);
|
||||
if file.is_none() {
|
||||
return Err(SystemError::EBADF);
|
||||
}
|
||||
let file: &mut File = file.unwrap();
|
||||
|
||||
return file.write(buf.len(), buf);
|
||||
}
|
||||
|
||||
/// @brief 调整文件操作指针的位置
|
||||
///
|
||||
/// @param fd 文件描述符编号
|
||||
/// @param seek 调整的方式
|
||||
///
|
||||
/// @return Ok(usize) 调整后,文件访问指针相对于文件头部的偏移量
|
||||
/// @return Err(SystemError) 调整失败,返回posix错误码
|
||||
pub fn lseek(fd: i32, seek: SeekFrom) -> Result<usize, SystemError> {
|
||||
let file: Option<&mut File> = current_pcb().get_file_mut_by_fd(fd);
|
||||
if file.is_none() {
|
||||
return Err(SystemError::EBADF);
|
||||
}
|
||||
let file: &mut File = file.unwrap();
|
||||
return file.lseek(seek);
|
||||
}
|
||||
|
||||
/// @brief 切换工作目录
|
||||
///
|
||||
/// @param dest_path 目标路径
|
||||
///
|
||||
/// @return 返回码 描述
|
||||
/// 0 | 成功
|
||||
///
|
||||
/// EACCESS | 权限不足
|
||||
///
|
||||
/// ELOOP | 解析path时遇到路径循环
|
||||
///
|
||||
/// ENAMETOOLONG | 路径名过长
|
||||
///
|
||||
/// ENOENT | 目标文件或目录不存在
|
||||
///
|
||||
/// ENODIR | 检索期间发现非目录项
|
||||
///
|
||||
/// ENOMEM | 系统内存不足
|
||||
///
|
||||
/// EFAULT | 错误的地址
|
||||
///
|
||||
/// ENAMETOOLONG | 路径过长
|
||||
pub fn chdir(dest_path: &str) -> Result<usize, SystemError> {
|
||||
// Copy path to kernel space to avoid some security issues
|
||||
let path: Box<&str> = Box::new(dest_path);
|
||||
let inode = match ROOT_INODE().lookup(&path) {
|
||||
Err(e) => {
|
||||
kerror!("Change Directory Failed, Error = {:?}", e);
|
||||
return Err(SystemError::ENOENT);
|
||||
}
|
||||
Ok(i) => i,
|
||||
};
|
||||
|
||||
if let Some(file) = &fds.fds[oldfd as usize] {
|
||||
if fds.fds[newfd as usize].is_some() {
|
||||
// close newfd
|
||||
if let Err(_) = current_pcb().drop_fd(newfd) {
|
||||
// An I/O error occurred while attempting to close fildes2.
|
||||
return Err(SystemError::EIO);
|
||||
}
|
||||
match inode.metadata() {
|
||||
Err(e) => {
|
||||
kerror!("INode Get MetaData Failed, Error = {:?}", e);
|
||||
return Err(SystemError::ENOENT);
|
||||
}
|
||||
Ok(i) => {
|
||||
if let FileType::Dir = i.file_type {
|
||||
return Ok(0);
|
||||
} else {
|
||||
return Err(SystemError::ENOTDIR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 尝试获取对应的文件结构体
|
||||
let file_cp = file.try_clone();
|
||||
if file_cp.is_none() {
|
||||
return Err(SystemError::EBADF);
|
||||
/// @brief 获取目录中的数据
|
||||
///
|
||||
/// TODO: 这个函数的语义与Linux不一致,需要修改!!!
|
||||
///
|
||||
/// @param fd 文件描述符号
|
||||
/// @param buf 输出缓冲区
|
||||
///
|
||||
/// @return 成功返回读取的字节数,失败返回错误码
|
||||
pub fn getdents(fd: i32, buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||
let dirent =
|
||||
unsafe { (buf.as_mut_ptr() as *mut Dirent).as_mut() }.ok_or(SystemError::EFAULT)?;
|
||||
|
||||
if fd < 0 || fd as u32 > PROC_MAX_FD_NUM {
|
||||
return Err(SystemError::EBADF);
|
||||
}
|
||||
|
||||
// 获取fd
|
||||
let file: &mut File = match current_pcb().get_file_mut_by_fd(fd) {
|
||||
None => {
|
||||
return Err(SystemError::EBADF);
|
||||
}
|
||||
Some(file) => file,
|
||||
};
|
||||
// kdebug!("file={file:?}");
|
||||
|
||||
return file.readdir(dirent).map(|x| x as usize);
|
||||
}
|
||||
|
||||
/// @brief 创建文件夹
|
||||
///
|
||||
/// @param path(r8) 路径 / mode(r9) 模式
|
||||
///
|
||||
/// @return uint64_t 负数错误码 / 0表示成功
|
||||
pub fn mkdir(path: &str, mode: usize) -> Result<usize, SystemError> {
|
||||
return do_mkdir(path, FileMode::from_bits_truncate(mode as u32)).map(|x| x as usize);
|
||||
}
|
||||
|
||||
/// **删除文件夹、取消文件的链接、删除文件的系统调用**
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `dirfd`:文件夹的文件描述符.目前暂未实现
|
||||
/// - `pathname`:文件夹的路径
|
||||
/// - `flags`:标志位
|
||||
///
|
||||
///
|
||||
pub fn unlinkat(_dirfd: i32, pathname: &str, flags: u32) -> Result<usize, SystemError> {
|
||||
// kdebug!("sys_unlink_at={path:?}");
|
||||
if (flags & (!AT_REMOVEDIR)) != 0 {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
if (flags & AT_REMOVEDIR) > 0 {
|
||||
// kdebug!("rmdir");
|
||||
match do_remove_dir(&pathname) {
|
||||
Err(err) => {
|
||||
kerror!("Failed to Remove Directory, Error Code = {:?}", err);
|
||||
return Err(err);
|
||||
}
|
||||
// 申请文件描述符,并把文件对象存入其中
|
||||
let res = current_pcb().alloc_fd(*file_cp.unwrap(), Some(newfd));
|
||||
Ok(_) => {
|
||||
return Ok(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
match do_unlink_at(&pathname, FileMode::from_bits_truncate(flags as u32)) {
|
||||
Err(err) => {
|
||||
kerror!("Failed to Remove Directory, Error Code = {:?}", err);
|
||||
return Err(err);
|
||||
}
|
||||
Ok(_) => {
|
||||
return Ok(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief 根据提供的文件描述符的fd,复制对应的文件结构体,并返回新复制的文件结构体对应的fd
|
||||
pub fn dup(oldfd: i32) -> Result<usize, SystemError> {
|
||||
if let Some(fds) = FileDescriptorVec::from_pcb(current_pcb()) {
|
||||
// 获得当前文件描述符数组
|
||||
// 确认oldfd是否有效
|
||||
if FileDescriptorVec::validate_fd(oldfd) {
|
||||
if let Some(file) = &fds.fds[oldfd as usize] {
|
||||
// 尝试获取对应的文件结构体
|
||||
let file_cp: Box<File> = file.try_clone().ok_or(SystemError::EBADF)?;
|
||||
|
||||
// 申请文件描述符,并把文件对象存入其中
|
||||
let res = current_pcb().alloc_fd(*file_cp, None).map(|x| x as usize);
|
||||
return res;
|
||||
}
|
||||
// oldfd对应的文件不存在
|
||||
return Err(SystemError::EBADF);
|
||||
}
|
||||
return Err(SystemError::EBADF);
|
||||
} else {
|
||||
return Err(SystemError::EBADF);
|
||||
return Err(SystemError::EMFILE);
|
||||
}
|
||||
}
|
||||
// 从pcb获取文件描述符数组失败
|
||||
return Err(SystemError::EMFILE);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
/// @brief 根据提供的文件描述符的fd,和指定新fd,复制对应的文件结构体,
|
||||
/// 并返回新复制的文件结构体对应的fd
|
||||
pub extern "C" fn sys_dup2(regs: &pt_regs) -> u64 {
|
||||
let ofd = regs.r8 as i32;
|
||||
let nfd = regs.r9 as i32;
|
||||
let r = do_dup2(ofd, nfd);
|
||||
if r.is_ok() {
|
||||
return r.unwrap() as u64;
|
||||
} else {
|
||||
return r.unwrap_err().to_posix_errno() as u64;
|
||||
/// 根据提供的文件描述符的fd,和指定新fd,复制对应的文件结构体,
|
||||
/// 并返回新复制的文件结构体对应的fd.
|
||||
/// 如果新fd已经打开,则会先关闭新fd.
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `oldfd`:旧文件描述符
|
||||
/// - `newfd`:新文件描述符
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// - 成功:新文件描述符
|
||||
/// - 失败:错误码
|
||||
pub fn dup2(oldfd: i32, newfd: i32) -> Result<usize, SystemError> {
|
||||
if let Some(fds) = FileDescriptorVec::from_pcb(current_pcb()) {
|
||||
// 获得当前文件描述符数组
|
||||
if FileDescriptorVec::validate_fd(oldfd) && FileDescriptorVec::validate_fd(newfd) {
|
||||
//确认oldfd, newid是否有效
|
||||
if oldfd == newfd {
|
||||
// 若oldfd与newfd相等
|
||||
return Ok(newfd as usize);
|
||||
}
|
||||
|
||||
if let Some(file) = &fds.fds[oldfd as usize] {
|
||||
if fds.fds[newfd as usize].is_some() {
|
||||
// close newfd
|
||||
if let Err(_) = current_pcb().drop_fd(newfd) {
|
||||
// An I/O error occurred while attempting to close fildes2.
|
||||
return Err(SystemError::EIO);
|
||||
}
|
||||
}
|
||||
|
||||
// 尝试获取对应的文件结构体
|
||||
let file_cp = file.try_clone();
|
||||
if file_cp.is_none() {
|
||||
return Err(SystemError::EBADF);
|
||||
}
|
||||
// 申请文件描述符,并把文件对象存入其中
|
||||
let res = current_pcb()
|
||||
.alloc_fd(*file_cp.unwrap(), Some(newfd))
|
||||
.map(|x| x as usize);
|
||||
|
||||
return res;
|
||||
}
|
||||
return Err(SystemError::EBADF);
|
||||
} else {
|
||||
return Err(SystemError::EBADF);
|
||||
}
|
||||
}
|
||||
// 从pcb获取文件描述符数组失败
|
||||
return Err(SystemError::EMFILE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <driver/pci/pci.h>
|
||||
#include <driver/video/video.h>
|
||||
#include <driver/virtio/virtio.h>
|
||||
#include <exception/gate.h>
|
||||
#include <include/DragonOS/refcount.h>
|
||||
#include <include/DragonOS/signal.h>
|
||||
#include <libs/libUI/textui.h>
|
||||
|
@ -16,7 +16,7 @@ use crate::{
|
||||
spinlock_t, verify_area, NULL, PF_EXITING, PF_KTHREAD, PF_SIGNALED, PF_WAKEKILL,
|
||||
PROC_INTERRUPTIBLE, USER_CS, USER_DS, USER_MAX_LINEAR_ADDR,
|
||||
},
|
||||
ipc::signal_types::{sigset_add, user_sigaction},
|
||||
ipc::signal_types::sigset_add,
|
||||
kBUG, kdebug, kerror, kwarn,
|
||||
libs::{
|
||||
ffi_convert::FFIBind2Rust,
|
||||
@ -35,12 +35,11 @@ use crate::{
|
||||
use super::signal_types::{
|
||||
si_code_val, sig_is_member, sigaction, sigaction__union_u, sigcontext, sigframe,
|
||||
sighand_struct, siginfo, signal_struct, sigpending, sigset_clear, sigset_del, sigset_delmask,
|
||||
sigset_equal, sigset_init, sigset_t, SigQueue, SignalNumber, MAX_SIG_NUM, SA_ALL_FLAGS,
|
||||
SA_FLAG_DFL, SA_FLAG_IGN, SA_FLAG_IMMUTABLE, SA_FLAG_RESTORER, STACK_ALIGN, USER_SIG_DFL,
|
||||
USER_SIG_IGN, _NSIG_U64_CNT,
|
||||
sigset_equal, sigset_t, SigQueue, SignalNumber, MAX_SIG_NUM, SA_ALL_FLAGS,
|
||||
SA_FLAG_DFL, SA_FLAG_IGN, SA_FLAG_IMMUTABLE, SA_FLAG_RESTORER, STACK_ALIGN, _NSIG_U64_CNT,
|
||||
};
|
||||
|
||||
use super::signal_types::{__siginfo_union, __siginfo_union_data};
|
||||
|
||||
|
||||
/// 默认信号处理程序占位符(用于在sighand结构体中的action数组中占位)
|
||||
pub static DEFAULT_SIGACTION: sigaction = sigaction {
|
||||
@ -63,53 +62,11 @@ pub static DEFAULT_SIGACTION_IGNORE: sigaction = sigaction {
|
||||
sa_restorer: NULL as u64,
|
||||
};
|
||||
|
||||
/// @brief kill系统调用,向指定的进程发送信号
|
||||
/// @param regs->r8 pid 要接收信号的进程id
|
||||
/// @param regs->r9 sig 信号
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_kill(regs: &pt_regs) -> u64 {
|
||||
let pid: pid_t = regs.r8 as pid_t;
|
||||
let sig: SignalNumber = SignalNumber::from(regs.r9 as i32);
|
||||
|
||||
if sig == SignalNumber::INVALID {
|
||||
// 传入的signal数值不合法
|
||||
kwarn!("Not a valid signal number");
|
||||
return SystemError::EINVAL.to_posix_errno() as u64;
|
||||
}
|
||||
|
||||
// 初始化signal info
|
||||
let mut info = siginfo {
|
||||
_sinfo: __siginfo_union {
|
||||
data: __siginfo_union_data {
|
||||
si_signo: sig as i32,
|
||||
si_code: si_code_val::SI_USER as i32,
|
||||
si_errno: 0,
|
||||
reserved: 0,
|
||||
_sifields: super::signal_types::__sifields {
|
||||
_kill: super::signal_types::__sifields__kill { _pid: pid },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
|
||||
let retval = signal_kill_something_info(sig, Some(&mut info), pid);
|
||||
let x;
|
||||
if retval.is_ok() {
|
||||
x = retval.unwrap();
|
||||
} else {
|
||||
x = retval.unwrap_err().to_posix_errno();
|
||||
}
|
||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
|
||||
return x as u64;
|
||||
}
|
||||
|
||||
/// 通过kill的方式向目标进程发送信号
|
||||
/// @param sig 要发送的信号
|
||||
/// @param info 要发送的信息
|
||||
/// @param pid 进程id(目前只支持pid>0)
|
||||
fn signal_kill_something_info(
|
||||
pub fn signal_kill_something_info(
|
||||
sig: SignalNumber,
|
||||
info: Option<&mut siginfo>,
|
||||
pid: pid_t,
|
||||
@ -827,124 +784,7 @@ pub fn flush_signal_handlers(pcb: *mut process_control_block, force_default: boo
|
||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
}
|
||||
|
||||
/// @brief 用户程序用于设置信号处理动作的函数(遵循posix2008)
|
||||
///
|
||||
/// @param regs->r8 signumber 信号的编号
|
||||
/// @param regs->r9 act 新的,将要被设置的sigaction
|
||||
/// @param regs->r10 oact 返回给用户的原本的sigaction(内核将原本的sigaction的值拷贝给这个地址)
|
||||
///
|
||||
/// @return int 错误码
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_sigaction(regs: &mut pt_regs) -> u64 {
|
||||
// 请注意:用户态传进来的user_sigaction结构体类型,请注意,这个结构体与内核实际的不一样
|
||||
let act = regs.r9 as usize as *mut user_sigaction;
|
||||
let mut old_act = regs.r10 as usize as *mut user_sigaction;
|
||||
let mut new_ka: sigaction = Default::default();
|
||||
let mut old_ka: sigaction = Default::default();
|
||||
|
||||
// 如果传入的,新的sigaction不为空
|
||||
if !act.is_null() {
|
||||
// 如果参数的范围不在用户空间,则返回错误
|
||||
if unsafe { !verify_area(act as usize as u64, size_of::<sigaction>() as u64) } {
|
||||
return SystemError::EFAULT.to_posix_errno() as u64;
|
||||
}
|
||||
let mask: sigset_t = unsafe { (*act).sa_mask };
|
||||
let _input_sah = unsafe { (*act).sa_handler as u64 };
|
||||
// kdebug!("_input_sah={}", _input_sah);
|
||||
match _input_sah {
|
||||
USER_SIG_DFL | USER_SIG_IGN => {
|
||||
if _input_sah == USER_SIG_DFL {
|
||||
new_ka = DEFAULT_SIGACTION;
|
||||
new_ka.sa_flags =
|
||||
(unsafe { (*act).sa_flags } & (!(SA_FLAG_DFL | SA_FLAG_IGN))) | SA_FLAG_DFL;
|
||||
} else {
|
||||
new_ka = DEFAULT_SIGACTION_IGNORE;
|
||||
new_ka.sa_flags =
|
||||
(unsafe { (*act).sa_flags } & (!(SA_FLAG_DFL | SA_FLAG_IGN))) | SA_FLAG_IGN;
|
||||
}
|
||||
|
||||
let sar = unsafe { (*act).sa_restorer };
|
||||
new_ka.sa_restorer = sar as u64;
|
||||
}
|
||||
_ => {
|
||||
// 从用户空间获得sigaction结构体
|
||||
new_ka = sigaction {
|
||||
_u: sigaction__union_u {
|
||||
_sa_handler: unsafe { (*act).sa_handler as u64 },
|
||||
},
|
||||
sa_flags: unsafe { (*act).sa_flags },
|
||||
sa_mask: sigset_t::default(),
|
||||
sa_restorer: unsafe { (*act).sa_restorer as u64 },
|
||||
};
|
||||
}
|
||||
}
|
||||
// kdebug!("new_ka={:?}", new_ka);
|
||||
// 如果用户手动给了sa_restorer,那么就置位SA_FLAG_RESTORER,否则报错。(用户必须手动指定restorer)
|
||||
if new_ka.sa_restorer != NULL as u64 {
|
||||
new_ka.sa_flags |= SA_FLAG_RESTORER;
|
||||
} else {
|
||||
kwarn!(
|
||||
"pid:{}: in sys_sigaction: User must manually sprcify a sa_restorer for signal {}.",
|
||||
current_pcb().pid,
|
||||
regs.r8.clone()
|
||||
);
|
||||
}
|
||||
sigset_init(&mut new_ka.sa_mask, mask);
|
||||
}
|
||||
|
||||
let sig = SignalNumber::from(regs.r8 as i32);
|
||||
// 如果给出的信号值不合法
|
||||
if sig == SignalNumber::INVALID {
|
||||
return SystemError::EINVAL.to_posix_errno() as u64;
|
||||
}
|
||||
|
||||
let retval = do_sigaction(
|
||||
sig,
|
||||
if act.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(&mut new_ka)
|
||||
},
|
||||
if old_act.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(&mut old_ka)
|
||||
},
|
||||
);
|
||||
|
||||
// 将原本的sigaction拷贝到用户程序指定的地址
|
||||
if (retval == Ok(())) && (!old_act.is_null()) {
|
||||
if unsafe { !verify_area(old_act as usize as u64, size_of::<sigaction>() as u64) } {
|
||||
return SystemError::EFAULT.to_posix_errno() as u64;
|
||||
}
|
||||
// !!!!!!!!!!todo: 检查这里old_ka的mask,是否位SIG_IGN SIG_DFL,如果是,则将_sa_handler字段替换为对应的值
|
||||
let sah: u64;
|
||||
let flag = old_ka.sa_flags & (SA_FLAG_DFL | SA_FLAG_IGN);
|
||||
match flag {
|
||||
SA_FLAG_DFL => {
|
||||
sah = USER_SIG_DFL;
|
||||
}
|
||||
SA_FLAG_IGN => {
|
||||
sah = USER_SIG_IGN;
|
||||
}
|
||||
_ => sah = unsafe { old_ka._u._sa_handler },
|
||||
}
|
||||
unsafe {
|
||||
(*old_act).sa_handler = sah as *mut c_void;
|
||||
(*old_act).sa_flags = old_ka.sa_flags;
|
||||
(*old_act).sa_mask = old_ka.sa_mask;
|
||||
(*old_act).sa_restorer = old_ka.sa_restorer as *mut c_void;
|
||||
}
|
||||
}
|
||||
//return retval as u64;
|
||||
if retval.is_ok() {
|
||||
return 0;
|
||||
} else {
|
||||
return retval.unwrap_err().to_posix_errno() as u64;
|
||||
}
|
||||
}
|
||||
|
||||
fn do_sigaction(
|
||||
pub fn do_sigaction(
|
||||
sig: SignalNumber,
|
||||
act: Option<&mut sigaction>,
|
||||
old_act: Option<&mut sigaction>,
|
||||
@ -1029,8 +869,7 @@ pub fn sigmask(sig: SignalNumber) -> u64 {
|
||||
return 1u64 << ((sig as i32) - 1);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_rt_sigreturn(regs: &mut pt_regs) -> u64 {
|
||||
pub fn sys_rt_sigreturn(regs: &mut pt_regs) -> u64 {
|
||||
let frame = regs.rsp as usize as *mut sigframe;
|
||||
|
||||
// 如果当前的rsp不来自用户态,则认为产生了错误(或被SROP攻击)
|
||||
|
@ -1,38 +1,203 @@
|
||||
use core::{
|
||||
ffi::{c_int, c_void},
|
||||
sync::atomic::compiler_fence,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
arch::asm::current::current_pcb,
|
||||
filesystem::vfs::file::{File, FileMode},
|
||||
include::bindings::bindings::pt_regs,
|
||||
syscall::SystemError,
|
||||
include::bindings::bindings::{pid_t, verify_area, NULL},
|
||||
kwarn,
|
||||
syscall::{Syscall, SystemError},
|
||||
};
|
||||
|
||||
use super::pipe::LockedPipeInode;
|
||||
use super::{
|
||||
pipe::LockedPipeInode,
|
||||
signal::{signal_kill_something_info, DEFAULT_SIGACTION, DEFAULT_SIGACTION_IGNORE},
|
||||
signal_types::{
|
||||
SignalNumber, __siginfo_union, __siginfo_union_data, si_code_val, sigaction,
|
||||
sigaction__union_u, siginfo, sigset_init, sigset_t, user_sigaction, SA_FLAG_DFL,
|
||||
SA_FLAG_IGN, SA_FLAG_RESTORER, USER_SIG_DFL, USER_SIG_IGN,
|
||||
},
|
||||
};
|
||||
|
||||
#[no_mangle]
|
||||
/// @brief 调用匿名管道
|
||||
pub extern "C" fn sys_pipe(regs: &pt_regs) -> u64 {
|
||||
let fd: *mut i32 = regs.r8 as *mut i32;
|
||||
return do_pipe(fd)
|
||||
.map(|x| x as u64)
|
||||
.unwrap_or_else(|e| e.to_posix_errno() as u64);
|
||||
}
|
||||
|
||||
pub fn do_pipe(fd: *mut i32) -> Result<i64, SystemError> {
|
||||
let pipe_ptr = LockedPipeInode::new();
|
||||
let read_file = File::new(pipe_ptr.clone(), FileMode::O_RDONLY);
|
||||
let write_file = File::new(pipe_ptr.clone(), FileMode::O_WRONLY);
|
||||
|
||||
let read_fd = current_pcb().alloc_fd(read_file.unwrap(), None);
|
||||
if !read_fd.is_ok() {
|
||||
return Err(read_fd.unwrap_err());
|
||||
}
|
||||
|
||||
let write_fd = current_pcb().alloc_fd(write_file.unwrap(), None);
|
||||
if !write_fd.is_ok() {
|
||||
return Err(write_fd.unwrap_err());
|
||||
}
|
||||
unsafe {
|
||||
*fd.offset(0) = read_fd.unwrap();
|
||||
*fd.offset(1) = write_fd.unwrap();
|
||||
}
|
||||
return Ok(0);
|
||||
impl Syscall {
|
||||
/// # 创建匿名管道
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `fd`: 用于返回文件描述符的数组
|
||||
pub fn pipe(fd: &mut [i32]) -> Result<usize, SystemError> {
|
||||
let pipe_ptr = LockedPipeInode::new();
|
||||
let read_file = File::new(pipe_ptr.clone(), FileMode::O_RDONLY)?;
|
||||
let write_file = File::new(pipe_ptr.clone(), FileMode::O_WRONLY)?;
|
||||
|
||||
let read_fd = current_pcb().alloc_fd(read_file, None)?;
|
||||
let write_fd = current_pcb().alloc_fd(write_file, None)?;
|
||||
|
||||
fd[0] = read_fd;
|
||||
fd[1] = write_fd;
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
pub fn kill(pid: pid_t, sig: c_int) -> Result<usize, SystemError> {
|
||||
let sig = SignalNumber::from(sig);
|
||||
if sig == SignalNumber::INVALID {
|
||||
// 传入的signal数值不合法
|
||||
kwarn!("Not a valid signal number");
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
// 初始化signal info
|
||||
let mut info = siginfo {
|
||||
_sinfo: __siginfo_union {
|
||||
data: __siginfo_union_data {
|
||||
si_signo: sig as i32,
|
||||
si_code: si_code_val::SI_USER as i32,
|
||||
si_errno: 0,
|
||||
reserved: 0,
|
||||
_sifields: super::signal_types::__sifields {
|
||||
_kill: super::signal_types::__sifields__kill { _pid: pid },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
|
||||
let retval = signal_kill_something_info(sig, Some(&mut info), pid).map(|x| x as usize);
|
||||
|
||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/// @brief 用户程序用于设置信号处理动作的函数(遵循posix2008)
|
||||
///
|
||||
/// @param regs->r8 signumber 信号的编号
|
||||
/// @param regs->r9 act 新的,将要被设置的sigaction
|
||||
/// @param regs->r10 oact 返回给用户的原本的sigaction(内核将原本的sigaction的值拷贝给这个地址)
|
||||
///
|
||||
/// @return int 错误码
|
||||
#[no_mangle]
|
||||
pub fn sigaction(
|
||||
sig: c_int,
|
||||
act: usize,
|
||||
old_act: usize,
|
||||
_from_user: bool,
|
||||
) -> Result<usize, SystemError> {
|
||||
// 请注意:用户态传进来的user_sigaction结构体类型,请注意,这个结构体与内核实际的不一样
|
||||
let act = act as *mut user_sigaction;
|
||||
let mut old_act = old_act as *mut user_sigaction;
|
||||
let mut new_ka: sigaction = Default::default();
|
||||
let mut old_ka: sigaction = Default::default();
|
||||
|
||||
// 如果传入的,新的sigaction不为空
|
||||
if !act.is_null() {
|
||||
// 如果参数的范围不在用户空间,则返回错误
|
||||
if unsafe {
|
||||
!verify_area(
|
||||
act as usize as u64,
|
||||
core::mem::size_of::<sigaction>() as u64,
|
||||
)
|
||||
} {
|
||||
return Err(SystemError::EFAULT);
|
||||
}
|
||||
let mask: sigset_t = unsafe { (*act).sa_mask };
|
||||
let _input_sah = unsafe { (*act).sa_handler as u64 };
|
||||
// kdebug!("_input_sah={}", _input_sah);
|
||||
match _input_sah {
|
||||
USER_SIG_DFL | USER_SIG_IGN => {
|
||||
if _input_sah == USER_SIG_DFL {
|
||||
new_ka = DEFAULT_SIGACTION;
|
||||
new_ka.sa_flags = (unsafe { (*act).sa_flags }
|
||||
& (!(SA_FLAG_DFL | SA_FLAG_IGN)))
|
||||
| SA_FLAG_DFL;
|
||||
} else {
|
||||
new_ka = DEFAULT_SIGACTION_IGNORE;
|
||||
new_ka.sa_flags = (unsafe { (*act).sa_flags }
|
||||
& (!(SA_FLAG_DFL | SA_FLAG_IGN)))
|
||||
| SA_FLAG_IGN;
|
||||
}
|
||||
|
||||
let sar = unsafe { (*act).sa_restorer };
|
||||
new_ka.sa_restorer = sar as u64;
|
||||
}
|
||||
_ => {
|
||||
// 从用户空间获得sigaction结构体
|
||||
new_ka = sigaction {
|
||||
_u: sigaction__union_u {
|
||||
_sa_handler: unsafe { (*act).sa_handler as u64 },
|
||||
},
|
||||
sa_flags: unsafe { (*act).sa_flags },
|
||||
sa_mask: sigset_t::default(),
|
||||
sa_restorer: unsafe { (*act).sa_restorer as u64 },
|
||||
};
|
||||
}
|
||||
}
|
||||
// kdebug!("new_ka={:?}", new_ka);
|
||||
// 如果用户手动给了sa_restorer,那么就置位SA_FLAG_RESTORER,否则报错。(用户必须手动指定restorer)
|
||||
if new_ka.sa_restorer != NULL as u64 {
|
||||
new_ka.sa_flags |= SA_FLAG_RESTORER;
|
||||
} else {
|
||||
kwarn!(
|
||||
"pid:{}: in sys_sigaction: User must manually sprcify a sa_restorer for signal {}.",
|
||||
current_pcb().pid,
|
||||
sig
|
||||
);
|
||||
}
|
||||
sigset_init(&mut new_ka.sa_mask, mask);
|
||||
}
|
||||
|
||||
let sig = SignalNumber::from(sig as i32);
|
||||
// 如果给出的信号值不合法
|
||||
if sig == SignalNumber::INVALID {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
let retval = super::signal::do_sigaction(
|
||||
sig,
|
||||
if act.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(&mut new_ka)
|
||||
},
|
||||
if old_act.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(&mut old_ka)
|
||||
},
|
||||
);
|
||||
|
||||
// 将原本的sigaction拷贝到用户程序指定的地址
|
||||
if (retval == Ok(())) && (!old_act.is_null()) {
|
||||
if unsafe {
|
||||
!verify_area(
|
||||
old_act as usize as u64,
|
||||
core::mem::size_of::<sigaction>() as u64,
|
||||
)
|
||||
} {
|
||||
return Err(SystemError::EFAULT);
|
||||
}
|
||||
// !!!!!!!!!!todo: 检查这里old_ka的mask,是否位SIG_IGN SIG_DFL,如果是,则将_sa_handler字段替换为对应的值
|
||||
let sah: u64;
|
||||
let flag = old_ka.sa_flags & (SA_FLAG_DFL | SA_FLAG_IGN);
|
||||
match flag {
|
||||
SA_FLAG_DFL => {
|
||||
sah = USER_SIG_DFL;
|
||||
}
|
||||
SA_FLAG_IGN => {
|
||||
sah = USER_SIG_IGN;
|
||||
}
|
||||
_ => sah = unsafe { old_ka._u._sa_handler },
|
||||
}
|
||||
unsafe {
|
||||
(*old_act).sa_handler = sah as *mut c_void;
|
||||
(*old_act).sa_flags = old_ka.sa_flags;
|
||||
(*old_act).sa_mask = old_ka.sa_mask;
|
||||
(*old_act).sa_restorer = old_ka.sa_restorer as *mut c_void;
|
||||
}
|
||||
}
|
||||
return retval.map(|_| 0);
|
||||
}
|
||||
}
|
||||
|
@ -151,14 +151,15 @@ static uint64_t __count_kmalloc_total()
|
||||
uint64_t result = 0;
|
||||
for (int i = 0; i < sizeof(kmalloc_cache_group) / sizeof(struct slab); ++i)
|
||||
{
|
||||
result += kmalloc_cache_group[i].size * (kmalloc_cache_group[i].count_total_free + kmalloc_cache_group[i].count_total_using);
|
||||
result += kmalloc_cache_group[i].size *
|
||||
(kmalloc_cache_group[i].count_total_free + kmalloc_cache_group[i].count_total_using);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取系统当前的内存信息(未上锁,不一定精准)
|
||||
*
|
||||
*
|
||||
* @return struct mm_stat_t 内存信息结构体
|
||||
*/
|
||||
struct mm_stat_t mm_stat()
|
||||
@ -182,14 +183,14 @@ struct mm_stat_t mm_stat()
|
||||
* @param r8 返回的内存信息结构体的地址
|
||||
* @return uint64_t
|
||||
*/
|
||||
uint64_t sys_mstat(struct pt_regs *regs)
|
||||
uint64_t sys_do_mstat(struct mm_stat_t *dst, bool from_user)
|
||||
{
|
||||
if (regs->r8 == NULL)
|
||||
return -EINVAL;
|
||||
if (dst == NULL)
|
||||
return -EFAULT;
|
||||
struct mm_stat_t stat = mm_stat();
|
||||
if (regs->cs == (USER_CS | 0x3))
|
||||
copy_to_user((void *)regs->r8, &stat, sizeof(struct mm_stat_t));
|
||||
if (from_user)
|
||||
copy_to_user((void *)dst, &stat, sizeof(struct mm_stat_t));
|
||||
else
|
||||
memcpy((void *)regs->r8, &stat, sizeof(struct mm_stat_t));
|
||||
memcpy((void *)dst, &stat, sizeof(struct mm_stat_t));
|
||||
return 0;
|
||||
}
|
@ -3,6 +3,7 @@ use crate::include::bindings::bindings::{mm_struct, process_control_block, PAGE_
|
||||
pub mod allocator;
|
||||
pub mod gfp;
|
||||
pub mod mmio_buddy;
|
||||
pub mod syscall;
|
||||
|
||||
/// @brief 将内核空间的虚拟地址转换为物理地址
|
||||
#[inline(always)]
|
||||
|
43
kernel/src/mm/syscall.rs
Normal file
43
kernel/src/mm/syscall.rs
Normal file
@ -0,0 +1,43 @@
|
||||
use crate::{
|
||||
include::bindings::bindings::mm_stat_t,
|
||||
syscall::{Syscall, SystemError},
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
fn sys_do_brk(new_addr: usize) -> usize;
|
||||
fn sys_do_sbrk(incr: isize) -> usize;
|
||||
fn sys_do_mstat(dst: *mut mm_stat_t, from_user: bool) -> usize;
|
||||
}
|
||||
impl Syscall {
|
||||
pub fn brk(new_addr: usize) -> Result<usize, SystemError> {
|
||||
let ret = unsafe { sys_do_brk(new_addr) };
|
||||
if (ret as isize) < 0 {
|
||||
return Err(
|
||||
SystemError::from_posix_errno(-(ret as isize) as i32).expect("brk: Invalid errno")
|
||||
);
|
||||
}
|
||||
return Ok(ret);
|
||||
}
|
||||
|
||||
pub fn sbrk(incr: isize) -> Result<usize, SystemError> {
|
||||
let ret = unsafe { sys_do_sbrk(incr) };
|
||||
if (ret as isize) < 0 {
|
||||
return Err(
|
||||
SystemError::from_posix_errno(-(ret as isize) as i32).expect("sbrk: Invalid errno")
|
||||
);
|
||||
}
|
||||
return Ok(ret);
|
||||
}
|
||||
|
||||
/// 获取内存统计信息
|
||||
///
|
||||
/// TODO: 该函数不是符合POSIX标准的,在将来需要删除!
|
||||
pub fn mstat(dst: *mut mm_stat_t, from_user: bool) -> Result<usize, SystemError> {
|
||||
let ret = unsafe { sys_do_mstat(dst, from_user) };
|
||||
if (ret as isize) < 0 {
|
||||
return Err(SystemError::from_posix_errno(-(ret as isize) as i32)
|
||||
.expect("mstat: Invalid errno"));
|
||||
}
|
||||
return Ok(ret);
|
||||
}
|
||||
}
|
@ -10,9 +10,10 @@ use crate::{
|
||||
file::{File, FileMode},
|
||||
syscall::{IoVec, IoVecs},
|
||||
},
|
||||
include::bindings::bindings::{pt_regs, verify_area},
|
||||
include::bindings::bindings::verify_area,
|
||||
libs::spinlock::SpinLockGuard,
|
||||
net::socket::{AddressFamily, SOL_SOCKET},
|
||||
syscall::SystemError,
|
||||
syscall::{Syscall, SystemError},
|
||||
};
|
||||
|
||||
use super::{
|
||||
@ -20,596 +21,399 @@ use super::{
|
||||
Endpoint, Protocol, ShutdownType, Socket,
|
||||
};
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_socket(regs: &pt_regs) -> u64 {
|
||||
let address_family = regs.r8 as usize;
|
||||
let socket_type = regs.r9 as usize;
|
||||
let protocol: usize = regs.r10 as usize;
|
||||
// kdebug!("sys_socket: address_family: {address_family}, socket_type: {socket_type}, protocol: {protocol}");
|
||||
return do_socket(address_family, socket_type, protocol)
|
||||
.map(|x| x as u64)
|
||||
.unwrap_or_else(|e| e.to_posix_errno() as u64);
|
||||
}
|
||||
|
||||
/// @brief sys_socket系统调用的实际执行函数
|
||||
///
|
||||
/// @param address_family 地址族
|
||||
/// @param socket_type socket类型
|
||||
/// @param protocol 传输协议
|
||||
pub fn do_socket(
|
||||
address_family: usize,
|
||||
socket_type: usize,
|
||||
protocol: usize,
|
||||
) -> Result<i64, SystemError> {
|
||||
let address_family = AddressFamily::try_from(address_family as u16)?;
|
||||
let socket_type = PosixSocketType::try_from((socket_type & 0xf) as u8)?;
|
||||
// kdebug!("do_socket: address_family: {address_family:?}, socket_type: {socket_type:?}, protocol: {protocol}");
|
||||
// 根据地址族和socket类型创建socket
|
||||
let socket: Box<dyn Socket> = match address_family {
|
||||
AddressFamily::Unix | AddressFamily::INet => match socket_type {
|
||||
PosixSocketType::Stream => Box::new(TcpSocket::new(SocketOptions::default())),
|
||||
PosixSocketType::Datagram => Box::new(UdpSocket::new(SocketOptions::default())),
|
||||
PosixSocketType::Raw => Box::new(RawSocket::new(
|
||||
Protocol::from(protocol as u8),
|
||||
SocketOptions::default(),
|
||||
)),
|
||||
_ => {
|
||||
// kdebug!("do_socket: EINVAL");
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
// kdebug!("do_socket: EAFNOSUPPORT");
|
||||
return Err(SystemError::EAFNOSUPPORT);
|
||||
}
|
||||
};
|
||||
// kdebug!("do_socket: socket: {socket:?}");
|
||||
let socketinode: Arc<SocketInode> = SocketInode::new(socket);
|
||||
let f = File::new(socketinode, FileMode::O_RDWR)?;
|
||||
// kdebug!("do_socket: f: {f:?}");
|
||||
// 把socket添加到当前进程的文件描述符表中
|
||||
let fd = current_pcb().alloc_fd(f, None).map(|x| x as i64);
|
||||
// kdebug!("do_socket: fd: {fd:?}");
|
||||
return fd;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_setsockopt(regs: &pt_regs) -> u64 {
|
||||
let fd = regs.r8 as usize;
|
||||
let level = regs.r9 as usize;
|
||||
let optname = regs.r10 as usize;
|
||||
let optval = regs.r11 as usize;
|
||||
let optlen = regs.r12 as usize;
|
||||
return do_setsockopt(fd, level, optname, optval as *const u8, optlen)
|
||||
.map(|x| x as u64)
|
||||
.unwrap_or_else(|e| e.to_posix_errno() as u64);
|
||||
}
|
||||
|
||||
/// @brief sys_setsockopt系统调用的实际执行函数
|
||||
///
|
||||
/// @param fd 文件描述符
|
||||
/// @param level 选项级别
|
||||
/// @param optname 选项名称
|
||||
/// @param optval 选项值
|
||||
/// @param optlen optval缓冲区长度
|
||||
pub fn do_setsockopt(
|
||||
fd: usize,
|
||||
level: usize,
|
||||
optname: usize,
|
||||
optval: *const u8,
|
||||
optlen: usize,
|
||||
) -> Result<i64, SystemError> {
|
||||
// 验证optval的地址是否合法
|
||||
if unsafe { verify_area(optval as u64, optlen as u64) } == false {
|
||||
// 地址空间超出了用户空间的范围,不合法
|
||||
return Err(SystemError::EFAULT);
|
||||
}
|
||||
|
||||
let socket_inode: Arc<SocketInode> = current_pcb()
|
||||
.get_socket(fd as i32)
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
let data: &[u8] = unsafe { core::slice::from_raw_parts(optval, optlen) };
|
||||
// 获取内层的socket(真正的数据)
|
||||
let socket = socket_inode.inner();
|
||||
return socket.setsockopt(level, optname, data).map(|_| 0);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_getsockopt(regs: &pt_regs) -> u64 {
|
||||
let fd = regs.r8 as usize;
|
||||
let level = regs.r9 as usize;
|
||||
let optname = regs.r10 as usize;
|
||||
let optval = regs.r11 as usize;
|
||||
let optlen = regs.r12 as usize;
|
||||
return do_getsockopt(fd, level, optname, optval as *mut u8, optlen as *mut u32)
|
||||
.map(|x| x as u64)
|
||||
.unwrap_or_else(|e| e.to_posix_errno() as u64);
|
||||
}
|
||||
|
||||
/// @brief sys_getsockopt系统调用的实际执行函数
|
||||
///
|
||||
/// 参考:https://man7.org/linux/man-pages/man2/setsockopt.2.html
|
||||
///
|
||||
/// @param fd 文件描述符
|
||||
/// @param level 选项级别
|
||||
/// @param optname 选项名称
|
||||
/// @param optval 返回的选项值
|
||||
/// @param optlen 返回的optval缓冲区长度
|
||||
pub fn do_getsockopt(
|
||||
fd: usize,
|
||||
level: usize,
|
||||
optname: usize,
|
||||
optval: *mut u8,
|
||||
optlen: *mut u32,
|
||||
) -> Result<i64, SystemError> {
|
||||
// 验证optval的地址是否合法
|
||||
if unsafe { verify_area(optval as u64, core::mem::size_of::<u8>() 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);
|
||||
}
|
||||
|
||||
// 获取socket
|
||||
let optval = optval as *mut u32;
|
||||
let binding: Arc<SocketInode> = current_pcb()
|
||||
.get_socket(fd as i32)
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
let socket = binding.inner();
|
||||
|
||||
if level as u8 == SOL_SOCKET {
|
||||
let optname =
|
||||
PosixSocketOption::try_from(optname as i32).map_err(|_| SystemError::ENOPROTOOPT)?;
|
||||
match optname {
|
||||
PosixSocketOption::SO_SNDBUF => {
|
||||
// 返回发送缓冲区大小
|
||||
unsafe {
|
||||
*optval = socket.metadata()?.send_buf_size as u32;
|
||||
*optlen = core::mem::size_of::<u32>() as u32;
|
||||
impl Syscall {
|
||||
/// @brief sys_socket系统调用的实际执行函数
|
||||
///
|
||||
/// @param address_family 地址族
|
||||
/// @param socket_type socket类型
|
||||
/// @param protocol 传输协议
|
||||
pub fn socket(
|
||||
address_family: usize,
|
||||
socket_type: usize,
|
||||
protocol: usize,
|
||||
) -> Result<usize, SystemError> {
|
||||
let address_family = AddressFamily::try_from(address_family as u16)?;
|
||||
let socket_type = PosixSocketType::try_from((socket_type & 0xf) as u8)?;
|
||||
// kdebug!("do_socket: address_family: {address_family:?}, socket_type: {socket_type:?}, protocol: {protocol}");
|
||||
// 根据地址族和socket类型创建socket
|
||||
let socket: Box<dyn Socket> = match address_family {
|
||||
AddressFamily::Unix | AddressFamily::INet => match socket_type {
|
||||
PosixSocketType::Stream => Box::new(TcpSocket::new(SocketOptions::default())),
|
||||
PosixSocketType::Datagram => Box::new(UdpSocket::new(SocketOptions::default())),
|
||||
PosixSocketType::Raw => Box::new(RawSocket::new(
|
||||
Protocol::from(protocol as u8),
|
||||
SocketOptions::default(),
|
||||
)),
|
||||
_ => {
|
||||
// kdebug!("do_socket: EINVAL");
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
return Ok(0);
|
||||
},
|
||||
_ => {
|
||||
// kdebug!("do_socket: EAFNOSUPPORT");
|
||||
return Err(SystemError::EAFNOSUPPORT);
|
||||
}
|
||||
PosixSocketOption::SO_RCVBUF => {
|
||||
let optval = optval as *mut u32;
|
||||
// 返回默认的接收缓冲区大小
|
||||
unsafe {
|
||||
*optval = socket.metadata()?.recv_buf_size as u32;
|
||||
*optlen = core::mem::size_of::<u32>() as u32;
|
||||
};
|
||||
// kdebug!("do_socket: socket: {socket:?}");
|
||||
let socketinode: Arc<SocketInode> = SocketInode::new(socket);
|
||||
let f = File::new(socketinode, FileMode::O_RDWR)?;
|
||||
// kdebug!("do_socket: f: {f:?}");
|
||||
// 把socket添加到当前进程的文件描述符表中
|
||||
let fd = current_pcb().alloc_fd(f, None).map(|x| x as usize);
|
||||
// kdebug!("do_socket: fd: {fd:?}");
|
||||
return fd;
|
||||
}
|
||||
|
||||
/// @brief sys_setsockopt系统调用的实际执行函数
|
||||
///
|
||||
/// @param fd 文件描述符
|
||||
/// @param level 选项级别
|
||||
/// @param optname 选项名称
|
||||
/// @param optval 选项值
|
||||
/// @param optlen optval缓冲区长度
|
||||
pub fn setsockopt(
|
||||
fd: usize,
|
||||
level: usize,
|
||||
optname: usize,
|
||||
optval: &[u8],
|
||||
) -> Result<usize, SystemError> {
|
||||
let socket_inode: Arc<SocketInode> = current_pcb()
|
||||
.get_socket(fd as i32)
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
// 获取内层的socket(真正的数据)
|
||||
let socket: SpinLockGuard<Box<dyn Socket>> = socket_inode.inner();
|
||||
return socket.setsockopt(level, optname, optval).map(|_| 0);
|
||||
}
|
||||
|
||||
/// @brief sys_getsockopt系统调用的实际执行函数
|
||||
///
|
||||
/// 参考:https://man7.org/linux/man-pages/man2/setsockopt.2.html
|
||||
///
|
||||
/// @param fd 文件描述符
|
||||
/// @param level 选项级别
|
||||
/// @param optname 选项名称
|
||||
/// @param optval 返回的选项值
|
||||
/// @param optlen 返回的optval缓冲区长度
|
||||
pub fn getsockopt(
|
||||
fd: usize,
|
||||
level: usize,
|
||||
optname: usize,
|
||||
optval: *mut u8,
|
||||
optlen: *mut u32,
|
||||
) -> Result<usize, SystemError> {
|
||||
// 获取socket
|
||||
let optval = optval as *mut u32;
|
||||
let binding: Arc<SocketInode> = current_pcb()
|
||||
.get_socket(fd as i32)
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
let socket = binding.inner();
|
||||
|
||||
if level as u8 == SOL_SOCKET {
|
||||
let optname = PosixSocketOption::try_from(optname as i32)
|
||||
.map_err(|_| SystemError::ENOPROTOOPT)?;
|
||||
match optname {
|
||||
PosixSocketOption::SO_SNDBUF => {
|
||||
// 返回发送缓冲区大小
|
||||
unsafe {
|
||||
*optval = socket.metadata()?.send_buf_size as u32;
|
||||
*optlen = core::mem::size_of::<u32>() as u32;
|
||||
}
|
||||
return Ok(0);
|
||||
}
|
||||
PosixSocketOption::SO_RCVBUF => {
|
||||
let optval = optval as *mut u32;
|
||||
// 返回默认的接收缓冲区大小
|
||||
unsafe {
|
||||
*optval = socket.metadata()?.recv_buf_size as u32;
|
||||
*optlen = core::mem::size_of::<u32>() as u32;
|
||||
}
|
||||
return Ok(0);
|
||||
}
|
||||
_ => {
|
||||
return Err(SystemError::ENOPROTOOPT);
|
||||
}
|
||||
return Ok(0);
|
||||
}
|
||||
_ => {
|
||||
return Err(SystemError::ENOPROTOOPT);
|
||||
}
|
||||
}
|
||||
}
|
||||
drop(socket);
|
||||
drop(socket);
|
||||
|
||||
// To manipulate options at any other level the
|
||||
// protocol number of the appropriate protocol controlling the
|
||||
// option is supplied. For example, to indicate that an option is
|
||||
// to be interpreted by the TCP protocol, level should be set to the
|
||||
// protocol number of TCP.
|
||||
// To manipulate options at any other level the
|
||||
// protocol number of the appropriate protocol controlling the
|
||||
// option is supplied. For example, to indicate that an option is
|
||||
// to be interpreted by the TCP protocol, level should be set to the
|
||||
// protocol number of TCP.
|
||||
|
||||
let posix_protocol =
|
||||
PosixIpProtocol::try_from(level as u16).map_err(|_| SystemError::ENOPROTOOPT)?;
|
||||
if posix_protocol == PosixIpProtocol::TCP {
|
||||
let optname = PosixTcpSocketOptions::try_from(optname as i32)
|
||||
.map_err(|_| SystemError::ENOPROTOOPT)?;
|
||||
match optname {
|
||||
PosixTcpSocketOptions::Congestion => return Ok(0),
|
||||
_ => {
|
||||
return Err(SystemError::ENOPROTOOPT);
|
||||
let posix_protocol =
|
||||
PosixIpProtocol::try_from(level as u16).map_err(|_| SystemError::ENOPROTOOPT)?;
|
||||
if posix_protocol == PosixIpProtocol::TCP {
|
||||
let optname = PosixTcpSocketOptions::try_from(optname as i32)
|
||||
.map_err(|_| SystemError::ENOPROTOOPT)?;
|
||||
match optname {
|
||||
PosixTcpSocketOptions::Congestion => return Ok(0),
|
||||
_ => {
|
||||
return Err(SystemError::ENOPROTOOPT);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Err(SystemError::ENOPROTOOPT);
|
||||
}
|
||||
return Err(SystemError::ENOPROTOOPT);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_connect(regs: &pt_regs) -> u64 {
|
||||
let fd = regs.r8 as usize;
|
||||
let addr = regs.r9 as usize;
|
||||
let addrlen = regs.r10 as usize;
|
||||
return do_connect(fd, addr as *const SockAddr, addrlen)
|
||||
.map(|x| x as u64)
|
||||
.unwrap_or_else(|e| e.to_posix_errno() as u64);
|
||||
}
|
||||
|
||||
/// @brief sys_connect系统调用的实际执行函数
|
||||
///
|
||||
/// @param fd 文件描述符
|
||||
/// @param addr SockAddr
|
||||
/// @param addrlen 地址长度
|
||||
///
|
||||
/// @return 成功返回0,失败返回错误码
|
||||
pub fn do_connect(fd: usize, addr: *const SockAddr, addrlen: usize) -> Result<i64, SystemError> {
|
||||
let endpoint: Endpoint = SockAddr::to_endpoint(addr, addrlen)?;
|
||||
let socket: Arc<SocketInode> = current_pcb()
|
||||
.get_socket(fd as i32)
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
let mut socket = socket.inner();
|
||||
// kdebug!("connect to {:?}...", endpoint);
|
||||
socket.connect(endpoint)?;
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_bind(regs: &pt_regs) -> u64 {
|
||||
let fd = regs.r8 as usize;
|
||||
let addr = regs.r9 as usize;
|
||||
let addrlen = regs.r10 as usize;
|
||||
return do_bind(fd, addr as *const SockAddr, addrlen)
|
||||
.map(|x| x as u64)
|
||||
.unwrap_or_else(|e| e.to_posix_errno() as u64);
|
||||
}
|
||||
|
||||
/// @brief sys_bind系统调用的实际执行函数
|
||||
///
|
||||
/// @param fd 文件描述符
|
||||
/// @param addr SockAddr
|
||||
/// @param addrlen 地址长度
|
||||
///
|
||||
/// @return 成功返回0,失败返回错误码
|
||||
pub fn do_bind(fd: usize, addr: *const SockAddr, addrlen: usize) -> Result<i64, SystemError> {
|
||||
let endpoint: Endpoint = SockAddr::to_endpoint(addr, addrlen)?;
|
||||
let socket: Arc<SocketInode> = current_pcb()
|
||||
.get_socket(fd as i32)
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
let mut socket = socket.inner();
|
||||
socket.bind(endpoint)?;
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_sendto(regs: &pt_regs) -> u64 {
|
||||
let fd = regs.r8 as usize;
|
||||
let buf = regs.r9 as usize;
|
||||
let len = regs.r10 as usize;
|
||||
let flags = regs.r11 as usize;
|
||||
let addr = regs.r12 as usize;
|
||||
let addrlen = regs.r13 as usize;
|
||||
return do_sendto(
|
||||
fd,
|
||||
buf as *const u8,
|
||||
len,
|
||||
flags,
|
||||
addr as *const SockAddr,
|
||||
addrlen,
|
||||
)
|
||||
.map(|x| x as u64)
|
||||
.unwrap_or_else(|e| e.to_posix_errno() as u64);
|
||||
}
|
||||
|
||||
/// @brief sys_sendto系统调用的实际执行函数
|
||||
///
|
||||
/// @param fd 文件描述符
|
||||
/// @param buf 发送缓冲区
|
||||
/// @param len 发送缓冲区长度
|
||||
/// @param flags 标志
|
||||
/// @param addr SockAddr
|
||||
/// @param addrlen 地址长度
|
||||
///
|
||||
/// @return 成功返回发送的字节数,失败返回错误码
|
||||
pub fn do_sendto(
|
||||
fd: usize,
|
||||
buf: *const u8,
|
||||
len: usize,
|
||||
_flags: usize,
|
||||
addr: *const SockAddr,
|
||||
addrlen: usize,
|
||||
) -> Result<i64, SystemError> {
|
||||
if unsafe { verify_area(buf as usize as u64, len as u64) } == false {
|
||||
return Err(SystemError::EFAULT);
|
||||
/// @brief sys_connect系统调用的实际执行函数
|
||||
///
|
||||
/// @param fd 文件描述符
|
||||
/// @param addr SockAddr
|
||||
/// @param addrlen 地址长度
|
||||
///
|
||||
/// @return 成功返回0,失败返回错误码
|
||||
pub fn connect(fd: usize, addr: *const SockAddr, addrlen: usize) -> Result<usize, SystemError> {
|
||||
let endpoint: Endpoint = SockAddr::to_endpoint(addr, addrlen)?;
|
||||
let socket: Arc<SocketInode> = current_pcb()
|
||||
.get_socket(fd as i32)
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
let mut socket = socket.inner();
|
||||
// kdebug!("connect to {:?}...", endpoint);
|
||||
socket.connect(endpoint)?;
|
||||
return Ok(0);
|
||||
}
|
||||
let buf = unsafe { core::slice::from_raw_parts(buf, len) };
|
||||
let endpoint = if addr.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(SockAddr::to_endpoint(addr, addrlen)?)
|
||||
};
|
||||
|
||||
let socket: Arc<SocketInode> = current_pcb()
|
||||
.get_socket(fd as i32)
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
let socket = socket.inner();
|
||||
return socket.write(buf, endpoint).map(|n| n as i64);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_recvfrom(regs: &pt_regs) -> u64 {
|
||||
let fd = regs.r8 as usize;
|
||||
let buf = regs.r9 as usize;
|
||||
let len = regs.r10 as usize;
|
||||
let flags = regs.r11 as usize;
|
||||
let addr = regs.r12 as usize;
|
||||
let addrlen = regs.r13 as usize;
|
||||
return do_recvfrom(
|
||||
fd,
|
||||
buf as *mut u8,
|
||||
len,
|
||||
flags,
|
||||
addr as *mut SockAddr,
|
||||
addrlen as *mut u32,
|
||||
)
|
||||
.map(|x| x as u64)
|
||||
.unwrap_or_else(|e| e.to_posix_errno() as u64);
|
||||
}
|
||||
|
||||
/// @brief sys_recvfrom系统调用的实际执行函数
|
||||
///
|
||||
/// @param fd 文件描述符
|
||||
/// @param buf 接收缓冲区
|
||||
/// @param len 接收缓冲区长度
|
||||
/// @param flags 标志
|
||||
/// @param addr SockAddr
|
||||
/// @param addrlen 地址长度
|
||||
///
|
||||
/// @return 成功返回接收的字节数,失败返回错误码
|
||||
pub fn do_recvfrom(
|
||||
fd: usize,
|
||||
buf: *mut u8,
|
||||
len: usize,
|
||||
_flags: usize,
|
||||
addr: *mut SockAddr,
|
||||
addrlen: *mut u32,
|
||||
) -> Result<i64, SystemError> {
|
||||
if unsafe { verify_area(buf as usize as u64, len as u64) } == false {
|
||||
return Err(SystemError::EFAULT);
|
||||
/// @brief sys_bind系统调用的实际执行函数
|
||||
///
|
||||
/// @param fd 文件描述符
|
||||
/// @param addr SockAddr
|
||||
/// @param addrlen 地址长度
|
||||
///
|
||||
/// @return 成功返回0,失败返回错误码
|
||||
pub fn bind(fd: usize, addr: *const SockAddr, addrlen: usize) -> Result<usize, SystemError> {
|
||||
let endpoint: Endpoint = SockAddr::to_endpoint(addr, addrlen)?;
|
||||
let socket: Arc<SocketInode> = current_pcb()
|
||||
.get_socket(fd as i32)
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
let mut socket = socket.inner();
|
||||
socket.bind(endpoint)?;
|
||||
return Ok(0);
|
||||
}
|
||||
// kdebug!(
|
||||
// "do_recvfrom: fd: {}, buf: {:x}, len: {}, addr: {:x}, addrlen: {:x}",
|
||||
// fd,
|
||||
// buf as usize,
|
||||
// len,
|
||||
// addr as usize,
|
||||
// addrlen as usize
|
||||
// );
|
||||
|
||||
let buf = unsafe { core::slice::from_raw_parts_mut(buf, len) };
|
||||
let socket: Arc<SocketInode> = current_pcb()
|
||||
.get_socket(fd as i32)
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
let socket = socket.inner();
|
||||
/// @brief sys_sendto系统调用的实际执行函数
|
||||
///
|
||||
/// @param fd 文件描述符
|
||||
/// @param buf 发送缓冲区
|
||||
/// @param flags 标志
|
||||
/// @param addr SockAddr
|
||||
/// @param addrlen 地址长度
|
||||
///
|
||||
/// @return 成功返回发送的字节数,失败返回错误码
|
||||
pub fn sendto(
|
||||
fd: usize,
|
||||
buf: &[u8],
|
||||
_flags: u32,
|
||||
addr: *const SockAddr,
|
||||
addrlen: usize,
|
||||
) -> Result<usize, SystemError> {
|
||||
let endpoint = if addr.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(SockAddr::to_endpoint(addr, addrlen)?)
|
||||
};
|
||||
|
||||
let (n, endpoint) = socket.read(buf);
|
||||
drop(socket);
|
||||
let socket: Arc<SocketInode> = current_pcb()
|
||||
.get_socket(fd as i32)
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
let socket = socket.inner();
|
||||
return socket.write(buf, endpoint);
|
||||
}
|
||||
|
||||
let n: usize = n?;
|
||||
/// @brief sys_recvfrom系统调用的实际执行函数
|
||||
///
|
||||
/// @param fd 文件描述符
|
||||
/// @param buf 接收缓冲区
|
||||
/// @param flags 标志
|
||||
/// @param addr SockAddr
|
||||
/// @param addrlen 地址长度
|
||||
///
|
||||
/// @return 成功返回接收的字节数,失败返回错误码
|
||||
pub fn recvfrom(
|
||||
fd: usize,
|
||||
buf: &mut [u8],
|
||||
_flags: u32,
|
||||
addr: *mut SockAddr,
|
||||
addrlen: *mut u32,
|
||||
) -> Result<usize, SystemError> {
|
||||
let socket: Arc<SocketInode> = current_pcb()
|
||||
.get_socket(fd as i32)
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
let socket = socket.inner();
|
||||
|
||||
let (n, endpoint) = socket.read(buf);
|
||||
drop(socket);
|
||||
|
||||
let n: usize = n?;
|
||||
|
||||
// 如果有地址信息,将地址信息写入用户空间
|
||||
if !addr.is_null() {
|
||||
let sockaddr_in = SockAddr::from(endpoint);
|
||||
unsafe {
|
||||
sockaddr_in.write_to_user(addr, addrlen)?;
|
||||
}
|
||||
}
|
||||
return Ok(n);
|
||||
}
|
||||
|
||||
/// @brief sys_recvmsg系统调用的实际执行函数
|
||||
///
|
||||
/// @param fd 文件描述符
|
||||
/// @param msg MsgHdr
|
||||
/// @param flags 标志,暂时未使用
|
||||
///
|
||||
/// @return 成功返回接收的字节数,失败返回错误码
|
||||
pub fn recvmsg(fd: usize, msg: &mut MsgHdr, _flags: u32) -> Result<usize, SystemError> {
|
||||
// 检查每个缓冲区地址是否合法,生成iovecs
|
||||
let mut iovs = unsafe { IoVecs::from_user(msg.msg_iov, msg.msg_iovlen, true)? };
|
||||
|
||||
let socket: Arc<SocketInode> = current_pcb()
|
||||
.get_socket(fd as i32)
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
let socket = socket.inner();
|
||||
|
||||
let mut buf = iovs.new_buf(true);
|
||||
// 从socket中读取数据
|
||||
let (n, endpoint) = socket.read(&mut buf);
|
||||
drop(socket);
|
||||
|
||||
let n: usize = n?;
|
||||
|
||||
// 将数据写入用户空间的iovecs
|
||||
iovs.scatter(&buf[..n]);
|
||||
|
||||
let sockaddr_in = SockAddr::from(endpoint);
|
||||
unsafe {
|
||||
sockaddr_in.write_to_user(msg.msg_name, &mut msg.msg_namelen)?;
|
||||
}
|
||||
return Ok(n);
|
||||
}
|
||||
|
||||
/// @brief sys_listen系统调用的实际执行函数
|
||||
///
|
||||
/// @param fd 文件描述符
|
||||
/// @param backlog 队列最大连接数
|
||||
///
|
||||
/// @return 成功返回0,失败返回错误码
|
||||
pub fn listen(fd: usize, backlog: usize) -> Result<usize, SystemError> {
|
||||
let socket: Arc<SocketInode> = current_pcb()
|
||||
.get_socket(fd as i32)
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
let mut socket = socket.inner();
|
||||
socket.listen(backlog)?;
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
/// @brief sys_shutdown系统调用的实际执行函数
|
||||
///
|
||||
/// @param fd 文件描述符
|
||||
/// @param how 关闭方式
|
||||
///
|
||||
/// @return 成功返回0,失败返回错误码
|
||||
pub fn shutdown(fd: usize, how: usize) -> Result<usize, SystemError> {
|
||||
let socket: Arc<SocketInode> = current_pcb()
|
||||
.get_socket(fd as i32)
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
let socket = socket.inner();
|
||||
socket.shutdown(ShutdownType::try_from(how as i32)?)?;
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
/// @brief sys_accept系统调用的实际执行函数
|
||||
///
|
||||
/// @param fd 文件描述符
|
||||
/// @param addr SockAddr
|
||||
/// @param addrlen 地址长度
|
||||
///
|
||||
/// @return 成功返回新的文件描述符,失败返回错误码
|
||||
pub fn accept(fd: usize, addr: *mut SockAddr, addrlen: *mut u32) -> Result<usize, SystemError> {
|
||||
let socket: Arc<SocketInode> = current_pcb()
|
||||
.get_socket(fd as i32)
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
// kdebug!("accept: socket={:?}", socket);
|
||||
let mut socket = socket.inner();
|
||||
// 从socket中接收连接
|
||||
let (new_socket, remote_endpoint) = socket.accept()?;
|
||||
drop(socket);
|
||||
|
||||
// kdebug!("accept: new_socket={:?}", new_socket);
|
||||
// Insert the new socket into the file descriptor vector
|
||||
let new_socket: Arc<SocketInode> = SocketInode::new(new_socket);
|
||||
let new_fd = current_pcb().alloc_fd(File::new(new_socket, FileMode::O_RDWR)?, None)?;
|
||||
// kdebug!("accept: new_fd={}", new_fd);
|
||||
if !addr.is_null() {
|
||||
// kdebug!("accept: write remote_endpoint to user");
|
||||
// 将对端地址写入用户空间
|
||||
let sockaddr_in = SockAddr::from(remote_endpoint);
|
||||
unsafe {
|
||||
sockaddr_in.write_to_user(addr, addrlen)?;
|
||||
}
|
||||
}
|
||||
return Ok(new_fd as usize);
|
||||
}
|
||||
|
||||
/// @brief sys_getsockname系统调用的实际执行函数
|
||||
///
|
||||
/// Returns the current address to which the socket
|
||||
/// sockfd is bound, in the buffer pointed to by addr.
|
||||
///
|
||||
/// @param fd 文件描述符
|
||||
/// @param addr SockAddr
|
||||
/// @param addrlen 地址长度
|
||||
///
|
||||
/// @return 成功返回0,失败返回错误码
|
||||
pub fn getsockname(
|
||||
fd: usize,
|
||||
addr: *mut SockAddr,
|
||||
addrlen: *mut u32,
|
||||
) -> Result<usize, SystemError> {
|
||||
if addr.is_null() {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
let socket: Arc<SocketInode> = current_pcb()
|
||||
.get_socket(fd as i32)
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
let socket = socket.inner();
|
||||
let endpoint: Endpoint = socket.endpoint().ok_or(SystemError::EINVAL)?;
|
||||
drop(socket);
|
||||
|
||||
// 如果有地址信息,将地址信息写入用户空间
|
||||
if !addr.is_null() {
|
||||
let sockaddr_in = SockAddr::from(endpoint);
|
||||
unsafe {
|
||||
sockaddr_in.write_to_user(addr, addrlen)?;
|
||||
}
|
||||
return Ok(0);
|
||||
}
|
||||
return Ok(n as i64);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_recvmsg(regs: &pt_regs) -> i64 {
|
||||
let fd = regs.r8 as usize;
|
||||
let msg = regs.r9 as usize;
|
||||
let flags = regs.r10 as usize;
|
||||
return do_recvmsg(fd, msg as *mut MsgHdr, flags)
|
||||
.map(|x| x as i64)
|
||||
.unwrap_or_else(|e| e.to_posix_errno() as i64);
|
||||
}
|
||||
/// @brief sys_getpeername系统调用的实际执行函数
|
||||
///
|
||||
/// @param fd 文件描述符
|
||||
/// @param addr SockAddr
|
||||
/// @param addrlen 地址长度
|
||||
///
|
||||
/// @return 成功返回0,失败返回错误码
|
||||
pub fn getpeername(
|
||||
fd: usize,
|
||||
addr: *mut SockAddr,
|
||||
addrlen: *mut u32,
|
||||
) -> Result<usize, SystemError> {
|
||||
if addr.is_null() {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
/// @brief sys_recvmsg系统调用的实际执行函数
|
||||
///
|
||||
/// @param fd 文件描述符
|
||||
/// @param msg MsgHdr
|
||||
/// @param flags 标志
|
||||
///
|
||||
/// @return 成功返回接收的字节数,失败返回错误码
|
||||
pub fn do_recvmsg(fd: usize, msg: *mut MsgHdr, _flags: usize) -> Result<i64, SystemError> {
|
||||
// 检查指针是否合法
|
||||
if unsafe { verify_area(msg as usize as u64, core::mem::size_of::<MsgHdr>() as u64) } == false {
|
||||
return Err(SystemError::EFAULT);
|
||||
}
|
||||
let msg: &mut MsgHdr = unsafe { msg.as_mut() }.ok_or(SystemError::EFAULT)?;
|
||||
// 检查每个缓冲区地址是否合法,生成iovecs
|
||||
let mut iovs = unsafe { IoVecs::from_user(msg.msg_iov, msg.msg_iovlen, true)? };
|
||||
let socket: Arc<SocketInode> = current_pcb()
|
||||
.get_socket(fd as i32)
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
let socket = socket.inner();
|
||||
let endpoint: Endpoint = socket.peer_endpoint().ok_or(SystemError::EINVAL)?;
|
||||
drop(socket);
|
||||
|
||||
let socket: Arc<SocketInode> = current_pcb()
|
||||
.get_socket(fd as i32)
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
let socket = socket.inner();
|
||||
|
||||
let mut buf = iovs.new_buf(true);
|
||||
// 从socket中读取数据
|
||||
let (n, endpoint) = socket.read(&mut buf);
|
||||
drop(socket);
|
||||
|
||||
let n: usize = n?;
|
||||
|
||||
// 将数据写入用户空间的iovecs
|
||||
iovs.scatter(&buf[..n]);
|
||||
|
||||
let sockaddr_in = SockAddr::from(endpoint);
|
||||
unsafe {
|
||||
sockaddr_in.write_to_user(msg.msg_name, &mut msg.msg_namelen)?;
|
||||
}
|
||||
return Ok(n as i64);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_listen(regs: &pt_regs) -> i64 {
|
||||
let fd = regs.r8 as usize;
|
||||
let backlog = regs.r9 as usize;
|
||||
return do_listen(fd, backlog)
|
||||
.map(|x| x as i64)
|
||||
.unwrap_or_else(|e| e.to_posix_errno() as i64);
|
||||
}
|
||||
|
||||
/// @brief sys_listen系统调用的实际执行函数
|
||||
///
|
||||
/// @param fd 文件描述符
|
||||
/// @param backlog 最大连接数
|
||||
///
|
||||
/// @return 成功返回0,失败返回错误码
|
||||
pub fn do_listen(fd: usize, backlog: usize) -> Result<i64, SystemError> {
|
||||
let socket: Arc<SocketInode> = current_pcb()
|
||||
.get_socket(fd as i32)
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
let mut socket = socket.inner();
|
||||
socket.listen(backlog)?;
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_shutdown(regs: &pt_regs) -> u64 {
|
||||
let fd = regs.r8 as usize;
|
||||
let how = regs.r9 as usize;
|
||||
return do_shutdown(fd, how)
|
||||
.map(|x| x as u64)
|
||||
.unwrap_or_else(|e| e.to_posix_errno() as u64);
|
||||
}
|
||||
|
||||
/// @brief sys_shutdown系统调用的实际执行函数
|
||||
///
|
||||
/// @param fd 文件描述符
|
||||
/// @param how 关闭方式
|
||||
///
|
||||
/// @return 成功返回0,失败返回错误码
|
||||
pub fn do_shutdown(fd: usize, how: usize) -> Result<i64, SystemError> {
|
||||
let socket: Arc<SocketInode> = current_pcb()
|
||||
.get_socket(fd as i32)
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
let socket = socket.inner();
|
||||
socket.shutdown(ShutdownType::try_from(how as i32)?)?;
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_accept(regs: &pt_regs) -> u64 {
|
||||
let fd = regs.r8 as usize;
|
||||
let addr = regs.r9 as usize;
|
||||
let addrlen = regs.r10 as usize;
|
||||
return do_accept(fd, addr as *mut SockAddr, addrlen as *mut u32)
|
||||
.map(|x| x as u64)
|
||||
.unwrap_or_else(|e| e.to_posix_errno() as u64);
|
||||
}
|
||||
|
||||
/// @brief sys_accept系统调用的实际执行函数
|
||||
///
|
||||
/// @param fd 文件描述符
|
||||
/// @param addr SockAddr
|
||||
/// @param addrlen 地址长度
|
||||
///
|
||||
/// @return 成功返回新的文件描述符,失败返回错误码
|
||||
pub fn do_accept(fd: usize, addr: *mut SockAddr, addrlen: *mut u32) -> Result<i64, SystemError> {
|
||||
let socket: Arc<SocketInode> = current_pcb()
|
||||
.get_socket(fd as i32)
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
// kdebug!("accept: socket={:?}", socket);
|
||||
let mut socket = socket.inner();
|
||||
// 从socket中接收连接
|
||||
let (new_socket, remote_endpoint) = socket.accept()?;
|
||||
drop(socket);
|
||||
|
||||
// kdebug!("accept: new_socket={:?}", new_socket);
|
||||
// Insert the new socket into the file descriptor vector
|
||||
let new_socket: Arc<SocketInode> = SocketInode::new(new_socket);
|
||||
let new_fd = current_pcb().alloc_fd(File::new(new_socket, FileMode::O_RDWR)?, None)?;
|
||||
// kdebug!("accept: new_fd={}", new_fd);
|
||||
if !addr.is_null() {
|
||||
// kdebug!("accept: write remote_endpoint to user");
|
||||
// 将对端地址写入用户空间
|
||||
let sockaddr_in = SockAddr::from(remote_endpoint);
|
||||
let sockaddr_in = SockAddr::from(endpoint);
|
||||
unsafe {
|
||||
sockaddr_in.write_to_user(addr, addrlen)?;
|
||||
}
|
||||
return Ok(0);
|
||||
}
|
||||
return Ok(new_fd as i64);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_getsockname(regs: &pt_regs) -> i64 {
|
||||
let fd = regs.r8 as usize;
|
||||
let addr = regs.r9 as usize;
|
||||
let addrlen = regs.r10 as usize;
|
||||
return do_getsockname(fd, addr as *mut SockAddr, addrlen as *mut u32)
|
||||
.map(|x| x as i64)
|
||||
.unwrap_or_else(|e| e.to_posix_errno() as i64);
|
||||
}
|
||||
|
||||
/// @brief sys_getsockname系统调用的实际执行函数
|
||||
///
|
||||
/// Returns the current address to which the socket
|
||||
/// sockfd is bound, in the buffer pointed to by addr.
|
||||
///
|
||||
/// @param fd 文件描述符
|
||||
/// @param addr SockAddr
|
||||
/// @param addrlen 地址长度
|
||||
///
|
||||
/// @return 成功返回0,失败返回错误码
|
||||
pub fn do_getsockname(
|
||||
fd: usize,
|
||||
addr: *mut SockAddr,
|
||||
addrlen: *mut u32,
|
||||
) -> Result<i64, SystemError> {
|
||||
if addr.is_null() {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
let socket: Arc<SocketInode> = current_pcb()
|
||||
.get_socket(fd as i32)
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
let socket = socket.inner();
|
||||
let endpoint: Endpoint = socket.endpoint().ok_or(SystemError::EINVAL)?;
|
||||
drop(socket);
|
||||
|
||||
let sockaddr_in = SockAddr::from(endpoint);
|
||||
unsafe {
|
||||
sockaddr_in.write_to_user(addr, addrlen)?;
|
||||
}
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_getpeername(regs: &pt_regs) -> u64 {
|
||||
let fd = regs.r8 as usize;
|
||||
let addr = regs.r9 as usize;
|
||||
let addrlen = regs.r10 as usize;
|
||||
return do_getpeername(fd, addr as *mut SockAddr, addrlen as *mut u32)
|
||||
.map(|x| x as u64)
|
||||
.unwrap_or_else(|e| e.to_posix_errno() as u64);
|
||||
}
|
||||
|
||||
/// @brief sys_getpeername系统调用的实际执行函数
|
||||
///
|
||||
/// @param fd 文件描述符
|
||||
/// @param addr SockAddr
|
||||
/// @param addrlen 地址长度
|
||||
///
|
||||
/// @return 成功返回0,失败返回错误码
|
||||
pub fn do_getpeername(
|
||||
fd: usize,
|
||||
addr: *mut SockAddr,
|
||||
addrlen: *mut u32,
|
||||
) -> Result<i64, SystemError> {
|
||||
if addr.is_null() {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
let socket: Arc<SocketInode> = current_pcb()
|
||||
.get_socket(fd as i32)
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
let socket = socket.inner();
|
||||
let endpoint: Endpoint = socket.peer_endpoint().ok_or(SystemError::EINVAL)?;
|
||||
drop(socket);
|
||||
|
||||
let sockaddr_in = SockAddr::from(endpoint);
|
||||
unsafe {
|
||||
sockaddr_in.write_to_user(addr, addrlen)?;
|
||||
}
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
// 参考资料: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html#tag_13_32
|
||||
|
@ -3,3 +3,4 @@ pub mod initial_proc;
|
||||
pub mod pid;
|
||||
pub mod preempt;
|
||||
pub mod process;
|
||||
pub mod syscall;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{arch::asm::current::current_pcb, include::bindings::bindings::pt_regs};
|
||||
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
@ -18,11 +18,3 @@ impl PartialEq for PidType {
|
||||
*self as u8 == *other as u8
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取当前进程的pid
|
||||
*/
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_getpid(_regs: &pt_regs) -> u64 {
|
||||
return current_pcb().pid as u64;
|
||||
}
|
||||
|
@ -51,13 +51,13 @@ extern int process_init_files();
|
||||
extern int rs_init_stdio();
|
||||
|
||||
// 设置初始进程的PCB
|
||||
#define INITIAL_PROC(proc) \
|
||||
{ \
|
||||
.state = PROC_UNINTERRUPTIBLE, .flags = PF_KTHREAD, .preempt_count = 0, .signal = 0, .cpu_id = 0, \
|
||||
.mm = &initial_mm, .thread = &initial_thread, .addr_limit = 0xffffffffffffffff, .pid = 0, .priority = 2, \
|
||||
.virtual_runtime = 0, .fds = {0}, .next_pcb = &proc, .prev_pcb = &proc, .parent_pcb = &proc, .exit_code = 0, \
|
||||
.wait_child_proc_exit = 0, .worker_private = NULL, .policy = SCHED_NORMAL, .sig_blocked = 0, \
|
||||
.signal = &INITIAL_SIGNALS, .sighand = &INITIAL_SIGHAND, \
|
||||
#define INITIAL_PROC(proc) \
|
||||
{ \
|
||||
.state = PROC_UNINTERRUPTIBLE, .flags = PF_KTHREAD, .preempt_count = 0, .signal = 0, .cpu_id = 0, \
|
||||
.mm = &initial_mm, .thread = &initial_thread, .addr_limit = 0xffffffffffffffff, .pid = 0, .priority = 2, \
|
||||
.virtual_runtime = 0, .fds = {0}, .next_pcb = &proc, .prev_pcb = &proc, .parent_pcb = &proc, .exit_code = 0, \
|
||||
.wait_child_proc_exit = 0, .worker_private = NULL, .policy = SCHED_NORMAL, .sig_blocked = 0, \
|
||||
.signal = &INITIAL_SIGNALS, .sighand = &INITIAL_SIGHAND, \
|
||||
}
|
||||
|
||||
struct thread_struct initial_thread = {
|
||||
@ -114,10 +114,8 @@ void __switch_to(struct process_control_block *prev, struct process_control_bloc
|
||||
// initial_tss[0].ist2, initial_tss[0].ist3, initial_tss[0].ist4, initial_tss[0].ist5,
|
||||
// initial_tss[0].ist6, initial_tss[0].ist7);
|
||||
|
||||
__asm__ __volatile__("movq %%fs, %0 \n\t"
|
||||
: "=a"(prev->thread->fs));
|
||||
__asm__ __volatile__("movq %%gs, %0 \n\t"
|
||||
: "=a"(prev->thread->gs));
|
||||
__asm__ __volatile__("movq %%fs, %0 \n\t" : "=a"(prev->thread->fs));
|
||||
__asm__ __volatile__("movq %%gs, %0 \n\t" : "=a"(prev->thread->gs));
|
||||
|
||||
__asm__ __volatile__("movq %0, %%fs \n\t" ::"a"(next->thread->fs));
|
||||
__asm__ __volatile__("movq %0, %%gs \n\t" ::"a"(next->thread->gs));
|
||||
@ -144,10 +142,7 @@ void process_switch_fsgs(uint64_t fs, uint64_t gs)
|
||||
*/
|
||||
int process_open_exec_file(char *path)
|
||||
{
|
||||
struct pt_regs tmp = {0};
|
||||
tmp.r8 = (uint64_t)path;
|
||||
tmp.r9 = O_RDONLY;
|
||||
int fd = sys_open(&tmp);
|
||||
int fd = enter_syscall_int(SYS_OPEN, (uint64_t)path, O_RDONLY, 0, 0, 0, 0, 0, 0);
|
||||
return fd;
|
||||
}
|
||||
|
||||
@ -172,22 +167,12 @@ static int process_load_elf_file(struct pt_regs *regs, char *path)
|
||||
void *buf = kzalloc(PAGE_4K_SIZE, 0);
|
||||
uint64_t pos = 0;
|
||||
|
||||
struct pt_regs tmp_use_fs = {0};
|
||||
tmp_use_fs.r8 = fd;
|
||||
tmp_use_fs.r9 = 0;
|
||||
tmp_use_fs.r10 = SEEK_SET;
|
||||
retval = sys_lseek(&tmp_use_fs);
|
||||
retval = enter_syscall_int(SYS_LSEEK, fd, 0, SEEK_SET, 0, 0, 0, 0, 0);
|
||||
|
||||
// 读取 Elf64_Ehdr
|
||||
tmp_use_fs.r8 = fd;
|
||||
tmp_use_fs.r9 = (uint64_t)buf;
|
||||
tmp_use_fs.r10 = sizeof(Elf64_Ehdr);
|
||||
retval = sys_read(&tmp_use_fs);
|
||||
retval = enter_syscall_int(SYS_READ, fd, (uint64_t)buf, sizeof(Elf64_Ehdr), 0, 0, 0, 0, 0);
|
||||
|
||||
tmp_use_fs.r8 = fd;
|
||||
tmp_use_fs.r9 = 0;
|
||||
tmp_use_fs.r10 = SEEK_CUR;
|
||||
pos = sys_lseek(&tmp_use_fs);
|
||||
pos = enter_syscall_int(SYS_LSEEK, fd, 0, SEEK_CUR, 0, 0, 0, 0, 0);
|
||||
|
||||
if (retval != sizeof(Elf64_Ehdr))
|
||||
{
|
||||
@ -235,21 +220,14 @@ static int process_load_elf_file(struct pt_regs *regs, char *path)
|
||||
|
||||
// 读取所有的phdr
|
||||
pos = ehdr.e_phoff;
|
||||
tmp_use_fs.r8 = fd;
|
||||
tmp_use_fs.r9 = pos;
|
||||
tmp_use_fs.r10 = SEEK_SET;
|
||||
pos = sys_lseek(&tmp_use_fs);
|
||||
|
||||
pos = enter_syscall_int(SYS_LSEEK, fd, pos, SEEK_SET, 0, 0, 0, 0, 0);
|
||||
|
||||
memset(buf, 0, PAGE_4K_SIZE);
|
||||
tmp_use_fs.r8 = fd;
|
||||
tmp_use_fs.r9 = (uint64_t)buf;
|
||||
tmp_use_fs.r10 = (uint64_t)ehdr.e_phentsize * (uint64_t)ehdr.e_phnum;
|
||||
sys_read(&tmp_use_fs);
|
||||
|
||||
tmp_use_fs.r8 = fd;
|
||||
tmp_use_fs.r9 = 0;
|
||||
tmp_use_fs.r10 = SEEK_CUR;
|
||||
pos = sys_lseek(&tmp_use_fs);
|
||||
enter_syscall_int(SYS_READ, fd, (uint64_t)buf, (uint64_t)ehdr.e_phentsize * (uint64_t)ehdr.e_phnum, 0, 0, 0, 0, 0);
|
||||
|
||||
pos = enter_syscall_int(SYS_LSEEK, fd, 0, SEEK_CUR, 0, 0, 0, 0, 0);
|
||||
|
||||
if ((long)retval < 0)
|
||||
{
|
||||
@ -328,10 +306,7 @@ static int process_load_elf_file(struct pt_regs *regs, char *path)
|
||||
}
|
||||
}
|
||||
|
||||
tmp_use_fs.r8 = fd;
|
||||
tmp_use_fs.r9 = pos;
|
||||
tmp_use_fs.r10 = SEEK_SET;
|
||||
pos = sys_lseek(&tmp_use_fs);
|
||||
pos = enter_syscall_int(SYS_LSEEK, fd, pos, SEEK_SET, 0, 0, 0, 0, 0);
|
||||
|
||||
int64_t val = 0;
|
||||
if (remain_file_size > 0)
|
||||
@ -342,17 +317,13 @@ static int process_load_elf_file(struct pt_regs *regs, char *path)
|
||||
while (to_trans > 0)
|
||||
{
|
||||
int64_t x = 0;
|
||||
tmp_use_fs.r8 = fd;
|
||||
tmp_use_fs.r9 = (uint64_t)buf3;
|
||||
tmp_use_fs.r10 = to_trans;
|
||||
x = sys_read(&tmp_use_fs);
|
||||
|
||||
x = enter_syscall_int(SYS_READ, fd, (uint64_t)buf3, to_trans, 0, 0, 0, 0, 0);
|
||||
memcpy(virt_base + beginning_offset + val, buf3, x);
|
||||
val += x;
|
||||
to_trans -= x;
|
||||
tmp_use_fs.r8 = fd;
|
||||
tmp_use_fs.r9 = 0;
|
||||
tmp_use_fs.r10 = SEEK_CUR;
|
||||
pos = sys_lseek(&tmp_use_fs);
|
||||
|
||||
pos = enter_syscall_int(SYS_LSEEK, fd, 0, SEEK_CUR, 0, 0, 0, 0, 0);
|
||||
}
|
||||
kfree(buf3);
|
||||
|
||||
@ -391,9 +362,7 @@ static int process_load_elf_file(struct pt_regs *regs, char *path)
|
||||
|
||||
load_elf_failed:;
|
||||
{
|
||||
struct pt_regs tmp = {0};
|
||||
tmp.r8 = fd;
|
||||
sys_close(&tmp);
|
||||
enter_syscall_int(SYS_CLOSE, fd, 0, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
if (buf != NULL)
|
||||
@ -460,6 +429,7 @@ ul do_execve(struct pt_regs *regs, char *path, char *argv[], char *envp[])
|
||||
|
||||
// 加载elf格式的可执行文件
|
||||
int tmp = process_load_elf_file(regs, path);
|
||||
|
||||
if (tmp < 0)
|
||||
goto exec_failed;
|
||||
|
||||
@ -623,7 +593,7 @@ ul initial_kernel_thread(ul arg)
|
||||
"m"(current_pcb->thread->rsp), "m"(current_pcb->thread->rip), "S"("/bin/shell.elf"), "c"(NULL),
|
||||
"d"(NULL)
|
||||
: "memory");
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
#pragma GCC pop_options
|
||||
|
64
kernel/src/process/syscall.rs
Normal file
64
kernel/src/process/syscall.rs
Normal file
@ -0,0 +1,64 @@
|
||||
use core::ffi::{c_int, c_void};
|
||||
|
||||
use crate::{
|
||||
arch::asm::current::current_pcb,
|
||||
include::bindings::bindings::{pid_t, process_do_exit},
|
||||
syscall::{Syscall, SystemError},
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
fn c_sys_wait4(pid: pid_t, wstatus: *mut c_int, options: c_int, rusage: *mut c_void) -> c_int;
|
||||
}
|
||||
|
||||
impl Syscall {
|
||||
#[allow(dead_code)]
|
||||
pub fn fork(&self) -> Result<usize, SystemError> {
|
||||
// 由于进程管理未完成重构,fork调用暂时在arch/x86_64/syscall.rs中调用,以后会移动到这里。
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn vfork(&self) -> Result<usize, SystemError> {
|
||||
// 由于进程管理未完成重构,vfork调用暂时在arch/x86_64/syscall.rs中调用,以后会移动到这里。
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn execve(
|
||||
_path: *const c_void,
|
||||
_argv: *const *const c_void,
|
||||
_envp: *const *const c_void,
|
||||
) -> Result<usize, SystemError> {
|
||||
// 由于进程管理未完成重构,execve调用暂时在arch/x86_64/syscall.rs中调用,以后会移动到这里。
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn wait4(
|
||||
pid: pid_t,
|
||||
wstatus: *mut c_int,
|
||||
options: c_int,
|
||||
rusage: *mut c_void,
|
||||
) -> Result<usize, SystemError> {
|
||||
let ret = unsafe { c_sys_wait4(pid, wstatus, options, rusage) };
|
||||
if (ret as isize) < 0 {
|
||||
return Err(SystemError::from_posix_errno(-(ret as isize) as i32)
|
||||
.expect("wait4: Invalid errno"));
|
||||
}
|
||||
return Ok(ret as usize);
|
||||
}
|
||||
|
||||
/// # 退出进程
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - status: 退出状态
|
||||
pub fn exit(status: usize) -> ! {
|
||||
unsafe { process_do_exit(status as u64) };
|
||||
loop {}
|
||||
}
|
||||
|
||||
/// # 获取进程ID
|
||||
pub fn getpid() -> Result<usize, SystemError> {
|
||||
return Ok(current_pcb().pid as usize);
|
||||
}
|
||||
}
|
@ -30,7 +30,7 @@ pub unsafe fn sched_cfs_init() {
|
||||
} else {
|
||||
kBUG!("Try to init CFS Scheduler twice.");
|
||||
panic!("Try to init CFS Scheduler twice.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief CFS队列(per-cpu的)
|
||||
|
@ -1,14 +1,10 @@
|
||||
use core::sync::atomic::compiler_fence;
|
||||
|
||||
use crate::{
|
||||
arch::asm::{current::current_pcb, ptrace::user_mode},
|
||||
arch::{
|
||||
context::switch_process,
|
||||
interrupt::{cli, sti},
|
||||
},
|
||||
arch::asm::current::current_pcb,
|
||||
include::bindings::bindings::smp_get_total_cpu,
|
||||
include::bindings::bindings::{
|
||||
process_control_block, pt_regs, MAX_CPU_NUM, PF_NEED_MIGRATE, PROC_RUNNING, SCHED_FIFO,
|
||||
process_control_block, MAX_CPU_NUM, PF_NEED_MIGRATE, PROC_RUNNING, SCHED_FIFO,
|
||||
SCHED_NORMAL, SCHED_RR,
|
||||
},
|
||||
process::process::process_cpu,
|
||||
@ -75,7 +71,7 @@ pub trait Scheduler {
|
||||
fn enqueue(&mut self, pcb: &'static mut process_control_block);
|
||||
}
|
||||
|
||||
fn __sched() -> Option<&'static mut process_control_block> {
|
||||
pub fn do_sched() -> Option<&'static mut process_control_block> {
|
||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
let cfs_scheduler: &mut SchedulerCFS = __get_cfs_scheduler();
|
||||
let rt_scheduler: &mut SchedulerRT = __get_rt_scheduler();
|
||||
@ -168,26 +164,6 @@ pub extern "C" fn sched_update_jiffies() {
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief 让系统立即运行调度器的系统调用
|
||||
/// 请注意,该系统调用不能由ring3的程序发起
|
||||
#[allow(dead_code)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sys_sched(regs: &'static mut pt_regs) -> u64 {
|
||||
cli();
|
||||
// 进行权限校验,拒绝用户态发起调度
|
||||
if user_mode(regs) {
|
||||
return SystemError::EPERM.to_posix_errno() as u64;
|
||||
}
|
||||
// 根据调度结果统一进行切换
|
||||
let pcb = __sched();
|
||||
|
||||
if pcb.is_some() {
|
||||
switch_process(current_pcb(), pcb.unwrap());
|
||||
}
|
||||
sti();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sched_set_cpu_idle(cpu_id: usize, pcb: *mut process_control_block) {
|
||||
|
@ -1,3 +1,4 @@
|
||||
pub mod cfs;
|
||||
pub mod core;
|
||||
pub mod rt;
|
||||
pub mod syscall;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use core::{ptr::null_mut, sync::atomic::compiler_fence};
|
||||
use core::sync::atomic::compiler_fence;
|
||||
|
||||
use alloc::{boxed::Box, collections::LinkedList, vec::Vec};
|
||||
|
||||
|
31
kernel/src/sched/syscall.rs
Normal file
31
kernel/src/sched/syscall.rs
Normal file
@ -0,0 +1,31 @@
|
||||
use crate::{
|
||||
arch::{
|
||||
asm::current::current_pcb,
|
||||
context::switch_process,
|
||||
interrupt::{cli, sti},
|
||||
},
|
||||
syscall::{Syscall, SystemError},
|
||||
};
|
||||
|
||||
use super::core::do_sched;
|
||||
|
||||
impl Syscall {
|
||||
/// @brief 让系统立即运行调度器的系统调用
|
||||
/// 请注意,该系统调用不能由ring3的程序发起
|
||||
#[inline(always)]
|
||||
pub fn sched(from_user: bool) -> Result<usize, SystemError> {
|
||||
cli();
|
||||
// 进行权限校验,拒绝用户态发起调度
|
||||
if from_user {
|
||||
return Err(SystemError::EPERM);
|
||||
}
|
||||
// 根据调度结果统一进行切换
|
||||
let pcb = do_sched();
|
||||
|
||||
if pcb.is_some() {
|
||||
switch_process(current_pcb(), pcb.unwrap());
|
||||
}
|
||||
sti();
|
||||
return Ok(0);
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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的系统调用
|
@ -3,6 +3,7 @@ use core::{fmt, ops};
|
||||
use self::timekeep::ktime_get_real_ns;
|
||||
|
||||
pub mod sleep;
|
||||
pub mod syscall;
|
||||
pub mod timekeep;
|
||||
pub mod timer;
|
||||
|
||||
@ -18,8 +19,9 @@ absolute and relative time.
|
||||
[Duration]: struct.Duration.html
|
||||
*/
|
||||
|
||||
/// 表示时间的结构体
|
||||
/// 表示时间的结构体,符合POSIX标准。
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
||||
#[repr(C)]
|
||||
pub struct TimeSpec {
|
||||
pub tv_sec: i64,
|
||||
pub tv_nsec: i64,
|
||||
|
@ -1,18 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/glib.h>
|
||||
#include <process/ptrace.h>
|
||||
#include <common/time.h>
|
||||
|
||||
|
||||
/**
|
||||
* @brief 休眠指定时间
|
||||
*
|
||||
* @param rqtp 指定休眠的时间
|
||||
* @param rmtp 返回的剩余休眠时间
|
||||
* @return int
|
||||
*/
|
||||
int rs_nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
|
||||
#include <process/ptrace.h>
|
||||
|
||||
/**
|
||||
* @brief 睡眠指定时间
|
||||
|
@ -1,14 +1,15 @@
|
||||
use core::{arch::x86_64::_rdtsc, hint::spin_loop, ptr::null_mut};
|
||||
use core::{arch::x86_64::_rdtsc, hint::spin_loop};
|
||||
|
||||
use alloc::{boxed::Box, sync::Arc};
|
||||
|
||||
use crate::{
|
||||
arch::{
|
||||
asm::current::current_pcb,
|
||||
interrupt::{cli, sti},
|
||||
sched::sched,
|
||||
CurrentIrqArch,
|
||||
},
|
||||
include::bindings::bindings::{timespec, useconds_t, Cpu_tsc_freq},
|
||||
exception::InterruptArch,
|
||||
include::bindings::bindings::{useconds_t, Cpu_tsc_freq},
|
||||
syscall::SystemError,
|
||||
};
|
||||
|
||||
@ -24,7 +25,7 @@ use super::{
|
||||
/// @return Ok(TimeSpec) 剩余休眠时间
|
||||
///
|
||||
/// @return Err(SystemError) 错误码
|
||||
pub fn nano_sleep(sleep_time: TimeSpec) -> Result<TimeSpec, SystemError> {
|
||||
pub fn nanosleep(sleep_time: TimeSpec) -> Result<TimeSpec, SystemError> {
|
||||
if sleep_time.tv_nsec < 0 || sleep_time.tv_nsec >= 1000000000 {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
@ -48,12 +49,13 @@ pub fn nano_sleep(sleep_time: TimeSpec) -> Result<TimeSpec, SystemError> {
|
||||
next_n_us_timer_jiffies((sleep_time.tv_nsec / 1000) as u64),
|
||||
);
|
||||
|
||||
cli();
|
||||
let irq_guard: crate::exception::IrqFlagsGuard =
|
||||
unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||
timer.activate();
|
||||
unsafe {
|
||||
current_pcb().mark_sleep_interruptible();
|
||||
}
|
||||
sti();
|
||||
drop(irq_guard);
|
||||
|
||||
sched();
|
||||
|
||||
@ -72,8 +74,8 @@ pub fn nano_sleep(sleep_time: TimeSpec) -> Result<TimeSpec, SystemError> {
|
||||
/// @return Ok(TimeSpec) 剩余休眠时间
|
||||
///
|
||||
/// @return Err(SystemError) 错误码
|
||||
pub fn us_sleep(sleep_time: TimeSpec) -> Result<TimeSpec, SystemError> {
|
||||
match nano_sleep(sleep_time) {
|
||||
pub fn usleep(sleep_time: TimeSpec) -> Result<TimeSpec, SystemError> {
|
||||
match nanosleep(sleep_time) {
|
||||
Ok(value) => return Ok(value),
|
||||
Err(err) => return Err(err),
|
||||
};
|
||||
@ -81,40 +83,6 @@ pub fn us_sleep(sleep_time: TimeSpec) -> Result<TimeSpec, SystemError> {
|
||||
|
||||
//===== 以下为提供给C的接口 =====
|
||||
|
||||
/// @brief 休眠指定时间(单位:纳秒)(提供给C的接口)
|
||||
///
|
||||
/// @param sleep_time 指定休眠的时间
|
||||
///
|
||||
/// @param rm_time 剩余休眠时间(传出参数)
|
||||
///
|
||||
/// @return Ok(i32) 0
|
||||
///
|
||||
/// @return Err(SystemError) 错误码
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rs_nanosleep(sleep_time: *const timespec, rm_time: *mut timespec) -> i32 {
|
||||
if sleep_time == null_mut() {
|
||||
return SystemError::EINVAL.to_posix_errno();
|
||||
}
|
||||
let slt_spec = TimeSpec {
|
||||
tv_sec: unsafe { *sleep_time }.tv_sec,
|
||||
tv_nsec: unsafe { *sleep_time }.tv_nsec,
|
||||
};
|
||||
|
||||
match nano_sleep(slt_spec) {
|
||||
Ok(value) => {
|
||||
if rm_time != null_mut() {
|
||||
unsafe { *rm_time }.tv_sec = value.tv_sec;
|
||||
unsafe { *rm_time }.tv_nsec = value.tv_nsec;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Err(err) => {
|
||||
return err.to_posix_errno();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief 休眠指定时间(单位:微秒)(提供给C的接口)
|
||||
///
|
||||
/// @param usec 微秒
|
||||
@ -128,7 +96,7 @@ pub extern "C" fn rs_usleep(usec: useconds_t) -> i32 {
|
||||
tv_sec: (usec / 1000000) as i64,
|
||||
tv_nsec: ((usec % 1000000) * 1000) as i64,
|
||||
};
|
||||
match us_sleep(sleep_time) {
|
||||
match usleep(sleep_time) {
|
||||
Ok(_) => {
|
||||
return 0;
|
||||
}
|
||||
|
47
kernel/src/time/syscall.rs
Normal file
47
kernel/src/time/syscall.rs
Normal file
@ -0,0 +1,47 @@
|
||||
use core::ptr::null_mut;
|
||||
|
||||
use crate::{
|
||||
syscall::{Syscall, SystemError},
|
||||
time::{sleep::nanosleep, TimeSpec},
|
||||
};
|
||||
|
||||
impl Syscall {
|
||||
/// @brief 休眠指定时间(单位:纳秒)(提供给C的接口)
|
||||
///
|
||||
/// @param sleep_time 指定休眠的时间
|
||||
///
|
||||
/// @param rm_time 剩余休眠时间(传出参数)
|
||||
///
|
||||
/// @return Ok(i32) 0
|
||||
///
|
||||
/// @return Err(SystemError) 错误码
|
||||
pub fn nanosleep(
|
||||
sleep_time: *const TimeSpec,
|
||||
rm_time: *mut TimeSpec,
|
||||
) -> Result<usize, SystemError> {
|
||||
if sleep_time == null_mut() {
|
||||
return Err(SystemError::EFAULT);
|
||||
}
|
||||
let slt_spec = TimeSpec {
|
||||
tv_sec: unsafe { *sleep_time }.tv_sec,
|
||||
tv_nsec: unsafe { *sleep_time }.tv_nsec,
|
||||
};
|
||||
|
||||
let r: Result<usize, SystemError> = nanosleep(slt_spec).map(|slt_spec| {
|
||||
if rm_time != null_mut() {
|
||||
unsafe { *rm_time }.tv_sec = slt_spec.tv_sec;
|
||||
unsafe { *rm_time }.tv_nsec = slt_spec.tv_nsec;
|
||||
}
|
||||
0
|
||||
});
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/// 获取cpu时间
|
||||
///
|
||||
/// todo: 该系统调用与Linux不一致,将来需要删除该系统调用!!! 删的时候记得改C版本的libc
|
||||
pub fn clock() -> Result<usize, SystemError> {
|
||||
return Ok(super::timer::clock() as usize);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user