요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
Configfs 구성
gpio-aggregator.rst:72-178device와 line의 `key`, `offset`, `name`, `live` attribute 및 동기 probe와 자동 `_sysfs` 항목의 제약을 정리합니다.
일반 목적 드라이버
gpio-aggregator.rst:179-218DT 장치를 `gpio_aggregator_dt_ids[]` 또는 `driver_override`로 bind해 사용자 공간 GPIO interface를 제공하는 방법을 보여 줍니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GPL-2.0-only
GPIO Aggregator
===============
The GPIO Aggregator provides a mechanism to aggregate GPIOs, and expose them as
a new gpio_chip. This supports the following use cases.
Aggregating GPIOs using Sysfs
-----------------------------
GPIO controllers are exported to userspace using /dev/gpiochip* character
devices. Access control to these devices is provided by standard UNIX file
system permissions, on an all-or-nothing basis: either a GPIO controller is
accessible for a user, or it is not.
The GPIO Aggregator provides access control for a set of one or more GPIOs, by
aggregating them into a new gpio_chip, which can be assigned to a group or user
using standard UNIX file ownership and permissions. Furthermore, this
simplifies and hardens exporting GPIOs to a virtual machine, as the VM can just
grab the full GPIO controller, and no longer needs to care about which GPIOs to
grab and which not, reducing the attack surface.
Aggregated GPIO controllers are instantiated and destroyed by writing to
write-only attribute files in sysfs.
/sys/bus/platform/drivers/gpio-aggregator/
"new_device" ...
Userspace may ask the kernel to instantiate an aggregated GPIO
controller by writing a string describing the GPIOs to
aggregate to the "new_device" file, using the format
.. code-block:: none
[<gpioA>] [<gpiochipB> <offsets>] ...
Where:
"<gpioA>" ...
is a GPIO line name,
"<gpiochipB>" ...
is a GPIO chip label, and
"<offsets>" ...
is a comma-separated list of GPIO offsets and/or
GPIO offset ranges denoted by dashes.
Example: Instantiate a new GPIO aggregator by aggregating GPIO
line 19 of "e6052000.gpio" and GPIO lines 20-21 of
"e6050000.gpio" into a new gpio_chip:
.. code-block:: sh
$ echo 'e6052000.gpio 19 e6050000.gpio 20-21' > new_device
"delete_device" ...
Userspace may ask the kernel to destroy an aggregated GPIO
controller after use by writing its device name to the
"delete_device" file.
Example: Destroy the previously-created aggregated GPIO
controller, assumed to be "gpio-aggregator.0":
.. code-block:: sh
$ echo gpio-aggregator.0 > delete_device
Aggregating GPIOs using Configfs
--------------------------------
**Group:** ``/config/gpio-aggregator``
This is the root directory of the gpio-aggregator configfs tree.
**Group:** ``/config/gpio-aggregator/<example-name>``
This directory represents a GPIO aggregator device. You can assign any
name to ``<example-name>`` (e.g. ``agg0``), except names starting with
``_sysfs`` prefix, which are reserved for auto-generated configfs
entries corresponding to devices created via Sysfs.
**Attribute:** ``/config/gpio-aggregator/<example-name>/live``
The ``live`` attribute allows to trigger the actual creation of the device
once it's fully configured. Accepted values are:
* ``1``, ``yes``, ``true`` : enable the virtual device
* ``0``, ``no``, ``false`` : disable the virtual device
**Attribute:** ``/config/gpio-aggregator/<example-name>/dev_name``
The read-only ``dev_name`` attribute exposes the name of the device as it
will appear in the system on the platform bus (e.g. ``gpio-aggregator.0``).
This is useful for identifying a character device for the newly created
aggregator. If it's ``gpio-aggregator.0``,
``/sys/devices/platform/gpio-aggregator.0/gpiochipX`` path tells you that the
GPIO device id is ``X``.
You must create subdirectories for each virtual line you want to
instantiate, named exactly as ``line0``, ``line1``, ..., ``lineY``, when
you want to instantiate ``Y+1`` (Y >= 0) lines. Configure all lines before
activating the device by setting ``live`` to 1.
**Group:** ``/config/gpio-aggregator/<example-name>/<lineY>/``
This directory represents a GPIO line to include in the aggregator.
**Attribute:** ``/config/gpio-aggregator/<example-name>/<lineY>/key``
**Attribute:** ``/config/gpio-aggregator/<example-name>/<lineY>/offset``
The default values after creating the ``<lineY>`` directory are:
* ``key`` : <empty>
* ``offset`` : -1
``key`` must always be explicitly configured, while ``offset`` depends.
Two configuration patterns exist for each ``<lineY>``:
(a). For lookup by GPIO line name:
* Set ``key`` to the line name.
* Ensure ``offset`` remains -1 (the default).
(b). For lookup by GPIO chip name and the line offset within the chip:
* Set ``key`` to the chip name.
* Set ``offset`` to the line offset (0 <= ``offset`` < 65535).
**Attribute:** ``/config/gpio-aggregator/<example-name>/<lineY>/name``
The ``name`` attribute sets a custom name for lineY. If left unset, the
line will remain unnamed.
Once the configuration is done, the ``'live'`` attribute must be set to 1
in order to instantiate the aggregator device. It can be set back to 0 to
destroy the virtual device. The module will synchronously wait for the new
aggregator device to be successfully probed and if this doesn't happen, writing
to ``'live'`` will result in an error. This is a different behaviour from the
case when you create it using sysfs ``new_device`` interface.
.. note::
For aggregators created via Sysfs, the configfs entries are
auto-generated and appear as ``/config/gpio-aggregator/_sysfs.<N>/``. You
cannot add or remove line directories with mkdir(2)/rmdir(2). To modify
lines, you must use the "delete_device" interface to tear down the
existing device and reconfigure it from scratch. However, you can still
toggle the aggregator with the ``live`` attribute and adjust the
``key``, ``offset``, and ``name`` attributes for each line when ``live``
is set to 0 by hand (i.e. it's not waiting for deferred probe).
Sample configuration commands
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: sh
# Create a directory for an aggregator device
$ mkdir /sys/kernel/config/gpio-aggregator/agg0
# Configure each line
$ mkdir /sys/kernel/config/gpio-aggregator/agg0/line0
$ echo gpiochip0 > /sys/kernel/config/gpio-aggregator/agg0/line0/key
$ echo 6 > /sys/kernel/config/gpio-aggregator/agg0/line0/offset
$ echo test0 > /sys/kernel/config/gpio-aggregator/agg0/line0/name
$ mkdir /sys/kernel/config/gpio-aggregator/agg0/line1
$ echo gpiochip0 > /sys/kernel/config/gpio-aggregator/agg0/line1/key
$ echo 7 > /sys/kernel/config/gpio-aggregator/agg0/line1/offset
$ echo test1 > /sys/kernel/config/gpio-aggregator/agg0/line1/name
# Activate the aggregator device
$ echo 1 > /sys/kernel/config/gpio-aggregator/agg0/live
Generic GPIO Driver
-------------------
The GPIO Aggregator can also be used as a generic driver for a simple
GPIO-operated device described in DT, without a dedicated in-kernel driver.
This is useful in industrial control, and is not unlike e.g. spidev, which
allows the user to communicate with an SPI device from userspace.
Binding a device to the GPIO Aggregator is performed either by modifying the
gpio-aggregator driver, or by writing to the "driver_override" file in Sysfs.
Example: If "door" is a GPIO-operated device described in DT, using its own
compatible value::
door {
compatible = "myvendor,mydoor";
gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>,
<&gpio2 20 GPIO_ACTIVE_LOW>;
gpio-line-names = "open", "lock";
};
it can be bound to the GPIO Aggregator by either:
1. Adding its compatible value to ``gpio_aggregator_dt_ids[]``,
2. Binding manually using "driver_override":
.. code-block:: sh
$ echo gpio-aggregator > /sys/bus/platform/devices/door/driver_override
$ echo door > /sys/bus/platform/drivers/gpio-aggregator/bind
After that, a new gpiochip "door" has been created:
.. code-block:: sh
$ gpioinfo door
gpiochip12 - 2 lines:
line 0: "open" unused input active-high
line 1: "lock" unused input active-high
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
GPIO Aggregator 개요
1-9GPIO Aggregator는 여러 GPIO를 하나로 모아 새로운 `gpio_chip`으로 노출하는 메커니즘입니다. 이어지는 절에서 Sysfs와 Configfs를 통한 접근 제어 및 일반 목적 드라이버 사용 사례를 설명합니다.
Sysfs로 GPIO 집계
10-71GPIO controller는 `/dev/gpiochip*` character device로 사용자 공간에 노출됩니다. 표준 UNIX 파일 소유권과 권한이 제공하는 접근 제어는 전체 허용 또는 전체 거부 방식이므로, 사용자는 controller 전체에 접근할 수 있거나 전혀 접근할 수 없습니다.
GPIO Aggregator는 하나 이상의 GPIO를 새 `gpio_chip`으로 모아 이 집합에 별도 접근 제어를 제공합니다. 새 장치의 소유자나 그룹과 UNIX 권한을 설정할 수 있습니다. VM은 전체 가상 GPIO controller 하나만 가져가면 되므로 내보낼 GPIO를 개별 선택할 필요가 없어지고 attack surface도 줄어듭니다.
집계 GPIO controller는 `/sys/bus/platform/drivers/gpio-aggregator/` 아래의 write-only attribute에 써서 만들고 제거합니다.
| attribute | 동작 |
|---|---|
| new_device | 집계할 GPIO를 설명하는 문자열을 써서 새 GPIO controller를 만듭니다. |
| delete_device | 사용이 끝난 집계 GPIO controller의 device name을 써서 제거합니다. |
`new_device` 입력 형식은 다음과 같습니다.
[<gpioA>] [<gpiochipB> <offsets>] ...
| 항목 | 의미 |
|---|---|
| <gpioA> | GPIO line name |
| <gpiochipB> | GPIO chip label |
| <offsets> | 쉼표로 구분한 GPIO offset 또는 대시로 표시한 offset range 목록 |
`e6052000.gpio`의 line 19와 `e6050000.gpio`의 line 20~21을 새 `gpio_chip`으로 집계하는 예입니다.
$ echo 'e6052000.gpio 19 e6050000.gpio 20-21' > new_device
앞에서 만든 장치 이름이 `gpio-aggregator.0`이라고 가정하고 제거하는 예입니다.
$ echo gpio-aggregator.0 > delete_device
Configfs device 구성
72-106| configfs 경로 | 설명 |
|---|---|
| /config/gpio-aggregator | gpio-aggregator configfs tree의 root group입니다. |
| /config/gpio-aggregator/<example-name> | GPIO aggregator device를 나타냅니다. `agg0`처럼 원하는 이름을 사용할 수 있지만 Sysfs로 만든 장치의 자동 항목에 예약된 `_sysfs` 접두사는 사용할 수 없습니다. |
| /config/gpio-aggregator/<example-name>/live | 구성이 끝난 device를 실제로 만들거나 제거합니다. `1`, `yes`, `true`는 활성화하고 `0`, `no`, `false`는 비활성화합니다. |
| /config/gpio-aggregator/<example-name>/dev_name | 읽기 전용. platform bus에 나타날 device name, 예를 들어 `gpio-aggregator.0`을 보여 줍니다. |
`dev_name`이 `gpio-aggregator.0`이면 `/sys/devices/platform/gpio-aggregator.0/gpiochipX`에서 GPIO device id가 `X`임을 알 수 있습니다.
`Y+1`개(`Y >= 0`) 가상 line을 만들려면 원하는 line마다 `line0`, `line1`, ..., `lineY`라는 정확한 이름의 하위 디렉터리를 만들어야 합니다. 모든 line을 구성한 뒤 `live`를 1로 설정합니다.
Configfs line 구성과 수명주기
107-156`/config/gpio-aggregator/<example-name>/<lineY>/`는 aggregator에 포함할 GPIO line 하나를 나타냅니다.
| attribute | 기본값과 의미 |
|---|---|
| key | 기본값은 빈 값이며 반드시 명시적으로 설정해야 합니다. line name 조회에서는 line name을, chip/offset 조회에서는 chip name을 지정합니다. |
| offset | 기본값은 -1입니다. line name 조회에서는 -1을 유지하고, chip/offset 조회에서는 `0 <= offset < 65535`인 line offset을 지정합니다. |
| name | `lineY`에 사용자 지정 이름을 설정합니다. 설정하지 않으면 이름이 없습니다. |
line name으로 찾으려면 `key`에 line name을 쓰고 `offset`을 기본값 -1로 둡니다. GPIO chip name과 chip 내부 line offset으로 찾으려면 `key`에 chip name을 쓰고 `offset`에 유효한 번호를 지정합니다.
구성이 끝나면 `live`를 1로 설정해 aggregator device를 만듭니다. 0으로 되돌리면 가상 장치를 제거합니다. 모듈은 새 장치 probe가 성공할 때까지 동기적으로 기다리며, 성공하지 않으면 `live` 쓰기가 오류를 반환합니다. 이는 Sysfs `new_device`로 만들 때와 다른 동작입니다.
Sysfs로 만든 aggregator의 configfs 항목은 `/config/gpio-aggregator/_sysfs.<N>/` 형식으로 자동 생성됩니다. `mkdir(2)`/`rmdir(2)`로 line 디렉터리를 추가하거나 제거할 수 없으며, line 구성을 바꾸려면 `delete_device`로 기존 장치를 제거하고 처음부터 다시 구성해야 합니다. 단, `live`가 수동으로 0이고 deferred probe를 기다리는 상태가 아닐 때는 `live` 토글과 각 line의 `key`, `offset`, `name` 조정이 가능합니다.
Configfs 구성 명령 예제
157-178aggregator 디렉터리를 만들고 `gpiochip0`의 offset 6과 7을 각각 `test0`, `test1`으로 구성한 뒤 활성화하는 전체 예입니다.
# Create a directory for an aggregator device
$ mkdir /sys/kernel/config/gpio-aggregator/agg0
# Configure each line
$ mkdir /sys/kernel/config/gpio-aggregator/agg0/line0
$ echo gpiochip0 > /sys/kernel/config/gpio-aggregator/agg0/line0/key
$ echo 6 > /sys/kernel/config/gpio-aggregator/agg0/line0/offset
$ echo test0 > /sys/kernel/config/gpio-aggregator/agg0/line0/name
$ mkdir /sys/kernel/config/gpio-aggregator/agg0/line1
$ echo gpiochip0 > /sys/kernel/config/gpio-aggregator/agg0/line1/key
$ echo 7 > /sys/kernel/config/gpio-aggregator/agg0/line1/offset
$ echo test1 > /sys/kernel/config/gpio-aggregator/agg0/line1/name
# Activate the aggregator device
$ echo 1 > /sys/kernel/config/gpio-aggregator/agg0/live
일반 목적 GPIO 드라이버
179-218GPIO Aggregator는 전용 커널 드라이버 없이 DT에 기술된 단순 GPIO 조작 장치의 일반 드라이버로도 사용할 수 있습니다. 산업 제어에 유용하며 사용자 공간에서 SPI 장치와 통신하게 하는 `spidev`와 비슷합니다.
장치를 GPIO Aggregator에 bind하려면 gpio-aggregator 드라이버를 수정하거나 Sysfs의 `driver_override` 파일에 씁니다.
`door`라는 GPIO 장치가 자체 compatible 값으로 DT에 기술된 예입니다.
door {
compatible = "myvendor,mydoor";
gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>,
<&gpio2 20 GPIO_ACTIVE_LOW>;
gpio-line-names = "open", "lock";
};
이 장치는 `gpio_aggregator_dt_ids[]`에 compatible 값을 추가하거나 다음처럼 `driver_override`로 수동 bind할 수 있습니다.
$ echo gpio-aggregator > /sys/bus/platform/devices/door/driver_override
$ echo door > /sys/bus/platform/drivers/gpio-aggregator/bind
bind 뒤에는 두 line을 가진 새 gpiochip `door`가 생성됩니다.
$ gpioinfo door
gpiochip12 - 2 lines:
line 0: "open" unused input active-high
line 1: "lock" unused input active-high
GPIO 집계와 접근 제어
gpio-aggregator.rst:1-71개별 GPIO 집합을 별도 character device로 만들고 UNIX 권한 또는 VM 할당 경계를 적용하는 Sysfs 인터페이스를 설명합니다.