无忧启动论坛

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

[原创] GRUB4DOS for UEFI

    [复制链接]
发表于 2020-10-29 13:23:16 | 显示全部楼层
厉害!
请问 yaya 是怎么解决 UEFI 函数调用约定方面的问题的?
据我所知,__attribute__((ms_abi)) 只支持 GCC4.7及以上版本,是用汇编解决的吗?
  1. #if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)))||(defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 2)))
  2.   #define EFIAPI __attribute__((ms_abi))
  3. #else
  4.   #error Compiler is too old for MS_ABI
  5. #endif
复制代码

另外 yaya 准备什么时候上传代码?
回复

使用道具 举报

发表于 2020-10-29 15:40:58 | 显示全部楼层
本帖最后由 wintoflash 于 2020-10-29 15:42 编辑

我觉得--unmap功能还是要加上的。如果map了winpe的ISO,微软的bootmgfw.efi启动光盘上的文件时,直接找的是第一个光盘。如果机器本来就有光盘(比如usb量产的光盘),那就出问题了。

对于交换磁盘的功能,我目前还没有想好怎么弄,但是似乎是有这个需求的。
另外是否支持启动linux?如果支持,是通过传统方式启动,还是通过efi handover protocol?
回复

使用道具 举报

发表于 2020-10-29 15:46:33 | 显示全部楼层
2011yaya2007777 发表于 2020-10-29 15:45
这个我再看一看怎么卸载。
map了winpe的ISO,干了什么,肯定是干了什么,要不就不映射了。也就是没有启 ...

要在map之前,卸载量产的光驱
回复

使用道具 举报

发表于 2020-10-29 18:35:04 | 显示全部楼层
不点 发表于 2020-10-29 18:21
wintoflash,能否把这个消息贴到 reboot.pro 或者别的外网去?

我今天一整天都访问不了 reboot.pro 了。 ...

我已经通知easy2boot的开发者了。
因为他没法下载无忧论坛上的东西,所以我传到了谷歌网盘。
希望chenall能快点上线,给yaya弄个新分支或者其他的什么方法,这样可以方便所有人。
回复

使用道具 举报

发表于 2020-10-29 18:42:47 | 显示全部楼层
2011yaya2007777 发表于 2020-10-29 18:24
我使用的比较少,理解交换磁盘是为了从 0x80 或者说是出 (hd0) 启动。但是在 UEFI 环境,没有这个限制,
...

我只遇到两个 【可能】需要交换磁盘的地方:
(1) 机器本来就有光驱或者U盘带量产,需要启动 winpe。
这个目前有解决方法,所以可以不用交换。
(2) 用移动硬盘上的 windows 安装镜像 安装 windows,windows【有一定几率】会把引导文件错误地安装到移动硬盘。
这个我只是遇到了 Steve 的报告,但是他也不能稳定重现。

Ventoy 的做法是 hook BS->LocateHandle。
https://github.com/ventoy/Ventoy ... /VentoyDebug.c#L168
回复

使用道具 举报

发表于 2020-10-29 19:03:01 | 显示全部楼层
2011yaya2007777 发表于 2020-10-29 18:53
我的笔记本电脑有机械光驱,我从U盘以uefi模式启动,然后加载winpe10,可以正常启动。
不过增加 --unmap ...

光驱插个光盘试试。

我比较偷懒,unmap的时候没有从grub2磁盘结构里面卸载,因为我发现在grub2里还能正常访问,只是chainloader之后就不能访问了。
回复

使用道具 举报

发表于 2020-10-29 19:23:29 | 显示全部楼层
2011yaya2007777 发表于 2020-10-29 19:13
我不熟悉 git 。以前都是 chenall 告诉我一步一步怎么做,我不敢越雷池一步。哈哈

先清理好工作区,记得先备份。然后创建分支。git branch efi
git checkout efi
然后把你的改动加上去,最后上传你的分支
git apply ../xxx.patch
...
...
git add .
git commit -m "add efi support ...."
git push -u origin efi
仅供参考,记得先备份。我也不确定你有没有上传分支的权限。


回复

使用道具 举报

发表于 2020-10-30 14:18:39 | 显示全部楼层
uefi下不存在vbe模式。
建议统一一下术语,叫 gfx模式吧
回复

