← Documents Documentation/filesystems/romfs.rst GitHub 원문 ↗

Linux 6.18.37 · Filesystems

ROMFS - ROM File System

ROMFS의 big-endian 온디스크 header, type mapping과 정렬 규칙의 전문 번역입니다.

Source pathDocumentation/filesystems/romfs.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

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

1. 요약·해설

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

요약·해설

romfs.rst:1-194

ROMFS는 초기 RAM disk와 read-only media를 위한 약 4KB 규모의 단순 파일시스템이다. 모든 구조를 16-byte boundary에 놓고 big-endian longword와 단순 checksum을 사용해 작은 kernel이 나머지 module을 늦게 적재하게 한다.

Parser는 `-rom1fs-` magic, full size, 첫 512바이트 checksum, volume name을 검증한 뒤 정렬된 file header를 따라가야 한다. Next pointer의 하위 bit에는 type과 executable 정보가 들어가며 `spec.info` 의미는 type마다 다르다.

ROMFS 탐색
Magic·full size·checksum 확인Volume name 뒤 16-byte 정렬`next filehdr`와 mode bit 분리Type별 `spec.info` 해석Padded name 뒤 regular/symlink data 읽기

Filesystem header에서 정렬된 file chain과 data로 이동한다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3 =======================
4 ROMFS - ROM File System
5 =======================
6
7 This is a quite dumb, read only filesystem, mainly for initial RAM
8 disks of installation disks. It has grown up by the need of having
9 modules linked at boot time. Using this filesystem, you get a very
10 similar feature, and even the possibility of a small kernel, with a
11 file system which doesn't take up useful memory from the router
12 functions in the basement of your office.
13
14 For comparison, both the older minix and xiafs (the latter is now
15 defunct) filesystems, compiled as module need more than 20000 bytes,
16 while romfs is less than a page, about 4000 bytes (assuming i586
17 code). Under the same conditions, the msdos filesystem would need
18 about 30K (and does not support device nodes or symlinks), while the
19 nfs module with nfsroot is about 57K. Furthermore, as a bit unfair
20 comparison, an actual rescue disk used up 3202 blocks with ext2, while
21 with romfs, it needed 3079 blocks.
22
23 To create such a file system, you'll need a user program named
24 genromfs. It is available on http://romfs.sourceforge.net/
25
26 As the name suggests, romfs could be also used (space-efficiently) on
27 various read-only media, like (E)EPROM disks if someone will have the
28 motivation.. :)
29
30 However, the main purpose of romfs is to have a very small kernel,
31 which has only this filesystem linked in, and then can load any module
32 later, with the current module utilities. It can also be used to run
33 some program to decide if you need SCSI devices, and even IDE or
34 floppy drives can be loaded later if you use the "initrd"--initial
35 RAM disk--feature of the kernel. This would not be really news
36 flash, but with romfs, you can even spare off your ext2 or minix or
37 maybe even affs filesystem until you really know that you need it.
38
39 For example, a distribution boot disk can contain only the cd disk
40 drivers (and possibly the SCSI drivers), and the ISO 9660 filesystem
41 module. The kernel can be small enough, since it doesn't have other
42 filesystems, like the quite large ext2fs module, which can then be
43 loaded off the CD at a later stage of the installation. Another use
44 would be for a recovery disk, when you are reinstalling a workstation
45 from the network, and you will have all the tools/modules available
46 from a nearby server, so you don't want to carry two disks for this
47 purpose, just because it won't fit into ext2.
48
49 romfs operates on block devices as you can expect, and the underlying
50 structure is very simple. Every accessible structure begins on 16
51 byte boundaries for fast access. The minimum space a file will take
52 is 32 bytes (this is an empty file, with a less than 16 character
53 name). The maximum overhead for any non-empty file is the header, and
54 the 16 byte padding for the name and the contents, also 16+14+15 = 45
55 bytes. This is quite rare however, since most file names are longer
56 than 3 bytes, and shorter than 15 bytes.
57
58 The layout of the filesystem is the following::
59
60 offset content
61
62 +---+---+---+---+
63 0 | - | r | o | m | \
64 +---+---+---+---+ The ASCII representation of those bytes
65 4 | 1 | f | s | - | / (i.e. "-rom1fs-")
66 +---+---+---+---+
67 8 | full size | The number of accessible bytes in this fs.
68 +---+---+---+---+
69 12 | checksum | The checksum of the FIRST 512 BYTES.
70 +---+---+---+---+
71 16 | volume name | The zero terminated name of the volume,
72 : : padded to 16 byte boundary.
73 +---+---+---+---+
74 xx | file |
75 : headers :
76
77 Every multi byte value (32 bit words, I'll use the longwords term from
78 now on) must be in big endian order.
79
80 The first eight bytes identify the filesystem, even for the casual
81 inspector. After that, in the 3rd longword, it contains the number of
82 bytes accessible from the start of this filesystem. The 4th longword
83 is the checksum of the first 512 bytes (or the number of bytes
84 accessible, whichever is smaller). The applied algorithm is the same
85 as in the AFFS filesystem, namely a simple sum of the longwords
86 (assuming bigendian quantities again). For details, please consult
87 the source. This algorithm was chosen because although it's not quite
88 reliable, it does not require any tables, and it is very simple.
89
90 The following bytes are now part of the file system; each file header
91 must begin on a 16 byte boundary::
92
93 offset content
94
95 +---+---+---+---+
96 0 | next filehdr|X| The offset of the next file header
97 +---+---+---+---+ (zero if no more files)
98 4 | spec.info | Info for directories/hard links/devices
99 +---+---+---+---+
100 8 | size | The size of this file in bytes
101 +---+---+---+---+
102 12 | checksum | Covering the meta data, including the file
103 +---+---+---+---+ name, and padding
104 16 | file name | The zero terminated name of the file,
105 : : padded to 16 byte boundary
106 +---+---+---+---+
107 xx | file data |
108 : :
109
110 Since the file headers begin always at a 16 byte boundary, the lowest
111 4 bits would be always zero in the next filehdr pointer. These four
112 bits are used for the mode information. Bits 0..2 specify the type of
113 the file; while bit 4 shows if the file is executable or not. The
114 permissions are assumed to be world readable, if this bit is not set,
115 and world executable if it is; except the character and block devices,
116 they are never accessible for other than owner. The owner of every
117 file is user and group 0, this should never be a problem for the
118 intended use. The mapping of the 8 possible values to file types is
119 the following:
120
121 == =============== ============================================
122 mapping spec.info means
123 == =============== ============================================
124 0 hard link link destination [file header]
125 1 directory first file's header
126 2 regular file unused, must be zero [MBZ]
127 3 symbolic link unused, MBZ (file data is the link content)
128 4 block device 16/16 bits major/minor number
129 5 char device - " -
130 6 socket unused, MBZ
131 7 fifo unused, MBZ
132 == =============== ============================================
133
134 Note that hard links are specifically marked in this filesystem, but
135 they will behave as you can expect (i.e. share the inode number).
136 Note also that it is your responsibility to not create hard link
137 loops, and creating all the . and .. links for directories. This is
138 normally done correctly by the genromfs program. Please refrain from
139 using the executable bits for special purposes on the socket and fifo
140 special files, they may have other uses in the future. Additionally,
141 please remember that only regular files, and symlinks are supposed to
142 have a nonzero size field; they contain the number of bytes available
143 directly after the (padded) file name.
144
145 Another thing to note is that romfs works on file headers and data
146 aligned to 16 byte boundaries, but most hardware devices and the block
147 device drivers are unable to cope with smaller than block-sized data.
148 To overcome this limitation, the whole size of the file system must be
149 padded to an 1024 byte boundary.
150
151 If you have any problems or suggestions concerning this file system,
152 please contact me. However, think twice before wanting me to add
153 features and code, because the primary and most important advantage of
154 this file system is the small code. On the other hand, don't be
155 alarmed, I'm not getting that much romfs related mail. Now I can
156 understand why Avery wrote poems in the ARCnet docs to get some more
157 feedback. :)
158
159 romfs has also a mailing list, and to date, it hasn't received any
160 traffic, so you are welcome to join it to discuss your ideas. :)
161
162 It's run by ezmlm, so you can subscribe to it by sending a message
163 to [email protected], the content is irrelevant.
164
165 Pending issues:
166
167 - Permissions and owner information are pretty essential features of a
168 Un*x like system, but romfs does not provide the full possibilities.
169 I have never found this limiting, but others might.
170
171 - The file system is read only, so it can be very small, but in case
172 one would want to write _anything_ to a file system, he still needs
173 a writable file system, thus negating the size advantages. Possible
174 solutions: implement write access as a compile-time option, or a new,
175 similarly small writable filesystem for RAM disks.
176
177 - Since the files are only required to have alignment on a 16 byte
178 boundary, it is currently possibly suboptimal to read or execute files
179 from the filesystem. It might be resolved by reordering file data to
180 have most of it (i.e. except the start and the end) laying at "natural"
181 boundaries, thus it would be possible to directly map a big portion of
182 the file contents to the mm subsystem.
183
184 - Compression might be an useful feature, but memory is quite a
185 limiting factor in my eyes.
186
187 - Where it is used?
188
189 - Does it work on other architectures than intel and motorola?
190
191
192 Have fun,
193
194 Janos Farkas <[email protected]>
195

