系统调用号列表可以在 Linux 源码中进行查看:include/uapi/asm-generic/unistd.h。
#define __NR_write 64
#define __NR_exit 93
复制代码
系统调用函数声明源码位置:include/linux/syscalls.h
asmlinkage long sys_write(unsigned int fd, const char __user *buf, size_t count);
asmlinkage long sys_exit(int error_code);
复制代码
C 标准库
直接使用汇编调用 Syscall 比较繁琐也不安全,C 标准库提供了对 Syscall 的封装。
(图片源自 wikipedia)
下面用一段 C 代码例子看看如何使用 Syscall ,这种方式大家都比较熟悉。
#include <unistd.h>
int main() {
write(1, "Hello, world!\n", 14);
return 0;
}
复制代码
使用下面的命令进行测试即可输出结果。
$ cat testc.c
#include <unistd.h>
int main() {
write(1, "Hello, world!\n", 14);
return 0;
}
$ riscv64-linux-gnu-gcc -static testc.c -o testc
$ qemu-riscv64 testc
Hello, world!
复制代码
三、总结
本篇文章主要从 Syscall 使用者的角度,阐述了什么是 Syscall。然后以实际代码为例,展示了在 RISC-V 架构下应用程序如何使用汇编代码和 C 标准库两种方式调用 Syscall 。
系列文章预告:RISC-V Syscall 系列2:Syscall 过程分析
参考资料
System call
syscall(2) — Linux manual page
Linux kernel interfaces
RISC-V Assembly Programmer's Manual
RISC-V架构下利用QEMU进行GDB调试
Risc-V Assembly Language Hello World
System Interface & Headers Reference
Misunderstanding RISC-V ecalls and syscalls