Answers:
构建自定义内核可能很耗时-主要是在配置中,因为现代计算机可以在几分钟内完成构建-但是如果保留当前有效的内核并确保不使用该内核,这并不是特别危险。通过引导加载程序作为选项(请参见下面的第6步)。这样,如果新的不起作用,则只需重启旧的。
在以下说明中,源树中的路径采用形式[src]/whatever
,[src]
您将源安装到的目录在哪里,例如/usr/src/linux-3.13.3
。您可能想做这些事情,su root
因为源树在写权限方面应该保持安全(它应该归根所有)。
尽管某些步骤是可选的,但您仍应阅读它们,因为它们包含理解其余过程所必需的信息。
下载并解压缩源压缩包。
这些可以从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,这样我就可以充当豚鼠,然后再投放到发行版中:)
从基本配置[可选]开始。
您不必这样做-您可以直接进入并从头开始创建配置。但是,如果您以前从未这样做过,请期待很多尝试和错误。这也意味着必须通读大多数选项(有数百个)。更好的选择是使用现有配置(如果有)。如果使用发行版源程序包,则它可能已经包含一个[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
是用于配置内核的文本文件。 不要直接编辑此文件。更改选项通常不是Y
用N
,等替换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
软件包,同样,它是一个已编译和构建的程序。如果您以前没有使用过这些功能,则可能需要大量下载。我之所以喜欢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
,但是请注意,发行版不这样做。他们使用外部gzip压缩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]
则为4(x86
如果您使用的是其他机器,则为其他)。将其复制到中,/boot
然后重命名为更具体,更有用的内容(无论如何)。使用进行相同的操作[src]/System.map
,但根据以下方案将其重命名:
System.map-[VERSION]
这里,[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]
}
如果您使用的是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
是一个好主意)。如果一切顺利,您可以稍后将其删除。
您也可以直接插入menuentry
到grub.cfg
直接,但是当他们的内核(而使用更新的一些发行版将覆盖这/etc/grub.d/
会保持它引入)。
而已。您现在要做的就是重新启动。如果它不起作用,请尝试从屏幕输出中推断出问题,重新启动以选择旧内核,然后返回步骤3(除非使用.config
已经拥有的内核并对其进行调整)。在make clean
(或make mrproper
)两次尝试之间可能是一个好主意,但请确保先复制[src]/.config
到某个备份,因为这将被删除。 这有助于确保构建过程中使用的对象不陈旧。
关于内核头文件 等
您可能应该做的一件事是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.如果您使用非标准压缩选项,则该文件的名称可能有所不同。我不确定所有可能性是什么。
initramfs
应该几乎总是使用。例如,在LVM + RAID上设置rootfs通常需要一个。加密的根肯定可以。即使是相当复杂的RAID设置也可以。实际上甚至不推荐使用琐碎数组的内核自动组装……
initramfs
是,如果你没有需要使用一次,你不必,这简化了过程。无论如何,我添加了一个注脚有关加密根文件系统,等等
localmodconfig
对streamline_config.pl
脚本等工具的提及。一种从现有设置中工作的有用方法……