无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站广告联系 微信:wuyouceo QQ:184822951
楼主: 2011yaya2007777
打印 上一主题 下一主题

[原创] GRUB4DOS for UEFI

    [复制链接]
151#
发表于 2021-5-1 12:47:43 | 显示全部楼层
回复

使用道具 举报

152#
发表于 2021-5-1 12:51:34 | 显示全部楼层
用 github actions 自动编译发布的 GRUB4EFI 外部命令有问题。
如果系统是 Ubuntu 16.04, GRUB4DOS 外部命令正常,GRUB4EFI 外部命令无法运行。
如果系统是 Ubuntu 18.04,GRUB4DOS 外部命令无法正常编译,GRUB4EFI 外部命令正常。
但是在我这边实体机上, Ubuntu 18.04 可以正常编译 GRUB4DOS 和 GRUB4EFI 的外部命令。
不知道 @chenall 有没有什么解决方法。

点评

应该是解决了 修改了 grubutils g4e 的编译脚本 (就改了一个字符^_^) https://github.com/chenall/grubutils/commit/7bb7f9638f2d77f374e260cd1d0b47b533caa651 这个是早上我编译的版本,后续再看看 htt  详情 回复 发表于 2021-5-11 12:04
我试了一下,好像是没有回显.我抽空测试下是什么情况.  详情 回复 发表于 2021-5-10 16:39
回复

使用道具 举报

153#
发表于 2021-5-1 16:21:20 | 显示全部楼层
Climbing 发表于 2021-4-29 07:40
我还是认为有可能性,保护模式切回实模式吧。EFI是可扩展的,完全可以开发一个应用模拟BIOS模式,事实上 ...
EFI是可扩展的,完全可以开发一个应用模拟BIOS模式

目前其实有人做过类似的东西:https://github.com/tkchia/biefircate (只是类似,拒绝抬杠) 但是是实验性的。
这在理论上是可行的,但是以下问题使得这种东西没有太大意义。
1. 开发难度极大。
  要写一大堆汇编,而且跑在实模式下,纯属吃饱了撑的。x86 实模式这些玩意已经是历史的糟粕了,没什么前景。一般有闲工夫的开发者不会自找麻烦,研究这个东西。
2. 很难做到比较好的兼容性。
  目前还是有很多 uefi 带有 csm 功能,即使不带 csm,也有很多 legacy 的东西。你如果自己写了个模拟的 bios,很可能会和这些东西冲突。
3. 即使写出来了,你也不能跑 Win7/Win98/XP,以及 DOS 下的一些程序。
  阻碍新电脑运行叉屁/Win7等老系统的最大障碍还真不是 UEFI,这个无需赘述。如果跑 DOS,也不能运行你那些存了几百年的什么各种硬件检测修改工具。

你要非得跑那些老掉牙的东西,不如搞个裸机虚拟机,啥问题都解决了。
比如,自己编译一个支持 KVM 的最小化 Linux 内核,然后弄个最小化 initramfs,装上 qemu 和 fbvnc。
fbvnc 是个不需要 x11/wayland ,直接用 framebuffer 显示的 VNC 客户端。fbvnc 通过 vnc 连上 qemu,就能全屏显示图像了。


点评

我并不需要跑这些复杂的东西,很简单,我做的基于wimboot的vhd的win7_x86系统,只能运行在传统的bios模式下,在传统的bios模式下,我只需要用grub4dos+ntboot/ntloader就可以加载启动,但在UEFI模式下是无法启动的。  详情 回复 发表于 2021-5-2 01:16
回复

使用道具 举报

154#
发表于 2021-5-3 17:34:32 | 显示全部楼层
Climbing 发表于 2021-5-3 16:33
你觉得我有那么弱智吗?我既然说了用U盘启动Grub4dos,当然是进的Legacy启动模式(也就是BIOS方式),我 ...

