gol*_*cks 39 compiling linux-kernel
我想尝试使用我的发行版提供的内核以外的内核——或者来自其他地方,或者是我定制的。这是困难还是危险?
我从哪里开始?
gol*_*cks 53
构建自定义内核可能很耗时——主要是在配置中,因为现代计算机可以在几分钟内完成构建——但是如果您保留当前的工作内核并确保离开它,这并不是特别危险作为通过引导加载程序的选项(请参阅下面的第 6 步)。这样,如果你的新的不起作用,你可以重新启动旧的。
在以下说明中,源代码树中的路径采用形式[src]/whatever
,其中[src]
是您将源代码安装到的目录,例如/usr/src/linux-3.13.3
. 您可能想要做这些事情,su root
因为源树在写权限方面应该保持安全(它应该由 root 拥有)。
虽然有些步骤是可选的,但您无论如何都应该阅读它们,因为它们包含理解过程其余部分所需的信息。
下载并解压源 tarball。
这些可以从kernel.org 获得。最新版本列在首页上,但如果您查看/pub/
目录内部,您会发现一个归档文件一直追溯到 1.0 版。除非您有特殊原因,否则最好选择“最新稳定版”。在撰写本文时,这是一个 74 MB 的tar.xz
文件。
下载 tarball 后,您需要将其解压缩到某处。正常的地方是在/usr/src
。将文件放在那里,然后:
tar -xJf linux-X.X.X.tar.xz
Run Code Online (Sandbox Code Playgroud)
请注意,个别发行版通常建议您使用它们的源包之一,而不是香草树。 这包含发行版特定的补丁,这对您来说可能重要也可能无关紧要。它还将匹配用于编译一些用户空间工具的内核包含头文件,尽管它们很可能是相同的。
在 15 年多的构建自定义内核(主要是在 Fedora/Debian/Ubuntu 上)中,我从未在使用 vanilla 1源时遇到问题。然而,这样做并没有太大的区别,除了如果您想要绝对最新的内核,您的发行版可能还没有打包它。 所以最安全的方法仍然是使用发行版包,它应该安装到/usr/src
. 我更喜欢最新的稳定版,所以我可以在它推出到发行版之前充当豚鼠:)
从基本配置开始 [可选]。
您不必这样做——您可以直接进入并从头开始创建配置。但是,如果您以前从未这样做过,请期待大量的反复试验。这也意味着必须通读大多数选项(有数百个)。更好的选择是使用您现有的配置(如果可用)。如果您使用了发行版源包,它可能已经包含一个[src]/.config
文件,因此您可以使用它。否则,请检查/proc/config.gz
. 这是 2.6 内核中添加的可选功能。如果存在,将其复制到源树的顶层和gunzip -c config.gz > .config
.
如果它不存在,可能是因为这个选项被配置为一个模块。尝试sudo modprobe configs
,然后再次检查/proc
目录config.gz
。
发行版配置不是很理想,因为它包含几乎所有可能的硬件驱动程序。这对内核的功能没有多大影响,因为它们是模块,并且其中的大多数永远不会被使用,但是它非常显着地增加了构建所需的时间。它也很尴尬,因为它需要一个 initramfs 来包含某些核心模块(参见下面的第 4 步)。但是,它可能是比默认值更好的起点。
请注意,配置选项会从一个内核版本转移到下一个内核版本,并且当您运行make config
以下程序之一时,您.config
将首先被解析和更新以匹配新版本。如果配置来自一个非常旧的版本,这可能会导致奇怪的结果,所以在进行配置时要注意。AFAIK 它根本无法正常工作(使用较新版本的配置)。
创造一个时代.config
。
[src]/.config
是用于配置内核的文本文件。 不要直接编辑这个文件。更改选项通常不是将 a 替换为Y
anN
等的简单问题;通常有一组相互依赖和分支的可能性。相反,您想使用内核 makefile 中的配置目标之一(意思是,make _____
从顶级源目录在命令行上输入):
make config
是最基本的,但可能不符合大多数人的口味。这是一系列问题——很多问题——如果你改变主意,你必须重新开始。
make oldconfig
就像make config
除了,如果您已经有.config
以前版本的一个,将跳过与新选项有关的问题以外的问题。仍然可能有很多这些,其中大部分与您无关,所以我不推荐它。
make menuconfig
是我(我认为大多数其他人)的首选方法。它构建并执行一个 TUI 界面(将在终端上工作的彩色菜单)。这要求您-dev
安装了 ncurses的包。除了可以通过以下方式访问的搜索之外,它是不言自明的/
;F1“帮助”提供了当前选项的解释。有一个替代版本,make nconfig
具有一些额外的功能,其中 F2 "syminfo" 相当于 menuconfig 的 F1。
make xconfig
是一个完整的 GUI 界面。这需要安装 Qtqmake
的-dev
包,同样,它是一个编译和构建的程序。如果您以前没有使用过这些,那可能需要大量下载。我更喜欢menuconfig
GUI 版本的原因是,在前者中使用连续屏幕显示选项层次结构,而在后者中使用类似手风琴的打开方式。
您应该(但不必)做的第一件事是添加一个“本地版本”字符串(在General Setup 下)。原因在下面的#5 中提到。
“迷宫”是描述选项层次结构的好方法,详细了解它远远超出了像这样的问答的范围。如果您想坐下来完成所有事情,请留出数小时。Greg Kroah-Hartman(Linux 内核的长期领导开发人员)有一本关于内核的免费在线书籍(请参阅下面的参考资料),其中包含有关配置的一章,尽管它是在 2006 年编写的。我的建议是从一个合理的基础开始从您当前的发行版内核(按照 #2),然后通过它并取消选中您知道不需要的所有内容。您可能还想将一些“模块”选项更改为“内置”,这将我们带到下一点......
关于initramfs
[可选]
“initramfs”是内核中内置和/或在启动时加载的压缩文件系统。它的主要目的是包含内核在访问/lib/modules
根文件系统中的模块之前需要的模块——例如,包含该文件系统的设备的驱动程序。发行版总是部分地使用这些,因为驱动程序是相互不兼容的,因此不能全部内置到内核中。相反,适合当前系统的那些是从initramfs
.
这很有效并且不代表任何缺点,但是在构建自己的内核时它可能是不必要的复杂化。2 问题 是,如果您不使用 initramfs,则需要确保根文件系统(及其所在设备)的驱动程序已内置到内核中。 在 中menuconfig
,这是M
(= 模块)选项和*
(= 内置)选项之间的区别。如果您没有做到这一点,系统将在引导过程的早期失败。因此,例如,如果您有一个 SATA 硬盘和一个 ext4 根文件系统,那么您需要内置驱动程序。[如果有人能想到任何其他必须具备的东西,请发表评论,我会在这里合并]。
如果确实要使用initramfs
,则必须在“常规设置”中选择适当的选项。有一个骨架引导到创建一个内置于内核中[src]/Documentation/filesystems/ramfs-rootfs-initramfs.txt
,但要注意的是,发行版不这样做; 他们使用外部 gzipped cpio 文件。但是,该文档确实包含了关于应该放入什么内容的讨论initramfs
(请参阅“initramfs 的内容”)。
构建并安装内核。
下一步很容易。要制作内核,只需make
在[src]
目录中运行即可。如果您使用的是多核系统,则可以添加-j N
以加快速度,其中N
是您要专用的内核数 + 1。没有test
或check
。完成后,您可以make modules
。在快速盒子上,所有这些都应该花费 < 10 分钟。
如果一切顺利,make INSTALL_MOD_STRIP=1 modules_install
. 这将创建一个/lib/modules
与内核版本号以及步骤 3 中提到的“本地版本”字符串(如果有)相匹配的目录。如果您没有使用“本地版本”字符串,请注意您是否已经拥有与您依赖的版本相同的内核,因为这些模块将替换那些。3 INSTALL_MOD_STRIP=1
是可选的,意义见这里。
然后您可以make install
将内核安装到默认位置。不过,我的建议是自己做,以确保现有文件不会被覆盖。查找[src]/arch/[ARCH]/boot
名为bzImage
4的文件,如果您使用的是 x86 或 x86-64 机器(如果您使用其他机器,[ARCH]
则查找x86
其他文件)。将其复制/boot
并重命名为更具体和信息量更大的内容(无关紧要)。对 做同样的事情[src]/System.map
,但根据以下方案重命名:
System.map-[VERSION]
Run Code Online (Sandbox Code Playgroud)
这里,[VERSION]
是完全相同一样在目录中的名称/lib/modules
通过创建make modules_install
,其中包括“本地版”字符串,如System.map-3.13.3-mykernel
。
配置 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]
}
Run Code Online (Sandbox Code Playgroud)
如果您使用的是 initramfs,您还应该有最后一行initrd /path/to/initramfs
。当心set root=
线路。该示例假定 grub 安装在第一个硬盘驱动器 (hd0,1) 的第一个分区上。如果您有多个驱动器,您可能希望改用分区 UUID 并将该行替换为:
search --no-floppy --fs-uuid --set=root [the UUID of the partition]
Run Code Online (Sandbox Code Playgroud)
除非 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
是一个好主意)。如果一切顺利,您可以稍后将其删除。
您也可以直接将其menuentry
插入grub.cfg
,但某些发行版会在其内核更新时覆盖它(而 using/etc/grub.d/
将保持其合并)。
就是这样。您现在需要做的就是重新启动。如果它不起作用,请尝试从屏幕输出中推断出问题,重新启动并选择旧内核,然后返回到第 3 步(使用.config
您已有的内核并对其进行调整)。在尝试之间make clean
(或make mrproper
)可能是个好主意,但请确保先复制[src]/.config
到某个备份,因为这会被删除。 这有助于确保构建过程中使用的对象不会过时。
关于内核头文件等。阿尔。
有一件事你应该做很可能是符号链接(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 Kernel in a Nutshell》一书(作为一系列 PDF 免费提供)的大部分内容都围绕着构建内核展开。
Grub 2 有一个在线手册。
1. “Vanilla”是指在 kernel.org 上找到的原始、纯正的官方来源。大多数发行版都采用这个香草源并添加一些小的自定义。
2. 请注意,在某些情况下需要 initramfs,因为需要一些用户空间来安装根文件系统——例如,如果它是加密的,或者分布在复杂的 RAID 阵列中。
3. 如果您没有构建它们,它不会删除已经存在的模块,但是,这意味着您可以稍后通过简单地修改配置并make modules_install
再次运行来添加模块。请注意,构建某些模块可能需要更改内核本身,在这种情况下,您还必须更换内核。您将能够判断何时尝试使用modprobe
插入模块。
4. 如果您使用了非标准的压缩选项,则此文件的名称可能有所不同。我不确定所有的可能性是什么。
归档时间: |
|
查看次数: |
25639 次 |
最近记录: |