[内核赛]系统调用实现
系统调用实现
系统调用的说明以及调用方式
系统调用方式遵循RISC-V ABI,即调用号存放在a7寄存器中,6个参数分别储存在a0-a5寄存器
中,返回值保存在a0中。
主要参考了Linux 5.10 syscalls,详细请参见:https://man7.org/linux/man-pages/man2/syscalls.2.html
如何添加一个系统调用
- 在user.h文件中添加系统调用封装后的函数声明
- 在usys.pl文件中添加一个entry
- 在syscall.h中添加对应的宏
- 在syscall.c中添加函数的声明,并更新系统调用表
- 根据功能,选择一个合适的内核模块,进行实现。
文件系统相关
#define SYS_getcwd 17(10.17)
功能:获取当前工作目录;
输入:
char *buf:一块缓存区,用于保存当前工作目录的字符串。当buf设为NULL,由系统来分配缓存区。
size:buf缓存区的大小。
返回值:成功执行,则返回当前工作目录的字符串的指针。失败,则返回NULL。
1 |
|
#define SYS_pipe2 59 (10.29)
功能:创建管道;
输入:
- fd[2]:用于保存2个文件描述符。其中,fd[0]为管道的读出端,fd[1]为管道的写入端。
返回值:成功执行,返回0。失败,返回-1。
1 |
|
#define SYS_dup 23 (10.29)
功能:复制文件描述符;
输入:
- fd:被复制的文件描述符。
返回值:成功执行,返回新的文件描述符。失败,返回-1。
1 |
|
#define SYS_dup3 24 (10.29)
功能:复制文件描述符,并指定了新的文件描述符;
输入:
- old:被复制的文件描述符。
- new:新的文件描述符。
返回值:成功执行,返回新的文件描述符。失败,返回-1。
1 |
|
#define SYS_chdir 49 (10.29)
功能:切换工作目录;
输入:
- path:需要切换到的目录。
返回值:成功执行,返回0。失败,返回-1。
1 |
|
#define SYS_openat 56 (10.29)
功能:打开或创建一个文件;
输入:
fd:文件所在目录的文件描述符。
filename:要打开或创建的文件名。如为绝对路径,则忽略fd。如为相对路径,且fd是AT_FDCWD,则filename是相对于当前工作目录来说的。如为相对路径,且fd是一个文件描述符,则filename是相对于fd所指向的目录来说的。
flags:必须包含如下访问模式的其中一种:O_RDONLY,O_WRONLY,O_RDWR。还可以包含文件创建标志和文件状态标志。
mode:文件的所有权描述。详见
man 7 inode
。
返回值:成功执行,返回新的文件描述符。失败,返回-1。
1 |
|
#define SYS_close 57 (10.29)
功能:关闭一个文件描述符;
输入:
- fd:要关闭的文件描述符。
返回值:成功执行,返回0。失败,返回-1。
1 |
|
#define SYS_getdents64 61 (12.11)
功能:获取目录的条目;
输入:
fd:所要读取目录的文件描述符。
buf:一个缓存区,用于保存所读取目录的信息。缓存区的结构如下:
1
2
3
4
5
6
7struct dirent {
uint64 d_ino; // 索引结点号
int64 d_off; // 到下一个dirent的偏移
unsigned short d_reclen; // 当前dirent的长度
unsigned char d_type; // 文件类型
char d_name[]; //文件名
};len:buf的大小。
返回值:成功执行,返回读取的字节数。当到目录结尾,则返回0。失败,则返回-1。
1 |
|
#define SYS_read 63 (10.29)
功能:从一个文件描述符中读取;
输入:
- fd:要读取文件的文件描述符。
- buf:一个缓存区,用于存放读取的内容。
- count:要读取的字节数。
返回值:成功执行,返回读取的字节数。如为0,表示文件结束。错误,则返回-1。
1 |
|
#define SYS_write 64 (10.29)
功能:从一个文件描述符中写入;
输入:
- fd:要写入文件的文件描述符。
- buf:一个缓存区,用于存放要写入的内容。
- count:要写入的字节数。
返回值:成功执行,返回写入的字节数。错误,则返回-1。
1 |
|
#define SYS_linkat 37 (12.13)
功能:创建文件的链接;
输入:
- olddirfd:原来的文件所在目录的文件描述符。
- oldpath:文件原来的名字。如果oldpath是相对路径,则它是相对于olddirfd目录而言的。如果oldpath是相对路径,且olddirfd的值为AT_FDCWD,则它是相对于当前路径而言的。如果oldpath是绝对路径,则olddirfd被忽略。
- newdirfd:新文件名所在的目录。
- newpath:文件的新名字。newpath的使用规则同oldpath。
- flags:在2.6.18内核之前,应置为0。其它的值详见
man 2 linkat
。
返回值:成功执行,返回0。失败,返回-1。
1 |
|
#define SYS_unlinkat 35 (12.13)
功能:移除指定文件的链接(可用于删除文件);
输入:
- dirfd:要删除的链接所在的目录。
- path:要删除的链接的名字。如果path是相对路径,则它是相对于dirfd目录而言的。如果path是相对路径,且dirfd的值为AT_FDCWD,则它是相对于当前路径而言的。如果path是绝对路径,则dirfd被忽略。
- flags:可设置为0或AT_REMOVEDIR。
返回值:成功执行,返回0。失败,返回-1。
1 |
|
#define SYS_mkdirat 34 (10.29)
功能:创建目录;
输入:
- dirfd:要创建的目录所在的目录的文件描述符。
- path:要创建的目录的名称。如果path是相对路径,则它是相对于dirfd目录而言的。如果path是相对路径,且dirfd的值为AT_FDCWD,则它是相对于当前路径而言的。如果path是绝对路径,则dirfd被忽略。
- mode:文件的所有权描述。详见
man 7 inode
。
返回值:成功执行,返回0。失败,返回-1。
1 |
|
#define SYS_umount2 39
- 功能:卸载文件系统;
- 输入:指定卸载目录,卸载参数;
- 返回值:成功返回0,失败返回-1;
1 |
|
#define SYS_mount 40
- 功能:挂载文件系统;
- 输入:
- special: 挂载设备;
- dir: 挂载点;
- fstype: 挂载的文件系统类型;
- flags: 挂载参数;
- data: 传递给文件系统的字符串参数,可为NULL;
- 返回值:成功返回0,失败返回-1;
1 |
|
#define SYS_fstat 80 (12.13)
- 功能:获取文件状态;
- 输入:
- fd: 文件句柄;
- kst: 接收保存文件状态的指针;
1 |
|
- 返回值:成功返回0,失败返回-1;
1 |
|
进程管理相关
#define SYS_clone 220 (10.26)
- 功能:创建一个子进程;
- 输入:
- flags: 创建的标志,如SIGCHLD;
- stack: 指定新进程的栈,可为0;
- ptid: 父线程ID;
- tls: TLS线程本地存储描述符;
- ctid: 子线程ID;
- 返回值:成功则返回子进程的线程ID,失败返回-1;
1 |
|
#define SYS_execve 221 (10.26)
- 功能:执行一个指定的程序;
- 输入:
- path: 待执行程序路径名称,
- argv: 程序的参数,
- envp: 环境变量的数组指针
- 返回值:成功不返回,失败返回-1;
1 |
|
#define SYS_wait4 260(10.26)
- 功能:等待进程改变状态;
- 输入:
- pid: 指定进程ID,可为-1等待任何子进程;
- status: 接收状态的指针;
- options: 选项:WNOHANG,WUNTRACED,WCONTINUED;
- 返回值:成功则返回进程ID;如果指定了WNOHANG,且进程还未改变状态,直接返回0;失败则返回-1;
1 |
|
#define SYS_exit 93 (10.26)
- 功能:触发进程终止,无返回值;
- 输入:终止状态值;
- 返回值:无返回值;
1 |
|
#define SYS_getppid 173 (10.25)
- 功能:获取父进程ID;
- 输入:系统调用ID;
- 返回值:成功返回父进程ID;
1 |
|
#define SYS_getpid 172 (10.25)
- 功能:获取进程ID;
- 输入:系统调用ID;
- 返回值:成功返回进程ID;
1 |
|
内存管理相关
#define SYS_brk 214 (10.26)
- 功能:修改数据段的大小;
- 输入:指定待修改的地址;
- 返回值:成功返回0,失败返回-1;
1 |
|
#define SYS_munmap 215 (12.13)
- 功能:将文件或设备取消映射到内存中;
- 输入:映射的指定地址及区间;
- 返回值:成功返回0,失败返回-1;
1 |
|
#define SYS_mmap 222 (12.13)
- 功能:将文件或设备映射到内存中;
- 输入:
- start: 映射起始位置,
- len: 长度,
- prot: 映射的内存保护方式,可取:PROT_EXEC, PROT_READ, PROT_WRITE, PROT_NONE
- flags: 映射是否与其他进程共享的标志,
- fd: 文件句柄,
- off: 文件偏移量;
- 返回值:成功返回已映射区域的指针,失败返回-1;
1 |
|
其他
#define SYS_times 153 (12.10)
- 功能:获取进程时间;
- 输入:tms结构体指针,用于获取保存当前进程的运行时间数据;
- 返回值:成功返回已经过去的滴答数,失败返回-1;
1 |
|
#define SYS_uname 160 (12.13)
- 功能:打印系统信息;
- 输入:utsname结构体指针用于获得系统信息数据;
- 返回值:成功返回0,失败返回-1;
1 |
|
#define SYS_sched_yield 124 (10.25)
- 功能:让出调度器;
- 输入:系统调用ID;
- 返回值:成功返回0,失败返回-1;
1 |
|
#define SYS_gettimeofday 169 (12.11)
- 功能:获取时间;
- 输入: timespec结构体指针用于获得时间值;
- 返回值:成功返回0,失败返回-1;
1 |
|
#define SYS_nanosleep 101 (12.11)
- 功能:执行线程睡眠,sleep()库函数基于此系统调用;
- 输入:睡眠的时间间隔;
1 |
|
- 返回值:成功返回0,失败返回-1;
1 |
|
调用
1 |
|