[U-Boot] [PATCH 01/14] dm: Initial import of design documents

Stephen Warren swarren at wwwdotorg.org
Wed Aug 8 20:20:32 CEST 2012


On 08/08/2012 05:42 AM, Marek Vasut wrote:
> From: Marek Vasut <marek.vasut at gmail.com>
> 
> This patch contains UDM-design.txt, which is document containing
> general description of the driver model. The remaining files contains
> descriptions of conversion process of particular subsystems.

> diff --git a/doc/driver-model/UDM-design.txt b/doc/driver-model/UDM-design.txt

> +II) Driver core initialization stages
> +-------------------------------------
> +
> +The drivers have to be initialized in two stages, since the U-Boot bootloader
> +runs in two stages itself. The first stage is the one which is executed before
> +the bootloader itself is relocated. The second stage then happens after
> +relocation.
> +
> +  1) First stage
> +  --------------
> +
> +  The first stage runs after the bootloader did very basic hardware init. This
> +  means the stack pointer was configured, caches disabled and that's about it.
> +  The problem with this part is the memory management isn't running at all. To
> +  make things even worse, at this point, the RAM is still likely uninitialized
> +  and therefore unavailable.
> +
> +  2) Second stage
> +  ---------------
> +
> +  At this stage, the bootloader has initialized RAM and is running from it's
> +  final location. Dynamic memory allocations are working at this point. Most of
> +  the driver initialization is executed here.

Given the above descriptions of the two stages, ...

> +III) The drivers
> +----------------
> +
> +  1) The structure of a driver
> +  ----------------------------
> +
> +  The driver will contain a structure located in a separate section, which
> +  will allow linker to create a list of compiled-in drivers at compile time.
> +  Let's call this list "driver_list".
> +
> +  struct driver __attribute__((section(driver_list))) {
> +    /* The name of the driver */
> +    char		name[STATIC_CONFIG_DRIVER_NAME_LENGTH];
> +
> +    /*
> +     * This function should connect this driver with cores it depends on and
> +     * with other drivers, likely bus drivers
> +     */
> +    int			(*bind)(struct instance *i);

... the comments here should probably say which stage each function will
be run at.

> +
> +    /* This function actually initializes the hardware. */
> +    int			(*probe)(struct instance *i);
> +
> +    /*
> +     * The function of the driver called when U-Boot finished relocation.
> +     * This is particularly important to eg. move pointers to DMA buffers
> +     * and such from the location before relocation to their final location.
> +     */
> +    int			(*reloc)(struct instance *i);

The need for this function implies that some other functions (both bind
and probe?) are to be called before relocation. Isn't the pre-relocation
environment rather strict, and hence this will require a bunch of
changes to driver code to initialize differently? Why not just
initialize everything after relocation; IIRC, that's how most things are
initialized now, isn't it?

Related, if you're intending to allow drivers to be loaded from e.g. the
filesystem later, that will happen after relocation. There will then be
a discrepancy between the environment where bind/probe get run for a
built-in driver vs. a dynamically loaded driver.


More information about the U-Boot mailing list