요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GPL-2.0
===================
Firmware Upload API
===================
A device driver that registers with the firmware loader will expose
persistent sysfs nodes to enable users to initiate firmware updates for
that device. It is the responsibility of the device driver and/or the
device itself to perform any validation on the data received. Firmware
upload uses the same *loading* and *data* sysfs files described in the
documentation for firmware fallback. It also adds additional sysfs files
to provide status on the transfer of the firmware image to the device.
Register for firmware upload
============================
A device driver registers for firmware upload by calling
firmware_upload_register(). Among the parameter list is a name to
identify the device under /sys/class/firmware. A user may initiate a
firmware upload by echoing a 1 to the *loading* sysfs file for the target
device. Next, the user writes the firmware image to the *data* sysfs
file. After writing the firmware data, the user echos 0 to the *loading*
sysfs file to signal completion. Echoing 0 to *loading* also triggers the
transfer of the firmware to the lower-lever device driver in the context
of a kernel worker thread.
To use the firmware upload API, write a driver that implements a set of
ops. The probe function calls firmware_upload_register() and the remove
function calls firmware_upload_unregister() such as::
static const struct fw_upload_ops m10bmc_ops = {
.prepare = m10bmc_sec_prepare,
.write = m10bmc_sec_write,
.poll_complete = m10bmc_sec_poll_complete,
.cancel = m10bmc_sec_cancel,
.cleanup = m10bmc_sec_cleanup,
};
static int m10bmc_sec_probe(struct platform_device *pdev)
{
const char *fw_name, *truncate;
struct m10bmc_sec *sec;
struct fw_upload *fwl;
unsigned int len;
sec = devm_kzalloc(&pdev->dev, sizeof(*sec), GFP_KERNEL);
if (!sec)
return -ENOMEM;
sec->dev = &pdev->dev;
sec->m10bmc = dev_get_drvdata(pdev->dev.parent);
dev_set_drvdata(&pdev->dev, sec);
fw_name = dev_name(sec->dev);
truncate = strstr(fw_name, ".auto");
len = (truncate) ? truncate - fw_name : strlen(fw_name);
sec->fw_name = kmemdup_nul(fw_name, len, GFP_KERNEL);
fwl = firmware_upload_register(THIS_MODULE, sec->dev, sec->fw_name,
&m10bmc_ops, sec);
if (IS_ERR(fwl)) {
dev_err(sec->dev, "Firmware Upload driver failed to start\n");
kfree(sec->fw_name);
return PTR_ERR(fwl);
}
sec->fwl = fwl;
return 0;
}
static int m10bmc_sec_remove(struct platform_device *pdev)
{
struct m10bmc_sec *sec = dev_get_drvdata(&pdev->dev);
firmware_upload_unregister(sec->fwl);
kfree(sec->fw_name);
return 0;
}
firmware_upload_register
------------------------
.. kernel-doc:: drivers/base/firmware_loader/sysfs_upload.c
:identifiers: firmware_upload_register
firmware_upload_unregister
--------------------------
.. kernel-doc:: drivers/base/firmware_loader/sysfs_upload.c
:identifiers: firmware_upload_unregister
Firmware Upload Ops
-------------------
.. kernel-doc:: include/linux/firmware.h
:identifiers: fw_upload_ops
Firmware Upload Progress Codes
------------------------------
The following progress codes are used internally by the firmware loader.
Corresponding strings are reported through the status sysfs node that
is described below and are documented in the ABI documentation.
.. kernel-doc:: drivers/base/firmware_loader/sysfs_upload.h
:identifiers: fw_upload_prog
Firmware Upload Error Codes
---------------------------
The following error codes may be returned by the driver ops in case of
failure:
.. kernel-doc:: include/linux/firmware.h
:identifiers: fw_upload_err
Sysfs Attributes
================
In addition to the *loading* and *data* sysfs files, there are additional
sysfs files to monitor the status of the data transfer to the target
device and to determine the final pass/fail status of the transfer.
Depending on the device and the size of the firmware image, a firmware
update could take milliseconds or minutes.
The additional sysfs files are:
* status - provides an indication of the progress of a firmware update
* error - provides error information for a failed firmware update
* remaining_size - tracks the data transfer portion of an update
* cancel - echo 1 to this file to cancel the update
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
Firmware Upload API 개요
1-14이 문서는 `GPL-2.0` SPDX license identifier를 사용하며 제목은 `Firmware Upload API`입니다.
Firmware loader에 등록한 device driver는 사용자가 해당 device의 firmware update를 시작할 수 있도록 persistent sysfs node를 노출합니다.
받은 data의 유효성을 검사할 책임은 device driver와 device 자체에 있습니다.
Firmware upload는 firmware fallback 문서에서 설명한 것과 같은 `loading` 및 `data` sysfs file을 사용합니다. 여기에 firmware image를 device로 전송하는 상태를 제공하는 추가 sysfs file도 노출합니다.
Firmware upload 등록과 전송 시작
15-27Device driver는 `firmware_upload_register()`를 호출해 firmware upload에 등록합니다. Parameter에는 `/sys/class/firmware` 아래에서 device를 식별할 이름이 포함됩니다.
사용자는 target device의 `loading` sysfs file에 1을 echo해 upload를 시작하고, 이어서 `data` sysfs file에 firmware image를 씁니다. Firmware data 기록이 끝나면 `loading`에 0을 echo해 완료를 알립니다.
`loading`에 0을 쓰면 kernel worker thread context에서 firmware를 lower-level device driver로 전송하는 작업도 시작됩니다.
Userspace가 sysfs로 image를 전달하고 worker thread가 driver로 전송하는 순서입니다.
Upload driver 구현 예제
28-80Firmware upload API를 사용하려면 operation 집합을 구현하는 driver를 작성합니다. Probe function은 `firmware_upload_register()`를 호출하고 remove function은 `firmware_upload_unregister()`를 호출합니다.
예제는 `prepare`, `write`, `poll_complete`, `cancel`, `cleanup` callback으로 `m10bmc_ops`를 구성합니다. Probe에서는 private data와 firmware name을 준비해 upload object를 등록하고, remove에서는 등록 해제 뒤 이름 memory를 해제합니다.
static const struct fw_upload_ops m10bmc_ops = {
.prepare = m10bmc_sec_prepare,
.write = m10bmc_sec_write,
.poll_complete = m10bmc_sec_poll_complete,
.cancel = m10bmc_sec_cancel,
.cleanup = m10bmc_sec_cleanup,
};
static int m10bmc_sec_probe(struct platform_device *pdev)
{
const char *fw_name, *truncate;
struct m10bmc_sec *sec;
struct fw_upload *fwl;
unsigned int len;
sec = devm_kzalloc(&pdev->dev, sizeof(*sec), GFP_KERNEL);
if (!sec)
return -ENOMEM;
sec->dev = &pdev->dev;
sec->m10bmc = dev_get_drvdata(pdev->dev.parent);
dev_set_drvdata(&pdev->dev, sec);
fw_name = dev_name(sec->dev);
truncate = strstr(fw_name, ".auto");
len = (truncate) ? truncate - fw_name : strlen(fw_name);
sec->fw_name = kmemdup_nul(fw_name, len, GFP_KERNEL);
fwl = firmware_upload_register(THIS_MODULE, sec->dev, sec->fw_name,
&m10bmc_ops, sec);
if (IS_ERR(fwl)) {
dev_err(sec->dev, "Firmware Upload driver failed to start\n");
kfree(sec->fw_name);
return PTR_ERR(fwl);
}
sec->fwl = fwl;
return 0;
}
static int m10bmc_sec_remove(struct platform_device *pdev)
{
struct m10bmc_sec *sec = dev_get_drvdata(&pdev->dev);
firmware_upload_unregister(sec->fwl);
kfree(sec->fw_name);
return 0;
}
Register·unregister API와 ops
81-95`firmware_upload_register`와 `firmware_upload_unregister`의 kernel-doc은 `drivers/base/firmware_loader/sysfs_upload.c`에서 가져옵니다.
.. kernel-doc:: drivers/base/firmware_loader/sysfs_upload.c
:identifiers: firmware_upload_register
.. kernel-doc:: drivers/base/firmware_loader/sysfs_upload.c
:identifiers: firmware_upload_unregister
Firmware upload operation 집합인 `fw_upload_ops`의 kernel-doc은 `include/linux/firmware.h`에서 가져옵니다.
.. kernel-doc:: include/linux/firmware.h
:identifiers: fw_upload_ops
예제 driver가 구현하는 upload 생명주기 operation입니다.
Progress code와 error code
96-112Firmware loader는 `fw_upload_prog` progress code를 내부적으로 사용합니다. 대응하는 string은 아래에서 설명하는 `status` sysfs node로 보고되며 ABI 문서에도 정의되어 있습니다.
.. kernel-doc:: drivers/base/firmware_loader/sysfs_upload.h
:identifiers: fw_upload_prog
Driver operation이 실패하면 `fw_upload_err` error code를 반환할 수 있습니다.
.. kernel-doc:: include/linux/firmware.h
:identifiers: fw_upload_err
Firmware upload sysfs attribute
113-127`loading`과 `data` 이외에도 target device로의 data transfer 상태와 최종 성공·실패를 확인하는 sysfs file을 제공합니다. Device와 firmware image 크기에 따라 update는 수 millisecond에서 수 minute까지 걸릴 수 있습니다.
- `status`: firmware update 진행 상태를 표시합니다.
- `error`: 실패한 firmware update의 error 정보를 제공합니다.
- `remaining_size`: update 중 data transfer 부분의 남은 크기를 추적합니다.
- `cancel`: 이 file에 1을 echo하면 update를 취소합니다.
Data 전송과 상태·오류·취소를 담당하는 persistent attribute입니다.
요약과 해설
fw_upload.rst:1-127Firmware Upload API는 `/sys/class/firmware` 아래 persistent node를 만들고 `loading`·`data` protocol로 image를 받은 뒤 kernel worker thread에서 `fw_upload_ops`를 호출해 device를 update합니다.
Driver는 validation과 prepare·write·poll·cancel·cleanup을 담당합니다. Userspace는 status·error·remaining_size·cancel attribute로 긴 update의 진행과 최종 결과를 관리할 수 있습니다.