使用道具 举报

发表于 2020-10-30 18:19:29 | 显示全部楼层
本帖最后由 wintoflash 于 2020-10-30 18:45 编辑
2011yaya2007777 发表于 2020-10-30 16:49
UEFI规范好像没有规定菜单放在哪里吧。我觉得当务之急是完善启动任意磁盘(光盘)、启动任意分区的efi文件 ...

UEFI 本身没有这种规定。
我也觉得这个目前不重要。

有人偏爱内置菜单,但是不易修改。再说,现在是在保护模式,内存不能任意指定。内置菜单怎么编译进去,又如何修改,需有这方面知识和经验的人来完成。

我记得 grub2 好像是生成镜像的时候把动态加载模块(.mod)、memdisk、内置菜单 都是当作 "模块" 来看的。模块头部记录了类型之类的东西。有一个链表记录了各模块的地址。

我也很好奇 grub4dos efi 是怎么做的,估计以前那些直接读内存地址的菜单用法都不兼容了。比如
  1. write 0x307ff8 1  && configfile
  2. calc *50000=*0x8280
复制代码


BIOS 的 grub4dos 是一直在实模式下吗?
怎么把c语言代码编译成纯16位的?
回复

使用道具 举报

发表于 2020-10-31 20:47:17 | 显示全部楼层
我转发到 reboot.pro 上了
http://reboot.pro/topic/22400-grub4dos-for-uefi/
我英语不好,希望英语好的可以帮忙挑挑错。
回复

使用道具 举报

发表于 2020-11-1 22:06:32 | 显示全部楼层
本帖最后由 wintoflash 于 2020-11-1 22:18 编辑

部分论坛上的朋友和reboot.pro那边的一些网友,想启动 RamOS 的 VHD。
但是目前的 Windows 驱动,比如 SVBus,要搜索 int13h 里面的 "$INT13SFGRUB4DOS" 来获取 GRUB4DOS 创建的虚拟盘信息。
UEFI 下没这东西,只能另想办法传递虚拟盘信息。我希望 GRUB4DOS 和 GRUB2 能用同样的方法记录虚拟盘信息,我觉得用 UEFI 环境变量比较合适。yaya 大佬有什么想法吗?比如,变量名叫 "GRUBvdisk",结构如下:
  1. struct grub_vdisk_data
  2. {
  3.     char magic[8]; // "GNU GRUB"
  4.     uint64_t vdisk_addr; // vhd加载到内存的地址
  5.     uint64_t vdisk_size;
  6.     char vdisk_path[];
  7. }
复制代码




回复

使用道具 举报

发表于 2020-11-1 22:08:49 | 显示全部楼层
pseudo 发表于 2020-11-1 13:16
盘要清爽,尽量不要增加目录。
盘上一般现成都有/EFI/boot/目录,就用它。
默认配置文件就约定为/EFI/boo ...

盘就是用来放东西的,你这也太强迫症了,就跟 "书桌上不能放书,垃圾桶里不能有垃圾,晾衣架上不能晾衣服" 一样。我觉得 /EFI/grub/ 就行
回复

使用道具 举报

发表于 2020-11-2 19:18:35 | 显示全部楼层
liuzhaoyzz 发表于 2020-11-2 13:32
UEFI下面,map xxx.vdf (hd0)这个的确可以实现,主要问题是实现之后,windows无法从这个(hd0)上 ...

试了一下,通过UEFI环境变量传递内存盘地址是可行的。
如图,我写了个小程序,在windows下获取grub2创建的内存盘地址。直接查看内存,是可以看到内存盘数据的。
问题是,我不会写windows驱动。
深度截图_选择区域_20201102191451.png
回复

使用道具 举报

发表于 2020-11-2 20:20:47 | 显示全部楼层
2011yaya2007777 发表于 2020-11-2 19:59
可以在内存某个地址写入"$INT13SFGRUB4DOS" 字符串,以及映射表。不知道那些程序的内存搜索范围,还有没有 ...

firadisk和svbus都不搜索内存,直接从中断向量表读。
  1. intVector = ((INTERRUPT_VECTOR*)(VOID*)(virtAddr))[0x13];
复制代码

这个位置在uefi下可能是不让写的。
回复

