I am writing this because I found some spotty info at best about how to get a UEFI USB Thumb Drive to boot on a UEFI Class 3 computer. So I wanted to share what I found out through a lot of trial and error.
THE HISTORY BEHIND THIS
I recently had bought a laptop that had windows 10 on it. I found out the hard way that I couldn't install any OS that was not 64-Bit. I also found out that I couldn't install Windows 7, since it was not a modern UEFI CLASS 3 based OS. What I mean is, my laptop was not UEFI-CSM class 2 or older. ( No legacy BIOS compatibility. )
This link is just one of many sources that say this. No more 16/32 Bit Booting. ( Although the article doesn't come out and say no more 16-Bit, but this tutorial I am providing will show you that 16-Bit is not required to boot anymore with UEFI Class 3, which is where Intel is heading. )
https://www.anandtech.com/show/12068/in ... fi-by-2020
This doesn't apply to everyone currently who have a computer that can run windows 7 64-Bit ( or even a 32-Bit OS for that matter ). EFI has been around for over a decade, but the BIOS in general has allowed legacy boot ( 16-Bit BOOT.BIN loading kind of files ) to load the OS. And in some cases, if your computer has CSM as an option, you most likely have a UEFI Class 2 Firmware or older.
I found out, my laptop is a UEFI Class 3, which doesn't allow anything other then 64-Bit UEFI boot loading. No options for legacy booting. So the 2020 date that Intel has set just shows that they already begun making hardware that is strictly 64-Bit, and in a little over a year from the time of this post, that is all they will be making. ( NOTE : This doesn't mean they are removing 16/32 Bit Registers )
I am coming from a Windows point of view, so if I get something wrong with regards to Linux, I do apologize ahead of time. I also know that parts of this tutorial might be totally wrong, but this is what I know from trial and error and what works. I am open to input.
PREREQUISITES
1.) Windows that has diskpart on it. I believe most windows versions ( Starting with VISTA ) have this.
2.) Linux, to compile the BOOTx64.EFI file.
EDIT UPDATE (4-10-2019) : I was successful in getting this to compile under Windows 8.1. I No longer need Linux. Make sure to use the 64-Bit version of GCC 8.1 or newer.
I used gcc 8.2 from this link ----> https://nuwen.net/mingw.html.
3.) A Bootable USB Thumb Drive ( minimum of 256 Megs, although in my tests I have an 8 gig Thumb Drive ).
4.) GNU-EFI.zip file that has all the UEFI code in it.
5.) A UEFI Class 3 computer ( Desktop or Laptop ------ I tested this on a laptop )
I followed this tutorial on how to get the GNU-EFI.zip file as well as how to compile it on a linux host. I wish there was a tutorial to get this to compile on a windows host that would actually work.
https://wiki.osdev.org/UEFI_Bare_Bones
CREATING THE UEFI CLASS 3 USB BOOT DRIVE
In windows, Plug in your USB Thumb Drive and format it as FAT32.
Open a command prompt in windows.
Type: diskpart ( at this point you will be asked about security in windows, just click yes and it will open another console window that uses the diskpart environment. )
In diskpart console type: list disk ( this will show you the list of all of the relevent drives, including the USB stick )
Type: select disk 1 ( 1 was the thumb drive for me, it might be a different number for you )
Type: clean
Type: convert gpt
Type: create partition efi
Type: list disk
NOTE : At this point you should see an asterisk next to the USB drive showing that it is a GPT partition
Type: exit
Now your USB Thumb drive is set for GPT. Now format the USB Drive as FAT32 under windows. After that, open the windows file explorer and at the root of the Thumb Drive create this folder structure ---> EFI\Boot\
Once that is done, your USB Drive is bootable as a UEFI GPT Boot drive. All that is missing is the EFI file that is required by the BIOS. Notice, the lack of anything related to 16-Bit booting.
At this point you could literally copy the windows BOOTX64.EFI file into this thumb drive and into the EFI\Boot\ folder. Just make sure the NAME is correct. It MUST BE BOOTX64.EFI. This goes for your own OS that you create from this. ( NOTE : I tried to rename the file to other names, but it wouldn't boot. Only the file named BOOTX64.EFI worked. )
If you want to know more about why the EFI\BOOT\ folder structure is important, read this page.
http://www.uefi.org/registry
And if you want to know why BOOTX64.EFI is important, you need to get the PDF files from that same site. This tells you everything you need to know about UEFI.
http://www.uefi.org/specifications
On that page you will need the latest UEFI Specification PDF.
Now to compile the EFI, this is where Linux comes in, because honestly, I still do not understand why I couldn't get this to work under windows, even when compiled successfully. It simply wouldn't work. So on to your linux machine.
Go to this page and read it. It has all the info you need to compile the EFI file. https://wiki.osdev.org/UEFI_Bare_Bones
Grab the GNU-EFI.zip file, extract it on linux.
Then make sure you read the directions on how to install the MinGWx64 cross compiler.
Then create the hello.c file that is suggested on that same page.
Make sure your extracted GNU-EFI.zip file is extracted into the same folder where your C file is at. In my case the folder name was gnu-efi-3.0.8, but I renamed it to gnu-efi.
Now, one change I had to make, and this is according to the tutorial here at OSDev, go into gnu-efi/lib/ folder and look for data.c.
CHANGE THIS
Code: Select all
EFI_UNICODE_COLLATION_INTERFACE LibStubUnicodeInterface = {
LibStubStriCmp,
LibStubMetaiMatch,
LibStubStrLwrUpr,
LibStubStrLwrUpr,
NULL, // FatToStr
NULL, // StrToFat
NULL // SupportedLanguages
};
Code: Select all
EFI_UNICODE_COLLATION_INTERFACE LibStubUnicodeInterface = {
NULL,
NULL,
NULL,
NULL,
NULL, // FatToStr
NULL, // StrToFat
NULL // SupportedLanguages
};
After all of that, open a console window where your hello.c file is at and enter in these commands one at a time.
Code: Select all
x86_64-w64-mingw32-gcc -ffreestanding -Ignu-efi/inc -Ignu-efi/inc/x86_64 -Ignu-efi/inc/protocol -c -o hello.o hello.c
Code: Select all
x86_64-w64-mingw32-gcc -ffreestanding -Ignu-efi/inc -Ignu-efi/inc/x86_64 -Ignu-efi/inc/protocol -c -o data.o gnu-efi/lib/data.c
Code: Select all
x86_64-w64-mingw32-gcc -nostdlib -Wl,-dll -shared -Wl,--subsystem,10 -e efi_main -o BOOTX64.EFI hello.o data.o -lgcc
If successful, just copy the resulting BOOTX64.EFI file onto the thumb drive EFI\Boot\ folder and you now have a bootable UEFI Class 3 USB Thumb Drive.
FINAL NOTES
This is pretty much all there is to it. Now you can use DD to make an IMG file from the USB drive. Or what ever you choose from here.
However if you use a different file system, other then FAT32, you must seperate the FAT32 GPT 100Meg partition from your OS, and then have the BOOTX64.EFI point to your kernal that resides on your OS partition. How to load and call that kernel is up to your OS design and is outside the scope of this tutorial. Your OS uses the rest of the space on your thumb drive.
Another note is, this is exactly how Microsoft does it for their Windows 8.x and Windows 10 systems. The UEFI resides on a 100Meg partitition. This is also where the multi-Boot takes place. For your OS you need a minimum of 48 Megs for this partition in case you have more then 1 OS to boot as a choice. You will notice that a lot of tutorials will tell you that you need 48 Megs, and even in the specs it looks like their minimum is also 48 Megs. ( Although I might have misread that, it is how it comes across to me. )
Thanks for reading, hope this helps some of you out there.