配置,编译和安装自定义Linux内核


38

我想尝试使用我的发行版提供的内核以外的内核-从其他地方或由我定制。这困难还是危险?

我从哪里开始?

Answers:


51

构建自定义内核可能很耗时-主要是在配置中,因为现代计算机可以在几分钟内完成构建-但是如果保留当前有效的内核并确保不使用该内核,这并不是特别危险。通过引导加载程序作为选项(请参见下面的第6步)。这样,如果新的不起作用,则只需重启旧的。

在以下说明中,源树中的路径采用形式[src]/whatever[src]您将源安装到的目录在哪里,例如/usr/src/linux-3.13.3。您可能想做这些事情,su root因为源树在写权限方面应该保持安全(它应该归根所有)。

尽管某些步骤是可选的,但您仍应阅读它们,因为它们包含理解其余过程所必需的信息。

  1. 下载并解压缩源压缩包。

    这些可以从kernel.org获得。最新的文件列在首页上,但是如果您查看/pub/目录中的内容,您会发现一个一直到1.0版的档案。除非有特殊原因,否则最好选择“最新稳定版”。在撰写本文时,这是一个74 MB的tar.xz文件。

    下载完压缩包后,您需要将其解压缩到某个地方。正常的地方在/usr/src。将文件放在此处,然后:

    tar -xJf linux-X.X.X.tar.xz
    

    请注意,个别发行版通常建议您使用其源代码包之一而不是香草树。 它包含发行版特定的修补程序,可能对您而言可能无关紧要。它也将与用于编译某些用户空间工具的内核包含标头匹配,尽管它们很可能是相同的。

    在15多年的构建自定义内核(主要在Fedora / Debian / Ubuntu上)中,使用vanilla 1源码从未遇到任何问题。这样做并没有太大的区别,但是,如果您想要绝对最新的内核,则您的发行版可能还没有打包它。 因此,最安全的方法仍然是使用发行版软件包,该软件包应该安装在中/usr/src 我更喜欢最新的马stable,这样我就可以充当豚鼠,然后再投放到发行版中:)

  2. 从基本配置[可选]开始。

    您不必这样做-您可以直接进入并从头开始创建配置。但是,如果您以前从未这样做过,请期待很多尝试和错误。这也意味着必须通读大多数选项(有数百个)。更好的选择是使用现有配置(如果有)。如果使用发行版源程序包,则它可能已经包含一个[src]/.config文件,因此可以使用它。否则,检查/proc/config.gz。这是2.6内核中添加的可选功能。如果存在,请将其复制到源树的顶层,然后单击gunzip -c config.gz > .config

如果不存在,则可能是因为此选项已配置为模块。尝试使用sudo modprobe configs,然后再次检查/proc目录config.gz

从几乎所有可能的硬件驱动程序的角度来看,发行版配置都不是很理想。这与内核的功能无关紧要,因为它们是模块,并且绝大部分模块都不会被使用,但是这极大地增加了构建所需的时间。这也很尴尬,因为它需要一个initramfs来包含某些核心模块(请参阅下面的步骤4)。但是,它可能是比默认值更好的起点。

