聊聊x86设备上的GRUB

GNU GRUB(简称“GRUB”)是一个来自GNU项目的启动引导程序。GRUB是多启动规范的实现,它允许用户可以在计算机内同时拥有多个操作系统,并在计算机启动时选择希望运行的操作系统。GRUB可用于选择操作系统分区上的不同内核,也可用于向这些内核传递启动参数。

简单解释出来,可以把GRUB理解成嵌入式系统中常说的bootloader。只不过主流嵌入式系统大部分是基于RISC(ARM/MIPS/PowerPC)指令集处理器架构的,而这些嵌入式系统上电引导时使用的bootloeader也都是基于uboot改造而来的。

目前 GRUB 分成 GRUB legacy 和 GRUB 2。版本号是 0.9x 以及之前的版本都称为 GRUB Legacy ,从 1.x 开始的就称为 GRUB 2。

本文介绍的GRUB基于1.99版本,实际内容还是以GRUB Legacy使用为主,简单介绍一下工作中用到过的几个命令。

查看可用GRUB命令

进入到GRUB界面之后,通常显示如下命令:

GNU GRUB  version 1.99                              

   Minimal BASH-like line editing is supported. For the first word, TAB lists possible command completions. Anywhere else TAB lists possible device or file completions. ESC at any time exits.                           

grub>

此时执行tab命令,会显示一系列GRUB命令行下可执行命令提示:

