linux的boot有一套流程:firware->media->bootloader->kernel(kernel module)->init
- firmware发现可启动media,加载media(远程启动等)
- bootloader从boot media加载kernel到RAM里,然后启动(会根据硬盘分区表之类的发现kernel,然后继续加载kernel module之类)
- kernel会根据bootloader传递给kernel的指令去找到主文件系统
- 启动文件系统中的init脚本
在第二步,uefi找到硬盘分区表后,发现文件系统,然后会开始加载kernel
如何加载,在按照系统时就已经确定好efi命令文件的路径,然后UEFI会执行这个程序
执行efibootmgr
命令可以看到:
1 | # efibootmgr -v |
对于readhat来说,efi相关文件结构如下.
1 | # tree /boot/efi |
而当UEFI启动时,调用程序的流程是UEFI->shim.efi->grubx64.efi->grub.cfg
查看shim.efi
里的十六进制信息,可以看到调用grubx64.efi
的过程
1 | # hexdump -C /boot/efi/EFI/redhat/shim.efi | egrep -i -C 2 'grub|g.r.u.b' |
接着查看grubx64.efi
1 | # strings /boot/efi/EFI/redhat/grubx64.efi | grep grub.cfg |
到最后就到了执行grub的地方,或者叫做Grand Unified Boot Loader
GRUB访问文件系统,找到kernel文件,加载到内存,然后启动kernel,传入一系列参数
kernel需要知道如何找到root目录,才能加载各种库和配置文件等,但是前提是要加载各种驱动后才可以做接下来的操作
那么下一步就是加载/lib/modules
下的内核模块了
参考一个中文对linux boot的简介: http://blog.jobbole.com/33224/