]> Git Repo - J-u-boot.git/blob - doc/develop/bootstd.rst
Merge tag 'v2023.10-rc4' into next
[J-u-boot.git] / doc / develop / bootstd.rst
1 .. SPDX-License-Identifier: GPL-2.0+:
2
3 U-Boot Standard Boot
4 ====================
5
6 Introduction
7 ------------
8
9 Standard boot provides a built-in way for U-Boot to automatically boot
10 an Operating System without custom scripting and other customisation. It
11 introduces 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
17 For Linux, the distro (Linux distribution, e.g. Debian, Fedora) is responsible
18 for creating a bootflow for each kernel combination that it wants to offer.
19 These bootflows are stored on media so they can be discovered by U-Boot. This
20 feature is typically called `distro boot` (see :doc:`distro`) because it is
21 a way for distributions to boot on any hardware.
22
23 Traditionally U-Boot has relied on scripts to implement this feature. See
24 distro_bootcmd_ for details. This is done because U-Boot has no native support
25 for scanning devices. While the scripts work remarkably well, they can be hard
26 to understand and extend, and the feature does not include tests. They are also
27 making it difficult to move away from ad-hoc CONFIGs, since they are implemented
28 using the environment and a lot of #defines.
29
30 Standard boot is a generalisation of distro boot. It provides a more built-in
31 way to boot with U-Boot. The feature is extensible to different Operating
32 Systems (such as Chromium OS) and devices (beyond just block and network
33 devices). It supports EFI boot and EFI bootmgr too.
34
35 Finally, standard boot supports the operation of :doc:`vbe`.
36
37 Bootflow
38 --------
39
40 A bootflow is a file that describes how to boot a distro. Conceptually there can
41 be different formats for that file but at present U-Boot only supports the
42 BootLoaderSpec_ format. which looks something like this::
43
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
54 As you can see it specifies a kernel, a ramdisk (initrd) and a directory from
55 which to load devicetree files. The details are described in distro_bootcmd_.
56
57 The bootflow is provided by the distro. It is not part of U-Boot. U-Boot's job
58 is simply to interpret the file and carry out the instructions. This allows
59 distros to boot on essentially any device supported by U-Boot.
60
61 Typically the first available bootflow is selected and booted. If that fails,
62 then the next one is tried.
63
64
65 Bootdev
66 -------
67
68 Where does U-Boot find the media that holds the operating systems? That is the
69 job of bootdev. A bootdev is simply a layer on top of a media device (such as
70 MMC, NVMe). The bootdev accesses the device, including partitions and
71 filesystems that might contain things related to an operating system.
72
73 For example, an MMC bootdev provides access to the individual partitions on the
74 MMC device. It scans through these to find filesystems with the boot flag set,
75 then provides a list of these for consideration.
76
77 Some bootdevs are not visible until a bus is enumerated, e.g. flash sticks
78 attached via USB. To deal with this, each bootdev has an associated 'hunter'
79 which can hunt for bootdevs of a particular uclass type. For example, the SCSI
80 bootdev scans the SCSI bus looking for devices, creating a bootdev for each
81 Logical Unit Number (LUN) that it finds.
82
83
84 Bootmeth
85 --------
86
87 Once the list of filesystems is provided, how does U-Boot find the bootflow
88 files in these filesystems. That is the job of bootmeth. Each boot method has
89 its own way of doing this.
90
91 For example, the distro bootmeth simply looks through the provided filesystem
92 for a file called `extlinux/extlinux.conf`. This files constitutes a bootflow.
93 If the distro bootmeth is used on multiple partitions it may produce multiple
94 bootflows.
95
96 Note: it is possible to have a bootmeth that uses a partition or a whole device
97 directly, but it is more common to use a filesystem.
98
99 Note that some bootmeths are 'global', meaning that they select the bootdev
100 themselves. Examples include VBE and EFI boot manager. In this case, they
101 provide a `read_bootflow()` method which checks whatever bootdevs it likes, then
102 returns the bootflow, if found. Some of these bootmeths may be very slow, if
103 they scan a lot of devices.
104
105
106 Boot process
107 ------------
108
109 U-Boot tries to use the 'lazy init' approach whereever possible and distro boot
110 is no exception. The algorithm is::
111
112    while (get next bootdev)
113       while (get next bootmeth)
114           while (get next bootflow)
115               try to boot it
116
117 So U-Boot works its way through the bootdevs, trying each bootmeth in turn to
118 obtain bootflows, until it either boots or exhausts the available options.
119
120 Instead of 500 lines of #defines and a 4KB boot script, all that is needed is
121 the following command::
122
123    bootflow scan -lb
124
125 which scans for available bootflows, optionally listing each find it finds (-l)
126 and trying to boot it (-b).
127
128 When global bootmeths are available, these are typically checked before the
129 above bootdev scanning.
130
131
132 Controlling ordering
133 --------------------
134
135 By default, faster bootdevs (or those which are assumed to be faster) are used
136 first, since they are more likely to be able to boot the device quickly.
137
138 Several options are available to control the ordering of boot scanning:
139
140
141 boot_targets
142 ~~~~~~~~~~~~
143
144 This environment variable can be used to control the list of bootdevs searched
145 and their ordering, for example::
146
147    setenv boot_targets "mmc0 mmc1 usb pxe"
148
149 Entries may be removed or re-ordered in this list to affect the boot order. If
150 the variable is empty, the default ordering is used, based on the priority of
151 bootdevs and their sequence numbers.
152
153
154 bootmeths
155 ~~~~~~~~~
156
157 By default bootmeths are checked in name order. Use `bootmeth list` to see the
158 ordering. Note that the `extlinux` and `script` bootmeth is first, to preserve the behaviour
159 used by the old distro scripts.
160
161 This environment variable can be used to control the list of bootmeths used and
162 their ordering for example::
163
164    setenv bootmeths "extlinux efi"
165
166 Entries may be removed or re-ordered in this list to affect the order the
167 bootmeths are tried on each bootdev. If the variable is empty, the default
168 ordering is used, based on the bootmeth sequence numbers, which can be
169 controlled by aliases.
170
171 The :ref:`usage/cmd/bootmeth:bootmeth command` (`bootmeth order`) operates in
172 the same way as setting this variable.
173
174 Bootdev uclass
175 --------------
176
177 The bootdev uclass provides an simple API call to obtain a bootflows from a
178 device::
179
180    int bootdev_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
181                             struct bootflow *bflow);
182
183 This takes a iterator which indicates the bootdev, partition and bootmeth to
184 use. It returns a bootflow. This is the core of the bootdev implementation. The
185 bootdev drivers that implement this differ depending on the media they are
186 reading from, but each is responsible for returning a valid bootflow if
187 available.
188
189 A helper called `bootdev_find_in_blk()` makes it fairly easy to implement this
190 function for each media device uclass, in a few lines of code. For many types
191 ot bootdevs, the `get_bootflow` member can be NULL, indicating that the default
192 handler is used. This is called `default_get_bootflow()` and it only works with
193 block devices.
194
195
196 Bootdev drivers
197 ---------------
198
199 A bootdev driver is typically fairly simple. Here is one for mmc::
200
201     static int mmc_bootdev_bind(struct udevice *dev)
202     {
203         struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
204
205         ucp->prio = BOOTDEVP_2_INTERNAL_FAST;
206
207         return 0;
208     }
209
210     struct bootdev_ops mmc_bootdev_ops = {
211     };
212
213     static const struct udevice_id mmc_bootdev_ids[] = {
214         { .compatible = "u-boot,bootdev-mmc" },
215         { }
216     };
217
218     U_BOOT_DRIVER(mmc_bootdev) = {
219         .name        = "mmc_bootdev",
220         .id        = UCLASS_BOOTDEV,
221         .ops        = &mmc_bootdev_ops,
222         .bind        = mmc_bootdev_bind,
223         .of_match    = mmc_bootdev_ids,
224     };
225
226 You may notice that the `get_bootflow` memory is not provided, so is NULL. This
227 means that `default_get_bootflow()` is used. This simply obtains the
228 block device and calls a bootdev helper function to do the rest. The
229 implementation of `bootdev_find_in_blk()` checks the partition table, and
230 attempts to read a file from a filesystem on the partition number given by the
231 `@iter->part` parameter. If there are any bootable partitions in the table,
232 then only bootable partitions are considered.
233
234 Each bootdev has a priority, which indicates the order in which it is used,
235 if `boot_targets` is not used. Faster bootdevs are used first, since they are
236 more likely to be able to boot the device quickly.
237
238
239 Environment Variables
240 ---------------------
241
242 Various environment variables are used by standard boot. These allow the board
243 to control where things are placed when booting the OS. You should ensure that
244 your boards sets values for these.
245
246 fdtfile
247     Name of the flattened device tree (FDT) file to load, e.g.
248     "rockchip/rk3399-rockpro64.dtb"
249
250 fdtaddr_addr_r
251     Address at which to load the FDT, e.g. 0x01f00000
252
253 fdtoverlay_addr_r (needed if overlays are used)
254     Address at which to load the overlay for the FDT, e.g. 0x02000000
255
256 kernel_addr_r
257     Address at which to load the kernel, e.g. 0x02080000
258
259 kernel_comp_addr_r
260     Address to which to decompress the kernel, e.g. 0x08000000
261
262 kernel_comp_size
263     Size of available space for decompressed kernel, e.g. 0x2000000
264
265 pxefile_addr_r
266     Address at which to load the PXE file, e.g. 0x00600000
267
268 ramdisk_addr_r
269     Address at which to load the ramdisk, e.g. 0x06000000
270
271 scriptaddr
272     Address at which to load the U-Boot script, e.g. 0x00500000
273
274 script_offset_f
275     SPI flash offset from which to load the U-Boot script, e.g. 0xffe000
276
277 script_size_f
278     Size of the script to load, e.g. 0x2000
279
280 Some variables are set by script bootmeth:
281
282 devtype
283     Device type being used for boot, e.g. mmc
284
285 devnum
286     Device number being used for boot, e.g. 1
287
288 distro_bootpart
289     Partition being used for boot, e.g. 2
290
291 prefix
292     Directory containing the script
293
294 mmc_bootdev
295     Device number being used for boot (e.g. 1). This is only used by MMC on
296     sunxi boards.
297
298
299 Device hierarchy
300 ----------------
301
302 A bootdev device is a child of the media device. In this example, you can see
303 that the bootdev is a sibling of the block device and both are children of
304 media device::
305
306     mmc           0  [ + ]   bcm2835-sdhost        |   |-- mmc@7e202000
307     blk           0  [ + ]   mmc_blk               |   |   |-- [email protected]
308     bootdev       0  [   ]   mmc_bootdev           |   |   `-- [email protected]
309     mmc           1  [ + ]   sdhci-bcm2835         |   |-- sdhci@7e300000
310     blk           1  [   ]   mmc_blk               |   |   |-- [email protected]
311     bootdev       1  [   ]   mmc_bootdev           |   |   `-- [email protected]
312
313 The bootdev device is typically created automatically in the media uclass'
314 `post_bind()` method by calling `bootdev_setup_for_dev()` or
315 `bootdev_setup_for_sibling_blk()`. The code typically something like this::
316
317     /* dev is the Ethernet device */
318     ret = bootdev_setup_for_dev(dev, "eth_bootdev");
319     if (ret)
320         return log_msg_ret("bootdev", ret);
321
322 or::
323
324     /* blk is the block device (child of MMC device)
325     ret = bootdev_setup_for_sibling_blk(blk, "mmc_bootdev");
326     if (ret)
327         return log_msg_ret("bootdev", ret);
328
329
330 Here, `eth_bootdev` is the name of the Ethernet bootdev driver and `dev`
331 is the ethernet device. This function is safe to call even if standard boot is
332 not enabled, since it does nothing in that case. It can be added to all uclasses
333 which implement suitable media.
334
335
336 The bootstd device
337 ------------------
338
339 Standard boot requires a single instance of the bootstd device to make things
340 work. This includes global information about the state of standard boot. See
341 `struct bootstd_priv` for this structure, accessed with `bootstd_get_priv()`.
342
343 Within the devicetree, if you add bootmeth devices, they should be children of
344 the bootstd device. See `arch/sandbox/dts/test.dts` for an example of this.
345
346
347 .. _`Automatic Devices`:
348
349 Automatic devices
350 -----------------
351
352 It is possible to define all the required devices in the devicetree manually,
353 but it is not necessary. The bootstd uclass includes a `dm_scan_other()`
354 function which creates the bootstd device if not found. If no bootmeth devices
355 are found at all, it creates one for each available bootmeth driver.
356
357 If your devicetree has any bootmeth device it must have all of them that you
358 want to use, since no bootmeth devices will be created automatically in that
359 case.
360
361
362 Using devicetree
363 ----------------
364
365 If a bootdev is complicated or needs configuration information, it can be
366 added to the devicetree as a child of the media device. For example, imagine a
367 bootdev which reads a bootflow from SPI flash. The devicetree fragment might
368 look like this::
369
370     spi@0 {
371         flash@0 {
372             reg = <0>;
373             compatible = "spansion,m25p16", "jedec,spi-nor";
374             spi-max-frequency = <40000000>;
375
376             bootdev {
377                 compatible = "u-boot,sf-bootdev";
378                 offset = <0x2000>;
379                 size = <0x1000>;
380             };
381         };
382     };
383
384 The `sf-bootdev` driver can implement a way to read from the SPI flash, using
385 the offset and size provided, and return that bootflow file back to the caller.
386 When distro boot wants to read the kernel it calls distro_getfile() which must
387 provide a way to read from the SPI flash. See `distro_boot()` at distro_boot_
388 for more details.
389
390 Of course this is all internal to U-Boot. All the distro sees is another way
391 to boot.
392
393
394 Configuration
395 -------------
396
397 Standard boot is enabled with `CONFIG_BOOTSTD`. Each bootmeth has its own CONFIG
398 option also. For example, `CONFIG_BOOTMETH_EXTLINUX` enables support for
399 booting from a disk using an `extlinux.conf` file.
400
401 To enable all feature sof standard boot, use `CONFIG_BOOTSTD_FULL`. This
402 includes the full set of commands, more error messages when things go wrong and
403 bootmeth ordering with the bootmeths environment variable.
404
405 You should probably also enable `CONFIG_BOOTSTD_DEFAULTS`, which provides
406 several filesystem and network features (if `CONFIG_NET` is enabled) so that
407 a good selection of boot options is available.
408
409
410 Available bootmeth drivers
411 --------------------------
412
413 Bootmeth drivers are provided for:
414
415    - extlinux / syslinux boot from a disk
416    - extlinux boot from a network (PXE)
417    - U-Boot scripts from disk, network or SPI flash
418    - EFI boot using bootefi from disk
419    - VBE
420    - EFI boot using boot manager
421
422
423 Command interface
424 -----------------
425
426 Three commands are available:
427
428 `bootdev`
429     Allows listing of available bootdevs, selecting a particular one and
430     getting information about it. See :doc:`../usage/cmd/bootdev`
431
432 `bootflow`
433     Allows scanning one or more bootdevs for bootflows, listing available
434     bootflows, selecting one, obtaining information about it and booting it.
435     See :doc:`../usage/cmd/bootflow`
436
437 `bootmeth`
438     Allow listing of available bootmethds and setting the order in which they
439     are tried. See :doc:`../usage/cmd/bootmeth`
440
441 .. _BootflowStates:
442
443 Bootflow states
444 ---------------
445
446 Here is a list of states that a bootflow can be in:
447
448 =======  =======================================================================
449 State    Meaning
450 =======  =======================================================================
451 base     Starting-out state, indicates that no media/partition was found. For an
452          SD card socket it may indicate that the card is not inserted.
453 media    Media was found (e.g. SD card is inserted) but no partition information
454          was found. It might lack a partition table or have a read error.
455 part     Partition was found but a filesystem could not be read. This could be
456          because the partition does not hold a filesystem or the filesystem is
457          very corrupted.
458 fs       Filesystem was found but the file could not be read. It could be
459          missing or in the wrong subdirectory.
460 file     File was found and its size detected, but it could not be read. This
461          could indicate filesystem corruption.
462 ready    File was loaded and is ready for use. In this state the bootflow is
463          ready to be booted.
464 =======  =======================================================================
465
466
467 Theory of operation
468 -------------------
469
470 This describes how standard boot progresses through to booting an operating
471 system.
472
473 To start. all the necessary devices must be bound, including bootstd, which
474 provides the top-level `struct bootstd_priv` containing optional configuration
475 information. The bootstd device is also holds the various lists used while
476 scanning. This step is normally handled automatically by driver model, as
477 described in `Automatic Devices`_.
478
479 Bootdevs are also required, to provide access to the media to use. These are not
480 useful by themselves: bootmeths are needed to provide the means of scanning
481 those bootdevs. So, all up, we need a single bootstd device, one or more bootdev
482 devices and one or more bootmeth devices.
483
484 Once these are ready, typically a `bootflow scan` command is issued. This kicks
485 of the iteration process, which involves hunting for bootdevs and looking
486 through the bootdevs and their partitions one by one to find bootflows.
487
488 Iteration is kicked off using `bootflow_scan_first()`.
489
490 The iterator is set up with `bootflow_iter_init()`. This simply creates an
491 empty one with the given flags. Flags are used to control whether each
492 iteration is displayed, whether to return iterations even if they did not result
493 in a valid bootflow, whether to iterate through just a single bootdev, etc.
494
495 Then the iterator is set up to according to the parameters given:
496
497 - When `dev` is provided, then a single bootdev is scanned. In this case,
498   `BOOTFLOWIF_SKIP_GLOBAL` and `BOOTFLOWIF_SINGLE_DEV` are set. No hunters are
499   used in this case
500
501 - Otherwise, when `label` is provided, then a single label or named bootdev is
502   scanned. In this case `BOOTFLOWIF_SKIP_GLOBAL` is set and there are three
503   options (with an effect on the `iter_incr()` function described later):
504
505   - If `label` indicates a numeric bootdev number (e.g. "2") then
506     `BOOTFLOW_METHF_SINGLE_DEV` is set. In this case, moving to the next bootdev
507     simple stops, since there is only one. No hunters are used.
508   - If `label` indicates a particular media device (e.g. "mmc1") then
509     `BOOTFLOWIF_SINGLE_MEDIA` is set. In this case, moving to the next bootdev
510     processes just the children of the media device. Hunters are used, in this
511     example just the "mmc" hunter.
512   - If `label` indicates a media uclass (e.g. "mmc") then
513     `BOOTFLOWIF_SINGLE_UCLASS` is set. In this case, all bootdevs in that uclass
514     are used. Hunters are used, in this example just the "mmc" hunter
515
516 - Otherwise, none of the above flags is set and iteration is set up to work
517   through `boot_targets` environment variable (or `bootdev-order` device tree
518   property) in order, running the relevant hunter first. In this case
519   `cur_label` is used to indicate the label being processed. If there is no list
520   of labels, then all bootdevs are processed in order of priority, running the
521   hunters as it goes.
522
523 With the above it is therefore possible to iterate in a variety of ways.
524
525 No attempt is made to determine the ordering of bootdevs, since this cannot be
526 known in advance if we are using the hunters. Any hunter might discover a new
527 bootdev and disturb the original ordering.
528
529 Next, the ordering of bootmeths is determined, by `bootmeth_setup_iter_order()`.
530 By default the ordering is again by sequence number, i.e. the `/aliases` node,
531 or failing that the order in the devicetree. But the `bootmeth order` command
532 or `bootmeths` environment variable can be used to set up an ordering. If that
533 has been done, the ordering is in `struct bootstd_priv`, so that ordering is
534 simply copied into the iterator. Either way, the `method_order` array it set up,
535 along with `num_methods`.
536
537 Note that global bootmeths are always put at the end of the ordering. If any are
538 present, `cur_method` is set to the first one, so that global bootmeths are done
539 first. Once all have been used, these bootmeths are dropped from the iteration.
540 When there are no global bootmeths, `cur_method` is set to 0.
541
542 At this point the iterator is ready to use, with the first bootmeth selected.
543 Most of the other fields are 0. This means that the current partition
544 is 0, which is taken to mean the whole device, since partition numbers start at
545 1. It also means that `max_part` is 0, i.e. the maximum partition number we know
546 about is 0, meaning that, as far as we know, there is no partition table on this
547 bootdev.
548
549 With the iterator ready, `bootflow_scan_first()` checks whether the current
550 settings produce a valid bootflow. This is handled by `bootflow_check()`, which
551 either returns 0 (if it got something) or an error if not (more on that later).
552 If the `BOOTFLOWIF_ALL` iterator flag is set, even errors are returned as
553 incomplete bootflows, but normally an error results in moving onto the next
554 iteration.
555
556 Note that `bootflow_check()` handles global bootmeths explicitly, by calling
557 `bootmeth_get_bootflow()` on each one. The `doing_global` flag indicates when
558 the iterator is in that state.
559
560 The `bootflow_scan_next()` function handles moving onto the next iteration and
561 checking it. In fact it sits in a loop doing that repeatedly until it finds
562 something it wants to return.
563
564 The actual 'moving on' part is implemented in `iter_incr()`. This is a fairly
565 simple function. It increments the first counter. If that hits its maximum, it
566 sets it to zero and increments the second counter. You can think of all the
567 counters together as a number with three digits which increment in order, with
568 the least-sigificant digit on the right, counting like this:
569
570    ========    =======    =======
571    bootdev     part       method
572    ========    =======    =======
573    0           0          0
574    0           0          1
575    0           0          2
576    0           1          0
577    0           1          1
578    0           1          2
579    1           0          0
580    1           0          1
581    ...
582    ========    =======    =======
583
584 The maximum value for `method` is `num_methods - 1` so when it exceeds that, it
585 goes back to 0 and the next `part` is considered. The maximum value for that is
586 `max_part`, which is initially zero for all bootdevs. If we find a partition
587 table on that bootdev, `max_part` can be updated during the iteration to a
588 higher value - see `bootdev_find_in_blk()` for that, described later. If that
589 exceeds its maximum, then the next bootdev is used. In this way, iter_incr()
590 works its way through all possibilities, moving forward one each time it is
591 called.
592
593 Note that global bootmeths introduce a subtlety into the above description.
594 When `doing_global` is true, the iteration takes place only among the bootmeths,
595 i.e. the last column above. The global bootmeths are at the end of the list.
596 Assuming that they are entries 3 and 4 in the list, the iteration then looks
597 like this:
598
599    ========    =======    =======   =======================================
600    bootdev     part       method    notes
601    ========    =======    =======   =======================================
602    .           .          3         doing_global = true, method_count = 5
603    .           .          4
604    0           0          0         doing_global = false, method_count = 3
605    0           0          1
606    0           0          2
607    0           1          0
608    0           1          1
609    0           1          2
610    1           0          0
611    1           0          1
612    ...
613    ========    =======    =======   =======================================
614
615 The changeover of the value of `doing_global` from true to false is handled in
616 `iter_incr()` as well.
617
618 Note that the value in the `bootdev` column above is not actually stored - it is
619 just for illustration. In practice, `iter_incr()` uses the flags to determine
620 whether to move to the next bootdev in the uclass, the next child of the media
621 device, the next label, or the next priority level, depending on the flag
622 settings (see `BOOTFLOW_METHF_SINGLE_DEV`, etc. above).
623
624 There is no expectation that iteration will actually finish. Quite often a
625 valid bootflow is found early on. With `bootflow scan -b`, that causes the
626 bootflow to be immediately booted. Assuming it is successful, the iteration never
627 completes.
628
629 Also note that the iterator hold the **current** combination being considered.
630 So when `iter_incr()` is called, it increments to the next one and returns it,
631 the new **current** combination.
632
633 Note also the `err` field in `struct bootflow_iter`. This is normally 0 and has
634 thus has no effect on `iter_inc()`. But if it is non-zero, signalling an error,
635 it indicates to the iterator what it should do when called. It can force moving
636 to the next partition, or bootdev, for example. The special values
637 `BF_NO_MORE_PARTS` and `BF_NO_MORE_DEVICES` handle this. When `iter_incr` sees
638 `BF_NO_MORE_PARTS` it knows that it should immediately move to the next bootdev.
639 When it sees `BF_NO_MORE_DEVICES` it knows that there is nothing more it can do
640 so it should immediately return. The caller of `iter_incr()` is responsible for
641 updating the `err` field, based on the return value it sees.
642
643 The above describes the iteration process at a high level. It is basically a
644 very simple increment function with a checker called `bootflow_check()` that
645 checks the result of each iteration generated, to determine whether it can
646 produce a bootflow.
647
648 So what happens inside of `bootflow_check()`? It simply calls the uclass
649 method `bootdev_get_bootflow()` to ask the bootdev to return a bootflow. It
650 passes the iterator to the bootdev method, so that function knows what we are
651 talking about. At first, the bootflow is set up in the state `BOOTFLOWST_BASE`,
652 with just the `method` and `dev` intiialised. But the bootdev may fill in more,
653 e.g. updating the state, depending on what it finds. For global bootmeths the
654 `bootmeth_get_bootflow()` function is called instead of
655 `bootdev_get_bootflow()`.
656
657 Based on what the bootdev or bootmeth responds with, `bootflow_check()` either
658 returns a valid bootflow, or a partial one with an error. A partial bootflow
659 is one that has some fields set up, but did not reach the `BOOTFLOWST_READY`
660 state. As noted before, if the `BOOTFLOWIF_ALL` iterator flag is set, then all
661 bootflows are returned, even partial ones. This can help with debugging.
662
663 So at this point you can see that total control over whether a bootflow can
664 be generated from a particular iteration, or not, rests with the bootdev (or
665 global bootmeth). Each one can adopt its own approach.
666
667 Going down a level, what does the bootdev do in its `get_bootflow()` method?
668 Let us consider the MMC bootdev. In that case the call to
669 `bootdev_get_bootflow()` ends up in `default_get_bootflow()`. It locates the
670 parent device of the bootdev, i.e. the `UCLASS_MMC` device itself, then finds
671 the block device associated with it. It then calls the helper function
672 `bootdev_find_in_blk()` to do all the work. This is common with just about any
673 bootdev that is based on a media device.
674
675 The `bootdev_find_in_blk()` helper is implemented in the bootdev uclass. It
676 names the bootflow and copies the partition number in from the iterator. Then it
677 calls the bootmeth device to check if it can support this device. This is
678 important since some bootmeths only work with network devices, for example. If
679 that check fails, it stops.
680
681 Assuming the bootmeth is happy, or at least indicates that it is willing to try
682 (by returning 0 from its `check()` method), the next step is to try the
683 partition. If that works it tries to detect a file system. If that works then it
684 calls the bootmeth device once more, this time to read the bootflow.
685
686 Note: Normally a filesystem is needed for the bootmeth to be called on block
687 devices, but bootmeths which don't need that can set the BOOTMETHF_ANY_PART
688 flag to indicate that they can scan any partition. An example is the ChromiumOS
689 bootmeth which can store a kernel in a raw partition. Note also that sandbox is
690 a special case, since in that case the host filesystem can be accessed even
691 though the block device is NULL.
692
693 If we take the example of the `bootmeth_extlinux` driver, this call ends up at
694 `extlinux_read_bootflow()`. It has the filesystem ready, so tries various
695 filenames to try to find the `extlinux.conf` file, reading it if possible. If
696 all goes well the bootflow ends up in the `BOOTFLOWST_READY` state.
697
698 At this point, we fall back from the bootmeth driver, to
699 `bootdev_find_in_blk()`, then back to `default_get_bootflow()`, then to
700 `bootdev_get_bootflow()`, then to `bootflow_check()` and finally to its caller,
701 either `bootflow_scan_first()` or `bootflow_scan_next()`. In either case,
702 the bootflow is returned as the result of this iteration, assuming it made it to
703 the  `BOOTFLOWST_READY` state.
704
705 That is the basic operation of scanning for bootflows. The process of booting a
706 bootflow is handled by the bootmeth driver for that bootflow. In the case of
707 extlinux boot, this parses and processes the `extlinux.conf` file that was read.
708 See `extlinux_boot()` for how that works. The processing may involve reading
709 additional files, which is handled by the `read_file()` method, which is
710 `extlinux_read_file()` in this case. All bootmethds should support reading
711 files, since the bootflow is typically only the basic instructions and does not
712 include the operating system itself, ramdisk, device tree, etc.
713
714 The vast majority of the bootstd code is concerned with iterating through
715 partitions on bootdevs and using bootmethds to find bootflows.
716
717 How about bootdevs which are not block devices? They are handled by the same
718 methods as above, but with a different implementation. For example, the bootmeth
719 for PXE boot (over a network) uses `tftp` to read files rather than `fs_read()`.
720 But other than that it is very similar.
721
722
723 Tests
724 -----
725
726 Tests are located in `test/boot` and cover the core functionality as well as
727 the commands. All tests use sandbox so can be run on a standard Linux computer
728 and in U-Boot's CI.
729
730 For testing, a DOS-formatted disk image is used with a FAT partition on it and
731 a second unused partition. This is created in `setup_bootflow_image()`, with a
732 canned one from the source tree used if it cannot be created (e.g. in CI).
733
734
735 Bootflow internals
736 ------------------
737
738 The bootstd device holds a linked list of scanned bootflows as well as the
739 currently selected bootdev and bootflow (for use by commands). This is in
740 `struct bootstd_priv`.
741
742 Each bootdev device has its own `struct bootdev_uc_plat` which holds a
743 list of scanned bootflows just for that device.
744
745 The bootflow itself is documented in bootflow_h_. It includes various bits of
746 information about the bootflow and a buffer to hold the file.
747
748
749 Future
750 ------
751
752 Apart from the to-do items below, different types of bootflow files may be
753 implemented in future, e.g. Chromium OS support which is currently only
754 available as a script in chromebook_coral.
755
756
757 To do
758 -----
759
760 Some things that need to be done to completely replace the distro-boot scripts:
761
762 - add bootdev drivers for dhcp, sata, scsi, ide, virtio
763 - PXE boot for EFI
764 - support for loading U-Boot scripts
765
766 Other ideas:
767
768 - `bootflow prep` to load everything preparing for boot, so that `bootflow boot`
769   can just do the boot.
770 - automatically load kernel, FDT, etc. to suitable addresses so the board does
771   not need to specify things like `pxefile_addr_r`
772
773
774 .. _distro_bootcmd: https://github.com/u-boot/u-boot/blob/master/include/config_distro_bootcmd.h
775 .. _BootLoaderSpec: http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/
776 .. _distro_boot: https://github.com/u-boot/u-boot/blob/master/boot/distro.c
777 .. _bootflow_h: https://github.com/u-boot/u-boot/blob/master/include/bootflow.h
This page took 0.070843 seconds and 4 git commands to generate.