对于支持 CSM 的 UEFI 固件,当然是有办法直接调用它的 Leagcy 启动功能的。
具体怎么调用,可以看 Intel 的文档。 (https://www.intel.com/content/da ... cification-v098.pdf)
但是, CSM 不在 UEFI 规范里面,所以主板的 UEFI 固件是否支持 CSM,要看制造商的心情。
另外,2020 年起,Intel 正式放弃 CSM,也就是说新电脑不会再支持 CSM 了。
回复

使用道具 举报

155#
发表于 2021-5-11 19:23:50 | 显示全部楼层
chenall 发表于 2021-5-11 12:04
应该是解决了 @wintoflash

修改了  grubutils g4e 的编译脚本 (我改错了,不过可以正常编译, $cc 需要 ...

OK
回复

使用道具 举报

156#
发表于 2021-5-18 20:14:06 | 显示全部楼层
2011whp 发表于 2021-5-13 21:31
临时 拼音 输入法,

很强。
以前江南一根葱用Lua写过grub2下的五笔输入法。
回复

使用道具 举报

157#
发表于 2021-5-19 17:09:01 | 显示全部楼层
今天的版本 (2021-05-19) 实体机启动报错:
  1. FAULT: <<<<<<<<<<SYSTETM STATCK RUNOUT>>>>>>>>>
复制代码

敲任何命令都显示这个。
上一个版本正常。
回复

使用道具 举报

158#
发表于 2021-5-19 21:29:23 | 显示全部楼层

测试正常
回复

使用道具 举报

159#
发表于 2021-5-28 19:35:45 | 显示全部楼层
本帖最后由 wintoflash 于 2021-5-28 20:15 编辑

请教一下,grub4dos的.mod文件是怎么制作的,有没有开源的工具可以制作.mod文件?
---------------------------
这两天把grub2的grub-mkimage程序单独给弄了出来:https://github.com/grub4dos/mkimage
并对其做了点修改,现在可以不需要 moddep.lst 就可以生成 EFI 文件了。
而且还可以向 EFI 中附加任意文件。不过我还没想好这部分在 grub4dos 里面如何对接,是应该附加 .mod 还是附加外部命令/字库之类的东西。
grub4dos.7z (579.54 KB, 下载次数: 7)
示例命令:
mkimage.exe -p /efi/grub -o BOOTX64.EFI -O x86_64-efi -c menu.lst fat fwsetup ver cpuid
不过这些附加的外部命令暂时没法用。
回复

使用道具 举报

160#
发表于 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;
回复

使用道具 举报

161#
发表于 2021-5-29 11:08:04 | 显示全部楼层
2011yaya2007777 发表于 2021-5-29 10:07
wintoflash 请教一下,官网编译的外部命令不带 .MOD,而本地编译的外部命令带 .MOD。
都是一样的编译指令 ...

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

使用道具 举报

162#
发表于 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
复制代码

回复

使用道具 举报

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

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

使用道具 举报

164#
发表于 2021-5-29 14:35:05 | 显示全部楼层

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

使用道具 举报

165#
发表于 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对比。
回复

使用道具 举报

166#
发表于 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
复制代码


回复

使用道具 举报

167#
发表于 2021-5-30 09:44:20 | 显示全部楼层
2011yaya2007777 发表于 2021-5-30 08:32
这个参数不起作用。编译后仍然是 pe64 头。



回复

使用道具 举报

168#
发表于 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
回复

使用道具 举报

169#
发表于 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 (好像不能用)。
回复

使用道具 举报

170#
发表于 2021-5-30 14:22:02 | 显示全部楼层
2011yaya2007777 发表于 2021-5-30 14:12
sh make   报错;   chmox +x mske  这样?

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

使用道具 举报

171#
发表于 2021-5-30 16:07:19 | 显示全部楼层
2011yaya2007777 发表于 2021-5-30 15:47
修改为如下,效率高一些:
@@ -3575,7 +3695,8 @@ static int insmod_func(char *arg,int flags)
     GR ...

我是这样想的:
执行insmod xxx.mod -- 加载mod
执行insmod xxx          -- 加载外置命令
执行insmod不带参数 -- 加载内置的mod
回复

使用道具 举报

172#
发表于 2021-5-30 17:18:57 | 显示全部楼层
2011yaya2007777 发表于 2021-5-30 16:28
这样简单一些
if (substring(skip_to(0,arg) - 4,".mod",1) == 0  ||  flags == 101)

我是这样改的。
主要是不想把处理模块方面的代码放在 disk_io.c 里面,感觉怪怪的。
  1. diff --git build build
  2. index 80b8e2d..e57201d 100755
  3. --- build
  4. +++ build
  5. @@ -136,13 +136,12 @@ make || exit $?
  6. #复制pre_stage2.exec
  7. mkdir $GRUB4DOS_TEMP/x86_64-efi
  8. cp stage2/pre_stage2.exec $GRUB4DOS_TEMP/x86_64-efi/kernel.img
  9. -cp $SOURCE_DIR/moddep.lst $GRUB4DOS_TEMP/x86_64-efi/moddep.lst
  10. platform=`uname -m`
  11. if [ $platform = 'x86_64' ]
  12. then
  13. -    $SOURCE_DIR/grub-mkimage64 -d $GRUB4DOS_TEMP/x86_64-efi -p /efi/grub -o BOOTX64.EFI -O x86_64-efi -c preset_menu.lst
  14. +    $SOURCE_DIR/mkimage -d $GRUB4DOS_TEMP/x86_64-efi -p /efi/grub -o BOOTX64.EFI -O x86_64-efi -c preset_menu.lst
  15. else
  16. -    $SOURCE_DIR/grub-mkimage -d $GRUB4DOS_TEMP/x86_64-efi -p /efi/grub -o BOOTX64.EFI -O x86_64-efi -c preset_menu.lst
  17. +    $SOURCE_DIR/mkimage.i386 -d $GRUB4DOS_TEMP/x86_64-efi -p /efi/grub -o BOOTX64.EFI -O x86_64-efi -c preset_menu.lst
  18. fi

  19. #**********************************************
  20. @@ -159,12 +158,11 @@ make clean
  21. make || exit $?
  22. mkdir $GRUB4DOS_TEMP/i386-efi
  23. cp stage2/pre_stage2.exec $GRUB4DOS_TEMP/i386-efi/kernel.img
  24. -cp $SOURCE_DIR/moddep.lst $GRUB4DOS_TEMP/i386-efi/moddep.lst
  25. if [ $platform = 'x86_64' ]
  26. then
  27. -    $SOURCE_DIR/grub-mkimage64 -d $GRUB4DOS_TEMP/i386-efi -p /efi/grub -o BOOTIA32.EFI -O i386-efi -c preset_menu.lst
  28. +    $SOURCE_DIR/mkimage -d $GRUB4DOS_TEMP/i386-efi -p /efi/grub -o BOOTIA32.EFI -O i386-efi -c preset_menu.lst
  29. else
  30. -    $SOURCE_DIR/grub-mkimage -d $GRUB4DOS_TEMP/i386-efi -p /efi/grub -o BOOTIA32.EFI -O i386-efi -c preset_menu.lst
  31. +    $SOURCE_DIR/mkimage.i386 -d $GRUB4DOS_TEMP/i386-efi -p /efi/grub -o BOOTIA32.EFI -O i386-efi -c preset_menu.lst
  32. fi

  33. #转到源目录
  34. @@ -176,7 +174,7 @@ cd $SOURCE_DIR
  35. rm -f ${RELEASE}.zip ${RELEASE}.rar ${RELEASE}.tar.gz || exit $?
  36. if ! 7z a ${RELEASE}.7z ${GRUB4DOS_TEMP}/BOOTX64.EFI ${GRUB4DOS_TEMP}/BOOTIA32.EFI $SOURCE_DIR/ChangeLog_UEFI.txt \
  37.      $SOURCE_DIR/menu.lst ${GRUB4DOS_TEMP}/Get_Source_of_This_Build.txt ${GRUB4DOS_TEMP}/grub4dos_${CURR_REVISION}.diff \
  38. -    ${GRUB4DOS_TEMP}/i386-efi ${GRUB4DOS_TEMP}/x86_64-efi grub-mkimage.exe; then
  39. +    ${GRUB4DOS_TEMP}/i386-efi ${GRUB4DOS_TEMP}/x86_64-efi mkimage.exe; then
  40.         echo 7z failed. Continue with zip or tar...
  41. fi

  42. diff --git stage2/builtins.c stage2/builtins.c
  43. index 7c25f41..91f4593 100644
  44. --- stage2/builtins.c
  45. +++ stage2/builtins.c
  46. @@ -3562,12 +3562,54 @@ static struct builtin builtin_command =
  47.    "--set-ext sets default extensions for executable files."
  48. };

  49. +static int insmod_embed (void)
  50. +{
  51. +  struct grub_module_header *header = 0;
  52. +  char *embed_mod = NULL;
  53. +  grub_size_t embed_mod_size = 0;
  54. +  char embed_mod_path[64];
  55. +  FOR_MODULES (header)
  56. +  {
  57. +    if (header->type != OBJ_TYPE_MEMDISK)
  58. +      continue;
  59. +
  60. +    embed_mod_size = header->size - header->pad_size - sizeof (struct grub_module_header);
  61. +    embed_mod = grub_malloc (embed_mod_size + 0x1ff);
  62. +    if (!embed_mod)
  63. +      return 0;
  64. +
  65. +    embed_mod = (char *)(grub_size_t)(((unsigned long long)(grub_size_t)embed_mod + 0x1ff) & 0xfffffffffffffe00);
  66. +    grub_memmove (embed_mod, (char *) header + sizeof (struct grub_module_header),
  67. +        embed_mod_size);
  68. +    grub_sprintf (embed_mod_path, "(md)0x%lx+0x%lx,0x%lx",
  69. +        ((grub_size_t) embed_mod) >> 9, (embed_mod_size + 0x1ff) >> 9, embed_mod_size);
  70. +
  71. +    /* load file.mod */
  72. +    if (!GRUB_MOD_ADDR)
  73. +    {        
  74. +      GRUB_MOD_ADDR = grub_malloc (0x100000);   //模块缓存
  75. +      mod_end = GRUB_MOD_ADDR;
  76. +    }
  77. +    struct exec_array *p_mod = (struct exec_array *) embed_mod;
  78. +    //skip grub4dos moduld head.
  79. +    if (strcmp(p_mod->name.sn,"\x05\x18\x05\x03\xBA\xA7\xBA\xBC") == 0)
  80. +      ++p_mod;
  81. +    while ((char *)p_mod < embed_mod + embed_mod_size && grub_mod_add (p_mod))
  82. +    {
  83. +      p_mod = (struct exec_array *)(p_mod->data + p_mod->len);
  84. +    }
  85. +    grub_free (embed_mod);
  86. +    return 1;
  87. +  }
  88. +  return 0;
  89. +}
  90. +
  91. static int insmod_func(char *arg,int flags);
  92. static int insmod_func(char *arg,int flags)
  93. {
  94.     errnum = 0;
  95.     if (arg == NULL || *arg == '\0')
  96. -      return 0;
  97. +      return insmod_embed ();
  98.     char *name = skip_to(1|SKIP_WITH_TERMINATE,arg);
  99.    
  100.    if (!GRUB_MOD_ADDR)
  101. @@ -10782,11 +10824,38 @@ ok:
  102.    }       
  103.    if (!UNIFONT_START)
  104.    {
  105. -    //进入图形模式,加载袖珍字库,防止黑屏。这样也可以使防止加载精简中文字库(不包含英文字符)的问题。
  106. -    grub_memmove ((char *)0x10000, mini_font_lzma, 820);
  107. -    font_func ("(md)0x80+2", 1);  //如果是gz压缩格式,要明确压缩文件尺寸,如:font_func ("(md)0x80+2,820", 1);
  108. +    struct grub_module_header *header = 0;
  109. +    char *embed_font = NULL;
  110. +    grub_size_t embed_font_size = 0;
  111. +    char embed_font_path[64];
  112. +    FOR_MODULES (header)
  113. +    {
  114. +      if (header->type != OBJ_TYPE_FONT)  //字体
  115. +        continue;
  116. +
  117. +      embed_font_size = header->size - header->pad_size - sizeof (struct grub_module_header);
  118. +      embed_font = grub_malloc (embed_font_size + 0x1ff);
  119. +      if (!embed_font)
  120. +        break;
  121. +
  122. +      embed_font = (char *)(grub_size_t)(((unsigned long long)(grub_size_t)embed_font + 0x1ff) & 0xfffffffffffffe00);
  123. +      grub_memmove (embed_font, (char *) header + sizeof (struct grub_module_header),
  124. +          embed_font_size);
  125. +      break;
  126. +    }
  127. +    if (!embed_font)
  128. +    {
  129. +      embed_font = (char *)0x10000;
  130. +      embed_font_size = 820;
  131. +      //进入图形模式,加载袖珍字库,防止黑屏。这样也可以使防止加载精简中文字库(不包含英文字符)的问题。
  132. +      grub_memmove ((char *)0x10000, mini_font_lzma, 820);
  133. +    }
  134. +    grub_sprintf (embed_font_path, "(md)0x%lx+0x%lx,0x%lx",
  135. +        ((grub_size_t) embed_font) >> 9, (embed_font_size + 0x1ff) >> 9, embed_font_size);
  136. +    font_func (embed_font_path, 1);
  137. +    grub_free (embed_font);
  138.    }
  139. -  
  140. +
  141.    return graphics_mode;
  142. bad_arg:
  143.         errnum = ERR_BAD_ARGUMENT;
  144. diff --git stage2/disk_io.c stage2/disk_io.c
  145. index 311fe8c..a661b26 100644
  146. --- stage2/disk_io.c
  147. +++ stage2/disk_io.c
  148. @@ -4269,7 +4269,8 @@ grub_efidisk_init (void)  //efidisk初始化

  149. //初始化变量空间       
  150.    run_line((char *)"set ?_BOOT=%@root%",1);
  151. -  QUOTE_CHAR = '"';       
  152. +  QUOTE_CHAR = '"';
  153. +  run_line ((char *) "insmod", 1);
  154. #if 0
  155.         run_line((char *)"errorcheck off",1);
  156.    if (!ret || i == 0xff)
  157. @@ -4277,5 +4278,6 @@ grub_efidisk_init (void)  //efidisk初始化
  158.    run_line((char *)"configfile /efi/grub/menu.lst",1);
  159.         run_line((char *)"errorcheck on",1);
  160. #endif
  161. +
  162.         cmain ();
  163. }
  164. diff --git stage2/shared.h stage2/shared.h
  165. index f4851c4..0d09ed9 100644
  166. --- stage2/shared.h
  167. +++ stage2/shared.h
  168. @@ -5304,24 +5304,22 @@ extern grub_efi_device_path_t *efi_file_path;
  169. extern grub_efi_handle_t efi_handle;
  170. extern void grub_machine_fini (void);

  171. -enum                //对象类型
  172. -{
  173. -  OBJ_TYPE_ELF,     //ELF             00
  174. -  OBJ_TYPE_MEMDISK, //内存盘          01
  175. -  OBJ_TYPE_CONFIG,  //配置            02
  176. -  OBJ_TYPE_PREFIX,  //前缀            03
  177. -  OBJ_TYPE_PUBKEY,  //公共密钥        04
  178. -  OBJ_TYPE_DTB      //数据传输总线    05
  179. -};
  180. +#define OBJ_TYPE_ELF     0x00  // 外部命令
  181. +#define OBJ_TYPE_MEMDISK 0x01  // MOD文件
  182. +#define OBJ_TYPE_CONFIG  0x02  // 配置菜单
  183. +#define OBJ_TYPE_PREFIX  0x03  // 前缀路径
  184. +#define OBJ_TYPE_FONT    0x04  // 字体

  185. -/* The module header.  模块标题*/
  186. +/* The module header.  */
  187. struct grub_module_header
  188. {
  189. -  /* The type of object.  对象的类型*/
  190. -  grub_uint32_t type;
  191. -  /* The size of object (including this header).  对象的大小(包括此标题)*/
  192. +  /* The type of object.  */
  193. +  grub_uint16_t type;
  194. +  /* real_size = size - sizeof (struct grub_module_header) - pad_size */
  195. +  grub_uint16_t pad_size;
  196. +  /* The size of object (including this header).  */
  197.    grub_uint32_t size;
  198. -};
  199. +} GRUB_PACKED;

  200. /* "gmim" (GRUB Module Info Magic).  GRUB模块信息魔法 */
  201. #define GRUB_MODULE_MAGIC 0x676d696d
