如何使用 efivars 检索 BIOS 使用的控制台端口的详细信息?
How to retrieve details of the console port used by BIOS using efivars?
作为 linux 安装的一部分,我想通过基于 Intel 的平台的内核命令行设置“控制台设备属性”(例如,console=ttyS0,115200n1)。
没有 VGA 控制台,只有通过 COM 接口的串行控制台。
在这些系统上,BIOS 已经具有使用适当的串行端口进行交互所需的设置。
我看到 EFI 有变量 ConIn、ConOut、ConErr,我可以从 /sys/firmware/efi 中看到这些变量,但无法解码其中的内容。
是否可以通过检查 efi 变量来识别 BIOS 正在使用哪个 COM 端口。
示例,我的盒子上的 EFI 变量。
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:~#
在我的例子中,因为我知道控制台端口是一个“串行 IOPORT”,
我现在可以得到详细信息如下。
一种。弄个/sys/firmware/acpi/tables/SPCtable。
b.读取地址偏移量 44-52。实际上一个最后两个字节就足够了。
Base Address 12 40
The base address of the Serial Port register set described using the ACPI Generic Address Structure.
0 = console redirection disabled
Note:
COM1 (0x3F8) would be:
Integer Form: 0x 01 08 00 00 00000000000003F8
Viewed in Memory: 0x01080000F803000000000000
COM2 (Ox2F8) would be:
Integer Form: 0x 01 08 00 00 00000000000002F8
Viewed in Memory: 0x01080000F802000000000000
UEFI 规范中描述了 ConOut 变量的内容 - current version (2.8B):
3.3 - 全局定义的变量:
| Name | Attribute | Description |
|---------|------------|------------------------------------------------|
| ConOut | NV, BS, RT | The device path of the default output console. |
关于设备路径的信息,我们有:
10 - 协议 - 设备路径协议:
除了设备路径的初始描述之外,table44 向您展示了通用设备路径节点结构,我们可以从中开始解码变量的内容。
第一个节点的类型是0x02
,告诉我们这个节点描述了一个0x000c
字节长度的ACPI设备路径。现在跳转到 10.3.3 - ACPI 设备路径和 table 52,它告诉我们 1) 这是正确的 table(子类型 0x01
)和 2) 默认 ConOut 具有0x0a03410d
的 _HID 和 0
.
的 _UID
下一个节点的类型为 0x01
- 硬件设备路径,在 10.3.2 中进一步描述,在本例中 table 46(SubType
是 0x01
) 用于 PCI 设备路径。
下一个节点描述了 UART 类型的消息传递设备路径等等...
不过,这只告诉您 UEFI 认为什么是它的默认控制台,SPCR 是操作系统应该查看的串行控制台。不幸的是,在 X86 上,linux 内核很容易忽略 SPCR,除了 earlycon。我想这就是您要解决的问题。最好在内核开发列表上开始一些关于是否修复该问题并让 X86 像 ARM64 一样工作的讨论。
作为 linux 安装的一部分,我想通过基于 Intel 的平台的内核命令行设置“控制台设备属性”(例如,console=ttyS0,115200n1)。
没有 VGA 控制台,只有通过 COM 接口的串行控制台。 在这些系统上,BIOS 已经具有使用适当的串行端口进行交互所需的设置。
我看到 EFI 有变量 ConIn、ConOut、ConErr,我可以从 /sys/firmware/efi 中看到这些变量,但无法解码其中的内容。
是否可以通过检查 efi 变量来识别 BIOS 正在使用哪个 COM 端口。
示例,我的盒子上的 EFI 变量。
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:~#
在我的例子中,因为我知道控制台端口是一个“串行 IOPORT”, 我现在可以得到详细信息如下。 一种。弄个/sys/firmware/acpi/tables/SPCtable。 b.读取地址偏移量 44-52。实际上一个最后两个字节就足够了。
Base Address 12 40
The base address of the Serial Port register set described using the ACPI Generic Address Structure.
0 = console redirection disabled
Note:
COM1 (0x3F8) would be:
Integer Form: 0x 01 08 00 00 00000000000003F8
Viewed in Memory: 0x01080000F803000000000000
COM2 (Ox2F8) would be:
Integer Form: 0x 01 08 00 00 00000000000002F8
Viewed in Memory: 0x01080000F802000000000000
UEFI 规范中描述了 ConOut 变量的内容 - current version (2.8B):
3.3 - 全局定义的变量:
| Name | Attribute | Description |
|---------|------------|------------------------------------------------|
| ConOut | NV, BS, RT | The device path of the default output console. |
关于设备路径的信息,我们有:
10 - 协议 - 设备路径协议:
除了设备路径的初始描述之外,table44 向您展示了通用设备路径节点结构,我们可以从中开始解码变量的内容。
第一个节点的类型是0x02
,告诉我们这个节点描述了一个0x000c
字节长度的ACPI设备路径。现在跳转到 10.3.3 - ACPI 设备路径和 table 52,它告诉我们 1) 这是正确的 table(子类型 0x01
)和 2) 默认 ConOut 具有0x0a03410d
的 _HID 和 0
.
下一个节点的类型为 0x01
- 硬件设备路径,在 10.3.2 中进一步描述,在本例中 table 46(SubType
是 0x01
) 用于 PCI 设备路径。
下一个节点描述了 UART 类型的消息传递设备路径等等...
不过,这只告诉您 UEFI 认为什么是它的默认控制台,SPCR 是操作系统应该查看的串行控制台。不幸的是,在 X86 上,linux 内核很容易忽略 SPCR,除了 earlycon。我想这就是您要解决的问题。最好在内核开发列表上开始一些关于是否修复该问题并让 X86 像 ARM64 一样工作的讨论。