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

Linux 6.18.37 · Driver API

Early userspace support

gen_init_cpio, initramfs, klibc와 CONFIG_INITRAMFS_SOURCE 기반 image 생성 및 root 전환을 설명합니다.

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

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

1. 요약·해설

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

요약과 해설

early_userspace_support.rst:1-154

early userspace는 kernel 밖에서 boot 초기 기능을 수행하도록 root filesystem CPIO image를 만들고 unpack합니다. 기존 archive를 직접 쓰거나 directory와 directive file을 조합해 unprivileged build에서도 root-owned·device-special entry를 포함할 수 있습니다.

initramfs 방식에서는 archive에서 온 `/init`이 `prepare_namespace()`의 역할을 대신합니다. klibc의 ipconfig, nfsmount, kinit 또는 custom ash 환경이 network root와 초기 boot logic을 담당할 수 있습니다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 =======================
2 Early userspace support
3 =======================
4
5 Last update: 2004-12-20 tlh
6
7
8 "Early userspace" is a set of libraries and programs that provide
9 various pieces of functionality that are important enough to be
10 available while a Linux kernel is coming up, but that don't need to be
11 run inside the kernel itself.
12
13 It consists of several major infrastructure components:
14
15 - gen_init_cpio, a program that builds a cpio-format archive
16 containing a root filesystem image. This archive is compressed, and
17 the compressed image is linked into the kernel image.
18 - initramfs, a chunk of code that unpacks the compressed cpio image
19 midway through the kernel boot process.
20 - klibc, a userspace C library, currently packaged separately, that is
21 optimized for correctness and small size.
22
23 The cpio file format used by initramfs is the "newc" (aka "cpio -H newc")
24 format, and is documented in the file "buffer-format.txt". There are
25 two ways to add an early userspace image: specify an existing cpio
26 archive to be used as the image or have the kernel build process build
27 the image from specifications.
28
29 CPIO ARCHIVE method
30 -------------------
31
32 You can create a cpio archive that contains the early userspace image.
33 Your cpio archive should be specified in CONFIG_INITRAMFS_SOURCE and it
34 will be used directly. Only a single cpio file may be specified in
35 CONFIG_INITRAMFS_SOURCE and directory and file names are not allowed in
36 combination with a cpio archive.
37
38 IMAGE BUILDING method
39 ---------------------
40
41 The kernel build process can also build an early userspace image from
42 source parts rather than supplying a cpio archive. This method provides
43 a way to create images with root-owned files even though the image was
44 built by an unprivileged user.
45
46 The image is specified as one or more sources in
47 CONFIG_INITRAMFS_SOURCE. Sources can be either directories or files -
48 cpio archives are *not* allowed when building from sources.
49
50 A source directory will have it and all of its contents packaged. The
51 specified directory name will be mapped to '/'. When packaging a
52 directory, limited user and group ID translation can be performed.
53 INITRAMFS_ROOT_UID can be set to a user ID that needs to be mapped to
54 user root (0). INITRAMFS_ROOT_GID can be set to a group ID that needs
55 to be mapped to group root (0).
56
57 A source file must be directives in the format required by the
58 usr/gen_init_cpio utility (run 'usr/gen_init_cpio -h' to get the
59 file format). The directives in the file will be passed directly to
60 usr/gen_init_cpio.
61
62 When a combination of directories and files are specified then the
63 initramfs image will be an aggregate of all of them. In this way a user
64 can create a 'root-image' directory and install all files into it.
65 Because device-special files cannot be created by a unprivileged user,
66 special files can be listed in a 'root-files' file. Both 'root-image'
67 and 'root-files' can be listed in CONFIG_INITRAMFS_SOURCE and a complete
68 early userspace image can be built by an unprivileged user.
69
70 As a technical note, when directories and files are specified, the
71 entire CONFIG_INITRAMFS_SOURCE is passed to
72 usr/gen_initramfs.sh. This means that CONFIG_INITRAMFS_SOURCE
73 can really be interpreted as any legal argument to
74 gen_initramfs.sh. If a directory is specified as an argument then
75 the contents are scanned, uid/gid translation is performed, and
76 usr/gen_init_cpio file directives are output. If a directory is
77 specified as an argument to usr/gen_initramfs.sh then the
78 contents of the file are simply copied to the output. All of the output
79 directives from directory scanning and file contents copying are
80 processed by usr/gen_init_cpio.
81
82 See also 'usr/gen_initramfs.sh -h'.
83
84 Where's this all leading?
85 =========================
86
87 The klibc distribution contains some of the necessary software to make
88 early userspace useful. The klibc distribution is currently
89 maintained separately from the kernel.
90
91 You can obtain somewhat infrequent snapshots of klibc from
92 https://www.kernel.org/pub/linux/libs/klibc/
93
94 For active users, you are better off using the klibc git
95 repository, at https://git.kernel.org/?p=libs/klibc/klibc.git
96
97 The standalone klibc distribution currently provides three components,
98 in addition to the klibc library:
99
100 - ipconfig, a program that configures network interfaces. It can
101 configure them statically, or use DHCP to obtain information
102 dynamically (aka "IP autoconfiguration").
103 - nfsmount, a program that can mount an NFS filesystem.
104 - kinit, the "glue" that uses ipconfig and nfsmount to replace the old
105 support for IP autoconfig, mount a filesystem over NFS, and continue
106 system boot using that filesystem as root.
107
108 kinit is built as a single statically linked binary to save space.
109
110 Eventually, several more chunks of kernel functionality will hopefully
111 move to early userspace:
112
113 - Almost all of init/do_mounts* (the beginning of this is already in
114 place)
115 - ACPI table parsing
116 - Insert unwieldy subsystem that doesn't really need to be in kernel
117 space here
118
119 If kinit doesn't meet your current needs and you've got bytes to burn,
120 the klibc distribution includes a small Bourne-compatible shell (ash)
121 and a number of other utilities, so you can replace kinit and build
122 custom initramfs images that meet your needs exactly.
123
124 For questions and help, you can sign up for the early userspace
125 mailing list at https://www.zytor.com/mailman/listinfo/klibc
126
127 How does it work?
128 =================
129
130 The kernel has currently 3 ways to mount the root filesystem:
131
132 a) all required device and filesystem drivers compiled into the kernel, no
133 initrd. init/main.c:init() will call prepare_namespace() to mount the
134 final root filesystem, based on the root= option and optional init= to run
135 some other init binary than listed at the end of init/main.c:init().
136
137 b) some device and filesystem drivers built as modules and stored in an
138 initrd. The initrd must contain a binary '/linuxrc' which is supposed to
139 load these driver modules. It is also possible to mount the final root
140 filesystem via linuxrc and use the pivot_root syscall. The initrd is
141 mounted and executed via prepare_namespace().
142
143 c) using initramfs. The call to prepare_namespace() must be skipped.
144 This means that a binary must do all the work. Said binary can be stored
145 into initramfs either via modifying usr/gen_init_cpio.c or via the new
146 initrd format, an cpio archive. It must be called "/init". This binary
147 is responsible to do all the things prepare_namespace() would do.
148
149 To maintain backwards compatibility, the /init binary will only run if it
150 comes via an initramfs cpio archive. If this is not the case,
151 init/main.c:init() will run prepare_namespace() to mount the final root
152 and exec one of the predefined init binaries.
153
154 Bryan O'Sullivan <[email protected]>
155