使用道具 举报

发表于 2020-11-2 21:57:15 | 显示全部楼层
sunsea 发表于 2020-11-2 21:28
以前稍微搞过这种东西……
其实不仅是驱动的问题,重要的是如何让系统在第一轮驱动加载之前,让【bootmg ...

其实不仅是驱动的问题,重要的是如何让系统在第一轮驱动加载之前,让【bootmgfw.efi】正确的把【bcd】,【winload.efi】,【SYSTEM】读进内存。这是最麻烦的。

bootmgr时代,bootmgr是直接呼叫INT13来读第一轮的这些东西

这是最不麻烦的。
GRUB2 UEFI 的 map, wimboot, ntboot,GRUB4DOS BIOS 和 UEFI 下的 map, Syslinux BIOS 下的 memdisk 都能做到这个。
回复

使用道具 举报

发表于 2020-11-2 22:12:24 | 显示全部楼层
本帖最后由 wintoflash 于 2020-11-2 22:13 编辑
2011yaya2007777 发表于 2020-11-2 20:44
有可能不让写,关键是uefi环境没有int13接口呀。在0x4c处写一个指针?我已知有一个电脑把0-0x8000占用了。

如果 uefi 让写,那应该是可行的。
我看 vgashim 和 grub2 的 fakebios 在 uefi 下模拟 int10h 就是在 0x40 的地方写了个指针。
但是如果 uefi 有 csm,写了估计会爆炸。
回复

使用道具 举报

发表于 2020-11-4 12:22:00 | 显示全部楼层
2011yaya2007777 发表于 2020-11-4 10:58
原先就这样。菜单可以放在这3个地址,没有考虑顺序问题。如果你3个地址都放置了菜单,那就有个顺序问题 ...
怎么从UEFI模式取字体

我记得HII Protocol之类的可以取字体。你可以到uefi spec上查一下。
回复

使用道具 举报

发表于 2020-11-5 13:23:00 | 显示全部楼层
wuwuzz 发表于 2020-11-5 10:47
哈,原因很简单,巧合。要不是L版你,事情还进展不到测试map -x呢,
我之前压根就不知道新增了这个选项。
...

又试了下,ventoy 的 hook LocateHandle 的方法可行。
我昨天可能是喝多了。
回复

使用道具 举报

发表于 2020-11-5 21:52:41 | 显示全部楼层
2011yaya2007777 发表于 2020-11-5 21:50
想当年,不点耗费大量的时间和精力排除bug,而这些bug好大一部分是由于不符合规范引起的。当年主要是对付U ...

uefi启动的光盘就没几个是规范的。特别操蛋。
回复

使用道具 举报

发表于 2020-11-6 22:58:00 | 显示全部楼层
本帖最后由 wintoflash 于 2020-11-6 22:59 编辑
sunsea 发表于 2020-11-6 22:19
以及还有几个可能的问题:
1,map --mem的内存盘是否会在退出UEFI环境后被释放掉,以及是否有类似于hook ...

EFI_RESERVED_MEMORY_TYPE,
EFI_LOADER_CODE,
EFI_LOADER_DATA,
EFI_BOOT_SERVICES_CODE,
EFI_BOOT_SERVICES_DATA,
EFI_RUNTIME_SERVICES_CODE,
EFI_RUNTIME_SERVICES_DATA,
EFI_CONVENTIONAL_MEMORY,
EFI_UNUSABLE_MEMORY,
EFI_ACPI_RECLAIM_MEMORY,
EFI_ACPI_MEMORY_NVS,
EFI_MEMORY_MAPPED_IO,
EFI_MEMORY_MAPPED_IO_PORT_SPACE,
EFI_PAL_CODE,
EFI_PERSISTENT_MEMORY,

分配内存的时候,选择 EFI_RUNTIME_SERVICES_DATA,OS 启动后也会被保留。
我的grub2,选--mem的时候,默认用的是 EFI_BOOT_SERVICES_DATA,OS 启动的时候就会被释放掉。加上 --rt 选项,就用 EFI_RUNTIME_SERVICES_DATA,这样可以保留。
因为yaya没放出代码,不知道yaya用的是哪种。

https://github.com/a1ive/grub/bl ... map/lib/misc.c#L142

点评

