原创——编译全部版本的Linux内核并可用——x86_64架构,2.6.7-3.1.4

jackyjkchen 2011-12-05 08:46:33
5月份的时候我做了LFS,当时第一次做,严格按照文档的步骤,做了4个i386的版本(6.8,6.4,6.3,6.1.1),没有加自定义的优化,基本没有定制,实验性的装了多个内核,基本上如果遇到编译错误和运行问题也就放弃了。

11月份,利用闲暇我决定做x86_64的LFS,而且像Gentoo那样加上优化,还想换掉x86
_64架构那个讨厌的x86_64-unknown-linux-gnu(也搞定了),另外,我希望能够以纵向的方式直观了解Linux内核的发展,这个方式就是支持x86_64架构的Linux内核全部编译一遍,并可用(版本跨度2.4.20-3.1.4),当然,使用最少的LFS版本(也就是说想方设法让一个LFS版本容纳更多的内核版本)。

一个最偷懒的方式就是用较低版本的LFS,通常低版本能安装高版本内核(2.4内核的RH9都能安装Linux 3.x),但那就没意思了。我的做法是“降级”,先用高版本LFS,逐渐降级内核,遇到能解决的问题就解决,直到遇到解决不了的问题才换低版本LFS继续

这篇文章的重点不是LFS教学,LFS的部分我以前发过3篇,不赘述,这里只着重内核部分。我也没严格按照LFS文档做,比如某些软件包我升级了(一定要小心,升级前要多去了解主要软件包尤其是工具链的特性变化,有可能高一个版本就会导致失败),而且LFS 6.4之前文档时不支持x86_64的,需要从LFS 6.5以后参考一些信息

1.LFS 7.0 x64 (安装内核2.6.28.10 ~ 3.1.4)

构建环境,列举内核,工具链和udev版本,这是决定内和适应性的关键软件包

原始软件包版本:Linux 3.1,gcc 4.6.1,binutils 2.21.1a,glibc 2.14.1,udev-173,etx3文件系统

我使用的版本:Linux 3.1.4,gcc 4.6.2,binutils 2.21.1a,glibc 2.14.1,udev-173,ext4文件系统

为了编译低版本Linux安装在/opt的额外工具链软件:gcc 4.5.3,gcc 4.4.6,make 3.81

大部分软件包的优化选项:-march=core2 -mtune=corei7 -pipe -O2(参考gentoo文档,不要去做文档中抨击的那些“装B”和为了吹牛资本的人,从优化选项优化软件这四个参数足矣),glibc可以用-O3,binutils和gcc不用优化选项,gmp/mpfr/mpc会自动检测机器(比较准,认出corei或core2),grub2用-Os替换-O2(否则会导致模块过大),还有一些软件包需要微调,原则是默认编译选项不是通用的-g -O2的,最好不要乱动,最多加上架构,尤其默认是Os的一定不要用O2。

LFS 7.0发布不久,软件包基本是最新的,Linux小版本号众所周知无所谓,只是bug修复,gcc升级的原因是4.6相对以前版本改动较大,必然引入很多bug,4.6.2修复了4.6.1有100多个bug,觉得4.6.2更靠谱,其实gcc第三个小版本号也是bug修复,基本不影响LFS构建成功率,其他版本的gcc我也用了最高的bug修复版本。
文件系统使用保守是LFS的一贯特点,我用了ext4,但这会导致内核适应性的的下降,事实证明,最后只能降级到2.6.28的直接原因就是因为ext4文件系统。
udev是另一个重要的影响低版本内核的软件包,他是linux内核组开发的,和内核关联紧密,udev173文档说明要2.6.34以上内核,不过2.6.32这个长期支持版(Debian、RHEL、SELS、ubuntu lts都在用,有史以来为稳定的、企业发行版集中度最高的内核版本)也明确说明支持。经过实际试验,向下到2.6.28.10和2.6.27.59(这个也是长期支持版,看修订号)都可以,而2.6.27不支持ext4,所以不能使用。

安装在/opt的额外工具链软件是因为gcc 4.6.2不能编译多个版本的内核的原因,下面列出2.6.28-3.1.4经过我的实际测试所支持的最高gcc版本
3.1.4 4.6.2
3.0.12 4.6.2
2.6.39.4 4.6.2
2.6.38.8 4.6.2
2.6.37.6 4.5.3 4.6.2编译失败
2.6.36.4 4.5.3 4.6.2编译失败
2.6.35.14 4.6.2
2.6.34.10 4.5.3 4.6.2编译失败
2.6.33.20 4.6.2
2.6.32.49 4.6.2
2.6.31.14 4.4.6 4.5.3生成内核不可用
2.6.30.10 4.4.6 4.5.3生成内核不可用
2.6.29.6 4.4.6
2.6.28.10 4.4.6

2.6.28的Makefile使用旧语法,需要低一版的make,make 3.81和make 3.82差了4年,区别很大的,当然,你也可以直接改Makefile,改两行,删掉两个%就行

除此之外,2.6.28.10 2.6.29.6 2.6.30.10 2.6.31.14 2.6.36.4都有一个x86_64的bug导致编译失败,其他更新的版本或长期支持版本已经修复,在arch/x86/kernel/entry_64.S,1300行左右,一个宏汇编函数的入口和出口名称不一致,把do_hypervisor_callback改成xen_do_hypervisor_callback即可。或者配置内核的时候别选xen支持

附加推荐安装的软件包(不在lfs文档内)
gpm 控制台鼠标
sudo 不解释
dosfsutils 支持fat文件系统
freetype 有了之后grub2才可以现实背景和高分辨率,安装那么多内核,grub菜单分辨率太小是很恶心的
unifont freetype和grub高分辨率需要

总体来说,2.6.28和2.6.29没事最好别用,他们的ext4刚刚起步,2.6.28早期版本(如ubuntu 9.04的测试版),ext4经常丢数据!虽说2.6.28.10号称已经修复了许多ext4的bug,但还是不放心
2.6.30和2.6.31会有计时不太准等小问题
2.6.32以上非常稳定

内核定制不是本文的主旨,不多说,不想麻烦的直接用著名发行版的config文件,ide硬盘,反正我不怕折腾,用scsi硬盘然后定制了一个最小内核,编译只要5分钟。

如果你原意用initrd,移植initrdramfs工具挺麻烦,有klibc、busybox等一堆依赖,直接用Debian的initrd工具可以生成并能够使用


2.LFS 6.6 x64 (安装内核2.6.16.62 ~ 2.6.27.59,外加2.6.32)

根据LFS 7.0内核安装的情况,下一级LFS版本应该在6.5左右,6.4~6.6(内核2.6.27、2.6.30、2.6.32)软件包版本差别不太大,我就直接用了最高的6.6

原始软件包版本:Linux 2.6.32.8,gcc 4.4.3,binutils 2.20,glibc 2.11.1,udev-151,etx3文件系统

我使用的版本:2.6.32.49,gcc 4.4.6,binutils 2.20.1a,glibc 2.11.3,udev-135,ext3文件系统

为了编译低版本Linux安装在/opt的额外工具链软件:gcc 4.3.6,gcc 4.2.4

大部分软件包的优化选项:-march=core2 -mtune=core2 -pipe -O2,gcc 4.4不支持corei7,其它的注意事项和LFS 7.0一样

基本上,LFS 6.6的工具链我都把bug修复小版本升级到最高,对构建没什么影响,从下一个版本开始,我有了经验就开始乱来了,这是后话。

udev降级了,因为如果仍使用udev151,最低只能到2.6.24左右,我降到了udev-135,标称支持到2.6.19,实际测试能支持2.6.16.62(这个也是长期支持版,看修订号)。

