日期:2014-05-16  浏览次数:20671 次

Linux 引导加载学习笔记

????????? 本文以是我的学习记录,其中一些文字和图片来自参考资料所列文档,感谢作者对其知识和分享!

?

????????? 最近在自学 Linux kernel 方面的东西,这两天了粗浅的研究了下 kernel boot 过程,在此记录。这里所指 Linux 引导加载未涉及虚拟化环境,即系统未运行在 hypervisor 之上。

?

????????? Linux 通过执行不同阶段的引导加载程序(boot loader)程序来引导操作系统,在完成内核等引导之后,最终会由调度器接管 CPU,其通过启用中断来周期性的抢占控制权,处理多个用户进程/客户进程(kvm 虚拟化)。Top level 的引导过程如下图。

?

Top level boot loader

?

?

????????? 整个 Linux 系统引导共分 5 步执行操作:

?

  1. BIOS/BootMonitor 引导程序;BIOS 包括 POST 和 Runtime 服务。
  2. 被称为第一阶段的 MBR (Master boot record)引导程序;位于 BIOS 配置的启动磁盘 0 柱面 1 扇区的主引导记录,用于启动第二阶段的 linux boot loader。
  3. 被称为第二阶段的 linux boot loader;主要有 LILO (Linux loader)和 GNU GRUB (Grand unified boot loader)两种 boot loader 程序,现主流为 GRUB。最后会将默认的内核映像和 initrd 映像加载到内存中。
  4. linux kernel (及 initrd 函数)引导;负责初使化、解压 zImage/bzImage kernel 及 gzip/cpio initrd 映像,并开始执行 kernel 初使化和引导程序/过程,最后会创建 RAM 盘,加载 initrd 并执行 init 脚本,通过 LKM (linux kernel module)加载本地磁盘等驱动程序来挂载磁盘中的 root 文件系统。RAM 盘中是个完整的小型 linux 环境,在没有磁盘的嵌入式环境中,initrd 可以是最终的根文件系统,也可以通过 NFS 来挂载最终的文件系统。
  5. init 进程。用于启动 linux 配置的各项用户空间服务(demon)进程。

?

????????? 加电后首先被执行的是 BIOS (Base input/output system)程序。 嵌入式环境使用 boot monitor,它负责在一个位于 rom/flash 中预定地址开始执行引导程序,而在 PC 环境中这个启动地址是 0xFFFF0,相对来讲 BIOS 提供了更多的配置功能。它主要由两部分组成:

?

  1. POST (Power On Self Test)程序;其负责接通电源时对硬件检测,包括创建中断向量、设置寄存器、对一些外部设备进行初始化和检测等。
  2. BIOS Runtime 服务;负责为操作系统提供一些基础服务,主要与IO外设有关。

????????? 当 BIOS POST 执行完后,其将会从内存中清理,而 Runtime 服务会常驻内存,为操作系统提供一些底层的支持。最后 BIOS 将控制权交给称为第一阶段引导程序的 MBR (Master boot record)程序。

?

????????? 接下来执行的 MBR 是一个512 byte 固定大小的映像。 包括 446 byte 长的被称为初始程序加裁程序 (Initial program loader, IPL)的可执行代码和 64 byte 分区表(16 byte * 4 个),最后以 0xaa55 特殊字节结束。如下图所示。

?

MBR

?

????????? MBR 引导程序会将扫描分区表,获得唯一活动分区后,将其中的引导程序读入 RAM 并开始执行。

?

????????? MBR 启动的引导程序被称为第二阶段引导程序,它是引导的主体,是引导加载的真正部分。 Linux 中该阶段有两个流行的程序,LILO (较老)和 GRUB。如果安装了 lilo 程序,可以通过 root 用户执行如下命令来通过 lilo 生成默认配置的 MBR ,并写入到启动磁盘 0 柱面 1扇区位置上。

?

# /sbin/lilo -v -v

?

????????? 一般需要修改 lilo 的配置文件,使生成的 MBR 有效。位于 /etc/lilo.conf 。lilo 配置示例。

?

boot=/dev/hda
map=/boot/map
install=/boot/boot.b
prompt
timeout=100
compact
default=Linux
image=/boot/vmlinuz-2.4.18-14
	label=Linux
	root=/dev/hdb3
	read-only
	password=linux
other=/dev/hda
	label=WindowsXP

?

????????? boot 键指定了 lilo 在哪里安装 MBR。可以通过替换 boot=/dev/fd0 配置来指定 lilo 创建有引导记录的软盘。

?

????????? LILO 天生存在一些缺点和不足,因此 linux 在新版本中引入了 GRUB 程序。 它为了从磁盘来加裁配置和 kernel 映像,不像 LILO 只能从裸扇区中执行引导程序,而具有了访问磁盘文件系统(ext2/3、reiserfs、 jfs、fat 等)的能力。GRUB 是通过引入所谓 1.5 阶段的引导加载程序来实现这项功能的,在该阶段中,GRUB 主要来加载特殊的文件系统驱动。此后,阶段 2 的引导加载程序就可以进行加载了。

????????? 一般 GRUB 有一个不错的 GUI 界面,其中通过分析配置文件来显示了一此引导选项。在我的 ubuntu 8.10 系统中,该配置文件位于 /boot/grub/menu.lst。我们可以选择内核甚至修改附加内核参数,甚至可以使用 GRUB shell 对引导过程进行高级手工控制。我的 menu.lst 文件内容如下。

?

default  0
timeout  3
hiddenmenu

title  Ubuntu 8.10, kernel 2.6.27-11-generic
uuid   e2cf53c5-11de-4d57-a532-878901afd9b4
kernel /boot/vmlinuz-2.6.27-11-generic root=UUID=e2cf53c5-11de-4d57-a532-878901afd9b4 ro locale=zh_CN quiet splash 
initrd /boot/initrd.img-2.6.27-11-generic
quiet

title  Ubuntu 8.10, kernel 2.6.27-11-generic (recovery mode)
uuid   e2cf53c5-11de-4d57-a532-878901afd9b4
kernel /boot/vmlinuz-2.6.27-11-generic root=UUID=e2cf53c5-11de-4d57-a532-878901afd9b4 ro loca