3. 한국어 전문 번역

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

ROMFS의 목적과 크기

1-56

ROMFS는 주로 설치 디스크의 초기 RAM disk를 위한 매우 단순한 read-only 파일시스템이다. Boot 때 module을 연결해야 한다는 요구에서 만들어졌으며, 작은 kernel이 처음에는 ROMFS만 내장하고 나중에 필요한 module을 올릴 수 있게 한다.

i586 코드를 가정하면 module로 빌드한 minix와 xiafs는 20,000바이트보다 크지만 ROMFS는 page 하나보다 작은 약 4,000바이트다. 같은 조건의 msdos는 약 30KB이면서 device node와 symlink를 지원하지 않고, nfsroot를 포함한 NFS module은 약 57KB다. 실제 rescue disk 예시는 ext2 3202 block, ROMFS 3079 block을 사용했다.

파일시스템 이미지는 `genromfs` userspace 도구로 만들며 원문은 `http://romfs.sourceforge.net/`을 제공한다. 이름처럼 EEPROM 같은 read-only media에서도 공간 효율적으로 쓸 수 있다.

핵심 용도는 작은 kernel이 boot한 뒤 현재 module utility로 SCSI·IDE·floppy·일반 filesystem driver를 필요할 때만 올리는 것이다. 배포판 boot disk는 CD·SCSI driver와 ISO 9660 module만 포함하고 큰 ext2fs는 설치 후 CD에서 읽을 수 있다. Network recovery에서도 모든 tool과 module을 server에서 받으므로 별도 disk를 줄일 수 있다.

