[PATCH 24/28] bootmethod: doc: Add documentation

Simon Glass sjg at chromium.org
Thu Aug 19 05:45:57 CEST 2021


Add documentation for this feature, including the commands.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

 MAINTAINERS                             |   3 +
 doc/develop/bootflow.rst                | 323 ++++++++++++++++++
 doc/develop/index.rst                   |   1 +
 doc/device-tree-bindings/bootmethod.txt |  14 +
 doc/usage/bootflow.rst                  | 419 ++++++++++++++++++++++++
 doc/usage/bootmethod.rst                | 138 ++++++++
 doc/usage/index.rst                     |   2 +
 7 files changed, 900 insertions(+)
 create mode 100644 doc/develop/bootflow.rst
 create mode 100644 doc/device-tree-bindings/bootmethod.txt
 create mode 100644 doc/usage/bootflow.rst
 create mode 100644 doc/usage/bootmethod.rst

diff --git a/MAINTAINERS b/MAINTAINERS
index 2f74f7dbb19..f472a589f61 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -637,6 +637,9 @@ F:	boot/bootmethod.c
 F:	boot/distro.c
 F:	cmd/bootflow.c
 F:	cmd/bootmethod.c
+F:	doc/develop/bootflow.rst
+F:	doc/usage/bootflow.rst
+F:	doc/usage/bootmethod.rst
 F:	include/bootmethod.h
 F:	include/distro.h
 F:	test/boot/bootmethod.c
