在书籍中,我通常会阅读对 Linux 源代码树的引用以及/usr/src/linux
通常的子目录集(arch
、block
、crypto
、 ...)。
我期望这棵树包含组成内核的二进制文件。在我的系统(Ubuntu 10.04)中...
对于我拥有的不同内核(使用自动软件下载,而不是手动安装),我在此位置找到每个内核的两个子目录,如下所示:
/usr/src/linux-headers-2.6.32-22 /usr/src/linux-headers-2.6.32-22-generic
在子目录中,我期望有二进制文件等。但是,我检查了相当多的树,并且这里的最后一个子目录似乎总是有一个
Makefile
(在阅读它时,它听起来通常更像是配置文件,然后是安装文件),偶尔还会有一些独立的其他文件(主要是Kconfig
)。
我的问题可能很幼稚,但我有点困惑。是 (2) 我应该在内核源代码树中看到的内容吗?为什么我要明确引用“标题”?我需要安装linux-generic-headers
一些其他软件,并且不确定这是否相关。我意识到 makefile 有充分的理由(例如,在 /driver 子目录中安装模块),但是(几乎)只有 makefile?
答案1
kernel-header
顾名思义,分发包仅包含构建内核模块等软件所需的内核头文件(加上必要的管道)。
你不应该期望在内核中找到二进制文件来源目录,构建输出除外。 (如果您自己配置和构建内核,则内核源目录还将包含已编译的对象、模块、构建的内核本身以及使其工作的其他一些二进制位和片段。)
KConfig
文件是内核配置选项的描述(及其依赖项)可用于给定的目录/模块。
除此之外,它都是(大部分)C 源代码、头文件和Makefile
s.c 文件。到处都有一些帮助程序脚本,还有汇编源代码。
标头包(你安装的)只包含标头上述的一部分(而不是全部 - 只有“导出的”标头),以及一些构建基础设施。所以你所看到的都是预期的。标头包不要包含 C 源代码(除了一些存根和构建基础设施代码)。拥有这种类型的包的全部目的是节省空间(和带宽)——整个 Linux 内核源代码树相当大,如果您不打算自己编译内核,则完全没有必要。标头包由发行版构建和提供,以提供构建模块所需的正确内容,但仅此而已。 (它们当然不包含已编译的内核。)
解决您的评论:标头包不会重新定位到任何地方。它们是为特定版本的内核构建的,打包在特定的目录中,仅此而已。它只是一组文件。 (请注意,标头包不一定与当前稳定的内核二进制包具有相同的版本 - 标头包是通用的,并且可能落后于您正在运行的实际内核。但是,它们不应该来自内核比当前安装(或目标)内核更新的版本。)
安装的内核二进制文件/boot
通常与引导加载程序二进制文件和配置文件一起安装在该目录中。 (有时这是一个独立的文件系统,默认情况下不安装。)文件的确切名称取决于内核和发行版。 (引导加载程序也是如此。)
安装的内核模块驻留在以下子目录中:
/lib/modules/`uname -r`/
例如在我的系统上,它们目前位于
/lib/modules/3.1.4-gentoo/
完整的内核源代码:在 Ubuntu 上,如果您想要完整的内核源代码来自己构建内核,您应该按照说明进行安装这里。
您还可以从中下载源 tarballkernel.org
并将其解压到某处(执行不是如果您使用此 tarball,请覆盖 Ubuntu 安装的文件,将您的个人内容与 RPM 管理的内容分开)。
/usr/src/linux
是放置内核源代码的传统位置,但没有什么可以阻止您将内核源代码放在其他地方。该路径通常也只是目录的符号链接。例如我的机器上有这个:
$ ls -l /usr/src/linux
lrwxrwxrwx 1 root root 18 Dec 7 17:03 /usr/src/linux -> linux-3.1.4-gentoo
符号链接的作用是简化依赖于内核源代码的应用程序的构建。您将该路径链接到正在运行的(或目标)内核,以便在树外构建模块时不必指定确切的版本或路径信息。至少对基于源代码的发行版有帮助。