Possible commands are:                                                           

 . [ acpi authenticate background_image badram blocklist boot break cat chainloader clear cmosclean cmostest cmp configfile continue cpuid crc cutmem   
date drivemap dump echo efiemu_loadcore efiemu_prepare efiemu_unload exit export extract_entries_configfile extract_entries_source                   extract_legacy_entries_configfile extract_legacy_entries_source false         functional_test gettext gptsync halt hashsum hdparm hello help hexdump inb initrd initrd16 inl insmod inw keymap keystatus kfreebsd kfreebsd_loadenv kfreebsd_module kfreebsd_module_elf knetbsd knetbsd_module knetbsd_module_elf kopenbsd kopenbsd_ramdisk legacy_check_password legacy_configfile legacy_initrd legacy_initrd_nounzip legacy_kernel legacy_password legacy_source linux linux16 list_env load_env loadfont loopback ls lsacpi lsapm lsfonts lsmmap lsmod lspci md5sum menuentry module module2 multiboot multiboot2 normal normal_exit ntldr outb outl outw parttool password password_pbkdf2 play probe pxe_unload read read_byte read_dword read_word reboot regexp return rmmod save_env search search.file search.fs_label search.fs_uuid sendkey serial set setparams setpci sha1sum sha256sum sha512sum shift sleep source submenu terminal_input terminal_output terminfo test test_blockarg testload true unset usb vbeinfo vbetest videoinfo videotest write_byte write_dword write_word xnu_devprop_load xnu_kernel xnu_kernel64 xnu_kext xnu_kextdir xnu_mkext xnu_ramdisk xnu_resume xnu_splash xnu_uuid zfs-bootfs zfsinfo

加载模块

GRUB自带了很多mod模块,一般存储在/boot的某个目录并以.mod结尾,通常GRUB自动加载基本模块。

grub> lsmod                                                                     
Name    Ref Count       Dependencies                                            
minicmd 1                                                                        
normal  1             terminal,boot,crypto,gfxterm,extcmd                     
gzio    0                                                                       
terminal        2                                                               
boot    2                                                                       
crypto  2                                                                       
gfxterm 2               video,font,bitmap_scale,bitmap,extcmd                   
font    3               video,bufio                                             
video   7                                                                       
bufio   4                                                                       
bitmap_scale    3               bitmap                                          
bitmap  7                                                                       
extcmd  5                                                                       
part_msdos      1                                                               
ext2    1               fshelp                                                   
fshelp  2                                                                       
biosdisk        1

特殊情况下,则需要手动加载,比如启动时最需要的文件系统和显示模块等。

grub> insmod ext2

查看设备列表

GRUB加载模块之后,如果模块兼容,设备上的外设能够自动被识别到:

grub> lspci                                                                     
00:00.0 8086:0150 [0600] Host Bridge                                            
00:01.0 8086:0151 [0604] PCI-PCI Bridge                                         
00:02.0 8086:0152 [0300] VGA Controller                                         
00:14.0 8086:1e31 [0c03] USB Controller [PI 30]                                 
00:1a.0 8086:1e2d [0c03] USB Controller [PI 20]                                 
00:1c.0 8086:1e10 [0604] PCI-PCI Bridge                                         
00:1d.0 8086:1e26 [0c03] USB Controller [PI 20]                                 
00:1e.0 8086:244e [0604] PCI-PCI Bridge [PI 01]                                 
00:1f.0 8086:1e47 [0601] ISA Bridge                                             
00:1f.2 8086:1e02 [0106] SATA Controller [PI 01]                                
00:1f.3 8086:1e22 [0c05] Serial Bus Controller                                  
00:1f.6 8086:1e24 [1180] Unknown Data Input System                              
01:00.0 177d:0091 [0b30] MIPS Processor                                          
07:00.0 8086:150f [0200] Ethernet Controller

查看磁盘分区

使用ls命令查看设备上所有可用的磁盘分区列表:

grub> ls                                                                        
(hd0) (hd0,msdos2) (hd0,msdos1) (hd1) (hd1,msdos1) (hd2) (hd2,msdos3) (hd2,msdos2) (hd2,msdos1)

设置启动分区

启动分区存储linux系统启动所需的linux内核和initrd文件。大型设备可能由于可用性需要,通常存在不止一个启动分区,比如说2个跟文件系统分区;一个紧急恢复系统分区。多个启动分区也就对应多个linux系统,如果想加载指定的操作系统,就要设置对应的操作系统内核所在的启动分区。
以设置最后一块磁盘的第一个分区(hd2,msdos1)为启动分区:

grub> set root=(hd2,msdos1)

加载linux内核

通过前文设置启动分区之后,在根目录下执行tab命令就能够看到分区下都有哪些文件可以使用,加载对应的内核文件即可:

grub> linux /
Possible files are:                                                              

lost+found/ System.map-2.6.32-220.el6.x86_64 config-2.6.32-220.el6.x86_64 efi/ initramfs-2.6.32-220.el6.x86_64.img initrd-2.6.32-220.el6.x86_64kdump.img symvers-2.6.32-220.el6.x86_64.gz vmlinuz-2.6.32-220.el6.x86_64 boot/
grub> linux /vmlinuz-2.6.32-220.el6.x86_64

加载initrd

初始 RAM 磁盘(initrd)是在实际根文件系统可用之前挂载到系统中的一个初始根文件系统。initrd 与内核绑定在一起,并作为内核引导过程的一部分进行加载。内核然后会将这个 initrd 文件作为其两阶段引导过程的一部分来加载模块,这样才能稍后使用真正的文件系统,并挂载实际的根文件系统。initrd 中包含了实现这个目标所需要的目录和可执行程序的最小集合,例如将内核模块加载到内核中所使用的 insmod 工具。在桌面或服务器 Linux 系统中,initrd 是一个临时的文件系统,用作真实文件系统加载的一个桥梁。在没有存储设备的嵌入式系统中,initrd 是永久的根文件系统。

grub> initrd /initramfs-2.6.32-220.el6.x86_64.img

执行boot命令

GRUB中boot用来执行最后的内核加载和启动的过程:

grub> boot

GRUB启动配置项实例

default=0
timeout=3

menuentry "Linux OS" {
    set root=(hd0,1)
    linux /vmlinuz-2.6.32-220.el6.x86_64 root=/dev/sdb1 console=tty1 console=ttyS1,115200n8
    initrd /initramfs-2.6.32-220.el6.x86_64.img
}
相关文章
相关标签/搜索