ROMFS는 block device에서 동작하며 접근 가능한 모든 구조가 빠른 접근을 위해 16-byte boundary에서 시작한다. 16자보다 짧은 이름의 빈 파일 최소 크기는 32바이트다. Non-empty 파일의 최대 overhead는 header 16, 이름 관련 14, 이름과 content padding 15를 합친 45바이트지만 일반 이름 길이에서는 드물다.

ROMFS가 줄이는 초기 부팅 비용
구성대략적 크기·효과
ROMFS module약 4KB, 한 page 미만
Minix/Xiafs module20KB 초과
MSDOS module약 30KB, device node·symlink 없음
NFS+nfsroot약 57KB
Rescue imageext2 3202 block 대 ROMFS 3079 block

작은 read-only driver로 나머지 storage stack을 늦게 적재한다.

.. SPDX-License-Identifier: GPL-2.0

=======================
ROMFS - ROM File System
=======================

This is a quite dumb, read only filesystem, mainly for initial RAM
disks of installation disks.  It has grown up by the need of having
modules linked at boot time.  Using this filesystem, you get a very
similar feature, and even the possibility of a small kernel, with a
file system which doesn't take up useful memory from the router
functions in the basement of your office.

For comparison, both the older minix and xiafs (the latter is now
defunct) filesystems, compiled as module need more than 20000 bytes,
while romfs is less than a page, about 4000 bytes (assuming i586
code).  Under the same conditions, the msdos filesystem would need
about 30K (and does not support device nodes or symlinks), while the
nfs module with nfsroot is about 57K.  Furthermore, as a bit unfair
comparison, an actual rescue disk used up 3202 blocks with ext2, while
with romfs, it needed 3079 blocks.

