C语言没死!嵌入式Linux内核开发离不开它

张开发
2026/4/16 5:25:35 15 分钟阅读

分享文章

C语言没死!嵌入式Linux内核开发离不开它
C语言还没死大家都说它老了可为啥啥都绕不开它。我于近期翻阅了数目众多的资料还向几位从事嵌入式以及内核相关工作的朋友进行了询问并非是他们存有懒惰之心不去换新语言而是没办法进行更换——在某些特定的地方条件确实是没有可供选择的余地。比如说Linux内核直至如今仍旧有97%或者更高的占比是采用C语言去书写的。即便Rust语言得以进入了几个驱动模块之中然而连调度器的边缘都未曾触及到。这是为什么呢原因在于上下文切换精确要求精细到精确到对于每一条汇编指令而言对于寄存器怎样进行保存又怎样进行恢复在C语言里面一个宏、一段内联汇编便能够将其搞定要是换成别的语言仅仅是运行时那一层的抽象就已然会出现超时的情况了。汽车之中的ESP控制器其响应时间不可以超过1.2微秒这个数字并非是凭借主观随意确定的而是当刹车被踩下去之后车辆还没有出现晃动一下的情况之时就必须要开始进行干预C语言编译完成之后能够计算出最坏执行时间然而Rust当前的工具链却没有办法做到这一点更为关键的是它不允许进行malloc操作不允许抛出异常甚至就连函数调用栈都需要手动去进行控制这些并非是限制而是铁律。C借助static进行限定 通过volatile来保证特殊的内存语义 利用__attribute__达成特定属性设置 从而能将代码固定在内存某一地址之处 其他语言若想效仿 需要历经蜿蜒曲折的三道流程 而且极易产生差错错误。写驱动这个事儿呢实际上就是充当一个“翻译官”的角色一方面要依据芯片手册逐比特地去对照寄存器与此同时还要跟操作系统清晰道明DMA如何传输、中断怎样清除。在2024年的时候出现了一个被用Rust重新编写的显卡驱动结果在休眠这种情况时就会出现故障经过长时间的排查发现是bitfield位序与硬件存在不一致的状况因为手册所写的情况是MSB在前排列而Rust按照默认设定是按小端进行排列的要是在C里面添加一个packed就能够保证稳定运行了。并非是某个人书写的质量差而是C的抽象程度恰好处于硬件与OS之间的那条缝隙之中。所有的高级语言统统都得依靠C来打下基础Python之所以能够运行那是因为CPython是用C编写而成的Node.js之所以速度快是由于V8会把JS编译成为机器码然而在申请可执行内存的这一步骤当中只有C能够以通用的方式调用mmap以及mprotect。就连Rust自身的标准库在堆内存分配方面最终仍旧需要调用libc的malloc——它压根就没打算避开C它心里明白自己绕不过去。密码学厉得多。OpenSSL当中AES加密务必恒定时间不可以因为密钥存在差异就多出一条分支不然会遭受侧信道攻击。C里面能够运用volatile强制读、借助内联汇编锁定指令顺序Rust的unsafe块没办法达成这种颗粒度的把控。FIPS认证报告所写的并非‘使用了何种语言’而是‘控制流图可不可以验证’当前仅有C的CFG能够被NIST认可的工具全面剖析。用FFmpeg去解HEVC视频在一帧当中存在几千个CABAC熵解码查表操作完全依靠一个static const数组直接注入到L1缓存当中。要是换成别的语言仅仅是封装一层如“List”或“Vec”这样的结构内存就会多跳转一次帧率便会下降。对于WebRTC音频同步而言需要纳秒级时间戳在POSIX里唯一不会产生漂移的就是C语言的clock_gettime(CLOCK_MONOTONIC_RAW)。对于SQLite而言写一个数据库页时校验和是直接拿uint8_t* 逐个字节去扫描的既不进行字符串转换也不创建对象更不进入GC。PostgreSQL的WAL日志进行刷盘操作时绕过了glibc缓冲区直接将write() 作用于fd实际测量发现这样做在CPU使用上比Rust原型节省了一半。并不是Rust运行速度慢而是C语言距离系统调用仅仅隔着一层纸而别的语言在中间至少铺垫了三张纸。身处太空的JWST望远镜代码无法重启无法调试一旦出现问题数亿美金便付诸东流。DO - 178C Level A认证规定每个判断语句都需覆盖两种结果C语言借助LDRA、VectorCAST等工具切实运行MC/DC而Rust仍在等待。辐射致使单粒子翻转需手动插入clrbt指令清除分支预测缓存此项工作唯有在C语言中嵌入汇编才能完成。简要来讲C并非那种写起来让人感觉畅快的语言而是一种写起来费劲、修改时需谨慎、读起来能明白的语言。它不会帮着用户去记录内存情况不会替用户挑选算法类型不会隐藏任何一行属于多余部分的指令。当用户需要针对一块指定内存、一个特定寄存器、一个精确时钟周期承担起相应责任的时候C便是用户唯一能够稳稳握在手中的扳手工具了。

更多文章