diff --git a/doc/develop/bootflow.rst b/doc/develop/bootflow.rst
new file mode 100644
index 00000000000..930952cf2c4
--- /dev/null
+++ b/doc/develop/bootflow.rst
@@ -0,0 +1,323 @@
+.. SPDX-License-Identifier: GPL-2.0+:
+
+Bootmethod and Bootflow
+=======================
+
+Introduction
+------------
+
+Bootmethod and bootflow provide a built-in way for U-Boot to automatically boot
+an Operating System without custom scripting and other customisation:
+
+  - bootmethod - a method to scan a device to find bootflows (owned by U-Boot)
+  - bootflow - a description of how to boot (owned by the distro)
+
+For Linux, the distro (Linux distribution, e.g. Debian, Fedora) is responsible
+for creating a bootflow for each kernel combination that it wants to offer.
+These bootflows are stored on media so they can be discovered by U-Boot.
+
+This feature is typically called `distro boot` (see :doc:`distro`) because it is
+a way for distributions to boot on any hardware.
+
+Traditionally U-Boot has relied on scripts to implement this feature. See
+disto_boodcmd_ for details. This is done because U-Boot has no native support
+for scanning devices. While the scripts work remarkably well, they can be hard
+to understand and extend, and the feature does not include tests.
+
+Bootmethod and bootflow together provide a more built-in way to boot with
+U-Boot. The feature is extensible to different Operating Systems (such as
+Chromium OS) and devices (beyond just block and network devices).
+
+
+Bootflow
+--------
+
+A bootflow is a file that describes how to boot a distro. Conceptually there can
+be different formats for that file but at present U-Boot only supports the
+BootLoaderSpec_ format. which looks something like this::
+
+   menu autoboot Welcome to Fedora-Workstation-armhfp-31-1.9. Automatic boot in # second{,s}. Press a key for options.
+   menu title Fedora-Workstation-armhfp-31-1.9 Boot Options.
+   menu hidden
+
+   label Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl)
+       kernel /vmlinuz-5.3.7-301.fc31.armv7hl
+       append ro root=UUID=9732b35b-4cd5-458b-9b91-80f7047e0b8a rhgb quiet LANG=en_US.UTF-8 cma=192MB cma=256MB
+       fdtdir /dtb-5.3.7-301.fc31.armv7hl/
+       initrd /initramfs-5.3.7-301.fc31.armv7hl.img
+
+As you can see it specifies a kernel, a ramdisk (initrd) and a directory from
+which to load devicetree files. The details are described in disto_boodcmd_.
+
+The bootflow is provided by the distro. It is not part of U-Boot. U-Boot's job
+is simply to interpret the file and carry out the instructions. This allows
+distros to boot on essentially any device supported by U-Boot.
+
+Typically the first available bootflow is selected and booted. If that fails,
+then the next one is tried.
+
+
+Bootmethod
+----------
+
+How does U-Boot find the bootflow files? That is the job of bootmethods.
+A bootmethod is simply a device that locates bootflow files. For example, an
+MMC bootmethod for distro boot would simply scan through the partitions on the
+MMC to find valid filesystems, then search each filesystem for a file called
+`extlinux/extlinux.conf`. Each of those files constitutes a bootflow, so the
+MMC device may produce multiple bootflows. Of course that is under control of
+the bootmethod.
+
+
+Boot process
+------------
+
+U-Boot tries to use the 'lazy init' approach whereever possible and distro boot
+is no exception. The algorithm is:
+
+   while (get next bootmethod)
+      while (get next bootflow)
+          try to boot it
+
+So U-Boot works its way through the bootmethods, trying in turn the bootflows
+provided by each, until it either boots or exhausts the available options.
+
+If you are familiar with the producer–consumer model, bootmethods are the
+producers and bootflows are the items produced. The consumer is the 'booter'
+which tries to boot each produced item.
+
+Instead of 500 lines of #defines and a 4KB boot script, all that is needed is
+the following command::
+
+   bootflow scan -lb
+
+which scans for available bootflows, listing each find it finds (-l) and trying
+to boot it (-b).
+
+
+Bootmethod uclass
+-----------------
+
+The bootmethod uclass provides an simple API call to obtain one or more
+bootflows from a device::
+
+   int bootmethod_get_bootflow(struct udevice *dev, int seq,
+                               struct bootflow *bflow);
+
+This takes a sequence number (0 for the first bootflow, 1 for the next) and
+returnS a bootflow. This is the core of the bootmethod implementation. The
+bootmethod drivers that implement this differ depending on the media they are
+reading from, but each is responsible for returning a valid bootflow if
+available.
+
+
+Bootmethod drivers
+------------------
+
+A bootmethod driver is typically fairly simple. Here is one for mmc::
+
+    static int mmc_get_bootflow(struct udevice *dev, int seq,
+                    struct bootflow *bflow)
+    {
+        struct udevice *mmc_dev = dev_get_parent(dev);
+        struct udevice *blk;
+        int ret;
+
+        ret = mmc_get_blk(mmc_dev, &blk);
+        /*
+         * If there is no media, indicate that no more partitions should be
+         * checked
+         */
+        if (ret == -EOPNOTSUPP)
+            ret = -ESHUTDOWN;
+        if (ret)
+            return log_msg_ret("blk", ret);
+        assert(blk);
+        ret = bootmethod_find_in_blk(dev, blk, seq, bflow);
+        if (ret)
+            return log_msg_ret("find", ret);
+
+        return 0;
+    }
+
+    struct bootmethod_ops mmc_bootmethod_ops = {
+        .get_bootflow    = mmc_get_bootflow,
+    };
+
+    U_BOOT_DRIVER(mmc_bootmethod) = {
+        .name        = "mmc_bootmethod",
+        .id        = UCLASS_BOOTMETHOD,
+        .ops        = &mmc_bootmethod_ops,
+    };
+
+The implementation of the `get_bootflow` method is simply to obtain the
+block device and call a bootmethod helper function to do the rest. The
+implementation of `bootmethod_find_in_blk()` checks the partition table, and
+attempts to read a file from a filesystem on the partition number given by the
+ at seq parameter.
+
+
+Device hierarchy
+----------------
+
+A bootmethod device is a child of the media device. In this example, you can see
+that the bootmethod is a sibling of the block device and both are children of
+media device::
+
+    mmc           0  [ + ]   bcm2835-sdhost        |   |-- mmc at 7e202000
+    blk           0  [ + ]   mmc_blk               |   |   |-- mmc at 7e202000.blk
+    bootmethod    0  [   ]   mmc_bootmethod        |   |   `-- mmc at 7e202000.bootmethod
+    mmc           1  [ + ]   sdhci-bcm2835         |   |-- sdhci at 7e300000
+    blk           1  [   ]   mmc_blk               |   |   |-- sdhci at 7e300000.blk
+    bootmethod    1  [   ]   mmc_bootmethod        |   |   `-- sdhci at 7e300000.bootmethod
+
+The bootmethod device is typically created automatically in the media uclass'
+`post_bind()` method. This is typically something like this::
+
+    ret = bootmethod_setup_for_dev(dev, "eth_bootmethod");
+        if (ret)
+            return log_msg_ret("bootmethod", ret);
+
+Here, `eth_bootmethod` is the name of the Ethernet bootmethod driver and `dev`
+is the ethernet device. This function is safe to call even if bootmethod is
+not enabled, since it does nothing in that case. It can be added to all uclasses
+which implement suitable media.
+
+
+Using devicetree
+----------------
+
+If a bootmethod is complicated or needs configuration information, it can be
+added to the devicetree as a child of the media device. For example, imagine a
+bootmethod which reads a bootflow from SPI flash. The devicetree fragment might
+look like this::
+
+    spi at 0 {
+        flash at 0 {
+            reg = <0>;
+            compatible = "spansion,m25p16", "jedec,spi-nor";
+            spi-max-frequency = <40000000>;
+
+            bootmethod {
+                compatible = "sf-bootmethod";
+                offset = <0x2000>;
+                size = <0x1000>;
+            };
+        };
+    };
+
+The `sf-bootmethod` driver can implement a way to read from the SPI flash, using
+the offset and size provided, and return that bootflow file back to the caller.
+When distro boot wants to read the kernel it calls disto_getfile() which must
+provide a way to read from the SPI flash. See `distro_boot()` at distro_boot_
+for more details.
+
+Of course this is all internal to U-Boot. All the distro sees is another way
+to boot.
+
+
+Configuration
+-------------
+
+The bootmethod/bootflow feature can be enabled with `CONFIG_BOOTMETHOD`. Each
+type of bootflow has its own CONFIG option also. For example,
+`CONFIG_BOOTMETHOD_DISTRO` enables support for distro boot.
+
+
+Command interface
+-----------------
+
+Two commands are available:
+
+`bootmethod`
+    Allows listing of available bootmethods, selecting a particular one and
+    getting information about it. See :doc:`../usage/bootmethod`
+
+`bootflow`
+    Allows scanning one or more bootmethods for bootflows, listing available
+    bootflows, selecting one, obtaining information about it and booting it.
+    See :doc:`../usage/bootflow`
+
+
+.. _BootflowStates:
+
+Bootflow states
+---------------
+
+Here is a list of states that a bootflow can be in:
+
+=======  =======================================================================
+State    Meaning
+=======  =======================================================================
+base     Starting-out state, indicates that no media/partition was found. For an
+         SD card socket it may indicate that the card is not inserted.
+media    Media was found (e.g. SD card is inserted) but no partition information
+         was found. It might lack a partition table or have a read error.
+part     Partition was found but a filesystem could not be read. This could be
+         because the partition does not hold a filesystem or the filesystem is
+         very corrupted.
+fs       Filesystem was found but the file could not be read. It could be
+         missing or in the wrong subdirectory.
+file     File was found and its size detected, but it could not be read. This
+         could indicate filesystem corruption.
+loaded   File was loaded and is ready for use. In this state the bootflow can
+         be booted.
+=======  =======================================================================
+
+
+Bootflow internals
+------------------
+
+The bootflow uclass holds a linked list of scanned bootflows as well as the
+currently selected bootmethod and bootflow (for use by commands). This is in
+`struct bootflow_state`.
+
+Each bootmethod device has its own `struct bootmethod_uc_plat` which holds a
+list of scanned bootflows just for that device.
+
+The bootflow itself is documented in bootflow_h_. It includes various bits of
+information about the bootflow and a buffer to hold the file.
+
+
+Future
+------
+
+Apart from the to-do items below, different types of bootflow files may be
+implemented in future, e.g. EFI support and Chromium OS support.
+
+
+To do
+-----
+
+Most of the following things will be completd as part of initial development,
+before a final series is sent:
+
+- use `ready` instead of `loaded` for the state name?
+- `bootflow prep` to load everything preparing for boot, so that `bootflow boot`
+  can just do the boot.
+- check ordering of bootmethods (should it use aliases?)
+- check ordering of bootflows within bootmethods (needed)
+- implement boot_targets env var?
+- quick way to boot from particular media - 'bootflow boot mmc1' ?
+- add bootmethod drivers for dhcp, sata, scsi, ide, usb, virtio
+- introduce an interface for disto_getfile() and disto_net_getfile() provided
+  by the bootmethod
+- better name for this feature? It is clearly not auto-boot or distro-boot,
+  but perhaps standard boot?
+
+Other ideas:
+
+- rename bootflow to flow, bootmethod to method (since this is a bootloader
+  after all)
+- bootmethod flags for speed (e.g. network and USB are slow)
+- should the means of scanning for particular files on a bootmethod device be
+  moved into a driver architecture, so we have drivers for distro boot,
+  Chromium OS, etc.?
+- automatically load kernel, FDT, etc. to suitable addresses so the board does
+  not need to specific things like `pxefile_addr_r`
+
+
+.. _disto_boodcmd: https://github.com/u-boot/u-boot/blob/master/include/config_distro_bootcmd.h
+.. _BootLoaderSpec: http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/
+.. _distro_boot: https://github.com/u-boot/u-boot/blob/master/boot/distro.c
+.. _bootflow_h: https://github.com/u-boot/u-boot/blob/master/include/bootflow.h
diff --git a/doc/develop/index.rst b/doc/develop/index.rst
index 1fb0f06f6e8..e87bac0185b 100644
--- a/doc/develop/index.rst
+++ b/doc/develop/index.rst
@@ -9,6 +9,7 @@ Implementation
 .. toctree::
    :maxdepth: 1
 
