Linux3.2.0 内核文件夹目录树
.
├── arch
//该目录下主要
├── block
├── build
├── COPYING
├── CREDITS
├── crypto
├── Documentation
├── drivers
├── firmware
├── fs
├── HEAD
├── hooks
├── include
├── info
├── init
├── ipc
├── Kbuild
├── Kconfig
├── kernel
├── lib
├── MAINTAINERS
├── Makefile
├── mm
├── modules.builtin
├── modules.order
├── Module.symvers
├── net
├── README
├── REPORTING-BUGS
├── samples
├── scripts
├── security
├── sound
├── System.map
├── tools
├── usr
├── virt
├── vmlinux
├── vmlinux.o
└── 编译说明.txt
Linux3.x 内核版本的下载地址为:<http://kernel.org/>
这是 Linux3.x 版本的注释。仔细的阅读,诚如他们告诉你的,这里解释了怎样安装内核,且
如果错误发生了应该怎么做。
什么是 LINUX?
Linux 是从 Unix 操作系统发展而来,最初的内核是由 Linus Torvalds 编写,其中也有来自网
络上组织松散的“黑客”的帮助。它的目的就是对抗 POSIX 和 Single UNIX 规范联盟。
诚如你所期望的,在成熟的 Unix 上所有的功能在 Linux 上也都有,包括多任务功能,
虚拟内存,共享库,请求装入,共享的写时复制技术,内存管理,多层网络技术包括 IPv4
和 IPv6 。
Linux 的发布遵循 GNU 通用公共许可协议,更为详细的介绍请参考版权文件。
Linux 所能支持的硬件?
虽然 Linux 最初的开发是在 32Bit 的 X86 机器上完成的,但是今天也可以运行在其它的
硬 件 上 , 像 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, Tilera TILE, AVR32 and Renesas M32R 等等架构的
机器。
Linux 可以方便的被移植到通用 32bit 或 64bit 架构上,只要这些硬件上具有也存储管理
单元(PMMU)和 GNU C 编译器(gcc)就可以。如果某些硬件架构上没有 PMMU,Linux
也完全可以被移植上去,只是在功能上受到一定程度的限制。
同样,你也可以运行 Linux 内核作为用户应用程序-这就是用户模式 Linux。
文档说明:
- 现在,不论互联网上的电子书还是纸质书籍都有大量的可利用的说明文档,像 Linux 规
范或者关于 Unix 问题。我推荐在 Linux FTP 站点或者 LDP ( Linux Documentation Project)
查找文档。这份说明文档并不是正对内核系统的文档:还有许多可以利用的文档资源。
- 在内核解压后的目录或者子目录下有多份 README 文件:他们通常包含内核安装注意
事项,像一些驱动程序示例。可以查看 Documentation/00-INDEX 文件,这是一份说明
文档的列表文件,你可以查看包含哪些文件。阅读 Changes 文件,它包含一些常见问题
的信息,这些可能是由你在更新内核时产生的。
- Documentation/DocBook/这个目录包含了一些针对内核开发者和用户的指导手册。这些
文档的格式一般有以下几种:.ps, PDF, HTML 以及在线帮助手册等等。安装后,
输入命令“make psdocs”,“make pdfdocs”,“make htmldocs”,或者“make mandocs”将会按照以上的格式提交文档。
安装内核源代码的步骤:
-
如果你要安装全部源代码,将内核安装包拷贝到你想要安装的目录下(例如,你的家目
录-/home),并解压缩:
gzip -cd linux-3.X.tar.gz | tar xvf -
或
bzip2 -dc linux-3.X.tar.bz2 | tar xvf -
使用最近的内核版本号替换掉“XX”。
不要使用/usr/src/linux 这个目录区域!它是用来存放当前运行内核的头文件集,这些头
文件是库文件的头文件。它们应该与相应的库对应,无论如何不能与当前安装的内核混
淆。
-
你也可以在 3.x 版本之间通过补丁进行更新。补丁通常使用传统的 gzip 或者最近的 bzip2
格式进行压缩。为了通过补丁安装,首先要取得最新的补丁文件,进入内核源代码顶层
目录(linux-3.x-)且执行命令:
gzip -cd ../patch-3.x.gz | patch -p1
或
bzip2 -dc ../patch-3.x.bz2 | patch -p1
(所有的版本号应该大于你当前的源文件树中的版本号)你可能想要删除备份文件(例
如 xxx~或 xxx.orig),但是要保证没有失败的补丁文件 (xxx#或 xxx.rej)。如果有错误
的补丁文件存在,说明我们的安装补丁文件发生了错误。
不像 3.x 内核的补丁,3.x.y 内核的补丁并不是递增的但是可以直接应用到 3.x 内核中。
详细的参考信息可以阅读 Documentation/applying-patches.txt 文档。
另一种方法就是,使用自动打内核补丁的脚本程序。它取决于现在内核版本然后寻找
相应补丁使用。
linux/scripts/patch-kernel linux
上面命令中的第一个参数中的 linux/是内核源代码顶层目录的位置。补丁会从当前目录
下查找使用,当然,你也可以通过第 2 个参数(linux)指定相应的补丁目录。
-
如果你在发行版内核中进行更新,使用稳定的补丁序列(例如,patch-3.x.y),这些补丁
序列号并不是递增的,所以它们必须被应用在 3.x 的基础版本上。例如,你的基础版本
是 3.2,你想要应用 3.2.3 补丁,你不能(事实上也是如此)首先打 3.2.1 或 3.2.2 的补丁。
相似的,如果你当前运行的内核版本是 3.2.2,而你又想应用 3.2.3 的内核版本,你必须
首先反向去掉 3.2.2 的补丁(patch -R),才能再次打 3.2.3 的补丁。
详细的参考信息可以参阅 Documentation/applying-patches.txt 文档。
-
确保你的源目录下没有 stale.o 文件和依赖性文件(也就是确保你的源代码是干净的):cd linux
make mrproper
参数说明:linux->你的内核源代码的路径。
现在,你已经拥有能够被正确安装的内核源代码了。
SOFTWARE REQUIREMENTS(软件依赖)
编译并运行 3.x 内核需要更新某些软件包。在编译之前,查看 Documentation/Changes
文档,获取这些软件包的最小版本号要求和怎样去更新这些软件包。如果使用这些软件
包的老版本,可能造成一些间接的错误,而且这些错误很难被跟踪,所以不要假设你可
以在构建或运行时发生错误再更新这些软件包。
设置内核构建路径:
当编译内核的时候,默认情况下,所有的输出文件都会被存放在内核源代码目录下。使
用选项“make O=output/dir”,允许你指定另外的输出文件(包括.config)存放路径。
例子:
kernel source code:
build directory:
/usr/src/linux-3.N
/home/name/build/kernel
配置和编译内核使用下面的命令(这些可以写入 build shell 脚本中):
cd /usr/src/linux-3.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"
基于带颜色的菜单, radiolists 和对话框的文本框
"make nconfig"
彩色菜单的增强版
"make xconfig"
基于 Qt 图形窗口的配置工具
"make gconfig"
基于 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"
通过尽可能多的设置配置参数为“y”,创建./.config 配置文件。
(尽可能的创建最小内核)。
"make randconfig"
设置配置参数为随机数,创建./.config 配置文件。
(这个.......)
更多关于使用 Linux 内核配置工具的信息请参阅《Documentation/kbuild/kconfig.txt》文
档。
命令"make config"注意事项:
-
可能会加入不需要的驱动而使得内核变的越来越大,且在某些情况下导致问题发
生:搜索不存在的控制卡可能会混淆你别的控制器。
-
编译内核的时候,使用"Processor type"配置参数设置高于 386 机器将会导致内核不
能在 386 机器上工作。内核将会在 bootup 时,检测出这个问题,然后放弃这次引
导。
-
如果存在协处理器的话,内核编译时仍会将协处理器作为数学仿真器来使用。
内核中是不会使用到数学仿真器的。内核也许会大一点,但是可以在不同类
别的机器上运行而不必去关心是否有一个数学协处理器。
-
"kernle hacking"这个配置项选中的话会导致编译处的内核大一些或慢一些(或两者
都有),如果通过改变一些固定而有规则的程序的配置来测试坏代码可能使内核 变
得不稳定(像 kmalloc())。因此你应该在“develoment”,
“ expermental “,或“debugging”
选项上回答 ’n‘。编译内核:
- 确保你的 gcc 编译器的版本在 3.2 以上。更多详细的信息可以参考 Documentation
/Changes 文档。
请注意:你仍然可以使用这个内核运行 a.out 用户程序。
- “make” 创建一个压缩内核镜像。
“make install”执行内核的安装,如果你安装的 lilo 与内核 makefiles 中的是搭配的,那
么就会执行安装,但是前提就是你必须确定你安装了正确的 lilo 引导程序。
安装需要 root 权限,但是正常的编译构建不需要。不使用 root 权限,安装是没有意义
的。
- 如 果 你 在 配 置 的 时 候 , 将 内 核 配 置 成 模 块 化 , 那 么 你 需 要 使 用 命 令 “make
modules_install”进行模块化安装。
- 全部显示内核编译/构建过程输出信息:
正常情况下,内核的构建过程是相对安静的(但也不总是沉默)。但是,有时候你或别
的内核开发者需要查看编译,链接或别的命令执行的准确性。基于此,使用“verbose”
构建方式。这种方法是通过在“make”命令后加入“V=1”来实现的。例如:
make V=1 all
为了在构建过程中得知每一个目标的重新编译的原因,使用参数“V=2”实现。默认值是
“V=0”。
-
一定要手动备份以下内核程序以防错误发生而导致的内核不可用。因为每一个新的发行
版都包含一些新的代码,而这些代码往往还没有被调试。同时,与内核相关的某个模块
也 需 要 备 份 。 如 果 你 新 升 级 的 内 核 与 你 当 前 的 内 核 是 相 同 的 , 那 么 在 你 “make
modules_install”之前备份你自己的模块程序,就更为重要了。
另外,在编译之前,使用内核配置选项“LOCALVERSION”会在新内核版本号后面添加
独一无二的的后缀用于与旧版本的内核文件相区别,这样就不会覆盖旧内核的文件了。
LOCALVERSION 可以在"General Setup" 菜单中进行设置。
- 为了引导新的内核,需要复制新内核镜像到启动内核的地方(编译之后,内核镜像文件
一般存储在 /linux/arch/i386/boot/bzImage ),这里/linux 一般是内核源代码的目录路径。
- 不使用引导程序如 LILO 等,而直接从软盘上启动内核的方法现在已经不支持了。
如果从硬盘引导 Linux,前提是你使用的 LILO 引导程序在内核镜像对应的/etc/lilo.conf
文 件 中 指 定 了 。 这 个 内 核 镜 像 文 件 通 常 是 /vmlinuz , /boot/vmlinuz , /bzImage 或
/boot/bzImage。为了使用新内核,备份旧内核,然后复制新内核覆盖旧内核。然后,你
必须运行 LILO 去更新加载的映像。如果你没有做,那么就不能引导新内核镜像。
重新安装 LILO 的方法就是运行/sbin/lilo。你可以编辑/etc/lilo.conf 去指定你旧内核镜像的
入口,以防新内核不能工作。更多详细的信息请参考 LILO 文档说明。
重新安装 LILO 后,到此为止你所有的设置就全部完成了。关闭系统,重启,开始享受
你的 linux 之旅吧。
错误处理:
- 如果你发现问题是由于内核 BUGS 的缘故,请检查文件 MAINTAINERS,看下是否
有人和你有问题的内核部分有关。如果没有任何人列在那里,那么第二个最好的选择就
是将他们发邮件给我([email protected]),以及给邮件列表中可能相关的任
何其他人,或者给新闻组。
- 在所有的 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
或者相似的内核调试信息在你的屏幕上,或者你的系统日志中,请完整准确地复制它。
这个转储信息可能看起来对你毫无意义,但是它包含可能有助于调试这个问题的信息。
上面转储的文本也是重要的:它提示一些关于为什么内核要转储代码的信息(在上面的
例子中,它是由错误的内核指针引起的)。 oops-tracing.txt 中更多的信息将使这个转储信
息变得更加有意义。
-
-
如果你使用 CONFIG_KALLSYMS 编译了这个内核,你能原样发送转储信息,否则,
你不得不使用"ksymoops"程序使转储信息变得有意义(但使用 CONFIG_KALLSYMS 编
译选项通常是优先被建议使用的)。这个工具能够从
ftp://ftp.<country>.kernel.org/pub/linux/utils/kernel/ksymoops/下载。
另外,你也可以手工进行转储信息查找。
像上面那样调试信息转储,如果你能查找出 EIP 值的含义,将是巨大的帮助。像这样的
16 进制值对我或任何其他人是不会有太大的帮助。它可能依赖于你安装的特定内核安
装。你应该做的是从 EIP 行(忽略"0010:")取出 16 进制值,在内核名字列表中查看一下,
看下那个内核名称列表中,究竟哪个内核函数包含这个令人讨厌的地址。
为了找出内核函数的名字,你需要找出与内核相关的系统二进制文件,它能够表现出这些问题的症状。这个文件就是“linux/vmlinux”。为了抽出函数名称列表,并将它们与崩
溃的内核的 EIP 数值比较,方法如下:
nm vmlinux | sort | less
这将给出一个排序好了的内核地址列表,从该列表中就很容易找到出错的地址。
注意:内核调试信息给出的地址并不与函数地址匹配(事实上也不太可能匹配),所以不
能使用'grep'。尽管如此,这个列表给出了内核中每个函数的起始地址,所以只需要找
到一个函数的起始地址小于 EIP 中给出的地址,但紧跟着的函数地址大于 EIP 中给出的
址(那么就定位到了该地址是在哪个函数中地,即出错在哪个函数中)。事实上,在提
交问题是给出一些"上下文"是非常不错的主意。
如果因为某些原因不能按照上面所的来提交信息,那将你的设置步骤告诉我,越多越
好。更多细节请阅读 REPORTING-BUGS 文档。
-
另外,也可使用 gdb 来在运行中调试内核。(只读,不能改变变量的值,不能设置断点)
编译时使用 -g 来编译内核;编辑 arch/i386/Makefile 文件,然后 "make clean"。当然
还需要使能 CONFIG_PROC_FS 。
重新启动新内核后,"gdb vmlinux /proc/kcore"。接着就可以使用一般的 gdb 命令了。查
看系统崩溃处的命令是"l *0xXXXXXXXX"。(XXXes 换成 EIP 的值)
使用 gdb 调试一个没有运行的内核会失败,因为 gdb 忽视内核编译时指定的起始地址。