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工作很忙,也没有帮我上传的意思,更顾不上开发维护。
总之,希望增加活力,使得由不点创建的这一项目荒废了。
页: 1 2 3 4 5 6 7 8 [9] 10 11 12 13 14 15 16 17 18
查看完整版本: GRUB4DOS for UEFI