Documentation/driver-api/firmware/fw_upload.rst GitHub 원문 ↗

Linux 6.18.37 · Driver API

Firmware Upload API

Persistent sysfs node와 fw_upload_ops를 사용해 device firmware update를 전송·감시·취소하는 API를 설명합니다.

Source pathDocumentation/driver-api/firmware/fw_upload.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약과 해설

fw_upload.rst:1-127

Firmware 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의 진행과 최종 결과를 관리할 수 있습니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3 ===================
4 Firmware Upload API
5 ===================
6
7 A device driver that registers with the firmware loader will expose
8 persistent sysfs nodes to enable users to initiate firmware updates for
9 that device. It is the responsibility of the device driver and/or the
10 device itself to perform any validation on the data received. Firmware
11 upload uses the same *loading* and *data* sysfs files described in the
12 documentation for firmware fallback. It also adds additional sysfs files
13 to provide status on the transfer of the firmware image to the device.
14
15 Register for firmware upload
16 ============================
17
18 A device driver registers for firmware upload by calling
19 firmware_upload_register(). Among the parameter list is a name to
20 identify the device under /sys/class/firmware. A user may initiate a
21 firmware upload by echoing a 1 to the *loading* sysfs file for the target
22 device. Next, the user writes the firmware image to the *data* sysfs
23 file. After writing the firmware data, the user echos 0 to the *loading*
24 sysfs file to signal completion. Echoing 0 to *loading* also triggers the
25 transfer of the firmware to the lower-lever device driver in the context
26 of a kernel worker thread.
27
28 To use the firmware upload API, write a driver that implements a set of
29 ops. The probe function calls firmware_upload_register() and the remove
30 function calls firmware_upload_unregister() such as::
31
32 static const struct fw_upload_ops m10bmc_ops = {
33 .prepare = m10bmc_sec_prepare,
34 .write = m10bmc_sec_write,
35 .poll_complete = m10bmc_sec_poll_complete,
36 .cancel = m10bmc_sec_cancel,
37 .cleanup = m10bmc_sec_cleanup,
38 };
39
40 static int m10bmc_sec_probe(struct platform_device *pdev)
41 {
42 const char *fw_name, *truncate;
43 struct m10bmc_sec *sec;
44 struct fw_upload *fwl;
45 unsigned int len;
46
47 sec = devm_kzalloc(&pdev->dev, sizeof(*sec), GFP_KERNEL);
48 if (!sec)
49 return -ENOMEM;
50
51 sec->dev = &pdev->dev;
52 sec->m10bmc = dev_get_drvdata(pdev->dev.parent);
53 dev_set_drvdata(&pdev->dev, sec);
54
55 fw_name = dev_name(sec->dev);
56 truncate = strstr(fw_name, ".auto");
57 len = (truncate) ? truncate - fw_name : strlen(fw_name);
58 sec->fw_name = kmemdup_nul(fw_name, len, GFP_KERNEL);
59
60 fwl = firmware_upload_register(THIS_MODULE, sec->dev, sec->fw_name,
61 &m10bmc_ops, sec);
62 if (IS_ERR(fwl)) {
63 dev_err(sec->dev, "Firmware Upload driver failed to start\n");
64 kfree(sec->fw_name);
65 return PTR_ERR(fwl);
66 }
67
68 sec->fwl = fwl;
69 return 0;
70 }
71
72 static int m10bmc_sec_remove(struct platform_device *pdev)
73 {
74 struct m10bmc_sec *sec = dev_get_drvdata(&pdev->dev);
75
76 firmware_upload_unregister(sec->fwl);
77 kfree(sec->fw_name);
78 return 0;
79 }
80
81 firmware_upload_register
82 ------------------------
83 .. kernel-doc:: drivers/base/firmware_loader/sysfs_upload.c
84 :identifiers: firmware_upload_register
85
86 firmware_upload_unregister
87 --------------------------
88 .. kernel-doc:: drivers/base/firmware_loader/sysfs_upload.c
89 :identifiers: firmware_upload_unregister
90
91 Firmware Upload Ops
92 -------------------
93 .. kernel-doc:: include/linux/firmware.h
94 :identifiers: fw_upload_ops
95
96 Firmware Upload Progress Codes
97 ------------------------------
98 The following progress codes are used internally by the firmware loader.
99 Corresponding strings are reported through the status sysfs node that
100 is described below and are documented in the ABI documentation.
101
102 .. kernel-doc:: drivers/base/firmware_loader/sysfs_upload.h
103 :identifiers: fw_upload_prog
104
105 Firmware Upload Error Codes
106 ---------------------------
107 The following error codes may be returned by the driver ops in case of
108 failure:
109
110 .. kernel-doc:: include/linux/firmware.h
111 :identifiers: fw_upload_err
112
113 Sysfs Attributes
114 ================
115
116 In addition to the *loading* and *data* sysfs files, there are additional
117 sysfs files to monitor the status of the data transfer to the target
118 device and to determine the final pass/fail status of the transfer.
119 Depending on the device and the size of the firmware image, a firmware
120 update could take milliseconds or minutes.
121
122 The additional sysfs files are:
123
124 * status - provides an indication of the progress of a firmware update
125 * error - provides error information for a failed firmware update
126 * remaining_size - tracks the data transfer portion of an update
127 * cancel - echo 1 to this file to cancel the update
128

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-27

Device 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로 전송하는 작업도 시작됩니다.

Firmware upload protocol
firmware_upload_register()로 device 등록echo 1 > loadingFirmware image > dataecho 0 > loadingKernel worker thread 시작fw_upload_ops를 통해 target device로 전송

Userspace가 sysfs로 image를 전달하고 worker thread가 driver로 전송하는 순서입니다.

Upload driver 구현 예제

28-80

Firmware 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
fw_upload_ops callback
Callback역할
prepare전송 전 device 준비와 image 검증
writeFirmware data chunk 전송
poll_completeDevice programming 완료 대기
cancel진행 중 update 취소
cleanup완료·실패 뒤 resource 정리

예제 driver가 구현하는 upload 생명주기 operation입니다.

Progress code와 error code

96-112

Firmware 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를 취소합니다.
Firmware upload sysfs files
FileDirection기능
loadinguserspace -> kernel1로 시작, 0으로 완료·전송 trigger
datauserspace -> kernelFirmware image 기록
statuskernel -> userspaceUpdate progress
errorkernel -> userspaceFailure detail
remaining_sizekernel -> userspace남은 data transfer 크기
canceluserspace -> kernel1을 기록해 update 취소

Data 전송과 상태·오류·취소를 담당하는 persistent attribute입니다.