直接贴
============================================================================
linux内核发行版2.6.xx <http://kernel.org/>
这是Linux内核2.6版本的发行注记。请认真阅读,因为这里告诉你所有相关的
信息,描述如何安装内核、以及如果出现错误该如何处理。
---------------------------------------------------------------------
什么是Linux?
Linux是Unix操作系统的一个克隆颁布,由Linus Torvalds和一些通过网络松散
组织起来的黑客门从头开始构建。它的目标是兼容POSIX和Single UNIX
Specification。
Linux具有你可以想象得到的在现在完全成熟的Unix上所具有的所有特征,包括
真正的多任务、虚拟内存、共享库、按需加载、共享的写时复制可执行程序、
合理的内存管理、以及包含IPv4和IPv6在内的多个网络协议栈。
Linux在GNU通用公共许可证下发布――查看文件COPYING获取更多细节。
---------------------------------------------------------------------
Linux可以运行于哪些硬件系统之上?
虽然最初是为基于32位x86的PC(386或者更高)开发的,现在的Linux可以运行
在(至少)Compaq Alpha AXP、Sun SPARC、UltraSPARC、Motorola 68000、
PowerPC、PowerPC64、ARM、Hitachi SuperH、Cell、IBM S/390、MIPS、
HP PA-RISC、Intel IA-64、DEC VAX、AMD x86-64、AXIS CRIS、Xtensa、AVR32
和Renesas M32R体系架构的处理器之上。
可以很容易地将Linux移植到大多数通用的32位和64位架构上,只要它们具备基
于页面的存储管理单元(PMMU)并移植了GNU C编译器(gcc)(属于GNU
Compiler Collection,GCC)。Linux也可以被移植到不具备PMMU的一些架构上,
虽然功能会明显地受到一些限制。Linux也可以移植到自身之上。你可以以用户
态应用程序的方式来运行内核――这称为用户态Linux(UML)。
---------------------------------------------------------------------
文档
- 网上有大量关于Linux和UNIX的电子文档,在这些方面也有大量的书籍。
有些是特定于Linux的,也有些是通用的UNIX相关的。我建议先查看任意
Linux FTP站点子目录下的有关LDP(Linux文档项目)的书籍。本篇不作
为讲解系统的文档:实际上有更好的资源可以参考。
- 在documentation/子目录下有大量的README文件:例如,这些文件包含与
内核相关的关于一些驱动程序的安装注记。查看Documentation/00-INDEX
来获取每个文件所包含信息的列表。请阅读文件Changes,该文件包含了
关于可能导致内核更新失败的问题的信息。
- Documentation/DocBook/子目录下包含适用于内核开发者和用户的一些
指南。这些指南可以以多种格式显示:PostScript(.ps)、PDF、HTML、
man手册页,以及其他格式。安装后,执行命令“make psdocs”、
“make pdfdocs”、“make htmldocs”或者“make mandocs”可以生成
指定格式的文档。
---------------------------------------------------------------------
安装内核源码
- 如果你要安装完整的源码,将内核tar包放在你拥有访问权限的目录下
(例如,你的home目录)并解压缩:
gzip -cd linux-2.6.XX.tar.gz | tar xvf -
或者
bzip2 -dc linux-2.6.XX.tar.bz2 | tar xvf -
将“XX”替换为最新内核的版本号。
不要使用/usr/src/linux!这里包含(通常不完整)一组由库的头文件使
用的内核头文件。这些头文件要与库代码匹配,并且不应该因为任何偶然
的kernel-du-jour而导致混乱。
- 你还可以通过打补丁在2.6.xx版本之间进行升级。补丁以传统的gzip格式
和新的bzip2格式发放。要通过打补丁安装,首先获取所有新的补丁文件,
然后进入内核源码(linux-2.6.xx)的顶层目录,执行下列命令:
gzip -cd ../patch-2.6.xx.gz | patch -p1
或者
bzip2 -dc ../patch-2.6.xx.bz2 | patch -p1
(按顺序重复处理版本号大于当前源码树的xx版本)就可以了。你可以删
除备份文件(xxx~或者xxx.orig),并确保没有失败的补丁(xxx#或者
xxx.rej)。如果有补丁失败,那么就是你或者我在操作时出了错。
与2.6.x内核所使用的补丁不同的是,用于2.6.x.y内核(称为-stable内
核)的补丁不是增量的,而是可以直接合并到基本的2.6.x内核中。请查
看Documentation/applying-patches.txt获取更多信息
另外,脚本patch-kernel可以自动化这个过程。它确定当前内核版本,
然后合并所有找到的补丁。
linux/scripts/patch-kernel linux
上面命令的第一个参数是内核源码的位置。当前目录下的补丁被合并入
内核,但是可以通过第二个参数指定一个替换目录。
- 如果是通过稳定版的补丁(例如patch-2.6.xx.y)在不同版本之间升级,
注意这些“dot-releases”不是增量的,它们只能用于2.6.xx基础内核
树。例如,如果基础内核为2.6.12,而你要应用补丁2.6.12.3,那么你
事先不能应用补丁2.6.12.1和2.6.12.2。同样的,如果使用的内核为
2.6.12.2,而你打算升级到2.6.12.3,那么你必须在应用补丁2.6.12.3
之前先撤销2.6.12.2补丁(即patch -R)。
可以阅读Documentation/applying-patches.txt获取更多信息。
- 确保不会有旧的.o文件和依赖存在:
cd linux
make mrproper
现在你可以正确地安装源码了。
---------------------------------------------------------------------
软件要求
编译和运行2.6.xx内核需要各种软件包的最新版本。查看Documentation/
Changes了解对这些软件包最低版本的要求以及如何进行更新。注意,如果
使用非常旧的版本的软件包会产生难以跟踪的间接错误,所以不要认为在
构建或者操作过程中出现明显的错误时只要更新软件包就可以。
---------------------------------------------------------------------
构建存放内核的目录
当编译内核时,缺省地,所有的输出文件将与对应的内核源码文件存放在
一起。使用选项“make O=output/dir”允许你指定一个可选目录来存放
输出文件(包括.config)。例如:
内核源码: /usr/src/linux-2.6.N
构建目录: /home/name/build/kernel
要配置和构建内核,执行如下命令:
cd /usr/src/linux-2.6.N
make O=/home/name/build/kernel menuconfig
make O=/home/name/build/kernel
sudo make O=/home/name/build/kernel modules_install install
请注意:如果使用了选项“O=output/dir”,那么每次调用make时都必须
使用该选项。
---------------------------------------------------------------------
配置内核
不要跳过这一步,即便是针对次版本进行升级。在每个发行版本中都会加入
新的配置选项,如果没有正确地设置配置文件,会出现一些奇怪的问题。如
果你打算花费尽量少的时间来将你现有的配置用于新版本,使用
“make oldconfig”,这样你只需要设置新选项即可。
- 可选的配置命令包括:
"make config" 普通文本界面
"make menuconfig" 基于彩色菜单、单选列表和对话框的文本界面
"make xconfig" 基于X window (Qt)的配置工具
"make gconfig" 基于X window (Gtk)的配置工具
"make oldconfig" 缺省所有的选项基于现有的./.config文件的内容,
询问用户对新的配置选项的设置
"make silentoldconfig"
类似于上一条命令,但是没有将已有的设置显示在
屏幕上。此外还更新依赖关系
"make defconfig" 基于arch/$ARCH/defconfig或者
arch/$ARCH/configs/${PLATFORM}_defconfig
中的缺省选项配置来创建一个./.config文件,
如何选择依赖于体系结构
"make ${PLATFORM}_defconfig"
基于arch/$ARCH/configs/${PLATFORM}_defconfig
中的缺省选项配置来创建一个./.config文件。使用
“make help”获取对应体系结构的所有平台的列表
"make allyesconfig" 创建一个选项值尽可能设置为'y'的./.config文件
"make allmodconfig" 创建一个选项值尽可能设置为'm'的./.config文件
"make allnoconfig" 创建一个选项值尽可能设置为'n'的./.config文件
"make randconfig" 创建一个选项值为随机值的./.config文件
使用Documentation/kbuild/kconfig.txt中的Linux内核配置工具可以获取更多信息。
关于“make config”:
- 加入无关的驱动程序会让内核臃肿,而且在某些情况下会
出问题:探测一个不存在的控制器时可能将驱动程序关联
到其他控制器。
- 编译内核时将“Processor type”设置为高于386会导致
内核不能在386机器上工作。内核在启动时会对处理器类
型进行检测并停止工作。
- 如果内核编译进了仿真数学协处理器,内核还是会使用
模拟的即便有一个物理的协处理器:这时永远不会使用
物理的数学协处理器。内核会稍微大一些,但是它能运
行于不同的机器上,不管这些机器上是否有物理的数学
协处理器。
- 配置“kernel hacking”会导致内核大一些,或者运行会
慢一些(或者两者兼有),而且内核会不稳定,因为配置
了一些例程会打断出错代码来查找内核的错误(kmalloc())。
因此多数情况下对选项 "development", "experimental",
or "debugging" features要回答'n'。
---------------------------------------------------------------------
编译内核
- 确认安装了最新的gcc 3.2。关于更多信息,查看Documentation/Changes。
请注意:你仍然可以在新内核上运行用户态程序a.out。
- 执行“make”构建一个压缩的内核映像。如果已经安装了lilo来配合内
核的makefile文件,可以执行“make install”;但是最好先检查一下
lilo的设置。
要进行实际的安装必须有root权限,但是正常的构建不会有此要求。
root自有它的用武之处。
- 如果将内核的一部分配置为`modules`,那么还需要执行命令
“make modules_install”。
- 输出内核编译/构建的详细信息:
通常内核构建系统以沉默模式运行(不是完全沉默)。但是,有时你
或者内核开发人员需要查看执行的编译、链接或者其他命令。要是这
样,使用“verbose”构建模式。在“make”命令中插入“V=1”即可。
例如:
make V=1 all
要让构建系统输出某个目标重新构建的理由,使用“V=2”。缺省为
“V=0”。
- 保存一个内核的副本,以免出现错误。对于开发版本来说这很重要,
因为新版本包含一些没有调试过的代码。
同时务必保存对应版本的模块的副本。如果安装跟当前工作的内核
版本号相同的新内核,在执行“make modules_install”之前构造
模块目录的备份。还有一种方式是,在编译内核之前,使用内核配
置选项“LOCALVERSION”在工作内核版本后添加一个唯一的后缀。
可以在菜单“General Setup”设置LOCALVERSION。
- 要启动新内核,需要将新内核映像(例如,编译后得到的
.../linux/arch/i386/boot /bzImage)复制到放置工作内核的地方。
- 已经不支持在不使用bootloader例如LILO的情况下而直接从软盘启动
内核。
如果从硬盘启动Linux,可能你使用的是LILO,而LILO使用的内核
映像由文件/etc/lilo.conf指定。通常内核映像文件为/vmlinuz、
/boot/vmlinuz、/bzImage或者/boot/bzImage。要使用新内核,先
保存旧映像文件的一个副本,然后用新映像覆盖旧的映像文件。
接下来,必须返回到LILO更新加载的映像!!如果不这样做,你将
无法启动新的内核映像。
通常重新安装LILO需要运行/sbin/lilo。可以编辑/etc/lilo.conf
来指定旧的内核映像(例如/vmlinux.old),以备新内核不能工作。
查看LILO文档获取更多信息。
重新安装LILO后,可以动手了。关闭系统,重启,使用新内核!
如果要改变内核映像中的缺省根设备、视频模式、ramdisk大小等等,
使用程序‘rdev’(或者适当的时候使用LILO的引导选项)。改变
这些参数不需要重新编译内核。
- 重启进入新内核,享受新的旅程。
---------------------------------------------------------------------
如果出现错误
- 如果错误可能是内核bug引起的,请查看MAINTAINERS,看看是否有专人
负责出问题的内核部分。若是没有,那么接下来最好把它们发给我
(torv...@linux-foundation.org),也可以发到其它相关的邮件列
表或者新闻组。
- 在bug报告中,请说明内核的详细信息、如何重现问题、以及你所使用
的系统配置(用你的常识描述)。如果是一个新发现的问题,说明这
一点,如果是一个已有的问题,请尽量在第一次发现时告诉我。
- 如果bug在屏幕上或者系统日志中产生一条类似这样的消息
unable to handle kernel paging request at address C0000010
Oops: 0002
EIP: 0010:XXXXXXXX
eax: xxxxxxxx ebx: xxxxxxxx ecx: xxxxxxxx edx: xxxxxxxx
esi: xxxxxxxx edi: xxxxxxxx ebp: xxxxxxxx
ds: xxxx es: xxxx fs: xxxx gs: xxxx
Pid: xx, process nr: xx
xx xx xx xx xx xx xx xx xx xx
或者类似的内核调试信息,请准确地复制下来。在你看来,dump可能
是难于理解的,但是它包含的信息有助于调试错误。dump信息上面的
文字描述也很重要:它描述了为什么内核会dump(在上面的例子中是
由于一个错误的内核指针)。如何利用dump信息请参考
Documentation/oops-tracing.txt。
- 如果编译内核时使用了CONFIG_KALLSYMS,那么可以将dump原样发送,
否则必须使用程序“ksymoops”将dump信息变得更容易使用(通常
建议编译时加入CONFIG_KALLSYMS选项) 。该工具可以从
ftp://ftp.<country>.kernel.org/pub/linux/utils/kernel/ksymoops/
下载。你还可以手工查看dump信息。
- 在调试类似上面的dump信息时,如果能弄清楚EIP的值是什么意思会
非常有帮助。类似这样的16进制值并不能给我或者其他人提供帮助:
它依赖于你自己的内核的设置。你需要做的是拿掉EIP那行的16进制值
(忽略“0010:”),然后查找内核的名字列表,看看偏移地址属于哪
个内核函数。
要找到内核函数的名字,需要到产生错误的内核的二进制映像中查找。
即‘linux/vmlinux’。要抽取名字列表来匹配内核崩溃时的EIP,
执行下面的命令:
nm vmlinux | sort | less
这样你会得到一个升序排列的内核地址列表,可以在该列表中找到包
含偏移地址的函数。注意内核调试信息给出的地址不需要与函数地址
完全匹配(实际上很少会这样),所以不能使用‘grep’:但是列表
中会给出每个内核函数的起始点,因此可以查找起始地址低于你给出的
偏移地址而其后又有高于偏移地址的函数的函数就可以了。实际上,
一个好的做法是在问题报告中包含一些“context”,即加入对应位置
前后的一些代码。
如果由于某种原因你无法进行上述操作(使用了预编译内核映像或者
类似的映像文件),那么尽可能详细的告诉我你的系统配置。请参考
REPORTING-BUGS获取更多细节信息。
- 还有一种方法,对工作内核使用gdb。(只读;例如你不能改变值或者
设置断点)要这样做,首先编译内核时使用-g选项;调整
arch/i386/Makefile,然后执行“make clean”。还需要设置选项
CONFIG_PROC_FS(通过“make config”)。
重启到新内核后,执行“gdb vmlinux /proc/kcore”。这时你可以
使用所有常用的gdb命令。查看系统崩溃位置的命令是“l *0xXXXXXXXX”。
(将XXX替换为EIP的值。)
对于非运行态的内核使用gdb会失败,因为gdb(错误地)忽视了内核
编译的起始偏移量。
在 09-11-2,Wenxy<wen_k...@163.com> 写道: