Grub

最後更新: 2019-05-17

目錄

 


Grub 介紹

 

現時在 Linux 上會看到 Grub 有以下兩個版本, 分別是

  • Grub1(legacy) (versions 0.9x) <-- Debian_5
  • Grub2 (versions1.9x) <-- Debian_6

查看當前 version:

grub-install -v

Grub 1 共分 3 個部份

第 1 部份是在 MBR 的

stage-1   <-- 440 bytes

由於空間所限, 它主要功能是載入 stage-1.5

第 2 部份 stage-1.5 是在 MBR 與第一個分區之間的空位上

stage-1.5 ( 負責支持 fs: fat, ntfs, ext3, reiserfs) [static list of sectors]

它具有讀取 fs 的能力, 負責載入 stage-2

第 3 部份是 stage-2, 它是以檔案形式存在在 /boot 資料夾內

stage-2 ( 負責載入 Kernel: vmlinuz, initrd )

設定及有關檔案在

 - /etc/default/grub

 - /boot/grub

 


Check BIOS / EFI Boot

 

[ -d /sys/firmware/efi ] && echo UEFI || echo BIOS

efibootmgr

 


Grub 1 (GRUB Legacy)設定

 

修改 Global 的 Default 設定值(下次更新 Kernel 的會引用它)

/etc/default/grub

GRUB_DEFAULT=0
GRUB_TIMEOUT=2
GRUB_CMDLINE_LINUX_DEFAULT="quiet vga=0x315 console=ttyS0,115200n80 console=tty0 console=tty0"
                                                       # parity, bits, flow control

更新 grub 的設定檔 (/boot/grub/grub.cfg):

執行: update-grub

之後在 grub.cfg 內就會有類似設定:

...
kernel /vmlinuz26 root=/dev/vda2 ro console=ttyS0,115200n80 console=tty0
... 

P.S.

注意那兩個 console 的次序

 


menu.lst

 

/boot/grub/menu.lst

# My Linux
title  My Linux
root   (hd0,0)
kernel /vmlinuz-linux root=/dev/sda1 ro
initrd /initramfs-linux.img

 


安裝 grub 到 MBR

 

方法1: grub-install

grub-install reads the device.map, that is the device file to BIOS drive mapping

Options

  • --recheck: Probe a device map even if it already exists

# 把新 fs 的 root 掛到 /mnt/new_root 上, 並把 boot loader 安到 /dev/sdb 上

grub-install  --no-floppy  --recheck  --root-directory=/mnt/new_root   /dev/sdb

P.S.

  • Probing devices to guess BIOS drives. This may take a long time.
  • Installation finished. No error reported.
  • This is the contents of the device map /mnt/new_root/boot/grub/device.map.

方法2: 用 grub 指令安裝:(grub v1)

# mount drive

mkdir /mnt/tmp

mount /dev/sdXy /mnt/tmp

mkdir -p /mnt/tmp/boot/grub

