a1ive / grub2-filemanager

GRUB2-based file manager
https://a1ive.github.io/grub2-filemanager/
GNU General Public License v3.0
524 stars 106 forks source link

Win8 MBR install #253

Closed steve6375 closed 4 years ago

steve6375 commented 4 years ago

MBR\Legacy Booting from USB to grub4dos and then grubfm.iso on real system.

When installing Windows 8, setup will not let me install to HDD 0 'We couldn't create a new partition or locate an existing one.' Log file X:\windows\panther\setupact.log says that setupact.log

2020-08-24 19:26:11, Info                  IBSLIB DiskRegionSupportsCapability:Disk [0] is BLOCKED against capability [CanBeSystemVolume] for the following reasons...
2020-08-24 19:26:11, Info                  IBSLIB LogReasons: [BLOCKING reason for disk 0: CanBeSystemVolume] The selected disk is not the computer's boot disk.

win.sh has auto_swap call, but USB boot drive will be drive 0 if booting from MBR USB drive.

function auto_swap {
  if regexp '^hd[0-9a-zA-Z,]+$' ${grubfm_disk};
  then
    regexp -s devnum '^hd([0-9]+).*$' ${grubfm_disk};
    if test "devnum" != "0";
    then
      drivemap -s (hd0) (${grubfm_disk});
    fi;
  fi;
}

grubfm_disk will be 0 since ISO file is on USB drive.

Can you reproduce the issue?

steve6375 commented 4 years ago

If I add as a quick test...

drivemap -s (hd0) (hd1);

to win.sh it works OK.

a1ive commented 4 years ago

if iso is on HDD 0, do we need to run drivemap -s (hd0) (hd1)?

steve6375 commented 4 years ago

AFAIK It is nothing to do with where the ISO file is located but how Windows determines what the boot drive is, so it can install the MBR boot sector to the boot drive. BIOS device hd0 (USB) is the boot device but in WinPE the first disk [0] is the internal disk. WinPE has identified the boot drive as the USB drive rdisk(2). Setup thinks it has not booted from USB. grubfm MBR boot - Win8 ISO - FAIL...

2020-08-24 19:25:22, Info       [0x0606cc] IBS    LogBootDeviceInfo:The firmware boot device ARC path is [multi(0)disk(0)rdisk(2)partition(1)] and NT path is [].
2020-08-24 19:25:22, Info       [0x0606cc] IBS    LogBootDeviceInfo:The system boot device ARC path is [ramdisk(0)] and NT path is [\Device\Ramdisk{d9b257fc-684e-4dcb-ab79-03cfa2f6b750}].

2020-08-24 19:25:33, Info                  IBS    Callback_WinPE_SetSourceMediaInfo_Unattend:Trying to determine source path.
2020-08-24 19:25:33, Info                  IBS    Callback_WinPE_SetSourceMediaInfo_Unattend:Not a media boot.
2020-08-24 19:25:33, Info                  IBS    Callback_WinPE_SetSourceMediaInfo_Unattend:Setting source path to [E:\Sources].

2020-08-24 19:25:33, Info       [0x0606cc] IBS    LogMediaDriveInfo: Media drive is of type CD/DVD (5)
2020-08-24 19:26:11, Info       [0x0606cc] IBS    GetSystemDiskNTPath: Found system disk at [\Device\Harddisk1\DR1].
2020-08-24 19:26:11, Info       [0x0606cc] IBS    GetSystemDiskNumber: Disk [1] is the system disk.
2020-08-24 19:26:11, Error      [0x06069d] IBS    GetMachineInfo:Couldn't find info for boot disk [1]

If boot from a flat file FAT32 USB (e.g. Windows Media Creation tool - no grubfm) then all OK...

2020-08-25 08:52:10, Info       [0x0601c2] IBS    InstallWindows:Setup Phase = 2
2020-08-25 08:52:10, Info       [0x0606cc] IBS    LogBootDeviceInfo:The firmware boot device ARC path is [multi(0)disk(0)rdisk(1)partition(1)] and NT path is [\Device\Harddisk1\Partition1].
2020-08-25 08:52:10, Info       [0x0606cc] IBS    LogBootDeviceInfo:The system boot device ARC path is [ramdisk(0)] and NT path is [\Device\Ramdisk{d9b257fc-684e-4dcb-ab79-03cfa2f6b750}].

2020-08-25 08:52:19, Info       [0x0605af] IBS    Callback_WinPE_SetSourceMediaInfo:Sources folder path is [C:\Sources]
2020-08-25 08:52:19, Info       [0x0606cc] IBS    LogMediaDriveInfo: Media drive is of type Removable (2)
2020-08-25 08:52:19, Info       [0x0606cc] IBS    LogMediaDriveInfo: Media drive [C:] is known as disk [1]
2020-08-25 08:52:19, Info       [0x0606cc] IBS    LogDeviceInfo: ----- Device instance ID: [USBSTOR\DISK&VEN_LEXAR&PROD_USB_FLASH_DRIVE&REV_1100\AA22ZX6NY3KMTMDLUCBH&0] -----

