跳转到内容

系统调用参考

OpenOS 采用 Channel/Handle 模型。以下是已实现的系统调用。

来自 kernel/src/syscall/number.rs

// Channel (5)
pub const SYS_CHANNEL_CREATE: u64 = 0x01;
pub const SYS_CHANNEL_SEND: u64 = 0x02;
pub const SYS_CHANNEL_RECEIVE: u64 = 0x03;
pub const SYS_CHANNEL_CALL: u64 = 0x04;
pub const SYS_CHANNEL_REPLY: u64 = 0x05;
// Handle (3)
pub const SYS_HANDLE_CLOSE: u64 = 0x10;
pub const SYS_HANDLE_DUPLICATE: u64 = 0x11;
pub const SYS_HANDLE_TRANSFER: u64 = 0x12;
// Process (4) — 部分实现
pub const SYS_PROCESS_CREATE: u64 = 0x30;
pub const SYS_PROCESS_START: u64 = 0x31;
pub const SYS_PROCESS_EXIT: u64 = 0x32;
pub const SYS_PROCESS_WAIT: u64 = 0x33;
// Thread (3) — 部分实现
pub const SYS_THREAD_CREATE: u64 = 0x40;
pub const SYS_THREAD_EXIT: u64 = 0x41;
pub const SYS_THREAD_YIELD: u64 = 0x42;
// 调试(非标准)
pub const SYS_CONSOLE_WRITE: u64 = 0xF0;
RAX = 系统调用号
RDI = 参数 1
RSI = 参数 2
RDX = 参数 3
R10 = 参数 4
R8 = 参数 5
R9 = 参数 6
返回值:
RAX = 结果(正数)或错误码(负数)

错误码:

-1 = EINVAL(无效参数)
-2 = ENOENT(未找到)
-3 = EPERM(权限不足)
-4 = ENOMEM(内存不足)
-5 = EBUSY(资源忙)
-6 = EPIPE(Channel 已关闭)
-7 = EAGAIN(会阻塞)
-8 = ETIME(超时)
-9 = EFAULT(错误指针)
-10 = ENOSYS(未知系统调用)

创建一个新的 Channel,返回两端的 Handle。

fn channel_create(flags: u64) -> (handle_a: Handle, handle_b: Handle)

示例(来自 user/hello.asm):

; 内核创建 Channel,handle_a 通过 RDI 传递给用户程序
mov rbx, rdi ; 保存 handle_a

发送消息。同步会合——阻塞直到接收方调用 channel_receive。

fn channel_send(handle: u64, msg: *const u8, len: u64) -> i64

示例(来自 user/hello.asm):

; channel_send(handle_a, msg, len)
mov rdi, rbx ; arg0: handle
lea rsi, [rel msg] ; arg1: 消息指针
mov rdx, msg_len ; arg2: 消息长度
mov rax, 0x02 ; SYS_CHANNEL_SEND
syscall

返回值:

  • 0 — 消息已发送
  • 负数 — 错误

接收消息。阻塞直到有消息可用。

fn channel_receive(handle: u64, buf: *mut u8, len: u64) -> u64

示例(来自 user/console_svc.asm):

; channel_receive(handle, buf, 256)
mov rdi, rbx ; arg0: handle
lea rsi, [rel buf] ; arg1: 缓冲区
mov rdx, 256 ; arg2: 最大长度
mov rax, 0x03 ; SYS_CHANNEL_RECEIVE
syscall
; RAX = 接收的字节数

返回值:

  • 正数 — 接收的字节数
  • 负数 — 错误

原子性的发送 + 阻塞等待回复(RPC 原语)。

fn channel_call(handle: u64, msg: *const u8, len: u64) -> u64

回复接收到的消息。解除调用方 channel_call 的阻塞。

fn channel_reply(handle: u64, msg: *const u8, len: u64) -> i64

示例(来自 user/console_svc.asm):

; channel_reply(handle, "OK", 2)
mov rdi, rbx ; arg0: handle
lea rsi, [rel ok_msg] ; arg1: 回复消息
mov rdx, 2 ; arg2: 长度
mov rax, 0x05 ; SYS_CHANNEL_REPLY
syscall

关闭 Handle。

fn handle_close(handle: u64) -> i64

克隆 Handle,可选择收窄权限。

fn handle_duplicate(handle: u64, new_rights: u64) -> u64

通过 Channel 将 Handle 发送给另一个进程。

fn handle_transfer(handle: u64, target_channel: u64, rights: u64) -> i64

终止当前进程。

fn process_exit(status: u64) -> !

示例(来自 user/hello.asm):

; process_exit(0)
mov rdi, 0 ; 退出状态
mov rax, 0x32 ; SYS_PROCESS_EXIT
syscall

让出 CPU。

fn thread_yield() -> i64

调试输出到串口。这不是标准系统调用,仅用于调试。

fn console_write(buf: *const u8, len: u64) -> u64

示例(来自 user/console_svc.asm):

; console_write(buf, len)
lea rdi, [rel buf]
mov rsi, rcx
mov rax, 0xF0 ; SYS_CONSOLE_WRITE
syscall

; user/hello.asm
; 内核创建 Channel,handle_a 通过 RDI 传递
BITS 64
SECTION .text
global _start
_start:
mov rbx, rdi ; 保存 handle_a
; channel_send(handle_a, msg, len)
mov rdi, rbx
lea rsi, [rel msg]
mov rdx, msg_len
mov rax, 0x02 ; SYS_CHANNEL_SEND
syscall
; process_exit(0)
mov rdi, 0
mov rax, 0x32 ; SYS_PROCESS_EXIT
syscall
SECTION .rodata
msg: db "Hello from initrd!", 10
msg_len equ $ - msg
; user/console_svc.asm
; 接收消息,打印到串口,回复 "OK",退出
BITS 64
SECTION .text
global _start
_start:
mov rbx, rdi ; 保存 handle (end B)
; channel_receive(handle, buf, 256)
mov rdi, rbx
lea rsi, [rel buf]
mov rdx, 256
mov rax, 0x03 ; SYS_CHANNEL_RECEIVE
syscall
; console_write(buf, len)
mov rcx, rax ; 保存消息长度
lea rdi, [rel buf]
mov rsi, rcx
mov rax, 0xF0 ; SYS_CONSOLE_WRITE
syscall
; channel_reply(handle, "OK", 2)
mov rdi, rbx
lea rsi, [rel ok_msg]
mov rdx, 2
mov rax, 0x05 ; SYS_CHANNEL_REPLY
syscall
; process_exit(0)
mov rdi, 0
mov rax, 0x32 ; SYS_PROCESS_EXIT
syscall
SECTION .bss
buf: resb 256
SECTION .rodata
ok_msg: db "OK"

系统调用状态说明
channel_create已完成创建 Channel
channel_send已完成发送消息
channel_receive已完成接收消息
channel_call已完成原子 RPC
channel_reply已完成回复消息
handle_close已完成关闭 Handle
handle_duplicate已完成克隆 Handle
handle_transfer已完成传递 Handle
process_exit已完成终止进程
thread_yield已完成让出 CPU
console_write已完成调试输出
process_create未实现编号已分配
process_start未实现编号已分配
thread_create未实现编号已分配