Linux Kernel in a Nutshell 笔记(三)

5.Install and Booting from a kernel
6.Upgrading a Kernel

通过 make 得到了可执行的二进制文件以及内核模块,接下来需要安装,下面所有的步骤都需要 root 权限。

大多数发行版本都有个叫 installkernel 的脚本,该脚本可以将内核安装到正确的位置并且修改 bootloader,该脚本通常位于 mkinitrd 的包中。ubuntu 下的叫 initramfs-tools:
$ sudo apt-cache show initramfs-tools | head
Package: initramfs-tools
Priority: required
Section: utils
Installed-Size: 432
Maintainer: Ubuntu Kernel Team <[email protected]>
Original-Maintainer: Debian kernel team <[email protected]>
Architecture: all
Version: 0.92bubuntu78
Provides: linux-initramfs-tool
Depends: initramfs-tools-bin (= 0.92bubuntu78), klibc-utils (>= 1.5.9-1), busybox-initramfs (>= 1:1.13.3-1ubuntu5), cpio, module-init-tools, udev (>= 147~-5), findutils (>= 4.2.24), util-linux (>> 2.15~rc1)

CentOS 下的:
$ sudo yum info  mkinitrd.x86_64
Name       : mkinitrd
Arch       : x86_64
Version    : 5.1.19.6
Release    : 68.el5
Size       : 917 k
Repo       : installed
Summary    : Creates an initial ramdisk image for preloading modules.
License    : GPL
Description: Mkinitrd creates filesystem images for use as initial ramdisk
           : (initrd) images.  These ramdisk images are often used to preload
           : the block device modules (SCSI or RAID) needed to access the root
           : filesystem.
           :
           : In other words, generic kernels can be built without drivers for
           : any SCSI adapters which load the SCSI driver as a module.  Since
           : the kernel needs to read those modules, but in this case it isn't
           : able to address the SCSI adapter, an initial ramdisk is used.  The
           : initial ramdisk is loaded by the operating system loader (normally
           : LILO) and is available to the kernel as soon as the ramdisk is
           : loaded.  The ramdisk image loads the proper SCSI adapter and allows
           : the kernel to mount the root filesystem.  The mkinitrd program
           : creates such a ramdisk using information found in the
           : /etc/modules.conf file.

如果先前在修改 .config 文件时有模块的选项,现在则需要安装:
[email protected]:~/linux/linux-2.6.32.28$ sudo make modules_install
  INSTALL arch/x86/kernel/test_nx.ko
  INSTALL drivers/scsi/scsi_wait_scan.ko
  DEPMOD  2.6.32.28

这会将生成的新模块安装到 /lib/modules/2.6.32.28/ 下面。

接下来就可以安装内核了:
[email protected]:~/linux/linux-2.6.32.28$ sudo make install
sh /home/jaseywang/linux/linux-2.6.32.28/arch/x86/boot/install.sh 2.6.32.28 arch/x86/boot/bzImage \
                System.map "/boot"

[email protected]:~/linux/linux-2.6.32.28$ ll /boot/
total 93295
drwxr-xr-x 3 root root     6144 2012-04-29 19:56 grub/
drwx—— 2 root root    12288 2012-03-14 04:04 lost+found/
-rw-r–r– 1 root root   647033 2012-02-14 10:49 abi-2.6.32-39-server
-rw-r–r– 1 root root    67801 2012-05-01 01:06 config-2.6.32.28
-rw-r–r– 1 root root   110676 2012-02-14 10:49 config-2.6.32-39-server
-rw-r–r– 1 root root   110678 2012-04-29 19:33 config-2.6.32.59+drm33.24
-rw-r–r– 1 root root  8281079 2012-03-14 04:07 initrd.img-2.6.32-39-server
-rw-r–r– 1 root root 67351318 2012-04-29 19:55 initrd.img-2.6.32.59+drm33.24
-rw-r–r– 1 root root   160280 2010-03-23 17:40 memtest86+.bin
-rw-r–r– 1 root root  2149269 2012-05-01 01:06 System.map-2.6.32.28
-rw-r–r– 1 root root  2181430 2012-02-14 10:49 System.map-2.6.32-39-server
-rw-r–r– 1 root root  2129676 2012-04-29 19:33 System.map-2.6.32.59+drm33.24
-rw-r–r– 1 root root     1336 2012-02-14 10:54 vmcoreinfo-2.6.32-39-server
-rw-r–r– 1 root root  4103584 2012-05-01 01:06 vmlinuz-2.6.32.28
-rw-r–r– 1 root root  4118656 2012-02-14 10:49 vmlinuz-2.6.32-39-server
-rw-r–r– 1 root root  4094784 2012-04-29 19:33 vmlinuz-2.6.32.59+drm33.24

上面的命令会做以下事情:
1.确认 kernel 被正确的 build。
2.将 kernel 安装到 /boot/ 目录下,根据版本号将其重命名
3.生成 ramdisk,包括用到前面 make modules_install 生成的模块
4.通知 bootloader 修改相应的文件,这个在 ubuntu 上需要手动完成

