Thread (1 message) 1 message, 1 author, 2010-06-04

Re: Boot interface for device trees on ARM

From: Grant Likely <hidden>
Date: 2010-06-04 20:01:08
Also in: linux-arm-kernel

On Wed, May 19, 2010 at 11:52 AM, Nicolas Pitre [off-list ref] wrote:
[ Complete boot description and proposal added at the end
 for those interested. ]
Alright, after much thinking, I'm okay with this approach.  None of my
remaining objections are showstoppers.

I've still got a few comments/questions.  I'll restrict them to the
full proposal to avoid confusion.
Booting Linux on ARM
====================

Two methods for passing boot information to the Linux kernel on ARM are
possible:

1) the legacy method

2) the DT (device tree) method

The legacy method
-----------------
[...]
The DT method
-------------

The DT method requires that a unique ID be registered for each SOC
family for the DT purpose within the same ID space.  But instead of
having one ID for each possible machine, only one ID per SOC family is
required.  So the bootloader simply has to pass into r1 the ID
corresponding to DT instead of the specific machine ID.  This is a hard
requirement.

With this, the kernel can remain largely backward compatible with the
legacy boot method, requiring _no_ change to the existing code, as the
ID is sufficient to distinguish between both boot types.  The machine
record remains largely relevant even for a DT boot as the majority of
its content is SOC specific anyway, and given a per SOC ID for DT usage
means that the early boot facilities are still usable as is even in the
DT context.  And then the init_machine method in the machine record is
naturally used to parse the device tree and do its work on multiple
machines' behalf instead of relying on compiled-in static data for a
specific machine.
There will still be instances of machine-specific setup code that
needs to be chosen at boot (based on the top level 'compatible'
property), but init_machine() appears to be early enough to handle
this.

hmmm... however, things the device tree blob and the initrd both need
to be marked as bootmem at paging_init() time, but init_machine()
doesn't run until later.  There will still need to be some hooks for
doing early DT processing, but none of that should be either board or
SoC specific.
The bootloader must also store in memory the DT data and pass its
location via r2.  The r2 initialization therefore becomes a hard
requirement when a DT is used. The boot_params field in the DT machine
record could be set to -1 to disable ATAG parsing when a DT machine ID
is used, and look into the DT data instead.

Backward Compatibility Considerations
-------------------------------------

Now let's have a look at what happens when we mix this with bootloaders.

If a kernel is too old, or was not configured with the "machine support"
for DT, then only one thing may happen when a bootloader passes a DT
machine ID to the kernel.  The early boot code will fail to find the
machine record for the provided ID and refuse to boot.  If you have
CONFIG_DEBUG_LL and are attempting to boot on the right SOC, then you'll
probably get the error message on a serial port, along with a list of
the actual machines and their IDs supported by that kernel.  In other
words, this is not a new failure mode. Two solutions: either reconfigure
your kernel to add DT support for your SOC, or configure your bootloader
to use the legacy boot method.  And having a bootloader that can do DT
only for a machine that has only legacy support in the kernel is
senseless, so that case needs no be considered any longer.

The opposite is the kernel being configured for DT _only_, and the
bootloader being too old, or misconfigured, so it passes a non-DT
machine ID to the kernel.  In this case the same failure mode as above
will be observed: kernel failing to find the matching machine record and
halting (after attempting to display the error and the available machine
supported). Solution: reconfigure your kernel with legacy support for
that machine.

If the goal is to experiment with DT support in the kernel, and the
bootloader does not support DT, then some shim can be prepended to the
kernel image to fix things up.  Most bootloaders already have the
ability to load arbitrary binary data in memory, and branch to arbitrary
location too.  So it should be pretty easy to tftp the kernel, then tftp
the DT data, to finally branch into the kernel with appropriate values
in r1 and r2.
A couple of other options here for experimenting is to carry a dtb as
a payload in the zImage wrapper, or to link dtbs directly into the
kernel proper and point to it from the machine structure.  Doing so
would allow even existing machines to use the same DT setup code.

My remaining objection is that the DT-only approach demands firmware
not just pass a dtb blob, but to also modify it.  The ATAG+DT approach
allows current firmware projects to continue passing data in the same
way it does now (less impact on firmware developers to add DT
support).

However, I'm not going to dwell on this point any longer because we
already have at least one firmware project (U-Boot) that understands
the device tree, and other firmware projects can use the shim approach
as a stop gap until native support is added.

It may make for a more painful transition, but you're probably right
in that it is better in the long run.

Go ahead and consider me "agreed".  :-)

g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help