요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>
===================================================
ACPI Device Tree - Representation of ACPI Namespace
===================================================
:Copyright: |copy| 2013, Intel Corporation
:Author: Lv Zheng <[email protected]>
:Credit: Thanks for the help from Zhang Rui <[email protected]> and
Rafael J.Wysocki <[email protected]>.
Abstract
========
The Linux ACPI subsystem converts ACPI namespace objects into a Linux
device tree under the /sys/devices/LNXSYSTM:00 and updates it upon
receiving ACPI hotplug notification events. For each device object
in this hierarchy there is a corresponding symbolic link in the
/sys/bus/acpi/devices.
This document illustrates the structure of the ACPI device tree.
ACPI Definition Blocks
======================
The ACPI firmware sets up RSDP (Root System Description Pointer) in the
system memory address space pointing to the XSDT (Extended System
Description Table). The XSDT always points to the FADT (Fixed ACPI
Description Table) using its first entry, the data within the FADT
includes various fixed-length entries that describe fixed ACPI features
of the hardware. The FADT contains a pointer to the DSDT
(Differentiated System Description Table). The XSDT also contains
entries pointing to possibly multiple SSDTs (Secondary System
Description Table).
The DSDT and SSDT data is organized in data structures called definition
blocks that contain definitions of various objects, including ACPI
control methods, encoded in AML (ACPI Machine Language). The data block
of the DSDT along with the contents of SSDTs represents a hierarchical
data structure called the ACPI namespace whose topology reflects the
structure of the underlying hardware platform.
The relationships between ACPI System Definition Tables described above
are illustrated in the following diagram::
+---------+ +-------+ +--------+ +------------------------+
| RSDP | +->| XSDT | +->| FADT | | +-------------------+ |
+---------+ | +-------+ | +--------+ +-|->| DSDT | |
| Pointer | | | Entry |-+ | ...... | | | +-------------------+ |
+---------+ | +-------+ | X_DSDT |--+ | | Definition Blocks | |
| Pointer |-+ | ..... | | ...... | | +-------------------+ |
+---------+ +-------+ +--------+ | +-------------------+ |
| Entry |------------------|->| SSDT | |
+- - - -+ | +-------------------| |
| Entry | - - - - - - - -+ | | Definition Blocks | |
+- - - -+ | | +-------------------+ |
| | +- - - - - - - - - -+ |
+-|->| SSDT | |
| +-------------------+ |
| | Definition Blocks | |
| +- - - - - - - - - -+ |
+------------------------+
|
OSPM Loading |
\|/
+----------------+
| ACPI Namespace |
+----------------+
Figure 1. ACPI Definition Blocks
.. note:: RSDP can also contain a pointer to the RSDT (Root System
Description Table). Platforms provide RSDT to enable
compatibility with ACPI 1.0 operating systems. The OS is expected
to use XSDT, if present.
Example ACPI Namespace
======================
All definition blocks are loaded into a single namespace. The namespace
is a hierarchy of objects identified by names and paths.
The following naming conventions apply to object names in the ACPI
namespace:
1. All names are 32 bits long.
2. The first byte of a name must be one of 'A' - 'Z', '_'.
3. Each of the remaining bytes of a name must be one of 'A' - 'Z', '0'
- '9', '_'.
4. Names starting with '_' are reserved by the ACPI specification.
5. The '\' symbol represents the root of the namespace (i.e. names
prepended with '\' are relative to the namespace root).
6. The '^' symbol represents the parent of the current namespace node
(i.e. names prepended with '^' are relative to the parent of the
current namespace node).
The figure below shows an example ACPI namespace::
+------+
| \ | Root
+------+
|
| +------+
+-| _PR | Scope(_PR): the processor namespace
| +------+
| |
| | +------+
| +-| CPU0 | Processor(CPU0): the first processor
| +------+
|
| +------+
+-| _SB | Scope(_SB): the system bus namespace
| +------+
| |
| | +------+
| +-| LID0 | Device(LID0); the lid device
| | +------+
| | |
| | | +------+
| | +-| _HID | Name(_HID, "PNP0C0D"): the hardware ID
| | | +------+
| | |
| | | +------+
| | +-| _STA | Method(_STA): the status control method
| | +------+
| |
| | +------+
| +-| PCI0 | Device(PCI0); the PCI root bridge
| +------+
| |
| | +------+
| +-| _HID | Name(_HID, "PNP0A08"): the hardware ID
| | +------+
| |
| | +------+
| +-| _CID | Name(_CID, "PNP0A03"): the compatible ID
| | +------+
| |
| | +------+
| +-| RP03 | Scope(RP03): the PCI0 power scope
| | +------+
| | |
| | | +------+
| | +-| PXP3 | PowerResource(PXP3): the PCI0 power resource
| | +------+
| |
| | +------+
| +-| GFX0 | Device(GFX0): the graphics adapter
| +------+
| |
| | +------+
| +-| _ADR | Name(_ADR, 0x00020000): the PCI bus address
| | +------+
| |
| | +------+
| +-| DD01 | Device(DD01): the LCD output device
| +------+
| |
| | +------+
| +-| _BCL | Method(_BCL): the backlight control method
| +------+
|
| +------+
+-| _TZ | Scope(_TZ): the thermal zone namespace
| +------+
| |
| | +------+
| +-| FN00 | PowerResource(FN00): the FAN0 power resource
| | +------+
| |
| | +------+
| +-| FAN0 | Device(FAN0): the FAN0 cooling device
| | +------+
| | |
| | | +------+
| | +-| _HID | Name(_HID, "PNP0A0B"): the hardware ID
| | +------+
| |
| | +------+
| +-| TZ00 | ThermalZone(TZ00); the FAN thermal zone
| +------+
|
| +------+
+-| _GPE | Scope(_GPE): the GPE namespace
+------+
Figure 2. Example ACPI Namespace
Linux ACPI Device Objects
=========================
The Linux kernel's core ACPI subsystem creates struct acpi_device
objects for ACPI namespace objects representing devices, power resources
processors, thermal zones. Those objects are exported to user space via
sysfs as directories in the subtree under /sys/devices/LNXSYSTM:00. The
format of their names is <bus_id:instance>, where 'bus_id' refers to the
ACPI namespace representation of the given object and 'instance' is used
for distinguishing different object of the same 'bus_id' (it is
two-digit decimal representation of an unsigned integer).
The value of 'bus_id' depends on the type of the object whose name it is
part of as listed in the table below::
+---+-----------------+-------+----------+
| | Object/Feature | Table | bus_id |
+---+-----------------+-------+----------+
| N | Root | xSDT | LNXSYSTM |
+---+-----------------+-------+----------+
| N | Device | xSDT | _HID |
+---+-----------------+-------+----------+
| N | Processor | xSDT | LNXCPU |
+---+-----------------+-------+----------+
| N | ThermalZone | xSDT | LNXTHERM |
+---+-----------------+-------+----------+
| N | PowerResource | xSDT | LNXPOWER |
+---+-----------------+-------+----------+
| N | Other Devices | xSDT | device |
+---+-----------------+-------+----------+
| F | PWR_BUTTON | FADT | LNXPWRBN |
+---+-----------------+-------+----------+
| F | SLP_BUTTON | FADT | LNXSLPBN |
+---+-----------------+-------+----------+
| M | Video Extension | xSDT | LNXVIDEO |
+---+-----------------+-------+----------+
| M | ATA Controller | xSDT | LNXIOBAY |
+---+-----------------+-------+----------+
| M | Docking Station | xSDT | LNXDOCK |
+---+-----------------+-------+----------+
Table 1. ACPI Namespace Objects Mapping
The following rules apply when creating struct acpi_device objects on
the basis of the contents of ACPI System Description Tables (as
indicated by the letter in the first column and the notation in the
second column of the table above):
N:
The object's source is an ACPI namespace node (as indicated by the
named object's type in the second column). In that case the object's
directory in sysfs will contain the 'path' attribute whose value is
the full path to the node from the namespace root.
F:
The struct acpi_device object is created for a fixed hardware
feature (as indicated by the fixed feature flag's name in the second
column), so its sysfs directory will not contain the 'path'
attribute.
M:
The struct acpi_device object is created for an ACPI namespace node
with specific control methods (as indicated by the ACPI defined
device's type in the second column). The 'path' attribute containing
its namespace path will be present in its sysfs directory. For
example, if the _BCL method is present for an ACPI namespace node, a
struct acpi_device object with LNXVIDEO 'bus_id' will be created for
it.
The third column of the above table indicates which ACPI System
Description Tables contain information used for the creation of the
struct acpi_device objects represented by the given row (xSDT means DSDT
or SSDT).
The fourth column of the above table indicates the 'bus_id' generation
rule of the struct acpi_device object:
_HID:
_HID in the last column of the table means that the object's bus_id
is derived from the _HID/_CID identification objects present under
the corresponding ACPI namespace node. The object's sysfs directory
will then contain the 'hid' and 'modalias' attributes that can be
used to retrieve the _HID and _CIDs of that object.
LNXxxxxx:
The 'modalias' attribute is also present for struct acpi_device
objects having bus_id of the "LNXxxxxx" form (pseudo devices), in
which cases it contains the bus_id string itself.
device:
'device' in the last column of the table indicates that the object's
bus_id cannot be determined from _HID/_CID of the corresponding
ACPI namespace node, although that object represents a device (for
example, it may be a PCI device with _ADR defined and without _HID
or _CID). In that case the string 'device' will be used as the
object's bus_id.
Linux ACPI Physical Device Glue
===============================
ACPI device (i.e. struct acpi_device) objects may be linked to other
objects in the Linux' device hierarchy that represent "physical" devices
(for example, devices on the PCI bus). If that happens, it means that
the ACPI device object is a "companion" of a device otherwise
represented in a different way and is used (1) to provide configuration
information on that device which cannot be obtained by other means and
(2) to do specific things to the device with the help of its ACPI
control methods. One ACPI device object may be linked this way to
multiple "physical" devices.
If an ACPI device object is linked to a "physical" device, its sysfs
directory contains the "physical_node" symbolic link to the sysfs
directory of the target device object. In turn, the target device's
sysfs directory will then contain the "firmware_node" symbolic link to
the sysfs directory of the companion ACPI device object.
The linking mechanism relies on device identification provided by the
ACPI namespace. For example, if there's an ACPI namespace object
representing a PCI device (i.e. a device object under an ACPI namespace
object representing a PCI bridge) whose _ADR returns 0x00020000 and the
bus number of the parent PCI bridge is 0, the sysfs directory
representing the struct acpi_device object created for that ACPI
namespace object will contain the 'physical_node' symbolic link to the
/sys/devices/pci0000:00/0000:00:02:0/ sysfs directory of the
corresponding PCI device.
The linking mechanism is generally bus-specific. The core of its
implementation is located in the drivers/acpi/glue.c file, but there are
complementary parts depending on the bus types in question located
elsewhere. For example, the PCI-specific part of it is located in
drivers/pci/pci-acpi.c.
Example Linux ACPI Device Tree
=================================
The sysfs hierarchy of struct acpi_device objects corresponding to the
example ACPI namespace illustrated in Figure 2 with the addition of
fixed PWR_BUTTON/SLP_BUTTON devices is shown below::
+--------------+---+-----------------+
| LNXSYSTM:00 | \ | acpi:LNXSYSTM: |
+--------------+---+-----------------+
|
| +-------------+-----+----------------+
+-| LNXPWRBN:00 | N/A | acpi:LNXPWRBN: |
| +-------------+-----+----------------+
|
| +-------------+-----+----------------+
+-| LNXSLPBN:00 | N/A | acpi:LNXSLPBN: |
| +-------------+-----+----------------+
|
| +-----------+------------+--------------+
+-| LNXCPU:00 | \_PR_.CPU0 | acpi:LNXCPU: |
| +-----------+------------+--------------+
|
| +-------------+-------+----------------+
+-| LNXSYBUS:00 | \_SB_ | acpi:LNXSYBUS: |
| +-------------+-------+----------------+
| |
| | +- - - - - - - +- - - - - - +- - - - - - - -+
| +-| PNP0C0D:00 | \_SB_.LID0 | acpi:PNP0C0D: |
| | +- - - - - - - +- - - - - - +- - - - - - - -+
| |
| | +------------+------------+-----------------------+
| +-| PNP0A08:00 | \_SB_.PCI0 | acpi:PNP0A08:PNP0A03: |
| +------------+------------+-----------------------+
| |
| | +-----------+-----------------+-----+
| +-| device:00 | \_SB_.PCI0.RP03 | N/A |
| | +-----------+-----------------+-----+
| | |
| | | +-------------+----------------------+----------------+
| | +-| LNXPOWER:00 | \_SB_.PCI0.RP03.PXP3 | acpi:LNXPOWER: |
| | +-------------+----------------------+----------------+
| |
| | +-------------+-----------------+----------------+
| +-| LNXVIDEO:00 | \_SB_.PCI0.GFX0 | acpi:LNXVIDEO: |
| +-------------+-----------------+----------------+
| |
| | +-----------+-----------------+-----+
| +-| device:01 | \_SB_.PCI0.DD01 | N/A |
| +-----------+-----------------+-----+
|
| +-------------+-------+----------------+
+-| LNXSYBUS:01 | \_TZ_ | acpi:LNXSYBUS: |
+-------------+-------+----------------+
|
| +-------------+------------+----------------+
+-| LNXPOWER:0a | \_TZ_.FN00 | acpi:LNXPOWER: |
| +-------------+------------+----------------+
|
| +------------+------------+---------------+
+-| PNP0C0B:00 | \_TZ_.FAN0 | acpi:PNP0C0B: |
| +------------+------------+---------------+
|
| +-------------+------------+----------------+
+-| LNXTHERM:00 | \_TZ_.TZ00 | acpi:LNXTHERM: |
+-------------+------------+----------------+
Figure 3. Example Linux ACPI Device Tree
.. note:: Each node is represented as "object/path/modalias", where:
1. 'object' is the name of the object's directory in sysfs.
2. 'path' is the ACPI namespace path of the corresponding
ACPI namespace object, as returned by the object's 'path'
sysfs attribute.
3. 'modalias' is the value of the object's 'modalias' sysfs
attribute (as described earlier in this document).
.. note:: N/A indicates the device object does not have the 'path' or the
'modalias' attribute.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
ACPI definition block에서 namespace까지
1-79Linux ACPI subsystem은 ACPI namespace object를 `/sys/devices/LNXSYSTM:00` 아래의 Linux device tree로 변환하고, ACPI hotplug notification event를 받으면 이 tree를 갱신한다. 이 hierarchy의 각 device object에는 `/sys/bus/acpi/devices` 아래에 대응하는 symbolic link가 있다.
ACPI firmware는 system memory address space에 RSDP(Root System Description Pointer)를 두고 XSDT(Extended System Description Table)를 가리키게 한다. XSDT의 첫 entry는 항상 FADT(Fixed ACPI Description Table)를 가리키며, FADT에는 hardware의 fixed ACPI feature를 설명하는 여러 fixed-length entry와 DSDT를 가리키는 pointer가 들어 있다.
XSDT에는 여러 SSDT를 가리키는 entry도 있을 수 있다. DSDT와 SSDT의 data는 AML(ACPI Machine Language)로 encoding된 control method를 비롯한 object definition을 담는 definition block으로 구성된다.
DSDT data block과 모든 SSDT content를 함께 load하면 underlying hardware platform 구조를 반영하는 단일 hierarchical ACPI namespace가 만들어진다. OSPM은 이 table 관계를 따라 definition block을 load한다.
RSDP는 ACPI 1.0 operating system과의 호환성을 위한 RSDT pointer도 포함할 수 있다. 다만 XSDT가 존재하면 operating system은 XSDT를 사용해야 한다.
Namespace object가 kernel device tree와 bus link로 노출되는 위치를 구분한다.
Figure 1의 pointer와 definition block 관계를 표로 다시 그렸다.
Firmware pointer 탐색에서 ACPI namespace 구성까지의 순서이다.
.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>
===================================================
ACPI Device Tree - Representation of ACPI Namespace
===================================================
:Copyright: |copy| 2013, Intel Corporation
:Author: Lv Zheng <[email protected]>
:Credit: Thanks for the help from Zhang Rui <[email protected]> and
Rafael J.Wysocki <[email protected]>.
Abstract
========
The Linux ACPI subsystem converts ACPI namespace objects into a Linux
device tree under the /sys/devices/LNXSYSTM:00 and updates it upon
receiving ACPI hotplug notification events. For each device object
in this hierarchy there is a corresponding symbolic link in the
/sys/bus/acpi/devices.
This document illustrates the structure of the ACPI device tree.
ACPI Definition Blocks
======================
The ACPI firmware sets up RSDP (Root System Description Pointer) in the
system memory address space pointing to the XSDT (Extended System
Description Table). The XSDT always points to the FADT (Fixed ACPI
Description Table) using its first entry, the data within the FADT
includes various fixed-length entries that describe fixed ACPI features
of the hardware. The FADT contains a pointer to the DSDT
(Differentiated System Description Table). The XSDT also contains
entries pointing to possibly multiple SSDTs (Secondary System
Description Table).
The DSDT and SSDT data is organized in data structures called definition
blocks that contain definitions of various objects, including ACPI
control methods, encoded in AML (ACPI Machine Language). The data block
of the DSDT along with the contents of SSDTs represents a hierarchical
data structure called the ACPI namespace whose topology reflects the
structure of the underlying hardware platform.
The relationships between ACPI System Definition Tables described above
are illustrated in the following diagram::
+---------+ +-------+ +--------+ +------------------------+
| RSDP | +->| XSDT | +->| FADT | | +-------------------+ |
+---------+ | +-------+ | +--------+ +-|->| DSDT | |
| Pointer | | | Entry |-+ | ...... | | | +-------------------+ |
+---------+ | +-------+ | X_DSDT |--+ | | Definition Blocks | |
| Pointer |-+ | ..... | | ...... | | +-------------------+ |
+---------+ +-------+ +--------+ | +-------------------+ |
| Entry |------------------|->| SSDT | |
+- - - -+ | +-------------------| |
| Entry | - - - - - - - -+ | | Definition Blocks | |
+- - - -+ | | +-------------------+ |
| | +- - - - - - - - - -+ |
+-|->| SSDT | |
| +-------------------+ |
| | Definition Blocks | |
| +- - - - - - - - - -+ |
+------------------------+
|
OSPM Loading |
\|/
+----------------+
| ACPI Namespace |
+----------------+
Figure 1. ACPI Definition Blocks
.. note:: RSDP can also contain a pointer to the RSDT (Root System
Description Table). Platforms provide RSDT to enable
compatibility with ACPI 1.0 operating systems. The OS is expected
to use XSDT, if present.
ACPI namespace 이름 규칙과 예제 hierarchy
80-191모든 definition block은 하나의 namespace로 load된다. Namespace는 name과 path로 식별되는 object의 hierarchy이다.
모든 object name은 32 bit 길이이다. 첫 byte는 `A`부터 `Z` 또는 `_`여야 하고, 나머지 byte는 `A`부터 `Z`, `0`부터 `9`, `_` 중 하나여야 한다. `_`로 시작하는 name은 ACPI specification이 예약한다.
`\` symbol은 namespace root를 나타내므로 `\`가 앞에 붙은 name은 root 기준이다. `^` symbol은 현재 namespace node의 parent를 나타내므로 `^`가 앞에 붙은 name은 parent 기준이다.
Figure 2의 예는 root 아래에 processor scope `_PR`, system bus scope `_SB`, thermal zone scope `_TZ`, GPE scope `_GPE`를 둔다. `_PR`에는 `CPU0`가 있고, `_SB`에는 lid `LID0`와 PCI root bridge `PCI0`가 있다.
`LID0`에는 hardware ID `PNP0C0D`를 담은 `_HID`와 status control method `_STA`가 있다. `PCI0`에는 `_HID=PNP0A08`, `_CID=PNP0A03`, power scope `RP03`, graphics adapter `GFX0`가 있다. `RP03`에는 power resource `PXP3`, `GFX0`에는 bus address `0x00020000`인 `_ADR`, LCD output `DD01`, 그 아래 backlight method `_BCL`이 이어진다.
`_TZ`에는 FAN0 power resource `FN00`, cooling device `FAN0`, thermal zone `TZ00`이 있다. 원문 Figure 2는 FAN0의 `_HID`를 `PNP0A0B`로 표시하지만 뒤의 Figure 3은 대응 sysfs object를 `PNP0C0B:00`으로 표시한다. 두 figure의 값을 임의로 합치지 않고 각각 그대로 보존한다.
32-bit name의 byte 제약과 path symbol을 정리한다.
ASCII tree의 모든 node를 parent, object와 의미가 보이는 구조로 다시 그렸다.
Example ACPI Namespace
======================
All definition blocks are loaded into a single namespace. The namespace
is a hierarchy of objects identified by names and paths.
The following naming conventions apply to object names in the ACPI
namespace:
1. All names are 32 bits long.
2. The first byte of a name must be one of 'A' - 'Z', '_'.
3. Each of the remaining bytes of a name must be one of 'A' - 'Z', '0'
- '9', '_'.
4. Names starting with '_' are reserved by the ACPI specification.
5. The '\' symbol represents the root of the namespace (i.e. names
prepended with '\' are relative to the namespace root).
6. The '^' symbol represents the parent of the current namespace node
(i.e. names prepended with '^' are relative to the parent of the
current namespace node).
The figure below shows an example ACPI namespace::
+------+
| \ | Root
+------+
|
| +------+
+-| _PR | Scope(_PR): the processor namespace
| +------+
| |
| | +------+
| +-| CPU0 | Processor(CPU0): the first processor
| +------+
|
| +------+
+-| _SB | Scope(_SB): the system bus namespace
| +------+
| |
| | +------+
| +-| LID0 | Device(LID0); the lid device
| | +------+
| | |
| | | +------+
| | +-| _HID | Name(_HID, "PNP0C0D"): the hardware ID
| | | +------+
| | |
| | | +------+
| | +-| _STA | Method(_STA): the status control method
| | +------+
| |
| | +------+
| +-| PCI0 | Device(PCI0); the PCI root bridge
| +------+
| |
| | +------+
| +-| _HID | Name(_HID, "PNP0A08"): the hardware ID
| | +------+
| |
| | +------+
| +-| _CID | Name(_CID, "PNP0A03"): the compatible ID
| | +------+
| |
| | +------+
| +-| RP03 | Scope(RP03): the PCI0 power scope
| | +------+
| | |
| | | +------+
| | +-| PXP3 | PowerResource(PXP3): the PCI0 power resource
| | +------+
| |
| | +------+
| +-| GFX0 | Device(GFX0): the graphics adapter
| +------+
| |
| | +------+
| +-| _ADR | Name(_ADR, 0x00020000): the PCI bus address
| | +------+
| |
| | +------+
| +-| DD01 | Device(DD01): the LCD output device
| +------+
| |
| | +------+
| +-| _BCL | Method(_BCL): the backlight control method
| +------+
|
| +------+
+-| _TZ | Scope(_TZ): the thermal zone namespace
| +------+
| |
| | +------+
| +-| FN00 | PowerResource(FN00): the FAN0 power resource
| | +------+
| |
| | +------+
| +-| FAN0 | Device(FAN0): the FAN0 cooling device
| | +------+
| | |
| | | +------+
| | +-| _HID | Name(_HID, "PNP0A0B"): the hardware ID
| | +------+
| |
| | +------+
| +-| TZ00 | ThermalZone(TZ00); the FAN thermal zone
| +------+
|
| +------+
+-| _GPE | Scope(_GPE): the GPE namespace
+------+
Figure 2. Example ACPI Namespace
Linux ACPI device object와 bus_id mapping
192-234Linux kernel의 core ACPI subsystem은 device, power resource, processor, thermal zone을 나타내는 ACPI namespace object마다 `struct acpi_device` object를 만든다. 이 object는 `/sys/devices/LNXSYSTM:00` subtree의 directory로 user space에 export된다.
Directory name 형식은 `<bus_id:instance>`이다. `bus_id`는 해당 object의 ACPI namespace 표현을 가리키고, `instance`는 같은 `bus_id`를 가진 여러 object를 구분하는 unsigned integer의 두 자리 decimal 표현이다.
Table 1은 source 유형을 `N`, `F`, `M`으로 표시한다. `N`은 namespace node, `F`는 FADT fixed hardware feature, `M`은 특정 control method로 식별되는 namespace node이다. Table 열의 `xSDT`는 DSDT 또는 SSDT를 뜻한다.
Namespace object type을 mapping한 뒤 instance를 붙여 directory name을 만든다.
원문의 11개 mapping row를 순서와 값을 유지해 구조화했다.
Linux ACPI Device Objects
=========================
The Linux kernel's core ACPI subsystem creates struct acpi_device
objects for ACPI namespace objects representing devices, power resources
processors, thermal zones. Those objects are exported to user space via
sysfs as directories in the subtree under /sys/devices/LNXSYSTM:00. The
format of their names is <bus_id:instance>, where 'bus_id' refers to the
ACPI namespace representation of the given object and 'instance' is used
for distinguishing different object of the same 'bus_id' (it is
two-digit decimal representation of an unsigned integer).
The value of 'bus_id' depends on the type of the object whose name it is
part of as listed in the table below::
+---+-----------------+-------+----------+
| | Object/Feature | Table | bus_id |
+---+-----------------+-------+----------+
| N | Root | xSDT | LNXSYSTM |
+---+-----------------+-------+----------+
| N | Device | xSDT | _HID |
+---+-----------------+-------+----------+
| N | Processor | xSDT | LNXCPU |
+---+-----------------+-------+----------+
| N | ThermalZone | xSDT | LNXTHERM |
+---+-----------------+-------+----------+
| N | PowerResource | xSDT | LNXPOWER |
+---+-----------------+-------+----------+
| N | Other Devices | xSDT | device |
+---+-----------------+-------+----------+
| F | PWR_BUTTON | FADT | LNXPWRBN |
+---+-----------------+-------+----------+
| F | SLP_BUTTON | FADT | LNXSLPBN |
+---+-----------------+-------+----------+
| M | Video Extension | xSDT | LNXVIDEO |
+---+-----------------+-------+----------+
| M | ATA Controller | xSDT | LNXIOBAY |
+---+-----------------+-------+----------+
| M | Docking Station | xSDT | LNXDOCK |
+---+-----------------+-------+----------+
Table 1. ACPI Namespace Objects Mapping
acpi_device 생성과 bus_id 규칙
235-285`N` object의 source는 표 둘째 열의 named object type으로 나타낸 ACPI namespace node이다. 이 경우 sysfs directory에는 namespace root에서 해당 node까지의 전체 경로를 값으로 갖는 `path` attribute가 있다.
`F` object는 둘째 열의 fixed feature flag가 나타내는 fixed hardware feature를 위해 생성된다. Namespace node에서 온 object가 아니므로 sysfs directory에 `path` attribute가 없다.
`M` object는 특정 control method를 가진 ACPI namespace node를 위해 생성되며 sysfs directory에 namespace `path`가 있다. 예를 들어 node에 `_BCL` method가 있으면 `LNXVIDEO` bus_id의 `struct acpi_device`가 생성된다.
표의 셋째 열은 object 생성 정보가 들어 있는 ACPI System Description Table을 나타낸다. `xSDT`는 DSDT 또는 SSDT를 의미한다.
넷째 열이 `_HID`이면 bus_id는 node 아래의 `_HID/_CID` identification object에서 만들어진다. 이 sysfs directory에는 `_HID`와 모든 `_CID`를 조회할 수 있는 `hid`와 `modalias` attribute가 생긴다.
Bus ID가 `LNXxxxxx` 형태인 pseudo device에도 `modalias`가 있으며, 값은 bus_id string 자체이다. 반면 `_HID/_CID`에서 bus_id를 정할 수 없는 device, 예를 들어 `_ADR`은 있지만 `_HID`와 `_CID`가 없는 PCI device에는 literal `device`가 bus_id로 사용된다.
Source 종류에 따른 namespace path와 생성 조건을 비교한다.
Table 1의 마지막 열이 sysfs identification attribute를 만드는 방식을 정리한다.
The following rules apply when creating struct acpi_device objects on
the basis of the contents of ACPI System Description Tables (as
indicated by the letter in the first column and the notation in the
second column of the table above):
N:
The object's source is an ACPI namespace node (as indicated by the
named object's type in the second column). In that case the object's
directory in sysfs will contain the 'path' attribute whose value is
the full path to the node from the namespace root.
F:
The struct acpi_device object is created for a fixed hardware
feature (as indicated by the fixed feature flag's name in the second
column), so its sysfs directory will not contain the 'path'
attribute.
M:
The struct acpi_device object is created for an ACPI namespace node
with specific control methods (as indicated by the ACPI defined
device's type in the second column). The 'path' attribute containing
its namespace path will be present in its sysfs directory. For
example, if the _BCL method is present for an ACPI namespace node, a
struct acpi_device object with LNXVIDEO 'bus_id' will be created for
it.
The third column of the above table indicates which ACPI System
Description Tables contain information used for the creation of the
struct acpi_device objects represented by the given row (xSDT means DSDT
or SSDT).
The fourth column of the above table indicates the 'bus_id' generation
rule of the struct acpi_device object:
_HID:
_HID in the last column of the table means that the object's bus_id
is derived from the _HID/_CID identification objects present under
the corresponding ACPI namespace node. The object's sysfs directory
will then contain the 'hid' and 'modalias' attributes that can be
used to retrieve the _HID and _CIDs of that object.
LNXxxxxx:
The 'modalias' attribute is also present for struct acpi_device
objects having bus_id of the "LNXxxxxx" form (pseudo devices), in
which cases it contains the bus_id string itself.
device:
'device' in the last column of the table indicates that the object's
bus_id cannot be determined from _HID/_CID of the corresponding
ACPI namespace node, although that object represents a device (for
example, it may be a PCI device with _ADR defined and without _HID
or _CID). In that case the string 'device' will be used as the
object's bus_id.
ACPI companion과 physical-device glue
286-320`struct acpi_device` object는 PCI bus device처럼 Linux device hierarchy에서 physical device를 나타내는 다른 object와 연결될 수 있다. 이때 ACPI object는 다른 방식으로도 표현되는 device의 `companion`이다.
Companion은 다른 수단으로 얻을 수 없는 configuration information을 physical device에 제공하고, ACPI control method를 이용해 그 device에 특정 operation을 수행하는 데 쓰인다. 하나의 ACPI device object가 여러 physical device와 연결될 수도 있다.
ACPI device의 sysfs directory에는 target physical device의 sysfs directory를 가리키는 `physical_node` symbolic link가 생긴다. 반대로 target directory에는 companion ACPI device directory를 가리키는 `firmware_node` symbolic link가 생긴다.
연결은 ACPI namespace identification을 사용한다. 예를 들어 parent PCI bridge bus number가 0이고 child namespace object의 `_ADR`이 `0x00020000`이면, 해당 `struct acpi_device` directory의 `physical_node`는 `/sys/devices/pci0000:00/0000:00:02:0/`을 가리킨다.
Glue mechanism은 일반적으로 bus-specific이다. Core 구현은 `drivers/acpi/glue.c`에 있고, PCI-specific 부분은 `drivers/pci/pci-acpi.c`에 있다. 다른 bus type은 각자 별도 보완 구현을 둘 수 있다.
Firmware 표현과 physical-device 표현이 reciprocal symbolic link로 연결된다.
PCI 예와 구현 source path를 보존해 정리한다.
Linux ACPI Physical Device Glue
===============================
ACPI device (i.e. struct acpi_device) objects may be linked to other
objects in the Linux' device hierarchy that represent "physical" devices
(for example, devices on the PCI bus). If that happens, it means that
the ACPI device object is a "companion" of a device otherwise
represented in a different way and is used (1) to provide configuration
information on that device which cannot be obtained by other means and
(2) to do specific things to the device with the help of its ACPI
control methods. One ACPI device object may be linked this way to
multiple "physical" devices.
If an ACPI device object is linked to a "physical" device, its sysfs
directory contains the "physical_node" symbolic link to the sysfs
directory of the target device object. In turn, the target device's
sysfs directory will then contain the "firmware_node" symbolic link to
the sysfs directory of the companion ACPI device object.
The linking mechanism relies on device identification provided by the
ACPI namespace. For example, if there's an ACPI namespace object
representing a PCI device (i.e. a device object under an ACPI namespace
object representing a PCI bridge) whose _ADR returns 0x00020000 and the
bus number of the parent PCI bridge is 0, the sysfs directory
representing the struct acpi_device object created for that ACPI
namespace object will contain the 'physical_node' symbolic link to the
/sys/devices/pci0000:00/0000:00:02:0/ sysfs directory of the
corresponding PCI device.
The linking mechanism is generally bus-specific. The core of its
implementation is located in the drivers/acpi/glue.c file, but there are
complementary parts depending on the bus types in question located
elsewhere. For example, the PCI-specific part of it is located in
drivers/pci/pci-acpi.c.
Linux ACPI sysfs device tree 예
321-400Figure 3은 Figure 2의 ACPI namespace에 fixed `PWR_BUTTON`과 `SLP_BUTTON` device를 추가해 만든 `struct acpi_device` sysfs hierarchy이다. 각 node는 `object/path/modalias` 순서로 표시된다.
`object`는 sysfs directory name이고, `path`는 object의 `path` sysfs attribute가 반환하는 ACPI namespace path이며, `modalias`는 앞서 설명한 `modalias` sysfs attribute 값이다. `N/A`는 해당 device object에 `path` 또는 `modalias` attribute가 없음을 뜻한다.
Root는 `LNXSYSTM:00`이다. Fixed button은 namespace path가 없어 `LNXPWRBN:00`과 `LNXSLPBN:00`의 path가 `N/A`이다. Processor와 system bus, thermal scope는 각각 `LNXCPU`, `LNXSYBUS`, `LNXTHERM` 계열 bus_id로 mapping된다.
PCI0의 `_HID=PNP0A08`과 `_CID=PNP0A03`은 modalias `acpi:PNP0A08:PNP0A03:`에 함께 나타난다. `_HID/_CID`가 없는 `RP03`과 `DD01`은 `device:00`, `device:01` fallback bus_id를 사용하며 modalias가 `N/A`이다.
Figure 3의 FAN sysfs object는 `PNP0C0B:00`이고 modalias는 `acpi:PNP0C0B:`이다. 이는 Figure 2에 적힌 `PNP0A0B`와 다르므로 원문 figure별 값을 그대로 유지했다.
ASCII hierarchy의 15개 node를 parent, object, path, modalias로 다시 그렸다.
각 열과 N/A가 뜻하는 바를 분리해 설명한다.
Example Linux ACPI Device Tree
=================================
The sysfs hierarchy of struct acpi_device objects corresponding to the
example ACPI namespace illustrated in Figure 2 with the addition of
fixed PWR_BUTTON/SLP_BUTTON devices is shown below::
+--------------+---+-----------------+
| LNXSYSTM:00 | \ | acpi:LNXSYSTM: |
+--------------+---+-----------------+
|
| +-------------+-----+----------------+
+-| LNXPWRBN:00 | N/A | acpi:LNXPWRBN: |
| +-------------+-----+----------------+
|
| +-------------+-----+----------------+
+-| LNXSLPBN:00 | N/A | acpi:LNXSLPBN: |
| +-------------+-----+----------------+
|
| +-----------+------------+--------------+
+-| LNXCPU:00 | \_PR_.CPU0 | acpi:LNXCPU: |
| +-----------+------------+--------------+
|
| +-------------+-------+----------------+
+-| LNXSYBUS:00 | \_SB_ | acpi:LNXSYBUS: |
| +-------------+-------+----------------+
| |
| | +- - - - - - - +- - - - - - +- - - - - - - -+
| +-| PNP0C0D:00 | \_SB_.LID0 | acpi:PNP0C0D: |
| | +- - - - - - - +- - - - - - +- - - - - - - -+
| |
| | +------------+------------+-----------------------+
| +-| PNP0A08:00 | \_SB_.PCI0 | acpi:PNP0A08:PNP0A03: |
| +------------+------------+-----------------------+
| |
| | +-----------+-----------------+-----+
| +-| device:00 | \_SB_.PCI0.RP03 | N/A |
| | +-----------+-----------------+-----+
| | |
| | | +-------------+----------------------+----------------+
| | +-| LNXPOWER:00 | \_SB_.PCI0.RP03.PXP3 | acpi:LNXPOWER: |
| | +-------------+----------------------+----------------+
| |
| | +-------------+-----------------+----------------+
| +-| LNXVIDEO:00 | \_SB_.PCI0.GFX0 | acpi:LNXVIDEO: |
| +-------------+-----------------+----------------+
| |
| | +-----------+-----------------+-----+
| +-| device:01 | \_SB_.PCI0.DD01 | N/A |
| +-----------+-----------------+-----+
|
| +-------------+-------+----------------+
+-| LNXSYBUS:01 | \_TZ_ | acpi:LNXSYBUS: |
+-------------+-------+----------------+
|
| +-------------+------------+----------------+
+-| LNXPOWER:0a | \_TZ_.FN00 | acpi:LNXPOWER: |
| +-------------+------------+----------------+
|
| +------------+------------+---------------+
+-| PNP0C0B:00 | \_TZ_.FAN0 | acpi:PNP0C0B: |
| +------------+------------+---------------+
|
| +-------------+------------+----------------+
+-| LNXTHERM:00 | \_TZ_.TZ00 | acpi:LNXTHERM: |
+-------------+------------+----------------+
Figure 3. Example Linux ACPI Device Tree
.. note:: Each node is represented as "object/path/modalias", where:
1. 'object' is the name of the object's directory in sysfs.
2. 'path' is the ACPI namespace path of the corresponding
ACPI namespace object, as returned by the object's 'path'
sysfs attribute.
3. 'modalias' is the value of the object's 'modalias' sysfs
attribute (as described earlier in this document).
.. note:: N/A indicates the device object does not have the 'path' or the
'modalias' attribute.
요약·해설
namespace.rst:1-400ACPI firmware의 RSDP·XSDT·FADT·DSDT·SSDT pointer 관계를 따라 definition block을 load하면 hardware topology를 반영하는 단일 ACPI namespace가 만들어진다. Linux는 device 성격의 namespace object를 `struct acpi_device`로 변환해 `/sys/devices/LNXSYSTM:00` 아래에 export한다.
Sysfs directory는 `<bus_id:instance>` 형식이다. Namespace node, fixed feature, 특정 method 기반 object에 따라 `N`, `F`, `M` 규칙을 적용하고 `_HID`, `LNXxxxxx`, `device` 중 알맞은 bus_id 생성 방식을 사용한다.
ACPI device가 physical device의 companion이면 `physical_node`와 `firmware_node`가 양쪽 sysfs directory를 연결한다. Core glue는 `drivers/acpi/glue.c`, PCI 보완 구현은 `drivers/pci/pci-acpi.c`에 있다.
원문 Figure 2의 FAN ID `PNP0A0B`와 Figure 3의 `PNP0C0B:00`은 불일치한다. 번역 페이지는 source fidelity를 위해 양쪽 값을 그대로 보존하고 figure별 차이를 명시한다.
Firmware table이 sysfs object와 physical device companion으로 변환되는 전체 흐름이다.