如果你的系统中没有 installkernel 脚本,可以手动完成。安装模块:
[email protected]:~/linux/linux-2.6.32.28$ sudo make modules_install

手动复制内核到 /boot/ 目录:
[email protected]:~/linux/linux-2.6.32.28$ make kernelversion
2.6.32.28

[email protected]:~/linux/linux-2.6.32.28$ sudo cp arch/x86/boot/bzImage  /boot/bzImage-2.6.32.28
[email protected]:~/linux/linux-2.6.32.28$ sudo cp System.map  /boot/System.map-2.6.32.28

修改 grub 文件。
[email protected]:/boot$ sudo update-initramfs -u -k 2.6.32.28
sudo update-initramfs -u -k 2.6.32.28
update-initramfs: Generating /boot/initrd.img-2.6.32.28
[email protected]:/boot$ ll
total 99824
drwxr-xr-x 3 root root     6144 2012-04-29 19:56 grub/
drwx—— 2 root root    12288 2012-03-14 04:04 lost+found/
-rw-r–r– 1 root root   647033 2012-02-14 10:49 abi-2.6.32-39-server
-rw-r–r– 1 root root  4103584 2012-05-01 01:15 bzImage-2.6.32.28
-rw-r–r– 1 root root    67801 2012-05-01 01:06 config-2.6.32.28
-rw-r–r– 1 root root   110676 2012-02-14 10:49 config-2.6.32-39-server
-rw-r–r– 1 root root   110678 2012-04-29 19:33 config-2.6.32.59+drm33.24
-rw-r–r– 1 root root  2581062 2012-05-01 01:28 initrd.img-2.6.32.28
-rw-r–r– 1 root root  8281079 2012-03-14 04:07 initrd.img-2.6.32-39-server
-rw-r–r– 1 root root 67351318 2012-04-29 19:55 initrd.img-2.6.32.59+drm33.24
-rw-r–r– 1 root root   160280 2010-03-23 17:40 memtest86+.bin
-rw-r–r– 1 root root  2149269 2012-05-01 01:06 System.map-2.6.32.28
-rw-r–r– 1 root root  2181430 2012-02-14 10:49 System.map-2.6.32-39-server
-rw-r–r– 1 root root  2129676 2012-04-29 19:33 System.map-2.6.32.59+drm33.24
-rw-r–r– 1 root root     1336 2012-02-14 10:54 vmcoreinfo-2.6.32-39-server
-rw-r–r– 1 root root  4103584 2012-05-01 01:06 vmlinuz-2.6.32.28
-rw-r–r– 1 root root  4118656 2012-02-14 10:49 vmlinuz-2.6.32-39-server
-rw-r–r– 1 root root  4094784 2012-04-29 19:33 vmlinuz-2.6.32.59+drm33.24

如果需要升级一个内核,步骤跟上面的差不多:
1.获取 patch 文件
2.打 patch
3.根据已有的 .config 生成新的 .config 文件
4.build
5.install

其中 4、5 两步骤跟之前一样,下面叙述 1、2、3 步骤。补丁怎么打?
* stable kernel patch apply to the base kernel version。也就是说 2.6.17.10 patch 只适用于 2.6.17 版本的内核,2.6.17.10 patch 不适用于 2.6.17.9 内核版本
* base kernel release patches only apply to the previous base kernel version。也就是说 2.6.18 patch 只适用于 2.6.17 内核版本,不会适用于 2.6.17.x 的版本。
* Incremental patches updrade from a specific release to the next release。

[email protected]:~/linux$ cp linux-2.6.32.28/.config good_config
[email protected]:~/linux$ ls

good_config  linux-2.6.32.28  linux-2.6.32.28.tar.gz  patch-2.6.32.28-29
[email protected]:~/linux$ wget ftp://ftp.kernel.org/pub/linux/kernel/v2.6/longterm/v2.6.32/incr/patch-2.6.32.28-29.gz
[email protected]:~/linux$ gunzip -d patch-2.6.32.28-29.gz
[email protected]:~/linux$ cd linux-2.6.32.28/
[email protected]:~/linux/linux-2.6.32.28$ patch  -p1 < ../patch-2.6.32.28-29

patching file Documentation/kernel-parameters.txt
patching file Makefile
patching file arch/ia64/include/asm/system.h
patching file arch/parisc/kernel/firmware.c
patching file arch/powerpc/include/asm/system.h
patching file arch/powerpc/kernel/cpu_setup_

[email protected]:~/linux/linux-2.6.32.28$ head -n 5 Makefile
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 32
EXTRAVERSION = .29
NAME = Man-Eating Seals of Antiquity

可以发现大了补之后,内核的版本号已经改变了。以前使用 make menuconfig,现在只要使用 oldconfig 就可以了,因为是基于现在的 .config 文件修改的,只需要修改 patch 新增加的选项:
$ make oldconfig

还有叫 silentoldconfig 的选项,跟上面的类似,不同的是有问才有答。接下来的跟之前的都一样。