Friday, 16 May 2014

Boot directly from grub4dos to UEFI using Clover!

Clover is a later revision of Tianocore. Both are 'firmware in RAM' replacements for UEFI firmware.
It allows you to boot in MBR\CSM mode and then run Clover which acts as a 'pseudo-UEFI boot manager', allowing you to boot to a UEFI OS from an MBR\CSM boot.

I would like to add this to the CSM menu of Easy2Boot so that users would not have to reboot the system and choose the UEFI: xxxxxx  boot option to boot from the E2B drive (when using .imgPTN image files).

First, I made a FAT32 USB Flash drive using BootDiskUtility.exe. This is a Windows tool that makes a Clover-bootable USB drive for you. Having done this, I found it would not boot under RMPrepUSB's QEMU (which doesn't support 64-bitness and just rebooted) or VirtualBox (text mode menu only) but did boot on a real system to the full GUI menu (see piccy below) - but only on a USB 2.0 port, Clover does not load on my Z87's USB 3.0 ports.

When is EFI not EFI?

Another important (and confusing!) point to note is that 'EFI booting' means MBR booting in 'Clover-speak' and UEFI booting means UEFI booting. If you see a Clover menu option to EFI-boot from a drive - it means MBR\CSM-boot!

This is the 'expected' full-GUI Clover Menu - select the UEFI option for UEFI booting as shown.

This is the text-mode screen I got!

Under VBox, I only got the 'text-mode' screen after making a USB Flash drive using BootDiskUtility.exe to make the USB drive. However, if I ran the USB drive on a real system, I got the correct GUI menu.

I later found that by pressing the 7 key after the first 2 seconds when booting from VBox, I managed to get the correct GUI menu!

To cut a long story short (essential data about Clover is hard to find!), here is how the Clover boot-chain works...

Master Boot Record (MBR)

First in the boot chain, we have the MBR. This is a normal MBR with a partition table, but the code in it seems to be 'special' (see PBR below for why I think this).

The MBR code can be found in a selection of boot0xxx files. You need to replace the boot code in your USB drive's MBR with the boot code from one of these files (but not the partition table).

The MBR code seems to look for and boot a Clover PBR. I found these files for the MBR code:

boot0af - looks for the active partition PBR
boot0ss - 'scan-signature' for AF type - MAC OS extended - seems to work best - no Active ptn needed.
boot0md - multiple drives - searches various drives for an HFS+/MAC OS extended partition - it seems to need the partition to be flagged as Active though!

see here for more (unclear) details! boot0ss still seems to boot from a FAT32 partition the best though!

Partition Boot Record

Moving on to the PBR - this code also seems 'special' in that we cannot just use chainloader ()+1 to boot from it in grub4dos. It seems we MUST go from the Clover MBR code to the Clover PBR code. Therefore both MBR code and PBR code are inter-dependent.

Again, various different Clover PBR code versions are available, these are prefixed as boot1xxx - the PBR code must be patched from byte 3 to byte 86 decimal. In the files produced by the BootDiskUtility, I had these files:

boot1f32 - understands the FAT32 filesystem
boot1f32alt - as above but waits for a key press for 2 seconds
boot1h - understands the HFS+ filesystem for MACs
boot1h2 - as above but waits 2 seconds for a key press

I used boot1f32alt for my experiments. See here for more PBR details.

The next stage in the boot chain is the file that is loaded by the PBR code. By default, this is a file in the root and is called boot.
  • boot - (default) Clover, recent or testing version - rumoured to be the same as boot6 in released versions
  • boot2 - Chameleon
  • boot3 - Clover 32-bit, tested and working version
  • boot6 - Clover 64-bit, tested and working version
  • boot7 - Clover 64-bit with BiosBlockIO driver that works with any controller supported by the BIOS.
Now, here we have a FUNDAMENTAL FLAW (did you spot it?) - the default boot file is boot but Windows uses a folder called boot to hold it's boot files - we cannot have both a file and a folder with the same name on a FAT32 partition! Great thinking guys!

So, assuming I must keep the \boot Windows folder, I had to press 6 or 7 on a real system  to get it to boot to Clover. Eventually I found a way around this though, the PBR code had an ASCII string of
near the beginning of the code. I then found that if I modified this to
it loaded the \boot7 file automatically! I am guessing that when a user presses 7 manually, it just adds the ASCII code for 7 to the end of the 'BOOT' string in memory, and then tries to load that file.

More Files!

