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

jackyjkchen 2011-12-05 08:34:34
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.8 4.4.6

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

除此之外,2.6.28.8 2.6.29.6 2.6.30.10 2.6.31.14 2.6.36.4都有一个x86_64的bug导致编译失败,其他更新的版本或长期支持版本已经修复,在arch/x86_64/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内核的全版本编译
...全文
756 1 收藏 28
写回复
28 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
玄冬Wong 2012-09-08
问下楼主工作多少年了,技术能力很强啊!
回复
scdxmoe 2012-09-07
学习了,高手
回复
duke56 2011-12-08
对Linux操作系统都不大熟哦...

何来...?
回复
jackyjkchen 2011-12-08
[Quote=引用 22 楼 vafox 的回复:]

好久不见过儿,貌似狒狒被封杀之后就很少见你来了。
过儿继续回复该贴啊,将口水贴进行到底。
[/Quote]

求真相
回复
jackyjkchen 2011-12-08
[Quote=引用 23 楼 vafox 的回复:]

楼主快毕业了吧,咋还那么悠闲弄这些。
[/Quote]

没什么其他用来浪费时间的爱好,那这个打发时间总比学人家抽烟喝酒三国杀有意义

回复
火狐狸 2011-12-08
楼主快毕业了吧,咋还那么悠闲弄这些。
回复
火狐狸 2011-12-08
好久不见过儿,貌似狒狒被封杀之后就很少见你来了。
过儿继续回复该贴啊,将口水贴进行到底。
回复
jackyjkchen 2011-12-08
LFS 6.1.1(2.4.29-2.4.37.11,2.6.16.62)

LFS 5.1.1(2.4.20~2.4.28,2.4.37.11)

下次预计的目录
回复
jackyjkchen 2011-12-08
2.6.4内核会有几个驱动说找不到memcpy_fromio和memcpy_toio的警告,这几个驱动无法加载,这已经确认是2.6.4内核的bug,gentoo论坛的存档中有说明的。

其中你可能会用到的就是声卡核心驱动snd.ko,编译为内建就可以,其它的都很非主流不用管,干脆删掉

2.4那一块现在完成的是以linux 2.6.16 + gcc 3.4.6 + binutils 2.15a为基础建立的LFS,向下降级到2.4.29,因为是跨大版本,启动脚本要改不少用于区分内核,modules tools也要装一个旧的,这是后话了

2.4.28又有问题了,这次无论怎么降级工具链也有好几个关键驱动(网卡,USB)找不到memcmp符号,虽然不影响系统引导,但我要做的是个基本上没问题、可用的LFS内核,所欲2.4.28-2.4.20打算放在下一个版本,等这个版本弄完,再发2.4的完整篇
回复
langyano1 2011-12-08
高!!!!!!!!!!
回复
机智的呆呆 2011-12-08
太深奥了。
表示看不懂。
回复
机智的呆呆 2011-12-08
12楼的高手好久不见,可以签个名合影留念吗?
回复
jackyjkchen 2011-12-08
文中有一条忘记说了

LFS 6.3的环境中编译2.6.10之下的内核时,别忘了打上一个linux-2.6-seg补丁,kernel.org有,不过kernel.org被黑了,现在还没完全恢复。可以找其他镜像

这个补丁是针对bunutils 2.15以上的汇编器的,里面汇编语法发生改变了

另外,在gcc 4环境下,这些低版本的内核还有一些编译错误,scripts/kconfig/mconf.c里报错的那一句声明删掉,include/asm-x86_64/calling.h里头删掉两个报错的函数,已经在arch/x86_64/kernel/entry.S中实现过了(错误可能会报在后面一个文件,不要改后面的,改前面的)

今天又试了下2.6.6以下的内核,2.6.6和2.6.5需要再将gcc降级到3.3.6,而且ntfs写入驱动也有汇编器的问题,要么改一行汇编要么干错不要ntfs写入

2.6.3就非常不成熟了,直接认不出我是x86_64的CPU,说我平台不兼容。

类似于Debian Sarge的2.4和2.6双版本的LFS也搞出来了,因为是降级安装,两三句说不完,过两天有时间把2.4那一块也写一篇。

fetag和我的个人恩怨,大家就当看戏好了

有句话说得好,没有真理,只有立场
回复
jackyjkchen 2011-12-08
[Quote=引用 12 楼 fetag 的回复:]

你总是喜欢做这些门面上的事,外表看上去很光鲜,实则没什么技术含量,回顾一下你以前的所谓项目吧,除

了编译这个,再不就是封装那个,现在又搞这种蛋疼的堆积木...你就不能踏踏实实学点东西,提高自己的能

力,而不是吸引别人眼球吗?

内核里面确实有很多trivial的东西,不过如果你连从trivial中抓出来backbone的能力或者勇气、尝试都没有,

那还真不适合干点实事!
……
[/Quote]

搞的好像你自己能力很强似的,你和你所在的那家公司的水平,其实大家心里清楚
回复
独孤过儿 2011-12-06
真有空就看看内核代码

这种拿人家做好的积木块搭城堡的事,途是门面而已
回复
「已注销」 2011-12-06
不太明白,以后看看
回复
jackyjkchen 2011-12-06
直接读Linux源码时间吃力不讨好的事情,源码中有差不多一半的行数是非功能性的,防御型编程、异常处理和安全补丁之类,非常干扰阅读

那些动不动“去看内核源码”的人基本上是误人子弟,直接看源码基本不会有收获,先找本《深入Linux内核架构》之类的大部头书,先把内核机制了解个大概,这一类书摘抄的源码基本上把异常处理去掉了,只留功能逻辑,即便这样,也最好养成看技术类书不看源码只看文字的习惯,特别是Linux内核,源码的细节很可能下一个版本就改的面目全非
回复
jackyjkchen 2011-12-06
[Quote=引用 9 楼 fetag 的回复:]
真有空就看看内核代码

这种拿人家做好的积木块搭城堡的事,途是门面而已
[/Quote]

有句话说的一点没错,这是个人情社会,许多人评价别人取决于关系的好坏
回复
ryfdizuo 2011-12-06
好久没看到过儿了。。。
回复
独孤过儿 2011-12-06
你总是喜欢做这些门面上的事,外表看上去很光鲜,实则没什么技术含量,回顾一下你以前的所谓项目吧,除

了编译这个,再不就是封装那个,现在又搞这种蛋疼的堆积木...你就不能踏踏实实学点东西,提高自己的能

力,而不是吸引别人眼球吗?

内核里面确实有很多trivial的东西,不过如果你连从trivial中抓出来backbone的能力或者勇气、尝试都没有,

那还真不适合干点实事!

你知道俺嘴黑,但是确实是为了你好!真心话!
回复
加载更多回复
相关推荐
发帖
其它技术问题
创建于2007-09-28

3849

社区成员

C/C++ 其它技术问题
申请成为版主
帖子事件
创建了帖子
2011-12-05 08:34
社区公告
暂无公告