通过 initrd 升级 ACPI 表¶
这是关于什么¶
如果 ACPI_TABLE_UPGRADE 编译选项为 true,则可以通过使用经过检测、修改、更新的版本升级 BIOS 提供的 ACPI 表,或安装全新的 ACPI 表,来升级由 ACPI 表定义的 ACPI 执行环境。
在将 initrd 与内核构建成单个镜像时,ACPI_TABLE_OVERRIDE_VIA_BUILTIN_INITRD 选项也应为 true,此功能才能正常工作。
有关所有可升级/安装的 ACPI 表的完整列表,请查看 drivers/acpi/tables.c 中 char *table_sigs[MAX_ACPI_SIGNATURE]; 的定义。
iasl (Intel 的 ACPI 编译器和反汇编器) 所知的所有 ACPI 表都应该可以被覆盖,除了
ACPI_SIG_RSDP (有 6 字节的签名)
ACPI_SIG_FACS (没有普通的 ACPI 表头)
这两者也可以实现。
这是用来做什么的¶
如果您发现了一个非常严重的 bug,以至于 Linux 内核不接受其变通方案,请向您的平台/BIOS 供应商投诉。此功能允许您在您的平台/BIOS 供应商发布升级的 BIOS 二进制文件之前,升级有 bug 的表。
此功能可供平台/BIOS 供应商使用,以在不修改底层平台固件的情况下提供与 Linux 兼容的环境。
通过修改旧平台提供的 ACPI 表或插入新的 ACPI 表,此功能还提供了一个强大的特性,可以轻松调试和测试 ACPI BIOS 表与 Linux 内核的兼容性。
它可以在任何内核中启用,也应该启用,因为对于未检测的 initrd,没有功能上的变化。
它是如何工作的¶
# Extract the machine's ACPI tables:
cd /tmp
acpidump >acpidump
acpixtract -a acpidump
# Disassemble, modify and recompile them:
iasl -d *.dat
# For example add this statement into a _PRT (PCI Routing Table) function
# of the DSDT:
Store("HELLO WORLD", debug)
# And increase the OEM Revision. For example, before modification:
DefinitionBlock ("DSDT.aml", "DSDT", 2, "INTEL ", "TEMPLATE", 0x00000000)
# After modification:
DefinitionBlock ("DSDT.aml", "DSDT", 2, "INTEL ", "TEMPLATE", 0x00000001)
iasl -sa dsdt.dsl
# Add the raw ACPI tables to an uncompressed cpio archive.
# They must be put into a /kernel/firmware/acpi directory inside the cpio
# archive. Note that if the table put here matches a platform table
# (similar Table Signature, and similar OEMID, and similar OEM Table ID)
# with a more recent OEM Revision, the platform table will be upgraded by
# this table. If the table put here doesn't match a platform table
# (dissimilar Table Signature, or dissimilar OEMID, or dissimilar OEM Table
# ID), this table will be appended.
mkdir -p kernel/firmware/acpi
cp dsdt.aml kernel/firmware/acpi
# A maximum of "NR_ACPI_INITRD_TABLES (64)" tables are currently allowed
# (see osl.c):
iasl -sa facp.dsl
iasl -sa ssdt1.dsl
cp facp.aml kernel/firmware/acpi
cp ssdt1.aml kernel/firmware/acpi
# The uncompressed cpio archive must be the first. Other, typically
# compressed cpio archives, must be concatenated on top of the uncompressed
# one. Following command creates the uncompressed cpio archive and
# concatenates the original initrd on top:
find kernel | cpio -H newc --create > /boot/instrumented_initrd
cat /boot/initrd >>/boot/instrumented_initrd
# reboot with increased acpi debug level, e.g. boot params:
acpi.debug_level=0x2 acpi.debug_layer=0xFFFFFFFF
# and check your syslog:
[ 1.268089] ACPI: PCI Interrupt Routing Table [\_SB_.PCI0._PRT]
[ 1.272091] [ACPI Debug] String [0x0B] "HELLO WORLD"
iasl 能够反汇编和重新编译许多不同的、甚至是静态的 ACPI 表。
在哪里获取用户空间工具¶
iasl 和 acpixtract 是 Intel ACPICA 项目的一部分:https://acpica.org/
并且应该由发行版打包 (例如在 SUSE 上的 acpica 包中)。
acpidump 可以在 Len Browns 的 pmtools 中找到:ftp://linuxkernel.org.cn/pub/linux/kernel/people/lenb/acpi/utils/pmtools/acpidump
此工具也是 SUSE 上 acpica 包的一部分。另外,在最新的内核中,可以通过 sysfs 检索使用的 ACPI 表:/sys/firmware/acpi/tables