Linux 2.6内核在2.6.2x阶段机制变化极大,2.6.3x直接叫3.x比现在的那个所谓的3.x更有说服力!所以LFS 6.6编译多个内核遇到的麻烦比LFS 7.0更多。

首先是gcc版本,还是一样,列个表,别超出表中的限制
2.6.27.59 4.4.6
2.6.26.8 4.4.6
2.6.25.20 4.4.6
2.6.24.7 4.3.6 4.4.6编译失败,当然你去掉那个失败的模块也能成功
2.6.23.17 4.3.6
2.6.22.19 4.3.6
2.6.21.7 4.3.6
2.6.20.21 4.3.6 2.6.20和2.6.19的nfs,oss等几个模块会编译失败,gcc降级到4.2.4也一样,如果不想继续降级gcc或binutils,那就去掉那几个模块吧
2.6.19.7 4.3.6
2.6.18.8 4.3.6
2.6.17.14 4.3.6
2.6.16.62 4.2.4 源码明确规定不得使用高于gcc 4.3的版本

然后是一些驱动,前面说过这个阶段内核变化很大,某些驱动名称可能都不同,还有些驱动存在有和没有的问题,如uvesafb,2.6.24以上才有,2.6.25以上才稳定,不加载这个驱动,用vesafb的话,x86_64架构不支持vesafb-ng,高分辨率下控制台卷动速度会很慢,我修改了grub2的/etc/grub.d的生成配置文件脚本,能自动检测出内核是否含有uvesafb,有则启用,相应的,/etc/rc.d/可能也要写一些启动脚本来根据不同内核版本修正一些驱动模块的问题,反正折腾几天,最后基本完美了

2.6.21以下版本不支持x86_64架构自动打成tar包,你要么手动安装内核,要么复制2.6.22内核的scripts/package/buildtar覆盖

同时2.6.21以下版本在LFS 6.6的高版本编译工具链环境下,会有编译错误,scripts/mod/sumversion.c的头部需要加上#include <limits.h>

驱动问题还要着重说一下时钟的问题,2.6.23以上版本支持pc cmos硬件时钟,以下版本得用传统的字符设备rtc,无论怎样,你得保证每一个内核都有自己有效地rtc时钟,否则,时区设置将会无效,这会导致不同内核使用不同的当前时间,到时候就会出现文件系统检查发现你的硬盘“来自未来”之类的错误,导致无法引导。

因为2.6.2x是个内核特性大发展时期,所以我以2.6.32为基础构建的LFS 6.6,比较完美运行的是2.6.25以上版本,以下版本多少有点小问题,不过不严重,可以解决,这个版本的LFS我折腾了最久

我当时没想到能向下移植内核到2.6.16,编译glibc的时候,直接限定了内核版本,没法往下试了,从后面LFS 6.3的实际情况看,也基本到底了


3.LFS 6.3 x64?(问号是因为这个版本我基本没按LFS文档,包括工具链的版本都改了许多)(安装内核2.6.7 ~ 2.6.16.62,外加2.6.27.59)

经验多了,就开始乱来,反正这个版本官方LFS文档不支持x86_64严格按照官方文档也搞不定,不如自己动脑

原始软件包版本:Linux 2.6.22.5,gcc 4.1.2,binutils 2.17,glibc 2.5.1,udev-113,etx3文件系统

我使用的版本:Linux 2.6.27.59,gcc 4.2.4,binutils 2.18a,glibc 2.6.1,udev-135+udev-058,ext3文件系统

为了编译低版本Linux安装在/opt的额外工具链软件:gcc 3.4.6

大部分软件包的优化选项:-march=nocona -mtune=nocona -pipe -O2,gcc 4.2不支持core2,其它的注意事项和LFS 7.0一样

瞧见没,我全改了,而且改的不仅是修订号,无论是内核特性,编译器、链接器、glic特性都会有较大变化,不过没关系,我手头LFS文档是全的,参照其他版本的及解决方法加自己动脑,解决得很完美

