blob: 9fe5630ab16c2dd62ee18f6fc98bdf6373486ab5 [file] [log] [blame]
Simon Glass83b9be62022-04-24 23:31:26 -06001.. SPDX-License-Identifier: GPL-2.0+:
2
Simon Glass16047dc2024-07-17 09:30:52 +01003Standard Boot Overview
4======================
Simon Glass83b9be62022-04-24 23:31:26 -06005
6Introduction
7------------
8
9Standard boot provides a built-in way for U-Boot to automatically boot
10an Operating System without custom scripting and other customisation. It
11introduces the following concepts:
12
13 - bootdev - a device which can hold or access a distro (e.g. MMC, Ethernet)
14 - bootmeth - a method to scan a bootdev to find bootflows (e.g. distro boot)
15 - bootflow - a description of how to boot (provided by the distro)
16
17For Linux, the distro (Linux distribution, e.g. Debian, Fedora) is responsible
18for creating a bootflow for each kernel combination that it wants to offer.
19These bootflows are stored on media so they can be discovered by U-Boot. This
Simon Glass16047dc2024-07-17 09:30:52 +010020feature is typically called `distro boot` (see :doc:`../distro`) because it is
Simon Glass83b9be62022-04-24 23:31:26 -060021a way for distributions to boot on any hardware.
22
23Traditionally U-Boot has relied on scripts to implement this feature. See
Paul Barker6c55d0d2022-07-29 14:31:58 +010024distro_bootcmd_ for details. This is done because U-Boot has no native support
Simon Glass83b9be62022-04-24 23:31:26 -060025for scanning devices. While the scripts work remarkably well, they can be hard
26to understand and extend, and the feature does not include tests. They are also
27making it difficult to move away from ad-hoc CONFIGs, since they are implemented
28using the environment and a lot of #defines.
29
30Standard boot is a generalisation of distro boot. It provides a more built-in
31way to boot with U-Boot. The feature is extensible to different Operating
32Systems (such as Chromium OS) and devices (beyond just block and network
33devices). It supports EFI boot and EFI bootmgr too.
34
Simon Glass16047dc2024-07-17 09:30:52 +010035Finally, standard boot supports the operation of :doc:`../vbe`.
Simon Glass83b9be62022-04-24 23:31:26 -060036
37Bootflow
38--------
39
40A bootflow is a file that describes how to boot a distro. Conceptually there can
41be different formats for that file but at present U-Boot only supports the
Quentin Schulze0ff5cc2024-06-12 16:58:48 +020042BootLoaderSpec_ format which looks something like this::
Simon Glass83b9be62022-04-24 23:31:26 -060043
44 menu autoboot Welcome to Fedora-Workstation-armhfp-31-1.9. Automatic boot in # second{,s}. Press a key for options.
45 menu title Fedora-Workstation-armhfp-31-1.9 Boot Options.
46 menu hidden
47
48 label Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl)
49 kernel /vmlinuz-5.3.7-301.fc31.armv7hl
50 append ro root=UUID=9732b35b-4cd5-458b-9b91-80f7047e0b8a rhgb quiet LANG=en_US.UTF-8 cma=192MB cma=256MB
51 fdtdir /dtb-5.3.7-301.fc31.armv7hl/
52 initrd /initramfs-5.3.7-301.fc31.armv7hl.img
53
54As you can see it specifies a kernel, a ramdisk (initrd) and a directory from
Quentin Schulze0ff5cc2024-06-12 16:58:48 +020055which to load Device Tree files. The details are described in distro_bootcmd_.
Simon Glass83b9be62022-04-24 23:31:26 -060056
57The bootflow is provided by the distro. It is not part of U-Boot. U-Boot's job
58is simply to interpret the file and carry out the instructions. This allows
59distros to boot on essentially any device supported by U-Boot.
60
61Typically the first available bootflow is selected and booted. If that fails,
62then the next one is tried.
63
64
65Bootdev
66-------
67
68Where does U-Boot find the media that holds the operating systems? That is the
69job of bootdev. A bootdev is simply a layer on top of a media device (such as
70MMC, NVMe). The bootdev accesses the device, including partitions and
71filesystems that might contain things related to an operating system.
72
73For example, an MMC bootdev provides access to the individual partitions on the
Simon Glass736612e2023-01-17 10:48:19 -070074MMC device. It scans through these to find filesystems with the boot flag set,
75then provides a list of these for consideration.
Simon Glass83b9be62022-04-24 23:31:26 -060076
Simon Glass736612e2023-01-17 10:48:19 -070077Some bootdevs are not visible until a bus is enumerated, e.g. flash sticks
78attached via USB. To deal with this, each bootdev has an associated 'hunter'
79which can hunt for bootdevs of a particular uclass type. For example, the SCSI
80bootdev scans the SCSI bus looking for devices, creating a bootdev for each
81Logical Unit Number (LUN) that it finds.
82
Simon Glass83b9be62022-04-24 23:31:26 -060083
84Bootmeth
85--------
86
87Once the list of filesystems is provided, how does U-Boot find the bootflow
Quentin Schulze0ff5cc2024-06-12 16:58:48 +020088files in these filesystems? That is the job of bootmeth. Each boot method has
Simon Glass83b9be62022-04-24 23:31:26 -060089its own way of doing this.
90
91For example, the distro bootmeth simply looks through the provided filesystem
92for a file called `extlinux/extlinux.conf`. This files constitutes a bootflow.
93If the distro bootmeth is used on multiple partitions it may produce multiple
94bootflows.
95
96Note: it is possible to have a bootmeth that uses a partition or a whole device
97directly, but it is more common to use a filesystem.
Mattijs Korpershoekb30baa92024-07-10 10:40:05 +020098For example, the Android bootmeth uses a whole device.
Simon Glass83b9be62022-04-24 23:31:26 -060099
Simon Glassafaeb772022-07-30 15:52:35 -0600100Note that some bootmeths are 'global', meaning that they select the bootdev
101themselves. Examples include VBE and EFI boot manager. In this case, they
102provide a `read_bootflow()` method which checks whatever bootdevs it likes, then
103returns the bootflow, if found. Some of these bootmeths may be very slow, if
104they scan a lot of devices.
105
Martyn Welch93a0d162024-10-09 14:15:40 +0100106The extlinux bootmeth also allows for bootmeth specific configuration to be
107set. A bootmeth that wishes to support this provides the `set_property()`
108method. This allows string properties and values to be passed to the bootmeth.
109It is up to the bootmeth to determine what action to take when this method is
110called.
111
Simon Glass83b9be62022-04-24 23:31:26 -0600112
113Boot process
114------------
115
Quentin Schulze0ff5cc2024-06-12 16:58:48 +0200116U-Boot tries to use the 'lazy init' approach wherever possible and distro boot
Simon Glass83b9be62022-04-24 23:31:26 -0600117is no exception. The algorithm is::
118
119 while (get next bootdev)
120 while (get next bootmeth)
121 while (get next bootflow)
122 try to boot it
123
124So U-Boot works its way through the bootdevs, trying each bootmeth in turn to
125obtain bootflows, until it either boots or exhausts the available options.
126
127Instead of 500 lines of #defines and a 4KB boot script, all that is needed is
128the following command::
129
130 bootflow scan -lb
131
132which scans for available bootflows, optionally listing each find it finds (-l)
133and trying to boot it (-b).
134
Simon Glassafaeb772022-07-30 15:52:35 -0600135When global bootmeths are available, these are typically checked before the
136above bootdev scanning.
137
Simon Glass83b9be62022-04-24 23:31:26 -0600138
139Controlling ordering
140--------------------
141
Simon Glass2f27e472023-08-19 16:49:35 -0600142By default, faster bootdevs (or those which are assumed to be faster) are used
143first, since they are more likely to be able to boot the device quickly.
144
Simon Glass83b9be62022-04-24 23:31:26 -0600145Several options are available to control the ordering of boot scanning:
146
147
148boot_targets
149~~~~~~~~~~~~
150
151This environment variable can be used to control the list of bootdevs searched
152and their ordering, for example::
153
154 setenv boot_targets "mmc0 mmc1 usb pxe"
155
156Entries may be removed or re-ordered in this list to affect the boot order. If
157the variable is empty, the default ordering is used, based on the priority of
158bootdevs and their sequence numbers.
159
160
161bootmeths
162~~~~~~~~~
163
Simon Glass2f27e472023-08-19 16:49:35 -0600164By default bootmeths are checked in name order. Use `bootmeth list` to see the
165ordering. Note that the `extlinux` and `script` bootmeth is first, to preserve the behaviour
166used by the old distro scripts.
167
Simon Glass83b9be62022-04-24 23:31:26 -0600168This environment variable can be used to control the list of bootmeths used and
169their ordering for example::
170
Simon Glassb71d7f72023-05-10 16:34:46 -0600171 setenv bootmeths "extlinux efi"
Simon Glass83b9be62022-04-24 23:31:26 -0600172
173Entries may be removed or re-ordered in this list to affect the order the
174bootmeths are tried on each bootdev. If the variable is empty, the default
175ordering is used, based on the bootmeth sequence numbers, which can be
176controlled by aliases.
177
178The :ref:`usage/cmd/bootmeth:bootmeth command` (`bootmeth order`) operates in
179the same way as setting this variable.
180
Simon Glass83b9be62022-04-24 23:31:26 -0600181Bootdev uclass
182--------------
183
Quentin Schulze0ff5cc2024-06-12 16:58:48 +0200184The bootdev uclass provides a simple API call to obtain a bootflow from a
Simon Glass83b9be62022-04-24 23:31:26 -0600185device::
186
187 int bootdev_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
188 struct bootflow *bflow);
189
Quentin Schulze0ff5cc2024-06-12 16:58:48 +0200190This takes an iterator which indicates the bootdev, partition and bootmeth to
Simon Glass83b9be62022-04-24 23:31:26 -0600191use. It returns a bootflow. This is the core of the bootdev implementation. The
192bootdev drivers that implement this differ depending on the media they are
193reading from, but each is responsible for returning a valid bootflow if
194available.
195
196A helper called `bootdev_find_in_blk()` makes it fairly easy to implement this
Simon Glass736612e2023-01-17 10:48:19 -0700197function for each media device uclass, in a few lines of code. For many types
Quentin Schulze0ff5cc2024-06-12 16:58:48 +0200198of bootdevs, the `get_bootflow` member can be NULL, indicating that the default
Simon Glass736612e2023-01-17 10:48:19 -0700199handler is used. This is called `default_get_bootflow()` and it only works with
200block devices.
Simon Glass83b9be62022-04-24 23:31:26 -0600201
202
203Bootdev drivers
204---------------
205
Quentin Schulze0ff5cc2024-06-12 16:58:48 +0200206A bootdev driver is typically fairly simple. Here is one for MMC::
Simon Glass83b9be62022-04-24 23:31:26 -0600207
Simon Glass83b9be62022-04-24 23:31:26 -0600208 static int mmc_bootdev_bind(struct udevice *dev)
209 {
210 struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
211
Simon Glass7e1f6a42023-01-17 10:48:08 -0700212 ucp->prio = BOOTDEVP_2_INTERNAL_FAST;
Simon Glass83b9be62022-04-24 23:31:26 -0600213
214 return 0;
215 }
216
217 struct bootdev_ops mmc_bootdev_ops = {
Simon Glass83b9be62022-04-24 23:31:26 -0600218 };
219
220 static const struct udevice_id mmc_bootdev_ids[] = {
221 { .compatible = "u-boot,bootdev-mmc" },
222 { }
223 };
224
225 U_BOOT_DRIVER(mmc_bootdev) = {
226 .name = "mmc_bootdev",
227 .id = UCLASS_BOOTDEV,
228 .ops = &mmc_bootdev_ops,
229 .bind = mmc_bootdev_bind,
230 .of_match = mmc_bootdev_ids,
231 };
232
Simon Glass736612e2023-01-17 10:48:19 -0700233You may notice that the `get_bootflow` memory is not provided, so is NULL. This
234means that `default_get_bootflow()` is used. This simply obtains the
235block device and calls a bootdev helper function to do the rest. The
Simon Glass83b9be62022-04-24 23:31:26 -0600236implementation of `bootdev_find_in_blk()` checks the partition table, and
237attempts to read a file from a filesystem on the partition number given by the
Simon Glass3c63a872025-03-15 14:25:58 +0000238`@iter->part` parameter. If there are any bootable partitions in the table and
239the BOOTFLOWIF_ONLY_BOOTABLE flag is set in `@iter->flags`, then only bootable
240partitions are considered.
Simon Glass736612e2023-01-17 10:48:19 -0700241
242Each bootdev has a priority, which indicates the order in which it is used,
243if `boot_targets` is not used. Faster bootdevs are used first, since they are
244more likely to be able to boot the device quickly.
245
246
247Environment Variables
248---------------------
249
250Various environment variables are used by standard boot. These allow the board
251to control where things are placed when booting the OS. You should ensure that
252your boards sets values for these.
253
254fdtfile
255 Name of the flattened device tree (FDT) file to load, e.g.
256 "rockchip/rk3399-rockpro64.dtb"
257
Heinrich Schuchardt75e86db2023-11-16 10:09:07 +0100258fdt_addr_r
Simon Glass736612e2023-01-17 10:48:19 -0700259 Address at which to load the FDT, e.g. 0x01f00000
260
261fdtoverlay_addr_r (needed if overlays are used)
262 Address at which to load the overlay for the FDT, e.g. 0x02000000
263
264kernel_addr_r
265 Address at which to load the kernel, e.g. 0x02080000
266
267kernel_comp_addr_r
268 Address to which to decompress the kernel, e.g. 0x08000000
269
270kernel_comp_size
271 Size of available space for decompressed kernel, e.g. 0x2000000
272
273pxefile_addr_r
274 Address at which to load the PXE file, e.g. 0x00600000
275
276ramdisk_addr_r
277 Address at which to load the ramdisk, e.g. 0x06000000
278
279scriptaddr
280 Address at which to load the U-Boot script, e.g. 0x00500000
Simon Glass83b9be62022-04-24 23:31:26 -0600281
Simon Glass736612e2023-01-17 10:48:19 -0700282script_offset_f
283 SPI flash offset from which to load the U-Boot script, e.g. 0xffe000
Simon Glass83b9be62022-04-24 23:31:26 -0600284
Simon Glass736612e2023-01-17 10:48:19 -0700285script_size_f
286 Size of the script to load, e.g. 0x2000
287
Mattijs Korpershoekb30baa92024-07-10 10:40:05 +0200288vendor_boot_comp_addr_r
289 Address to which to load the vendor_boot Android image, e.g. 0xe0000000
290
Simon Glass736612e2023-01-17 10:48:19 -0700291Some variables are set by script bootmeth:
292
293devtype
294 Device type being used for boot, e.g. mmc
295
296devnum
297 Device number being used for boot, e.g. 1
298
299distro_bootpart
300 Partition being used for boot, e.g. 2
301
302prefix
303 Directory containing the script
304
305mmc_bootdev
306 Device number being used for boot (e.g. 1). This is only used by MMC on
307 sunxi boards.
308
Simon Glass83b9be62022-04-24 23:31:26 -0600309
310Device hierarchy
311----------------
312
313A bootdev device is a child of the media device. In this example, you can see
314that the bootdev is a sibling of the block device and both are children of
315media device::
316
317 mmc 0 [ + ] bcm2835-sdhost | |-- mmc@7e202000
318 blk 0 [ + ] mmc_blk | | |-- mmc@7e202000.blk
319 bootdev 0 [ ] mmc_bootdev | | `-- mmc@7e202000.bootdev
320 mmc 1 [ + ] sdhci-bcm2835 | |-- sdhci@7e300000
321 blk 1 [ ] mmc_blk | | |-- sdhci@7e300000.blk
322 bootdev 1 [ ] mmc_bootdev | | `-- sdhci@7e300000.bootdev
323
324The bootdev device is typically created automatically in the media uclass'
Simon Glass736612e2023-01-17 10:48:19 -0700325`post_bind()` method by calling `bootdev_setup_for_dev()` or
Simon Glassb1d581d2023-07-30 11:15:14 -0600326`bootdev_setup_for_sibling_blk()`. The code typically something like this::
Simon Glass83b9be62022-04-24 23:31:26 -0600327
Simon Glass736612e2023-01-17 10:48:19 -0700328 /* dev is the Ethernet device */
Simon Glass83b9be62022-04-24 23:31:26 -0600329 ret = bootdev_setup_for_dev(dev, "eth_bootdev");
330 if (ret)
331 return log_msg_ret("bootdev", ret);
332
Simon Glass736612e2023-01-17 10:48:19 -0700333or::
334
335 /* blk is the block device (child of MMC device)
Simon Glassb1d581d2023-07-30 11:15:14 -0600336 ret = bootdev_setup_for_sibling_blk(blk, "mmc_bootdev");
Simon Glass736612e2023-01-17 10:48:19 -0700337 if (ret)
338 return log_msg_ret("bootdev", ret);
339
340
Simon Glass83b9be62022-04-24 23:31:26 -0600341Here, `eth_bootdev` is the name of the Ethernet bootdev driver and `dev`
Quentin Schulze0ff5cc2024-06-12 16:58:48 +0200342is the Ethernet device. This function is safe to call even if standard boot is
Simon Glass83b9be62022-04-24 23:31:26 -0600343not enabled, since it does nothing in that case. It can be added to all uclasses
344which implement suitable media.
345
346
347The bootstd device
348------------------
349
350Standard boot requires a single instance of the bootstd device to make things
351work. This includes global information about the state of standard boot. See
352`struct bootstd_priv` for this structure, accessed with `bootstd_get_priv()`.
353
Quentin Schulze0ff5cc2024-06-12 16:58:48 +0200354Within the Device Tree, if you add bootmeth devices, they should be children of
Simon Glassafaeb772022-07-30 15:52:35 -0600355the bootstd device. See `arch/sandbox/dts/test.dts` for an example of this.
Simon Glass83b9be62022-04-24 23:31:26 -0600356
Simon Glass83b9be62022-04-24 23:31:26 -0600357
358.. _`Automatic Devices`:
359
360Automatic devices
361-----------------
362
Quentin Schulze0ff5cc2024-06-12 16:58:48 +0200363It is possible to define all the required devices in the Device Tree manually,
Simon Glass83b9be62022-04-24 23:31:26 -0600364but it is not necessary. The bootstd uclass includes a `dm_scan_other()`
365function which creates the bootstd device if not found. If no bootmeth devices
Simon Glassafaeb772022-07-30 15:52:35 -0600366are found at all, it creates one for each available bootmeth driver.
Simon Glass83b9be62022-04-24 23:31:26 -0600367
Quentin Schulze0ff5cc2024-06-12 16:58:48 +0200368If your Device Tree has any bootmeth device it must have all of them that you
Simon Glassafaeb772022-07-30 15:52:35 -0600369want to use, since no bootmeth devices will be created automatically in that
370case.
Simon Glass83b9be62022-04-24 23:31:26 -0600371
372
373Using devicetree
374----------------
375
376If a bootdev is complicated or needs configuration information, it can be
Quentin Schulze0ff5cc2024-06-12 16:58:48 +0200377added to the Device Tree as a child of the media device. For example, imagine a
378bootdev which reads a bootflow from SPI flash. The Device Tree fragment might
Simon Glass83b9be62022-04-24 23:31:26 -0600379look like this::
380
381 spi@0 {
382 flash@0 {
383 reg = <0>;
384 compatible = "spansion,m25p16", "jedec,spi-nor";
385 spi-max-frequency = <40000000>;
386
387 bootdev {
388 compatible = "u-boot,sf-bootdev";
389 offset = <0x2000>;
390 size = <0x1000>;
391 };
392 };
393 };
394
395The `sf-bootdev` driver can implement a way to read from the SPI flash, using
396the offset and size provided, and return that bootflow file back to the caller.
Dario Binacchi3c9c6d72022-08-26 15:15:41 +0200397When distro boot wants to read the kernel it calls distro_getfile() which must
Simon Glass83b9be62022-04-24 23:31:26 -0600398provide a way to read from the SPI flash. See `distro_boot()` at distro_boot_
399for more details.
400
401Of course this is all internal to U-Boot. All the distro sees is another way
402to boot.
403
404
405Configuration
406-------------
407
408Standard boot is enabled with `CONFIG_BOOTSTD`. Each bootmeth has its own CONFIG
Simon Glassb71d7f72023-05-10 16:34:46 -0600409option also. For example, `CONFIG_BOOTMETH_EXTLINUX` enables support for
410booting from a disk using an `extlinux.conf` file.
Simon Glass83b9be62022-04-24 23:31:26 -0600411
Quentin Schulze0ff5cc2024-06-12 16:58:48 +0200412To enable all features of standard boot, use `CONFIG_BOOTSTD_FULL`. This
Simon Glass736612e2023-01-17 10:48:19 -0700413includes the full set of commands, more error messages when things go wrong and
414bootmeth ordering with the bootmeths environment variable.
415
Simon Glass2e5161eb2023-01-28 15:00:21 -0700416You should probably also enable `CONFIG_BOOTSTD_DEFAULTS`, which provides
417several filesystem and network features (if `CONFIG_NET` is enabled) so that
418a good selection of boot options is available.
419
Simon Glassf1d8e0f2024-07-17 09:31:04 +0100420Some devicetree properties are supported in the bootstd node when
421`CONFIG_BOOTSTD_FULL` is enabled:
422
423 filename-prefixes
424 List of prefixes to use when searching for files on block devices. This
425 defaults to {"/", "/boot/"} if not provided.
426
427 bootdev-order
428 Lists the bootdev ordering to use. Note that the deprecated
429 `boot_targets` environment variable overrides this, if present.
430
431 theme (subnode)
432 Sets the theme to use for menus. See :doc:`/develop/expo`.
Simon Glass83b9be62022-04-24 23:31:26 -0600433
434Available bootmeth drivers
435--------------------------
436
Simon Glass6d5d1212024-07-17 09:30:54 +0100437Bootmeth drivers are provided for booting from various media:
Simon Glass83b9be62022-04-24 23:31:26 -0600438
Mattijs Korpershoekcb6fa2f2024-07-24 14:41:25 +0200439 - :doc:`Android <android>` bootflow (boot image v4)
Simon Glass53898fb2024-07-17 09:31:02 +0100440 - :doc:`ChromiumOS <cros>` ChromiumOS boot from a disk
441 - EFI boot using bootefi from disk
442 - EFI boot using boot manager
Simon Glass6d5d1212024-07-17 09:30:54 +0100443 - :doc:`extlinux / syslinux <extlinux>` boot from a storage device
Simon Glass08379df2024-07-17 09:30:55 +0100444 - :doc:`extlinux / syslinux <extlinux>` boot from a network (PXE)
Simon Glass53898fb2024-07-17 09:31:02 +0100445 - :doc:`sandbox <sandbox>` used only for testing
Simon Glass257ddc22024-07-17 09:31:01 +0100446 - :doc:`U-Boot scripts <script>` from disk, network or SPI flash
Simon Glass01bd6f62024-07-17 09:30:56 +0100447 - :doc:`QFW <qfw>`: QEMU firmware interface
Simon Glass53898fb2024-07-17 09:31:02 +0100448 - :doc:`VBE </develop/vbe>`: Verified Boot for Embedded
Simon Glass83b9be62022-04-24 23:31:26 -0600449
Simon Glassdc1917d2024-07-17 09:30:53 +0100450Each driver is controlled by a Kconfig option. If no bootmeth driver is
451selected by a compatible string in the devicetree, all available bootmeth
452drivers are bound automatically.
Simon Glass83b9be62022-04-24 23:31:26 -0600453
454Command interface
455-----------------
456
Simon Glassc6a52e72024-11-15 16:19:23 -0700457Four commands are available:
Simon Glass83b9be62022-04-24 23:31:26 -0600458
459`bootdev`
460 Allows listing of available bootdevs, selecting a particular one and
Simon Glass16047dc2024-07-17 09:30:52 +0100461 getting information about it. See :doc:`/usage/cmd/bootdev`
Simon Glass83b9be62022-04-24 23:31:26 -0600462
463`bootflow`
464 Allows scanning one or more bootdevs for bootflows, listing available
465 bootflows, selecting one, obtaining information about it and booting it.
Simon Glass16047dc2024-07-17 09:30:52 +0100466 See :doc:`/usage/cmd/bootflow`
Simon Glass83b9be62022-04-24 23:31:26 -0600467
468`bootmeth`
Martyn Welch93a0d162024-10-09 14:15:40 +0100469 Allow listing of available bootmethds, setting the order in which they are
470 tried and bootmeth specific configuration. See :doc:`/usage/cmd/bootmeth`
Simon Glass83b9be62022-04-24 23:31:26 -0600471
Simon Glassc6a52e72024-11-15 16:19:23 -0700472`bootstd`
473 Allow access to standard boot itself, so far only for listing images across
474 all bootflows. See :doc:`/usage/cmd/bootstd`
475
476Images
477------
478
479Standard boot keeps track of images which can or have been loaded. These are
480kept in a list attached to each bootflow. They can be listed using the
481``bootstd images`` command (see :doc:`/usage/cmd/bootstd`).
482
483For now most bootmeths load their images when scanning. Over time, some may
484adjust to load them only when needed, but in this case the images will still
485be visible.
486
487Once a bootflow has been selected, images for those that are not selected can
488potentially be dropped from the memory map. For now, this is not implemented.
489
490
Simon Glass83b9be62022-04-24 23:31:26 -0600491.. _BootflowStates:
492
493Bootflow states
494---------------
495
496Here is a list of states that a bootflow can be in:
497
498======= =======================================================================
499State Meaning
500======= =======================================================================
501base Starting-out state, indicates that no media/partition was found. For an
502 SD card socket it may indicate that the card is not inserted.
503media Media was found (e.g. SD card is inserted) but no partition information
504 was found. It might lack a partition table or have a read error.
505part Partition was found but a filesystem could not be read. This could be
506 because the partition does not hold a filesystem or the filesystem is
507 very corrupted.
508fs Filesystem was found but the file could not be read. It could be
509 missing or in the wrong subdirectory.
510file File was found and its size detected, but it could not be read. This
511 could indicate filesystem corruption.
512ready File was loaded and is ready for use. In this state the bootflow is
513 ready to be booted.
514======= =======================================================================
515
516
Simon Glasse27d7df2023-09-14 10:55:55 -0600517Migrating from distro_boot
518--------------------------
519
520To migrate from distro_boot:
521
522#. Update your board header files to remove the BOOTENV and BOOT_TARGET_xxx
523 defines. Standard boot finds available boot devices automatically.
524
525#. Remove the "boot_targets" variable unless you need it. Standard boot uses a
526 default order from fastest to slowest, which generally matches the order used
527 by boards.
528
529#. Make sure that CONFIG_BOOTSTD_DEFAULTS is enabled by your board, so it can
530 boot common Linux distributions.
531
532An example patch is at migrate_patch_.
533
534If you are using custom boot scripts for your board, consider creating your
535own bootmeth to hold the logic. There are various examples at
536`boot/bootmeth_...`.
537
538
Simon Glass83b9be62022-04-24 23:31:26 -0600539Theory of operation
540-------------------
541
542This describes how standard boot progresses through to booting an operating
543system.
544
Quentin Schulze0ff5cc2024-06-12 16:58:48 +0200545To start, all the necessary devices must be bound, including bootstd, which
Simon Glass83b9be62022-04-24 23:31:26 -0600546provides the top-level `struct bootstd_priv` containing optional configuration
Quentin Schulze0ff5cc2024-06-12 16:58:48 +0200547information. The bootstd device also holds the various lists used while
Simon Glass83b9be62022-04-24 23:31:26 -0600548scanning. This step is normally handled automatically by driver model, as
549described in `Automatic Devices`_.
550
551Bootdevs are also required, to provide access to the media to use. These are not
552useful by themselves: bootmeths are needed to provide the means of scanning
553those bootdevs. So, all up, we need a single bootstd device, one or more bootdev
554devices and one or more bootmeth devices.
555
556Once these are ready, typically a `bootflow scan` command is issued. This kicks
Quentin Schulze0ff5cc2024-06-12 16:58:48 +0200557off the iteration process, which involves hunting for bootdevs and looking
Simon Glass736612e2023-01-17 10:48:19 -0700558through the bootdevs and their partitions one by one to find bootflows.
Simon Glass83b9be62022-04-24 23:31:26 -0600559
Simon Glass736612e2023-01-17 10:48:19 -0700560Iteration is kicked off using `bootflow_scan_first()`.
Simon Glass83b9be62022-04-24 23:31:26 -0600561
562The iterator is set up with `bootflow_iter_init()`. This simply creates an
563empty one with the given flags. Flags are used to control whether each
564iteration is displayed, whether to return iterations even if they did not result
565in a valid bootflow, whether to iterate through just a single bootdev, etc.
566
Simon Glass736612e2023-01-17 10:48:19 -0700567Then the iterator is set up to according to the parameters given:
568
569- When `dev` is provided, then a single bootdev is scanned. In this case,
Simon Glass99e68182023-02-22 12:17:03 -0700570 `BOOTFLOWIF_SKIP_GLOBAL` and `BOOTFLOWIF_SINGLE_DEV` are set. No hunters are
Simon Glass736612e2023-01-17 10:48:19 -0700571 used in this case
572
573- Otherwise, when `label` is provided, then a single label or named bootdev is
Simon Glass99e68182023-02-22 12:17:03 -0700574 scanned. In this case `BOOTFLOWIF_SKIP_GLOBAL` is set and there are three
Simon Glass736612e2023-01-17 10:48:19 -0700575 options (with an effect on the `iter_incr()` function described later):
576
577 - If `label` indicates a numeric bootdev number (e.g. "2") then
578 `BOOTFLOW_METHF_SINGLE_DEV` is set. In this case, moving to the next bootdev
Quentin Schulze0ff5cc2024-06-12 16:58:48 +0200579 simply stops, since there is only one. No hunters are used.
Simon Glass736612e2023-01-17 10:48:19 -0700580 - If `label` indicates a particular media device (e.g. "mmc1") then
Simon Glass99e68182023-02-22 12:17:03 -0700581 `BOOTFLOWIF_SINGLE_MEDIA` is set. In this case, moving to the next bootdev
Simon Glass736612e2023-01-17 10:48:19 -0700582 processes just the children of the media device. Hunters are used, in this
583 example just the "mmc" hunter.
Nam Caocb0d3fb2024-02-21 13:41:44 +0100584 - If `label` indicates a particular partition in a particular media device
585 (e.g. "mmc1:3") then `BOOTFLOWIF_SINGLE_PARTITION` is set. In this case,
586 only a single partition within a bootdev is processed. Hunters are used, in
587 this example just the "mmc" hunter.
Simon Glass736612e2023-01-17 10:48:19 -0700588 - If `label` indicates a media uclass (e.g. "mmc") then
Simon Glass99e68182023-02-22 12:17:03 -0700589 `BOOTFLOWIF_SINGLE_UCLASS` is set. In this case, all bootdevs in that uclass
Simon Glass736612e2023-01-17 10:48:19 -0700590 are used. Hunters are used, in this example just the "mmc" hunter
591
592- Otherwise, none of the above flags is set and iteration is set up to work
593 through `boot_targets` environment variable (or `bootdev-order` device tree
594 property) in order, running the relevant hunter first. In this case
595 `cur_label` is used to indicate the label being processed. If there is no list
596 of labels, then all bootdevs are processed in order of priority, running the
597 hunters as it goes.
598
599With the above it is therefore possible to iterate in a variety of ways.
600
601No attempt is made to determine the ordering of bootdevs, since this cannot be
602known in advance if we are using the hunters. Any hunter might discover a new
603bootdev and disturb the original ordering.
Simon Glass83b9be62022-04-24 23:31:26 -0600604
Simon Glassafaeb772022-07-30 15:52:35 -0600605Next, the ordering of bootmeths is determined, by `bootmeth_setup_iter_order()`.
Simon Glass83b9be62022-04-24 23:31:26 -0600606By default the ordering is again by sequence number, i.e. the `/aliases` node,
Quentin Schulze0ff5cc2024-06-12 16:58:48 +0200607or failing that the order in the Device Tree. But the `bootmeth order` command
Simon Glass83b9be62022-04-24 23:31:26 -0600608or `bootmeths` environment variable can be used to set up an ordering. If that
609has been done, the ordering is in `struct bootstd_priv`, so that ordering is
610simply copied into the iterator. Either way, the `method_order` array it set up,
Simon Glassafaeb772022-07-30 15:52:35 -0600611along with `num_methods`.
612
613Note that global bootmeths are always put at the end of the ordering. If any are
614present, `cur_method` is set to the first one, so that global bootmeths are done
615first. Once all have been used, these bootmeths are dropped from the iteration.
616When there are no global bootmeths, `cur_method` is set to 0.
Simon Glass83b9be62022-04-24 23:31:26 -0600617
Simon Glass736612e2023-01-17 10:48:19 -0700618At this point the iterator is ready to use, with the first bootmeth selected.
619Most of the other fields are 0. This means that the current partition
Simon Glassafaeb772022-07-30 15:52:35 -0600620is 0, which is taken to mean the whole device, since partition numbers start at
6211. It also means that `max_part` is 0, i.e. the maximum partition number we know
Simon Glass83b9be62022-04-24 23:31:26 -0600622about is 0, meaning that, as far as we know, there is no partition table on this
623bootdev.
624
Simon Glass736612e2023-01-17 10:48:19 -0700625With the iterator ready, `bootflow_scan_first()` checks whether the current
Simon Glass83b9be62022-04-24 23:31:26 -0600626settings produce a valid bootflow. This is handled by `bootflow_check()`, which
627either returns 0 (if it got something) or an error if not (more on that later).
Simon Glass99e68182023-02-22 12:17:03 -0700628If the `BOOTFLOWIF_ALL` iterator flag is set, even errors are returned as
Simon Glass83b9be62022-04-24 23:31:26 -0600629incomplete bootflows, but normally an error results in moving onto the next
630iteration.
631
Simon Glass736612e2023-01-17 10:48:19 -0700632Note that `bootflow_check()` handles global bootmeths explicitly, by calling
Simon Glassafaeb772022-07-30 15:52:35 -0600633`bootmeth_get_bootflow()` on each one. The `doing_global` flag indicates when
634the iterator is in that state.
635
Simon Glass83b9be62022-04-24 23:31:26 -0600636The `bootflow_scan_next()` function handles moving onto the next iteration and
637checking it. In fact it sits in a loop doing that repeatedly until it finds
638something it wants to return.
639
Simon Glass736612e2023-01-17 10:48:19 -0700640The actual 'moving on' part is implemented in `iter_incr()`. This is a fairly
Simon Glass83b9be62022-04-24 23:31:26 -0600641simple function. It increments the first counter. If that hits its maximum, it
642sets it to zero and increments the second counter. You can think of all the
643counters together as a number with three digits which increment in order, with
644the least-sigificant digit on the right, counting like this:
645
646 ======== ======= =======
647 bootdev part method
648 ======== ======= =======
649 0 0 0
650 0 0 1
651 0 0 2
652 0 1 0
653 0 1 1
Simon Glassafaeb772022-07-30 15:52:35 -0600654 0 1 2
Simon Glass83b9be62022-04-24 23:31:26 -0600655 1 0 0
656 1 0 1
Simon Glassafaeb772022-07-30 15:52:35 -0600657 ...
Simon Glass83b9be62022-04-24 23:31:26 -0600658 ======== ======= =======
659
660The maximum value for `method` is `num_methods - 1` so when it exceeds that, it
661goes back to 0 and the next `part` is considered. The maximum value for that is
662`max_part`, which is initially zero for all bootdevs. If we find a partition
663table on that bootdev, `max_part` can be updated during the iteration to a
664higher value - see `bootdev_find_in_blk()` for that, described later. If that
665exceeds its maximum, then the next bootdev is used. In this way, iter_incr()
666works its way through all possibilities, moving forward one each time it is
667called.
668
Simon Glassafaeb772022-07-30 15:52:35 -0600669Note that global bootmeths introduce a subtlety into the above description.
670When `doing_global` is true, the iteration takes place only among the bootmeths,
671i.e. the last column above. The global bootmeths are at the end of the list.
672Assuming that they are entries 3 and 4 in the list, the iteration then looks
673like this:
674
675 ======== ======= ======= =======================================
676 bootdev part method notes
677 ======== ======= ======= =======================================
678 . . 3 doing_global = true, method_count = 5
679 . . 4
680 0 0 0 doing_global = false, method_count = 3
681 0 0 1
682 0 0 2
683 0 1 0
684 0 1 1
685 0 1 2
686 1 0 0
687 1 0 1
688 ...
689 ======== ======= ======= =======================================
690
691The changeover of the value of `doing_global` from true to false is handled in
692`iter_incr()` as well.
693
Simon Glass736612e2023-01-17 10:48:19 -0700694Note that the value in the `bootdev` column above is not actually stored - it is
695just for illustration. In practice, `iter_incr()` uses the flags to determine
696whether to move to the next bootdev in the uclass, the next child of the media
697device, the next label, or the next priority level, depending on the flag
698settings (see `BOOTFLOW_METHF_SINGLE_DEV`, etc. above).
699
Simon Glass83b9be62022-04-24 23:31:26 -0600700There is no expectation that iteration will actually finish. Quite often a
701valid bootflow is found early on. With `bootflow scan -b`, that causes the
702bootflow to be immediately booted. Assuming it is successful, the iteration never
703completes.
704
Quentin Schulze0ff5cc2024-06-12 16:58:48 +0200705Also note that the iterator holds the **current** combination being considered.
Simon Glass83b9be62022-04-24 23:31:26 -0600706So when `iter_incr()` is called, it increments to the next one and returns it,
707the new **current** combination.
708
709Note also the `err` field in `struct bootflow_iter`. This is normally 0 and has
Quentin Schulze0ff5cc2024-06-12 16:58:48 +0200710thus no effect on `iter_inc()`. But if it is non-zero, signalling an error,
Simon Glass83b9be62022-04-24 23:31:26 -0600711it indicates to the iterator what it should do when called. It can force moving
712to the next partition, or bootdev, for example. The special values
713`BF_NO_MORE_PARTS` and `BF_NO_MORE_DEVICES` handle this. When `iter_incr` sees
714`BF_NO_MORE_PARTS` it knows that it should immediately move to the next bootdev.
715When it sees `BF_NO_MORE_DEVICES` it knows that there is nothing more it can do
716so it should immediately return. The caller of `iter_incr()` is responsible for
717updating the `err` field, based on the return value it sees.
718
719The above describes the iteration process at a high level. It is basically a
720very simple increment function with a checker called `bootflow_check()` that
721checks the result of each iteration generated, to determine whether it can
722produce a bootflow.
723
724So what happens inside of `bootflow_check()`? It simply calls the uclass
725method `bootdev_get_bootflow()` to ask the bootdev to return a bootflow. It
726passes the iterator to the bootdev method, so that function knows what we are
727talking about. At first, the bootflow is set up in the state `BOOTFLOWST_BASE`,
Quentin Schulze0ff5cc2024-06-12 16:58:48 +0200728with just the `method` and `dev` initialised. But the bootdev may fill in more,
Simon Glassafaeb772022-07-30 15:52:35 -0600729e.g. updating the state, depending on what it finds. For global bootmeths the
730`bootmeth_get_bootflow()` function is called instead of
731`bootdev_get_bootflow()`.
Simon Glass83b9be62022-04-24 23:31:26 -0600732
Simon Glassafaeb772022-07-30 15:52:35 -0600733Based on what the bootdev or bootmeth responds with, `bootflow_check()` either
Simon Glass83b9be62022-04-24 23:31:26 -0600734returns a valid bootflow, or a partial one with an error. A partial bootflow
735is one that has some fields set up, but did not reach the `BOOTFLOWST_READY`
Simon Glass99e68182023-02-22 12:17:03 -0700736state. As noted before, if the `BOOTFLOWIF_ALL` iterator flag is set, then all
Simon Glass83b9be62022-04-24 23:31:26 -0600737bootflows are returned, even partial ones. This can help with debugging.
738
739So at this point you can see that total control over whether a bootflow can
Simon Glassafaeb772022-07-30 15:52:35 -0600740be generated from a particular iteration, or not, rests with the bootdev (or
741global bootmeth). Each one can adopt its own approach.
Simon Glass83b9be62022-04-24 23:31:26 -0600742
743Going down a level, what does the bootdev do in its `get_bootflow()` method?
744Let us consider the MMC bootdev. In that case the call to
Simon Glass736612e2023-01-17 10:48:19 -0700745`bootdev_get_bootflow()` ends up in `default_get_bootflow()`. It locates the
746parent device of the bootdev, i.e. the `UCLASS_MMC` device itself, then finds
747the block device associated with it. It then calls the helper function
Simon Glass83b9be62022-04-24 23:31:26 -0600748`bootdev_find_in_blk()` to do all the work. This is common with just about any
749bootdev that is based on a media device.
750
751The `bootdev_find_in_blk()` helper is implemented in the bootdev uclass. It
752names the bootflow and copies the partition number in from the iterator. Then it
753calls the bootmeth device to check if it can support this device. This is
754important since some bootmeths only work with network devices, for example. If
755that check fails, it stops.
756
757Assuming the bootmeth is happy, or at least indicates that it is willing to try
758(by returning 0 from its `check()` method), the next step is to try the
759partition. If that works it tries to detect a file system. If that works then it
760calls the bootmeth device once more, this time to read the bootflow.
761
Simon Glass0fca7e82023-08-24 13:55:43 -0600762Note: Normally a filesystem is needed for the bootmeth to be called on block
763devices, but bootmeths which don't need that can set the BOOTMETHF_ANY_PART
764flag to indicate that they can scan any partition. An example is the ChromiumOS
765bootmeth which can store a kernel in a raw partition. Note also that sandbox is
766a special case, since in that case the host filesystem can be accessed even
767though the block device is NULL.
Simon Glass83b9be62022-04-24 23:31:26 -0600768
Simon Glassb71d7f72023-05-10 16:34:46 -0600769If we take the example of the `bootmeth_extlinux` driver, this call ends up at
770`extlinux_read_bootflow()`. It has the filesystem ready, so tries various
Simon Glass83b9be62022-04-24 23:31:26 -0600771filenames to try to find the `extlinux.conf` file, reading it if possible. If
772all goes well the bootflow ends up in the `BOOTFLOWST_READY` state.
773
774At this point, we fall back from the bootmeth driver, to
Simon Glass736612e2023-01-17 10:48:19 -0700775`bootdev_find_in_blk()`, then back to `default_get_bootflow()`, then to
Simon Glass83b9be62022-04-24 23:31:26 -0600776`bootdev_get_bootflow()`, then to `bootflow_check()` and finally to its caller,
Simon Glass736612e2023-01-17 10:48:19 -0700777either `bootflow_scan_first()` or `bootflow_scan_next()`. In either case,
Simon Glass83b9be62022-04-24 23:31:26 -0600778the bootflow is returned as the result of this iteration, assuming it made it to
779the `BOOTFLOWST_READY` state.
780
781That is the basic operation of scanning for bootflows. The process of booting a
782bootflow is handled by the bootmeth driver for that bootflow. In the case of
Simon Glassb71d7f72023-05-10 16:34:46 -0600783extlinux boot, this parses and processes the `extlinux.conf` file that was read.
784See `extlinux_boot()` for how that works. The processing may involve reading
Simon Glass83b9be62022-04-24 23:31:26 -0600785additional files, which is handled by the `read_file()` method, which is
Quentin Schulze0ff5cc2024-06-12 16:58:48 +0200786`extlinux_read_file()` in this case. All bootmeths should support reading
Simon Glassb71d7f72023-05-10 16:34:46 -0600787files, since the bootflow is typically only the basic instructions and does not
788include the operating system itself, ramdisk, device tree, etc.
Simon Glass83b9be62022-04-24 23:31:26 -0600789
790The vast majority of the bootstd code is concerned with iterating through
Quentin Schulze0ff5cc2024-06-12 16:58:48 +0200791partitions on bootdevs and using bootmeths to find bootflows.
Simon Glass83b9be62022-04-24 23:31:26 -0600792
793How about bootdevs which are not block devices? They are handled by the same
794methods as above, but with a different implementation. For example, the bootmeth
795for PXE boot (over a network) uses `tftp` to read files rather than `fs_read()`.
796But other than that it is very similar.
797
798
799Tests
800-----
801
802Tests are located in `test/boot` and cover the core functionality as well as
803the commands. All tests use sandbox so can be run on a standard Linux computer
804and in U-Boot's CI.
805
Simon Glass736612e2023-01-17 10:48:19 -0700806For testing, a DOS-formatted disk image is used with a FAT partition on it and
807a second unused partition. This is created in `setup_bootflow_image()`, with a
808canned one from the source tree used if it cannot be created (e.g. in CI).
Simon Glass83b9be62022-04-24 23:31:26 -0600809
810
811Bootflow internals
812------------------
813
814The bootstd device holds a linked list of scanned bootflows as well as the
815currently selected bootdev and bootflow (for use by commands). This is in
816`struct bootstd_priv`.
817
818Each bootdev device has its own `struct bootdev_uc_plat` which holds a
819list of scanned bootflows just for that device.
820
821The bootflow itself is documented in bootflow_h_. It includes various bits of
822information about the bootflow and a buffer to hold the file.
823
824
825Future
826------
827
828Apart from the to-do items below, different types of bootflow files may be
829implemented in future, e.g. Chromium OS support which is currently only
830available as a script in chromebook_coral.
831
832
833To do
834-----
835
836Some things that need to be done to completely replace the distro-boot scripts:
837
Simon Glass5fd48162023-08-24 19:39:24 -0600838- implement extensions (devicetree overlays with add-on boards)
Mattijs Korpershoekb30baa92024-07-10 10:40:05 +0200839- implement legacy (boot image v2) android boot flow
Simon Glass83b9be62022-04-24 23:31:26 -0600840
841Other ideas:
842
843- `bootflow prep` to load everything preparing for boot, so that `bootflow boot`
844 can just do the boot.
845- automatically load kernel, FDT, etc. to suitable addresses so the board does
846 not need to specify things like `pxefile_addr_r`
847
848
Paul Barker6c55d0d2022-07-29 14:31:58 +0100849.. _distro_bootcmd: https://github.com/u-boot/u-boot/blob/master/include/config_distro_bootcmd.h
Simon Glass83b9be62022-04-24 23:31:26 -0600850.. _BootLoaderSpec: http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/
851.. _distro_boot: https://github.com/u-boot/u-boot/blob/master/boot/distro.c
852.. _bootflow_h: https://github.com/u-boot/u-boot/blob/master/include/bootflow.h
Simon Glasse27d7df2023-09-14 10:55:55 -0600853.. _migrate_patch: https://patchwork.ozlabs.org/project/uboot/patch/20230727215433.578830-2-sjg@chromium.org/