cp /boot/grub/*stage* /mnt/tmp/boot/grub

# 進入 grub shell

grub

# grub shell cmd

find /mypart

root (hd?,?)

setup (hd?)

quit

 


重建 initrd

 

  • Centos: mkinitrd
  • Debian: update-initramfs

修改 /etc/modprobe

virtio_balloon
virtio_net
virtio_blk

詳見

http://datahunter.org/initramfs

 


重建 Boot Loader

 

Step1: Identification of the boot and root filesystems

fsarchiver probe simple

Step2: Reinstallation of Grub using chroot

mkdir /mnt/linux

mount /dev/sda2 /mnt/linux

mount -o bind /proc /mnt/linux/proc

mount -o bind /dev /mnt/linux/dev

mount -o bind /sys /mnt/linux/sys

# chroot

chroot /mnt/linux /bin/bash

# Install boot loader

mount /dev/sda1 /boot/

grub-install /dev/sda

OR

# 當 /etc/mtab 沒有對應 "/boot" mount point 時, 就要加上 '--root-directory=/boot'

grub-install --root-directory=/boot /dev/vda

 


Grub Shell Command

 

find

# 什麼都用 "/" 開始

i.e. 例出 "/" 有的檔案及目錄

find / TAB

cat

看某 file 內容

root (hd0,0)

設定當前 Partitation

kernel

# set Kernel parameters

kernel /boot/vmlinuz-linux root=/dev/sda1

initrd

未必要

boot

用 kernel & initrd 設定去 boot 機

# 安裝 grub 到 HardDisk (sda / hda ...)

setup (hd0)

 



Grub2 Config

 

# Centos 7 Config

/etc/default/grub.cfg

# GRUB_DEFAULT=saved
GRUB_DEFAULT=0

# 0 => 沒有 boot menu, 立即 boot 入 OS
GRUB_TIMEOUT=0
GRUB_CMDLINE_LINUX="console=ttyS0,115200n8"

# 在 5 秒內不按鍵就不 display menu

GRUB_HIDDEN_TIMEOUT=5

# 是否 countdown 那 5 秒

GRUB_HIDDEN_TIMEOUT_QUIET=true

# Save Setting

GRUB_SAVEDEFAULT

# 重建 config

grub2-mkconfig -o /boot/grub2/grub.cfg

grub-setup

grub-probe /boot

grub-probe -d /dev/sda1

result:

ext2

grub-probe -v -d /dev/sda1

grub-probe: info: cannot open `/boot/grub/device.map'.
grub-probe: info: Scanning for dmraid_nv RAID devices on disk hd0.
grub-probe: info: the size of hd0 is 1953525168.
grub-probe: info: scanning hd0 for LVM.
.......................
ext2

grub-mkrescue

# generates a bootable GRUB rescue image

grub-mkrescue -o grub.iso

# grub 不用 emulation mode 的 ( 亦是不用扮 floppy )

update-grub 基本上是 call grub-mkconfig 的

http://www.gnu.org/software/grub/manual/html_node/

 


GRUB2 and Serial Console

 

/etc/default/grub

# Default: GRUB_TERMINAL=console

GRUB_TERMINAL="serial console"

# Default: GRUB_SERIAL_COMMAND="serial --unit=0 --speed=9600 --word=8 --stop=1 --parity=no"

GRUB_SERIAL_COMMAND="serial --unit=0 --speed=38400"           <--- 對應 console=ttyS0,38400n80

在 80x24 的 putty 上可以見到

                  GNU GRUB  version 1.98+20100804-14+squeeze1

 +--------------------------------------------------------------------------+
 |Debian GNU/Linux, with Linux 2.6.32-5-686                                 |
 |                                                                          |
 |                                                                          |
 |                                                                          |
 |                                                                          |
 |                                                                          |
 |                                                                          |
 |                                                                          |
 |                                                                          |
 |                                                                          |
 |                                                                          |
 +--------------------------------------------------------------------------+

      Use the ^ and v keys to select which entry is highlighted.
      Press enter to boot the selected OS, 'e' to edit the commands
      before booting or 'c' for a command-line.

   The highlighted entry will be executed automatically in 4s.

 


grub rescue mode

 

grub

 

grub> find /boot/grub/stage1

 

grub> find /grub/stage1

 

grub> root (hd0,0)

 

grub> setup (hd0,0)

 


Config

 

/etc/grub.d/00_header

if [ "\${recordfail}" = 1 ] ; then
  set timeout=${GRUB_RECORDFAIL_TIMEOUT:--1}
else

/etc/default/grub

GRUB_RECORDFAIL_TIMEOUT=10

update-grub

/boot/grub/grub.cfg

if [ "${recordfail}" = 1 ] ; then
  set timeout=10
else
  set timeout=5
fi

 


Toubleshoot

 

Q1: Could not find device for /boot: Not found or not a block device.

A1 解決方法:

grub

grub> root (hd0,0)
 Filesystem type is ext2fs, partition type 0x83

grub> setup (hd0)
 Checking if "/boot/grub/stage1" exists... yes
 Checking if "/boot/grub/stage2" exists... yes
 Checking if "/boot/grub/e2fs_stage1_5" exists... yes
 Running "embed /boot/grub/e2fs_stage1_5 (hd0)"...  16 sectors are embedded.
succeeded
 Running "install /boot/grub/stage1 (hd0) (hd0)1+16 p (hd0,0)/boot/grub/stage2 /boot/grub
/grub.conf"... succeeded
Done.

 


LVM partition

 

# insmod lvm

# boot partition
# /dev/sda1: UUID="9603b1f2-27c4-4725-b1c7-a0161d51ec95" TYPE="ext3"

menuentry 'Debian GNU/Linux, with Linux 3.2.0-4-amd64' --class debian --class gnu-linux --class gnu --class os {
        load_video
        insmod gzio
        insmod part_msdos
        insmod ext2
        set root='(hd0,msdos1)'
        search --no-floppy --fs-uuid --set=root 9603b1f2-27c4-4725-b1c7-a0161d51ec95
        echo    'Loading Linux 3.2.0-4-amd64 ...'
        linux   /vmlinuz-3.2.0-4-amd64 root=/dev/mapper/myvg-root ro  quiet
        echo    'Loading initial ramdisk ...'
        initrd  /initrd.img-3.2.0-4-amd64
}

 

search command

search [--file|--label|--fs-uuid] [--set [var]] [--no-floppy] name

--set
the first device found is set as the value of environment variable var.
The default variable is ‘root’.

--no-floppy
#prevents searching floppy devices

 


linux16 與 initrd16

 

Command: linux16 file …

    Load a Linux kernel image from file in 16-bit mode.

initrd16 file

    Load an initial ramdisk for a Linux kernel image to be booted in 16-bit mode,

    and set the appropriate parameters in the Linux setup area in memory. This may only be used after the linux16 command (see linux16) has been run.

config example:

menuentry "FreeDOS" {
        insmod fat
        set root='(hd0,msdos2)'
        linux16 /memdisk
        initrd16 /fdboot.img
}

 


grub2 memdisk boot

 

* Grub2 and memdisk.mod which is NOT the memdisk of syslinux

GRUB2's 'core.img' is a file consisting of "blobs" that include: The GRUB2 "kernel," GRUB2 modules (.mod files) required to access the GRUB2 config-file (and possibly to access additional, non-'core.img' modules)

Modules (.mod files) built into 'core.img' are loaded automatically by GRUB2 as it establishes its environment.

Now suppose that the GRUB2 'core.img' contains an embedded disk image as well as the 'memdisk.mod' module. When GRUB2 establishes its environment, it will load this module. It will find the embedded disk image and extract it to a nice place in memory. That RAM-backed, virtual disk will then be available as a device for GRUB2 to use.

Further suppose that the 'core.img' GRUB2 was set to read its config-file from the "memdisk" (whose name unfortunately conflicts with H. Peter Anvin's MEMDISK). So the module is loaded, then GRUB2 finds the virtual disk, then reads its config-file from whatever filesystem is on that virtual disk.

GRUB2 does _not_ provide an INT 0x13 hook for 'memdisk.mod'-provided virtual disks, nor for its "loopback" virtual disks, so it doesn't allow for any booted OS to use those virtual disks;

there's simply no way to access those disk images once GRUB2 has handed over control.

 


syslinux

 

GRUB2's 'core.img' is a file consisting of "blobs" that include: The GRUB2 "kernel," GRUB2 modules (.mod files)

MEMDISK simulates a disk by claiming a chunk of high memory for the disk and

a (very small - typically, 2K) chunk of low (DOS) memory for the driver itself,

then hooking the INT 13h (disk driver) and INT 15h (memory query) BIOS interrupts.

The disk image can be compressed with zip or gzip

 -> to allow booting legacy operating systems.

 -> boot floppy images, hard disk images and some ISO images.

The "map" process is implemented using INT13h - any disk emulation will remain accessible from an OS that uses compatible mode disk access,

However, the emulation via INT 13h can't be accessed from an OS that uses protected mode drivers once the protected mode kernel drivers take control.

i.e.

syslinux

# Hardware Detection Tool from floppy image
LABEL hdt_floppy
 LINUX memdisk
 INITRD hdt.img

GRUB2

menuentry "Hardware Detection Tool from floppy" {
  linux16 /memdisk
  initrd16 /hdt.img
}

MEMDISK will try to guess its geometry based on the size of the file.

< 4M => Floppy images
 > 4M => Hard disk images

# If your image is smaller than 4 MiB and it is a hard disk image, you can force MEMDISK to treat it as a hard disk image:

 LABEL harddisk_image
  LINUX memdisk
  INITRD harddisk.img
  APPEND harddisk

For ISO images, the parameter 'iso' must be passed to MEMDISK.

LABEL hdt_iso
  LINUX memdisk
  INITRD hdt.iso
  APPEND iso

 


GPT with Grub

 

# reserve a whole partition for GRUB, called the BIOS Boot Partition.
# it can also be used on BIOS platforms if system software supports it

parted /dev/disk set partition-number bios_grub on

partition type to ‘0xEF02’

 * When GRUB finds a BIOS Boot Partition during installation, it will automatically overwrite part of it.
    (Make sure that the partition does not contain any other data. )
 

 


其他

 

 

 

Creative Commons license icon Creative Commons license icon