无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站广告联系 微信:wuyouceo QQ:184822951
查看: 372257|回复: 3266

[原创] GRUB4DOS for UEFI

    [复制链接]
发表于 2020-10-29 10:31:46 | 显示全部楼层 |阅读模式
本帖最后由 2011yaya2007777 于 2021-4-24 10:50 编辑

  使用于 UEFI 环境的 GRUB4DOS。
  
  这是一个庞大的工程,几乎所有的代码都捋了一遍。修改了控制台键盘输入输出,控制台屏幕输出,内存控制,
  驱动器控制,获取日期时间,暂停控制,图形模式及Unicode字体实现,PXE 网启,等等。
  
  开发过程中,参考了 GRUB2 源码。有关映射,参考了 wintoflash 的源码。

  文件下载:http://grub4dos.chenall.net/

更新说明:
2021-04-24 (yaya)
  支持尾续菜单, 改进批处理调试, 内置 unicode 16*16 英文点阵字符。

2020-11-18 (yaya)
  1. 菜单目录更改为:/efi/grub/menu.lst
  2. 支持实体光盘、硬盘启动。
  3. 多个光盘时,启动光盘调整为第一光盘,以适应 windows。
  4. 增加退出 GRUB4DOS 函数 exit_g4d。
  5. 批处理变更:
     函数下标不变,参数由 32 位变更为 64 位。(Fn.下标 参数1 参数2 ...)
     变量地址由 0x8304 变更为 0x8308,由 32 位变更为 64 位。
     call Fn 函数,如果使用变量 0x8200-0x8400 则要在前面加g4e,如 g4e0x8217。
     批处理增加 else 函数。增加 {脚本集} 表示法。
     如:
     if 条件
     {
       脚本集
       if 条件 {
         脚本集 }
       else {
         脚本集 }
     }
     else if 条件
     {
       脚本集
     }
     else
     {
       脚本集
     }
     注意:
     1. 大括弧必须是一行的结尾。
     2. 脚本集可多行书写。
     3. 大括弧内部可以嵌套。

2020-10-30
  1. 可以启动 efi 文件。
  2. 可以启动 iso 及 img 文件。
  3. 内置热键功能。
  
  与旧版本不同之处:
  1. 可以通过 graphicsmode 命令查看系统支持的图形模式。
  2. map 函数执行后即挂载。不需要执行 --hook 指令。
  3. 取消 --hook,--unhook,--rehook,--unmap=,--floppies=,--harddrives= 指令。
  4. 在 UEFI 环境,可以从 0x80 以外的磁盘启动,因此不需要交换磁盘操作,如 map (hd0) (hd1)。
  5. 取消删除磁盘功能,如 map (hd1) (hd1)。
  6. 目前 PXE 网启只支持 tftp。
  





点评

楼主, 建议提供一个样本PE,包括ISO镜像,包含某PE制作工具对应的完整包。 这样比较易学易用。 比较像grub4DOSmenu.lst那样  发表于 2023-7-22 11:13
有没有efi siso 模块啊?  发表于 2022-2-17 07:02
菜单目录更能不能自定义?  发表于 2022-1-7 21:32

评分

参与人数 128无忧币 +640 收起 理由
liangzr1976 + 5 很给力!
slyneo + 5 很给力!
jhdonline + 1 很给力!
1928374655 -1 赞一个!
msvcdll + 1 很给力!
天涯无痕 + 5 很给力!
kunpeng + 5
快雪时晴 + 1 很给力!
wawakuliao + 5 赞一个!
weiteng + 5 赞一个!
2012chenyuwen + 5 很给力!
xuxuezeng + 5 很给力!
f111 + 5 很给力!!!
994956737 + 1 很给力!
9001 + 5 致敬技术大神们!
szmsys + 5 很给力!
hzghgz + 5 赞一个!
ddngng + 5 很给力!
wwj402 + 5 很给力!
小妹 + 3
lpsyuntao + 1 赞一个!
ddianxing + 5 很给力!
defswffaaaawe + 1 赞一个!
robincai + 30 亲测非常好用!
wfccsqk + 2
ypf188 + 5 很给力!
a-lao + 5 很给力!
2011cwj6958 + 5 很给力!
榕龙 + 1 很给力!
amita + 5

