Using the UEFI Shell to Restore Boot Configuration

biosbootloaderuefi

I am using an embedded board that supports UEFI. It is a new fangled board and comes up with American Megatrends BIOS and a UEFI shell (I am more used to dealing with a bootloader and not a PC BIOS on an embedded board).

The details of the board are not so important.

What is important is that under certain conditions (in software while writing to PCI space in an incorrect way) we can hose the boot sector in the onboard Flash.

Since this hardware will be a REMOTE piece of hardware, there is no option of walking out to nowhere land, sticking in a USB and reflashing this thing.

I would like to write a script to make the BIOS Shell do this. If the machine is hosed and we have corrupted the bootsector on a deployed system, I would like to automatically run a restore sequence. Is this sort of thing possible? Can I do it with a UEFI shell? Is this doable in anyway?

Now I understand UEFI was created to provide 'secure' boot, I may be doing the opposite of what it was intended to do!

Best Answer

EFI doesn't use the boot sector of the disk. Thus, I suspect that you misunderstand what's happening to your system. My guess is that you're actually damaging the NVRAM entries that hold the boot order for the device. The easiest way to deal with this problem is to not use those entries, and instead name your EFI boot loader EFI/BOOT/bootx64.efi (or more generally, boot{arch}.efi, where {arch} is an architecture code; x64 is the architecture code for x86-64). If you don't want to do this for some reason, and if your EFI shell is a version 2 shell, you can use the bcfg command in an EFI shell script to do the job. This command is documented to varying extents in various places, such as the Arch Linux wiki and Intel's site. Unfortunately, the older version 1 EFI shell doesn't support the bcfg command, so this option won't work with it, although it might be possible to extract the relevant code from the TianoCore source code and create a standalone bcfg command that you could use with an older shell.

If you really need to write to the MBR, then writing an EFI application in C might be a better choice than trying to do it in the EFI shell. There's a lot of EFI programming documentation out there, but most of it is like Unix man pages -- it assumes that you already know the topic and just need to check the details. I've written a brief tutorial introduction, but it's very basic and doesn't cover disk I/O. (You could use that and the source code to gptsync, which is included in the last couple versions of rEFInd, though, to learn how to read and write the MBR of a disk.)

If I understand correctly, whatever you do (unless using the fallback filename is sufficient), you'd need to fit it into the normal boot sequence. This would be possible with either an EFI shell program launched as the default or as a binary program; but you'll have to be sure that your custom program concludes by launching the "real" boot loader, or that the "real" boot loader launches after the new program.