2020-08-25 08:52:25, Info       [0x0606cc] IBS    GetSystemDiskNTPath: Found system disk at [\Device\Harddisk0\DR0].
2020-08-25 08:52:25, Info       [0x0606cc] IBS    GetSystemDiskNumber: Disk [0] is the system disk.

Log files from grubfm.iso (fail) install and flat-file (OK) install - same Win8 files - same USB drive... setupact.log setupactfllat8.log

I am not exactly sure how Windows determines what the boot device is (was) in the system. If we booted from USB then BIOS hd0 will be the USB drive and Setup will make allowance for this, but if Setup thinks media type is CD\DVD maybe it assumes hd0 is the boot/system disk?

So we can swap hd0 with hd1 (drivemap -s hd0 hd1) if we know that hd0 is our USB drive and we booted from it. This means if the user installs Windows to disk 5, then the bootsector and bootmgr files will be on hd1 (first BIOS internal hard disk) which is usually the boot disk in a system.

A complication is that if a system has more than one USB drive connected to it, then BIOS hd0=first USB, hd1=second USB, hd2=first internal hard disk, hd3=second internal hard disk.

a1ive commented 4 years ago

so we just need to swap (hd0) and (hd1) in most cases?

nguyentumine commented 4 years ago

@steve6375 this function will automatically shift the order of the disks down to 1 if the grub2 disk <> 0, grub2 disk --> 0. try this

function drivemap_to_hd0 {
    if [ -z "$1" ]; then
        set _device="${root}"
    else
        set _device="${1}"
    fi
    if ! regexp -s _disknum '^hd([0-9]+)' "$_device"; then
        echo "Only hard disks are supported."
        return 1
    fi
    if [ "$_disknum" != "0" ]; then
        if [ "$_disknum" == "1" ]; then
            drivemap -s (hd0) (hd1)
        else
            set arr="9 8 7 6 5 4 3 2 1"
            # 10 disks is enough?
            regexp -s arr "${_disknum} (.*)" "$arr"
            drivemap -s (hd${_disknum}) (hd0)
            set _newdisknum="$_disknum"
            for num in $arr; do
                drivemap -s (hd${_newdisknum}) (hd${num})
                set _newdisknum=${num}
            done
            drivemap (hd0) (hd1)
            unset num
            unset _newdisknum
            unset arr
        fi
    fi
    unset _disknum
    unset _device
    return 0
}
steve6375 commented 4 years ago

Yes, but only if boot device was a USB drive. P.S. $root = cd when booting from grubfm.iso. Not sure it is necessary to move all devices down as Windows will re-enumerate them anyway. The essential thing is that the target boot device is hd0.

nguyentumine commented 4 years ago

that means grubfm needs to know where it is booted from. don't swap hd0 and $root if their order is not contiguous

if swap -s hd0 hd1 but root (USB) is hd0 then the bootloader and bootmgr will be installed on root (USB) hd1

I think the easiest solution is to reorder the disks before booting to grubfm

steve6375 commented 4 years ago

win.sh

  if [ "$grub_platform" = "pc" ];   then 
    #auto_swap; 
    if [ "${bootdev}" = "hd0" ]; then drivemap -s (hd0) (hd1); fi;
  fi;

it seems to work OK. Boot code is installed onto the internal hard disk correctly (the USB drive is unaltered). This is similar to what E2B does using grub4dos,

nguyentumine commented 4 years ago

@steve6375 for all devices? Usb, hdd...? What if I boot from hd2?

steve6375 commented 4 years ago

I tested grubfm booting from USB HDD and USB Flash drive. I would not expect anyone to boot from an internal drive to install Windows onto the same system. Does this ever happen?

nguyentumine commented 4 years ago

@steve6375 I can confirm that it works as expected. The system partition is created and the installer is completed.

Boot from USB and external SSD HDD.

win.sh

  if [ "$grub_platform" = "pc" ];   then 
  #auto_swap; 
  if [ "${bootdev}" = "hd0" ]; then drivemap -s (hd0) (hd1); fi;
  fi;

it seems to work OK. Boot code is installed onto the internal hard disk correctly (the USB drive is unaltered). This is similar to what E2B does using grub4dos,

a1ive commented 4 years ago

@steve6375 I can confirm that it works as expected. The system partition is created and the installer is completed.

Boot from USB and external SSD HDD.

win.sh

  if [ "$grub_platform" = "pc" ];   then 
    #auto_swap; 
    if [ "${bootdev}" = "hd0" ]; then drivemap -s (hd0) (hd1); fi;
  fi;

it seems to work OK. Boot code is installed onto the internal hard disk correctly (the USB drive is unaltered). This is similar to what E2B does using grub4dos,

same with winxp?