提问人:MainID 提问时间:1/30/2009 最后编辑:MainID 更新时间:9/18/2013 访问量:17197
Linux 内核如何自我编译?
How can the Linux kernel compile itself?
问:
我不太了解安装时Linux内核的编译过程 我机器上的 Linux 系统。
以下是一些让我感到困惑的事情:
- 内核是用 C 语言编写的,但是如何在没有安装编译器的情况下编译内核呢?
- 如果在编译内核之前在我的机器上安装了 C 编译器,那么如何在没有安装编译器的情况下编译编译器本身?
几天来我很困惑,谢谢你的回复。
答:
你的 Linux 机器的第一轮二进制文件是建立在其他一些 Linux 机器上(可能是)。
第一个 Linux 系统的二进制文件是建立在其他平台上的。
该计算机的二进制文件可以将其根源追溯到在另一个平台上构建的原始系统。
...
如果把这个推得足够远,你会发现编译器是用更原始的工具构建的,而这些工具又是在主机以外的机器上构建的。
...
继续推动,您会发现计算机的构建可以通过在机器前面板上设置开关来输入其指令。
很酷的东西。
规则是“构建工具以构建工具来构建工具......”。非常像运行我们物理环境的工具。也被称为“通过引导将自己拉起来”。
评论
内核本身不会编译 -- 它是由用户空间中的 C 编译器编译的。在大多数 CPU 架构中,CPU 在特殊寄存器中有许多位,这些位表示当前运行的代码具有哪些特权。在 x86 中,这些是代码段 (CS) 寄存器中的当前权限级别位 (CPL)。如果 CPL 位为 00,则代码称为在安全环 0(也称为内核模式)中运行。如果 CPL 位为 11,则代码称在安全环 3(也称为用户模式)中运行。其他两个组合 01 和 10(分别为安全环 1 和 2)很少使用。
关于代码在用户模式和内核模式下可以做什么和不能做什么的规则相当复杂,但可以说,用户模式的权限严重降低。
现在,当人们谈论操作系统的内核时,他们指的是操作系统代码中以内核模式运行并具有提升权限的部分。通常,出于安全原因,内核作者会尽量保持内核尽可能小,因此不需要额外权限的代码就没有这些权限。
C 编译器就是这种程序的一个例子——它不需要内核模式提供的额外权限,因此它像大多数其他程序一样在用户模式下运行。
在 Linux 中,内核由两部分组成:内核的源代码和内核的编译可执行文件。任何带有 C 编译器的机器都可以将内核从源代码编译到二进制映像中。那么,问题是如何处理这个二进制图像。
在新系统上安装 Linux 时,将安装预编译的二进制映像,通常来自物理介质(如 CD DVD)或网络。BIOS 将从介质或网络加载内核的引导加载程序(二进制映像),然后引导加载程序将内核的(二进制映像)安装到您的硬盘上。然后,当您重新启动时,BIOS 会从您的硬盘加载内核的引导加载程序,引导加载程序会将内核加载到内存中,然后您就可以关闭并运行了。
如果你想重新编译自己的内核,这有点棘手,但可以做到。
哪一个先到?先有鸡还是先有蛋?
自恐龙时代以来,蛋就已经存在了。
..有些人混淆了一切,说鸡实际上是巨兽的后代。长话短说:技术(鸡蛋)在当前产品(鸡)之前就已经存在了
你需要一个内核来构建一个内核,即你用另一个来构建一个内核。
第一个内核可以是你想要的任何东西(最好是可以创建你想要的最终产品^__^的明智之物)
Bran 的内核开发教程教你开发和构建一个小型内核,然后你可以用你选择的虚拟机进行测试。
意思是:你在某个地方编写和编译一个内核,然后在一个空的(没有操作系统)的虚拟机上读取它。
这些 Linux 安装所发生的情况遵循相同的想法,但增加了复杂性。
描述这种现象的术语是引导,这是一个有趣的概念。如果你考虑嵌入式开发,很明显,许多需要软件的设备,比如闹钟、微波炉、遥控器,都不够强大,无法编译自己的软件。事实上,这类设备通常没有足够的资源来远程运行任何像编译器一样复杂的设备。
他们的软件是在台式计算机上开发的,然后在编译后进行复制。
如果你对这种事情感兴趣,我想到的一篇文章是:关于信任信任的反思(pdf),这是一本经典而有趣的读物。
评论
我认为你应该区分:
compile, v:使用编译器处理源代码并生成可执行代码 [1]。
和
install, v:连接、设置或准备要使用的东西 [2]。
编译从源代码生成二进制可执行文件。安装只是将这些二进制可执行文件放在正确的位置,以便以后运行它们。因此,如果二进制文件可用,则安装和使用不需要编译。相应地考虑“编译”和“安装”,就像“烹饪”和“服务”一样。
现在,您的问题:
- 内核是用 C 语言编写的,但是如何在没有安装编译器的情况下编译内核呢?
内核不能在没有编译器的情况下编译,但可以从编译的二进制文件安装。
通常,在安装操作系统时,会安装预编译的内核(二进制可执行文件)。它是由其他人编译的。只有当你想自己编译内核时,你才需要源代码和编译器,以及所有其他工具。
即使在像gentoo这样的“基于源代码”的发行版中,你也要从运行一个编译好的二进制文件开始。
所以,你可以不编译内核就过一辈子,因为你让别人编译了它们。
- 如果在编译内核之前在我的机器上安装了 C 编译器,那么如何在没有安装编译器的情况下编译编译器本身?
如果没有内核 (OS),编译器将无法运行。因此,必须安装编译的内核来运行编译器,但不需要自己编译内核。
同样,最常见的做法是安装编译器的编译二进制文件,并使用它们来编译其他任何内容(包括编译器本身和内核)。
现在,先有鸡还是先有蛋的问题。第一个二进制文件是由其他人编译的......查看 dmckee 的出色答案。
它不是一路向下的。就像你说的,你不能在运行该操作系统的系统上编译以前从未编译过的操作系统。同样,至少编译器的第一次构建必须在另一个编译器上完成(如果第一个编译器还不能编译自己的源代码,通常也要进行一些后续构建)。
我认为最早的 Linux 内核是在 Minix 机器上编译的,尽管我不确定这一点。GCC当时可用。许多操作系统的早期目标之一是运行编译器,使其足够好,以编译自己的源代码。更进一步,几乎可以肯定,第一个编译器是用汇编语言编写的。第一批汇编程序是由那些不得不用原始机器代码编写的穷人编写的。
您可能想查看 Linux From Scratch 项目。在书中,你实际上构建了两个系统:一个是建立在你不是自己构建的系统上的“临时系统”,另一个是建立在你的临时系统上的“LFS系统”。按照本书目前的写法,你实际上是在另一个Linux机器上构建临时系统,但理论上你可以调整它,在一个完全不同的操作系统上构建临时系统。
如果我正确理解了你的问题。如今,内核并没有“自行编译”。如今,大多数 Linux 发行版都通过 linux live cd 提供系统安装。内核从 CD 加载到内存中,并像往常一样运行,就像安装到磁盘上一样。在您的系统上启动并运行 linux 环境后,只需将必要的文件提交到磁盘即可轻松。
如果你在谈论引导问题;DMCKEE总结得很好。
只是提供了另一种可能性......
评论