Linux 内核 4.x 版 http://kernel.org/
这些是 Linux 4.x 版的发布说明。请仔细阅读,它们会告诉您这是什么、 如何安装内核,以及出现问题时应如何处理。
什么是 LINUX?
Linux 是 Unix 操作系统的克隆,由 Linus Torvalds 从零开始编写,并得到 了来自网络的一个松散黑客团队的协助。它致力于实现与 POSIX 和单一 UNIX 规范(Single UNIX Specification)的兼容。
它拥有您期望在现代功能完整的 Unix 中拥有的所有特性,包括真正的多任务 处理、虚拟内存、共享库、按需加载、共享写时复制可执行文件、妥善的内存 管理,以及包括 IPv4 和 IPv6 在内的多栈网络。
它按照 GNU 通用公共许可证分发——更多详情请参阅随附的 COPYING 文件。
它能在什么硬件上运行?
尽管最初是为基于 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、 Tilera TILE、AVR32 和 Renesas M32R 架构上。
只要具备分页内存管理单元(PMMU)以及 GNU C 编译器(gcc)(GNU 编译器 套件 GCC 的一部分)的移植版本,Linux 就很容易移植到大多数通用的 32 位 或 64 位架构上。Linux 也被移植到了一些没有 PMMU 的架构,不过功能显然 会有所限制。 Linux 还被移植到了自身。现在您可以将内核作为用户空间应用程序运行—— 这称为 UserMode Linux(UML)。
文档:
互联网上有大量电子形式的文档和书籍,既有专门针对 Linux 的,也涉及 一般 UNIX 问题。我建议在任何 Linux FTP 站点的文档子目录中查找 LDP (Linux 文档计划)丛书的书籍。本 README 并非旨在作为系统的文档: 有更好的资料来源可用。
Documentation/ 子目录中有各种 README 文件:它们通常包含针对某些 驱动程序的内核特定安装说明。请参阅 Documentation/00-INDEX 以了解 每个文件包含的内容。请阅读 Changes 文件,因为它包含升级内核可能 引发的问题的信息。
Documentation/DocBook/ 子目录包含几本面向内核开发者和用户的指南。 这些指南可以渲染为多种格式:PostScript(.ps)、PDF、HTML 和 man 手册页等。安装后,运行 "make psdocs"、"make pdfdocs"、 "make htmldocs" 或 "make mandocs" 将以请求的格式渲染文档。
安装内核源代码:
如果要安装完整源代码,请将内核 tarball 放在您有权限的目录(例如 您的主目录)中,然后解包:
xz -cd linux-4.X.tar.xz | tar xvf -
用最新内核的版本号替换 "X"。
不要使用 /usr/src/linux 目录!该目录中有一组(通常不完整的)内核 头文件,供库头文件使用。它们应当与库匹配,不应被碰巧最新的内核 (kernel-du-jour)弄乱。
您也可以通过打补丁在 4.x 各版本之间升级。补丁以 xz 格式发布。要 通过打补丁方式安装,请获取所有较新的补丁文件,进入内核源代码的 顶层目录(linux-4.X),然后执行:
xz -cd ../patch-4.x.xz | patch -p1
对于比当前源代码树版本 "X" 大的所有版本,请_按顺序_替换 "x",这样 就应该没问题了。您可能想要删除备份文件(some-file-name~ 或 some-file-name.orig),并确保没有失败的补丁(some-file-name# 或 some-file-name.rej)。如果有,那说明您或我犯了错误。
与 4.x 内核的补丁不同,4.x.y 内核(也称为 -stable 内核)的补丁不是 增量的,而是直接应用于基础 4.x 内核。例如,如果您的内核基础版本是 4.0,并且想要应用 4.0.3 补丁,则不能先应用 4.0.1 和 4.0.2 补丁。 同样,如果您运行的是内核版本 4.0.2,并且想要跳到 4.0.3,则必须先 反转 4.0.2 补丁(即 patch -R),_然后_再应用 4.0.3 补丁。您可以 在 Documentation/applying-patches.txt 中阅读更多相关内容。
另外,可以使用 patch-kernel 脚本来自动化此过程。它会确定当前内核 版本并应用找到的任何补丁。
linux/scripts/patch-kernel linux
上面命令中的第一个参数是内核源代码的位置。补丁从当前目录应用,但 也可以将另一个目录指定为第二个参数。
确保没有残留的过期 .o 文件和依赖项:
cd linux make mrproper
现在您应该已经正确安装了源代码。
软件要求
编译和运行 4.x 内核需要各种软件包的最新版本。请参阅 Documentation/Changes 了解所需的最低版本号以及如何获取这些软件包 的更新。请注意,使用过旧版本的这些软件包可能会导致非常难以追踪的 间接错误,因此不要以为在构建或运行期间出现明显问题时只需更新软件包 即可。
内核的 BUILD(构建)目录:
编译内核时,默认情况下所有输出文件将与内核源代码存储在一起。 使用 "make O=output/dir" 选项可以指定输出文件(包括 .config)的 另一个位置。 示例:
内核源代码:/usr/src/linux-4.X
构建目录: /home/name/build/kernel
要配置和构建内核,请使用:
cd /usr/src/linux-4.X
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 nconfig" 增强的基于文本的彩色菜单。
"make xconfig" 基于 X windows(Qt)的配置工具。
"make gconfig" 基于 X windows(Gtk)的配置工具。
"make oldconfig" 根据现有 ./.config 文件的内容对默认问题给出答案, 并询问关于新的配置符号的问题。
"make silentoldconfig" 与上面相同,但避免用已回答过的问题使屏幕杂乱; 另外还会更新依赖关系。
"make olddefconfig" 与上面相同,但将新符号设置为其默认值而不提示。
"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 文件。
"make localmodconfig" 基于当前配置和已加载模块(lsmod)创建配置。 禁用已加载模块不需要的任何模块选项。
要为另一台机器创建 localmodconfig,请将该机器
的 lsmod 保存到文件中,并将其作为 LSMOD 参数传入。
target$ lsmod > /tmp/mylsmod
target$ scp /tmp/mylsmod host:/tmp
host$ make LSMOD=/tmp/mylsmod localmodconfig
上述操作在交叉编译时同样适用。
"make localyesconfig" 与 localmodconfig 类似,只是它会将所有模块选项 转换为内置(=y)选项。
您可以在 Documentation/kbuild/kconfig.txt 中找到有关使用 Linux 内核 配置工具的更多信息。
关于 "make config" 的说明:
不必要的驱动程序会使内核变大,并且在某些情况下可能导致问题: 探测不存在的控制器卡可能会干扰您的其他控制器
将 "Processor type"(处理器类型)设置为高于 386 来编译内核,将会 产生一个无法在 386 上工作的内核。内核会在启动时检测到这一点并放弃。
编译了数学仿真(math-emulation)的内核,如果存在协处理器,仍会使用 它:在这种情况下数学仿真根本不会被使用。内核会稍微大一些,但在不同 的机器上都能工作,无论它们是否有数学协处理器。
"kernel hacking"(内核调试)配置细节通常会导致内核变大或变慢(或两者 兼有),甚至可能通过配置一些例程主动尝试破坏不良代码以找出内核问题 (kmalloc())而使内核更不稳定。因此,对于 "development"(开发)、 "experimental"(试验)或 "debugging"(调试)功能的问题,您可能应该 回答 'n'。
编译内核:
确保您至少有 gcc 3.2 可用。 更多信息请参阅 Documentation/Changes。
请注意,您仍然可以使用此内核运行 a.out 用户程序。
执行 "make" 以创建压缩的内核映像。如果您安装了适合内核 makefile 的 lilo,也可以执行 "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" 为常规内核版本附加 一个唯一后缀。LOCALVERSION 可以在 "General Setup"(常规设置)菜单中 设置。
要启动您的新内核,您需要将内核映像(例如编译后的 .../linux/arch/i386/boot/bzImage)复制到常规可启动内核所在的位置。
不再支持在没有 LILO 等引导加载程序协助的情况下直接从软盘启动内核。
如果您从硬盘启动 Linux,那么很可能使用 LILO,它使用 /etc/lilo.conf 文件中指定的内核映像。内核映像文件通常是 /vmlinuz、/boot/vmlinuz、 /bzImage 或 /boot/bzImage。要使用新内核,请保存旧映像的副本,并将新 映像复制到旧映像之上。然后,您必须重新运行 LILO 以更新加载映射!! 否则,您将无法启动新的内核映像。
重新安装 LILO 通常只需运行 /sbin/lilo。您可能希望编辑 /etc/lilo.conf, 为旧内核映像(例如 /vmlinux.old)指定一个条目,以防新内核无法工作。 更多信息请参阅 LILO 文档。
重新安装 LILO 后,一切就都准备好了。关闭系统,重新启动,尽情享受吧!
如果您需要更改内核映像中的默认根设备、视频模式、ramdisk 大小等, 请使用 'rdev' 程序(或在适当时使用 LILO 启动选项)。更改这些参数无需 重新编译内核。
用新内核重新启动,尽情享受吧。
如果出现问题:
如果遇到似乎是由内核错误引起的问题,请查看 MAINTAINERS 文件,看看 是否有特定人员负责您遇到问题的内核部分。如果那里没有列出任何人,那么 次优的办法是将问题邮寄给我([email protected]),也可能 发给任何其他相关的邮件列表或新闻组。
在所有错误报告中,请说明您指的是哪个内核、如何重现问题,以及您的 环境配置是什么(请运用您的常识)。如果问题是新出现的,请告诉我;如果 问题由来已久,请尽量告诉我您最初注意到它是什么时候。
如果错误导致类似如下的消息
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
或屏幕上或系统日志中出现类似的调试信息,请精确地复制它。该转储在 您看来可能难以理解,但它确实包含有助于调试问题的信息。转储上方的文本 也很重要:它说明了内核为何转储代码(在上面的示例中,是由于内核指针 错误)。有关如何理解转储的更多信息,请参阅 Documentation/oops-tracing.txt
如果您使用 CONFIG_KALLSYMS 编译内核,可以直接发送转储;否则,您必须 使用 "ksymoops" 程序来理解转储(但通常更倾向于使用 CONFIG_KALLSYMS 编译)。该工具可以从 ftp://ftp..kernel.org/pub/linux/utils/kernel/ksymoops/ 下载。 或者,您也可以手动进行转储查找:
在调试此类转储时,如果您能查出 EIP 值的含义,将大有帮助。十六进制值 本身对我和其他人都没有太大帮助:它取决于您的特定内核配置。您应该做的 是取出 EIP 行中的十六进制值(忽略 "0010:"),在内核符号表中查找,看看 哪个内核函数包含出错地址。
要找出内核函数名称,您需要找到与出现症状的内核相关联的系统二进制文件。 这就是文件 'linux/vmlinux'。要提取符号表并将其与内核崩溃时的 EIP 匹配, 请执行:
nm vmlinux | sort | less
这会给出按升序排列的内核地址列表,从中很容易找到包含出错地址的函数。 请注意,内核调试消息给出的地址不一定与函数地址完全匹配(事实上,这 不太可能),所以您不能直接 'grep' 该列表:不过,该列表会给出每个内核 函数的起始地址,因此通过查找起始地址低于您要搜索的地址、但后面跟着 一个更高地址的函数,您就能找到想要的那个。事实上,在问题报告中加入 一点"上下文"(在感兴趣的那一行周围给出几行)可能是个好主意。
如果您出于某种原因无法做到上述操作(您有预编译的内核映像或类似情况), 尽可能详细地告诉我您的环境配置会有所帮助。请阅读 REPORTING-BUGS 文档 了解详情。
另外,您可以在正在运行的内核上使用 gdb。(只读;即您不能更改值或设置 断点。)为此,首先用 -g 编译内核;适当编辑 arch/i386/Makefile,然后 执行 "make clean"。您还需要启用 CONFIG_PROC_FS(通过 "make config")。
用新内核重新启动后,执行 "gdb vmlinux /proc/kcore"。您现在可以使用 所有常用的 gdb 命令。用于查找系统崩溃点的命令是 "l *0xFFFFFFFF"。 (将 XXX 替换为 EIP 值。)
对未运行的内核使用 gdb 目前会失败,因为 gdb(错误地)忽略了内核编译 时使用的起始偏移量。