|
今天在 https://github.com/Sha0/winvblock/blob/master/src/winvblock/grub4dos/g4dbus.c
看到了如下的代码:
- /* Check for a RAM disk mapping */
- if (slot->DestDrive == 0xFF) {
- new_dev_obj = WvRamdiskCreateG4dDisk(
- slot,
- bus_dev_obj,
- media_type,
- sector_size
- );
- } else {
- new_dev_obj = WvFilediskCreateG4dDisk(
- slot,
- bus_dev_obj,
- media_type,
- sector_size
- );
- }
复制代码
在这段代码中,开发者把 0xff 号的数据盘都当成内存盘来处理,这是不对的。
当 bios 光驱(El Torito)盘号正好是 0xff 时,也会出现这种情况。
就是说,数据介质盘的盘号 0xff 存在两种可能:其一是内存介质,其二是光盘介质。
如果是内存介质,其扇区大小是正常的(即 512 字节)。如果是光盘介质,其扇区大小是 2048 字节。
以下是修复:
- /* Check for a RAM disk mapping */
- if (slot->DestDrive == 0xFF && ! (slot->DestODD)) { <------- 只更动了这一句,增加了 “数据介质不是光盘” 的判断
- new_dev_obj = WvRamdiskCreateG4dDisk(
- slot,
- bus_dev_obj,
- media_type,
- sector_size
- );
- } else {
- new_dev_obj = WvFilediskCreateG4dDisk(
- slot,
- bus_dev_obj,
- media_type,
- sector_size
- );
- }
复制代码
顺便说,firadisk 的开发者没有犯这个错误。
虽然 BIOS 赋予 eltorito 光盘盘号正好是 0xff 的情况不多,并且在这种情况下创建 grub4dos 虚拟盘的情况也不多,但是,毕竟存在这种情况。
有了上述修复,代码就更完善、更健壮了。
另外,WinVblock 的以下数据结构也有小错:
- /* From GRUB4DOS 0.4.4's stage2/shared.h */
- struct S_WV_G4D_DRIVE_MAPPING_ {
- UCHAR SourceDrive;
- UCHAR DestDrive;
- UCHAR MaxHead;
- UCHAR MaxSector:6;
- UCHAR RestrictionX:1; <---------- 此处应该有 2 位,却只有 1 位。
- UCHAR UnUsed1:1; <---------- 这是应该新增的,补足 1 位。如果上述 RestrictionX 改成两位的话,就不要再增加 UnUsed1 了。
- UINT16 DestMaxCylinder:13; <--------- 这个位数太多了。柱面号是 10 位,因此应该改成 10。如果改成 10,下面就要增加 UnUsed2 一行了。
- UCHAR UnUsed2:3; <---------- 这是应该新增的,补足 3 位。如果上述 DestMaxCylinder 保持 13 位的话,就不要再增加 UnUsed2 了。
- UINT16 SourceODD:1;
- UINT16 DestODD:1;
- UINT16 DestLBASupport:1;
- UCHAR DestMaxHead;
- UCHAR DestMaxSector:6;
- UCHAR RestrictionY:1;
- UCHAR InSituOption:1;
- UINT64 SectorStart;
- UINT64 SectorCount;
- };
复制代码
【补充】似乎 winvblock 本来就不支持光盘虚拟。就是说,既不支持在光盘介质上虚拟出软盘、硬盘、光盘,也不支持从软盘、硬盘介质上虚拟出光盘。我不能肯定这一点,我没有研究过,我只是猜测。
|
|