是的,希望yaya尽快上传代码。  详情 回复 发表于 2020-11-6 23:12
回复

使用道具 举报

发表于 2020-11-7 11:36:07 | 显示全部楼层
本帖最后由 wintoflash 于 2020-11-7 11:54 编辑
2011yaya2007777 发表于 2020-11-7 10:41
终于搞明白了,是启动 Windows 时只认第一光驱!我的电脑内存小,平时只是测试个小空壳iso,所以老是不能重 ...
我知道uefi有引导服务和运行服务性质的代码、数据。那什么时候引导服务数据被清除?是执行了启动镜像(b->start_imag)服务后,由uefi清除的吗?

boot services 里面有个 ExitBootServices。bootloader或者os kernel调用了这个之后,uefi就释放所有的boot services数据。
这个是在转圈之后调用的,应该在winload.efi里面。
我看grub2好像在引导镜像前释放了自己的内存。W大好像没有什么动作。

没有吧。uefi下grub2都是要通过boot services申请内存的,反正到系统启动的时候uefi就会自己放掉。
回复

使用道具 举报

发表于 2020-11-7 11:59:21 | 显示全部楼层
sunsea 发表于 2020-11-7 10:45
第一个问题盲猜是UEFI只告诉Windows这块内存没人用了,然后Windows把它加入可用内存列表分配使用,仅此而 ...

我觉得yaya想弄清楚的是,如果不加--mem,
根据slot找到【镜像所在的】【磁盘位置】,然后直接【读写磁盘】

svbus是怎么把bios下的磁盘和windows下的磁盘对上号的?
比如 (hd0,1)/xxx.vhd,是怎么对应到 E:\xxx.vhd 的。
回复

使用道具 举报

发表于 2020-11-7 14:45:41 | 显示全部楼层
2011yaya2007777 发表于 2020-11-7 11:05
之所以没有尽快上传代码,一是还有些已知遗留问题需要处理,还要清除众多的内部调试代码。二是不知道怎么 ...

你要是不会操作,要不先把代码传给我,我研究一下。
回复

使用道具 举报

发表于 2020-11-7 19:37:53 | 显示全部楼层
sunsea 发表于 2020-11-7 17:09
SVBus作者思路就两部:
1,算出镜像文件应该所在物理磁盘上的位置
2,根据位置,逐个检查物理磁盘,读 ...

这还真是简单粗暴。
那map信息里面的CHS什么的也用不到吧,只要文件在磁盘上的扇区号或者内存地址信息就行了。
回复

使用道具 举报

发表于 2020-11-10 19:07:31 | 显示全部楼层
2011yaya2007777 发表于 2020-11-8 19:00
W大,我 --mem 使用的是 GRUB_EFI_LOADER_DATA,这个不知道会不会被释放?

对于分配页,分配池,我有些 ...

EFI_LOADER_CODE 和 EFI_LOADER_DATA,操作系统可以自行决定是否回收。
AllocatePages分配的内存不跨页,可能对驱动更友好一点。但是要注意,AllocatePages在32位uefi上可能被分配到4GB之后的内存。

点评

自行决定是否回收的话对我们的虚拟盘估计就比较有风险了……  详情 回复 发表于 2020-11-10 19:28
回复

使用道具 举报

发表于 2020-11-10 20:29:01 | 显示全部楼层
2011yaya2007777 发表于 2020-11-10 19:57
操作系统可以自行决定是否回收。那就是和引导时代码及引导时数据一样了?操作系统执行退出引导代码及数据时 ...

EFI_BOOT_SERVICES_CODE和EFI_BOOT_SERVICES_CODE是由uefi固件在系统启动的时候自动收回的,启动服务驱动用的就是这种。
EFI_LOADER_CODE 和 EFI_LOADER_DATA 是由loader或者系统自己决定的。
所以应该用runtime data类型的。
回复

使用道具 举报

发表于 2020-11-11 13:18:25 | 显示全部楼层
cchessbd 发表于 2020-11-11 12:28
不知道yaya大有没有认真看我的贴,那我再说一下遇到uefi版本的问题吧,虚拟机的暂且不管。。。
1.实机命 ...
不能启动/bootmgr.efi

