|  | 
 
| 本帖最后由 wintoflash 于 2019-11-19 10:06 编辑 
 最近在尝试制作UEFI grub2下类似NTBOOT的功能,遇到了一些问题,请教一下。
 
 NTBOOT.MOD文件夹下 NTBOOT.NT6是一个gz压缩的img,
 里面的/BOOT/BCD文件应该是特制的,请教一下这个文件是怎么制作的?
 难道是先bcdedit生成正常BCD再用hex编辑器强改的?
 另外这个img文件是不是有什么讲究,我用7-ZIP打开看到的是一个空的ntfs分区,用UltraISO打开看到的是FAT分区。
 
 
 至于NTBOOT的原理,我下面说一下我的理解,不知道对不对。
 
 
 BCD里面有多个启动项,GUID分别是
 {a294e1da-8a7c-11de-942c-f24e6a367b43} -- 启动WIM
 
 {a294e1db-8a7c-11de-942c-f24e6a367b43} -- 启动VHD
 
 {a294e1dc-8a7c-11de-942c-f24e6a367b43}
 {a294e1dd-8a7c-11de-942c-f24e6a367b43} -- 启动Windows系统
 
 ....
 其中,只有 a294e1dd 这一项是默认显示,也是默认的启动项。
 首先根据启动的是VHD还是WIM,更改显示项和启动项。
 只需要修改这个guid的第8个数,存储位置分别是 0x343c 和 0x35dc。修改成a(WIM)或b(VHD)
 
   
 
   
 
 然后把WIM的路径写入BCD。复制代码<div>:NT6.VHD_BOOT
::固定用法,本软盘对应的BCD文件专用.下同
set boot_cfg=:BCD_CFG_VHD#WIM b VHD
goto :NT6_BOOT
:NT6.WIM_BOOT
set boot_cfg=:BCD_CFG_VHD#WIM a WIM
goto :NT6_BOOT</div><div>
</div><div>:BCD_CFG_VHD#WIM
::本软盘BCD对应的特定语句,修改默认启动项
write --offset=0x343C (rd)/BOOT/BCD %1
write --offset=0x35DC (rd)/BOOT/BCD %1</div>
其中,这个特制BCD里面WIM和VHD的启动项的路径是有特殊标志的,分别是
 \WIM_FILE_PATH (0x3bb8 0x4430) 和 \VHD_FILE_PATH (0x4dda 0x58ea)
 
   另外,还需要把路径转换成Unicode转码,再把斜杠(\x2F)转换成反斜杠(\x5C)。
 / W I N D O W S => \x2F\0\x57\0\x49\0\x4E\0\x44\0\x4F\0\x57\0\x53\0\0\0 =>\x5C\0\x57\0\x49\0\x4E\0\x44\0\x4F\0\x57\0\x53\0\0\0
 这个路径有两处。
 
 
 第三步是修改磁盘。复制代码cat --locate=\\x2F --replace=\\x5C (md)0x200+3
::本软盘BCD对应的特定语句,修改文件路径
cat --locate=\\%2_ --number=2 (rd)/BOOT/BCD | call :BCD_CFG_PATH=
:BCD_CFG_PATH
WENV call write --offset=0x%1 (rd)/BOOT/BCD *0x40000$
WENV call write --offset=0x%2 (rd)/BOOT/BCD *0x40000$
如果是mbr磁盘,bcd里面记录的是磁盘签名和该分区的偏移。
 BCD里面的磁盘签名是"53 B7 53 B7",4个uint8_t,替换成wim所在磁盘的磁盘签名就行了。
 
 复制代码cat --locate=\x53\xB7\x53\xB7 --replace=*0x60000 --hex=4 (rd)/BOOT/BCD
  
 BCD里面分区的偏移要查找 00 7E 00 00, 8个uint8_t复制代码struct grub_msdos_partition_mbr
{
  /* The code area (actually, including BPB).  */
  grub_uint8_t code[440];
  grub_uint8_t unique_signature[4];                            //这个就是磁盘签名
  grub_uint8_t unknown[2];
  /* Four partition entries.  */
  struct grub_msdos_partition_entry entries[4];
  /* The signature 0xaa55.  */
  grub_uint16_t signature;
} GRUB_PACKED;
 
 复制代码cat --locate=\0\x7E\0\0 --replace=*0x60004 --hex=8 (rd)/BOOT/BCD
  
 我对GRUB4DOS的语法不太熟,不知道我理解得对不对,还有是不是漏了什么步骤。复制代码struct grub_msdos_partition_entry
{
  /* If active, 0x80, otherwise, 0x00.  */
  grub_uint8_t flag;
  /* The head of the start.  */
  grub_uint8_t start_head;
  /* (S | ((C >> 2) & 0xC0)) where S is the sector of the start and C
     is the cylinder of the start. Note that S is counted from one.  */
  grub_uint8_t start_sector;
  /* (C & 0xFF) where C is the cylinder of the start.  */
  grub_uint8_t start_cylinder;
  /* The partition type.  */
  grub_uint8_t type;
  /* The end versions of start_head, start_sector and start_cylinder,
     respectively.  */
  grub_uint8_t end_head;
  grub_uint8_t end_sector;
  grub_uint8_t end_cylinder;
  /* The start sector. Note that this is counted from zero.  */
  grub_uint32_t start;                                 //这个乘以512(左移9位)就是偏移量 (不考虑扩展分区)
  /* The length in sector units.  */
  grub_uint32_t length;
} GRUB_PACKED;
如果错了希望大神们能指导一下,谢谢。
 
 
 
 | 
 |