Novus OS Debug 级接口手册 V1.0

Novus OS Debug 级接口手册

文档版本:V1.0(对应 Novus OS V1.6-FinalSpec) 用途:开发调试手册,每个接口展开到参数级、错误码级、前置/后置条件、调试检查点 配套:《全部接口总表》《NUC 格式规范》《NKM 格式规范》 状态:冻结


0. 阅读指南

每个接口条目包含:

  1. 原型:C 函数签名
  2. 所属子系统
  3. 调用方 / 被调用方
  4. 前置条件:调用前必须满足什么(锁、CAP、中断状态、内存)
  5. 参数表:逐字段类型、取值范围、单位、默认值、说明
  6. 返回值:逐情况说明
  7. 错误码对照表:什么情况返回什么错误码
  8. 后置条件:返回后系统状态变化
  9. 调试检查点:开发时应该打日志/断言的位置
  10. 使用示例:最小调用代码
  11. 常见 Bug:易犯错误

1. 通用错误码(全局复用)

值 宏名 含义 触发场景举例
0 NOVUS_OK 成功 一切正常
-1 NOVUS_EINVAL 参数无效 指针为NULL、长度为0、枚举值越界
-2 NOVUS_ENOMEM 内存不足 页分配失败、缓冲区不够
-3 NOVUS_ENOTFOUND 对象不存在 路径不存在、符号未找到、设备不存在
-4 NOVUS_EPERM 权限不足 cap_check() 返回 false
-5 NOVUS_EBUSY 资源忙 锁超时、文件被占用、模块被依赖
-6 NOVUS_EIO IO错误 磁盘读失败、PCI读写错误
-7 NOVUS_ECORRUPT 数据损坏 SHA256不匹配、CRC32校验失败
-8 NOVUS_EMODULE 模块错误 签名校验失败、ABI不兼容
-9 NOVUS_EFULL 队列满 IPC队列满、WAL日志满
-10 NOVUS_EAGAIN 重试 资源暂时不可用
-11 NOVUS_EOVERFLOW 溢出 段大小越界、文件偏移超出文件长度
-12 NOVUS_EDEP 循环依赖 模块依赖图成环

2. SMP / AB 双核接口

2.1 smp_shmem_write

void smp_shmem_write(uint32_t offset, uint64_t val);
参数 类型 范围 说明
offset uint32_t 0 ~ 4095 共享内存内偏移,必须 8 字节对齐
val uint64_t 任意 要写入的值

2.2 smp_shmem_read

uint64_t smp_shmem_read(uint32_t offset);

2.3 smp_shmem_lock / smp_shmem_unlock

int smp_shmem_lock(void);
void smp_shmem_unlock(void);

2.4 acore_enter_sleep

void acore_enter_sleep(void);

2.5 smp_wake_ap

int smp_wake_ap(uint64_t ap_id);

2.6 smp_ap_signal_ready

void smp_ap_signal_ready(void);

3. 内存管理接口

3.1 mm_alloc

void* mm_alloc(size_t pages);
参数 类型 单位 说明
pages size_t 4KiB/页 要分配的连续物理页数

3.2 mm_free

void mm_free(void* vaddr, size_t pages);

3.3 vm_map

int vm_map(uint64_t va, uint64_t pa, uint64_t len, uint32_t flags);
参数 类型 单位 说明
va uint64_t 字节 虚拟起始地址,4KiB 对齐
pa uint64_t 字节 物理起始地址,4KiB 对齐
len uint64_t 字节 长度,4KiB 对齐
flags uint32_t 位掩码 bit0=READ bit1=WRITE bit2=EXEC bit3=USER

3.4 vm_unmap

int vm_unmap(uint64_t va, uint64_t len);

3.5 oom_scan

int oom_scan(proc_info_t* out);

3.6 oom_reclaim

int oom_reclaim(uint32_t level);

4. 调度器接口

4.1 sched_spawn

int sched_spawn(const char* path, uint64_t caps, pid_t* out_pid);
参数 说明
path .nuc 文件路径,如 "/system/bin/novus-settings"
caps 进程初始 CAP 掩码(低64位)
out_pid 输出参数,成功写入新 PID

4.2 sched_ctl

int sched_ctl(pid_t pid, uint32_t op, void* arg);

4.3 sched_exception_report

