요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GPL-2.0
============================================
Accessing PCI device resources through sysfs
============================================
sysfs, usually mounted at /sys, provides access to PCI resources on platforms
that support it. For example, a given bus might look like this::
/sys/devices/pci0000:17
|-- 0000:17:00.0
| |-- class
| |-- config
| |-- device
| |-- enable
| |-- irq
| |-- local_cpus
| |-- remove
| |-- resource
| |-- resource0
| |-- resource1
| |-- resource2
| |-- revision
| |-- rom
| |-- subsystem_device
| |-- subsystem_vendor
| `-- vendor
`-- ...
The topmost element describes the PCI domain and bus number. In this case,
the domain number is 0000 and the bus number is 17 (both values are in hex).
This bus contains a single function device in slot 0. The domain and bus
numbers are reproduced for convenience. Under the device directory are several
files, each with their own function.
=================== =====================================================
file function
=================== =====================================================
class PCI class (ascii, ro)
config PCI config space (binary, rw)
device PCI device (ascii, ro)
enable Whether the device is enabled (ascii, rw)
irq IRQ number (ascii, ro)
local_cpus nearby CPU mask (cpumask, ro)
remove remove device from kernel's list (ascii, wo)
resource PCI resource host addresses (ascii, ro)
resource0..N PCI resource N, if present (binary, mmap, rw\ [1]_)
resource0_wc..N_wc PCI WC map resource N, if prefetchable (binary, mmap)
revision PCI revision (ascii, ro)
rom PCI ROM resource, if present (binary, ro)
subsystem_device PCI subsystem device (ascii, ro)
subsystem_vendor PCI subsystem vendor (ascii, ro)
vendor PCI vendor (ascii, ro)
=================== =====================================================
::
ro - read only file
rw - file is readable and writable
wo - write only file
mmap - file is mmapable
ascii - file contains ascii text
binary - file contains binary data
cpumask - file contains a cpumask type
.. [1] rw for IORESOURCE_IO (I/O port) regions only
The read only files are informational, writes to them will be ignored, with
the exception of the 'rom' file. Writable files can be used to perform
actions on the device (e.g. changing config space, detaching a device).
mmapable files are available via an mmap of the file at offset 0 and can be
used to do actual device programming from userspace. Note that some platforms
don't support mmapping of certain resources, so be sure to check the return
value from any attempted mmap. The most notable of these are I/O port
resources, which also provide read/write access.
The 'enable' file provides a counter that indicates how many times the device
has been enabled. If the 'enable' file currently returns '4', and a '1' is
echoed into it, it will then return '5'. Echoing a '0' into it will decrease
the count. Even when it returns to 0, though, some of the initialisation
may not be reversed.
The 'rom' file is special in that it provides read-only access to the device's
ROM file, if available. It's disabled by default, however, so applications
should write the string "1" to the file to enable it before attempting a read
call, and disable it following the access by writing "0" to the file. Note
that the device must be enabled for a rom read to return data successfully.
In the event a driver is not bound to the device, it can be enabled using the
'enable' file, documented above.
The 'remove' file is used to remove the PCI device, by writing a non-zero
integer to the file. This does not involve any kind of hot-plug functionality,
e.g. powering off the device. The device is removed from the kernel's list of
PCI devices, the sysfs directory for it is removed, and the device will be
removed from any drivers attached to it. Removal of PCI root buses is
disallowed.
Accessing legacy resources through sysfs
----------------------------------------
Legacy I/O port and ISA memory resources are also provided in sysfs if the
underlying platform supports them. They're located in the PCI class hierarchy,
e.g.::
/sys/class/pci_bus/0000:17/
|-- bridge -> ../../../devices/pci0000:17
|-- cpuaffinity
|-- legacy_io
`-- legacy_mem
The legacy_io file is a read/write file that can be used by applications to
do legacy port I/O. The application should open the file, seek to the desired
port (e.g. 0x3e8) and do a read or a write of 1, 2 or 4 bytes. The legacy_mem
file should be mmapped with an offset corresponding to the memory offset
desired, e.g. 0xa0000 for the VGA frame buffer. The application can then
simply dereference the returned pointer (after checking for errors of course)
to access legacy memory space.
Supporting PCI access on new platforms
--------------------------------------
In order to support PCI resource mapping as described above, Linux platform
code should ideally define ARCH_GENERIC_PCI_MMAP_RESOURCE and use the generic
implementation of that functionality. To support the historical interface of
mmap() through files in /proc/bus/pci, platforms may also set HAVE_PCI_MMAP.
Alternatively, platforms which set HAVE_PCI_MMAP may provide their own
implementation of pci_mmap_resource_range() instead of defining
ARCH_GENERIC_PCI_MMAP_RESOURCE.
Platforms which support write-combining maps of PCI resources must define
arch_can_pci_mmap_wc() which shall evaluate to non-zero at runtime when
write-combining is permitted. Platforms which support maps of I/O resources
define arch_can_pci_mmap_io() similarly.
Legacy resources are protected by the HAVE_PCI_LEGACY define. Platforms
wishing to support legacy functionality should define it and provide
pci_legacy_read, pci_legacy_write and pci_mmap_legacy_page_range functions.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
PCI sysfs 계층과 BDF
1-35보통 `/sys`에 mount되는 sysfs는 이를 지원하는 platform에서 PCI resource에 접근할 수 있게 합니다.
예제의 최상위 `/sys/devices/pci0000:17`은 PCI domain `0000`과 bus `17`을 나타내며 두 값은 모두 hexadecimal입니다. 이 bus에는 slot 0의 single-function device `0000:17:00.0`이 하나 있습니다. 편의를 위해 device 이름에도 domain과 bus 번호가 반복됩니다.
Device directory 아래에는 class, config, device, enable, irq, local_cpus, remove, resource, 각 resource file, revision, ROM, subsystem ID와 vendor ID 등 서로 다른 역할의 file이 있습니다.
원문의 ASCII tree를 경로와 하위 file 관계가 같은 구조로 다시 그렸습니다.
예제 path의 domain:bus:slot.function을 분해합니다.
.. SPDX-License-Identifier: GPL-2.0
============================================
Accessing PCI device resources through sysfs
============================================
sysfs, usually mounted at /sys, provides access to PCI resources on platforms
that support it. For example, a given bus might look like this::
/sys/devices/pci0000:17
|-- 0000:17:00.0
| |-- class
| |-- config
| |-- device
| |-- enable
| |-- irq
| |-- local_cpus
| |-- remove
| |-- resource
| |-- resource0
| |-- resource1
| |-- resource2
| |-- revision
| |-- rom
| |-- subsystem_device
| |-- subsystem_vendor
| `-- vendor
`-- ...
The topmost element describes the PCI domain and bus number. In this case,
the domain number is 0000 and the bus number is 17 (both values are in hex).
This bus contains a single function device in slot 0. The domain and bus
numbers are reproduced for convenience. Under the device directory are several
files, each with their own function.
Device file과 접근 mode
36-66원문 표의 file, 기능, 형식과 접근 mode를 보존합니다.
`ro`는 read-only, `rw`는 read/write, `wo`는 write-only입니다. `mmap`은 file을 memory map할 수 있다는 뜻이며 `ascii`, `binary`, `cpumask`는 각각 text, binary data, CPU mask 형식을 나타냅니다.
Sysfs file의 access와 data 표현을 해석합니다.
주석 `[1]`의 `resource0..N` write 가능 조건은 `IORESOURCE_IO`, 즉 I/O port region에만 해당합니다.
=================== =====================================================
file function
=================== =====================================================
class PCI class (ascii, ro)
config PCI config space (binary, rw)
device PCI device (ascii, ro)
enable Whether the device is enabled (ascii, rw)
irq IRQ number (ascii, ro)
local_cpus nearby CPU mask (cpumask, ro)
remove remove device from kernel's list (ascii, wo)
resource PCI resource host addresses (ascii, ro)
resource0..N PCI resource N, if present (binary, mmap, rw\ [1]_)
resource0_wc..N_wc PCI WC map resource N, if prefetchable (binary, mmap)
revision PCI revision (ascii, ro)
rom PCI ROM resource, if present (binary, ro)
subsystem_device PCI subsystem device (ascii, ro)
subsystem_vendor PCI subsystem vendor (ascii, ro)
vendor PCI vendor (ascii, ro)
=================== =====================================================
::
ro - read only file
rw - file is readable and writable
wo - write only file
mmap - file is mmapable
ascii - file contains ascii text
binary - file contains binary data
cpumask - file contains a cpumask type
.. [1] rw for IORESOURCE_IO (I/O port) regions only
Read·write·mmap 동작
67-76Read-only file은 정보를 제공하며 write는 무시됩니다. 단 `rom` file은 뒤에서 설명하는 특별한 enable 절차가 있습니다.
Writable file은 config space 변경이나 device detach 같은 동작을 수행하는 데 사용할 수 있습니다.
Mmapable file은 offset 0에서 file을 `mmap()`하여 user space에서 실제 device programming에 사용할 수 있습니다. 일부 platform은 특정 resource의 mmap을 지원하지 않으므로 모든 mmap 시도의 반환값을 반드시 확인해야 합니다.
대표적인 예외는 I/O port resource이며, 이 resource는 mmap 대신 read/write 접근도 제공합니다.
File mode마다 가능한 작업과 주의점을 구분합니다.
The read only files are informational, writes to them will be ignored, with
the exception of the 'rom' file. Writable files can be used to perform
actions on the device (e.g. changing config space, detaching a device).
mmapable files are available via an mmap of the file at offset 0 and can be
used to do actual device programming from userspace. Note that some platforms
don't support mmapping of certain resources, so be sure to check the return
value from any attempted mmap. The most notable of these are I/O port
resources, which also provide read/write access.
enable·rom·remove file
77-97`enable` file은 단순 boolean이 아니라 device가 enable된 횟수를 나타내는 counter입니다. 현재 `4`일 때 `1`을 기록하면 `5`가 되고 `0`을 기록하면 count가 감소합니다. Count가 0으로 돌아가도 일부 초기화는 되돌려지지 않을 수 있습니다.
`rom` file은 존재하는 device ROM을 read-only로 제공합니다. 기본적으로 disable되어 있으므로 application은 읽기 전에 문자열 `1`을 기록해 enable하고, 접근을 마친 뒤 `0`을 기록해 다시 disable해야 합니다.
ROM read가 data를 성공적으로 반환하려면 device 자체도 enable되어 있어야 합니다. Driver가 bind되지 않았다면 앞서 설명한 `enable` file로 device를 enable할 수 있습니다.
ROM decode와 device enable 상태를 모두 관리한 뒤 반드시 원상 복구합니다.
`remove` file에 0이 아닌 integer를 기록하면 PCI device를 제거합니다. 이는 device power-off 같은 hot-plug 기능을 수행하는 것이 아닙니다.
제거 시 device는 kernel의 PCI device list에서 사라지고 sysfs directory가 제거되며 연결된 driver에서도 제거됩니다. PCI root bus 제거는 허용되지 않습니다.
값의 의미와 실제 kernel 동작을 정리합니다.
The 'enable' file provides a counter that indicates how many times the device
has been enabled. If the 'enable' file currently returns '4', and a '1' is
echoed into it, it will then return '5'. Echoing a '0' into it will decrease
the count. Even when it returns to 0, though, some of the initialisation
may not be reversed.
The 'rom' file is special in that it provides read-only access to the device's
ROM file, if available. It's disabled by default, however, so applications
should write the string "1" to the file to enable it before attempting a read
call, and disable it following the access by writing "0" to the file. Note
that the device must be enabled for a rom read to return data successfully.
In the event a driver is not bound to the device, it can be enabled using the
'enable' file, documented above.
The 'remove' file is used to remove the PCI device, by writing a non-zero
integer to the file. This does not involve any kind of hot-plug functionality,
e.g. powering off the device. The device is removed from the kernel's list of
PCI devices, the sysfs directory for it is removed, and the device will be
removed from any drivers attached to it. Removal of PCI root buses is
disallowed.
Legacy I/O와 ISA memory resource
98-118Platform이 지원하면 legacy I/O port와 ISA memory resource도 PCI class hierarchy의 sysfs에 제공됩니다.
원문의 ASCII tree를 동일한 symlink와 file 관계로 다시 그렸습니다.
`legacy_io`는 application이 legacy port I/O를 수행하는 read/write file입니다. File을 열고 원하는 port, 예를 들어 `0x3e8`로 seek한 뒤 1, 2 또는 4 byte를 read하거나 write합니다.
`legacy_mem`은 원하는 memory offset에 해당하는 offset으로 mmap해야 합니다. 예를 들어 VGA frame buffer는 `0xa0000`을 사용합니다. 오류를 확인한 뒤 반환 pointer를 dereference하면 legacy memory space에 접근할 수 있습니다.
Port I/O와 ISA memory map의 절차가 다릅니다.
Accessing legacy resources through sysfs
----------------------------------------
Legacy I/O port and ISA memory resources are also provided in sysfs if the
underlying platform supports them. They're located in the PCI class hierarchy,
e.g.::
/sys/class/pci_bus/0000:17/
|-- bridge -> ../../../devices/pci0000:17
|-- cpuaffinity
|-- legacy_io
`-- legacy_mem
The legacy_io file is a read/write file that can be used by applications to
do legacy port I/O. The application should open the file, seek to the desired
port (e.g. 0x3e8) and do a read or a write of 1, 2 or 4 bytes. The legacy_mem
file should be mmapped with an offset corresponding to the memory offset
desired, e.g. 0xa0000 for the VGA frame buffer. The application can then
simply dereference the returned pointer (after checking for errors of course)
to access legacy memory space.
새 platform의 PCI resource mapping
119-130위의 PCI resource mapping을 지원하려면 Linux platform code는 가능하면 `ARCH_GENERIC_PCI_MMAP_RESOURCE`를 정의하고 generic implementation을 사용해야 합니다.
`/proc/bus/pci` file을 통한 역사적인 `mmap()` interface도 지원하려면 platform이 `HAVE_PCI_MMAP`을 설정할 수 있습니다.
대안으로 `HAVE_PCI_MMAP`을 설정한 platform은 `ARCH_GENERIC_PCI_MMAP_RESOURCE` 대신 자체 `pci_mmap_resource_range()` implementation을 제공할 수 있습니다.
Generic sysfs mapping과 역사적 proc interface의 build contract입니다.
Supporting PCI access on new platforms
--------------------------------------
In order to support PCI resource mapping as described above, Linux platform
code should ideally define ARCH_GENERIC_PCI_MMAP_RESOURCE and use the generic
implementation of that functionality. To support the historical interface of
mmap() through files in /proc/bus/pci, platforms may also set HAVE_PCI_MMAP.
Alternatively, platforms which set HAVE_PCI_MMAP may provide their own
implementation of pci_mmap_resource_range() instead of defining
ARCH_GENERIC_PCI_MMAP_RESOURCE.
WC·I/O·legacy platform hook
131-138PCI resource의 write-combining map을 지원하는 platform은 `arch_can_pci_mmap_wc()`를 정의해야 하며, runtime에 write-combining이 허용되면 0이 아닌 값을 반환해야 합니다.
I/O resource map을 지원하는 platform은 같은 방식으로 `arch_can_pci_mmap_io()`를 정의합니다.
Legacy resource는 `HAVE_PCI_LEGACY`로 보호됩니다. Legacy 기능을 지원하려는 platform은 이를 정의하고 `pci_legacy_read`, `pci_legacy_write`, `pci_mmap_legacy_page_range` 함수를 제공해야 합니다.
Mapping 종류별 runtime 검사와 구현 함수를 정리합니다.
Platforms which support write-combining maps of PCI resources must define
arch_can_pci_mmap_wc() which shall evaluate to non-zero at runtime when
write-combining is permitted. Platforms which support maps of I/O resources
define arch_can_pci_mmap_io() similarly.
Legacy resources are protected by the HAVE_PCI_LEGACY define. Platforms
wishing to support legacy functionality should define it and provide
pci_legacy_read, pci_legacy_write and pci_mmap_legacy_page_range functions.
요약·해설
sysfs-pci.rst:1-138PCI sysfs device directory는 ID·IRQ·resource 정보를 text로 제공하고 config space와 resource를 binary read/write 또는 mmap으로 노출합니다. Platform마다 mmap 가능 범위가 다르므로 반환값 검사가 필수입니다.
`enable`은 reference counter이고 `rom`은 읽기 전후에 1과 0으로 decode를 제어해야 합니다. `remove`는 power-off가 아니라 kernel list, sysfs, bind된 driver에서 device를 분리합니다.
새 architecture는 generic PCI mmap을 우선 사용하고 WC·I/O·legacy 지원 여부에 맞는 capability hook과 read·write·mmap 함수를 제공해야 합니다.