syscall_table.rst 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. 系统调用表实现方案
  2. ====================
  3. .. note::
  4. Author: longjin <longjin@dragonos.org>
  5. Date: 2025/05/13
  6. 概述
  7. ----
  8. .. mermaid::
  9. :align: center
  10. :caption: 系统调用表架构
  11. classDiagram
  12. class Syscall {
  13. <<trait>>
  14. +num_args() usize
  15. +handle(args, from_user) Result<usize, SystemError>
  16. +entry_format(args) Vec<FormattedSyscallParam>
  17. }
  18. class SyscallHandle {
  19. +nr: usize
  20. +inner_handle: &dyn Syscall
  21. }
  22. class SyscallTable {
  23. -entries: [Option<&SyscallHandle>; 512]
  24. +get(nr) Option<&dyn Syscall>
  25. }
  26. Syscall <|.. SysXXXXXXHandle
  27. SyscallHandle "1" *-- "1" Syscall
  28. SyscallTable "1" *-- "512" SyscallHandle
  29. 相比于将原本集中在一个大match中的系统调用分发,本方案采用基于trait和系统调用表的实现。主要优势包括:
  30. - 降低栈内存使用:避免单个大函数占用过多栈空间
  31. - 支持参数打印:通过统一的参数格式化接口
  32. - 更好的扩展性:新增系统调用无需修改分发逻辑
  33. 核心设计
  34. --------
  35. Syscall Trait
  36. ~~~~~~~~~~~~~
  37. 所有系统调用处理函数都需要实现 `Syscall` trait:
  38. .. code-block:: rust
  39. pub trait Syscall: Send + Sync + 'static {
  40. fn num_args(&self) -> usize;
  41. fn handle(&self, args: &[usize], from_user: bool) -> Result<usize, SystemError>;
  42. fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam>;
  43. }
  44. - `num_args()`: 返回该系统调用需要的参数数量
  45. - `handle()`: 实际执行系统调用处理
  46. - `entry_format()`: 格式化参数用于调试打印
  47. SyscallHandle
  48. ~~~~~~~~~~~~~
  49. `SyscallHandle` 结构体将系统调用号与处理函数关联:
  50. .. code-block:: rust
  51. pub struct SyscallHandle {
  52. pub nr: usize, // 系统调用号
  53. pub inner_handle: &'static dyn Syscall, // 处理函数
  54. pub name: &'static str,
  55. }
  56. SyscallTable
  57. ~~~~~~~~~~~~
  58. `SyscallTable` 管理所有系统调用:
  59. - 固定大小512项
  60. - 编译时初始化
  61. - 通过系统调用号快速查找处理函数
  62. 使用方式
  63. --------
  64. 实现系统调用
  65. ~~~~~~~~~~~~
  66. 1. 定义实现``Syscall`` trait的结构体
  67. 2. 实现``handle()``和``entry_format()``方法
  68. 3. 使用``declare_syscall!``宏注册
  69. 参考实现:`sys_write.rs <sys_write_>`_
  70. .. _sys_write:
  71. https://github.com/DragonOS-Community/DragonOS/blob/master/kernel/src/filesystem/vfs/syscall/sys_write.rs
  72. 注册系统调用
  73. ~~~~~~~~~~~~
  74. 使用``declare_syscall!``宏注册系统调用:
  75. .. code-block:: rust
  76. syscall_table_macros::declare_syscall!(SYS_WRITE, SysWriteHandle);
  77. 参数说明:
  78. 1. 系统调用名称(用于生成符号)
  79. 2. 实现``Syscall`` trait的结构体
  80. 初始化流程
  81. ----------
  82. 1. 内核启动时调用``syscall_table_init()``
  83. 2. 从链接器符号``_syscall_table``加载所有注册的系统调用
  84. 3. 填充系统调用表