复制代码


回复

使用道具 举报

173#
发表于 2021-5-30 19:00:51 | 显示全部楼层
2011yaya2007777 发表于 2021-5-30 18:46
如果在命令行执行 insmod ,会产生问题。

重复执行的话,只是会提醒 "xxx already loaded"。
要不就这样:
    if (arg == NULL || *arg == '\0')
-      return 0;
+     return flags == 101 ? insmod_embed () : 0;
回复

使用道具 举报

174#
发表于 2021-6-1 19:08:03 | 显示全部楼层
32位uefi下外部命令是不是没法获取正确的grub_efi_system_table的地址?
  1. static int main(char *arg,int key)
  2. {
  3.   get_G4E_image();
  4.   if (! g4e_data)
  5.     return 0;
  6.   return printf ("0x%lx\n", grub_efi_system_table);
  7. }
复制代码

  1. diff --git a/g4eext/include/grub4dos.h b/g4eext/include/grub4dos.h
  2. index a7c9205..e317b25 100644
  3. --- a/g4eext/include/grub4dos.h
  4. +++ b/g4eext/include/grub4dos.h
  5. @@ -8,9 +8,9 @@
  6. #undef NULL
  7. #define NULL         ((void *) 0)
  8. #define        IMG(x)  ((x) - 0x8200 + g4e_data)
  9. -#define        SYSVAR(x)       (*(unsigned long long *)((*(unsigned long long *)IMG(0x8308)) + (x<<3)))
  10. -#define        SYSVAR_2(x)     (*(unsigned long long **)((*(unsigned long long *)IMG(0x8308)) + (x<<3)))
  11. -#define        SYSFUN(x)       (*(unsigned long long *)((*(unsigned long long *)IMG(0x8300)) + (x<<3)))
  12. +#define        SYSVAR(x)       (*(unsigned long *)((*(unsigned long *)IMG(0x8308)) + (x<<3)))
  13. +#define        SYSVAR_2(x)     (*(unsigned long **)((*(unsigned long *)IMG(0x8308)) + (x<<3)))
  14. +#define        SYSFUN(x)       (*(unsigned long *)((*(unsigned long *)IMG(0x8300)) + (x<<3)))

  15. #define L( x ) _L ( x )
  16. #define _L( x ) L ## x
  17. @@ -211,8 +211,8 @@ typedef enum
  18. #define quit_print             (SYSVAR(10))
  19. #define image   (SYSVAR(12))
  20. #define filesystem_type (SYSVAR(13))
  21. -#define grub_efi_image_handle (SYSVAR(14))
  22. -#define grub_efi_system_table (SYSVAR(15))
  23. +#define grub_efi_image_handle ((void *)*(SYSVAR_2(14)))
  24. +#define grub_efi_system_table ((void *)*(SYSVAR_2(15)))
  25. #define buf_geom ((struct geometry *)(SYSVAR(16)))
  26. #define tmp_geom ((struct geometry *)(SYSVAR(17)))
  27. #define term_table ((struct term_entry *)(SYSVAR(18)))                 //地址
  28. @@ -500,7 +500,7 @@ struct grub_datetime
  29. };

  30. //UEFI 函数调用约定
  31. -#if !(i386)
  32. +#ifndef __i386__
  33. #if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)))||(defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 2)))
  34.    #define EFIAPI __attribute__((ms_abi))
  35. #else
