GNU GRUB是一个Multiboot引导加载程序。它源自GRUB,GRand Unified Bootloader,最初由Erich Stefan Boleyn设计和实现。
简而言之,引导加载程序是计算机启动时运行的第一个软件程序。它负责加载并将控制转移到操作系统内核软件 (如Hurd或Linux)。内核反过来初始化操作系统的其余部分 (例如GNU)。
GRUB2取代了以前称为 GRUB 的内容 (即 0.9x 版),保留为GRUB Legacy模块。GRUB2的增强功能仍在进行中,但当前发布的版本对于正常操作非常有用。
官方地址:https://www.gnu.org/software/grub/index.html
grub2手册地址:https://www.gnu.org/software/grub/manual/grub/grub.html#Introduction
GRUB2主要支持Legacy和EFI两种引导启动方式:
Legacy
硬盘上的第一个扇区称为主引导记录 (MBR)。这个扇区只有512字节长度,包含一小段代码 (446 字节),称为主引导加载程序 和 分区表(64 字节),描述主分区和扩展分区。
默认情况下,MBR代码查找标记为活动的分区,一旦找到这样的分区,它就会加载其 将扇区引导到内存中并将控制权传递给它。
GRUB用自己的代码替换默认的MBR。
此外,GRUB分阶段工作:
阶段1 位于MBR中,主要指向阶段2,因为MBR太小,无法包含所有需要的数据。
阶段2 指向其配置文件,其中包含我们在谈论GRUB时通常熟悉的所有复杂用户界面和选项。阶段2可以位于磁盘上的任何位置。如果阶段2找不到它的配置表,GRUB将停止引导序列,并向用户提供一个用于手动配置的命令行。
阶段1.5 也存在,如果引导信息足够小,足以容纳MBR之后的区域,则可以使用阶段1.5。
Stage体系结构允许GRUB很大 (约20-30K),因此与大多数引导加载程序相比,GRUB相当复杂且高度可配置,而大多数引导加载是稀疏且简单的,以适应分区表的限制。
EFI
EFI模式首先通过静态GUID(全局唯一标识)地址作为GPT (GUID Partition Table,全局唯一标识分区表)使用,然后通过协议服务获取到image的加载地址并计算出32位装载模块等等。
启动输入、输出控制台,初始化堆栈保护器,设置set_watchdog_timer、启动设备磁盘等等。
grub2项目(编译之前)首先执行autogen.sh文件:
: ${PYTHON:=python} // 通过 export PYTHON=python2等方式,指定当前的PYTHON环境
export LC_COLLATE=C // 使用系统默认的locale环境
unset LC_ALL // 清除LC_ALL (LC_ALL 覆盖所有其他区域设置(如LC_ALL为test,其他参数同为test),locale指令查看相关参数)
设置当前的PYTHON环境,使用系统默认的locale环境,清除LC_ALL
find . -iname '*.[ch]' ! -ipath './grub-core/lib/libgcrypt-grub/*' ! -ipath './build-aux/*' ! -ipath './grub-core/lib/libgcrypt/src/misc.c' ! -ipath './grub-core/lib/libgcrypt/src/global.c' ! -ipath './grub-core/lib/libgcrypt/src/secmem.c' ! -ipath './util/grub-gen-widthspec.c' ! -ipath './util/grub-gen-asciih.c' |sort > po/POTFILES.in
从项目内所有的.c和.h文件中,过滤掉条件指定的文件/文件夹,其余的文件按字母排列顺序写入 po/POTFILES.in
find util -iname '*.in' ! -name Makefile.in |sort > po/POTFILES-shell.in
从util目录内所有的.in文件中,过滤掉Makefile.in,其余的文件按字母排列顺序写入 po/POTFILES-shell.in
echo "Importing unicode..."
${PYTHON} util/import_unicode.py unicode/UnicodeData.txt unicode/BidiMirroring.txt unicode/ArabicShaping.txt grub-core/unidata.c
生成unicode数据文件,包含grub_unicode_compact 和 grub_unicode_bidi_pairs结构对象
struct grub_unicode_compact_range grub_unicode_compact[] = {
{0x0, 0x9, GRUB_BIDI_TYPE_BN, 0, 0, GRUB_JOIN_TYPE_NONJOINING},
{0x9, 0x1, GRUB_BIDI_TYPE_S, 0, 0, GRUB_JOIN_TYPE_NONJOINING},
{0xa, 0x1, GRUB_BIDI_TYPE_B, 0, 0, GRUB_JOIN_TYPE_NONJOINING},
{0xb, 0x1, GRUB_BIDI_TYPE_S, 0, 0, GRUB_JOIN_TYPE_NONJOINING},
{0xc, 0x1, GRUB_BIDI_TYPE_WS, 0, 0, GRUB_JOIN_TYPE_NONJOINING},
{0xd, 0x1, GRUB_BIDI_TYPE_B, 0, 0, GRUB_JOIN_TYPE_NONJOINING},
...
}
struct grub_unicode_bidi_pair grub_unicode_bidi_pairs[] = {
{0x28, 0x29},
{0x29, 0x28},
{0x3c, 0x3e},
{0x3e, 0x3c},
...
}
unicode范围、双向(bidi)算法结构
echo "Importing libgcrypt..."
${PYTHON} util/import_gcry.py grub-core/lib/libgcrypt/ grub-core
cp grub-core/lib/libgcrypt-grub/src/g10lib.h include/grub/gcrypt/g10lib.h
cp -R grub-core/lib/libgcrypt/mpi/generic grub-core/lib/libgcrypt-grub/mpi/generic
...
导入加密库相关文件(grub-core/lib/libgcrypt-grub/cipher/*),生成grub-core/lib/libgcrypt-grub/cipher/init.c,拷贝mpi文件夹相关的文件到目标等等
UTIL_DEFS='Makefile.util.def Makefile.utilgcry.def'
CORE_DEFS='grub-core/Makefile.core.def grub-core/Makefile.gcry.def'
...
${PYTHON} gentpl.py $UTIL_DEFS > Makefile.util.am
${PYTHON} gentpl.py $CORE_DEFS > grub-core/Makefile.core.am
...
cho "Saving timestamps..."
echo timestamp > stamp-h.in
exit 0
根据编译机器架构生成对应的Makefile.util.am、Makefile.core.am文件,包括i386_pc、i386_efi、i386_qemu、i386_coreboot、x86_64_efi等架构对应的规格条件