Linux 3.0 内核系统调用

首先需要明确一点:系统调用的具体列表和编号会随着内核版本演进而变化,增加新的调用或废弃旧的调用。虽然核心功能(如文件 I/O、进程管理)相对稳定,但细节上会有差异。请注意,最准确的信息始终来自于查阅对应内核版本的源代码或权威文档。

### Linux 3.0 内核系统调用 (基于 x86_64 架构)
Linux 3.0 是一个相对成熟的内核版本。其系统调用接口已经非常丰富和稳定。
#### **系统调用分类与接口**
1. **进程控制 (Process Control)**
* `fork` (57): 创建一个子进程。
* `vfork` (58): 创建子进程,但在子进程调用 `exec` 或 `_exit` 前阻塞父进程。
* `clone` (56): 创建子进程或线程,比 `fork`/`vfork` 更灵活,允许共享内存空间等。
* `execve` (59): 用新程序替换当前进程镜像。
* `exit` (60): 终止调用进程。
* `exit_group` (231): 终止线程组中的所有线程。
* `wait4` (61): 等待子进程状态变化。
* `waitid` (247): 等待子进程状态变化(提供比 `wait4` 更丰富的信息)。
* `kill` (62): 发送信号给进程。
* `tkill` (200): 发送信号给指定线程 (已废弃,推荐使用 `tgkill`)。
* `tgkill` (234): 发送信号给指定进程内的指定线程。
* `getpid` (39): 获取调用进程的进程 ID (PID)。
* `getppid` (110): 获取调用进程的父进程 ID (PPID)。
* `getuid` (102): 获取真实用户 ID。
* `geteuid` (107): 获取有效用户 ID。
* `getgid` (104): 获取真实组 ID。
* `getegid` (108): 获取有效组 ID。
* `setuid` (105): 设置用户 ID。
* `setgid` (106): 设置组 ID。
* `getgroups` (115): 获取附加组 ID 列表。
* `setgroups` (116): 设置附加组 ID 列表。
* `setreuid` (113): 设置真实和有效用户 ID。
* `setregid` (114): 设置真实和有效组 ID。
* `setresuid` (117): 设置真实、有效和保存的用户 ID。
* `setresgid` (119): 设置真实、有效和保存的组 ID。
* `getresuid` (118): 获取真实、有效和保存的用户 ID。
* `getresgid` (120): 获取真实、有效和保存的组 ID。
* `setsid` (112): 创建新的会话。
* `getsid` (124): 获取会话 ID。
* `setpgid` (109): 设置进程组 ID。
* `getpgid` (121): 获取进程组 ID。
* `getpgrp` (111): 获取当前进程的进程组 ID。
* `prctl` (157): 操作进程属性(如设置进程名、安全模块等)。
* `arch_prctl` (158): 特定于架构的进程控制(x86_64 上用于设置 FS/GS 段基址)。
* `personality` (135): 设置进程执行域(personality)。
* `getpriority` (140): 获取进程/进程组的调度优先级。
* `setpriority` (141): 设置进程/进程组的调度优先级。
* `sched_setscheduler` (144): 设置进程的调度策略和参数。
* `sched_getscheduler` (145): 获取进程的调度策略。
* `sched_yield` (24): 主动让出 CPU。
* `sched_get_priority_max` (146): 获取指定调度策略的最大优先级。
* `sched_get_priority_min` (147): 获取指定调度策略的最小优先级。
* `sched_rr_get_interval` (148): 获取 SCHED_RR 策略的时间片。
* `nanosleep` (35): 高精度睡眠。
* `getitimer` (36): 获取间隔计时器值。
* `setitimer` (38): 设置间隔计时器值。

