Commit | Line | Data |
---|---|---|
7b9b816f MH |
1 | .. SPDX-License-Identifier: GPL-2.0 |
2 | ||
47781947 MH |
3 | .. _bootconfig: |
4 | ||
7b9b816f MH |
5 | ================== |
6 | Boot Configuration | |
7 | ================== | |
8 | ||
9 | :Author: Masami Hiramatsu <mhiramat@kernel.org> | |
10 | ||
11 | Overview | |
12 | ======== | |
13 | ||
a4798eb4 MH |
14 | The boot configuration expands the current kernel command line to support |
15 | additional key-value data when booting the kernel in an efficient way. | |
16 | This allows administrators to pass a structured-Key config file. | |
7b9b816f MH |
17 | |
18 | Config File Syntax | |
19 | ================== | |
20 | ||
21 | The boot config syntax is a simple structured key-value. Each key consists | |
a4798eb4 | 22 | of dot-connected-words, and key and value are connected by ``=``. The value |
7b9b816f MH |
23 | has to be terminated by semi-colon (``;``) or newline (``\n``). |
24 | For array value, array entries are separated by comma (``,``). :: | |
25 | ||
2e5b1886 | 26 | KEY[.WORD[...]] = VALUE[, VALUE2[...]][;] |
7b9b816f | 27 | |
a4798eb4 MH |
28 | Unlike the kernel command line syntax, spaces are OK around the comma and ``=``. |
29 | ||
7b9b816f MH |
30 | Each key word must contain only alphabets, numbers, dash (``-``) or underscore |
31 | (``_``). And each value only contains printable characters or spaces except | |
32 | for delimiters such as semi-colon (``;``), new-line (``\n``), comma (``,``), | |
33 | hash (``#``) and closing brace (``}``). | |
34 | ||
35 | If you want to use those delimiters in a value, you can use either double- | |
36 | quotes (``"VALUE"``) or single-quotes (``'VALUE'``) to quote it. Note that | |
37 | you can not escape these quotes. | |
38 | ||
39 | There can be a key which doesn't have value or has an empty value. Those keys | |
a4798eb4 | 40 | are used for checking if the key exists or not (like a boolean). |
7b9b816f MH |
41 | |
42 | Key-Value Syntax | |
43 | ---------------- | |
44 | ||
45 | The boot config file syntax allows user to merge partially same word keys | |
46 | by brace. For example:: | |
47 | ||
48 | foo.bar.baz = value1 | |
49 | foo.bar.qux.quux = value2 | |
50 | ||
51 | These can be written also in:: | |
52 | ||
53 | foo.bar { | |
54 | baz = value1 | |
55 | qux.quux = value2 | |
56 | } | |
57 | ||
58 | Or more shorter, written as following:: | |
59 | ||
60 | foo.bar { baz = value1; qux.quux = value2 } | |
61 | ||
62 | In both styles, same key words are automatically merged when parsing it | |
63 | at boot time. So you can append similar trees or key-values. | |
64 | ||
4e4694d8 MH |
65 | Same-key Values |
66 | --------------- | |
67 | ||
68 | It is prohibited that two or more values or arrays share a same-key. | |
69 | For example,:: | |
70 | ||
71 | foo = bar, baz | |
72 | foo = qux # !ERROR! we can not re-define same key | |
73 | ||
c58b46cb MH |
74 | If you want to update the value, you must use the override operator |
75 | ``:=`` explicitly. For example:: | |
76 | ||
77 | foo = bar, baz | |
78 | foo := qux | |
79 | ||
80 | then, the ``qux`` is assigned to ``foo`` key. This is useful for | |
81 | overriding the default value by adding (partial) custom bootconfigs | |
82 | without parsing the default bootconfig. | |
83 | ||
5f811c57 MH |
84 | If you want to append the value to existing key as an array member, |
85 | you can use ``+=`` operator. For example:: | |
86 | ||
87 | foo = bar, baz | |
88 | foo += qux | |
89 | ||
90 | In this case, the key ``foo`` has ``bar``, ``baz`` and ``qux``. | |
91 | ||
0ff2bb7d MH |
92 | Moreover, sub-keys and a value can coexist under a parent key. |
93 | For example, following config is allowed.:: | |
a24d286f MH |
94 | |
95 | foo = value1 | |
0ff2bb7d MH |
96 | foo.bar = value2 |
97 | foo := value3 # This will update foo's value. | |
98 | ||
99 | Note, since there is no syntax to put a raw value directly under a | |
100 | structured key, you have to define it outside of the brace. For example:: | |
101 | ||
102 | foo { | |
103 | bar = value1 | |
104 | bar { | |
105 | baz = value2 | |
106 | qux = value3 | |
107 | } | |
108 | } | |
109 | ||
110 | Also, the order of the value node under a key is fixed. If there | |
111 | are a value and subkeys, the value is always the first child node | |
112 | of the key. Thus if user specifies subkeys first, e.g.:: | |
113 | ||
114 | foo.bar = value1 | |
115 | foo = value2 | |
116 | ||
117 | In the program (and /proc/bootconfig), it will be shown as below:: | |
a24d286f | 118 | |
0ff2bb7d MH |
119 | foo = value2 |
120 | foo.bar = value1 | |
a24d286f | 121 | |
7b9b816f MH |
122 | Comments |
123 | -------- | |
124 | ||
a4798eb4 | 125 | The config syntax accepts shell-script style comments. The comments starting |
7b9b816f MH |
126 | with hash ("#") until newline ("\n") will be ignored. |
127 | ||
128 | :: | |
129 | ||
130 | # comment line | |
131 | foo = value # value is set to foo. | |
132 | bar = 1, # 1st element | |
133 | 2, # 2nd element | |
134 | 3 # 3rd element | |
135 | ||
136 | This is parsed as below:: | |
137 | ||
138 | foo = value | |
139 | bar = 1, 2, 3 | |
140 | ||
141 | Note that you can not put a comment between value and delimiter(``,`` or | |
142 | ``;``). This means following config has a syntax error :: | |
143 | ||
144 | key = 1 # comment | |
145 | ,2 | |
146 | ||
147 | ||
148 | /proc/bootconfig | |
149 | ================ | |
150 | ||
151 | /proc/bootconfig is a user-space interface of the boot config. | |
152 | Unlike /proc/cmdline, this file shows the key-value style list. | |
153 | Each key-value pair is shown in each line with following style:: | |
154 | ||
155 | KEY[.WORDS...] = "[VALUE]"[,"VALUE2"...] | |
156 | ||
157 | ||
158 | Boot Kernel With a Boot Config | |
159 | ============================== | |
160 | ||
2f51efc6 MH |
161 | There are two options to boot the kernel with bootconfig: attaching the |
162 | bootconfig to the initrd image or embedding it in the kernel itself. | |
163 | ||
164 | Attaching a Boot Config to Initrd | |
165 | --------------------------------- | |
166 | ||
167 | Since the boot configuration file is loaded with initrd by default, | |
168 | it will be added to the end of the initrd (initramfs) image file with | |
169 | padding, size, checksum and 12-byte magic word as below. | |
85c46b78 | 170 | |
05227490 MH |
171 | [initrd][bootconfig][padding][size(le32)][checksum(le32)][#BOOTCONFIG\n] |
172 | ||
173 | The size and checksum fields are unsigned 32bit little endian value. | |
fbc6e1c6 MH |
174 | |
175 | When the boot configuration is added to the initrd image, the total | |
176 | file size is aligned to 4 bytes. To fill the gap, null characters | |
177 | (``\0``) will be added. Thus the ``size`` is the length of the bootconfig | |
178 | file + padding bytes. | |
85c46b78 MH |
179 | |
180 | The Linux kernel decodes the last part of the initrd image in memory to | |
181 | get the boot configuration data. | |
7b9b816f | 182 | Because of this "piggyback" method, there is no need to change or |
fbc6e1c6 MH |
183 | update the boot loader and the kernel image itself as long as the boot |
184 | loader passes the correct initrd file size. If by any chance, the boot | |
9d54ee78 | 185 | loader passes a longer size, the kernel fails to find the bootconfig data. |
7b9b816f | 186 | |
26c9c72f | 187 | To do this operation, Linux kernel provides ``bootconfig`` command under |
7b9b816f | 188 | tools/bootconfig, which allows admin to apply or delete the config file |
a4798eb4 | 189 | to/from initrd image. You can build it by the following command:: |
7b9b816f MH |
190 | |
191 | # make -C tools/bootconfig | |
192 | ||
193 | To add your boot config file to initrd image, run bootconfig as below | |
194 | (Old data is removed automatically if exists):: | |
195 | ||
196 | # tools/bootconfig/bootconfig -a your-config /boot/initrd.img-X.Y.Z | |
197 | ||
198 | To remove the config from the image, you can use -d option as below:: | |
199 | ||
200 | # tools/bootconfig/bootconfig -d /boot/initrd.img-X.Y.Z | |
201 | ||
7495e092 SRV |
202 | Then add "bootconfig" on the normal kernel command line to tell the |
203 | kernel to look for the bootconfig at the end of the initrd file. | |
b743852c PM |
204 | Alternatively, build your kernel with the ``CONFIG_BOOT_CONFIG_FORCE`` |
205 | Kconfig option selected. | |
7b9b816f | 206 | |
2f51efc6 MH |
207 | Embedding a Boot Config into Kernel |
208 | ----------------------------------- | |
209 | ||
210 | If you can not use initrd, you can also embed the bootconfig file in the | |
211 | kernel by Kconfig options. In this case, you need to recompile the kernel | |
212 | with the following configs:: | |
213 | ||
214 | CONFIG_BOOT_CONFIG_EMBED=y | |
215 | CONFIG_BOOT_CONFIG_EMBED_FILE="/PATH/TO/BOOTCONFIG/FILE" | |
216 | ||
217 | ``CONFIG_BOOT_CONFIG_EMBED_FILE`` requires an absolute path or a relative | |
218 | path to the bootconfig file from source tree or object tree. | |
219 | The kernel will embed it as the default bootconfig. | |
220 | ||
221 | Just as when attaching the bootconfig to the initrd, you need ``bootconfig`` | |
b743852c PM |
222 | option on the kernel command line to enable the embedded bootconfig, or, |
223 | alternatively, build your kernel with the ``CONFIG_BOOT_CONFIG_FORCE`` | |
224 | Kconfig option selected. | |
2f51efc6 MH |
225 | |
226 | Note that even if you set this option, you can override the embedded | |
227 | bootconfig by another bootconfig which attached to the initrd. | |
26c9c72f MH |
228 | |
229 | Kernel parameters via Boot Config | |
230 | ================================= | |
231 | ||
232 | In addition to the kernel command line, the boot config can be used for | |
233 | passing the kernel parameters. All the key-value pairs under ``kernel`` | |
234 | key will be passed to kernel cmdline directly. Moreover, the key-value | |
235 | pairs under ``init`` will be passed to init process via the cmdline. | |
e378cb9a | 236 | The parameters are concatenated with user-given kernel cmdline string |
26c9c72f MH |
237 | as the following order, so that the command line parameter can override |
238 | bootconfig parameters (this depends on how the subsystem handles parameters | |
239 | but in general, earlier parameter will be overwritten by later one.):: | |
240 | ||
241 | [bootconfig params][cmdline params] -- [bootconfig init params][cmdline init params] | |
242 | ||
243 | Here is an example of the bootconfig file for kernel/init parameters.:: | |
244 | ||
245 | kernel { | |
246 | root = 01234567-89ab-cdef-0123-456789abcd | |
247 | } | |
248 | init { | |
249 | splash | |
250 | } | |
251 | ||
252 | This will be copied into the kernel cmdline string as the following:: | |
253 | ||
254 | root="01234567-89ab-cdef-0123-456789abcd" -- splash | |
255 | ||
256 | If user gives some other command line like,:: | |
257 | ||
258 | ro bootconfig -- quiet | |
259 | ||
260 | The final kernel cmdline will be the following:: | |
261 | ||
262 | root="01234567-89ab-cdef-0123-456789abcd" ro bootconfig -- splash quiet | |
263 | ||
264 | ||
a4798eb4 | 265 | Config File Limitation |
7b9b816f MH |
266 | ====================== |
267 | ||
268 | Currently the maximum config size size is 32KB and the total key-words (not | |
269 | key-value entries) must be under 1024 nodes. | |
270 | Note: this is not the number of entries but nodes, an entry must consume | |
271 | more than 2 nodes (a key-word and a value). So theoretically, it will be | |
272 | up to 512 key-value pairs. If keys contains 3 words in average, it can | |
273 | contain 256 key-value pairs. In most cases, the number of config items | |
274 | will be under 100 entries and smaller than 8KB, so it would be enough. | |
275 | If the node number exceeds 1024, parser returns an error even if the file | |
fbc6e1c6 MH |
276 | size is smaller than 32KB. (Note that this maximum size is not including |
277 | the padding null characters.) | |
7b9b816f MH |
278 | Anyway, since bootconfig command verifies it when appending a boot config |
279 | to initrd image, user can notice it before boot. | |
280 | ||
281 | ||
282 | Bootconfig APIs | |
283 | =============== | |
284 | ||
285 | User can query or loop on key-value pairs, also it is possible to find | |
286 | a root (prefix) key node and find key-values under that node. | |
287 | ||
288 | If you have a key string, you can query the value directly with the key | |
a4798eb4 MH |
289 | using xbc_find_value(). If you want to know what keys exist in the boot |
290 | config, you can use xbc_for_each_key_value() to iterate key-value pairs. | |
7b9b816f | 291 | Note that you need to use xbc_array_for_each_value() for accessing |
a4798eb4 | 292 | each array's value, e.g.:: |
7b9b816f MH |
293 | |
294 | vnode = NULL; | |
295 | xbc_find_value("key.word", &vnode); | |
296 | if (vnode && xbc_node_is_array(vnode)) | |
297 | xbc_array_for_each_value(vnode, value) { | |
298 | printk("%s ", value); | |
299 | } | |
300 | ||
a4798eb4 MH |
301 | If you want to focus on keys which have a prefix string, you can use |
302 | xbc_find_node() to find a node by the prefix string, and iterate | |
7b9b816f MH |
303 | keys under the prefix node with xbc_node_for_each_key_value(). |
304 | ||
305 | But the most typical usage is to get the named value under prefix | |
306 | or get the named array under prefix as below:: | |
307 | ||
308 | root = xbc_find_node("key.prefix"); | |
309 | value = xbc_node_find_value(root, "option", &vnode); | |
310 | ... | |
311 | xbc_node_for_each_array_value(root, "array-option", value, anode) { | |
312 | ... | |
313 | } | |
314 | ||
315 | This accesses a value of "key.prefix.option" and an array of | |
316 | "key.prefix.array-option". | |
317 | ||
a4798eb4 MH |
318 | Locking is not needed, since after initialization, the config becomes |
319 | read-only. All data and keys must be copied if you need to modify it. | |
7b9b816f MH |
320 | |
321 | ||
322 | Functions and structures | |
323 | ======================== | |
324 | ||
325 | .. kernel-doc:: include/linux/bootconfig.h | |
326 | .. kernel-doc:: lib/bootconfig.c | |
327 |