syscalls

syscall 通过寄存器里放的数值,判断该调用哪个内核函数.不同主流架构都有自己的 syscall 方式,例如

在 Rust 中,我们可以用 unsafe { core::arch::asm!() } 手动调用汇编 syscall.

Arch Instruction Syscall ID Reg Return Reg Argument Registers
x86_64 syscall rax rax rdi, rsi, rdx, r10, r8, r9
aarch64 svc #0 x8 x0 x0, x1, x2, x3, x4, x5
riscv64 ecall a7 a0 a0, a1, a2, a3, a4, a5
x86_64 调用示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
pub unsafe fn syscall3(
id: usize,
arg0: usize,
arg1: usize,
arg2: usize
) -> isize {
let ret: isize;
unsafe {
core::arch::asm!(
"syscall",
inlateout("rax") id as isize => ret,
in("rdi") arg0,
in("rsi") arg1,
in("rdx") arg2,
// 由于 x86 会使用 rcx, r11 寄存器,所以需要用 out() 标记
out("rcx") _,
out("r11") _,
);
}
ret
}
ARM64 调用示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
pub unsafe fn syscall3(
id: usize,
arg0: usize,
arg1: usize,
arg2: usize
) -> isize {
let ret: isize;
unsafe {
core::arch::asm!(
"svc #0",
in("x8") id,
inlateout("x0") arg0 as isize => ret,
in("x1") arg1,
in("x2") arg2,
);
}
ret
}

迷你堆分配器

Handle Table