首先,构建LFS的时候不能光看LFS 6.3,得看6.5,尤其是前面临时工具链的时候,否则64位构建必然失败。

工具链的补丁你得去了解版本特性的变化,有的要打,有的千万不能打

其他软件包也会编译失败,有的能在6.4找到方案(gzip,换高点版本也可以),有的要换版本(perl 5.8.8->5.8.9)等等……

udev我装了俩,制定不同的目录,反正udev这两个版本跨度很大,总共只有一个文件是重的……保证他们不互相覆盖就行了。为什么装两个?我用2.6.27编译的LFS系统,向下移植的版本跨度太大,没有udev能完美支持这么大跨度(能运行,但有问题),所以我用双版本,再用启动脚本决定使用哪一个。这个LFS 6.3,要的,就是折腾

gcc版本,老规矩,列个表,别超出表中的限制

2.6.16.62 4.2.4
2.6.15.7 4.2.4
2.6.14.7 4.2.4
2.6.13.5 4.2.4
2.6.12.6 4.2.4
2.6.11.12 3.4.6 gcc 4以上都会失败
2.6.10 3.4.6
2.6.9 3.4.6 以下版本文档中推荐gcc 2.95.3,和内核2.4版本一样的,如果你愿意装的话,那个是最稳定的……
2.6.8.1 3.4.6
2.6.7 3.4.6

说内核之前,先说说grub,LFS 6.3的grub0.9x不支持x86_64,你要么用multilib,要么用32位静态编译,而且x86_64内核开启ia32模拟,我不想折腾这个了,而且这么多内核,grub0.9x得自己写menu.lst配置文件,会死人的……直接用grub2了

2.6.11~2.6.16开发的时期这是udev机制变化最厉害的时候,如果发生udev不兼容,基本上在这个区段(另一个区段就是2.6.24左右),反正我用较低版本的udev058,基本没问题了

2.6.14~2.6.16一样得从2.6.22拷贝buildtar文件来支持64位的打包,2.6.13以下干脆连打包都不支持了……要么改Makefile,要么老老实实用make modules_install+复制文件来安装内核吧。make install依赖lilo,这里没有……

2.6.14以下鼠标驱动这里有变化,可能需要写额外的配置加载鼠标驱动

2.6.8以下连localverrsion都不支持了,想给自己的内核名字加上自定义字符串得去改makefile了

2.6.6编译失败,一个驱动的问题,2.6.0~2.6.8是2.6内核的初期成长期,可能有许多东西不成熟,我就没试了

稳定性上,2.6.27.59还是最靠谱的,2.6.16.62也还可以,2.6.14以下总给人不放心的感觉,光启动就慢了许多(可能和udev-058不能自动检测许多pci设备,得依靠hotpug软件报有关)


结束

下面准备做2.4内核的全版本编译
...全文
595 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
昵称很不好取 2011-12-12
  • 打赏
  • 举报
回复
这帖子怎么能不顶一下
Arnold9009 2011-12-12
  • 打赏
  • 举报
回复
很强大~~~
李迟 2011-12-12
  • 打赏
  • 举报
回复
我只搞过一次LFS,好像是6.3还是6.5,忘了,两年前的事情了,后面基本上就不再折腾Linux,什么升级内核啊,搞桌面啊,都不搞了,专心看程序了。
马甲1 2011-12-06
  • 打赏
  • 举报
回复
xunxun 2011-12-05
  • 打赏
  • 举报
回复
lz直博了?
念茜 2011-12-05
  • 打赏
  • 举报
回复
谢谢分享,lz辛苦了
stein42 2011-12-05
  • 打赏
  • 举报
回复
好强大

19,612

社区成员

发帖
与我相关
我的任务
社区描述
系统使用、管理、维护问题。可以是Ubuntu, Fedora, Unix等等
社区管理员
  • 系统维护与使用区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