2. **文件 I/O (File Input/Output)**
* `open` (2): 打开或创建文件。
* `openat` (257): 类似 `open`,但允许指定相对路径的基准目录描述符。
* `creat` (85): 创建新文件(等同于 `open` 带 `O_CREAT|O_WRONLY|O_TRUNC` 标志)。
* `close` (3): 关闭打开的文件描述符。
* `read` (0): 从文件描述符读取数据。
* `write` (1): 向文件描述符写入数据。
* `pread64` (17): 从文件指定偏移量读取数据(原子操作)。
* `pwrite64` (18): 向文件指定偏移量写入数据(原子操作)。
* `readv` (19): 从文件描述符读取数据到多个缓冲区(分散读)。
* `writev` (20): 从多个缓冲区写入数据到文件描述符(集中写)。
* `lseek` (8): 设置文件偏移量。
* `fcntl` (72): 对打开的文件描述符进行各种控制操作(如复制描述符、设置标志)。
* `dup` (32): 复制文件描述符。
* `dup2` (33): 复制文件描述符,并允许指定新的描述符号。
* `dup3` (292): 类似 `dup2`,但允许设置 `O_CLOEXEC` 标志。
* `select` (23): I/O 多路复用,监视多个文件描述符。
* `poll` (7): I/O 多路复用,监视多个文件描述符。
* `epoll_create` (213): 创建 epoll 实例。
* `epoll_create1` (291): 创建 epoll 实例,允许设置标志。
* `epoll_ctl` (233): 控制 epoll 实例(添加/修改/删除监视的文件描述符)。
* `epoll_wait` (232): 等待 epoll 实例上的事件。
* `pipe` (22): 创建管道。
* `pipe2` (293): 创建管道,允许设置标志(如 `O_CLOEXEC`, `O_NONBLOCK`)。

3. **文件系统控制 (File System Control)**
* `stat` (4): 获取文件状态信息。
* `lstat` (6): 获取文件状态信息(不跟随符号链接)。
* `fstat` (5): 获取打开文件描述符对应的文件状态信息。
* `newstat` (106, 64-bit 版本): 获取文件状态信息(64位兼容)。
* `newlstat` (107, 64-bit 版本): 获取文件状态信息(不跟随符号链接,64位兼容)。
* `newfstat` (108, 64-bit 版本): 获取打开文件描述符对应的文件状态信息(64位兼容)。
* `statfs` (137): 获取文件系统统计信息。
* `fstatfs` (138): 获取打开文件描述符所在文件系统的统计信息。
* `access` (21): 检查调用进程是否可以访问文件(按实际用户ID和组ID)。
* `chmod` (90): 改变文件权限。
* `fchmod` (91): 改变打开文件描述符对应的文件权限。
* `chown` (92): 改变文件所有者和组。
* `fchown` (93): 改变打开文件描述符对应的文件所有者和组。
* `lchown` (94): 改变符号链接本身的所有者和组。
* `truncate` (76): 将文件截断或扩展到指定长度。
* `ftruncate` (77): 将打开文件描述符对应的文件截断或扩展到指定长度。
* `utime` (132): 改变文件的访问时间和修改时间。
* `utimes` (235): 改变文件的访问时间和修改时间(使用 `timeval` 结构)。
* `link` (86): 创建硬链接。
* `linkat` (265): 创建硬链接,允许指定相对路径基准。
* `symlink` (88): 创建符号链接。
* `symlinkat` (266): 创建符号链接,允许指定相对路径基准。
* `readlink` (89): 读取符号链接的内容。
* `readlinkat` (267): 读取符号链接的内容,允许指定相对路径基准。
* `unlink` (87): 删除目录项(通常用于删除文件)。
* `unlinkat` (263): 删除目录项,允许指定相对路径基准和标志。
* `rename` (82): 重命名文件或目录。
* `renameat` (264): 重命名文件或目录,允许指定相对路径基准。
* `mkdir` (83): 创建目录。
* `mkdirat` (258): 创建目录,允许指定相对路径基准。
* `rmdir` (84): 删除空目录。
* `chdir` (80): 改变当前工作目录。
* `fchdir` (81): 通过文件描述符改变当前工作目录。
* `getcwd` (79): 获取当前工作目录路径。
* `umask` (95): 设置或获取文件模式创建掩码。
* `mknod` (133): 创建特殊文件(设备文件、FIFO)。
* `mknodat` (259): 创建特殊文件,允许指定相对路径基准。
* `getdents` (78): 读取目录内容(旧接口)。
* `getdents64` (217): 读取目录内容(新接口,支持 64 位 inode)。

4. **内存管理 (Memory Management)**
* `brk` (12): 改变数据段大小。
* `sbrk` (12, 库函数封装): 改变数据段大小。
* `mmap` (9): 将文件或设备映射到内存,或分配匿名内存。
* `munmap` (11): 解除内存映射。
* `mremap` (25): 重新映射虚拟内存地址。
* `msync` (26): 将映射区域的修改同步到文件。
* `mprotect` (10): 设置内存页的保护属性。
* `mincore` (27): 确定内存页是否在物理内存中。
* `madvise` (28): 给内核提供关于内存访问模式的建议。
* `shmget` (29): 分配 System V 共享内存段。
* `shmat` (30): 连接 System V 共享内存段。
* `shmdt` (67): 断开 System V 共享内存段连接。
* `shmctl` (31): 控制 System V 共享内存段。

