因此,您已经决定尝试一下您听到别人谈论的这个事情,称为“编译自定义内核”。如果您是业余爱好,或者想要学习新技能,那就很好-继续阅读。
但是,在开始之前,我们将尝试解释何时出现这种需要的情况以及如何处理它。请注意,这是一门广泛的主题,在空间方面比我们在此提供的更多。您将学习基础知识,需要的知识,要做的事情和将要实现的目标。
有关更多信息,与往常一样,Google是您的朋友;同样,驻留在内核源代码树中的文档将回答很多问题。因此,让我们从头开始,最后一点:如果需要,我们将发布更多与内核发行版有关的文章,这些文章与其他发行版有关。
什么时候需要编译自己的内核
第一种情况是您需要比发行版提供的内核更高的内核,尤其是当您运行稳定的发行版(例如Debian稳定版,CentOS)时,因为您的内核不支持所需的某些功能/驱动程序,或者仅仅是因为您觉得您想尝试最新和最好的。
但是,警告:如果要运行bleeding-edge内核,请确保它与系统的其他关键组件(例如glibc)兼容,请记住,更新的版本意味着较少的测试,并且(可能)更加不稳定;您的发行版的内核维护者通常会很好地将某些新功能向后移植到较旧的,更稳定的内核,因此请确保您确实需要bleeding-edge。我们的建议是不要在生产系统上使用这些内核(长期内核在这里会例外)。如前所述,请信任您发行版的维护者。
第二种情况是您觉得自己正在运行一个a肿的内核,不需要许多组件。尽管内核仅加载与现有硬件相匹配的模块,但是内核较小的内存占用通常有助于提高速度和启动时间。
# lspci -vv
# lsusb
# hwinfo
# cat /proc/cpuinfo
上面的命令可以帮助您更好地了解您的硬件。写下您发现的内容,并确保您以超级用户身份运行上述ls *命令,以获取更多信息。
另一种情况是您想通过在系统上运行最新版本来帮助测试内核。与上述警告同样适用:在测试系统上执行此操作,请在发现错误时与上游保持联系(lkml.org是主要的内核邮件列表–高访问量),并在询问信息时尝试尽可能提供帮助强调起来很困难:请阅读文档,因为您发现自己处于令人讨厌的境地,想要报告错误或只是有疑问。
接下来,您可能想成为一个很酷的孩子,并运行最新,最出色的软件,也许浏览一下源代码(前提是您了解此知识并且您具有C和ASM知识),甚至提交补丁。如果您的发行版还没有提供较新的内核包,那么您可能要先看一下,例如,如果您更改了sources.list,则可以在测试系统上安装Debian Experiment的内核。同样,如果您发现错误,请与维护人员合作。
术语
在深入研究这个有点神秘的主题之前,我们应该弄清楚一些基本术语。这对于理解内核测试和编译的关键部分至关重要。
- 核心 –操作系统的核心,负责管理硬件资源(I /O,网络,CPU,内存…)。基本上,它是操作系统中负责所有脏活的基本部分。用户程序与内核通信,并通过系统库请求CPU时间或其他资源,这些系统库充当用户区(请参见下文)与内核/硬件之间的中介。内核可以是整体的,也可以是微内核(有关更多信息,如果您感兴趣,请参阅Wikipedia.org上的Kernel-wide设计方法。微内核(如Minix)使用一种将内核与内核其余部分分开的设计方案。分为各个组件,每个组件执行特定的工作:I /O,网络等。顾名思义,单片内核(Linux,BSD,Solaris)包含一个单元中的大部分内核,并提供了额外的功能(例如驱动程序)也有混合内核,两者结合在一起,Windows内核就是一个很好的例子。
- 用户区-操作系统中不属于内核的所有内容(库,应用程序)都被称为用户区的一部分。这个名字很明显。
- 模块-如前所示,内核模块是一个二进制软件,基本上可以”teaches”内核如何使用一块硬件来”talk”或提供一些功能(例如nfs)
- 编译器-编译器是一个应用程序,它基本上采用您从kernel.org下载的书面代码,然后将其转换为二进制文件。在Linux发行版中找到的编译器称为’gcc’,它代表GNU编译器集合,它也需要构建软件必不可少的组件:在binutils中找到的实用程序,例如汇编程序(as)或库归档程序(ar)。 ,您可以通过安装并运行apt-file来找到文件所属的软件包。说到这一点,让我们看看要成功构建内核,需要安装哪些软件包。
- 香草仁-这是用于上游内核的名称,可以在kernel.org上找到,因此没有distro-specific补丁。
请注意,只要您在本文档中看到以提示符开头的命令‘$’这意味着该命令将必须以普通的日常用户运行;每当你看到‘#’提示,这意味着该命令将以root身份运行(我们使用sudo,但这不是强制性的)。除非另外指定,否则当前目录是保存您的源树的目录,在本例中为linux-2.6。
您需要安装什么
- gcc-当然,编译器必不可少
- binutils-该软件包包含链接器,汇编器和其他实用程序,这些实用程序对于编译用C编写的程序至关重要。
- gcc-doc-gcc的手册和信息页。如果您想变脏并修改一些编译标志,则很有用。无论如何,如果您想编写或编译C程序包,它很有用。
- gdb-GNU调试器。不是强制性的,但在出现问题时很有用。 Gdb-doc也将提供帮助。
- libreadline5-dev-用于使用基于ncurses的内核配置接口。您可以使用其他界面(请参见下文)。
- make-将作为依赖项安装,但顺序不多。请查阅手册或书籍,因为在如此短的空间内这不是一个轻描淡写的主题。 Make是在编译C /C++程序时使用的实用程序,它的作用是在Makefile中查找该文件,其中包含有关应如何进行构建以及以何种顺序进行构建并尝试执行这些指令的规则。阅读源代码树中的Makefile以获得一瞥。
- git-Git是一个VCS(版本控制系统),可以执行cvs或subversion的工作,即使up-to-date拥有最新的内核树。
获取内核源
如果要从发行版安装源,请使用
# apt-get install linux-source-<version>
可以从哪里收集发行信息:
uname -r
如果要修改现有内核(添加驱动程序,修整等),请使用此选项。否则,您需要香草内核。您可以从www.kernel.org上获得它(我们建议使用wget或curl作为下载管理器),或者,如果您想要最新的版本,则可以使用git。我们建议将源存储在用户的主目录中,获取最新主线树的命令是(请参见man git):
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git linux-2.6
过去,我们在http://linux.yyz.us/git-howto.html上发现了mini-howto很有用;还可以查看kernelnewbies.org。上面的命令将在您当前的目录中创建一个名为linux-2.6的文件夹,稍后可以通过将其复制到CD并发出一个简单的文件夹来进行更新
make clean; git pull
现在,在获得源代码之后,我们将必须配置内核。
配置和构建
如果您有一个现有的.config文件(该文件包含用于内核构建的选项–可以输入什么内容,哪些不可以),则将其复制到linux-2.6中(从/boot /config-或/proc/config.gz –当前配置)。如果您不想修改现有的.config,只需发出
$ make oldconfig
否则,请继续阅读。如果要修改现有配置,请发出
$ make menuconfig
(建议:您可以使用make config来解决有关内核中选项的许多问题,也可以使用make xconfig来获取更好的图形菜单,而make xconfig则需要qt库,以获得更好的图形菜单),然后选择“加载备用配置文件”,然后按Enter键以获取.config ,配置文件的默认名称,或输入已经保存在linux-2.6中的备用文件名。
之后,开始浏览菜单以进行必要的更改。这里的经验法则是“如果您不知道它的作用,请不要混淆它”,至少要等到您有经验的时候再进行。最后,从顶部菜单中选择“保存备用配置文件”,按Enter键输入默认名称(.config –推荐),然后从下面按”Exit”。如果您想从头开始,请忽略“加载备用配置文件”步骤,然后继续。在下一个内核编译时,在清理和更新树后,使用上述’make oldconfig’来使用旧配置。好的,现在我们可以根据自己的需求量身定制配置了,只需等待构建。构建内核就像配置它一样简单(!)。只需键入make,输出将如下所示:
$ make
HOSTCC scripts/basic/fixdep
HOSTCC scripts/kconfig/conf.o
SHIPPED scripts/kconfig/zconf.tab.c
SHIPPED scripts/kconfig/zconf.lex.c
SHIPPED scripts/kconfig/zconf.hash.c
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/conf
CHK include/linux/version.h
UPD include/linux/version.h
CHK include/generated/utsrelease.h
UPD include/generated/utsrelease.h
CC kernel/bounds.s
GEN include/generated/bounds.h
CC arch/x86/kernel/asm-offsets.s
...
然后,根据您的机器和内核配置,将完成此操作。如果您想加快速度,请使用-jn标志,其中n是处理器/核心数+1。但是请注意,这可能会暴露内核中的错误或构建基础结构,因此如果出现问题,请使用不带任何标志的make重试。如果在阅读了gcc手册之后(如果您仍然很理智),您感到冒险并且想要修改一些hardware-specific标志,或者想优化代码,请使用make手册页来查找操作方法(主要是COPTS和CFLAGS)。但是,大于-O2的优化是有风险的。
小心并预期会损坏,内核可以毫无问题地进行编译,但是它可能表现得很奇怪。请记住以普通用户身份键入所有命令。无需以root用户身份进行构建,内核开发人员对此想法并不满意。
安装
现在让我们安装模块:由于模块安装在/lib中,并且普通用户没有写访问权限,因此需要以root用户身份完成。所以,
# make modules_install
这样做就可以了,这需要在安装内核之前完成,以便模块和已安装的内核保持同步。采用
# make install
将内核安装到/boot,然后
# depmod
并准备创建initramfs(初始RAM文件系统),它是在启动初期阶段加载到RAM的临时文件系统,用于提供基本的驱动程序和其他功能,以便挂载根文件系统。可以在Wikipedia的Initrd页面上找到更多信息。该任务所需的命令是update-initramfs(在安装新内核时,由程序包管理器触发该命令),该命令可以创建一个initramfs(-c)或更新一个现有的(-u)。完整的命令是
# update-initramfs -c -k
版本是您在’make modules_install’完成后将看到的版本(其输出的最后一行将是”DEPMOD”)。如果您想要确切且更长的版本号,则可以告诉开发人员您使用了什么“git moment”,请选择”General Setup”→“自动”发出menuconfig后,将版本信息附加到版本字符串中。我的Ubuntu系统上的输出如下所示:
update-initramfs: Generating /boot/initrd.img-3.1.0-rc3+
...
更新您的Grub,使它注意到您的新内核
# update-grub
在我的Debian测试机上,输出如下所示:
Generating grub.cfg ...
Found background image: /usr/share/images/desktop-base/desktop-grub.png
Found linux image: /boot/vmlinuz-3.0.0-1-amd64
Found initrd image: /boot/initrd.img-3.0.0-1-amd64
Found linux image: /boot/vmlinuz-3.0.0-rc6-amd64
Found initrd image: /boot/initrd.img-3.0.0-rc6-amd64
Found linux image: /boot/vmlinuz-2.6.39-07727-gbd1bfe4
Found initrd image: /boot/initrd.img-2.6.39-07727-gbd1bfe4
Found linux image: /boot/vmlinuz-2.6.39-2-amd64
Found initrd image: /boot/initrd.img-2.6.39-2-amd64
Found linux image: /boot/vmlinuz-2.6.39-rc7-amd64
Found initrd image: /boot/initrd.img-2.6.39-rc7-amd64
Found linux image: /boot/vmlinuz-2.6.38.5
Found initrd image: /boot/initrd.img-2.6.38.5
Found linux image: /boot/vmlinuz-2.6.38.4-00001-gfaa8ee7
Found initrd image: /boot/initrd.img-2.6.38.4-00001-gfaa8ee7
Found linux image: /boot/vmlinuz-2.6.38.4
Found initrd image: /boot/initrd.img-2.6.38.4
Found linux image: /boot/vmlinuz-2.6.38-2-amd64
Found initrd image: /boot/initrd.img-2.6.38-2-amd64
Found linux image: /boot/vmlinuz-2.6.32-5-amd64
Found initrd image: /boot/initrd.img-2.6.32-5-amd64
Found memtest86+ image: /memtest86+.bin
Found memtest86+ multiboot image: /memtest86+_multiboot.bin
done
当然,您的输出看起来不会完全一样,但是轮廓应该是一样的。最后,请记住:如果需要,请在update-grub之前编辑/etc /default /grub更改一些选项,然后用手指交叉,重新引导计算机以测试新内核。
如果出问题了
当您的新内核不可用时,最常见的情况是您无法首先启动它,或者它无法启动,并且没有某些必要的驱动程序(例如,网络驱动程序)。通常,update-grub在编写grub菜单文件方面做得很好,但是无论如何您可能都想签出来。如果您通过了grub,则很可能会过分狂热,淘汰出系统的基本驱动程序,例如disk-related部件(ATA,SATA,SCSI …),或者如果您拥有NFS-mounted根,则可能是NFS。使用Google和可能的其他来源(例如IRC)引导可用的内核并对其进行重新配置。
过去曾经有人偶然发现您的问题,您就有机会找到答案。如果问题更严重,并且您有信心阅读有关网络礼节以及如何将其发布到内核邮件列表的信息,请很好地询问。那里有很多乐于助人和乐于助人的人,但是当您没有完成作业和/或浪费他们的时间时,他们往往是not-so-nice。如果您有单独的/boot,请记住,它通常不是很大,并且可能很快被内核填满。此外,/lib /modules往往会在/中积累大量空间,因此请确保不时进行一些清理。请记住,内核是一个复杂的软件,许多原因可能是问题的根源。如果您没有任何困难,可以按照本指南进行操作高级Linux内核配置。