无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站投放广告、加入VIP会员,请联系 微信:wuyouceo
楼主: 2011yaya2007777
打印 上一主题 下一主题

[原创] GRUB4DOS for UEFI

    [复制链接]
1591#
 楼主| 发表于 2021-5-29 08:44:39 | 只看该作者
这两天把grub2的grub-mkimage程序单独给弄了出来

以前你在64位操作系统编译,需要grub-mkimage64(chenall 却不需要),而在32位系统编译,需要 grub-mkimage。现在单独弄了出来,可否合二为一?

grub-mkimage64 编译使用 grub_pe64_optional_header,而 grub-mkimage 编译使用 grub_pe32_optional_header 。
bootx64.efi 无论使用 grub_pe64_optional_header 还是 grub_pe32_optional_header ,都可以正常运行,使用 grub_pe32_optional_header 体积小一些,建议统一为 grub_pe32_optional_header 。

点评

这是另一码事。github actions 的 linux 环境是没有 32 位库的,只能执行纯 64 位 linux 程序,所以我放了个 64 位的。 你确定吗?我看 grub-mkimage 的源码,好像是根据目标镜像是 i386-efi 还是 x86_64-efi  详情 回复 发表于 2021-5-29 10:32
回复

使用道具 举报

1592#
 楼主| 发表于 2021-5-29 08:57:23 | 只看该作者
而且还可以向 EFI 中附加任意文件。不过我还没想好这部分在 grub4dos 里面如何对接,是应该附加 .mod 还是附加外部命令/字库之类的东西。

我觉得把外部命令打包成 FILE.MOD 比较好。
现在是程序启动时判断有无预置菜单,有就加载。
将来程序可以判断有无预置 MOD,有就使用 insmod 加载。

建议再增加一个参数来区别预置菜单及 MOD,不知有无必要。
如:mkimage.exe -p /efi/grub -o BOOTX64.EFI -O x86_64-efi -c menu.lst -m fat fwsetup ver cpuid
grub-mkimag 把 fat fwsetup ver cpuid 打包为 FILE.MOD 。

字库现在就可以附加在预置菜单末尾,如:
0000:0000000000000000000000000000000000000000000000000000000000000000#,DotSize=16
91CD:00000000000001E03E0002007FF022203FE022203FE002003FE002007FF00000
73B0:00000000000000007BE0122012A012A07AA012A012A011401940625004300000
7528:00000000000000003FE0222022203FE0222022203FE022202220222040E00000
5047:00000000000010001EF02A102A106EF028002EF028902E90286028A029100000
88C5:000000000000488028800FF0188028804BE002007FF0050018A06A400C300000
8FD9:0000000000002100108007F00020722011401080114012201410280047F00000
4E2A:0000000000000200020005000880124062300200020002000200020002000000
83DC:00000000000008807FF0088000E07F002440128002007FF00A80124062300000
5355:000000000000104008803FE022203FE022203FE002007FF00200020002000000
53EF:00000000000000007FF0002000203F202120212021203F202020002000E00000
542F:000000000000020001001FF0101010101FF010001FF0181028102FF048100000
52A8:00000000000000803880008001F07C9010902090289044907D10011002600000

点评

insmod 加载mod或外部命令,能自己判断出外部命令的体积大小吗? 比如 insmod (md)0x1234+2,这样会导致加载的mod文件大小有问题。  详情 回复 发表于 2021-5-29 14:00
回复

使用道具 举报

1593#
 楼主| 发表于 2021-5-29 10:07:04 | 只看该作者
wintoflash 请教一下,官网编译的外部命令不带 .MOD,而本地编译的外部命令带 .MOD。
都是一样的编译指令,不知为什么。按 grub4dos 的本意,.MOD 是外部命令的集合。所以单个外部命令不应当带.MOD。有没有办法编译时不带.MOD,或者编译完毕去掉这个尾缀。

点评

我这边编译出来的不带.mod啊???  详情 回复 发表于 2021-5-29 11:08
回复

使用道具 举报

1594#
发表于 2021-5-29 10:23:57 | 只看该作者
本帖最后由 2011whp 于 2021-6-6 21:13 编辑