请注意,配置选项从一个内核版本转移到另一个内核版本,并且在您运行make config以下程序之一时,.config将首先解析并更新您的程序以匹配新版本。如果配置来自较旧的版本,则可能导致奇怪的结果,因此在进行配置时请注意。AFAIK不能完全相反(使用较新版本的配置)。

  1. 创建一个.config小便。

    [src]/.config是用于配置内核的文本文件。 不要直接编辑此文件。更改选项通常不是YN,等替换a的简单问题。通常存在一系列相互依赖和分支的可能性。相反,您要使用内核makefile中的一个配置目标(即,make _____从顶级源目录的命令行中输入):

    • make config是最基本的,但可能不符合大多数人的口味。这是一系列问题- 很多问题-如果您改变主意,则必须重新开始。

    • make oldconfig就像,make config除了,如果您已经有.config以前版本的,将跳过除与新选项有关的问题以外的其他问题。这些仍然有很多,其中大多数与您无关,所以我不建议您这样做。

    • make menuconfig是我(而且我认为大多数其他人)的首选方法。它构建并执行一个TUI界面(可在终端上使用的彩色菜单)。这需要您-dev安装ncurses软件包。除了可以通过/; 访问的seach之外,它是不言自明的。F1“帮助”提供当前选项的说明。有一个替代版本,make nconfig具有一些额外的功能,其中F2“ syminfo”等效于menuconfig的F1。

    • make xconfig是完整的GUI界面。这需要安装Qt qmake-dev软件包,同样,它是一个已编译和构建的程序。如果您以前没有使用过这些功能,则可能需要大量下载。我之所以喜欢menuconfigGUI版本,是因为在前者中使用连续屏幕来显示选项层次结构,而在后者中则使用类似开放手风琴的形式。

    您应该(但不必)要做的第一件事就是添加一个“本地版本”字符串(在General Setup下)。其原因在下面的#5中提到。

    “迷宫式”是描述期权层次结构的一种好方法,对其进行详细介绍远远超出了像这样的问答环节。如果您想坐下来进行所有检查,请预留时间。Greg Kroah-Hartman(Linux内核的长期开发负责人)有一本关于内核的免费在线书(请参阅下面的参考资料),其中包含有关配置的一章,尽管该书是2006年编写的。我的建议是从一个合理的基础开始。从您当前的发行版内核(按照#2)开始,然后遍历它,然后取消选中您不需要的所有内容。您可能还需要将某些“模块”选项更改为“内置”,这将使我们进入下一步。

  2. 关于initramfs[可选]

    “ initramfs”是内置于内核和/或在引导时加载的压缩文件系统。它的主要目的是包含内核访问/lib/modules根文件系统上的模块之前所需的模块,例如,包含该文件系统的设备的驱动程序。发行版总是部分使用这些驱动程序,因为驱动程序相互不兼容,因此不能全部内置在内核中。而是从中选择适合当前系统的系统initramfs

    这很好用,并且没有任何缺点,但是在构建自己的内核时可能是不必要的麻烦。2要注意 的是,如果您不使用initramfs,则需要确保根文件系统(及其所在设备)的驱动程序已内置在内核中。 在中menuconfig,这是M(=模块)选项和*(=内置)选项之间的区别。如果您做不到这一点,则系统将在启动过程中尽早失败。因此,例如,如果您有SATA硬盘和ext4根文件系统,则需要内置驱动程序。[如果有人能想到其他必须要做的事情,请发表评论,我将在此处合并]。

    如果确实要使用initramfs,则必须在常规设置中选择适当的选项。在中有一个框架指南来创建内置于内核的指南[src]/Documentation/filesystems/ramfs-rootfs-initramfs.txt,但是请注意,发行版不这样做。他们使用外部gzip压缩cpio文件。但是,该文档确实包含了有关内容的讨论initramfs(请参阅“ initramfs的内容”)。

  3. 构建并安装内核。

    下一步很容易。要制作内核,只需make[src]目录中运行即可。如果您使用的是多核系统,则可以添加-j N以加快速度,N要使用的专用核数是+1。没有testcheck。完成后,您可以make modules。在快速包装盒上,所有这些操作应少于10分钟。

    如果一切顺利,make INSTALL_MOD_STRIP=1 modules_install。这将创建一个/lib/modules与内核版本号以及第3步中提到的“本地版本”字符串相匹配的目录(如果有)。如果您没有使用“本地版本”字符串,请小心,如果您已经拥有与您依赖的相同版本的内核,因为这些模块将替换那些模块。3 INSTALL_MOD_STRIP=1是可选的,其含义请参见此处

    然后make install,您可以将内核安装到默认位置。不过,我的建议是自己做,以确保不会覆盖现有文件。查找[src]/arch/[ARCH]/boot名为bzImage4的文件,如果您使用的是x86或x86-64机器,[ARCH]则为4x86如果您使用的是其他机器,则为其他)。将其复制到中,/boot然后重命名为更具体,更有用的内容(无论如何)。使用进行相同的操作[src]/System.map,但根据以下方案将其重命名:

    System.map-[VERSION]
    

    这里,[VERSION]完全相同一样在目录中的名称/lib/modules通过创建make modules_install,其中包括“本地版”字符串,如System.map-3.13.3-mykernel

  4. 配置GRUB 2引导程序。

    如果您不使用grub(大多数linux桌面用户在使用),那么这显然不适用于您。您应该有一个/etc/grub.d/40_custom没有太多文件的文件。如果不是,则创建它由root和拥有chmod 755(必须是可执行文件)。加上:

    menuentry 'My new kernel, or whatever' {
        set root='hd0,1'
        linux /boot/[name-of-kernel] root=/dev/sda1 [other kernel options]
    }
    

    如果您使用的是initramfs,则还应该有最后一行initrd /path/to/initramfs。当心set root=线。该示例假定将grub安装在第一个硬盘驱动器(hd0,1)的第一个分区上。如果您有多个驱动器,则可能要改用分区UUID并将该行替换为:

        search --no-floppy --fs-uuid --set=root [the UUID of the partition]
    

    除非grub不在您的根文件系统上,否则它还应该与root=linux行上的指令相对应,该指令指示您的根文件系统(带有/sbin/init和的那个/lib/modules)。的UUID版本是root=UUID=[the UUID]

    您可以查看现有/boot/grub2/grub.cfg设备以获取有关设备名称的线索。这是在grub 2下进行此类操作的简要指南。一旦感到满意,请运行grub2-mkconfig -o /boot/grub2/grub.cfg(但请先备份当前版本grub.cfg)。然后,您可能要编辑该文件并将条目移到顶部。它应该仍然包含旧的(运行)内核的列表,和你的发行版可能有其复制为自动将新内核的条目的机制(因为它是在发现/boot; Fedora的做到这一点,因此,使用不同的冠军,menuentry是一个好主意)。如果一切顺利,您可以稍后将其删除。

    您也可以直接插入menuentrygrub.cfg直接,但是当他们的内核(而使用更新的一些发行版将覆盖这/etc/grub.d/会保持它引入)。

    而已。您现在要做的就是重新启动。如果它不起作用,请尝试从屏幕输出中推断出问题,重新启动以选择旧内核,然后返回步骤3(除非使用.config已经拥有的内核并对其进行调整)。在make clean(或make mrproper)两次尝试之间可能是一个好主意,但请确保先复制[src]/.config到某个备份,因为这将被删除。 这有助于确保构建过程中使用的对象不陈旧。

  5. 关于内核头文件 等

    您可能应该做的一件事是symlink(ln -s -i/lib/modules/X.X.X/source并链接/lib/modules/X.X.X/build/usr/src源树所在的目录(保持该目录)。这是必需的,以便某些用户空间工具(和第三方驱动程序安装程序)可以访问正在运行的内核的源。

    与之相关的一个问题是.h文件中的/usr/include等等。这些文件变化非常缓慢,并且向后兼容。您有两种选择:

    • 保留发行版使用的那些。如果您定期更新整个系统,则发行版仍将定期安装新系统,因此这是“省力”的选项。

    • 使用make headers_install

    由于它们是向后兼容的(意味着“使用较旧的内核标头针对C库构建的程序应在较新的内核上运行”),因此您不必对此太烦躁。如果你建立一个定制的内核,并保持了一段时间,在这段时间内发行版更新的“内核头文件”包到一个唯一的潜在问题将是新的比用于构建您的内核版本,有原来是一些不兼容(仅适用于随后从源代码编译的软件)。

参考文献

以下是一些资源:

  • [src]/README 包括有关构建和安装的简要指南。

  • [src]/Documentation目录包含许多信息,可能对配置有所帮助。

  • Greg KH的书《坚果壳中的Linux内核》(可免费获得,以一系列PDF格式提供)围绕着构建内核。

  • Grub 2拥有在线手册


1.“ Vanilla”是指可在kernel.org上找到的原始,纯正的官方资源。大多数发行版都采用这种原始资源,并添加了一些较小的自定义项。

2.请注意,在某些情况下需要使用initramfs,因为挂载根文件系统需要一些用户空间-例如,如果该文件系统已加密或散布在复杂的RAID阵列中。

3.但是,如果您不构建模块,它不会删除已经存在的模块,这意味着您以后可以通过简单地修改配置并make modules_install再次运行来添加模块。请注意,构建某些模块可能需要更改内核本身,在这种情况下,您还必须替换内核。您将能够知道何时尝试使用modprobe该模块。

4.如果您使用非标准压缩选项,则该文件的名称可能有所不同。我不确定所有可能性是什么。


3
已投票。您可能需要添加localmodconfigstreamline_config.pl脚本等工具的提及。一种从现有设置中工作的有用方法……
jasonwryan 2014年

1
根据@terdon的倡议,这可能足够详细,成为规范的类型问题。考虑为他关于meta的问题提供答案。或者,如果您愿意,我可以。由于您仍然提出了问题,因此这似乎是出于此目的。我认为,包括特定于发行版的方法来构建二进制软件包也将很有用。
Faheem Mitha 2014年

1
仅供参考:initramfs应该几乎总是使用。例如,在LVM + RAID上设置rootfs通常需要一个。加密的根肯定可以。即使是相当复杂的RAID设置也可以。实际上甚至不推荐使用琐碎数组的内核自动组装……
derobert 2014年

2
@derobert:这引起了一个问题,即“几乎总是” Linux被用来运行企业服务器。我对一点initramfs是,如果你没有需要使用一次,你不必,这简化了过程。无论如何,我添加了一个注脚有关加密根文件系统,等等
金发姑娘

请提供有关EFI和linux的efi-stub功能的详细信息。
IW16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.