复制代码


回复

使用道具 举报

175#
发表于 2021-6-1 22:25:01 | 显示全部楼层
2011yaya2007777 发表于 2021-6-1 20:25
32位efi,就是个鸡肋,食之无味,弃之可惜。没有几个人真真使用32位真实机。大部分是在搞测试,研究,或者 ...

确实。估计跑ia32 uefi的设备数量比arm64 uefi还要少,而且数量不会继续增加了。
回复

使用道具 举报

176#
发表于 2021-6-15 14:08:47 | 显示全部楼层
本帖最后由 wintoflash 于 2021-6-15 14:12 编辑
fmwqsn 发表于 2021-6-15 09:02
yaya大,不知道g4e是否支持启动参数?或者读取UEFI的环境变量?如果从外部UEFI shell 脚本启动g4e的话,没 ...

你具体想怎么用这个参数?当作g4e的一句命令来执行,还是把它保存到某个g4e变量中以便脚本调用?
请说一下具体的使用场景。

如果是读取uefi环境变量的话,那这个变量的数据类型是什么?utf-16le字符串,还是二进制数据?
g4e内部的字符串都是utf-8编码的,如果你想传递字符串的话,那得转码。

点评

没想到也惊动了flash大。 其实就是想传递一个不确定是啥的镜像名字进去然后引导启动。  详情 回复 发表于 2021-6-15 18:26
回复