To create such a file system, you'll need a user program named
genromfs. It is available on http://romfs.sourceforge.net/

As the name suggests, romfs could be also used (space-efficiently) on
various read-only media, like (E)EPROM disks if someone will have the
motivation.. :)

However, the main purpose of romfs is to have a very small kernel,
which has only this filesystem linked in, and then can load any module
later, with the current module utilities.  It can also be used to run
some program to decide if you need SCSI devices, and even IDE or
floppy drives can be loaded later if you use the "initrd"--initial
RAM disk--feature of the kernel.  This would not be really news
flash, but with romfs, you can even spare off your ext2 or minix or
maybe even affs filesystem until you really know that you need it.

For example, a distribution boot disk can contain only the cd disk
drivers (and possibly the SCSI drivers), and the ISO 9660 filesystem
module.  The kernel can be small enough, since it doesn't have other
filesystems, like the quite large ext2fs module, which can then be
loaded off the CD at a later stage of the installation.  Another use
would be for a recovery disk, when you are reinstalling a workstation
from the network, and you will have all the tools/modules available
from a nearby server, so you don't want to carry two disks for this
purpose, just because it won't fit into ext2.

romfs operates on block devices as you can expect, and the underlying
structure is very simple.  Every accessible structure begins on 16
byte boundaries for fast access.  The minimum space a file will take
is 32 bytes (this is an empty file, with a less than 16 character
name).  The maximum overhead for any non-empty file is the header, and
the 16 byte padding for the name and the contents, also 16+14+15 = 45
bytes.  This is quite rare however, since most file names are longer
than 3 bytes, and shorter than 15 bytes.

Filesystem header와 checksum

57-111
ROMFS filesystem header
Offset크기내용
08 bytesASCII magic `-rom1fs-`
84 bytesFilesystem 시작부터 접근 가능한 전체 byte 수
124 bytes첫 512바이트 또는 전체 크기 중 작은 범위의 checksum
16가변NUL 종료 volume name, 16-byte boundary까지 padding
`xx`가변이어지는 file header들

원문의 ASCII layout을 offset별 구조로 옮겼다.

모든 multi-byte 값, 즉 32-bit longword는 big-endian 순서다. 첫 8바이트는 사람이 보아도 파일시스템을 식별할 magic이다. 셋째 longword가 접근 가능 byte 수, 넷째가 checksum이다.

Checksum은 AFFS와 같은 방식으로 big-endian longword를 단순 합산한다. 신뢰성이 높지는 않지만 table이 필요 없고 구현이 매우 단순해 선택됐다. 자세한 알고리즘은 source를 참고한다.

ROMFS image 판독
Offset 0의 `-rom1fs-` 확인Offset 8의 big-endian full size 읽기`min(512, full size)` 범위 longword 합 검증NUL 종료 volume name 읽기16-byte boundary로 정렬해 file header 순회

Magic과 길이·checksum을 검증한 뒤 정렬된 첫 file header로 이동한다.


