Documentation/driver-api/early-userspace/buffer-format.rst GitHub 원문 ↗

Linux 6.18.37 · Driver API

initramfs buffer format

newc/crc CPIO grammar, header field, alignment, checksum과 hard-link tuple 처리를 설명합니다.

Source pathDocumentation/driver-api/early-userspace/buffer-format.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

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

1. 요약·해설

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

요약과 해설

buffer-format.rst:1-132

initramfs는 압축 또는 비압축 newc/crc CPIO archive를 이어 붙인 buffer입니다. 각 entry는 4-byte alignment, fixed-width hexadecimal ASCII header, NUL-terminated filename과 data로 구성되며 `TRAILER!!!`은 archive 경계와 hard-link tuple reset을 나타냅니다.

구현 시에는 `c_filesize`, `c_namesize`, `c_chksum`의 특수 규칙과 `(c_maj,c_min,c_ino)` 기반 hard-link 재사용을 정확히 지켜야 합니다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 =======================
2 initramfs buffer format
3 =======================
4
5 Al Viro, H. Peter Anvin
6
7 With kernel 2.5.x, the old "initial ramdisk" protocol was complemented
8 with an "initial ramfs" protocol. The initramfs content is passed
9 using the same memory buffer protocol used by initrd, but the content
10 is different. The initramfs buffer contains an archive which is
11 expanded into a ramfs filesystem; this document details the initramfs
12 buffer format.
13
14 The initramfs buffer format is based around the "newc" or "crc" CPIO
15 formats, and can be created with the cpio(1) utility. The cpio
16 archive can be compressed using gzip(1), or any other algorithm provided
17 via CONFIG_DECOMPRESS_*. One valid version of an initramfs buffer is
18 thus a single .cpio.gz file.
19
20 The full format of the initramfs buffer is defined by the following
21 grammar, where::
22
23 * is used to indicate "0 or more occurrences of"
24 (|) indicates alternatives
25 + indicates concatenation
26 GZIP() indicates gzip compression of the operand
27 BZIP2() indicates bzip2 compression of the operand
28 LZMA() indicates lzma compression of the operand
29 XZ() indicates xz compression of the operand
30 LZO() indicates lzo compression of the operand
31 LZ4() indicates lz4 compression of the operand
32 ZSTD() indicates zstd compression of the operand
33 ALGN(n) means padding with null bytes to an n-byte boundary
34
35 initramfs := ("\0" | cpio_archive | cpio_compressed_archive)*
36
37 cpio_compressed_archive := (GZIP(cpio_archive) | BZIP2(cpio_archive)
38 | LZMA(cpio_archive) | XZ(cpio_archive) | LZO(cpio_archive)
39 | LZ4(cpio_archive) | ZSTD(cpio_archive))
40
41 cpio_archive := cpio_file* + (<nothing> | cpio_trailer)
42
43 cpio_file := ALGN(4) + cpio_header + filename + "\0" + ALGN(4) + data
44
45 cpio_trailer := ALGN(4) + cpio_header + "TRAILER!!!\0" + ALGN(4)
46
47
48 In human terms, the initramfs buffer contains a collection of
49 compressed and/or uncompressed cpio archives (in the "newc" or "crc"
50 formats); arbitrary amounts zero bytes (for padding) can be added
51 between members.
52
53 The cpio "TRAILER!!!" entry (cpio end-of-archive) is optional, but is
54 not ignored; see "handling of hard links" below.
55
56 The structure of the cpio_header is as follows (all fields contain
57 hexadecimal ASCII numbers fully padded with '0' on the left to the
58 full width of the field, for example, the integer 4780 is represented
59 by the ASCII string "000012ac"):
60
61 ============= ================== ==============================================
62 Field name Field size Meaning
63 ============= ================== ==============================================
64 c_magic 6 bytes The string "070701" or "070702"
65 c_ino 8 bytes File inode number
66 c_mode 8 bytes File mode and permissions
67 c_uid 8 bytes File uid
68 c_gid 8 bytes File gid
69 c_nlink 8 bytes Number of links
70 c_mtime 8 bytes Modification time
71 c_filesize 8 bytes Size of data field
72 c_maj 8 bytes Major part of file device number
73 c_min 8 bytes Minor part of file device number
74 c_rmaj 8 bytes Major part of device node reference
75 c_rmin 8 bytes Minor part of device node reference
76 c_namesize 8 bytes Length of filename, including final \0
77 c_chksum 8 bytes Checksum of data field if c_magic is 070702;
78 otherwise zero
79 ============= ================== ==============================================
80
81 The c_mode field matches the contents of st_mode returned by stat(2)
82 on Linux, and encodes the file type and file permissions.
83
84 c_mtime is ignored unless CONFIG_INITRAMFS_PRESERVE_MTIME=y is set.
85
86 The c_filesize should be zero for any file which is not a regular file
87 or symlink.
88
89 c_namesize may account for more than one trailing '\0', as long as the
90 value doesn't exceed PATH_MAX. This can be useful for ensuring that a
91 subsequent file data segment is aligned, e.g. to a filesystem block
92 boundary.
93
94 The c_chksum field contains a simple 32-bit unsigned sum of all the
95 bytes in the data field. cpio(1) refers to this as "crc", which is
96 clearly incorrect (a cyclic redundancy check is a different and
97 significantly stronger integrity check), however, this is the
98 algorithm used.
99
100 If the filename is "TRAILER!!!" this is actually an end-of-archive
101 marker; the c_filesize for an end-of-archive marker must be zero.
102
103
104 Handling of hard links
105 ======================
106
107 When a nondirectory with c_nlink > 1 is seen, the (c_maj,c_min,c_ino)
108 tuple is looked up in a tuple buffer. If not found, it is entered in
109 the tuple buffer and the entry is created as usual; if found, a hard
110 link rather than a second copy of the file is created. It is not
111 necessary (but permitted) to include a second copy of the file
112 contents; if the file contents is not included, the c_filesize field
113 should be set to zero to indicate no data section follows. If data is
114 present, the previous instance of the file is overwritten; this allows
115 the data-carrying instance of a file to occur anywhere in the sequence
116 (GNU cpio is reported to attach the data to the last instance of a
117 file only.)
118
119 c_filesize must not be zero for a symlink.
120
121 When a "TRAILER!!!" end-of-archive marker is seen, the tuple buffer is
122 reset. This permits archives which are generated independently to be
123 concatenated.
124
125 To combine file data from different sources (without having to
126 regenerate the (c_maj,c_min,c_ino) fields), therefore, either one of
127 the following techniques can be used:
128
129 a) Separate the different file data sources with a "TRAILER!!!"
130 end-of-archive marker, or
131
132 b) Make sure c_nlink == 1 for all nondirectory entries.
133

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

