[PATCH 2/2] Documentation: devel: porting: bring up to date

Ulrich Ölmann u.oelmann at pengutronix.de
Fri Aug 5 00:29:46 PDT 2022


Hi Ahmad,

On Fri, Aug 05 2022 at 06:09 +0200, Ahmad Fatoum <ahmad at a3f.at> wrote:
> Recent barebox rework has simplified things a bit, so update the porting
> doc accordingly.
>
> Signed-off-by: Ahmad Fatoum <ahmad at a3f.at>
> ---
>  Documentation/devel/porting.rst | 62 ++++++++++++++++++++-------------
>  1 file changed, 38 insertions(+), 24 deletions(-)
>
> diff --git a/Documentation/devel/porting.rst b/Documentation/devel/porting.rst
> index 1abaabc03ae1..0533d6d1ed20 100644
> --- a/Documentation/devel/porting.rst
> +++ b/Documentation/devel/porting.rst
> @@ -81,9 +81,9 @@ barebox images
>  ==============
>  
>  In a typical build, the barebox build process generates multiple images
> -(:ref:`multi_image`).  All enabled PBLs are linked with the same barebox
> -proper binary and then the resulting image are processed to be in the
> -format expected by the loader.
> +(:ref:`multi_image`).  All enabled PBLs are each linked with the same
> +barebox proper binary and then the resulting image are processed to be

again a kind request for a drive-by typo fix:

  s/image/images/

Best regards
Ulrich