查看全部评分

 楼主| 发表于 2020-10-29 15:02:23 | 显示全部楼层
先ISO和IMG,然后再支持Wim和VHD?

GRUB4DOS 本来就应当支持 VHD 吧,不过我没有测试。
Wim 现在内部没有支持。好像 RUN 及 NTBOOT 支持吧,不过需要有人更新一下。
回复

使用道具 举报

 楼主| 发表于 2020-10-29 15:10:22 | 显示全部楼层
64位的出了?

这就是 64 位的。
pxe网启支持proxydhcp不

现在就是通过 UEFI 接口支持 tftp。我的虚拟机 UEFI 不支持 http、ipv4、ipv6 协议。实体机没有测试。

点评

有ipxe差不多了,g4e没必要支持  详情 回复 发表于 2021-4-21 10:12
[attachimg]467557[/attachimg] 似乎不支持proxydhcp 支持参数不  详情 回复 发表于 2020-10-29 20:53
回复

使用道具 举报

 楼主| 发表于 2020-10-29 15:12:24 | 显示全部楼层
\bootx64.efi
如何加载引导PXE启动菜单

常规的 menu.lst。
现在版本不支持内置菜单。
回复

使用道具 举报

 楼主| 发表于 2020-10-29 15:29:45 | 显示全部楼层
据我所知,__attribute__((ms_abi)) 只支持 GCC4.7及以上版本,是用汇编解决的吗?

我使用的是 GCC4.8 版本。我就是把你贴的代码复制到头文件。
没有这段头文件,其他函数不影响,就是影响 block_io_protocol_t blockio_template。他传入的参数是 32 位的,且参数不对位。
另外 yaya 准备什么时候上传代码?

这个还请 chenall 定夺,是新开一个分支,还是怎样。这些我都不会。
目前一套代码怎样编译为 32 位或 64 位,我也不擅长,比较懵懂。

点评

爱心会员 32# 发表于 2 分钟前 | 只看该作者 2011yaya2007777 发表于 2020-10-29 15:29 我使用的是 GCC4.8 版本。我就是把你贴的代码复制到头文件。 没有这段头文件,其他函数不影响,就是影响 ... 另外,  详情 回复 发表于 2020-10-29 15:40
另外,我觉得--unmap功能还是要加上的。如果map了winpe的ISO,微软的bootmgfw.efi启动光盘上的文件时,直接找的是第一个光盘。如果机器本来就有光盘(比如usb量产的光盘),那就出问题了。  详情 回复 发表于 2020-10-29 15:35
回复

使用道具 举报

 楼主| 发表于 2020-10-29 15:45:36 | 显示全部楼层
另外,我觉得--unmap功能还是要加上的。如果map了winpe的ISO,微软的bootmgfw.efi启动光盘上的文件时,直接找的是第一个光盘。如果机器本来就有光盘(比如usb量产的光盘),那就出问题了。

这个我再看一看怎么卸载。
map了winpe的ISO,干了什么,肯定是干了什么,要不就不映射了。也就是没有启动前,使用他做了某些事情,然后卸载,去启动量产的光盘?

点评

要在map之前,卸载量产的光驱  详情 回复 发表于 2020-10-29 15:46
回复

使用道具 举报

 楼主| 发表于 2020-10-29 17:41:07 来自手机 | 显示全部楼层
那这个量产的光驱不是由map映射的,原先的grub4dos也不能卸载呀。

点评

这个确实查不到相关资料,但是我这样写的,经实践确实可以。 https://github.com/a1ive/grub/blob/68e6f41bdd84e1ea7132ac1393bdb90ebfa4a28b/grub-core/map/efi/map.c#L72 ventoy的做法是交换磁盘,可能更合理一  详情 回复 发表于 2020-10-29 18:18
回复

