打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
请问什么是内核头文件(Kernel Headers)、工具链(Tool Chain)?

简单说,就好像“你买手机充电线要先看看自己的手机充电口是micro-usb、usb-c还是别的什么,买错了就没法用”一样,无论我们写的程序要调用内核提供的什么功能、还是我们本身要开发内核模块,首先就得保证我们写的程序能够和内核的数据结构以及函数接口匹配,对吧?

kernel headers就是这么一组“头文件”(header file),它是C/C++系语言的一个特殊设计。

程序员可以把程序里可能多处使用的常量定义、宏定义、函数接口定义(函数原型)等等东西写进头文件;然后其它程序用#include把它包含进来(效果是,将来编译器会自动把对应的文件内容拷进来、附加到文件头部),这样就不需要到处重新定义它了。

举例来说,我们的程序将要用到操作系统提供的chmod功能,它的作用是修改文件访问权限;但直接在程序里调用chmod的行不通的,因为编译器不知道这个函数有几个参数、分别是怎么传进去的、执行结束会返回什么。然后我们到网上一搜,知道这个函数的原型是:

int chmod(const char *path, mode_t mode);

那么把这行原型声明写进我们的程序,编译器就能编译通过了。

但这个做法虽然可行,但却是野路子玩法。

这是因为,Linux提供的结构、功能非常非常多;一个个找出来、自己敲进去也太累人了;而且一不小心就会出错。

尤其是,某些函数、数据结构在不同版本的Linux kernel下可能是不一样的;这种硬编码不会及时反映变化,很可能版本一升级,完蛋。

因此,正确的做法是把对应的kernel header用#include包含进去,这样将来Linux升级了,相应的定义也会跟着升级——然后编译器就会报告接口不匹配,你照着提示改一改就好。

比如,chmod的定义就可以用#include取得,有了它你就可以自由使用相关函数了。

chmod(3): change mode of file

总结出来就是:#include和法院判决书的“根据中华人民共和国刑法第XXX条第X款规定”一样,是在明确引用各种C/C++库接口规格的最权威定义。

头文件(header file)就是格式规范的、可以被编译器识别的软件接口规格书;有了它,相关接口的访问才能不走样、万一接口更改了也能第一时间发现(因为内核/库/模块编写者也引用它、相关功能使用者也引用它;而且它可以被机器自动识别,任何一方有任何违例都会被第一时间发现:充分利用它,才能确保软件不会在接口上闹出差错)。

而kernel headers就是Linux内核的接口规格书。

前面提到过“头文件是机器可以自动识别的接口规格书”;那么要识别它、处理它,自然就需要一套工具。

进一步的,不仅头文件是机器可识别的,程序本身也是机器可识别的。

但识别归识别,它们并不能被执行。

这是因为,现在写程序都用高级语言,最靠下也要用汇编;这些都是为了方便人阅读/撰写而设计的;机器只认二进制指令。

因此,我们需要一套工具,把程序员们写的、给人看的程序转换成可以给程序执行(但人看起来只是一堆数字)的、固定格式的二进制序列。

这套工具包括但不限于:

编译器——把程序员们敲的C语言源程序文件一个个转换成计算机指令,输出一大堆“目标文件”。

链接器——把编译器输出的、散乱的目标文件以及动态/静态链接库文件整合起来,把彼此的引用关系理顺(比如A文件可能会调用B文件定义的函数a)、检查接口是否存在并整合成可执行文件(或动态/静态库文件)。

调试器——跟踪观察执行中的程序,甚至修改运行中的程序中的某些变量,确保程序在任何状况下都能正确完成任务。

make工具——当我提到链接器既能链接出程序也能链接出动态库/静态库、且给链接器的输入可以是目标文件或者动静态库时,你可能已经意识到这个过程可能非常非常复杂、而且可能需要分区分块进行很多次。因此,我们需要一套管理系统,帮我们管理源文件之间的依赖关系、考察本次编译哪些源文件改动过所以需要重新编译哪些则不需要(并找出依赖于它们因此也不得不重新编译的源文件并重新编译)、甚至动态切换不同的编译配置(比如更慢更大更方便调试的debug版配置或者更小更快深度优化但难以跟踪调试的release版系统;比如目标CPU是arm还是x86,等等)。

随着设计目的不同、应用领域不同以及程序员团队的偏好不同,这些工具可以是千变万化的。

比如,有些团队喜欢用c/c++而另一些喜欢java;有的领域只有c/c++能做而另一些领域用python开发代价更小;有的团队习惯cmake而另一些选择了qt以及配套的qmake;做网页开发的使用python-django且不需要编译;等等。

使用的开发工具不同,写出来的程序、编译/链接参数以及makefile的写法往往也各不相同。必须所有这些工具配合起来,才能把一套源码正确转换为可以执行的程序。

这一整套工具就是所谓的工具链(tool-chain)。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
ELF文件的加载和动态链接过程
C语言内存中执行外部代码详解(一) | Hoverlees' Blog
Linux内核源码分析
Linux 引导过程内幕
引导过程
图解linux启动过程
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服