无忧启动论坛

标题: 请教关于 grub4dos NTBOOT的原理 [打印本页]

作者: wintoflash    时间: 2019-11-18 19:56
标题: 请教关于 grub4dos NTBOOT的原理
本帖最后由 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)




  1. <div>:NT6.VHD_BOOT
  2. ::固定用法,本软盘对应的BCD文件专用.下同
  3. set boot_cfg=:BCD_CFG_VHD#WIM b VHD
  4. goto :NT6_BOOT

  5. :NT6.WIM_BOOT
  6. set boot_cfg=:BCD_CFG_VHD#WIM a WIM
  7. goto :NT6_BOOT</div><div>
  8. </div><div>:BCD_CFG_VHD#WIM
  9. ::本软盘BCD对应的特定语句,修改默认启动项
  10. write --offset=0x343C (rd)/BOOT/BCD %1
  11. write --offset=0x35DC (rd)/BOOT/BCD %1</div>
复制代码
然后把WIM的路径写入BCD。
其中,这个特制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
这个路径有两处。

  1. cat --locate=\\x2F --replace=\\x5C (md)0x200+3
  2. ::本软盘BCD对应的特定语句,修改文件路径
  3. cat --locate=\\%2_ --number=2 (rd)/BOOT/BCD | call :BCD_CFG_PATH=
  4. :BCD_CFG_PATH
  5. WENV call write --offset=0x%1 (rd)/BOOT/BCD *0x40000$
  6. WENV call write --offset=0x%2 (rd)/BOOT/BCD *0x40000$
复制代码
第三步是修改磁盘。
如果是mbr磁盘,bcd里面记录的是磁盘签名和该分区的偏移。
BCD里面的磁盘签名是"53 B7 53 B7",4个uint8_t,替换成wim所在磁盘的磁盘签名就行了。
  1. cat --locate=\x53\xB7\x53\xB7 --replace=*0x60000 --hex=4 (rd)/BOOT/BCD
复制代码

  1. struct grub_msdos_partition_mbr
  2. {
  3.   /* The code area (actually, including BPB).  */
  4.   grub_uint8_t code[440];
  5.   grub_uint8_t unique_signature[4];                            //这个就是磁盘签名
  6.   grub_uint8_t unknown[2];
  7.   /* Four partition entries.  */
  8.   struct grub_msdos_partition_entry entries[4];
  9.   /* The signature 0xaa55.  */
  10.   grub_uint16_t signature;
  11. } GRUB_PACKED;
复制代码
BCD里面分区的偏移要查找 00 7E 00 00, 8个uint8_t

  1. cat --locate=\0\x7E\0\0 --replace=*0x60004 --hex=8 (rd)/BOOT/BCD
复制代码

  1. struct grub_msdos_partition_entry
  2. {
  3.   /* If active, 0x80, otherwise, 0x00.  */
  4.   grub_uint8_t flag;
  5.   /* The head of the start.  */
  6.   grub_uint8_t start_head;
  7.   /* (S | ((C >> 2) & 0xC0)) where S is the sector of the start and C
  8.      is the cylinder of the start. Note that S is counted from one.  */
  9.   grub_uint8_t start_sector;
  10.   /* (C & 0xFF) where C is the cylinder of the start.  */
  11.   grub_uint8_t start_cylinder;
  12.   /* The partition type.  */
  13.   grub_uint8_t type;
  14.   /* The end versions of start_head, start_sector and start_cylinder,
  15.      respectively.  */
  16.   grub_uint8_t end_head;
  17.   grub_uint8_t end_sector;
  18.   grub_uint8_t end_cylinder;
  19.   /* The start sector. Note that this is counted from zero.  */
  20.   grub_uint32_t start;                                 //这个乘以512(左移9位)就是偏移量 (不考虑扩展分区)
  21.   /* The length in sector units.  */
  22.   grub_uint32_t length;
  23. } GRUB_PACKED;
复制代码
我对GRUB4DOS的语法不太熟,不知道我理解得对不对,还有是不是漏了什么步骤。
如果错了希望大神们能指导一下,谢谢。



作者: 邪恶海盗    时间: 2019-11-18 23:42
不懂,帮顶下...
作者: chenall    时间: 2019-11-19 09:37
本帖最后由 chenall 于 2019-11-19 09:45 编辑

您的理解是对的

这个BCD确实是是使用BCDEDIT编辑后再使用HEX工具修改过的,
要修改了几处方便定位和修改的地方,然后文件路径是预留了空间,印像中好像是256的样子.

NTBOOT.NT6是FAT软盘镜像,7Z看到的显示为NTFS估计是识别错误.

EDIT: 要移稙到GRUB2理论上应该没有什么问题, 有了你的map之后再写一个模块来完成以上的操作应该效率会更高,目前使用的是GRUB4DOS的脚本效率会比较低,而且相对比较麻烦.
因为需要改写里面的内容, 需要map后的磁盘可写,如果能够先在内存中修改好再map就可以只读了,另外之前也没有考虑到EFI的问题.
作者: wintoflash    时间: 2019-11-19 09:44
chenall 发表于 2019-11-19 09:37
您的理解是对的

这个BCD确实是是使用BCDEDIT编辑后再使用HEX工具修改过的,

谢谢大佬。
请问您的博客上的NTBOOT是不是下载链接坏了?
http://chenall.net/post/ntboot/