initramfs buffer 형식 개요

1-19

문서 제목은 `initramfs buffer format`이며 Al Viro와 H. Peter Anvin이 작성했습니다.

kernel 2.5.x에서 기존 `initial ramdisk` protocol에 `initial ramfs` protocol이 추가되었습니다. initramfs 내용은 initrd와 같은 memory buffer protocol로 전달되지만 내용 형식은 다릅니다. initramfs buffer에는 ramfs filesystem으로 펼칠 archive가 들어 있으며, 이 문서는 그 buffer format을 규정합니다.

initramfs buffer format은 CPIO의 `newc` 또는 `crc` format을 기반으로 하며 `cpio(1)` utility로 만들 수 있습니다. cpio archive는 `gzip(1)` 또는 `CONFIG_DECOMPRESS_*`가 제공하는 다른 algorithm으로 압축할 수 있으므로, 단일 `.cpio.gz` file도 유효한 initramfs buffer입니다.

initramfs grammar

20-54

전체 initramfs buffer format은 다음 grammar로 정의됩니다. `*`는 0회 이상 반복, `(|)`는 대안, `+`는 이어 붙이기, `GZIP()`·`BZIP2()`·`LZMA()`·`XZ()`·`LZO()`·`LZ4()`·`ZSTD()`는 operand 압축, `ALGN(n)`은 n-byte boundary까지 null byte로 padding함을 뜻합니다.

*        is used to indicate "0 or more occurrences of"
(|)        indicates alternatives
+        indicates concatenation
GZIP()        indicates gzip compression of the operand
BZIP2()        indicates bzip2 compression of the operand
LZMA()        indicates lzma compression of the operand
XZ()        indicates xz compression of the operand
LZO()        indicates lzo compression of the operand
LZ4()        indicates lz4 compression of the operand
ZSTD()        indicates zstd compression of the operand
ALGN(n)        means padding with null bytes to an n-byte boundary

initramfs := ("\0" | cpio_archive | cpio_compressed_archive)*

cpio_compressed_archive := (GZIP(cpio_archive) | BZIP2(cpio_archive)
        | LZMA(cpio_archive) | XZ(cpio_archive) | LZO(cpio_archive)
        | LZ4(cpio_archive) | ZSTD(cpio_archive))

cpio_archive := cpio_file* + (<nothing> | cpio_trailer)

cpio_file := ALGN(4) + cpio_header + filename + "\0" + ALGN(4) + data

cpio_trailer := ALGN(4) + cpio_header + "TRAILER!!!\0" + ALGN(4)

사람이 이해하기 쉽게 말하면 initramfs buffer는 `newc` 또는 `crc` format의 압축되거나 압축되지 않은 cpio archive 모음입니다. member 사이에는 padding 목적으로 임의 개수의 zero byte를 넣을 수 있습니다.