3. 한국어 전문 번역

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

Early userspace 개요와 구성 요소

1-28

문서 제목은 `Early userspace support`이며 마지막 갱신 표기는 `Last update: 2004-12-20 tlh`입니다.

early userspace는 Linux kernel이 올라오는 동안 사용할 만큼 중요하지만 kernel 내부에서 실행할 필요는 없는 기능을 제공하는 library와 program 집합입니다.

주요 infrastructure component는 세 가지입니다.

  • `gen_init_cpio`: root filesystem image를 담는 cpio-format archive를 만드는 program입니다. archive를 압축하고 그 image를 kernel image에 link합니다.
  • `initramfs`: kernel boot 중간에 압축된 cpio image를 unpack하는 code입니다.
  • `klibc`: correctness와 작은 크기에 최적화된 userspace C library이며 현재 별도 package로 유지됩니다.

initramfs가 사용하는 cpio format은 `newc`, 즉 `cpio -H newc` format입니다. 원문은 이를 `buffer-format.txt`에 문서화했다고 표기합니다. early userspace image를 추가하는 방법은 기존 cpio archive를 지정하는 방법과 kernel build가 specification에서 image를 만들게 하는 방법 두 가지입니다.

Early userspace infrastructure
Component역할시점
gen_init_cpioroot filesystem cpio archive 생성kernel build
initramfs압축 cpio image unpackkernel boot 중간
klibc작고 정확한 userspace C runtimeearly userspace program 실행