Once the \boot(n) code runs, it loads up the rest of Clover from the \EFI\CLOVER folder starting off with
CloverIA32.efi or CloverX64.efi or CloverGUI. Note how these files have the .efi file extension but actually run in MBR mode, whereas normal files such as Microsoft bootx64.efi and bootia32.efi files have the same file extension but run in UEFI mode! Confusing huh?

It then accesses more files under the \EFI\CLOVER folder - see here for more details.

Putting it all together

So after all this - here is my boot chain that works for 64-bit UEFI Windows 8 booting from a single FAT32 partition:

MBR (using boot0md code) ->  PBR (using modified boot1f32alt code) -> \boot7 -> \EFI\CLOVER\CloverX64.efi  ->  Clover menu - \EFI\boot\bootx64.efi ---> Windows UEFI boot.

However, I found that if I chainloaded to /boot0md or /boot0ss in grub4dos, as long as the PBR  had the Clover code in it, it would boot (the md version also needed the partition to be Active too). This meant I can boot to grub4dos in MBR mode to the grub4dos menu and then, from that menu, run Clover - at last!


So here is my current grub4dos menu for booting directly to UEFI via Clover from grub4dos:
Note it is for FAT32 only and has not been tested on linux, only Windows 8.1 x64 so far.

iftitle [cat --locate="FAT32" --length=10 --skip=0x50 ()+1 > nul] Run Clover UEFI Boot Menu\n Run this if you wish to use Clover to UEFI boot
set CL=0
## boot7 is default boot file
cat --locate="BOOT7" --length=10 --skip=0x58 ()+1 > nul && set /a CL=%CL%+1 > nul
if "%CL%"=="1" echo Information: Clover is already installed to the PBR
## configfile /menu.lst
echo ffffffffff > (md)0x350+1
dd if=(hd0,0)+1 of=(md)0x350+1 > nul
dd if=()/clover/boot1f32alt7 of=(md)0x350+1 skip=87 seek=87 bs=1 > nul
dd if=()/clover/boot1f32alt7 of=(md)0x350+1 count=3 bs=1 > nul
#cat --hex (md)0x350+1 && pause 
if not "%CL%"=="1" cat --locate="SYSLINUX" --length=10 --skip=0x2 ()+1 > nul && pause PROBLEM: SYSLINUX PBR DETECTED - Cannot install Clover to PBR... && configfile /menu.lst
if not "%CL%"=="1" dd if=(md)0x350+1 of=(hd0,0)+1 > nul && pause --wait=2 PBR updated with Clover boot code
chainloader /clover/boot0ss || chainloader /clover/boot0md || chainloader /clover/boot0af

# User can press 2 for 3 for 32-bit UEFI, 6 for 64-bit UEFI or 1 for Chameleon - within 3 seconds
# boot0md gives a boot0 message and is slower - boot0ss is silent with no message

It needs a bit more work and tidying up.

boot1f32alt7 is the modified PBR 512-byte file which will load \boot7 instead of \boot.
The grub4dos menu code works by permanently installing the Clover PBR code into the PBR (it must be FAT32 and it must not have syslinux in the PBR as I assume that if syslinux is in the PBR, it needs it in order to boot to linux - overwriting it would prevent it from booting via syslinux in MBR mode!)
I also moved the boot0xx and boot1xx files to a \Clover folder to keep it tidier.
The user can still press 2, 3 6 or 7 to boot to \boot2, \boot3, \boot6 or \boot7 as these are (currently) still in the root of the FAT32 partition (Edit: in Clover_Pack 002 only boot6 and boot7 are present!).

It would be nice to be able to run syslinux in MBR-bot mode (see below for how I got this to work too).

I now need to test this out on different platforms and different scenarios - hey ho...

A good source of info on Clover is here.

P.S. In later versions, I first save the current PBR into a file using grub4dos code at the start of the menu.lst file. Then, to boot to syslinux, I just use  'chainloader /PBR.bin' to boot using the code that was in the PBR. In this way I can boot to the syslinux code that was in the PBR before it was replaced by Clover. The \PBR.bin file must already exist on the USB drive and must be 512 bytes or longer if FAT32 (for NTFS it needs to be approx. 1K or larger).

# backup PBR if it does NOT contain Clover boot code
cat --locate="BOOT7" --length=10 --skip=0x58 ()+1 > nul || dd if=()+2 of=()/PBR.BIN > nul

# boot to syslinux using the PBR.BIN file if it contains syslinux

cat --locate="SYSLINUX" --length=10 --skip=0x2 /PBR.BIN > nul && chainloader /PBR.BIN && boot

You can obtain the Clover files by downloading the MPI Tool Pack for Easy2Boot.