> +in the format expected by the loader.
>  
>  The loader is often a BootROM, but maybe another first stage bootloader
>  or a hardware debugger.
> @@ -110,10 +110,10 @@ Entry point
>  
>  The PBL's entry point is the first of your code that's run. What happens
>  there depends on the previously running code. If a previous stage has already
> -set up a stack and initialized the DRAM, the only thing you need to do
> -is to call the common PBL code with a memory region and your device tree blob::
> +initialized the DRAM, the only thing you need to do is to set up a stack and
> +call the common PBL code with a memory region and your device tree blob::
>  
> -  ENTRY_FUNCTION(start_my_board, r0, r1, r2)
> +  ENTRY_FUNCTION_WITHSTACK(start_my_board, MY_STACK_TOP, r0, r1, r2)
>    {
>    	extern char __dtb_my_board_start[];
>    	void *fdt;
> @@ -128,11 +128,15 @@ is to call the common PBL code with a memory region and your device tree blob::
>  
>  Lets look at this line by line:
>  
> - - ``ENTRY_FUNCTION(start_my_board, r0, r1, r2)``
> + - ``ENTRY_FUNCTION_WITHSTACK(start_my_board, STACK_TOP, r0, r1, r2)``
>     The entry point is special: It needs to be located at the beginning of the
>     image, it does not return and may run before a stack is set up.
> -   The ``ENTRY_POINT()`` macro takes care of these details and passes along
> -   a number of registers, in case the Boot ROM has placed something interesting there.
> +   To make it possible to write this entry point in C, the macro places
> +   a machine code prologue that uses ``STACK_TOP`` as the initial stack
> +   pointer. If the stack is already set up, you may pass 0 here.
> +
> +   Additionally, the macro passes along a number of registers, in case the
> +   Boot ROM has placed something interesting there.
>  
>   - ``extern char __dtb_my_board_start[];``
>     When a device tree is built as part of the PBL, ``__dtb_*_start`` and
> @@ -171,14 +175,17 @@ Looking at other boards you might see some different patterns:
>  
>   - ``__naked``: All functions called before stack is correctly initialized must be
>     marked with this attribute. Otherwise, function prologue and epilogue may access
> -   the uninitialized stack. If the compiler for the target architecture doesn't
> -   support the attribute, stack must be set up in non-inline assembly:
> -   Either a barebox assembly entry point or in earlier firmware.
> -   The compiler may still spill excess local C variables used in a naked function
> -   to the stack before it was initialized.
> -   A naked function should thus preferably only contain inline assembly, set up a
> -   stack and jump directly after to a ``noinline`` non naked function where the
> -   stack is then normally usable.
> +   the uninitialized stack. Note that even with ``__naked``, the compiler may still
> +   spill excess local C variables used in a naked function to the stack before it
> +   was initialized. A naked function should thus preferably only contain inline
> +   assembly, set up a stack and jump directly after to a ``noinline`` non naked
> +   function where the stack is then normally usable. This pattern is often seen
> +   together with ``ENTRY_FUNCTION``. Modern boards better avoid this footgun
> +   by using ``ENTRY_FUNCTION_WITHSTACK``, which will take care to initialize the
> +   stack beforehand. If either a barebox assembly entry point,
> +   ``ENTRY_FUNCTION_WITHSTACK`` or earlier firmware has set up the stack, there is
> +   no reason to use ``__naked``, just use ``ENTRY_FNCTION_WITHSTACK`` with a zero
> +   stack top.
>  
>   - ``noinline``: Compiler code inlining is oblivious to stack manipulation in
>     inline assembly. If you want to ensure a new function has its own stack frame
> @@ -186,8 +193,9 @@ Looking at other boards you might see some different patterns:
>     a ``__noreturn noinline`` function.
>  
>   - ``arm_setup_stack``: For 32-bit ARM, ``arm_setup_stack`` initializes the stack
> -   top when called from a naked C function, which allows to write the entry point
> -   directly in C. The stack pointer will be decremented before pushing values.
> +   top when called from a naked C function, which allowed to write the entry point
> +   directly in C. Modern code should use ``ENTRY_FUNCTION_WITHSTACK`` instead.
> +   Note that in both cases the stack pointer will be decremented before pushing values.
>     Avoid interleaving with C-code. See ``__naked`` above for more details.
>  
>   - ``__dtb_z_my_board_start[];``: Because the PBL normally doesn't parse anything out
> @@ -362,12 +370,11 @@ Considerations when writing Linux drivers also apply to barebox:
>  Miscellaneous Linux porting advice:
>  
>    * Branches dependent on ``system_state``: Take the ``SYSTEM_BOOTING`` branch
> -  * ``struct of_clk_hw_simple_get``: rename to ``struct of_clk_src_simple_get``
>    * ``usleep`` and co.: use ``[mud]elay``
> -  * ``.of_node``: use ``.device_node``
> +  * ``.of_node``: use ``.device_node`` or ``dev_of_node``
>    * ``jiffies``: use ``get_time_ns()``
>    * ``time_before``: use ``!is_timeout()``
> -  * ``clk_hw_register_fixed_rate_with_accuracy``: use ``clk_register_fixed_rate`` without accuracy
> +  * ``clk_hw_register_fixed_rate_with_accuracy``: use ``clk_hw_register_fixed_rate`` without accuracy
>    * ``CLK_SET_RATE_GATE`` can be ignored
>    * ``clk_prepare``: is for the non-atomic code preparing for clk enablement. Merge it into ``clk_enable``
>  
> @@ -503,6 +510,10 @@ This can be done by implementing three functions:
>     and resumes execution at the new location. This can be omitted
>     if barebox won't initially execute out of ROM.
>  
> + - ``relocate_to_adr_full()``: This function does what
> +   ``relocate_to_adr()`` does and in addition moves the piggy data
> +   (the usually compressed barebox appended to the prebootloader).
> +
>  Of course, for these functions to work. The linker script needs
>  to ensure that the ELF relocation records are included in the
>  final image and define start and end markers so code can iterate
> @@ -511,7 +522,7 @@ over them.
>  To ease debugging, even when relocation has no yet happened,
>  barebox supports ``DEBUG_LL``, which acts similarly to the
>  PBL console, but does not require relocation. This is incompatible
> -with multi-image, function mso this should only be considered while debugging.
> +with multi-image, so this should only be considered while debugging.
>  
>  Linker scripts
>  ==============
> @@ -526,4 +537,7 @@ Generic DT image
>  It's a good idea to have the architecture generate an image that
>  looks like and can be booted just like a Linux kernel. This allows
>  easy testing with QEMU or booting from barebox or other bootloaders.
> -Refer to ``BOARD_GENERIC_DT`` for examples.
> +Refer to ``BOARD_GENERIC_DT`` for examples. If not possible, the
> +(sub-)architecture making use of the image should
> +``register_image_handler`` that can chain-boot the format from
> +a running barebox. This allows for quick debugging iterations.
-- 
Pengutronix e.K.                           | Ulrich Ölmann               |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



More information about the barebox mailing list