使用道具 举报

177#
发表于 2021-6-15 21:32:49 | 显示全部楼层

我是用 grub2 加载 g4e 的。
  1. menuentry "grub4dos" {
  2.   chainloader /boot/bootx64.efi "microsoft, fuck you!"
  3. }
复制代码

测试用外部命令:
cmdline.zip (2.46 KB, 下载次数: 6)
理论上支持中文,但是 grub2 chainloader 不支持传送中文,所以没测试。
另外 @2011yaya2007777 请问我怎么样才能把字符串保存到一个 g4e 变量里面以便调用,比如 echo %?%

点评

[attachimg]481797[/attachimg]  详情 回复 发表于 2021-6-16 19:16
回复

使用道具 举报

178#
发表于 2021-6-16 09:53:06 | 显示全部楼层
本帖最后由 wintoflash 于 2021-6-16 10:47 编辑
2011yaya2007777 发表于 2021-6-16 09:07
set 变量名=字符串
echo %变量名%

我说的是在外部命令里面,怎么样才能返回一个字符串,存到%?%里面。不是g4d脚本。
找到了

点评

意思是你这个外部命令,能找到 启动g4e.efi的参数 ,起码能找到grub2 chainloader 时的参数 办法是找个内存区,弄成g4e的扩展变量 ,参见 2015版 grub4dos.chm帮助的 6.14节 后面部分,(这个功能我试过  详情 回复 发表于 2021-6-16 14:07
回复

使用道具 举报

179#
发表于 2021-6-16 10:51:27 | 显示全部楼层
fmwqsn 发表于 2021-6-16 10:17
唔,我一开始也是这么想的,也是这么做的。不过实际用的时候要批量起机器的时候还是得挨个机器操作一遍。 ...

试试这个外部命令获取efi命令行
cmdline.zip (981 Bytes, 下载次数: 6)

用法:
cmdline [变量名]
把命令行字符串保存到某个变量里面,比如
cmdline abcd,之后就可以用 %abcd% 来获取这个命令行了。

点评

flash大威武。 我做了个实验性的脚本试了下,可以生效。 我看看继续折腾折腾。  详情 回复 发表于 2021-6-16 18:51
经 试验 这个 和 我说的 那个 (md)法, 都 躲不 过 set * 不过write (md) 法 1. 是容量大,( 和map内存区 并存,方便 驱动自定义 数据的回找) 2. set * 消失 后可以重建 (数据还在那里  详情 回复 发表于 2021-6-16 18:51
回复

使用道具 举报

180#
发表于 2021-6-16 20:24:27 | 显示全部楼层
2011whp 发表于 2021-6-16 19:16
2011yaya2007777  有什么办法看这个变量的 二进制呢
试了下,  grub2   可能是 gbk码( 因为 英文是  ...

不是,我前面说过了,是 grub2 的 chainloader 自己的问题。它的转码代码只适用于 ASCII 码。

uefi cmdline 是 UTF-16 LE 编码的,且只支持 UCS-2 部分。(U+0000 ~ U+FFFF, 两个字节)
grub2/grub4dos 内部字符串都是 UTF-8 编码的。
grub2 的 chainloader 的转码实现得比较简单粗暴,就是把每一个字节后面加上 0x00。
这样只有 ASCII 码部分转成了正确的 UTF-16 LE 码。
回复

使用道具 举报

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

本版积分规则

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

闽公网安备 35020302032614号

GMT+8, 2024-5-1 19:57

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

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