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): 创建新文件(等同于 openO_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 系统编程!

data-ad-format="auto" data-full-width-responsive="true">