使用道具 举报

 楼主| 发表于 2020-10-29 18:24:31 | 显示全部楼层
本帖最后由 2011yaya2007777 于 2020-10-29 18:32 编辑
ventoy的做法是交换磁盘,可能更合理一些。

我使用的比较少,理解交换磁盘是为了从 0x80 或者说是出 (hd0) 启动。但是在 UEFI 环境,没有这个限制,
所以我觉得好像没有必要。是否还有其他用途?
这个确实查不到相关资料,但是我这样写的,经实践确实可以。
这些代码很有参考价值,谢谢。

点评

我只遇到两个 【可能】需要交换磁盘的地方: (1) 机器本来就有光驱或者U盘带量产,需要启动 winpe。 这个目前有解决方法,所以可以不用交换。 (2) 用移动硬盘上的 windows 安装镜像 安装 windows,windows【有一  详情 回复 发表于 2020-10-29 18:42
回复

使用道具 举报

 楼主| 发表于 2020-10-29 18:53:34 | 显示全部楼层
我只遇到两个 【可能】需要交换磁盘的地方:

我的笔记本电脑有机械光驱,我从U盘以uefi模式启动,然后加载winpe10,可以正常启动。
不过增加 --unmap 也可以,只是麻烦一些,要从UEFI结构卸载,还要从map映射插槽卸载,还要从grub4dos磁盘结构(新增加的)卸载,还要从grub4dos分区结构(新增加的)卸载。

点评

光驱插个光盘试试。 我比较偷懒,unmap的时候没有从grub2磁盘结构里面卸载,因为我发现在grub2里还能正常访问,只是chainloader之后就不能访问了。  详情 回复 发表于 2020-10-29 19:03
回复

使用道具 举报

 楼主| 发表于 2020-10-29 19:09:55 | 显示全部楼层
请问,菜单应该放在什么位置? 菜单默认文件名应该是什么?

/menu.lst
/grub/menu.lst
/boot/grub/menu.lst

点评

反馈个问题,yaya在57楼和81楼说的菜单搜索顺序似乎不对,优先级似乎是: /boot/grub/menu.lst /menu.lst /grub/menu.lst 因为我这几个目录都有menu.lst文件,在测试字体文件unifont.hex的时候发现,必  详情 回复 发表于 2020-11-4 09:21
多谢! 烦请您在休整一段时间后,再写一个教程。  详情 回复 发表于 2020-10-29 19:12
回复

使用道具 举报

 楼主| 发表于 2020-10-29 19:13:33 | 显示全部楼层
我不知道 yaya 对 git 的操作是否熟练。

我不熟悉 git 。以前都是 chenall 告诉我一步一步怎么做,我不敢越雷池一步。哈哈

点评

先清理好工作区,记得先备份。然后创建分支。git branch efi git checkout efi 然后把你的改动加上去,最后上传你的分支 git apply ../xxx.patch ... ... git add . git commit -m "add efi support ...."  详情 回复 发表于 2020-10-29 19:23
回复

使用道具 举报

 楼主| 发表于 2020-10-29 21:01:32 来自手机 | 显示全部楼层
原来支持不?我只是把接口由BIOS改为UEFI,另外屏蔽了ipxe.

点评

[attachimg]467585[/attachimg] 原来支持的  详情 回复 发表于 2020-10-30 13:23
回复

使用道具 举报

 楼主| 发表于 2020-10-30 07:14:11 来自手机 | 显示全部楼层
2011cwj6958:  你的汉字字库缺少英文字母及数字。BIOS版本自带这些字符。花屏是由于显示模式设置不对。图片尺寸要匹配你设置的屏幕分辨率。

点评