bootmgr.efi本来就不是efi可执行程序,不能启动。
实机启动后usb光驱变为(fd0),找不到(cd0) (cd1)
启动bootx64.efi后无法进入win10 pe,出现0xc000000e的错误,没有进入加载wim的过程。(虚拟机有0xa0光驱,没有出现0xc000000e的错误,进入了加载wim的过程)见343楼。

(fd0)是光盘的El Torito软盘镜像。
uefi固件没有认出来光盘,只认出了里面的软盘镜像,当然启动不了。
3.实机执行以下菜单项后不是进入win系统,按c进入命令行,root,找不到root设备了.bios版本无影响正常启动进入win.
title   Windows 硬盘系统
cat --length=0 /boot/default && savedefault
find --set-root --devices=h makeactive --status || rootnoverify (hd0,0)
checkrange 0x17,0x1c,0x1b parttype && unhide
rootnoverify
chainloader /gr1dr || chainloader /bootmgr || chainloader /ntldr || chainloader +1
boot

这个菜单本来就只能在BIOS下用。grldr, bootmfr, ntldr, 启动扇区都是BIOS下的老东西,uefi下没用。
实机菜单又能显示汉字,但缺一汉字(虚拟机无汉字),文本菜单横向也没有对齐。见340楼图。

你没有进图形模式,只能显示uefi固件里面自带的字符。虚拟机uefi固件一般只带ASCII字符,不带中文字符。
所以我建议:uefi版本尽量兼容以前的菜单命令,如果该命令不能运行,应该直接退出,或者应该采用不同的菜单文件名。
第2项我不知道是不是普遍现象,所以这个需要会量产的拿uefi版本再试一试。

UEFI跟BIOS几乎没有共同之处,grub4dos的uefi版本可以看作一个全新的引导器,要忘掉以前BIOS的那堆过时东西。

点评

谢谢您的解释,如果不能用bios的那套,那grub uefi下怎么启动windows呢。 启动img是不是只能是硬盘镜像,还是chainloader (hd0)+1之类的吗 ?  详情 回复 发表于 2020-11-11 13:26
回复

使用道具 举报

发表于 2020-11-11 21:54:00 | 显示全部楼层
cchessbd 发表于 2020-11-11 21:31
谢谢解惑,我又研究了下Ventoy,也启动不了win,uefi启动可能还需要修复硬盘的bcd,如果有多个主分区,多 ...

你得先保证自己的windows系统是安装在gpt分区上的,有ESP分区,ESP分区里面有bootmgfw.efi,才可能支持UEFI启动 (不接受抬杠)

点评

Windows 系统,并不只是安装在 GPT 分区上,才可以用 UEFI 启动,安装在 MBR 分区上也是可以的。我一个安装在 120GB SSD MBR 盘上的同一个 Windows 7 x64 系统,就可以使用传统和 UEFI 启动它,只要在相应的 BCD 菜  详情 回复 发表于 2020-11-12 10:10
回复

使用道具 举报

发表于 2020-11-12 12:45:43 | 显示全部楼层
xianglang 发表于 2020-11-12 10:10
Windows 系统,并不只是安装在 GPT 分区上,才可以用 UEFI 启动,安装在 MBR 分区上也是可以的。我一个安 ...

说了,不接受抬杠。
我回复的这个网友对UEFI一点了解也没有,你说了太多例外情况,他就迷糊了。
回复

使用道具 举报

发表于 2020-11-12 12:55:27 | 显示全部楼层
sunsea 发表于 2020-11-12 11:45
本质上这类驱动只是把这块内存“占用”起来,然后向Windows创建了一个设备而已。
然后如果映射到的磁盘 ...

SVBus之类的支持带文件碎片的map吗?

点评

我迷糊了,是否支持带碎片映射,不是只是 G4D 之类的事情吗,好像与 SVBUS 之类无关?G4D 能够映射出来的磁盘,安装了 SVBUS 之类驱动的 Windows 都难认出来并使用啊。  详情 回复 发表于 2020-11-12 13:45
不清楚,似乎没看见处理碎片的代码,应该是不支持的。  详情 回复 发表于 2020-11-12 13:22
回复

使用道具 举报

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

本版积分规则

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

闽公网安备 35020302032614号

GMT+8, 2024-4-18 11:10

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

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