Files
build_infra/0_笔记/操作系统知识.md
T
2026-06-16 10:23:51 +08:00

2.5 KiB

目录 说明
/usr/include/linux/ 从 Linux 内核源码生成,描述内核接口(系统调用等)
/usr/include/asm/ 和架构相关的定义(如 syscall 编号、CPU 寄存器布局)
/usr/include/sys/ glibc 的封装头,用于标准 C 接口,对上层屏蔽差异

/usr/include/linux//usr/include/asm/ 是你编译 Linux 内核后,通过 make headers_install 安装出来的 /usr/include/sys/ 是编译 glibc 时自动放进去的,不依赖内核。

由于glibc是源代码级,跨架构,跨平台的。又封装了系统调用,所以 /usr/include/sys/ 下的文件是 glibc构建过程中的脚本和模板 时根据架构,平台生成的。 编译脚本判断完目标系统系统以后,比如 X86+LINUX,它会寻找OS对外暴露的系统调用头文件,比如'/usr/include/linux',里面是C库如何调用本OS的系统调用的格式和指令, 然后编译脚本通过 代码模板 将这些系统调用封装好,基本上就是用宏将汇编指令封装成最低层的C函数,然后稍微上层一点的C函数, 比如read/write函数早就适配好要调用哪些封装C函数。 这些都是编译脚本自动生成,然后就可以编译了。 如果将glibc移植到一个新的平台,只要按照规则将一些脚本和模板编写好,后面都是由编译脚本自动完成。 这种约定已经很成熟了,基本上不需要我们操心。

Linux的内核系统调用接口除了几个独有的之外,大部分都兼容POSIX标准,而glibc将系统调用封装成用户空间函数接口,命名是一样的,glibc还实现了ISO C的标准库。

而Windows的系统调用通过ntdll.dll封装成Native API,然后再被kernel32.dll, user32.dll, gdi32.dll, ws2_32.dll之类的封装成常见的Win32API, 内核接口和用户空间接口命名不一样,而ISO C的标准库则是通过msvcrt.dll, msvcr*.dll, ucrtbase.dll之类的实现, 所以glibc和Windows的 API本质都是用户空间API而不是系统调用,是逻辑层次上基本等价的东西,只是要注意C标准库实现的所在位置。 参考: https://en.wikipedia.org/wiki/Microsoft_Windows_library_files

系统调用是:用户态程序 → 内核

系统调用本身在内核中是“汇编 + C”实现的

glibc是c标准库的一个实现。