archive 생성부터 boot 중 unpack, 실행 library까지의 역할입니다.

CPIO ARCHIVE 방식

29-37

early userspace image를 담은 cpio archive를 직접 만들 수 있습니다. 이 archive를 `CONFIG_INITRAMFS_SOURCE`에 지정하면 그대로 사용됩니다.

`CONFIG_INITRAMFS_SOURCE`에는 cpio file 하나만 지정할 수 있습니다. cpio archive와 directory 또는 file name을 함께 조합하는 것은 허용되지 않습니다.

IMAGE BUILDING 방식

38-83

kernel build process가 완성된 cpio archive 대신 source part에서 early userspace image를 만들 수도 있습니다. unprivileged user가 build해도 root-owned file이 들어간 image를 만들 수 있다는 장점이 있습니다.

`CONFIG_INITRAMFS_SOURCE`에 하나 이상의 source를 지정합니다. source는 directory 또는 file일 수 있지만 source에서 build할 때 cpio archive는 허용되지 않습니다.

source directory를 지정하면 해당 directory와 모든 contents가 package되며 지정 directory name은 `/`에 mapping됩니다. directory package 시 제한된 user/group ID translation을 수행할 수 있습니다. `INITRAMFS_ROOT_UID`는 user root(0)로 mapping할 user ID, `INITRAMFS_ROOT_GID`는 group root(0)로 mapping할 group ID입니다.

source file은 `usr/gen_init_cpio` utility가 요구하는 directive format이어야 합니다. format은 `usr/gen_init_cpio -h`로 확인하며, file의 directive는 `usr/gen_init_cpio`에 그대로 전달됩니다.

directory와 file을 함께 지정하면 모든 source를 합친 initramfs image가 만들어집니다. user는 일반 file을 설치한 `root-image` directory를 만들고, unprivileged user가 생성할 수 없는 device-special file은 `root-files` directive file에 적을 수 있습니다. 두 source를 `CONFIG_INITRAMFS_SOURCE`에 함께 나열하면 권한 없는 user도 완전한 early userspace image를 build할 수 있습니다.

기술적으로는 directory와 file을 지정할 때 `CONFIG_INITRAMFS_SOURCE` 전체가 `usr/gen_initramfs.sh`에 전달되므로 이 설정은 `gen_initramfs.sh`의 유효한 argument로 해석할 수 있습니다. directory argument는 contents를 scan하고 uid/gid translation을 수행한 뒤 `usr/gen_init_cpio` directive를 출력합니다. 이어지는 문장은 원문에서 다시 directory라고 표기하지만, file contents를 output에 단순 복사하는 source-file 경우를 설명합니다. directory scan과 file copy에서 나온 모든 directive를 `usr/gen_init_cpio`가 처리합니다.

추가 설명은 `usr/gen_initramfs.sh -h`를 참고하십시오.

CONFIG_INITRAMFS_SOURCE image build
root-image directory scanINITRAMFS_ROOT_UID/GID translationroot-files directive contents 복사gen_initramfs.sh가 모든 directive 집계usr/gen_init_cpio가 cpio archive 생성압축 후 kernel image에 link

directory와 directive file을 하나의 cpio image로 합치는 과정입니다.