The layout of the filesystem is the following::

 offset            content

        +---+---+---+---+
  0        | - | r | o | m |  \
        +---+---+---+---+        The ASCII representation of those bytes
  4        | 1 | f | s | - |  /        (i.e. "-rom1fs-")
        +---+---+---+---+
  8        |   full size        |        The number of accessible bytes in this fs.
        +---+---+---+---+
 12        |    checksum        |        The checksum of the FIRST 512 BYTES.
        +---+---+---+---+
 16        | volume name        |        The zero terminated name of the volume,
        :               :        padded to 16 byte boundary.
        +---+---+---+---+
 xx        |     file        |
        :    headers        :

Every multi byte value (32 bit words, I'll use the longwords term from
now on) must be in big endian order.

The first eight bytes identify the filesystem, even for the casual
inspector.  After that, in the 3rd longword, it contains the number of
bytes accessible from the start of this filesystem.  The 4th longword
is the checksum of the first 512 bytes (or the number of bytes
accessible, whichever is smaller).  The applied algorithm is the same
as in the AFFS filesystem, namely a simple sum of the longwords
(assuming bigendian quantities again).  For details, please consult
the source.  This algorithm was chosen because although it's not quite
reliable, it does not require any tables, and it is very simple.

The following bytes are now part of the file system; each file header
must begin on a 16 byte boundary::

 offset            content

             +---+---+---+---+
  0        | next filehdr|X|        The offset of the next file header
        +---+---+---+---+          (zero if no more files)
  4        |   spec.info        |        Info for directories/hard links/devices
        +---+---+---+---+
  8        |     size      |        The size of this file in bytes
        +---+---+---+---+
 12        |   checksum        |        Covering the meta data, including the file
        +---+---+---+---+          name, and padding
 16        | file name     |        The zero terminated name of the file,
        :               :        padded to 16 byte boundary
        +---+---+---+---+
 xx        | file data        |
        :                :

Since the file headers begin always at a 16 byte boundary, the lowest
4 bits would be always zero in the next filehdr pointer.  These four

File header·type·spec.info

112-162
ROMFS file header
Offset내용
0`next filehdr | X`; 다음 header offset, 0이면 끝, 하위 bit는 mode
4`spec.info`; directory·hard link·device별 의미
8File size in bytes
12File name과 padding을 포함한 metadata checksum
16NUL 종료 file name, 16-byte padding
`xx`File data

모든 file header와 data는 16-byte boundary에 맞춘다.

File header가 항상 16-byte boundary에 있으므로 next pointer의 하위 4 bit는 원래 0이다. 이 bit를 mode 정보로 재사용한다. Bit 0..2는 file type, 원문이 말하는 bit 4는 executable 여부를 나타낸다.

기본 permission은 world-readable이고 executable bit가 있으면 world-executable이다. Character와 block device는 owner 외 접근할 수 없다. 모든 파일의 owner와 group은 0이다.

ROMFS type mapping
Type`spec.info`
0hard link대상 file header
1directory첫 file header
2regular file미사용, 0이어야 함(MBZ)
3symbolic link미사용·MBZ; file data가 link 내용
4block device상위/하위 16 bit major/minor
5character device상위/하위 16 bit major/minor
6socket미사용·MBZ
7fifo미사용·MBZ

3-bit type 값과 `spec.info`의 전체 의미다.

Hard link는 명시적으로 표시되지만 예상대로 inode 번호를 공유한다. Hard link loop를 만들지 않고 directory의 `.`와 `..` link를 모두 만드는 책임은 image 생성자에게 있으며 `genromfs`가 보통 정확히 처리한다.

Socket과 fifo의 executable bit는 미래 용도가 있을 수 있으므로 특별한 의미로 재사용하면 안 된다. Regular file과 symlink만 nonzero size를 가져야 하며, padded file name 직후의 실제 byte 수를 뜻한다.

bits are used for the mode information.  Bits 0..2 specify the type of
the file; while bit 4 shows if the file is executable or not.  The
permissions are assumed to be world readable, if this bit is not set,
and world executable if it is; except the character and block devices,
they are never accessible for other than owner.  The owner of every
file is user and group 0, this should never be a problem for the
intended use.  The mapping of the 8 possible values to file types is
the following:

==        =============== ============================================
          mapping                spec.info means