cpio end-of-archive를 나타내는 `TRAILER!!!` entry는 선택 사항이지만, 존재할 때 무시되지는 않습니다. hard link 처리에서 tuple buffer를 reset하는 의미가 있습니다.

initramfs buffer grammar
initramfs: zero byte, cpio_archive, compressed archive를 0회 이상 연결compressed archive: GZIP/BZIP2/LZMA/XZ/LZO/LZ4/ZSTD 중 하나cpio_archive: cpio_file 반복 뒤 선택적 TRAILER!!!cpio_file: 4-byte align + header + filename + NUL + align + datatrailer: 4-byte align + header + TRAILER!!! + NUL + align

압축 여부와 archive 내부 구성의 계층을 정리했습니다.

cpio_header 구조와 field 규칙

55-103

`cpio_header`의 모든 field는 field width 전체를 왼쪽의 `0`으로 채운 hexadecimal ASCII number입니다. 예를 들어 integer 4780은 ASCII string `000012ac`로 표현합니다.

============= ================== ==============================================
Field name    Field size         Meaning
============= ================== ==============================================
c_magic              6 bytes                 The string "070701" or "070702"
c_ino              8 bytes                 File inode number
c_mode              8 bytes                 File mode and permissions
c_uid              8 bytes                 File uid
c_gid              8 bytes                 File gid
c_nlink              8 bytes                 Number of links
c_mtime              8 bytes                 Modification time
c_filesize    8 bytes                 Size of data field
c_maj              8 bytes                 Major part of file device number
c_min              8 bytes                 Minor part of file device number
c_rmaj              8 bytes                 Major part of device node reference
c_rmin              8 bytes                 Minor part of device node reference
c_namesize    8 bytes                 Length of filename, including final \0
c_chksum      8 bytes                 Checksum of data field if c_magic is 070702;
                                 otherwise zero
============= ================== ==============================================

`c_magic`은 `070701` 또는 `070702`이고, `c_ino`는 inode number, `c_mode`는 file type·mode·permission, `c_uid`와 `c_gid`는 owner ID, `c_nlink`는 link count, `c_mtime`은 modification time, `c_filesize`는 data field 크기입니다.

`c_maj`와 `c_min`은 file device number의 major/minor 부분이고, `c_rmaj`와 `c_rmin`은 device node reference의 major/minor 부분입니다. `c_namesize`는 마지막 `\0`을 포함한 filename 길이이며, `c_chksum`은 `c_magic`이 `070702`일 때 data field checksum이고 그 외에는 0입니다.

`c_mode`는 Linux의 `stat(2)`가 반환하는 `st_mode` 내용과 일치하며 file type과 permission을 encode합니다. `c_mtime`은 `CONFIG_INITRAMFS_PRESERVE_MTIME=y`가 아니면 무시됩니다.

regular file이나 symlink가 아닌 file의 `c_filesize`는 0이어야 합니다. `c_namesize`는 `PATH_MAX`를 넘지 않는 한 trailing `\0`을 둘 이상 포함할 수 있습니다. 이를 이용해 뒤따르는 file data segment를 filesystem block boundary 같은 정렬 경계에 맞출 수 있습니다.

`c_chksum`은 data field의 모든 byte를 더한 단순 32-bit unsigned sum입니다. `cpio(1)`은 이를 `crc`라고 부르지만 cyclic redundancy check와는 다른, 훨씬 약한 방식입니다. 이름이 부정확해도 실제로 사용하는 algorithm은 이 합계입니다.

filename이 `TRAILER!!!`이면 실제 file이 아니라 end-of-archive marker이며, 이 marker의 `c_filesize`는 반드시 0이어야 합니다.

newc/crc cpio header field
Field크기의미
c_magic6 bytes070701 또는 070702
c_ino8 bytesfile inode number
c_mode8 bytesfile type, mode, permissions
c_uid / c_gid각 8 bytesuser/group ID
c_nlink8 byteslink 개수
c_mtime8 bytesmodification time
c_filesize8 bytesdata field 크기
c_maj / c_min각 8 bytesfile device number
c_rmaj / c_rmin각 8 bytesdevice node reference
c_namesize8 bytes마지막 NUL을 포함한 filename 길이
c_chksum8 bytes070702 data의 32-bit byte sum

모든 field는 hexadecimal ASCII이며 magic만 6 bytes, 나머지는 8 bytes입니다.

서로 다른 source의 file data 결합

124-132

서로 다른 source의 file data를 `(c_maj,c_min,c_ino)` field 재생성 없이 결합하려면 두 방법 중 하나를 사용합니다.

  • 서로 다른 file data source 사이에 `TRAILER!!!` end-of-archive marker를 둡니다.
  • 모든 nondirectory entry에서 `c_nlink == 1`이 되도록 보장합니다.