Linux Kernel in a Nutshell - 5
Installing and Booting from a Kernel
本书年代有点久,有些内容已经淘汰不用了
上一章展示了如何下载和编译你的内核。现在你具有了一个可执行文件,以及一些模块,现在是时候安装并启动这个内核了。本章,所有的命令都将以 root
用户权限运行。
Using a Distribution's Installation Scripts
几乎所有的发布都带有一个安装脚本称为 installkernel
,可以被编译系统用来自动安装一个编译得到的内核到指定的位置,并修改 bootloader
,这样开发者就不需要做额外的工作。
提供的 installkernel
脚本通常放在一个称为 mkinitrd
包中
如果你编译了需要使用的模块,使用下面的方法来安装内核,首先键入:
# make modules_install
这会将所有编译得到的模块安装到文件系统中合适的位置,以方便内核找到。模块放置在 /lib/modules/kernel_version
目录下,其中 kernel_version
你刚编译的内核版本号。
在成功安装内核模块之后,必须安装主内核镜像:
# make install
这会进行下面的过程:
- 内核编译系统将会校验内核是否成功编译
- 内核编译系统将会安装静态内核分区到
/boot
目录,并将这个可执行文件基于内核版本进行命名。 - 任何需要的初始化
ramdisk
镜像将会自动创建,并在modules_install
阶段使用刚才安装的模块 - 通知
bootloader
存在一个新的内核,并将新内核添加到合适的菜单,这样下次启动时,用户可以进行选择 - 在完成上面的操作后,内核就成功的安装了,此时可以安全地重启并尝试新内核镜像了。注意到不会覆写任何老的内核镜像,因此,如果新的内核存在任何问题,都不是致命的
Installing by Hand
如果你的发布版本中没有 installkernel
命令,或者你希望手动进行一次操作,来完成各个步骤的含义,下面是详细步骤。
模块必须安装:
# make module_install
静态内核镜像必须复制到 /boot
目录,对于一个 i386
内核需要做下面的操作:
# make kernelversion
注意到,内核版本可能与你的内核不同,因此后面的命令使用你自己的内核版本 KERNEL_VERSION
替换各个命令:
# cp arch/i386/boot/bzImage /boot/bzImage-KERNEL_VERSION
# cp System.map /boot/System.map-KERNEL_VERSION
修改 bootloader
,让其知晓有了新内核。这涉及到编辑你使用的 bootloader
的配置文件,后面会介绍。
如果启动过程不顺利,通常是因为需要一个初始化 ramdisk
镜像。为了正确创建它,可以参考下面的脚本:
#!/bin/sh
#
# installs a kernel
#
make modules_install
# find out what kernel version this is
for TAG in VERSION PATCHLEVEL SUBLEVEL EXTRAVERSION ; do
eval `sed -ne "/^$TAG/s/ //gp" Makefile`
done
SRC_RELEASE=$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION
# figure out the architecture
ARCH=`grep "CONFIG_ARCH " include/linux/autoconf.h | cut -f 2 -d "\""`
# copy the kernel image
cp arch/$ARCH/boot/bzImage /boot/bzImage-"$SRC_RELEASE"
# copy the System.map file
cp System.map /boot/System.map-"$SRC_RELEASE"
echo "Installed $SRC_RELEASE for $ARCH"
Modifying the Bootloader for the New Kernel
现在有两个主流的 Linux
内核 bootloader
,GRUB
以及 LILO
。GRUB
是比较常用的一种,相较于 LILO
更加简单。
为了确定你的系统使用的 bootloader
是什么,去看一下 /boot
目录,如果有一个 grub
子目录:
$ ls -F /boot | grep grub
grub/
那么你使用的就是 GRUB
启动引导程序。如果没有这个目录,查看 /etc/lilo.conf
文件是否存在:
$ ls /etc/lilo.conf
/etc/lilo.conf
如果这个文件存在,那么你在使用 LILO
作为启动引导程序。
对这两个引导程序添加新内核的步骤是不同的,因此会分开进行讲解。
GRUB
为了让 GRUB
知道有一个新内核存在,你需要做的就是修改 /boot/grub/menu.lst
文件,这个文件的具体细节,以及可以使用的不同选项,可以查看 GRUB
的 info
页:
$ info grub
添加一个新内核到 /boot/grub/menu.lst
文件最简单的方式是复制一个现有的条目,比如,考虑下面 Gentoo
系统中存在的 menu.lst
:
timeout 300
default 0
splashimage(hd0,0)/grub/splash.xpm.gz
title 2.6.16.11
root (hd0,0)
kernel /bzImage-2.6.16.11 root=/dev/sda2 vga=0x0305
title 2.6.16
root (hd0,0)
kernel /bzImage-2.6.16 root=/dev/sda2 vga=0x0305
以 title
起始的行定义了一个新内核入口,因此这个文件包含两个入口。简单复制这一个条目中的内容:
title 2.6.16.11
root (hd0,0)
kernel /bzImage-2.6.16.11 root=/dev/sda2 vga=0x0305
之后在文件的结尾处添加要安装的新内核,因为要体现在启动菜单中,因此需要令信息表述地有意义。在我们的例子中,可以修改为:
timeout 300
default 0
splashimage(hd0,0)/grub/splash.xpm.gz
title 2.6.16.11
root (hd0,0)
kernel /bzImage-2.6.16.11 root=/dev/sda2 vga=0x0305
title 2.6.16
root (hd0,0)
kernel /bzImage-2.6.16 root=/dev/sda2 vga=0x0305
title 2.6.17.11
root (hd0,0)
kernel /bzImage-2.6.17.11 root=/dev/sda2 vga=0x0305
在保存这个文件之后,重启系统,确保新内核镜像的 title
在启动菜单中。使用上下箭头来高亮选择新的内核版本,按下回车键来启动新内核镜像。
LILO
为了让 LILO
知道有新的内核,必须修改 /etc/lilo.conf
配置文件,之后运行 lilo
命令来应用修改之后的配置文件。详细的 LILO
配置文件结构,可以查看 LILO
manpage
:
$ man lilo
最简单向 /etc/lilo.conf
配置文件中添加新内核条目的方法是复制一个现有的条目。比如,考虑 Gentoo
系统中下面的 LILO
配置文件:
boot=/dev/hda
prompt
timeout=50
default=2.6.12
image=/boot/bzImage-2.6.15
label=2.6.15
read-only
root=/dev/hda2
image=/boot/bzImage-2.6.12
label=2.6.12
read-only
root=/dev/hda2
image
部分就是一个新内核条目,因此复制这一部分内容。添加后的内容如下:
boot=/dev/hda
prompt
timeout=50
default=2.6.12
image=/boot/bzImage-2.6.15
label=2.6.15
read-only
root=/dev/hda2
image=/boot/bzImage-2.6.12
label=2.6.12
read-only
root=/dev/hda2
image=/boot/bzImage-2.6.17
label=2.6.17
read-only
root=/dev/hda2
在保存文件之后,运行 /sbin/lilo
程序将配置写道盘内:
# /sbin/lilo
现在可以安全重启系统了。新的内核选择可以在启动时看到了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~