Plan 9: Quick Boot with UEFI

 UEFI (Unified Extensible Firmware Interface) provides a quick way to set up a Plan 9 terminal on modern hardwareEFI System Partition (ESP) is a FAT32 partition. You should be able to modify it in most of the operating systems.


 
 

Run mk in \sys\src\boot\efi. aux/aout2efi converts an a.out file to an EFI executable. Copy over the files bootx64.efi, 9pc64, plan9.ini (for x86_64 hardware) to \EFI\plan9\ directory in the ESP. If you want it be the default OS, you can create a symlink \EFI\boot to \EFI\plan9. Remember to include the full path to the kernel in plan9.ini.

bootfile=\EFI\plan9\9pc64 
   

When bootx64.efi fails to find the bootfile (e.g. kernel is missing, plan9.ini is missing or path is incorrect), you can provide the arguments at > prompt followed by a boot command.

You can use EFI shell or efibootmgr on Linux to modify the EFI entries that are displayed during boot.

 

Test in QEMU

Before running on actual hardware, it might help to get familiar with the process in a virtual environment. OVMF, or Open Virtual Machine Firmware, is an open-source implementation of the UEFI (Unified Extensible Firmware Interface) specification for virtual machines. Install QEMU and OVMF.
sudo apt-get install qemu-system ovmf

Copy all the files mentioned above to a root dir maintaining the directory structure. Also copy OVMF.fd to the current dir.
cp /usr/share/qemu/OVMF.fd .

Then run QEMU using the following:
qemu-system-x86_64 -drive if=pflash,format=raw,file=OVMF.fd -drive format=raw,file=fat:rw:root
 

Manage boot configuration with efibootmgr

Use efibootmgr to manage the EFI boot configuration. Linux mounts the ESP at /boot/efi.

efibootmgr -c -d /dev/sda -p 7 -L "Plan 9" -l EFI/plan9/bootx64.efi

 

EFI Shell

EFI Shell follows DOS conventions - it is case insensitive and uses backslash (\) for directory separator. 
List attached devices:
map
 
Boot an EFI application on FS0:
FS0:
EFI\plan9\bootx64.efi 
 
Add Plan 9 as the first (zero based index) boot option.
bcfg boot add 0 FS0:\EFI\plan9\bootx64.efi "Plan 9"
 

Programming

Print a CHAR16 string txt:
eficall(ST->ConOut->OutputString, ST->ConOut, txt);   
 

Image file path:

typedef struct {
  void *ConvertDeviceNodeToText;
  void *ConvertDevicePathToText;
} EFI_DEVICE_PATH_TO_TEXT_PROTOCOL;

static EFI_GUID EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID = {
  0x8b843e20,0x8132,0x4852,
  {0x90,0xcc,0x55,0x1a,0x4e,0x4a,0x7f,0x1c}
};


EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *dpt;
CHAR16 *txt;
eficall(ST->BootServices->LocateProtocol, &EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID, nil, &dpt);
txt = (CHAR16*) eficall(dpt->ConvertDevicePathToText, image->FilePath, 1, 1);
   

  

Lessons Learnt

  • Always backup ESP especially if you need Windows. It's almost impossible to get bootmgr.efi for Windows from external sources. (Boot manager: \EFI\Microsoft\Boot\bootmgfw.efi , OS loader: \windows\system32\windload.efi) 
  • Depending on your configuration in Linux, you might have a copy of the ESP at /boot/efi.

 

References


Comments

Popular posts from this blog

Plan 9 : The Infinity Notebook

Emacs: Binary File Viewer

Emacs: A non-intrusive browser