==        =============== ============================================
 0        hard link        link destination [file header]
 1        directory        first file's header
 2        regular file        unused, must be zero [MBZ]
 3        symbolic link        unused, MBZ (file data is the link content)
 4        block device        16/16 bits major/minor number
 5        char device                    - " -
 6        socket                unused, MBZ
 7        fifo                unused, MBZ
==        =============== ============================================

Note that hard links are specifically marked in this filesystem, but
they will behave as you can expect (i.e. share the inode number).
Note also that it is your responsibility to not create hard link
loops, and creating all the . and .. links for directories.  This is
normally done correctly by the genromfs program.  Please refrain from
using the executable bits for special purposes on the socket and fifo
special files, they may have other uses in the future.  Additionally,
please remember that only regular files, and symlinks are supposed to
have a nonzero size field; they contain the number of bytes available
directly after the (padded) file name.

Another thing to note is that romfs works on file headers and data
aligned to 16 byte boundaries, but most hardware devices and the block
device drivers are unable to cope with smaller than block-sized data.
To overcome this limitation, the whole size of the file system must be
padded to an 1024 byte boundary.

If you have any problems or suggestions concerning this file system,
please contact me.  However, think twice before wanting me to add
features and code, because the primary and most important advantage of
this file system is the small code.  On the other hand, don't be
alarmed, I'm not getting that much romfs related mail.  Now I can
understand why Avery wrote poems in the ARCnet docs to get some more
feedback. :)

romfs has also a mailing list, and to date, it hasn't received any
traffic, so you are welcome to join it to discuss your ideas. :)

It's run by ezmlm, so you can subscribe to it by sending a message

Image padding과 남은 과제

163-194

ROMFS 내부 header와 data는 16-byte 정렬이지만 많은 hardware device와 block driver는 block보다 작은 I/O를 처리하지 못한다. 이를 보완하려면 전체 filesystem 크기를 1024-byte boundary까지 padding해야 한다.

기능 추가를 제안할 때는 ROMFS의 가장 중요한 장점이 작은 코드라는 점을 고려해야 한다. 원문은 ROMFS mailing list 가입 주소로 `[email protected]`를 기록한다.

Pending issue
과제설명
Permission·ownerUnix의 전체 permission 모델을 제공하지 않음
Write 지원Read-only라 작은 대신 write가 필요하면 별도 writable FS가 필요
16-byte alignment직접 mapping에 자연스러운 hardware boundary보다 작을 수 있음
Compression유용할 수 있지만 memory 제약이 큼
사용 현황실제 배포 위치에 대한 질문
ArchitectureIntel·Motorola 외 동작 검증 질문

원문이 남긴 기능·성능·이식성 질문이다.

쓰기 해법으로 compile-time 옵션이나 RAM disk용의 비슷하게 작은 writable filesystem을 제안한다. 읽기·실행 성능은 file data 대부분을 자연 정렬 경계에 재배치해 mm subsystem에 직접 mapping하는 방식으로 개선할 수 있다.

to [email protected], the content is irrelevant.

Pending issues:

- Permissions and owner information are pretty essential features of a
  Un*x like system, but romfs does not provide the full possibilities.
  I have never found this limiting, but others might.

- The file system is read only, so it can be very small, but in case
  one would want to write _anything_ to a file system, he still needs
  a writable file system, thus negating the size advantages.  Possible
  solutions: implement write access as a compile-time option, or a new,
  similarly small writable filesystem for RAM disks.

- Since the files are only required to have alignment on a 16 byte
  boundary, it is currently possibly suboptimal to read or execute files
  from the filesystem.  It might be resolved by reordering file data to
  have most of it (i.e. except the start and the end) laying at "natural"
  boundaries, thus it would be possible to directly map a big portion of
  the file contents to the mm subsystem.

- Compression might be an useful feature, but memory is quite a
  limiting factor in my eyes.

- Where it is used?

- Does it work on other architectures than intel and motorola?


Have fun,

Janos Farkas <[email protected]>