path: root/Documentation
diff options
Diffstat (limited to 'Documentation')
7 files changed, 157 insertions, 5 deletions
diff --git a/Documentation/boards/mips/loongson_ls1b.rst b/Documentation/boards/mips/loongson_ls1b.rst
index 8f475e6..ea7ed8d 100644
--- a/Documentation/boards/mips/loongson_ls1b.rst
+++ b/Documentation/boards/mips/loongson_ls1b.rst
@@ -30,7 +30,7 @@ Running barebox
3. Wait ``Press <Enter> to execute loading image`` prompt and press the space key.
- 4. Build barebox and upload ``zbarebox.bin`` via Ymodem to the board:
+ 4. Build barebox and upload ``images/barebox-loongson-ls1b.img`` via Ymodem to the board:
.. code-block:: none
diff --git a/Documentation/boards/stm32mp.rst b/Documentation/boards/stm32mp.rst
index 607c59f..b235c39 100644
--- a/Documentation/boards/stm32mp.rst
+++ b/Documentation/boards/stm32mp.rst
@@ -31,6 +31,7 @@ The resulting images will be placed under ``images/``:
+ barebox-stm32mp157c-seeed-odyssey.img
Flashing barebox
@@ -63,7 +64,7 @@ An appropriate image for a SD-Card can be generated with following
For eMMC, the boot partitions are used as the FSBL partitions and so the user
-partitions may look like this:
+partitions may look like this::
image @STM32MP_BOARD@.img {
partition ssbl {
@@ -79,6 +80,17 @@ partitions may look like this:
The fsbl1 and fsbl2 can be flashed by writing to barebox ``/dev/mmcX.boot0`` and
``/dev/mmcX.boot1`` respectively or from a booted operating system.
+Additionally, the eMMC's ``ext_csd`` register must be modified to activate the
+boot acknowledge signal (``BOOT_ACK``) and to select a boot partition.
+Assuming ``CONFIG_CMD_MMC_EXTCSD`` is enabled and the board shall boot from
+ mmc_extcsd /dev/mmc1 -i 179 -v 0x50
+The STM32MP1 BootROM does *not* support booting from eMMC without fast boot
Boot source selection
diff --git a/Documentation/devel/background-execution.rst b/Documentation/devel/background-execution.rst
new file mode 100644
index 0000000..eadad9d
--- /dev/null
+++ b/Documentation/devel/background-execution.rst
@@ -0,0 +1,125 @@
+Background execution in barebox
+barebox is single-threaded and doesn't support interrupts. Nevertheless it is
+sometimes desired to execute code "in the background", like for example polling
+for completion of transfers or to regularly blink a heartbeat LED. For these
+scenarios barebox offers the techniques described below.
+Pollers are a way in barebox to frequently execute code in the background.
+barebox is single-threaded, so a poller is not executed as a separate thread,
+but instead pollers are executed whenever ``is_timeout()`` is called. This has
+a few implications. First of all, pollers are not executed when
+``is_timeout()`` is not called. For this and other reasons, loops polling for
+hardware events should always use a timeout, which is best implemented with
+``is_timeout()``. Another thing to remember is that pollers can be executed
+anywhere in the middle of other device accesses whenever ``is_timeout()`` is
+called. Care must be taken that a poller doesn't access the very same device
+again itself. See "slices" below on how devices can safely be accessed from
+pollers. Some operations are entirely forbidden from pollers. For example it is
+forbidden to access the virtual filesystem, as this could trigger arbitrary
+device accesses. The macro ``assert_command_context()`` is added to those
+places to make sure they are not called in the wrong context. The poller
+interface is declared in ``include/poller.h``. ``poller_register()`` is used
+to register a poller. The ``struct poller_struct`` passed to
+``poller_register()`` needs to have the ``poller_struct.func()`` member
+populated with the function that shall be called. From the moment a poller is
+registered ``poller_struct.func()`` will be called regularly as long as someone
+calls ``is_timeout()``. A special poller can be registered with
+``poller_async_register()``. A poller registered this way won't be called right
+away, instead running it can be triggered by calling ``poller_call_async()``.
+This will execute the poller after the ``@delay_ns`` argument.
+``poller_call_async()`` may also be called from with the poller, so with this
+it's possible to run a poller regularly with configurable delays.
+Pollers are limited in the things they can do. Poller code must always be
+prepared for the case that the resources it accesses are currently busy and
+handle this gracefully by trying again later. Most places in barebox either do
+not test for resources being busy or return with an error if they are busy.
+Calling into the filesystem potentially uses arbitrary other devices, so
+doing this from pollers is forbidden. For the same reason it is forbidden
+to execute barebox commands from pollers.
+Sometimes code wants to access files from poller context or even wants to
+execute barebox commands from poller context. The fastboot implementation is an
+example for such a case. The fastboot commands come in via USB or network and
+the completion and packet receive handlers are executed in poller context. Here
+workqueues come into play. They allow to queue work items from poller context.
+These work items are executed later at the point where the shell fetches its
+next command. At this point we implicitly know that it's allowed to execute
+commands or to access the filesystem, because otherwise the shell could not do
+it. This means that execution of the next shell command will be delayed until
+all work items are being done. Likewise the work items will only be executed
+when the current shell command has finished.
+The workqueue interface is declared in ``include/work.h``.
+``wq_register()`` is the first step to use the workqueue interface.
+``wq_register()`` registers a workqueue to which work items can be attached.
+Before registering a workqueue a ``struct work_queue`` has to be populated with
+two function callbacks. ``work_queue.fn()`` is the callback that actually does
+the work once it is scheduled. ``work_queue.cancel()`` is a callback which is
+executed when the pending work shall be cancelled. This is primarily for
+freeing the memory associated to a work item. ``wq_queue_work()`` is for
+actually queueing a work item on a work queue. This can be called from poller
+code. Usually a work item is allocated by the poller and then freed either in
+``work_queue.fn()`` or in ``work_queue.cancel()``.
+Slices are a way to check if a device is currently busy and thus may not be
+called into currently. Pollers wanting to access a device must call
+``slice_busy()`` on the slice provided by the device before calling into it.
+When the slice is acquired (which can only happen inside a poller) the poller
+can't continue at this moment and must try again next time it is executed.
+Drivers whose devices provide a slice must call ``slice_acquire()`` before
+accessing the device and ``slice_release()`` afterwards. Slices can have
+dependencies to other slices, for example a USB network controller uses the
+corresponding USB host controller. A dependency can be expressed with
+``slice_depends_on()``. With this the USB network controller can add a
+dependency from the network device it provides itself to the USB host
+controller it depends on. With this ``slice_busy()`` on the network device
+will return ``true`` when the USB host controller is busy.
+The usual pattern for using slices is that the device driver for a device
+calls ``slice_acquire()`` when entering the driver and ``slice_release()``
+before leaving the driver. The driver also provides a function returning
+the slice for a device, for example the ethernet support code provides
+``struct slice *eth_device_slice(struct eth_device *edev)``. Poller code
+which wants to use the ethernet device checks for the availability doing
+``slice_busy(eth_device_slice(edev))`` before accessing the ethernet
+device. When the slice is not busy the poller can continue with accessing
+that device. Otherwise the poller must return and try again next time it
+is called.
+What barebox does is best described as cooperative multitasking. As pollers
+can't be interrupted, it will directly affect the user experience when they
+take too long. When barebox reacts sluggishly to key presses, then probably
+pollers take too long to execute. A first test if this is the case can
+be done by executing ``poller -t`` on the command line. This command will print
+how many times we can execute all registered pollers in one second. When this
+number is too low then pollers are guilty responsible. Workqueues help to run
+schedule/execute longer running code, but during the time while workqueues are
+executed nothing else happens. This means that when fastboot flashes an image
+in a workqueue then barebox won't react to any key presses on the command line.
+The usage of the interfaces described in this document is not yet very
+widespread in barebox. The interfaces are used in the places where we need
+them, but there are other places which do not use them but should. For example
+using a LED driven by a I2C GPIO exander used as hearbeat LED won't work
+properly currently. Consider the I2C driver accesses an unrelated I2C device,
+like an EEPROM. After having initiated the transfer the driver polls for the
+transfer being completed using a ``is_timeout()`` loop. The call to
+``is_timeout()`` then calls into the registered pollers from which one accesses
+the same I2C bus whose driver is just polling for completion of another
+transfer. With this the I2C driver is in an undefined state and will likely not
+work anymore.
diff --git a/Documentation/devel/devel.rst b/Documentation/devel/devel.rst
new file mode 100644
index 0000000..f559512
--- /dev/null
+++ b/Documentation/devel/devel.rst
@@ -0,0 +1,14 @@
+.. highlight:: console
+barebox programming
+.. toctree::
+ :maxdepth: 2
+ background-execution
+* :ref:`search`
+* :ref:`genindex`
diff --git a/Documentation/index.rst b/Documentation/index.rst
index b7dae23..836dc41 100644
--- a/Documentation/index.rst
+++ b/Documentation/index.rst
@@ -19,6 +19,7 @@ Contents:
+ devel/devel.rst
* :ref:`search`
* :ref:`genindex`
diff --git a/Documentation/user/booting-linux.rst b/Documentation/user/booting-linux.rst
index 983b56d..60babb5 100644
--- a/Documentation/user/booting-linux.rst
+++ b/Documentation/user/booting-linux.rst
@@ -274,7 +274,7 @@ In any case, make sure that the specified mountpoint is exported by your NFS
For more information about booting with ``nfsroot``, see
-`Documentation/filesystems/nfs/nfsroot.txt <>`__
+`Documentation/admin-guide/nfs/nfsroot.rst <>`__
in the Linux kernel documentation.
If the preconfigured paths or names are not suitable, they can be adjusted in
diff --git a/Documentation/user/usb.rst b/Documentation/user/usb.rst
index 4c1b292..ca5f813 100644
--- a/Documentation/user/usb.rst
+++ b/Documentation/user/usb.rst
@@ -266,7 +266,7 @@ USB Gadget autostart Options
See :ref:`command_usbgadget` -a. (Default 0).
Function description for DFU. See :ref:`command_usbgadget` -D [desc].
Function description for fastboot. See :ref:`command_usbgadget` -A [desc].
Export barebox update handlers. See :ref:`command_usbgadget` -b. (Default 0).