作者: chenall    时间: 2019-11-19 09:51
博客好久没有更新了.
我找了一下还有一个地址.
http://b.chenall.net/ntboot.iso.gz
作者: 江南一根葱    时间: 2019-11-19 12:47
kkkssc 发表于 2019-11-19 12:45
关键是,搞那么复杂干吗啊,可以用bootmgr启动grub,也可以用grub启动bootmgr,启动菜单你可以放在munulst ...

机器人id?,没看帖就……
作者: gnuxwy    时间: 2019-11-19 22:29
W大牛比,这氏要把 grub4dos 的功能都移去grub2 啊,能做成功肯定氏大好事耶。。。

作者: 指南针    时间: 2019-11-20 09:49
chenall 发表于 2019-11-19 09:37
您的理解是对的

这个BCD确实是是使用BCDEDIT编辑后再使用HEX工具修改过的,

请问,内置的bootmgr是不是也做了某些特殊修改?如果对它进行更新,是否有其他影响?比如换成win8的bootmgr
作者: chenall    时间: 2019-11-20 10:48
指南针 发表于 2019-11-20 09:49
请问,内置的bootmgr是不是也做了某些特殊修改?如果对它进行更新,是否有其他影响?比如换成win8的bootm ...

bootmgr是原版的

作者: 求道者    时间: 2019-11-21 16:15
ntboot是否只是bootmgr的封包?
而不是bootmgr重新实现?
能在efi-ia32下启动64位pe吗?
作者: wintoflash    时间: 2019-11-21 16:22
求道者 发表于 2019-11-21 16:15
ntboot是否只是bootmgr的封包?
而不是bootmgr重新实现?
能在efi-ia32下启动64位pe吗?

你需要把boot-shim移植到x86下
https://github.com/imbushuo/boot-shim
作者: wintoflash    时间: 2020-1-13 16:42
chenall 发表于 2019-11-19 09:51
博客好久没有更新了.
我找了一下还有一个地址.
http://b.chenall.net/ntboot.iso.gz

老大,GRUB4DOS 的 NTBOOT 不支持带中文的路径,比如 winpe中文.wim 。
原因是 wenv 里面的 ascii_unicode 函数不支持将带中文等内容的 utf8 字符串转换成 utf16le 编码的字符串。
https://github.com/chenall/grubu ... g4dext/wenv.c#L1813
而 GRUB2里面的 charset.h 有现成的转码函数 grub_utf8_to_utf16 可以借鉴(抄袭)
https://github.com/a1ive/grub/bl ... grub/charset.h#L123
我尝试修改了一下,因为不太熟悉 GRUB4DOS 结果不成功,老大看看要不要加上这个功能?




作者: chenall    时间: 2020-1-14 10:16
utf8转unicode印像中grub4dos里面有相关代码的,

使用带中文路径和文件的毕竟是少数, 这个是可以避免的. 目前没有打算增加这个功能.

作者: wintoflash    时间: 2020-1-21 10:20
chenall 发表于 2020-1-14 10:16
utf8转unicode印像中grub4dos里面有相关代码的,

使用带中文路径和文件的毕竟是少数, 这个是可以避免的.  ...

再次请教一下老大:
NTBOOT中,最后启动系统,是先把(rd)+1 映射到 (fd0),启动 (fd0)/bootmgr 的,

  1. :BOOT
  2. if exist BOOT && %BOOT%
  3. map --mem (rd)+1 %BOOTDEV%
  4. map --unmap=0xfb,0xfc,0xfe,0xff,0xcd
  5. map --rehook
  6. call :CHECK_FILE %NTLDR%
  7. chainloader %NTLDR%
  8. root %BOOTDEV%
  9. boot
  10. exit
复制代码

map --unmap=0xfb,0xfc,0xfe,0xff,0xcd
请问为什么还要把 0xfb-0xff和0xcd unmap掉?
在reboot.pro上,有人发现,如果之前map一个软盘到0x03,ntboot会失败,是不是跟这个有关系?
http://reboot.pro/topic/22232-a1 ... great-uefi-support/
https://github.com/a1ive/grub2-filemanager/issues/83
作者: chenall    时间: 2020-1-21 16:28
这个我也记不清为什么了,可能是为了防止干扰. 中间可能有使用了临时盘.
作者: wintoflash    时间: 2020-1-21 16:39
chenall 发表于 2020-1-21 16:28
这个我也记不清为什么了,可能是为了防止干扰. 中间可能有使用了临时盘.

那我改成
map --unmap=1:0xff
应该没有问题吧
作者: chenall    时间: 2020-1-21 16:47
这些代码是在哪个文件里面的?我没有找到,还是这个NTBOOT是修改版?
作者: wintoflash    时间: 2020-1-21 16:57
chenall 发表于 2020-1-21 16:47
这些代码是在哪个文件里面的?我没有找到,还是这个NTBOOT是修改版?

http://b.chenall.net/ntboot.iso
iso根目录下的NTBOOT文件
解压后352行
作者: chenall    时间: 2020-1-21 17:29
看了一下, BOOTDEV有(0) 和 (0xfd)这两个.

如果不启动PE1,那就可以
作者: cbl    时间: 2020-3-1 18:06

作者: cbl    时间: 2020-3-3 12:21
学习了
作者: kisssky_545    时间: 2023-2-17 17:10
11111111111111111111111111111111111111111
作者: 879792799    时间: 2023-2-18 19:40
大神级




欢迎光临 无忧启动论坛 (http://bbs.wuyou.net/) Powered by Discuz! X3.3