pk/Linux 上的 RISC-V ecall 系统调用调用约定
RISC-V ecall syscall calling convention on pk/Linux
在 RISC-V 伪内核 (pk) 或 Linux 下运行的程序中系统调用的调用约定是什么?
查看 riscv-gnu-toolchain 生成的代码,规则似乎是:
- 传入系统调用号
a7
- 系统调用参数在
a0
到 a5
中传递
- 未使用的参数设置为
0
- return 值是 return 在
a0
中编辑的
是这个吗?
真的有必要将未使用的参数清零吗?
寄存器a6
呢?这可以用于另一个 sycall 参数吗?
调用 exit()
系统调用的示例:
li a0, 1 # argument that is used by the syscall
li a1, 0 # unused arguments
li a2, 0
li a3, 0
li a4, 0
li a5, 0
li a7, 93 # exit syscall number
是的,基本上就是这样。
不,没有必要将未使用的参数清零。使用 riscv-gnu-toolchain(使用 newlib C 库)时将未使用的参数归零只是 newlib sycall 调用代码的产物。为了简单起见,代码只有一个 scall
(old name for ecall
) wrapper with 6 syscall arguments. Thus, the exit()
implementation just calls that wrapper with some additional zeroes.
截至 2020 年,maximum number of syscall arguments in Linux is 6。伪内核也是如此。因此,a6
始终未使用。
Linux 和 pk 都在 a7
中提供系统调用编号。并且 pk 使用的系统调用编号遵循 Linux 标准。
syscall(2) Linux man-page also summarizes the calling conventions on different architectures, including RISC-V. It specifies a1
可能用于 return 第二个 return 值,但这与 glibc 和 newlib 中的代码不匹配。
在 RISC-V 伪内核 (pk) 或 Linux 下运行的程序中系统调用的调用约定是什么?
查看 riscv-gnu-toolchain 生成的代码,规则似乎是:
- 传入系统调用号
a7
- 系统调用参数在
a0
到a5
中传递
- 未使用的参数设置为
0
- return 值是 return 在
a0
中编辑的
是这个吗?
真的有必要将未使用的参数清零吗?
寄存器a6
呢?这可以用于另一个 sycall 参数吗?
调用 exit()
系统调用的示例:
li a0, 1 # argument that is used by the syscall
li a1, 0 # unused arguments
li a2, 0
li a3, 0
li a4, 0
li a5, 0
li a7, 93 # exit syscall number
是的,基本上就是这样。
不,没有必要将未使用的参数清零。使用 riscv-gnu-toolchain(使用 newlib C 库)时将未使用的参数归零只是 newlib sycall 调用代码的产物。为了简单起见,代码只有一个 scall
(old name for ecall
) wrapper with 6 syscall arguments. Thus, the exit()
implementation just calls that wrapper with some additional zeroes.
截至 2020 年,maximum number of syscall arguments in Linux is 6。伪内核也是如此。因此,a6
始终未使用。
Linux 和 pk 都在 a7
中提供系统调用编号。并且 pk 使用的系统调用编号遵循 Linux 标准。
syscall(2) Linux man-page also summarizes the calling conventions on different architectures, including RISC-V. It specifies a1
可能用于 return 第二个 return 值,但这与 glibc 和 newlib 中的代码不匹配。