Search code examples
linux-device-driveruefi

How to retrieve details of the console port used by BIOS using efivars?


As part of installation of linux, I would like to set the "console device properties"(example, console=ttyS0,115200n1) via the kernel cmdline for Intel based platform.

There is No VGA console, only serial consoles via COM interface. On these systems BIOS already has the required settings to interact using the appropriate serial port.

I see that EFI has variables ConIn, ConOut, ConErr which I am able to see from /sys/firmware/efi but unable to decode the contents of it.

Is it possible to identify which COM port is being used by the BIOS by examining the efi variables.

Example, of the EFI var on my box.

root@linux:~# efivar -p -n 8be4df61-93ca-11d2-aa0d-00e098032b8c-ConOut
GUID: 8be4df61-93ca-11d2-aa0d-00e098032b8c
Name: "ConOut"
Attributes:
        Non-Volatile
        Boot Service Access
        Runtime Service Access
Value:
00000000  02 01 0c 00 d0 41 03 0a  00 00 00 00 01 01 06 00  |.....A..........|
00000010  00 1a 03 0e 13 00 00 00  00 00 00 c2 01 00 00 00  |................|
00000020  00 00 08 01 01 03 0a 18  00 9d 9a 49 37 2f 54 89  |...........I7/T.|
00000030  4c a0 26 35 da 14 20 94  e4 01 00 00 00 03 0a 14  |L.&5.. .........|
00000040  00 53 47 c1 e0 be f9 d2  11 9a 0c 00 90 27 3f c1  |.SG..........'?.|
00000050  4d 7f 01 04 00 02 01 0c  00 d0 41 03 0a 00 00 00  |M.........A.....|
00000060  00 01 01 06 00 00 1f 02  01 0c 00 d0 41 01 05 00  |............A...|
00000070  00 00 00 03 0e 13 00 00  00 00 00 00 c2 01 00 00  |................|
00000080  00 00 00 08 01 01 03 0a  18 00 9d 9a 49 37 2f 54  |............I7/T|
00000090  89 4c a0 26 35 da 14 20  94 e4 01 00 00 00 03 0a  |.L.&5.. ........|
000000a0  14 00 53 47 c1 e0 be f9  d2 11 9a 0c 00 90 27 3f  |..SG..........'?|
000000b0  c1 4d 7f ff 04 00                                 |.M....          |
root@linux:~#

Solution

  • The contents of the ConOut variable are described in the UEFI specification - current version (2.8B):

    3.3 - globally defined variables:

    | Name    | Attribute  | Description                                    |
    |---------|------------|------------------------------------------------|
    | ConOut  | NV, BS, RT | The device path of the default output console. |
    

    For information about device paths, we have:

    10 - Protocols — Device Path Protocol:

    Apart from the initial description of device paths, table 44 shows you the Generic Device Path Node structure, from which we can start decoding the contents of the variable.

    The type of the first node is 0x02, telling us this node describes an ACPI device path, of 0x000c bytes length. Now jump down to 10.3.3 - ACPI Device Path and table 52, which tells us 1) that this is the right table (subtype 0x01) and 2) that the default ConOut has a _HID of 0x0a03410d and a _UID of 0.

    The next node has a type of 0x01 - a Hardware Device Path, described further in 10.3.2, in this case table 46 (SubType is 0x01) for a PCI device path. The next node describes a Messaging Device Path of type UART and so on...

    Still, this only tells you what UEFI considers to be its default console, SPCR is what an operating system is supposed to be looking at for serial consoles. Unfortunately, on X86 the linux kernel handily ignores SPCR apart from for earlycon. I guess this is what you're trying to work around. It might be good to start some discussion on kernel development lists about whether to fix that and have X86 work like ARM64.