5. **信号处理 (Signal Handling)**
* `signal` (48, 库函数封装): 设置信号处理函数(不推荐直接使用,推荐 `sigaction`)。
* `sigaction` (13): 检查或修改信号的处理动作。
* `sigprocmask` (14): 检查或修改信号掩码。
* `sigpending` (15): 检查挂起的信号。
* `sigsuspend` (16): 等待信号。
* `sigaltstack` (131): 设置或获取信号栈信息。

6. **时间管理 (Time Management)**
* `time` (201): 获取当前时间(秒)。
* `gettimeofday` (96): 获取当前时间(秒和微秒)。
* `settimeofday` (164): 设置系统时间。
* `clock_gettime` (228): 获取指定时钟的时间。
* `clock_settime` (227): 设置指定时钟的时间。
* `clock_getres` (229): 获取指定时钟的精度。

7. **套接字 (Sockets)**
* `socket` (41): 创建套接字。
* `bind` (49): 将套接字绑定到地址。
* `connect` (42): 建立到另一个套接字的连接。
* `listen` (50): 监听套接字上的连接。
* `accept` (43): 接受一个套接字连接。
* `getsockname` (51): 获取套接字本地地址。
* `getpeername` (52): 获取套接字对端地址。
* `socketpair` (53): 创建一对已连接的套接字。
* `send` (44): 通过套接字发送消息。
* `recv` (45): 通过套接字接收消息。
* `sendto` (46): 通过套接字发送数据报。
* `recvfrom` (47): 通过套接字接收数据报。
* `shutdown` (48): 关闭套接字的全部或部分连接。
* `setsockopt` (54): 设置套接字选项。
* `getsockopt` (55): 获取套接字选项。
* `sendmsg` (46): 通过套接字发送消息(支持辅助数据)。
* `recvmsg` (47): 通过套接字接收消息(支持辅助数据)。

8. **用户和组管理 (User and Group Management)**
* (已在进程控制部分列出:`getuid`, `geteuid`, `getgid`, `getegid`, `setuid`, `setgid`, `getgroups`, `setgroups`, `setreuid`, `setregid`, `setresuid`, `setresgid`, `getresuid`, `getresgid`)

9. **系统信息和控制 (System Information and Control)**
* `uname` (63): 获取系统名称、版本等信息。
* `sysinfo` (179): 获取系统统计信息。
* `times` (100): 获取进程时间。
* `getrusage` (98): 获取资源使用信息。
* `syslog` (103): 读写内核日志缓冲区。
* `iopl` (172): 设置 I/O 权限级别(需要特权)。
* `ioperm` (173): 设置端口 I/O 权限位图(需要特权)。

10. **其他 (Miscellaneous)**
* `ioctl` (16): 设备特定的 I/O 操作。
* `fcntl` (72): 文件描述符控制(已在文件 I/O 部分列出)。
* `mount` (165): 挂载文件系统。
* `umount2` (166): 卸载文件系统。
* `pivot_root` (155): 改变根文件系统。
* `swapon` (167): 启用交换空间。
* `swapoff` (168): 禁用交换空间。
* `reboot` (169): 重启或关闭系统(需要特权)。
* `init_module` (171): 加载内核模块(需要特权)。
* `delete_module` (176): 卸载内核模块(需要特权)。
* `kexec_load` (246): 加载新的内核以供 `kexec` 使用。
* `acct` (163): 启用或禁用进程记账。
* `capget` (125): 获取线程的能力。
* `capset` (126): 设置线程的能力。
* `ptrace` (101): 进程跟踪。
* `sysfs` (139): 获取关于系统文件系统的信息。
* `ustat` (136): 获取文件系统统计信息(已废弃)。

### Linux 5.x 内核系统调用 (基于 x86_64 架构)

Linux 5.x 是一个较新的内核系列,它在保持向后兼容的同时,引入了许多新特性和系统调用。

#### **系统调用分类与接口 (与 3.0 相比的主要变化)**

核心分类基本一致,但在具体调用上有所增减和演进:

