文章目录
- README
-
- 什么是 Linux ?
- Linux 可以运行在什么样的硬件上
- 安装内核源码
- 软件要求
- 用于内核编译的目录
- 配置内核
- 编译内核
- 如果出错
README
本系列为 Linux v5 发布笔记。请仔细阅读,这会告诉你所有你想知道的,解释如何安装内核,并且告诉你出错时该怎么做。
什么是 Linux ?
Linux 是 Unix 操作系统的一个克隆,由 Linus Torvalds 在散布于网络的黑客团队的帮助下从零编写。Linux 旨在符合 POSIX 和 Single UNIX 规范。
Linux 具有你在当代羽翼丰满的 Unix 系统上所能期望到的全部特性,包括真实的多任务,虚拟内存,共享库,按需加载,共享的写入时拷贝可执行,恰当的内存管理和多个网络栈(包括 IPv4 和 IPv6)
Linux 在 GNU General Public License v2 许可证下发布 – 更多细节可以查看附加的 COPYING 文件。
Linux 可以运行在什么样的硬件上
虽然起初只为 32-bit 的 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 Xtensa 和 ARC architectures。
Linux 很容易被移植到具有分页管理单元(PMMU) 和相应的 gcc 版本的通用 32 位或 64 位体系架构上。Linux 同样被大量移植到无 PMMU 的平台上,虽然功能上显著受限。
Linux 也可以移植到其自身。你现在可以将内核作为用户空间应用来运行 - 也就是用户模式的 Linux (UML)。
安装内核源码
-
如果安装整个源码,需要将内核归档文件(tarball) 放入到一个你具有权限的目录(比如 home 目录),然后解压:
xz -cd linux-5.x.tar.xz | tar xvf -
根据需要更改上诉命令中的文件名。
不要使用 /usr/src/linux 目录!该目录下拥有一些会被库头文件用到的内核头文件。这些头文件应当和库文件相匹配,并且不能其他内核头文件混淆。
-
你也可以通过补丁来升级内核。补丁以 xz 格式发布。为了安装补丁,需要获取所有较新的补丁文件,然后进入到内核源文件(linux-5.x)的根目录并执行:
xz -cd ../patch-5.x.xz | patch -p1
注意补丁需要按顺序安装。然后你也可以删除所有的备份文件(如 some-file-name~ 或 some-file-name.orig),同时要确保没有失败的补丁(some-file-name# 或 some-file-name.rej)。如果有失败的补丁,要么是你操作错误,要么就是补丁有问题。
和 5.x 内核不一样,5.x.y 内核(也就是稳定版内核)的补丁不是递增的,而是直接安装到 5.x 的内核上。比如,如果你的基本内核是 5.0 版本,然后你想安装 5.0.3 补丁,则禁止先打上 5.0.1 和 5.0.2 补丁。相似的,如果内核版本是 5.0.2 ,然后想升级到 5.0.3,则必须在安装 5.0.3 补丁之前先反转 5.0.2 的补丁(也就是
patch -R
)。除了手动安装补丁,你还可以通过 patch-kernel 脚本来自动完成这一过程。下面命令会决定当前内核版本,并安装任何找到的补丁:
linux/scripts/patch-kernel linux
上述命令中的第一个参数为内核源码的位置。补丁是从当前目录安装,但也可以通过第二个参数来指定补丁所在的目录。
-
确保没有任何未更新的 .o 文件和相关依赖:
cd linux make mrproper
这时你应该已经安装了正确的源码
软件要求
编译 5.x 内核,各种软件都尽量是最新的。如果使用特别老的软件版本,则可能会导致间接错误,并且很难跟踪。
用于内核编译的目录
编译内核的时候,所有的输出文件默认会和内核源码放在一起。使用 make 0=output/dir
选项,可以指定输出目录(包括 .config 文件)。一旦使用了 0=output/dir
选项,则所有的 make
调用都需要加上该选项。
配置内核
即便你只升级了一个小版本,也不要跳过该步骤。每一个发布版本中,都会加入新的配置选项,并且如果没有进行正确的配置,可能会导致各种奇怪的问题。在新版本中可以使用已经存在的配置来减少配置内核的工作量 – make oldconfig
。
可替代的配置命令如下:
命令 | 描述 |
---|---|
make config |
普通文本接口 |
make menuconfig |
基于文本的彩色菜单、选项列表、对话框 |
make nconfig |
增强的基于文本的彩色菜单 |
make xconfig |
基于 QT 的配置工具 |
make gconfig |
基于 GTK+ 的配置工具 |
make oldconfig |
使用以存在的 ./.config 文件里的配置,然后再询问新版本的配置 |
make olddefconfig |
和上面一样,但会把新配置设为默认值,而不进行提示 |
make defconfig |
使用默认值来创建 ./.config 文件,这些值来源于 arch/$ARCH/defconfig 或 arch/$ARCH/configs/${PLATFORM}_defconfig |
make ${PLATFORM}_defconfig |
使用来自于 arch/$ARCH/configs/${PLATFORM}_defconfig 的默认值创建 ./.config 文件 |
make allyesconfig |
创建一个 ./.config 文件,其中所有值都是 y |
make allmodconfig |
创建一个值全是 m 的 ./.config 文件 |
make allnoconfig |
创建一个所有值为 n 的 ./.config 文件 |
make randconfig` | 创建一个具有随即值的 ./.config 文件 |
make localmodconfig |
创建一个基于当前 config 和已加载的模块的 config 文件。禁用那些没必要加载的模块 |
make localyesconfig |
和 localmodconfig 相似,除了所有模块选项都是 =y (内置) |
make kvmconfig |
使能用于 kvm guest 内核的额外选项 |
make xenconfig |
是能用于 xen dom0 guest 内核的额外选项 |
make tinyconfig |
尽可能配置最小的内核 |
其中,你可以通过 lsmod 将本机已加载内核模块保存到一个文件中,然后在其他机器上使用该文件通过 localmodconfig 选项配置内核 :
lsmod > /tmp/mylsmod
scp /tmp/mylsmod host:/tmp
make LSMOD=/tmp/mylsmod localmodconfig
注意:
- 不必要的驱动会让内核变大,在部分情况下,还会导致一些问题:探测不存在的控制器会让其他控制感到困惑。
- 使用仿真的数学处理还是会使用协处理器的(如果有的花),这种情况下始终不会通过软仿进行数学处理的。内核会稍大一点,但会更通用一些(不管是否存在协处理器)
编译内核
-
确保 gcc 版本至少为 3.2.
-
make
命令会创建一个压缩的内核映像,如果你安装了适用于内核 makefiles 的 lilo ,则也会执行make install
,但是你最好县检查一下自己的 lilo 设置。在真正安装的时候,会需要 root 权限(编译不需要)。
-
显示内核编译输出:
正常情况下,内核会在安静模式下编译(非完全静音)。如果需要显示的输出编译时所执行的动作,可以使用V=1
选项。如果需要输出重新构建目标文件的理由时,可以使用V=2
选项。默认为V=0
。 -
手动的备份内核,以免新版本有 bug,这样可以回退。同样,手动备份好与内核相关的模块。
但是,也可以通过内核配置选项
LOCALVERSION
来为内核添加版本后缀。 -
为了能够启动新的内核,需要将内核映像复制到你通常可引导的内核所在的地方。
-
直接从软盘而非 bootloader(如 LILO)中启动内核,不再受支持。
如果你使用 LILO 从硬盘上启动 Linux,则会使用 /etc/lilo.conf 中所指定的内核映像。内核映像文件通常是 /vmlinuz,/boot/vmlinuz,/bzImage 或者 /boot/bzImage。为了使用新的内核,将旧内核备份后,使用新内核覆盖旧内核,然后更新 loading map,否则无法启动新的内核。
通常只需要运行 /sbin/lilo 便可以重新安装 LILO。你也可以编辑 /etc/lilo.conf 来指定旧内核映像的条目(如 /vmlinux.old)。重新安装 LILO 后便可以重启系统了。
如果需要更改默认的根设备,视频模式,ramdisk 大小等,则可以通过 LILO 启动选项或者内核映像中的 rdev
程序(不需要重新编译内核)。
如果出错
-
如果是因为内核 bug 而出错,可以通过 MAINTAINERS 文件中找到相关内核部分的维护者,然后将你的问题发送给他。如果找不到任何相关的维护者,则可以直接发送给 Linus Torvalds 本人 (torvalds@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
或者类似的调试信息,请原文复制到报告中。
-
在上面的 dumps 中,如果能知道 EIP 值的含义是最好的。该 16 进制值依赖于特定的内核设置。你可以从内核名称列表中查看到哪一个函数包含该地址。以下命令可以按内核地质升序获取函数名(预编译的内核映像可能无法获取)。
-
你也可以对正在运行的内核使用 gdb(只读模式,你无法更改值或者设置断点)。为了能够使用 gdb,需要使用 gcc 的 -g 选项,为此要恰当的修改 arch/x86/Makefile,然后运行
make clean
。你还需要使能CONFIG_PROC_FS
(通过make config
)。使用新内核重启后,使用
gdb vmlinux /proc/kcore
,这是你可以使用所用常规的 gdb 命令。查看系统崩溃所在的位置为l *0xXXXXXXXX
(将 XXXXXXXX 替换为EIP
的值)