虚拟机和实体机都试了下,不能正常显示菜单,menu.lst好像不能放在(ESP)\EFI\boot目录下,与bootx64.efi同目录也不行。放在ESP分区根目录下,menu.lst无论用utf-8还是ansi编码都不行。截图如下:(昨天论坛上不了,  详情 回复 发表于 2020-10-30 10:41
回复

使用道具 举报

 楼主| 发表于 2020-10-30 11:22:19 | 显示全部楼层
/menu.lst
/grub/menu.lst
/boot/grub/menu.lst
回复

使用道具 举报

 楼主| 发表于 2020-10-30 11:48:07 来自手机 | 显示全部楼层
就是grub4dos的那个呀

点评

好艰难地进入PE了,原来菜单写的不对! yaya能够给个demo,把menu.lst,目录结构,字体什么的打包传上来,这些全靠用户自己摸索,太难了!title /boot/imgs/SXWIN10PEX64_17763_NET20200902.iso find --set-root /  详情 回复 发表于 2020-10-30 12:04
回复

使用道具 举报

 楼主| 发表于 2020-10-30 12:11:11 | 显示全部楼层
就是grub4dos的那个呀


unifont.hex.gz

589.24 KB, 下载次数: 830, 下载积分: 无忧币 -2

回复

使用道具 举报

 楼主| 发表于 2020-10-30 12:47:03 来自手机 | 显示全部楼层
chainloader (hd0)      你是没有使用map函数,而直接启动第一个磁盘吗?

点评

是的,就是好奇。  详情 回复 发表于 2020-10-30 12:53
回复

使用道具 举报

 楼主| 发表于 2020-10-30 14:36:56 来自手机 | 显示全部楼层
不如就叫文本模式,图形模式。管他何种图形模式。

点评

我也是这样想。  发表于 2020-10-30 16:05
回复

使用道具 举报

 楼主| 发表于 2020-10-30 14:40:01 | 显示全部楼层
@yaya,反馈个问题,前面wintoflash大神也曾经反馈过的

昨天测试没有问题,这个容我再测试一下。
回复

使用道具 举报

 楼主| 发表于 2020-10-30 16:44:40 来自手机 | 显示全部楼层
有人偏爱内置菜单,但是不易修改。再说,现在是在保护模式,内存不能任意指定。内置菜单怎么编译进去,又如何修改,需有这方面知识和经验的人来完成。
回复

使用道具 举报

 楼主| 发表于 2020-10-30 16:49:01 来自手机 | 显示全部楼层
UEFI规范好像没有规定菜单放在哪里吧。我觉得当务之急是完善启动任意磁盘(光盘)、启动任意分区的efi文件。

点评

确实应该先完善基础的部分,比如启动efi文件。 关于UEFI规范,不同的efi和不同厂商我们当初也讨论过,感觉对于菜单的存放位置,UEFI规范并没有很明确地指明。http://bbs.wuyou.net/forum.php?mod=redirect&goto=f  详情 回复 发表于 2020-11-2 08:17
UEFI规范没有规定菜单放在哪里,但有规范efi文件的位置,如 /EFI/vendor_dir/ 或 /EFI/vendor_dir/Boot/ 因此我建议相关的文件都放在这一位置。 例如: \EFI\Microsoft\Boot\ \EFI\Xorboot\ \EFI\grub 以此类  详情 回复 发表于 2020-10-30 21:21
UEFI 本身没有这种规定。 我也觉得这个目前不重要。 我记得 grub2 好像是生成镜像的时候把动态加载模块(.mod)、memdisk、内置菜单 都是当作 "模块" 来看的。模块头部记录了类型之类的东西。有一个链表记录了  详情 回复 发表于 2020-10-30 18:19
回复

使用道具 举报

 楼主| 发表于 2020-10-30 19:03:41 来自手机 | 显示全部楼层
函数 Fn.xx 可以使用,注意跟随的参数是 64 位的。变量指针由 0x8304 gbwei
回复

使用道具 举报

 楼主| 发表于 2020-10-30 19:05:16 来自手机 | 显示全部楼层
手机编辑真麻烦!改变为0x8308.
回复

使用道具 举报

 楼主| 发表于 2020-10-30 20:43:57 来自手机 | 显示全部楼层
前面已经说了,启动实机上的磁盘、分区功能还为实现,抱歉<(_ _)>
回复

使用道具 举报

 楼主| 发表于 2020-11-1 11:43:35 | 显示全部楼层
提一个建议,能否把支持UEFI启动的menu.lst菜单的位置设置成EFI/grub/menu.lst,

这个建议理由比较充分,可以区分不同内容的同名菜单文件。

点评

建议:BIOS、UEFI共用一个menu.lst菜单为好,兼容bios使用习惯,便于管理、不凌乱,否则pc、x86、x64三个启动模式要分3个菜单 如grub2利用启动环境判断执行不同菜单命令即可: if [ "$grub_platform" = "pc" ] ;  详情 回复 发表于 2020-11-1 12:03
谢谢!!! 这样做的话,在同一个启动U盘中就可以同时拥有新的支持UEFI启动的和旧的只支持BIOS启动的新旧两套 grub4dos,这就为grub4dos在启动U盘中对新旧电脑的维护提供了广阔的天地!!!  详情 回复 发表于 2020-11-1 11:54
回复

使用道具 举报

 楼主| 发表于 2020-11-2 09:52:57 来自手机 | 显示全部楼层
颜色可使用8位或64位。bios或uefi版本都一样。8位是为了兼容最古老的版本。推荐使用64位颜色。

点评

谢谢回复,明白了!  发表于 2020-11-2 10:46
回复

使用道具 举报

 楼主| 发表于 2020-11-2 11:04:00 | 显示全部楼层
如果UEFI下面能够实现map --mem xxx.vhd或者map xxx.vdf并启动,那UEFI-RAMOS就非常有意思

bios 版本就可以实现上述功能。测试了一下,uefi 版本同样可以实现。
vdf静态:map xxx.vdf (hd)
vdf动态:map --mem xxx.vhd (hd)
vdf差分:好像bios版本也不支持。

点评

我试过了直接map vdf,不带mem的这种,启动到BCD这里,如果采用NTFS单分区就会报0xc0000225错误。 如果采用激活的FAT32+NTFS双分区,则会报0xc000000f错误。 晚点我把菜单贴上来。 根据前面的微软知  详情 回复 发表于 2020-12-18 07:34
UEFI下面,map xxx.vdf (hd0)这个的确可以实现,主要问题是实现之后,windows无法从这个(hd0)上面继续启动,windows不认识这个磁盘,无法继续启动,卡在BCD那里出错了,错误代码忘记了,原因不明。  详情 回复 发表于 2020-11-2 13:32
回复

使用道具 举报

 楼主| 发表于 2020-11-2 13:48:32 来自手机 | 显示全部楼层
那增加--mem加载到内存,windows认识吗?

点评

也不认识啊。  详情 回复 发表于 2020-11-2 14:35
回复

使用道具 举报

 楼主| 发表于 2020-11-2 19:59:09 来自手机 | 显示全部楼层
可以在内存某个地址写入"$INT13SFGRUB4DOS" 字符串,以及映射表。不知道那些程序的内存搜索范围,还有没有判断的关键字。

点评

firadisk和svbus都不搜索内存,直接从中断向量表读。 这个位置在uefi下可能是不让写的。  详情 回复 发表于 2020-11-2 20:20
回复

使用道具 举报

 楼主| 发表于 2020-11-2 20:44:46 来自手机 | 显示全部楼层
有可能不让写,关键是uefi环境没有int13接口呀。在0x4c处写一个指针?我已知有一个电脑把0-0x8000占用了。

点评

如果 uefi 让写,那应该是可行的。 我看 vgashim 和 grub2 的 fakebios 在 uefi 下模拟 int10h 就是在 0x40 的地方写了个指针。  详情 回复 发表于 2020-11-2 22:12
回复

使用道具 举报

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

本版积分规则

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

闽公网安备 35020302032614号

GMT+8, 2024-3-29 15:01

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

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