+   bootflow
    ci_testing
    commands
    devicetree/index
diff --git a/doc/device-tree-bindings/bootmethod.txt b/doc/device-tree-bindings/bootmethod.txt
new file mode 100644
index 00000000000..ef2545cab68
--- /dev/null
+++ b/doc/device-tree-bindings/bootmethod.txt
@@ -0,0 +1,14 @@
+U-Boot Bootmethod
+=================
+
+A bootmethod provides a way to obtain a bootflow file from a device. It is a
+child of the media device (UCLASS_MMC, UCLASS_SPI_FLASH, etc.)
+
+The bootmethod driver is provided by the media devices. The bindings for each
+are described in this file.
+
+
+MMC bootmethod
+--------------
+
+Optional properties:
diff --git a/doc/usage/bootflow.rst b/doc/usage/bootflow.rst
new file mode 100644
index 00000000000..39cae8beed9
--- /dev/null
+++ b/doc/usage/bootflow.rst
@@ -0,0 +1,419 @@
+.. SPDX-License-Identifier: GPL-2.0+:
+
+bootflow command
+================
+
+Synopis
+-------
+
+::
+
+    bootflow scan [-abel]
+    bootflow list [-e]
+    bootflow select [<num|name>]
+    bootflow info [-d]
+    bootflow boot
+
+
+Description
+-----------
+
+The `bootflow` command is used to manage bootflows. It can scan bootmethods to
+locate bootflows, list them and boot them.
+
+See :doc:`../develop/bootflow` for more information.
+
+
+bootflow scan
+~~~~~~~~~~~~~
+
+Scans for available bootflows, optionally booting the first valid one it finds.
+This operates in two modes:
+
+- If no bootmethod is selected (see `bootmethod select`) it scans bootflows one
+  by one, extracting all the bootmethods from each
+- If a bootmethod is selected, it just scans that one bootflow
+
+Flags are:
+
+-a
+    Collect all bootflows, even those that cannot be loaded. Normally if a file
+    is not where it is expected, then the bootflow fails and so is dropped
+    during the scan. With this option you can see why each bootflow would be
+    dropped.
+
+-b
+    Boot each valid bootflow as it is scanned. Typically only the first bootflow
+    matters, since by then the system boots in the OS and U-Boot is no-longer
+    running. `bootflow scan -b` is a quick way to boot the first available OS.
+    A valid bootflow is one that made it all the way to the `loaded` state.
+
+-e
+    Used with -l to also show errors for each bootflow. The shows detailed error
+    information for each bootflow that failed to make it to the `loaded` state.
+
+-l
+    List bootflows while scanning. This is helpful when you want to see what
+    is happening during scanning. Use it with the `-b` flag to see which
+    bootmethod and bootflows are being tried.
+
+
+bootflow list
+~~~~~~~~~~~~~
+
+Lists the previously scanned bootflows. You must use `bootflow scan` before this
+to see anything.
+
+If you scanned with -a and have bootflows with errors, -e can be used to show
+those errors.
+
+The list looks something like this:
+
+===  ===========  ======  ========  ====  ===============================   ================
+Seq  Type         State   Uclass    Part  Name                              Filename
+===  ===========  ======  ========  ====  ===============================   ================
+  0  distro-boot  loaded  mmc          2  mmc\@7e202000.bootmethod.part_2   extlinux/extlinux.conf
+  1  distro-boot  loaded  ethernet     0  smsc95xx_eth.bootmethod.0         rpi.pxe/extlinux/extlinux.conf
+===  ===========  ======  ========  ====  ===============================   ================
+
+The fields are as follows:
+
+Seq:
+    Sequence number in the scan, used to reference the bootflow later
+
+Type:
+    Type of the bootflow. Currently this is always 'distro-boot', indicating
+    that it is an extlinux.conf file.
+
+State:
+    Current state of the bootflow, indicating how far the bootmethod got in
+    obtaining a valid one. See :ref:`BootflowStates` for a list of states.
+
+Uclass:
+    Name of the media device's Uclass. This indicates the type of the parent
+    device (e.g. MMC, Ethernet).
+
+Part:
+    Partition number being accesseed, numbered from 1. Normally a device will
+    have a partition table with a small number of partitions. For devices
+    without partition tables (e.g. network) this field is 0.
+
+Name:
+    Name of the bootflow. This is generated from the bootmethod appended with
+    the partition information
+
+Filename:
+    Name of the bootflow file. This indicates where the file is on the
+    filesystem or network device.
+
+
+bootflow select
+~~~~~~~~~~~~~~~
+
+Use this to select a particular bootflow. You can select it by the sequence
+number or name, as shown in `bootflow list`.
+
+Once a bootflow is selected, you can use `bootflow info` and `bootflow boot`.
+
+If no bootflow name or number is provided, then any existing bootflow is
+unselected.
+
+
+bootflow info
+~~~~~~~~~~~~~
+
+This shows information on the current bootflow, with the format looking like
+this:
+
+=========  ===============================
+Name       mmc\@7e202000.bootmethod.part_2
+Device     mmc\@7e202000.bootmethod
+Block dev  mmc\@7e202000.blk
+Sequence   1
+Type       distro-boot
+State      loaded
+Partition  2
+Subdir     (none)
+Filename   extlinux/extlinux.conf
+Buffer     3db7ad48
+Size       232 (562 bytes)
+Error      0
+=========  ===============================
+
+Most of the information is the same as `bootflow list` above. The new fields
+are:
+
+Device
+    Name of the bootmethod
+
+Block dev
+    Name of the block device, if any. Network devices don't have a block device.
+
+Subdir
+    Subdirectory used for retrieving files. For network bootmethods this is the
+    directory of the 'bootfile' parameter passed from DHCP. All file retrievals
+    when booting are relative to this.
+
+Buffer
+    Buffer containing the bootflow file. You can use the :doc:`md` to look at
+    it, or dump it with `bootflow info -d`.
+
+Size
+    Size of the bootflow file
+
+Error
+    Error number returned from scanning for the bootflow. This is 0 if the
+    bootflow is in the 'loaded' state, or a negative error value on error. You
+    can look up Linux error codes to find the meaning of the number.
+
+Use the `-d` flag to dump out the contents of the bootfile file.
+
+
+bootflow boot
+~~~~~~~~~~~~~
+
+This boots the current bootflow.
+
+
+Example
+-------
+
+Here is an example of scanning for bootflows, then listing them::
+
+    U-Boot> bootflow scan -l
+    Scanning for bootflows in all bootmethods
+    Seq  Type         State   Uclass    Part  Name                      Filename
+    ---  -----------  ------  --------  ----  ------------------------  ----------------
+    Scanning bootmethod 'mmc at 7e202000.bootmethod':
+      0  distro-boot  loaded  mmc          2  mmc at 7e202000.bootmethod.p extlinux/extlinux.conf
+    Scanning bootmethod 'sdhci at 7e300000.bootmethod':
+    Card did not respond to voltage select! : -110
+    Scanning bootmethod 'smsc95xx_eth.bootmethod':
+    Waiting for Ethernet connection... done.
+    BOOTP broadcast 1
+    DHCP client bound to address 192.168.4.30 (4 ms)
+    Using smsc95xx_eth device
+    TFTP from server 192.168.4.1; our IP address is 192.168.4.30
+    Filename 'rpi.pxe/'.
+    Load address: 0x200000
+    Loading: *
+    TFTP error: 'Is a directory' (0)
+    Starting again
+
+    missing environment variable: pxeuuid
+    Retrieving file: rpi.pxe/pxelinux.cfg/01-b8-27-eb-a6-61-e1
+    Waiting for Ethernet connection... done.
+    Using smsc95xx_eth device
+    TFTP from server 192.168.4.1; our IP address is 192.168.4.30
+    Filename 'rpi.pxe/pxelinux.cfg/01-b8-27-eb-a6-61-e1'.
+    Load address: 0x2500000
+    Loading: ##################################################  566 Bytes
+    	 45.9 KiB/s
+    done
+    Bytes transferred = 566 (236 hex)
+      1  distro-boot  loaded  ethernet     0  smsc95xx_eth.bootmethod.0 rpi.pxe/extlinux/extlinux.conf
+    No more bootmethods
+    ---  -----------  ------  --------  ----  ------------------------  ----------------
+    (2 bootflows, 2 valid)
+    U-Boot> bootflow l
+    Showing all bootflows
+    Seq  Type         State   Uclass    Part  Name                      Filename
+    ---  -----------  ------  --------  ----  ------------------------  ----------------
+      0  distro-boot  loaded  mmc          2  mmc at 7e202000.bootmethod.p extlinux/extlinux.conf
+      1  distro-boot  loaded  ethernet     0  smsc95xx_eth.bootmethod.0 rpi.pxe/extlinux/extlinux.conf
+    ---  -----------  ------  --------  ----  ------------------------  ----------------
+    (2 bootflows, 2 valid)
+
+
+The second one is then selected by name (we could instead use `bootflow sel 0`),
+displayed and booted::
+
+    U-Boot> bootflow info
+    No bootflow selected
+    U-Boot> bootflow sel mmc at 7e202000.bootmethod.part_2
+    U-Boot> bootflow info
+    Name:      mmc at 7e202000.bootmethod.part_2
+    Device:    mmc at 7e202000.bootmethod
+    Block dev: mmc at 7e202000.blk
+    Sequence:  1
+    Type:      distro-boot
+    State:     loaded
+    Partition: 2
+    Subdir:    (none)
+    Filename:  extlinux/extlinux.conf
+    Buffer:    3db7ae88
+    Size:      232 (562 bytes)
+    Error:     0
+    U-Boot> bootflow boot
+    ** Booting bootflow 'smsc95xx_eth.bootmethod.0'
+    Ignoring unknown command: ui
+    Ignoring malformed menu command:  autoboot
+    Ignoring malformed menu command:  hidden
+    Ignoring unknown command: totaltimeout
+    1:	Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl)
+    Retrieving file: rpi.pxe/initramfs-5.3.7-301.fc31.armv7hl.img
+    get 2700000 rpi.pxe/initramfs-5.3.7-301.fc31.armv7hl.img
+    Waiting for Ethernet connection... done.
+    Using smsc95xx_eth device
+    TFTP from server 192.168.4.1; our IP address is 192.168.4.30
+    Filename 'rpi.pxe/initramfs-5.3.7-301.fc31.armv7hl.img'.
+    Load address: 0x2700000
+    Loading: ###################################T ###############  57.7 MiB
+    	 1.9 MiB/s
+    done
+    Bytes transferred = 60498594 (39b22a2 hex)
+    Retrieving file: rpi.pxe//vmlinuz-5.3.7-301.fc31.armv7hl
+    get 80000 rpi.pxe//vmlinuz-5.3.7-301.fc31.armv7hl
+    Waiting for Ethernet connection... done.
+    Using smsc95xx_eth device
+    TFTP from server 192.168.4.1; our IP address is 192.168.4.30
+    Filename 'rpi.pxe//vmlinuz-5.3.7-301.fc31.armv7hl'.
+    Load address: 0x80000
+    Loading: ##################################################  7.2 MiB
+    	 2.3 MiB/s
+    done
+    Bytes transferred = 7508480 (729200 hex)
+    append: ro root=UUID=9732b35b-4cd5-458b-9b91-80f7047e0b8a rhgb quiet LANG=en_US.UTF-8 cma=192MB cma=256MB
+    Retrieving file: rpi.pxe//dtb-5.3.7-301.fc31.armv7hl/bcm2837-rpi-3-b.dtb
+    get 2600000 rpi.pxe//dtb-5.3.7-301.fc31.armv7hl/bcm2837-rpi-3-b.dtb
+    Waiting for Ethernet connection... done.
+    Using smsc95xx_eth device
+    TFTP from server 192.168.4.1; our IP address is 192.168.4.30
+    Filename 'rpi.pxe//dtb-5.3.7-301.fc31.armv7hl/bcm2837-rpi-3-b.dtb'.
+    Load address: 0x2600000
+    Loading: ##################################################  13.8 KiB
+    	 764.6 KiB/s
+    done
+    Bytes transferred = 14102 (3716 hex)
+    Kernel image @ 0x080000 [ 0x000000 - 0x729200 ]
+    ## Flattened Device Tree blob at 02600000
+       Booting using the fdt blob at 0x2600000
+       Using Device Tree in place at 02600000, end 02606715
+
+    Starting kernel ...
+
+    [  OK  ] Started Show Plymouth Boot Screen.
+    [  OK  ] Started Forward Password R…s to Plymouth Directory Watch.
+    [  OK  ] Reached target Local Encrypted Volumes.
+    [  OK  ] Reached target Paths.
+    ....
+
+
+Here we scan for bootflows and boot the first one found::
+
+    U-Boot> bootflow scan -bl
+    Scanning for bootflows in all bootmethods
+    Seq  Type         State   Uclass    Part  Name                      Filename
+    ---  -----------  ------  --------  ----  ------------------------  ----------------
+    Scanning bootmethod 'mmc at 7e202000.bootmethod':
+      0  distro-boot  loaded  mmc          2  mmc at 7e202000.bootmethod.p extlinux/extlinux.conf
+    ** Booting bootflow 'mmc at 7e202000.bootmethod.part_2'
+    Ignoring unknown command: ui
+    Ignoring malformed menu command:  autoboot
+    Ignoring malformed menu command:  hidden
+    Ignoring unknown command: totaltimeout
+    1:	Fedora-KDE-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl)
+    Retrieving file: /initramfs-5.3.7-301.fc31.armv7hl.img
+    getfile 2700000 /initramfs-5.3.7-301.fc31.armv7hl.img
+    Retrieving file: /vmlinuz-5.3.7-301.fc31.armv7hl
+    getfile 80000 /vmlinuz-5.3.7-301.fc31.armv7hl
+    append: ro root=UUID=b8781f09-e2dd-4cb8-979b-7df5eeaaabea rhgb LANG=en_US.UTF-8 cma=192MB console=tty0 console=ttyS1,115200
+    Retrieving file: /dtb-5.3.7-301.fc31.armv7hl/bcm2837-rpi-3-b.dtb
+    getfile 2600000 /dtb-5.3.7-301.fc31.armv7hl/bcm2837-rpi-3-b.dtb
+    Kernel image @ 0x080000 [ 0x000000 - 0x729200 ]
+    ## Flattened Device Tree blob at 02600000
+       Booting using the fdt blob at 0x2600000
+       Using Device Tree in place at 02600000, end 02606715
+
+    Starting kernel ...
+
+    [    0.000000] Booting Linux on physical CPU 0x0
+
+
+Here is am example using the -e flag to see all errors::
+
+    U-Boot> bootflow scan -a
+    Card did not respond to voltage select! : -110
+    Waiting for Ethernet connection... done.
+    BOOTP broadcast 1
+    DHCP client bound to address 192.168.4.30 (4 ms)
+    Using smsc95xx_eth device
+    TFTP from server 192.168.4.1; our IP address is 192.168.4.30
+    Filename 'rpi.pxe/'.
+    Load address: 0x200000
+    Loading: *
+    TFTP error: 'Is a directory' (0)
+    Starting again
+
+    missing environment variable: pxeuuid
+    Retrieving file: rpi.pxe/pxelinux.cfg/01-b8-27-eb-a6-61-e1
+    Waiting for Ethernet connection... done.
+    Using smsc95xx_eth device
+    TFTP from server 192.168.4.1; our IP address is 192.168.4.30
+    Filename 'rpi.pxe/pxelinux.cfg/01-b8-27-eb-a6-61-e1'.
+    Load address: 0x2500000
+    Loading: ##################################################  566 Bytes
+    	 49.8 KiB/s
+    done
+    Bytes transferred = 566 (236 hex)
+    U-Boot> bootflow l -e
+    Showing all bootflows
+    Seq  Type         State   Uclass    Part  Name                      Filename
+    ---  -----------  ------  --------  ----  ------------------------  ----------------
+      0  distro-boot  fs      mmc          1  mmc at 7e202000.bootmethod.p extlinux/extlinux.conf
+         ** File not found, err=-2
+      1  distro-boot  loaded  mmc          2  mmc at 7e202000.bootmethod.p extlinux/extlinux.conf
+      2  distro-boot  fs      mmc          3  mmc at 7e202000.bootmethod.p extlinux/extlinux.conf
+         ** File not found, err=-1
+      3  distro-boot  media   mmc          0  mmc at 7e202000.bootmethod.p <NULL>
+         ** No partition found, err=-2
+      4  distro-boot  media   mmc          0  mmc at 7e202000.bootmethod.p <NULL>
+         ** No partition found, err=-2
+      5  distro-boot  media   mmc          0  mmc at 7e202000.bootmethod.p <NULL>
+         ** No partition found, err=-2
+      6  distro-boot  media   mmc          0  mmc at 7e202000.bootmethod.p <NULL>
+         ** No partition found, err=-2
+      7  distro-boot  media   mmc          0  mmc at 7e202000.bootmethod.p <NULL>
+         ** No partition found, err=-2
+      8  distro-boot  media   mmc          0  mmc at 7e202000.bootmethod.p <NULL>
+         ** No partition found, err=-2
+      9  distro-boot  media   mmc          0  mmc at 7e202000.bootmethod.p <NULL>
+         ** No partition found, err=-2
+      a  distro-boot  media   mmc          0  mmc at 7e202000.bootmethod.p <NULL>
+         ** No partition found, err=-2
+      b  distro-boot  media   mmc          0  mmc at 7e202000.bootmethod.p <NULL>
+         ** No partition found, err=-2
+      c  distro-boot  media   mmc          0  mmc at 7e202000.bootmethod.p <NULL>
+         ** No partition found, err=-2
+      d  distro-boot  media   mmc          0  mmc at 7e202000.bootmethod.p <NULL>
+         ** No partition found, err=-2
+      e  distro-boot  media   mmc          0  mmc at 7e202000.bootmethod.p <NULL>
+         ** No partition found, err=-2
+      f  distro-boot  media   mmc          0  mmc at 7e202000.bootmethod.p <NULL>
+         ** No partition found, err=-2
+     10  distro-boot  media   mmc          0  mmc at 7e202000.bootmethod.p <NULL>
+         ** No partition found, err=-2
+     11  distro-boot  media   mmc          0  mmc at 7e202000.bootmethod.p <NULL>
+         ** No partition found, err=-2
+     12  distro-boot  media   mmc          0  mmc at 7e202000.bootmethod.p <NULL>
+         ** No partition found, err=-2
+     13  distro-boot  media   mmc          0  mmc at 7e202000.bootmethod.p <NULL>
+         ** No partition found, err=-2
+     14  distro-boot  loaded  ethernet     0  smsc95xx_eth.bootmethod.0 rpi.pxe/extlinux/extlinux.conf
+    ---  -----------  ------  --------  ----  ------------------------  ----------------
+    (21 bootflows, 2 valid)
+    U-Boot>
+
+
+Return value
+------------
+
+On success `bootflow boot` normally boots into the Operating System and does not
+return to U-Boot. If something about the U-Boot processing fails, then the
+return value $? is 1. If the boot succeeds but for some reason the Operating
+System returns, then $? is 0, indicating success.
+
+For other subcommands, the return value $? is always 0 (true).
+
+
+.. BootflowStates_:
diff --git a/doc/usage/bootmethod.rst b/doc/usage/bootmethod.rst
new file mode 100644
index 00000000000..28afe09f06f
--- /dev/null
+++ b/doc/usage/bootmethod.rst
@@ -0,0 +1,138 @@
+.. SPDX-License-Identifier: GPL-2.0+:
+
+bootmethod command
+==================
+
+Synopis
+-------
+
+::
+
+    bootmethod list [-p]      - list all available bootmethods (-p to probe)\n"
+    bootmethod select <bm>    - select a bootmethod by name\n"
+    bootmethod info [-p]      - show information about a bootmethod";
+
+Description
+-----------
+
+The `` command is used to manage bootmethods. It can list available
+bootmethods, select one and obtain information about it.
+
+See :doc:`../develop/bootflow` for more information about bootmethods in
+general.
+
+
+bootmethod list
+~~~~~~~~~~~~~~~
+
+This lists available bootmethods
+
+Scanning with -p causes the bootmethods to be probed. This happens automatically
+when they are used.
+
+The list looks something like this:
+
+===  ======  ======  ========  =========================
+Seq  Probed  Status  Uclass    Name
+===  ======  ======  ========  =========================
+  0   [ + ]      OK  mmc       mmc at 7e202000.bootmethod
+  1   [   ]      OK  mmc       sdhci at 7e300000.bootmethod
+  2   [   ]      OK  ethernet  smsc95xx_eth.bootmethod
+===  ======  ======  ========  =========================
+
+
+The fields are as follows:
+
+Seq:
+    Sequence number in the scan, used to reference the bootflow later
+
+Probed:
+    Shows a plus (+) if the device is probed, empty if not.
+
+Status:
+    Shows the status of the device. Typically this is `OK` meaning that there is
+    no error. If you use -p and an error occurs when probing, then this shows
+    the error number. You can look up Linux error codes to find the meaning of
+    the number.
+
+Uclass:
+    Name of the media device's Uclass. This indicates the type of the parent
+    device (e.g. MMC, Ethernet).
+
+Name:
+    Name of the bootmethod. This is generated from the media device appended
+    with `.bootmethod`
+
+
+bootmethod select
+~~~~~~~~~~~~~~~~~
+
+Use this to select a particular bootmethod. You can select it by the sequence
+number or name, as shown in `bootmethod list`.
+
+Once a bootmethod is selected, you can use `bootmethod info` to look at it or
+`bootflow scan` to scan it.
+
+If no bootmethod name or number is provided, then any existing bootmethod is
+unselected.
+
+
+bootmethod info
+~~~~~~~~~~~~~~~
+
+This shows information on the current bootmethod, with the format looking like
+this:
+
+=========  =======================
+Name       mmc at 7e202000.bootmethod
+Sequence   0
+Status     Probed
+Uclass     mmc
+Bootflows  1 (1 valid)
+=========  =======================
+
+Most of the information is the same as `bootmethod list` above. The new fields
+are:
+
+Device
+    Name of the bootmethod
+
+Status
+    Shows `Probed` if the device is probed, `OK` if not. If -p is used and the
+    device fails to probe, an error code is shown.
+
+Bootflows
+    Indicates the number of bootflows attached to the bootmethod. This is 0
+    unless you have used 'bootflow scan' on the bootflow, or on all bootflows.
+
+
+Example
+-------
+
+This example shows listing available bootmethod and getting information about
+one of them::
+
+   U-Boot> bootmethod list
+   Seq  Probed  Status  Uclass    Name
+   ---  ------  ------  --------  ------------------
+     0   [ + ]      OK  mmc       mmc at 7e202000.bootmethod
+     1   [   ]      OK  mmc       sdhci at 7e300000.bootmethod
+     2   [   ]      OK  ethernet  smsc95xx_eth.bootmethod
+   ---  ------  ------  --------  ------------------
+   (3 devices)
+   U-Boot> bootmethod sel 0
+   U-Boot> bootflow scan
+   U-Boot> bootmethod info
+   Name:      mmc at 7e202000.bootmethod
+   Sequence:  0
+   Status:    Probed
+   Uclass:    mmc
+   Bootflows: 1 (1 valid)
+
+
+Return value
+------------
+
+The return value $? is always 0 (true).
+
+
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index 356f2a56181..0abfad26e8e 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -21,8 +21,10 @@ Shell commands
    askenv
    base
    bootefi
+   bootflow
    booti
    bootmenu
+   bootmethod
    button
    x86/cbsysinfo
    conitrace
-- 
2.33.0.rc1.237.g0d66db33f3-goog



More information about the U-Boot mailing list