ahxx
发表于 2020-11-6 16:34:06
万分感谢楼主的辛勤付出
liuzhaoyzz
发表于 2020-11-6 16:36:25
本帖最后由 liuzhaoyzz 于 2020-11-6 16:49 编辑
2011yaya2007777 发表于 2020-11-6 16:04
麻烦你在简单的,复杂的环境测试一下,我这里可以从众多 cdrom 中选择任意一个引导。
现在除了可以启 ...
还是不行啊。
title /boot/imgs/SXWIN10PEX64_17763_NET20200902.iso
find --set-root /boot/imgs/SXWIN10PEX64_17763_NET20200902.iso
map --mem /boot/imgs/SXWIN10PEX64_17763_NET20200902.iso (cd0)
chainloader (cd0)
hilsonma
发表于 2020-11-6 16:45:57
本帖最后由 hilsonma 于 2020-11-6 16:54 编辑
2011yaya2007777 发表于 2020-11-5 21:15
问题找到了。是启动光盘制作不规范。请问,是所以什么软件制作的?
我的z.iso是用mkisofs 制作的,出错信息同样是boot_image_handle not found
iso制作脚本如下:
@echo off
set bios=-no-emul-boot -boot-load-size 4 -b grldr
set uefi=-eltorito-alt-boot -no-emul-boot -eltorito-platform efi -b efi.img
set iso=-o z.iso
set dir=%1
if %1a==a set dir=iso1
set iso9660x=-U -max-iso9660-filenames -D
set RR=-R
set joliet=-J -joliet-long -hide-joliet boot.catalog
pushd %~dp0
bin\mkisofs %iso9660x% %RR% %joliet% %bios% %uefi% %iso% %dir%
请问怎样制作才规范?
-----------------------------
不好意思,没注意看有更新,用244#的更新版,我的iso可以启动了。
2011whp
发表于 2020-11-6 16:55:09
本帖最后由 2011whp 于 2020-11-6 16:58 编辑
是不是,没有efi.img的iso更好
efi.img多了个步骤,cdboot.efi 找 bootmgr.efi
去掉 或 直接光盘的 bootmgfw.efi
sunsea 驱动方面的大佬,际会和合。
2011yaya2007777
发表于 2020-11-6 16:59:41
liuzhaoyzz:你已经有了一个光盘 0xa0,它就是 cd0,你不能再虚拟一个光盘也是 cd0。
sunsea
发表于 2020-11-6 17:07:32
本帖最后由 sunsea 于 2020-11-6 17:10 编辑
阅读了一下SVBus处理INT13信息的关键代码
// we do two RAM mappings, because if we would map the first MB of physical memory we get the following problems:
// - on Windows 10 x64 Build 1709 we get the bug check 0x1A MEMORY_MANAGEMENT if WinDbg is attached and the driver runs on an ESXi machine
// - on Windows 10 x64 Build 1803 MmMapIoSpace returns NULL for the virtual address even without an attached debugger on an ESXi machine
// map real mode RAM range 0 - 1024 bytes
physAddr.QuadPart = 0;
mapSize = 0x400;
// map physical address range to nonpaged system space
// we should map this non cached, otherwise Driver Verifier shows the following error in WinDbg: Iospace mapping overlap
// the reason is because the OS has already mapped the same address range with another cache type
virtAddr = (PUCHAR)MmMapIoSpace(physAddr,mapSize,MmNonCached);
if(virtAddr == NULL)
{
IoDeleteSymbolicLink(&DosDeviceName);
IoDetachDevice(DeviceExtension->Bus.LowerDeviceObject);
IoDeleteDevice(DeviceObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
// get interrupt vector for int13h
intVector = ((INTERRUPT_VECTOR*)(VOID*)(virtAddr));
// unmap real mode RAM range 0 - 1024 bytes
MmUnmapIoSpace(virtAddr,mapSize);
// map real mode RAM INT13 segment for a size of interrupt vector offset + 1024 bytes
physAddr.QuadPart = (LONGLONG)intVector.Segment << 4;
mapSize = (SIZE_T)intVector.Offset + 0x400;
// map physical address range to nonpaged system space
// we should map this non cached, otherwise Driver Verifier shows the following error in WinDbg: Iospace mapping overlap
// the reason is because the OS has already mapped the same address range with another cache type
virtAddr = (PUCHAR)MmMapIoSpace(physAddr,mapSize,MmNonCached);
if(virtAddr == NULL)
{
IoDeleteSymbolicLink(&DosDeviceName);
IoDetachDevice(DeviceExtension->Bus.LowerDeviceObject);
IoDeleteDevice(DeviceObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
// check for the GRUB4DOS identify string "$INT13SFGRUB4DOS" at int13h offset + 0x03
if(RtlCompareMemory(&virtAddr,"$INT13SFGRUB4DOS",(SIZE_T)0x10) == 0x10)
{
// GRUB4DOS identify string "$INT13SFGRUB4DOS" found
// copy all GRUB4DOS drive map slots to our driver context area slot structure
RtlCopyMemory(&DriverExtension->slot,&virtAddr,sizeof(GRUB4DOS_DRIVE_MAP_SLOT) * MAXIMUM_GRUB4DOS_DRIVE_MAP_SLOTS);
// unmap real mode RAM INT13 segment for a size of interrupt vector offset + 1024 bytes
MmUnmapIoSpace(virtAddr,mapSize);
return STATUS_SUCCESS;
}
// unmap real mode RAM INT13 segment for a size of interrupt vector offset + 1024 bytes
MmUnmapIoSpace(virtAddr,mapSize);
// GRUB4DOS identify string "$INT13SFGRUB4DOS" not found
// we now try to search for the GRUB4DOS INT13 handler in the first 640 KB
// check the first 640 KB for the GRUB4DOS identify string "$INT13SFGRUB4DOS"
// we search in reverse order from top to down, because this is faster
for(i = 0x9F000; i >= 0; i -= 0x1000)
{
// map real mode RAM address for a size of 4096 bytes
physAddr.QuadPart = (LONGLONG)i;
mapSize = 0x1000;
// map physical address range to nonpaged system space
// we should map this non cached, otherwise Driver Verifier shows the following error in WinDbg: Iospace mapping overlap
// the reason is because the OS has already mapped the same address range with another cache type
virtAddr = (PUCHAR)MmMapIoSpace(physAddr,mapSize,MmNonCached);
if(virtAddr == NULL)
{
IoDeleteSymbolicLink(&DosDeviceName);
IoDetachDevice(DeviceExtension->Bus.LowerDeviceObject);
IoDeleteDevice(DeviceObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
// do this for 4096 bytes - 16 bytes for the GRUB4DOS identify string "$INT13SFGRUB4DOS"
for(k = 0; k < 0xFF0; k++)
{
// check for the GRUB4DOS identify string "$INT13SFGRUB4DOS"
if(RtlCompareMemory(&virtAddr,"$INT13SFGRUB4DOS",(SIZE_T)0x10) == 0x10)
{
// GRUB4DOS identify string "$INT13SFGRUB4DOS" found
// copy all GRUB4DOS drive map slots to our driver context area slot structure
// k - 0xE3 is the start offset of our drive map table, this negative memory range is included in our memory map
RtlCopyMemory(&DriverExtension->slot,&virtAddr,sizeof(GRUB4DOS_DRIVE_MAP_SLOT) * MAXIMUM_GRUB4DOS_DRIVE_MAP_SLOTS);
// unmap real mode RAM address for a size of 4096 bytes
MmUnmapIoSpace(virtAddr,mapSize);
return STATUS_SUCCESS;
}
}
// unmap real mode RAM address for a size of 4096 bytes
MmUnmapIoSpace(virtAddr,mapSize);
}
可以发现是直接套用了G4D对于映射信息的格式:
/*lint -esym(768,_GRUB4DOS_DRIVE_MAP_SLOT::in_situ) Info 768: global struct member not referenced */
typedef struct _GRUB4DOS_DRIVE_MAP_SLOT
{
UCHAR from_drive;
UCHAR to_drive; // 0xFF indicates a memdrive
UCHAR max_head;
UCHAR max_sector:6;
UCHAR disable_lba:1; // bit 6: disable lba
UCHAR read_only:1; // bit 7: read only
USHORT to_cylinder:13; // max cylinder of the TO drive
USHORT from_cdrom:1; // bit 13: FROM drive is CDROM(with big 2048-byte sector)
USHORT to_cdrom:1; // bit 14:TOdrive is CDROM(with big 2048-byte sector)
USHORT to_support_lba:1; // bit 15:TOdrive support LBA
UCHAR to_head; // max head of the TO drive
UCHAR to_sector:6; // max sector of the TO drive
UCHAR fake_write:1; // bit 6: fake-write or safe-boot
UCHAR in_situ:1; // bit 7: in-situ
ULONGLONG start_sector;
ULONGLONG sector_count;
}GRUB4DOS_DRIVE_MAP_SLOT,*PGRUB4DOS_DRIVE_MAP_SLOT;
重点句:
// copy all GRUB4DOS drive map slots to our driver context area slot structure
// k - 0xE3 is the start offset of our drive map table, this negative memory range is included in our memory map
RtlCopyMemory(&DriverExtension->slot,&virtAddr,sizeof(GRUB4DOS_DRIVE_MAP_SLOT) * MAXIMUM_GRUB4DOS_DRIVE_MAP_SLOTS);
直接拷贝,毫无改写!
再看一下对于内存映射的处理也是直来直去型的。
那么请问yaya,可不可以设计一个UEFI变量,名字就叫$INT13SFGRUB4DOS之类,然后内部存储的信息还是上面这个GRUB4DOS_DRIVE_MAP_SLOT结构?大概这样问题就能解决了。
只要命名空间的GUID明确而且有EFI_VARIABLE_RUNTIME_ACCESS 这个属性应该都可以读到,我是觉得可能map的时候设置一下EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS。
2011yaya2007777
发表于 2020-11-6 17:08:13
hilsonma:我的双引导光盘就是使用你的模板制作的。我说的不规范,主要是指光盘 0x17 扇区启动目录里,软盘镜像的尺寸填写不正确。比如扇区数是 0x1680,填写的却是 4。
2011yaya2007777
发表于 2020-11-6 17:19:00
sunsea:你太了!粗看了一下 ,代码从 9F000 开始从高到低搜索特定字符串。在程序搜索范围内,写特定字符串,并复制内存映射插槽,可以办到。
sunsea
发表于 2020-11-6 17:29:39
2011yaya2007777 发表于 2020-11-6 17:19
sunsea:你太了!粗看了一下 ,代码从 9F000 开始从高到低搜索特定字符串。在程序搜索范围内,写特定字符串 ...
sunsea:你太了!
没看懂,是不是打错字了
嘛,反正就把所有的slot连续摆放进这个变量里就行了。然后把这个变量的两个属性设置上,确保启动器和操作系统下都能访问。然后应该就可以了。然后还需要一下这个变量在的名字空间的GUID。
感谢!
2011yaya2007777
发表于 2020-11-6 17:31:32
抱歉,手机上发了一个牛的表情符号,结果没有了。那两个访问属性怎么设置,还的研究一下。如有人知道,可告知我。
sunsea
发表于 2020-11-6 17:35:13
本帖最后由 sunsea 于 2020-11-6 17:52 编辑
2011yaya2007777 发表于 2020-11-6 17:31
抱歉,手机上发了一个牛的表情符号,结果没有了。那两个访问属性怎么设置,还的研究一下。如有人知道,可告 ...
过奖过奖了。
看了一下资料。
https://blog.csdn.net/jiangwei0512/article/details/52877055/
在这里应该就行了
typedef
EFI_STATUS
(EFIAPI *EFI_SET_VARIABLE)(
INCHAR16 *VariableName,
INEFI_GUID *VendorGuid,
INUINT32 Attributes, // 就在这里,传入EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS应该就可以了。
INUINTN DataSize,
INVOID *Data
);
随便生成了一个GUID作为名字空间的VendorGuid:
{621F0DF7-B6BB-4334-B16B-3C8AFC883B3A}
就用这个吧,应该没人重复。
然后Data就是那堆slots构成的数组,Name就叫$INT13SFGRUB4DOS这样。
希望能做参考。
————
在看了下UEFI Spec,SetVariable似乎是个Runtime Service,直接找到表然后调用就行了?具体我也不懂……
hilsonma
发表于 2020-11-6 17:47:58
2011whp 发表于 2020-11-6 16:55
是不是,没有efi.img的iso更好
efi.img多了个步骤,cdboot.efi 找 bootmgr.efi
oscdimg 制作的 iso 就是没有 efi.img 的。但是制作速度慢,制作出来的iso体积较大。
mkisofs 制作的 iso 有efi.img,但制作速度较快,制作出来的iso体积较小。
至于引导效果,有没有efi.img 我感觉不到差别。
wuwuzz
发表于 2020-11-6 18:05:30
2011yaya2007777 发表于 2020-11-6 16:04
麻烦你在简单的,复杂的环境测试一下,我这里可以从众多 cdrom 中选择任意一个引导。
现在除了可以启 ...
一、简单环境测试未通过,因此未进行复杂环境测试。
直接chainloader实体机boot失败,现象与11月5日测试版雷同;
map优盘上的ISO,再chainloadr和boot,将启动实体USB光驱内容。
看来这次的代码,未能像W大grub2新增map -first项那样,将选中
的ISO重新排序到第1光驱,以欺骗MS的boot*.efi。
二、有事需要提前汇报。
本周六--周日,单位组织培训,因此将无法及时测试回复,很抱歉。
周日晚或周一将有时间参与测试。
2011yaya2007777
发表于 2020-11-6 19:01:35
在有0xa0及0xa1的情况下,执行 map --status ,看看情况。
2011yaya2007777
发表于 2020-11-6 19:09:56
0xa0
2011yaya2007777
发表于 2020-11-6 19:11:12
直接启动第一或者第二光盘,看看结果。
2011yaya2007777
发表于 2020-11-6 19:17:34
再一个是,输入 cd3欠妥,应当是 0xa2,或者是 cd(map时),cd-1(chainloader时)。)
2011star21cn
发表于 2020-11-6 20:42:49
大家都很兴奋,这是里程碑啊
lzt9989
发表于 2020-11-6 22:10:18
xxxxxxxxxxxxxxxxxxxxxxxxxx
liuzhaoyzz
发表于 2020-11-6 22:14:51
2011yaya2007777 发表于 2020-11-6 16:59
liuzhaoyzz:你已经有了一个光盘 0xa0,它就是 cd0,你不能再虚拟一个光盘也是 cd0。
不对呀,我试过了map到(0xff)也不行啊?
sunsea
发表于 2020-11-6 22:19:15
本帖最后由 sunsea 于 2020-11-6 22:23 编辑
2011yaya2007777 发表于 2020-11-6 17:31
抱歉,手机上发了一个牛的表情符号,结果没有了。那两个访问属性怎么设置,还的研究一下。如有人知道,可告 ...
以及还有几个可能的问题:
1,map --mem的内存盘是否会在退出UEFI环境后被释放掉,以及是否有类似于hook INT15的机制来告诉操作系统【这块内存被保留】什么的……担心后来的操作系统把仿真盘破坏掉
2,有何种手段能够欺骗bootmgfw.efi让它能够正确读取仿真盘上的bcd等关键文件……不过看样子似乎这个问题已经被解决了
wuwuzz
发表于 2020-11-6 22:23:26
2011yaya2007777 发表于 2020-11-6 19:17
再一个是,输入 cd3欠妥,应当是 0xa2,或者是 cd(map时),cd-1(chainloader时)。)
结果如下:
wuwuzz
发表于 2020-11-6 22:24:46
本帖最后由 wuwuzz 于 2020-11-6 22:45 编辑
2011yaya2007777 发表于 2020-11-6 19:11
直接启动第一或者第二光盘,看看结果。
所有参与测试的ISO,刻光盘或用grub2 map,都是可以启动成功,进入win10 PE的
wintoflash
发表于 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/blob/b92d0cd5954a2c148c335515fc4b62bcae4c4e50/grub-core/map/lib/misc.c#L142
sunsea
发表于 2020-11-6 23:12:54
wintoflash 发表于 2020-11-6 22:58
EFI_RESERVED_MEMORY_TYPE,
EFI_LOADER_CODE,
EFI_LOADER_DATA,
是的,希望yaya尽快上传代码。
2011whp
发表于 2020-11-7 10:39:01
本帖最后由 2011whp 于 2020-11-7 10:40 编辑
菜单其余部分 为 1# 的,热键?
graphicsmode -1 640:1920
setmenu --hotkey -A commandline
title ^Ctrl+d commandline
commandline
title reboot
reboot
2011yaya2007777
发表于 2020-11-7 10:41:32
终于搞明白了,是启动 Windows 时只认第一光驱!我的电脑内存小,平时只是测试个小空壳iso,所以老是不能重现bug。
现在有几个疑问,请坛友释疑。
我知道uefi有引导服务和运行服务性质的代码、数据。那什么时候引导服务数据被清除?是执行了启动镜像(b->start_imag)服务后,由uefi清除的吗?我感觉启动的windowe转圈圈以前,还在读盘,grub4dos还在起作用。当然windows启动后,加载自己的驱动,不需要uefi服务支持。我看grub2好像在引导镜像前释放了自己的内存。W大好像没有什么动作。
SVBus在windows挂载的内存盘,是使用 --mem 加载到内存的镜像?还是不使用 --mem 的,如 map /a.iso (0xff) 这种有映射关系,但是数据仍然在磁盘上,也可以挂载?
2011yaya2007777
发表于 2020-11-7 10:44:18
因为yaya没放出代码,不知道yaya用的是哪种。
我采用的是你以前的代码,应该是引导服务吧。
sunsea
发表于 2020-11-7 10:45:27
2011yaya2007777 发表于 2020-11-7 10:41
终于搞明白了,是启动 Windows 时只认第一光驱!我的电脑内存小,平时只是测试个小空壳iso,所以老是不能重 ...
第一个问题盲猜是UEFI只告诉Windows这块内存没人用了,然后Windows把它加入可用内存列表分配使用,仅此而已。
第二个问题,根据我目前阅读到的代码:
加了--mem参数:根据slot找到镜像所在内存位置,然后登记并读写数据。
没加mem:根据slot找到【镜像所在的】【磁盘位置】,然后直接【读写磁盘】
(其实我没看懂你这个问题……
2011yaya2007777
发表于 2020-11-7 11:05:27
本帖最后由 2011yaya2007777 于 2020-11-7 16:06 编辑
是的,希望yaya尽快上传代码。
之所以没有尽快上传代码,一是还有些已知遗留问题需要处理,还要清除众多的内部调试代码。二是不知道怎么上传。
现在我想寻求一个有能力,有精力,有担当,愿意开发和维护GRUB4DOS的有缘人,接手这件事情。
本来我是想作为chenall项目的一个分支,使得GRUB4DOS的BIOS分支、UEFI分支在一起,即有继承性,又方便浏览下载。
但是chenall工作很忙,也没有帮我上传的意思,更顾不上开发维护。
总之,希望增加活力,使得由不点创建的这一项目荒废了。