编译环境搭建 学习贴:
[求助] grub4dos for uefi 编译环境搭建出错
       http://bbs.wuyou.net/forum.php?m ... 4635&extra=page%3D1

grub4dos_BIOS和grub4dos_UEFI编译环境搭建(ubuntu14.04)
       http://bbs.wuyou.net/forum.php?m ... 5582&extra=page%3D1



回复

使用道具 举报

1595#
发表于 2021-5-29 10:32:09 | 只看该作者
2011yaya2007777 发表于 2021-5-29 08:44
以前你在64位操作系统编译,需要grub-mkimage64(chenall 却不需要),而在32位系统编译,需要 grub-mkim ...
以前你在64位操作系统编译,需要grub-mkimage64(chenall 却不需要),而在32位系统编译,需要 grub-mkimage。现在单独弄了出来,可否合二为一?

这是另一码事。github actions 的 linux 环境是没有 32 位库的,只能执行纯 64 位 linux 程序,所以我放了个 64 位的。
grub-mkimage64 编译使用 grub_pe64_optional_header,而 grub-mkimage 编译使用 grub_pe32_optional_header 。
bootx64.efi 无论使用 grub_pe64_optional_header 还是 grub_pe32_optional_header ,都可以正常运行,使用 grub_pe32_optional_header 体积小一些,建议统一为 grub_pe32_optional_header 。

你确定吗?我看 grub-mkimage 的源码,好像是根据目标镜像是 i386-efi 还是 x86_64-efi 来判断使用的 pe 头的。
#define EFI32_HEADER_SIZE ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE                \
                                    + GRUB_PE32_SIGNATURE_SIZE                \
                                    + sizeof (struct grub_pe32_coff_header) \
                                    + sizeof (struct grub_pe32_optional_header) \
                                    + 4 * sizeof (struct grub_pe32_section_table), \
                                    GRUB_PE32_FILE_ALIGNMENT)

