Adding serial console support to EFI Shell

Return to index.

The EFI environment relies heavily on abstractions that various drivers can extend; for example, GRUB (by default) or the EFI Shell do not directly deal with graphics, but output to a generic "stdout" based on the Simple Text Output protocol.

By default the firmware includes a generic VGA driver to display such text through a connected monitor, but additional drivers attaching to the same protocol can be loaded at some later point – and the upstream EDK2 (aka Tianocore) project already has drivers for serial port output, which can be loaded at boot time.

Note: This doesn't add serial console support to all of UEFI – not the boot screen and certainly not the (entirely graphics-mode) setup interface. Still, having the EFI Shell available can become a useful recovery tool when.

Download the EDK2 repository and some build dependencies:

sudo pacman -S --asdeps iasl nasm
git clone https://github.com/tianocore/edk2
cd edk2
git submodule update --init

Compile the MdeModule package:

. ./edksetup.sh
make -C BaseTools
build -a X64 -t GCC -p MdeModulePkg/MdeModulePkg.dsc

Copy the built *Dxe.efi binaries to somewhere in the EFI system partition:

scp Build/MdeModule/DEBUG_GCC/X64/*{Serial,Terminal}Dxe.efi root@horizon:/boot/

Finally, write (or update) your startup.nsh (which should be placed in the EFI partition right next to ShellX64.efi, usually that's /boot/startup.nsh):

# Stub SerialIO driver for EFI-provided "serial I/O" protocol
#load fs0:\SerialDxe.efi

# SerialIO driver for direct UART access
load fs0:\PciSioSerialDxe.efi

# SimpleTextIn/Out driver which runs over SerialIO
load fs0:\TerminalDxe.efi

If everything goes well, booting into ShellX64.efi (e.g. selecting the EFI Shell menu entry in GRUB) will show a Shell> prompt at the serial console.

Only one of the SerialIO drivers is necessary, and in most cases you will need PciSioSerialDxe as desktop PC firmwares won't have any support built in for SerialDxe to work. You can load the drivers interactively, then use the dh command to dump EFI handles and see which SerialIO implementations are active:

Shell> dh -p SerialIO > fs1:\ser.txt

The TerminalDxe driver is what implements the "ANSI" or "VT220" terminal control. Beware that it assumes a fixed-size terminal – by default 80x25 – and since the Shell does use cursor positioning, a larger terminal window will result in a bit of a mess. (But that is nothing new, if you've ever tried to use Vim over serial tty.)