Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1370772
  • 博文数量: 245
  • 博客积分: 10021
  • 博客等级: 上将
  • 技术积分: 3094
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-12 14:51
文章存档

2011年(2)

2009年(152)

2008年(91)

我的朋友

分类: LINUX

2009-01-27 14:40:12

  initrd 的重要性

  我们在本章稍早之前‘ boot loader 与 kernel 载入’的地方有稍微讲过这个 initrd 的咚咚, 这玩意儿可以被称为 Initial RAM Disk (初始化虚拟磁碟)。前面也提到过 initrd 可以帮助提供核心模组, 让 Linux 核心在‘开机的过程’当中不需要挂载根目录就能够载入所需要的模组,最后得以顺利进入 Linux 系统。 那你会问啊,啥时后需要 initrd 呢?这就得要从开机的流程谈起了。

  我们知道核心解压缩之后会开始侦测并且驱动所有硬体,但是核心档案并没有包含所有的硬体驱动程式, 而是一堆驱动程式以模组的方式存放在 /lib/modules/`uname -r`/kernel/.... 当中。 也就是说,在开机的过程当中我们还需要挂载根目录以方便让核心读取 /lib/modules/.... 内的核心模组, 这样才能够开机完成。简单的流程如下所示:

  1. 读取 BIOS 设定,取得开机装置与主机板晶片等资讯;
  2. 读取 MBR 内的开机载入器 (loader),并透过主机的 INT 13 硬体功能读取核心档案
  3. 核心解压缩并且侦测硬体
  4. 挂载根目录,视需要载入 /lib/modules/`uname -r`/... 内的核心模组
  5. 开始执行 init 这支程式的后续流程等......

  在上面的流程当中不知道你有没有发现一个问题,那就是第 3, 4 步骤之间,如果核心本身不认识档案系统格式时, 那如何挂载根目录啊?当然无法挂载对吧!此时就会造成无法开机的问题了!因为连根目录都无法挂载, 如何进入 Linux 系统啊?您说是吧!那么可能会出现这个问题吗?当然可能的! 如果你的 filesystem 是 LVM, RAID时,或者硬碟是 SCSI 介面时 (包括 SATA 或 USB 介面的磁碟), 那么预设的 Linux 核心档案将无法认识而无法挂载的啦! 果真如上所示,那么你除了重新编译核心将这些模组直接包在核心档案内之外,还有什么选择?有的,那就是 initrd 啦!

  initrd 可以将 /lib/modules/.... 内的‘开机过程当中一定需要的模组’包成一个档案 (档名就是 initrd), 然后在开机时透过主机的 INT 13 硬体功能将该档案读出来解压缩,此时核心就不需要挂载根目录, 因为核心所需要的模组都在 initrd 内了!其实所有的核心模组都在 /lib/modules/ 内, 因此只要能够挂载根目录,其他的模组读取都没有问题的,所以说:‘initrd 内所包含的模组大多是与开机过程有关,而主要以档案系统及硬碟模组 (如 usb, SCSI 等) 为主’的啦!

  一般来说,需要 initrd 的时刻为:

  * 根目录所在磁碟为 SATA、USB 或 SCSI 等连接介面;
  * 根目录所在档案系统为 LVM, RAID 等特殊格式;
  * 根目录所在档案系统为非传统 Linux 认识的档案系统时。

  之前鸟哥非常容易忽略 initrd 这个档案的重要性,是因为鸟哥很穷... ^_^,因为鸟哥的 Linux 主机都是较早期的硬体, 使用的是 IDE 介面的硬碟,而且并没有使用 LVM 等特殊格式的档案系统,而 Linux 预设核心本身就认识 IDE 介面的磁碟, 因此不需要 initrd 也可以顺利开机完成的。自从 SATA 硬碟流行起来后,没有 initrd 就没办法开机了! 因为 SATA 硬碟使用的是 SCSI 模组来驱动的,而 Linux 预设核心并没有包含 SCSI 模组....

  一般来说,各 distribution 提供的核心都会附上 initrd 档案,但如果你有特殊需要所以想重制 initrd 档案的话, 可以使用 mkinitrd 来处理的。这个档案的处理方式很简单, man mkinitrd 就知道了! ^_^。 我们还是简单的介绍一下去!

  [root@linux ~]# mkinitrd [--with=模组名称] initrd档名 核心版本
  参数:
  --with=模组名称:模组名称指的是模组的名字而已,不需要填写档名。举例来说,
  目前核心版本的 ext3 档案系统模组为底下的档名:
  /lib/modules/`uname -r`/kernel/fs/ext3/ext3.ko
  那你应该要写成: --with=ext3 就好了 (省略 .ko)
  initrd档名:你所要建立的 initrd 档名,尽量取有意义又好记的名字。
  核心版本  :某一个核心的版本,如果是目前的核心则是‘ `uname -r` ’


  范例一:以 mkinitrd 的预设功能建立一个 initrd 虚拟磁碟档案
  [root@linux ~]# mkinitrd initrd_`uname -r` `uname -r`
  [root@linux ~]# ll
  -rw-r--r--  1 root root 589106 Jun 27 11:39 initrd_2.6.9-55.EL
  # 由于目前的核心版本可使用 uname -r 取得,因此鸟哥使用较简单的指令来处理啰~
  # 此时 initrd_2.6.9-55.EL 会被建立起来,你可以将他移动到 /boot 等待使用。

  范例二:使用旧版核心建立含有 8139too 这个模组的 initrd 档案
  [root@linux ~]# ll /lib/modules
  drwxr-xr-x  3 root root 4096 Feb 28 23:59 2.6.9-42.0.10.EL
  drwxr-xr-x  3 root root 4096 Feb  1 05:17 2.6.9-42.0.8.EL
  drwxr-xr-x  3 root root 4096 Oct 15  2006 2.6.9-42.EL
  drwxr-xr-x  3 root root 4096 May 20 16:53 2.6.9-55.EL
  # 这个指令可以看出有多少核心版本,鸟哥想要用 2.6.9-42.EL 来玩的!

  [root@linux ~]# mkinitrd --with=8139too initrd_2.6.9-44.EL 2.6.9-42.EL
  [root@linux ~]# ll
  -rw-r--r--  1 root root 603934 Jun 27 11:45 initrd_2.6.9-44.EL
  # 如果与范例一比较,有没有发现这个档案比较大一点,因为多含了一个模组之故。

  initrd 建立完成之后,同时核心也处理完毕后,我们就可以使用 grub 来建立选单了! 底下继续瞧一瞧吧!

阅读(2041) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-01-21 11:32:08

  一般来说,需要 initrd 的时刻为:   * 根目录所在磁碟为 SATA、USB 或 SCSI 等连接介面;   * 根目录所在档案系统为 LVM, RAID 等特殊格式;   * 根目录所在档案系统为非传统 Linux 认识的档案系统时。 =========== 请看完整了,再来评论啊……

JohnBull2009-02-01 19:46:32

哪有那么复杂啊?我自己编译内核从来不用initrd...