116 lines
4.3 KiB
ReStructuredText
116 lines
4.3 KiB
ReStructuredText
|
.. SPDX-License-Identifier: GPL-2.0
|
||
|
|
||
|
================================
|
||
|
Upgrading ACPI tables via initrd
|
||
|
================================
|
||
|
|
||
|
What is this about
|
||
|
==================
|
||
|
|
||
|
If the ACPI_TABLE_UPGRADE compile option is true, it is possible to
|
||
|
upgrade the ACPI execution environment that is defined by the ACPI tables
|
||
|
via upgrading the ACPI tables provided by the BIOS with an instrumented,
|
||
|
modified, more recent version one, or installing brand new ACPI tables.
|
||
|
|
||
|
When building initrd with kernel in a single image, option
|
||
|
ACPI_TABLE_OVERRIDE_VIA_BUILTIN_INITRD should also be true for this
|
||
|
feature to work.
|
||
|
|
||
|
For a full list of ACPI tables that can be upgraded/installed, take a look
|
||
|
at the char `*table_sigs[MAX_ACPI_SIGNATURE];` definition in
|
||
|
drivers/acpi/tables.c.
|
||
|
|
||
|
All ACPI tables iasl (Intel's ACPI compiler and disassembler) knows should
|
||
|
be overridable, except:
|
||
|
|
||
|
- ACPI_SIG_RSDP (has a signature of 6 bytes)
|
||
|
- ACPI_SIG_FACS (does not have an ordinary ACPI table header)
|
||
|
|
||
|
Both could get implemented as well.
|
||
|
|
||
|
|
||
|
What is this for
|
||
|
================
|
||
|
|
||
|
Complain to your platform/BIOS vendor if you find a bug which is so severe
|
||
|
that a workaround is not accepted in the Linux kernel. And this facility
|
||
|
allows you to upgrade the buggy tables before your platform/BIOS vendor
|
||
|
releases an upgraded BIOS binary.
|
||
|
|
||
|
This facility can be used by platform/BIOS vendors to provide a Linux
|
||
|
compatible environment without modifying the underlying platform firmware.
|
||
|
|
||
|
This facility also provides a powerful feature to easily debug and test
|
||
|
ACPI BIOS table compatibility with the Linux kernel by modifying old
|
||
|
platform provided ACPI tables or inserting new ACPI tables.
|
||
|
|
||
|
It can and should be enabled in any kernel because there is no functional
|
||
|
change with not instrumented initrds.
|
||
|
|
||
|
|
||
|
How does it work
|
||
|
================
|
||
|
::
|
||
|
|
||
|
# 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 is able to disassemble and recompile quite a lot different,
|
||
|
also static ACPI tables.
|
||
|
|
||
|
|
||
|
Where to retrieve userspace tools
|
||
|
=================================
|
||
|
|
||
|
iasl and acpixtract are part of Intel's ACPICA project:
|
||
|
https://acpica.org/
|
||
|
|
||
|
and should be packaged by distributions (for example in the acpica package
|
||
|
on SUSE).
|
||
|
|
||
|
acpidump can be found in Len Browns pmtools:
|
||
|
ftp://kernel.org/pub/linux/kernel/people/lenb/acpi/utils/pmtools/acpidump
|
||
|
|
||
|
This tool is also part of the acpica package on SUSE.
|
||
|
Alternatively, used ACPI tables can be retrieved via sysfs in latest kernels:
|
||
|
/sys/firmware/acpi/tables
|