bootstd: Update documentation
Add some documentation updates, particularly about global bootmeths. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
0917f77393
commit
228fe57ad2
@ -90,6 +90,12 @@ bootflows.
|
||||
Note: it is possible to have a bootmeth that uses a partition or a whole device
|
||||
directly, but it is more common to use a filesystem.
|
||||
|
||||
Note that some bootmeths are 'global', meaning that they select the bootdev
|
||||
themselves. Examples include VBE and EFI boot manager. In this case, they
|
||||
provide a `read_bootflow()` method which checks whatever bootdevs it likes, then
|
||||
returns the bootflow, if found. Some of these bootmeths may be very slow, if
|
||||
they scan a lot of devices.
|
||||
|
||||
|
||||
Boot process
|
||||
------------
|
||||
@ -113,6 +119,9 @@ the following command::
|
||||
which scans for available bootflows, optionally listing each find it finds (-l)
|
||||
and trying to boot it (-b).
|
||||
|
||||
When global bootmeths are available, these are typically checked before the
|
||||
above bootdev scanning.
|
||||
|
||||
|
||||
Controlling ordering
|
||||
--------------------
|
||||
@ -270,18 +279,8 @@ Standard boot requires a single instance of the bootstd device to make things
|
||||
work. This includes global information about the state of standard boot. See
|
||||
`struct bootstd_priv` for this structure, accessed with `bootstd_get_priv()`.
|
||||
|
||||
Within the devicetree, if you add bootmeth devices or a system bootdev, they
|
||||
should be children of the bootstd device. See `arch/sandbox/dts/test.dts` for
|
||||
an example of this.
|
||||
|
||||
|
||||
The system bootdev
|
||||
------------------
|
||||
|
||||
Some bootmeths don't operate on individual bootdevs, but on the whole system.
|
||||
For example, the EFI boot manager does its own device scanning and does not
|
||||
make use of the bootdev devices. Such bootmeths can make use of the system
|
||||
bootdev, typically considered last, after everything else has been tried.
|
||||
Within the devicetree, if you add bootmeth devices, they should be children of
|
||||
the bootstd device. See `arch/sandbox/dts/test.dts` for an example of this.
|
||||
|
||||
|
||||
.. _`Automatic Devices`:
|
||||
@ -292,12 +291,11 @@ Automatic devices
|
||||
It is possible to define all the required devices in the devicetree manually,
|
||||
but it is not necessary. The bootstd uclass includes a `dm_scan_other()`
|
||||
function which creates the bootstd device if not found. If no bootmeth devices
|
||||
are found at all, it creates one for each available bootmeth driver as well as a
|
||||
system bootdev.
|
||||
are found at all, it creates one for each available bootmeth driver.
|
||||
|
||||
If your devicetree has any bootmeth device it must have all of them that you
|
||||
want to use, as well as the system bootdev if needed, since no bootmeth devices
|
||||
will be created automatically in that case.
|
||||
want to use, since no bootmeth devices will be created automatically in that
|
||||
case.
|
||||
|
||||
|
||||
Using devicetree
|
||||
@ -348,6 +346,7 @@ Bootmeth drivers are provided for:
|
||||
- distro boot from a disk (syslinux)
|
||||
- distro boot from a network (PXE)
|
||||
- EFI boot using bootefi
|
||||
- VBE
|
||||
- EFI boot using boot manager
|
||||
|
||||
|
||||
@ -434,18 +433,23 @@ case, the iterator ends up with a `dev_order` array containing the bootdevs that
|
||||
are going to be used, with `num_devs` set to the number of bootdevs and
|
||||
`cur_dev` starting at 0.
|
||||
|
||||
Next, the ordering of bootdevs is determined, by `bootmeth_setup_iter_order()`.
|
||||
Next, the ordering of bootmeths is determined, by `bootmeth_setup_iter_order()`.
|
||||
By default the ordering is again by sequence number, i.e. the `/aliases` node,
|
||||
or failing that the order in the devicetree. But the `bootmeth order` command
|
||||
or `bootmeths` environment variable can be used to set up an ordering. If that
|
||||
has been done, the ordering is in `struct bootstd_priv`, so that ordering is
|
||||
simply copied into the iterator. Either way, the `method_order` array it set up,
|
||||
along with `num_methods`. Then `cur_method` is set to 0.
|
||||
along with `num_methods`.
|
||||
|
||||
Note that global bootmeths are always put at the end of the ordering. If any are
|
||||
present, `cur_method` is set to the first one, so that global bootmeths are done
|
||||
first. Once all have been used, these bootmeths are dropped from the iteration.
|
||||
When there are no global bootmeths, `cur_method` is set to 0.
|
||||
|
||||
At this point the iterator is ready to use, with the first bootdev and bootmeth
|
||||
selected. All the other fields are 0. This means that the current partition is
|
||||
0, which is taken to mean the whole device, since partition numbers start at 1.
|
||||
It also means that `max_part` is 0, i.e. the maximum partition number we know
|
||||
selected. Most of the other fields are 0. This means that the current partition
|
||||
is 0, which is taken to mean the whole device, since partition numbers start at
|
||||
1. It also means that `max_part` is 0, i.e. the maximum partition number we know
|
||||
about is 0, meaning that, as far as we know, there is no partition table on this
|
||||
bootdev.
|
||||
|
||||
@ -456,6 +460,10 @@ If the `BOOTFLOWF_ALL` iterator flag is set, even errors are returned as
|
||||
incomplete bootflows, but normally an error results in moving onto the next
|
||||
iteration.
|
||||
|
||||
Note that `bootflow_check()` handles global bootmeths explicitly, but calling
|
||||
`bootmeth_get_bootflow()` on each one. The `doing_global` flag indicates when
|
||||
the iterator is in that state.
|
||||
|
||||
The `bootflow_scan_next()` function handles moving onto the next iteration and
|
||||
checking it. In fact it sits in a loop doing that repeatedly until it finds
|
||||
something it wants to return.
|
||||
@ -474,9 +482,10 @@ the least-sigificant digit on the right, counting like this:
|
||||
0 0 2
|
||||
0 1 0
|
||||
0 1 1
|
||||
0 1 1
|
||||
0 1 2
|
||||
1 0 0
|
||||
1 0 1
|
||||
...
|
||||
======== ======= =======
|
||||
|
||||
The maximum value for `method` is `num_methods - 1` so when it exceeds that, it
|
||||
@ -488,6 +497,31 @@ exceeds its maximum, then the next bootdev is used. In this way, iter_incr()
|
||||
works its way through all possibilities, moving forward one each time it is
|
||||
called.
|
||||
|
||||
Note that global bootmeths introduce a subtlety into the above description.
|
||||
When `doing_global` is true, the iteration takes place only among the bootmeths,
|
||||
i.e. the last column above. The global bootmeths are at the end of the list.
|
||||
Assuming that they are entries 3 and 4 in the list, the iteration then looks
|
||||
like this:
|
||||
|
||||
======== ======= ======= =======================================
|
||||
bootdev part method notes
|
||||
======== ======= ======= =======================================
|
||||
. . 3 doing_global = true, method_count = 5
|
||||
. . 4
|
||||
0 0 0 doing_global = false, method_count = 3
|
||||
0 0 1
|
||||
0 0 2
|
||||
0 1 0
|
||||
0 1 1
|
||||
0 1 2
|
||||
1 0 0
|
||||
1 0 1
|
||||
...
|
||||
======== ======= ======= =======================================
|
||||
|
||||
The changeover of the value of `doing_global` from true to false is handled in
|
||||
`iter_incr()` as well.
|
||||
|
||||
There is no expectation that iteration will actually finish. Quite often a
|
||||
valid bootflow is found early on. With `bootflow scan -b`, that causes the
|
||||
bootflow to be immediately booted. Assuming it is successful, the iteration never
|
||||
@ -517,17 +551,19 @@ method `bootdev_get_bootflow()` to ask the bootdev to return a bootflow. It
|
||||
passes the iterator to the bootdev method, so that function knows what we are
|
||||
talking about. At first, the bootflow is set up in the state `BOOTFLOWST_BASE`,
|
||||
with just the `method` and `dev` intiialised. But the bootdev may fill in more,
|
||||
e.g. updating the state, depending on what it finds.
|
||||
e.g. updating the state, depending on what it finds. For global bootmeths the
|
||||
`bootmeth_get_bootflow()` function is called instead of
|
||||
`bootdev_get_bootflow()`.
|
||||
|
||||
Based on what the bootdev responds with, `bootflow_check()` either
|
||||
Based on what the bootdev or bootmeth responds with, `bootflow_check()` either
|
||||
returns a valid bootflow, or a partial one with an error. A partial bootflow
|
||||
is one that has some fields set up, but did not reach the `BOOTFLOWST_READY`
|
||||
state. As noted before, if the `BOOTFLOWF_ALL` iterator flag is set, then all
|
||||
bootflows are returned, even partial ones. This can help with debugging.
|
||||
|
||||
So at this point you can see that total control over whether a bootflow can
|
||||
be generated from a particular iteration, or not, rests with the bootdev.
|
||||
Each one can adopt its own approach.
|
||||
be generated from a particular iteration, or not, rests with the bootdev (or
|
||||
global bootmeth). Each one can adopt its own approach.
|
||||
|
||||
Going down a level, what does the bootdev do in its `get_bootflow()` method?
|
||||
Let us consider the MMC bootdev. In that case the call to
|
||||
|
@ -31,7 +31,9 @@ scanning bootdevs, each bootmeth is tried in turn to see if it can find a valid
|
||||
bootflow. You can use this command to adjust the order or even to omit some
|
||||
boomeths.
|
||||
|
||||
The argument is a quoted list of bootmeths to use, by name.
|
||||
The argument is a quoted list of bootmeths to use, by name. If global bootmeths
|
||||
are included, they must be at the end, otherwise the scanning mechanism will not
|
||||
work correctly.
|
||||
|
||||
|
||||
bootmeth list
|
||||
@ -47,14 +49,15 @@ Order Seq Name Description
|
||||
1 1 efi EFI boot from an .efi file
|
||||
2 2 pxe PXE boot from a network device
|
||||
3 3 sandbox Sandbox boot for testing
|
||||
4 4 efi_mgr EFI bootmgr flow
|
||||
glob 4 efi_mgr EFI bootmgr flow
|
||||
===== === ================== =================================
|
||||
|
||||
The fields are as follows:
|
||||
|
||||
Order:
|
||||
The order in which these bootmeths are invoked for each bootdev. If this
|
||||
shows as a hyphen, then the bootmeth is not in the current ordering.
|
||||
shows as a hyphen, then the bootmeth is not in the current ordering. If it
|
||||
shows as 'glob', then this is a global bootmeth and should be at the end.
|
||||
|
||||
Seq:
|
||||
The sequence number of the bootmeth, i.e. the normal ordering if none is set
|
||||
|
Loading…
Reference in New Issue
Block a user