41 心中的内核——效率至上而非历史遗留原因:为什么内核仍用C语言开发
# 41 心中的内核——效率至上而非历史遗留原因:为什么内核仍用C语言开发
系统编程语言的目的并非服务程序员,而是允许内核独立运行——仅凭自身,直接在硬件上运行。无需运行时环境,无需依赖项,只有代码、机器及两者之间的接口。
内核使用C语言并非出于历史原因,而是因为没有其他语言能在软件与硬件的交界处提供同等水平的效率、控制力和结构清晰度。
C语言是一种组件化语言。源文件定义函数、结构体和指针,头文件仅声明需要可见的内容。编译结果形成应用二进制接口(ABI)——这是一种稳定的二进制契约,允许每个模块在不同构建和架构中可预测地运行。
内核并非在运行时定义,而是在构建时塑造。通过C预处理器,.config设置使用条件宏激活或排除功能。这些决策控制编译路径,为特定硬件定制内核,并完全消除未使用的逻辑。看似通用的行为是通过宏和内联函数实现的基于模式的代码重用——而非通过模板或反射。
C语言在内核设计中扮演三个角色。首先,它直接表达与硬件数据表(寄存器、内存映射I/O和控制流)一致的控制逻辑。其次,它实现紧凑、可预测的算法来管理CPU时间、内存和线程。第三,它通过引用和组合构建系统结构。嵌套结构体、嵌入式回调和函数指针支持模块化框架,无需继承。
C语言中的结构体在内存中精确布局。每个字段根据ABI强制的对齐规则放置,仅在必要时引入填充,总体大小不仅反映数据,还反映布局。这使得每次访问都可预测,每个偏移量都有意义,且该结构适用于二进制级通信。
C语言中的指针不仅仅代表地址。函数指针绑定到代码,结构体指针指向状态,void* 引用原始内存——它并非用于强制转换任何内容,不进行转换,而是进行解释。它允许对平面内存进行结构化访问,其中结构由程序员基于已知类型应用——而非通过改变类型本身。内存是平面的,void* 是在该空间中表示数据的最自然方式。
C语言中的可见性是经过深思熟虑的。static符号保留在内部,外部声明仅定义共享内容。在内核中,符号导出通过EXPORT_SYMBOL显式控制,该宏定义模块在运行时可链接的内容。没有隐式可见性——每个边界都是有意设定的。
C语言提供对内存、执行和结构的直接访问,无需假设机器之上的任何内容。这就是它仍然是内核语言的原因——不是因为它古老,而是因为它仍然是描述系统如何独立运行的最有效、最真实的方式。
使用C语言并非因为它古老,而是因为它适合系统的边缘地带。
在Linux的边缘——准备潜入内核的深处。
全文完。