1. **新增的系统调用 (New Syscalls):**
* `io_uring_setup` (425): 设置 io_uring 异步 I/O 接口。
* `io_uring_enter` (426): 启动/提交 io_uring 操作。
* `io_uring_register` (427): 注册文件/缓冲区等供 io_uring 使用。
* `openat2` (437): `openat` 的扩展版本,提供更多控制选项。
* `pidfd_send_signal` (424): 通过 PID 文件描述符发送信号,更安全。
* `pidfd_open` (434): 为进程 ID 打开一个文件描述符。
* `clone3` (435): `clone` 的扩展版本,提供更丰富的参数。
* `close_range` (436): 关闭一个范围内的文件描述符。
* `fsconfig` (431): 配置和管理文件系统挂载参数。
* `fsmount` (432): 创建挂载实例。
* `fsopen` (430): 打开文件系统。
* `fspick` (433): 选择文件系统挂载点。
* `move_mount` (429): 移动挂载点。
* `open_tree` (428): 打开目录树以进行挂载操作。
* `landlock_create_ruleset` (444+): Landlock LSM 安全模块相关。
* `landlock_add_rule` (445+): Landlock LSM 安全模块相关。
* `landlock_restrict_self` (446+): Landlock LSM 安全模块相关。
* `memfd_secret` (447+): 创建一个内存文件描述符,其内容对内核其他部分保密。
* `process_mrelease` (448+): 释放与进程相关的内存。
* `futex_waitv` (449+): `futex` 的扩展,支持等待多个 futex。
* `set_mempolicy_home_node` (450+): 设置内存策略的首选 NUMA 节点。

2. **演进和改进 (Evolution & Improvements):**
* **`statx` (332):** 一个新的、更强大和灵活的获取文件状态信息的系统调用,旨在替代 `stat/lstat/fstat` 系列。它提供了更丰富的元数据和更好的性能。
* **`copy_file_range` (326):** 在两个文件描述符之间高效地复制数据,内核层面优化。
* **`preadv2` (327), `pwritev2` (328):** `preadv`/`pwritev` 的增强版,支持额外的标志(如 `RWF_NOWAIT`, `RWF_HIPRI`)。
* **`pkey_mprotect` (329):** 与内存保护密钥(Memory Protection Keys)一起使用,提供比 `mprotect` 更细粒度的保护。
* **`pkey_alloc` (330), `pkey_free` (331):** 分配和释放内存保护密钥。
* **`statfs`/`fstatfs` 行为改进:** 对某些文件系统的支持和信息返回可能更完善。
* **`mount`/`umount` 相关:** 旧的 `mount` 系统调用仍然存在,但新的文件系统 API (`fsopen`, `fsconfig`, `fsmount` 等) 提供了更现代、更安全的挂载方式。
* **`seccomp` 增强:** 与安全相关的系统调用可能有更新,用于构建更严格的沙箱。

3. **废弃或不推荐 (Deprecated/Obsolete):**
* 一些旧的、功能重叠或有安全问题的调用可能被标记为废弃,鼓励使用新接口。例如,某些特定架构的旧调用可能不再推荐。
* `sysfs` (139): 在某些场景下可能被新的接口替代或使用减少。

4. **核心功能保持稳定 (Core Functionality Remains Stable):**
* `read`, `write`, `open`, `close`, `fork`, `execve`, `mmap`, `socket`, `bind`, `connect` 等基础且核心的系统调用在 5.x 中依然存在,保证了向后兼容性。它们的编号和基本语义通常不变。

#### **总结**

* **Linux 3.0:** 代表了内核成熟期的一个稳定版本,包含了当时绝大多数常用和必要的系统调用。其分类清晰,是学习经典 Linux 系统编程的良好起点。
* **Linux 5.x:** 在 3.0 的基础上,增加了许多现代化特性,特别是在异步 I/O (`io_uring`)、安全 (`Landlock`, `memfd_secret`)、内存管理 (`pkey_*`)、文件系统操作 (新挂载 API) 和进程控制 (`clone3`, `pidfd_*`) 方面。这些新调用旨在提高性能、安全性、灵活性和易用性。

**学习建议:**

1. **从基础开始:** 先掌握 3.0 中列出的核心系统调用,理解它们的工作原理和使用场景。
2. **查阅手册:** 始终使用 `man 2 syscall_name` 来获取最准确的文档。
3. **实践编码:** 通过编写小程序来实践这些调用。
4. **关注演进:** 学习 5.x 新增的调用,特别是那些能显著提升性能或安全性的功能(如 `io_uring`, `statx`)。
5. **检查兼容性:** 如果你的程序需要在不同内核版本上运行,务必检查所使用的系统调用的可用性。

希望这份详细的分类和介绍能帮助你更好地理解 Linux 系统编程!

此条目发表在未分类分类目录。将固定链接加入收藏夹。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注