klibc 배포 위치

84-96

klibc distribution은 early userspace를 유용하게 만드는 데 필요한 software 일부를 포함하며 현재 kernel과 별도로 유지됩니다.

비정기 snapshot은 `https://www.kernel.org/pub/linux/libs/klibc/`에서 받을 수 있습니다. 활발히 사용하는 경우에는 `https://git.kernel.org/?p=libs/klibc/klibc.git`의 klibc git repository를 쓰는 편이 낫습니다.

klibc program과 향후 이동 대상

97-126

standalone klibc distribution은 klibc library 외에 세 component를 제공합니다.

  • `ipconfig`: network interface를 static하게 설정하거나 DHCP로 정보를 동적으로 얻는 IP autoconfiguration program입니다.
  • `nfsmount`: NFS filesystem을 mount하는 program입니다.
  • `kinit`: ipconfig와 nfsmount를 묶어 기존 IP autoconfig 지원을 대체하고, NFS를 통해 filesystem을 mount한 뒤 이를 root로 사용해 system boot를 계속하는 glue입니다.

공간을 절약하기 위해 `kinit`은 하나의 statically linked binary로 build됩니다.

향후에는 더 많은 kernel 기능을 early userspace로 옮기기를 기대합니다.

  • `init/do_mounts*`의 거의 전부. 초기 작업은 이미 들어가 있습니다.
  • ACPI table parsing.
  • kernel space에 실제로 있을 필요가 없는 다루기 힘든 subsystem.

현재 요구에 `kinit`이 맞지 않고 사용할 여유 공간이 있다면 klibc의 작은 Bourne-compatible shell인 `ash`와 다른 utility를 사용해 kinit을 대체하고 정확한 요구에 맞춘 custom initramfs image를 만들 수 있습니다.

질문과 도움은 `https://www.zytor.com/mailman/listinfo/klibc`의 early userspace mailing list를 이용할 수 있습니다.

root filesystem을 mount하는 세 방식

127-154

kernel에는 현재 root filesystem을 mount하는 세 방식이 있습니다.

a) 필요한 모든 device·filesystem driver를 kernel에 compile하고 initrd를 쓰지 않습니다. `init/main.c:init()`이 `prepare_namespace()`를 호출해 `root=` option에 따라 최종 root filesystem을 mount합니다. 선택적 `init=`으로 `init/main.c:init()` 끝에 나열된 것과 다른 init binary를 실행할 수 있습니다.

b) 일부 device·filesystem driver를 module로 build해 initrd에 저장합니다. initrd에는 module을 load할 `/linuxrc` binary가 있어야 합니다. linuxrc에서 최종 root filesystem을 mount하고 `pivot_root` syscall을 사용할 수도 있습니다. initrd는 `prepare_namespace()`를 통해 mount되고 실행됩니다.

c) initramfs를 사용합니다. 이 경우 `prepare_namespace()` 호출을 건너뛰고 한 binary가 모든 작업을 해야 합니다. 그 binary는 `usr/gen_init_cpio.c`를 수정하거나 새 initrd format인 cpio archive를 사용해 initramfs에 저장할 수 있으며 반드시 `/init`이라는 이름이어야 합니다. `/init`은 `prepare_namespace()`가 할 모든 작업을 담당합니다.

backward compatibility를 위해 `/init` binary는 initramfs cpio archive를 통해 들어온 경우에만 실행됩니다. 그렇지 않으면 `init/main.c:init()`이 `prepare_namespace()`를 실행해 최종 root를 mount하고 미리 정의된 init binary 중 하나를 exec합니다.

문서 끝의 작성자 표기는 Bryan O'Sullivan `<[email protected]>`입니다.

Root filesystem boot 방식
방식driver 위치초기 binaryprepare_namespace()
a) built-inkernel 내부기본 init 또는 init=호출
b) initrdinitrd의 module/linuxrcmount와 실행에 사용
c) initramfscpio archive 내용/init건너뜀

driver 위치, 초기 binary와 prepare_namespace() 사용 여부를 비교합니다.