#define EFI64_HEADER_SIZE ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE                \
                                    + GRUB_PE32_SIGNATURE_SIZE                \
                                    + sizeof (struct grub_pe32_coff_header) \
                                    + sizeof (struct grub_pe64_optional_header) \
                                    + 4 * sizeof (struct grub_pe32_section_table), \
                                    GRUB_PE32_FILE_ALIGNMENT)

  switch (image_target->id)
    {
    case IMAGE_EFI:
      {
        char *pe_img, *pe_sbat, *header;
        struct grub_pe32_section_table *section;
        size_t n_sections = 4;
        size_t scn_size;
        grub_uint32_t vma, raw_data;
        size_t pe_size, header_size;
        struct grub_pe32_coff_header *c;
        static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB;
        struct grub_pe32_optional_header *o32 = NULL;
        struct grub_pe64_optional_header *o64 = NULL;

        if (image_target->voidp_sizeof == 4)
          header_size = EFI32_HEADER_SIZE;
        else
          header_size = EFI64_HEADER_SIZE;
回复

使用道具 举报

1596#
发表于 2021-5-29 10:43:38 | 只看该作者
2011yaya2007777 发表于 2021-5-29 07:21
所有的外部命令目前都是64位的。

能不能像DOS一样用command --set-path=a;b;c形式给外部命令或批处理设搜索路径?
回复

使用道具 举报

1597#
 楼主| 发表于 2021-5-29 11:07:14 | 只看该作者
你确定吗?我看 grub-mkimage 的源码,好像是根据目标镜像是 i386-efi 还是 x86_64-efi 来判断使用的 pe 头的。

源码是这样的,所以他区分 32/64 。而事实上所以 grub_pe32_optional_header  编译的 64 位可以正常运行。

点评

试了一下,确实可以正常运行。不过两者的体积是一样大的。 加 '-E' 参数强制使用 pe32 头。 [attachimg]480818[/attachimg]  详情 回复 发表于 2021-5-29 12:01
回复

使用道具 举报

1598#
发表于 2021-5-29 11:08:04 | 只看该作者
2011yaya2007777 发表于 2021-5-29 10:07
wintoflash 请教一下,官网编译的外部命令不带 .MOD,而本地编译的外部命令带 .MOD。
都是一样的编译指令 ...

我这边编译出来的不带.mod啊???
回复

使用道具 举报

1599#
 楼主| 发表于 2021-5-29 11:13:30 | 只看该作者
本帖最后由 2011yaya2007777 于 2021-5-29 11:15 编辑

g4eext->Makefile

%.o: %.c
$(CC) $(CFLAGS) -Iinclude/ $< -o $@
%.mod: %.o
$(OBJCOPY) -O binary $< $@
$(MV) $@ bin/$$(basename -s .mod $@)
.PHONY: prepare
prepare:
$(MKDIR) -p bin
.PHONY: clean
clean:
$(RM) -f *.o *.mod bin/*
回复

使用道具 举报

1600#
发表于 2021-5-29 12:01:54 | 只看该作者
本帖最后由 wintoflash 于 2021-5-29 12:07 编辑
2011yaya2007777 发表于 2021-5-29 11:07
源码是这样的,所以他区分 32/64 。而事实上所以 grub_pe32_optional_header  编译的 64 位可以正常运行 ...

试了一下,确实可以正常运行。不过两者的体积是一样大的。
加 '-E' 参数强制使用 pe32 头。
grub4dos.7z (587.17 KB, 下载次数: 6)
  1. mkimage.exe -E -p /efi/grub -o BOOTX64_32.EFI -O x86_64-efi -c menu.lst
复制代码

回复

使用道具 举报

1601#
 楼主| 发表于 2021-5-29 12:53:56 来自手机 | 只看该作者
本帖最后由 2011yaya2007777 于 2021-5-29 12:58 编辑

应当节省0xc00字节

点评

pe_size = ALIGN_UP (header_size + core_size, GRUB_PE32_FILE_ALIGNMENT) + ... GRUB_PE32_FILE_ALIGNMENT 应该是 4096,所以可能不会改变文件大小。  详情 回复 发表于 2021-5-29 14:35
回复

使用道具 举报

1602#
发表于 2021-5-29 14:00:38 | 只看该作者
2011yaya2007777 发表于 2021-5-29 08:57
我觉得把外部命令打包成 FILE.MOD 比较好。
现在是程序启动时判断有无预置菜单,有就加载。
将来程序可 ...

insmod 加载mod或外部命令,能自己判断出外部命令的体积大小吗?
比如 insmod (md)0x1234+2,这样会导致加载的mod文件大小有问题。
回复

使用道具 举报

1603#
 楼主| 发表于 2021-5-29 14:24:38 来自手机 | 只看该作者
能。首先打开文件,获得filemax。
回复

使用道具 举报

1604#
发表于 2021-5-29 14:35:05 | 只看该作者

pe_size = ALIGN_UP (header_size + core_size, GRUB_PE32_FILE_ALIGNMENT) + ...
GRUB_PE32_FILE_ALIGNMENT 应该是 4096,所以可能不会改变文件大小。
回复

使用道具 举报

1605#
 楼主| 发表于 2021-5-29 15:36:52 | 只看该作者
32位头0x400,64位头0x1000,大0xc00。
我编译的 5.28 版本的 BOOTX64.EFI,比官网的小 0x2000,即 8k。

点评

不具有可比性。你应该在你的电脑上用官网的kernel.img生成bootx64.efi,再和官网的bootx64.efi对比。  详情 回复 发表于 2021-5-29 15:45
回复

使用道具 举报

1606#
发表于 2021-5-29 15:45:05 | 只看该作者
2011yaya2007777 发表于 2021-5-29 15:36
32位头0x400,64位头0x1000,大0xc00。
我编译的 5.28 版本的 BOOTX64.EFI,比官网的小 0x2000,即 8k。

不具有可比性。你应该在你的电脑上用官网的kernel.img生成bootx64.efi,再和官网的bootx64.efi对比。
回复

使用道具 举报

1607#
发表于 2021-5-29 19:19:25 来自手机 | 只看该作者
应该是这个 https://github.com/chenall/grubutils/tree/master/grubutils/makemod
回复

使用道具 举报

1608#
发表于 2021-5-29 21:27:15 | 只看该作者
改了一下,现在 mkimage 可以用 -f 参数嵌入字库,用 -m 参数嵌入 FILE.mod 文件。
grub4dos.7z (1.9 MB, 下载次数: 25)
也修改了 G4E 的代码以适应 mkimage。
目前 内置菜单 支持 lzma。gz 有问题。
字库 支持 lzma 和 gz。
FILE.mod 由于 insmod 加载文件的时候会检测文件扩展名是不是 .mod ,所以还不能正常工作,不知道 yaya 怎么考虑。
  1. mkimage.exe -p /efi/grub -c present.lst -O x86_64-efi -o BOOTX64.EFI -f unifont.gz -m ext.mod
复制代码


回复

使用道具 举报

1609#
 楼主| 发表于 2021-5-29 22:10:53 来自手机 | 只看该作者
这个ext.mod是使用上面提出来的2个工具之一生成的吗?
回复

使用道具 举报

1610#
 楼主| 发表于 2021-5-30 08:32:48 | 只看该作者
加 '-E' 参数强制使用 pe32 头。

这个参数不起作用。编译后仍然是 pe64 头。

点评

[attachimg]480925[/attachimg] [attachimg]480926[/attachimg]  详情 回复 发表于 2021-5-30 09:44
回复

使用道具 举报

1611#
发表于 2021-5-30 09:44:20 | 只看该作者
2011yaya2007777 发表于 2021-5-30 08:32
这个参数不起作用。编译后仍然是 pe64 头。



回复

使用道具 举报

1612#
 楼主| 发表于 2021-5-30 10:49:12 | 只看该作者
我觉得pe头不只是Magic不同,头部尺寸也不同。pe32是0x400字节,pe64是0x1000字节。

预置模块加载成功了!
修改:
     GRUB_MOD_ADDR = grub_malloc (0x100000);   //模块缓存
     mod_end = GRUB_MOD_ADDR;
   }
-   if (substring(skip_to(0,arg) - 4,".mod",1) == 0)
+//   if (substring(skip_to(0,arg) - 4,".mod",1) == 0)
    {
       if (!command_open(arg,1))
          return 0;
@@ -3597,6 +3717,11 @@ static int insmod_func(char *arg,int flags)
       //skip grub4dos moduld head.
       if (strcmp(p_mod->name.sn,"\x05\x18\x05\x03\xBA\xA7\xBA\xBC") == 0)
         ++p_mod;
+      else
+      {
+        grub_free(buff);
+        goto external_command;
+      }
       while ((char *)p_mod < buff_end && grub_mod_add(p_mod))
       {
          p_mod = (struct exec_array *)(p_mod->data + p_mod->len);
@@ -3604,6 +3729,8 @@ static int insmod_func(char *arg,int flags)
       grub_free(buff);
       return 1;
    }
+
+external_command:
    switch(command_open(arg,0))
回复

使用道具 举报

1613#
 楼主| 发表于 2021-5-30 10:50:52 | 只看该作者
本帖最后由 2011yaya2007777 于 2021-5-30 10:52 编辑

现在问题是,编译后没有 bootx64.efi.

mkdir: can't create directory '/tmp/grub4dos-temp/x86_64-efi': File exists
./build: line 144: /mnt/.31/home/dev/grub4dos/mkimage.i386: Permission denied
7-Zip 9.20  Copyright (c) 1999-2010 Igor Pavlov  2010-11-18
p7zip Version 9.20 (locale=en_US,Utf16=on,HugeFiles=on,1 CPU)
Scanning

/tmp/grub4dos-temp/BOOTX64.EFI:  WARNING: No more files               
/tmp/grub4dos-temp/BOOTIA32.EFI:  WARNING: No more files   

点评

chmod +x mkimage.i386 chmod +x mkimage  详情 回复 发表于 2021-5-30 10:58
回复

使用道具 举报

1614#
发表于 2021-5-30 10:58:48 | 只看该作者
2011yaya2007777 发表于 2021-5-30 10:50
现在问题是,编译后没有 bootx64.efi.

mkdir: can't create directory '/tmp/grub4dos-temp/x86_64-efi' ...

chmod +x mkimage.i386
chmod +x mkimage
回复

使用道具 举报

1615#
发表于 2021-5-30 11:08:45 | 只看该作者
本帖最后由 wintoflash 于 2021-5-30 11:38 编辑

makemod.7z (4.8 KB, 下载次数: 7)
makemod.exe ext\cpuid ext\fat ext\date ...
生成 grub4dos.mod。这玩意好像不太好用。。。
-------------
现在 github 上也提供自动编译的这些工具了
https://github.com/chenall/grubu ... latest/grubutils.7z
包括 weesetup.exe, makerom.exe, makemod.exe, fbinst.exe (好像不能用)。
回复

使用道具 举报

1616#
 楼主| 发表于 2021-5-30 13:05:38 | 只看该作者
本帖最后由 2011yaya2007777 于 2021-5-30 13:07 编辑

$SOURCE_DIR/chmod +x mkimage -d $GRUB4DOS_TEMP/x86_64-efi .....  报错
$SOURCE_DIR/(chmod +x mkimage) -d $GRUB4DOS_TEMP/x86_64-efi .....  报错
chmod +x $SOURCE_DIR/mkimage -d $GRUB4DOS_TEMP/x86_64-efi ...... 报错
(chmod +x $SOURCE_DIR/mkimage) -d $GRUB4DOS_TEMP/x86_64-efi ...... 报错

点评

chmox +x是加上可执行权限。加上之后再执行mkimage。  详情 回复 发表于 2021-5-30 13:52
回复

使用道具 举报

1617#
 楼主| 发表于 2021-5-30 14:12:24 来自手机 | 只看该作者
sh make   报错;   chmox +x mske  这样?

点评

先执行 chmod +x mkimage.i386 给这个文件加上可执行权限。 然后执行./mkimage.i386 看看能不能用。  详情 回复 发表于 2021-5-30 14:22
回复

使用道具 举报

1618#
发表于 2021-5-30 14:22:02 | 只看该作者
2011yaya2007777 发表于 2021-5-30 14:12
sh make   报错;   chmox +x mske  这样?

先执行
chmod +x mkimage.i386
给这个文件加上可执行权限。
然后执行./mkimage.i386 看看能不能用。
回复

使用道具 举报

1619#
 楼主| 发表于 2021-5-30 15:45:28 | 只看该作者
先执行
chmod +x mkimage
chmod +x mkimage.i386
再执行
make
就行了。

再以后就有权限了,不用重复赋权。
谢谢 wintoflash !
回复

使用道具 举报

1620#
 楼主| 发表于 2021-5-30 15:47:08 | 只看该作者
修改为如下,效率高一些:
@@ -3575,7 +3695,8 @@ static int insmod_func(char *arg,int flags)
     GRUB_MOD_ADDR = grub_malloc (0x100000);   //模块缓存
     mod_end = GRUB_MOD_ADDR;
   }
-   if (substring(skip_to(0,arg) - 4,".mod",1) == 0)
+   if (substring(skip_to(0,arg) - 4,".mod",1) == 0
+          || (arg[0] == '(' && arg[1] == 'm' && arg[2] == 'd' && arg[3] == ')'))
    {
       if (!command_open(arg,1))
          return 0;
@@ -3597,6 +3718,11 @@ static int insmod_func(char *arg,int flags)
       //skip grub4dos moduld head.
       if (strcmp(p_mod->name.sn,"\x05\x18\x05\x03\xBA\xA7\xBA\xBC") == 0)
         ++p_mod;
+      else
+      {
+        grub_free(buff);
+        goto external_command;
+      }
       while ((char *)p_mod < buff_end && grub_mod_add(p_mod))
       {
          p_mod = (struct exec_array *)(p_mod->data + p_mod->len);
@@ -3604,6 +3730,8 @@ static int insmod_func(char *arg,int flags)
       grub_free(buff);
       return 1;
    }
+
+external_command:
    switch(command_open(arg,0))
    {
       case 2:

点评

我是这样想的: 执行insmod xxx.mod -- 加载mod 执行insmod xxx -- 加载外置命令 执行insmod不带参数 -- 加载内置的mod  详情 回复 发表于 2021-5-30 16:07
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2024-11-27 10:44

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表