美文网首页Grub2
编译UEFI版本Grub2引导多系统文件efi

编译UEFI版本Grub2引导多系统文件efi

作者: 吉凶以情迁 | 来源:发表于2018-10-16 23:49 被阅读0次
     可以直接从这个人的源码github中下载学习,项目地址:https://github.com/beatfan/UEFI_grub2
    

    官网源码地址
    首先要从grub官网下在grub2,grub2中包含所有grub2相关的命令,可以用来生成grub2引导,这里着重介绍制作UEFI版本的grub2

        UEFI启动是fat/fat32分区/EFI/Boot/bootia32.efi或者/EFI/Boot/bootx64.efi,然后进程由UEFI交给efi程序,我们就是制作这个efi程序,使用grub-mkimage命令即可生成。
        efi程序中需要内置配置文件,类似grub的grldr文件,一旦生成后就很难修改了,所以,我们需要一个类似与menu.lst的配置文件,所以我们指定的配置文件中指向外部的cfg配置文件
        以下为64位efi生成,32位参考文件夹名称,将x86_64-efi修改为i386-efi即可,一般是不需要,支持UEFI的基本都是64位的PC。
    

    定制文件目录方法

    内置配置文件为:grub.cfg,内置配置文件搜索/EFI/grub/compile.cfg 文件,并将其设定为配置文件。
    将其保存在grub2解压的压缩目录下,内容如下:

    search.file /EFI/grub/grub.cfg root  
    set prefix=($root)/EFI/grub  
    configfile ($root)/EFI/grub/grub.cfg  
    

    编译64位efi文件Bootx64.efi

    在grub2压缩包下面解压目录下打开命令行,输入以下命令:下面是编译64的文件

    grub-mkimage.exe -d x86_64-efi -c compile.cfg -p /EFI/grub -o Bootx64.efi -O x86_64-efi part_gpt part_msdos disk fat exfat ext2 ntfs xfs appleldr hfs iso9660 normal search_fs_file configfile linux linux16 chain loopback echo efi_gop efi_uga video_bochs video_cirrus file gfxmenu gfxterm gfxterm_background gfxterm_menu halt reboot help jpeg ls png true 
    

    编译32位efi文件BOOTIA32.efi

    grub-mkimage.exe -d i386-efi -c compile.cfg  -p /EFI/grub -o BOOTIA32.efi -O i386-efi part_gpt part_msdos disk fat exfat ext2 ntfs xfs appleldr hfs iso9660 normal search_fs_file configfile linux linux16 chain loopback echo efi_gop efi_uga video_bochs video_cirrus file gfxmenu gfxterm gfxterm_background gfxterm_menu halt reboot help jpeg ls png true
    

    命令解释

    -d 表示指定查找模块目录
    -c 表示指定配置文件,这个配置文件会集成到efi文件内,就是我们刚刚编写的x86_64-efi.cfg
    -p 设置偏好文件夹,cfg文件中会调
    -o 表示生成的目标文件
    -O 表示集成的模块
    模块这东西,有些命令不需要刻意不编译进去,如果有些linux16命令没编译进去,就会找不到linux16.
    

    以上生成完毕,在文件夹下会出现一个bootx64.efi文件,BOOTIA32.efi 文件夹,

    将其和x86_64-efi、locale文件夹、unicode.pf2一起拷贝到第一个fat/fat32分区,并新建一个grub.cfg。

    其中,x86_64-efi为模块目录,locale为地区语言,unicode.pf2为字体,grub.cfg为引导加载的配置文件

    目录如下:

    FAT/FAT32
    #########################
    /EFI/Boot/bootx64.efi
    /EFI/Boot/BOOTIA32.efi
    /EFI/grub/grub.cfg
    /EFI/grub/unicode.pf2
    /EFI/grub/x86_64-efi/
    /EFI/grub/locale/

    #####################

    x64.cfg内容示例:

    [plain] view plain copy
    function load_video {
    if [ x$feature_all_video_module = xy ]; then
    insmod all_video
    else
    insmod efi_gop
    insmod efi_uga
    insmod ieee1275_fb
    insmod vbe
    insmod vga
    insmod video_bochs
    insmod video_cirrus
    fi
    }

    insmod part_gpt
    insmod fat
    set root='hd0,gpt1'

    set font

    font="/EFI/grub/unicode.pf2"
    if loadfont font ; then set gfxmode=auto load_video insmod gfxterm set locale_dir=prefix/locale
    set lang=zh_CN
    insmod gettext
    fi

    adjust the screen resolution

    terminal_output gfxterm

    background

    insmod jpeg
    if background_image /EFI/grub/background.jpg; then
    true
    else
    set menu_color_normal=white/black
    set menu_color_highlight=black/light-gray
    if background_color 255,255,155,0; then
    clear
    fi
    fi

    default select menu index

    set default=0

    timeout

    set timeout_style=menu
    set timeout=5

    menuentry "启动 delta win7" --class windows --class os {
    insmod ntfs
    set root='(hd0,gpt2)'

    clear  
    echo "Start Windows"  
    chainloader /EFI/Microsoft/Boot/bootmgfw.efi  
    

    }

    menuentry "local win7" --class windows --class os {
    insmod ntfs
    set root='(hd0,gpt3)'

    clear  
    echo "Start Windows"  
    chainloader /EFI/Microsoft/Boot/bootmgfw.efi  
    

    }

    menuentry "ubuntu16.04 x86" --class ubuntu --class os {
    insmod ext2
    set root='(hd0,gpt5)'
    linux /vmlinuz ro root=/dev/sda5
    initrd /initrd.img
    echo "Start Ubuntu 16.04"
    }

    menuentry "ubuntu16.04 x64" --class ubuntu --class os {
    insmod ext2
    set root='(hd0,gpt6)'
    linux /vmlinuz ro root=/dev/sda6
    initrd /initrd.img
    echo "Start Ubuntu 16.04"
    }

    menuentry "-------------------" --class ubuntu --class os{
    set root=(hd0,gpt1)
    }

    menuentry "ubuntu-efi" --class ubuntu --class os {
    insmod ext2
    set root='(hd0,gpt5)'
    chainloader /efi/grub.efi
    }

    menuentry "install ubuntu" --class ubuntu --class os {
    insmod ext2
    insmod loopback
    set root=(hd0,gpt4)
    set isofile=/OS/linux/ubuntu-16.04.2-desktop-amd64.iso
    loopback loop isofile linux (loop)/casper/vmlinuz.efi boot=casper iso-scan/filename=isofile
    initrd (loop)/casper/initrd.lz
    }

    menuentry "-------------------" --class ubuntu --class os{
    set root=(hd0,gpt1)
    }

    menuentry "reboot" --class windows --class os{
    insmod reboot
    reboot
    }

    menuentry "halt" --class windows --class os{
    insmod halt
    halt
    }

    参考文档

    https://wiki.archlinux.org/index.php/GRUB_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)
    https://help.ubuntu.com/community/UEFIBooting

    官网源代码

    http://ftp.gnu.org/gnu/grub/
    http://ftp.gnu.org/gnu/grub/grub-2.02-for-windows.zip

    官网说明文档

    https://www.gnu.org/software/grub/manual/grub.html

    排错教程

    http://jingyan.baidu.com/article/c85b7a640cd7d6003bac95f8.html

    其他源代码

    https://packages.ubuntu.com/source/trusty/grub2

    https://www.kernel.org/pub/linux/utils/boot/syslinux/

    命令参考文档

    http://www.jinbuguo.com/linux/grub.cfg.html
    http://blog.csdn.net/listener_ri/article/details/45621947

    grub2入门教程

    http://bbs.wuyou.net/forum.php?mod=viewthread&tid=385353

    测试配置是否生效

    在进入grub界面如果出现

    [Minima] BASH-like line editing is supported.For the first word,TAB
    lists possible command completions. Anywhere else TAB lists the possible 
    completions of a device/filename. ESC at any time exits
    
    

    问题出在引导配置文件没有找到.
    那么如何调试呢?
    可以尝试打印变量的方法,输入C进入命令模式
    输入gettext $prefix
    我们发现还是提示(hd0,gp1)/EFI/grub
    说明目录并没有被更改,我们可以验证一下放到此目录在跑起来.
    发现果然又可以了,后面原因就是便宜目录的compile.cfg里面的目录并没有修改到根目录。

    1. 文件语法错误,语法错误问题找起来比较难!

    字体乱码

    打开cfg文件查看是不是配置了语言文件,但是目录不存在

    loadfont ($root)/grub/fonts/unicode.pf2
    set locale_dir=($root)/grub/locale
    

    如果依然乱码,修改文件编码为utf-8

    题外话 编译bios模式

    
    echo 正在编译bios 模式引导文件
    grub-mkimage.exe -d i386-pc -c compile.cfg -p /grub -o core.img -O i386-pc biosdisk part_gpt part_msdos disk fat exfat ext2 ntfs xfs appleldr hfs iso9660 normal search_fs_file configfile linux linux16 chain loopback echo efi_gop efi_uga video_bochs video_cirrus file search gfxmenu gfxterm gfxterm_background gfxterm_menu halt reboot help jpeg ls png true blocklist cat date echo play memdisk tar
    pause
    

    在④步骤中,已经生成BIOS模式所需的内核文件Core.img,其大小是86.5 KB
    生成的只是单单BIOS模式的内核文件,还无法引导Grub2,还需要个启动文件Boot.img,该文件很小,只有512Byte,位于i386-pc文件夹,该文件的作用是启动Grub2,然后加载内核文件Core.img
    所以这里的最后壹步就是把启动文件Boot.img和内核文件Core.img以二进制形式合并,合并后的文件我个人称呼为扇区文件G2ldr(不知道这个文件有没标准的名称),因为可以直接导入到扇区,来引导启动Grub2,也可以由GRUB4DOS直接加载这个扇区文件来启动Grub2。
    老样子,先给出命令(如果命令行的路径不是Grub2包所在的路径,就先要修改命令行的路径,前面有提到)
    Copy /B i386-pc\Boot.img+Core.img G2ldr

    导入g2ldr

    用bootice 导入扇区
    恢复扇区数改成63不能大于63的
    之所以会超过是定制问题, 那么这个不会

    grub-mkimage.exe -d I386-PC -p (hd0,1)/Grub2/BIOS -o Core. img -O i386-pc biosdisk part_msdos fat exfat ntfs 
    

    学习uefi和bios所使用的启动器仿真
    http://bbs.wuyou.net/forum.php?mod=viewthread&tid=335197

    具体教程来自 http://bbs.wuyou.net/forum.php?mod=viewthread&tid=339411&extra=page%3D1

    : qq5274202

    我的cmd批处理定制

    
    @echo off
    echo 所有文件将移动到根目录下的grub文件夹下
    echo 正在编译64位
    grub-mkimage.exe -d x86_64-efi -c compile.cfg -p /grub -o Bootx64.efi -O x86_64-efi part_gpt part_msdos disk fat exfat ext2 ntfs xfs appleldr hfs iso9660 normal search_fs_file configfile linux linux16 chain loopback echo efi_gop efi_uga video_bochs video_cirrus file search gfxmenu gfxterm gfxterm_background gfxterm_menu halt reboot help jpeg ls png true blocklist cat date echo play memdisk tar search_fs_uuid
    
    echo 正在编译32位
    
    
    grub-mkimage.exe -d i386-efi -c compile.cfg  -p /grub -o BootIA32.efi -O i386-efi part_gpt part_msdos disk fat exfat ext2 ntfs xfs appleldr hfs iso9660 normal search_fs_file configfile linux linux16 chain loopback echo efi_gop efi_uga video_bochs video_cirrus file search gfxmenu gfxterm gfxterm_background gfxterm_menu halt reboot help jpeg ls png true blocklist cat date echo  play memdisk tar search_fs_uuid
    
    ::grub-mkimage.exe -d I386-PC -p (hd0,1)/Grub2/BIOS -o Core.img -O i386-pc biosdisk part_msdos fat exfat ext2 ntfs normal iso9660 search_fs_file 定制bios模式生成了core.img
    
    echo 正在编译bios 模式引导文件
    grub-mkimage.exe -d i386-pc -c compile.cfg -p /grub -o core.img -O i386-pc biosdisk part_gpt part_msdos disk fat exfat ext2 ntfs xfs hfs iso9660 normal search_fs_file configfile linux linux16 chain loopback echo video_bochs video_cirrus file search gfxmenu gfxterm gfxterm_background gfxterm_menu halt reboot help jpeg ls png true blocklist cat date echo play memdisk tar
    
    ::不是所有模块其他编译架构就有的不如efi开头的,在bios里面肯定会找不到
    copy /b i386-pc\boot.img+core.img g2ldr
    echo 编译完成
    pause
    

    那么bios加载方式如何启动呢。

    下是主要的命令示例,%%围绕的变量自行替换成实际的路径或名称。
    
    ECHO 生成bios启动文件
    start /wait /min %grubDir%\grub-mkimage.exe -d %grubDir%\i386-pc -p /grub2/bios -o %BootFileDir%\Core.img -O i386-pc biosdisk part_msdos iso9660 udf configfile search help reiserfs font linux chain search_fs_file 
    Copy /B %grubDir%\i386-pc\cdboot.img+%BootFileDir%\Core.img %BootFileDir%\G2ldr.bin
    COPY /y %BootFileDir%\G2ldr.bin %ISODir%\G2ldr.bin
    COPY /y %BootFileDir%\Core.img %ISODir%\grub2\bios\i386-pc\Core.img
    ECHO 生成EFI 64启动文件
    start /wait /min %grubDir%\grub-mkimage.exe -d %grubDir%\x86_64-efi -p /grub2/uefi -o %EFIImgDir%\Bootx64.efi -O x86_64-efi search search_fs_file configfile help iso9660 fat part_gpt part_msdos disk exfat ext2 ntfs appleldr hfs normal reiserfs font linux chain
    ECHO 生成EFI 32启动文件
    start /wait /min %grubDir%\grub-mkimage.exe -d %grubDir%\i386-efi -p /grub2/uefi -o %EFIImgDir%\Bootia32.efi -O i386-efi search search_fs_file configfile help iso9660 fat part_gpt part_msdos disk exfat ext2 ntfs appleldr hfs normal reiserfs font linux chain
    ECHO 生成EFI启动扇区
    start /wait /min %ToolDir%\WinImage\WinImage.exe %ToolDir%\efisys.bin %BootFileDir%\efiImg /i /h /y
    COPY /y %ToolDir%\efisys.bin  %ISODir%\efisys.bin
    IF "%1" neq "NoPause" PAUSE 
    ECHO 生成ISO镜像
    mkisofs.exe -v -d -N -R -J -boot-info-table -l -relaxed-filenames -gbk4dos-filenames -gbk4win-filenames -no-emul-boot -boot-load-size 4 -o %ISOName% -v -V "%ISOTitle%" -b %biosImg% %efi% %ISODir%
    
    IF "%1" neq "NoPause" PAUSE 
    

    unknown filesystem排错教程

    出现这个错误,说明文件系统是不支持引导此分区,可以一个一个测试
    输入 ls
    出现了(hd0) (hd0,msdos2) (hd0,msdos1)
    (hd1)
    出现了msdos的都可以引导bios,
    尝试输入了ls (hd0,msdos2)显示的是存储盘的内容,
    尝试输入(hd0,msdos1)显示的是uefi分区内容.

    而输入 其他的都显示未知的系统,也验证了bios只识别mbr分区表.

    于是我把grub移动到了uefi分区 也就是(hd0,msdos1) 然后输入如下内容
    后依次输入如下内容:

    set root=(hd0,msdos1)/boot/grub
    set prefix=(hd0,msdos1)/grub
    insmod normal
    normal
    

    成功加载菜单.

    相关文章

      网友评论

        本文标题:编译UEFI版本Grub2引导多系统文件efi

        本文链接:https://www.haomeiwen.com/subject/huokzftx.html