int sched_exception_report(pid_t pid, exc_info_t* exc);
typedef struct {
    uint64_t pid;
    uint64_t rip;        // 出错指令地址
    uint64_t cr2;        // 页错误地址
    uint32_t err_code;   // 错误码
    char proc_name[64];
    uint8_t  cause;      // 0=页错误 1=非法指令 2=除零 3=断点
} exc_info_t;

5. 安全/CAP 接口

5.1 cap_check

int cap_check(proc_cap_t* p, uint32_t bit);

5.2 cap_drop

int cap_drop(proc_cap_t* p, uint32_t bit);

5.3 nkm_load

int nkm_load(const char* path);

6. VFS 接口

6.1 vfs_open

int vfs_open(const char* path, uint32_t flags, uint32_t mode);

6.2 vfs_read / vfs_write

int vfs_read(int fd, void* buf, uint64_t len);
int vfs_write(int fd, const void* buf, uint64_t len);

7. NovusFS 接口

7.1 novusfs_alloc_block

int novusfs_alloc_block(uint64_t* out_block);

7.2 WAL 事务

wal_begin_tx

int wal_begin_tx(uint32_t type, uint64_t block_no, wal_tx_t* out);

wal_commit

int wal_commit(wal_tx_t* tx, const void* data, uint32_t len);

wal_rollback

void wal_rollback(wal_tx_t* tx);

WAL 满判定

// 满条件:write_ptr == tail_ptr
if (wal_write_ptr == wal_tail_ptr) {
    // 推进 tail 到下一个完整事务边界
    wal_advance_tail();
}

8. Merkle 树接口

8.1 merkle_verify_root

int merkle_verify_root(dev_t dev, const uint8_t expect[32]);

8.2 节点磁盘映射

// idx: 节点索引(根=1)
uint64_t node_to_block(uint64_t idx) {
    return merkle_start_block + (idx / 64);
}
uint64_t node_offset_in_block(uint64_t idx) {
    return (idx % 64) * 64;
}

9. 图形栈系统调用

9.1 sys_gfx_create_surface

int sys_gfx_create_surface(uint32_t w, uint32_t h, uint32_t fmt, fb_handle_t* out);

9.2 sys_gfx_submit_dirty

int sys_gfx_submit_dirty(fb_handle_t h, const rect_t* rects, uint32_t n);

10. IPC 接口

10.1 ipc_send

int ipc_send(novus_ipc_hdr_t* hdr, const void* payload);

11. 系统调用 ABI(debug 要点)

11.1 寄存器约定

用途 寄存器
调用号 rax
参数1 rdi
参数2 rsi
参数3 rdx
参数4 rcx
参数5 r8
参数6 r9
返回值 rax
被调用者保存 rbp, rbx, r12, r13, r14, r15

11.2 常见调试技巧

  1. 系统调用号打印:在 syscall 入口打印 rax 和参数
  2. 返回值检查:用户态库包装后检查 rax 是否为负
  3. 栈对齐:进入内核时检查 rsp % 16 == 0
  4. 权限拒绝:syscall 入口先 cap_check,拒绝时打印 bit 号

12. 日志接口

12.1 log_print

void log_print(uint32_t level, const char* fmt, ...);

12.2 panic_handler

void panic_handler(cpu_state_t* state);

13. 调试通用建议

13.1 打印策略

13.2 断言

13.3 常见 Bug 清单

  1. 忘记持锁 → 多进程竞态
  2. 锁顺序错误 → 死锁(必须按 超级块→目录→inode→块分配)
  3. 双重释放 → 内存 corruption
  4. 偏移未对齐 → x86_64 严格对齐异常
  5. CAP 忘记检查 → 越权访问
  6. WAL 写了 PREP 没写 COMMIT → 崩溃后数据丢失
  7. Merkle 哈希包含了自身 hash 字段 → 校验永远失败
  8. NKM 签名时公钥不匹配 → 模块无法加载

文档状态

本文档为 Debug 级接口手册,开发时对照此文档逐行检查代码。 所有函数签名、参数、错误码、前置条件已冻结。

文档状态:✅ 冻结,可作为 M0–M10 开发调试基准。


Revision #1
Created 2026-10-31 11:25:14 UTC by Admin
Updated 2026-10-31 11:25:25 UTC by Admin