[U-Boot] Complete verified uboot example

Rick Altherr raltherr at google.com
Mon Feb 27 21:53:18 UTC 2017


You set the load address for the linux image to the same location as the
FIT.  U-Boot verified the hashes on the FIT and then tried to copy the
kernel over top the FIT.  I assume you put the FIT in flash.  Pick a
location in RAM for the kernel's load address.

On Mon, Feb 27, 2017 at 1:49 PM, Ron Brash <ron.brash at gmail.com> wrote:

> Looks like far more progress:
>
> #> setenv my_bootcount 0; bootm 0xD0084000
> Initial value for argc=3
> Final value for argc=3
> ## Current stack ends at 0x23f11db8 *  kernel: cmdline image address =
> 0xd0084000
>    Reading image header from dataflash address d0084000 to RAM address
> 22000000
>    FIT/FDT format image found at 0x22000000, size 0x0016c0b1
>    Reading image remaining data from dataflash address d0084040 to RAM
> address 22000040
> ## Loading kernel from FIT Image at 22000000 ...
> No configuration specified, trying default...
> Found default configuration: 'config at 1'
>    Using 'config at 1' configuration
>    Trying 'linux_kernel at 1' kernel subimage
>      Description:  Linux zImage
>      Type:         Kernel Image
>      Compression:  uncompressed
>      Data Start:   0x220000dc
>      Data Size:    1465544 Bytes = 1.4 MiB
>      Architecture: ARM
>      OS:           Linux
>      Load Address: 0x22000000
>      Entry Point:  0x22008000
>      Hash node:    'hash at 1'
>      Hash algo:    sha256
>      Hash value:   5dcf9a4328bca6fe5c3405e03b9a58
> 402dce36f3a4f0c757e52091b050d2bcb2
>      Hash len:     32
>    Verifying Hash Integrity ... sha256+ OK
>    kernel data at 0x220000dc, len = 0x00165cc8 (1465544)
> *  ramdisk: using config 'config at 1' from image at 0x22000000
> *  ramdisk: no 'ramdisk' in config
> *  fdt: using config 'config at 1' from image at 0x22000000
> ## Checking for 'FDT'/'FDT Image' at 22000000
> ## Loading fdt from FIT Image at 22000000 ...
>    Using 'config at 1' configuration
>    Trying 'fdt at 1' fdt subimage
>      Description:  FDT blob
>      Type:         Flat Device Tree
>      Compression:  uncompressed
>      Data Start:   0x22165ea4
>      Data Size:    21681 Bytes = 21.2 KiB
>      Architecture: ARM
>      Hash node:    'hash at 1'
>      Hash algo:    sha256
>      Hash value:   c7f32d039871d858dda8d397c3b6a6
> 85bc914c78cf70f03d1860f61ecfe9c689
>      Hash len:     32
>    Verifying Hash Integrity ... sha256+ OK
>    Loading fdt from 0x22165ea4 to 0x28000000
>    Booting using the fdt blob at 0x28000000
>    of_flat_tree at 0x28000000 size 0x000054b1
> Initial value for argc=3
> Final value for argc=3
>    Loading Kernel Image ... OK
> CACHE: Misaligned operation at range [22000000, 22165cc8]
>    kernel loaded at 0x22000000, end = 0x22165cc8
> images.os.start = 0x22000000, images.os.end = 0x2216c0f1
> images.os.load = 0x22000000, load_end = 0x22165cc8
> ERROR: new format image overwritten - must RESET the board to recover
> resetting ...
>
> This appears to be an addressing issue.  Anyone care to comment?
>
> I'll put up how I got to this point after, but I am curious on how all of
> the addresses are leveraged, is there an order they follow and more?
>
>
>
> On 27 February 2017 at 15:58, Rick Altherr <raltherr at google.com> wrote:
>
>> The projects I'm working on are based on Yocto so I've been using the
>> u-boot signing support that is built in there.  I believe the magic you are
>> looking for is in http://git.yoctoproject.org
>> /cgit/cgit.cgi/poky/tree/meta/classes/uboot-sign.bbclass.  Specifically,
>> when you run 'mkimage -F -k <key-name> -K <control-dtb> -r <fit>', the
>> public keys will be inserted into the control dtb.  You can then rebuild
>> u-boot with 'make EXT_DTB=<control-dtb>' which will use the dtb that
>> includes the keys.
>>
>> On Mon, Feb 27, 2017 at 7:34 AM, Ron Brash <ron.brash at gmail.com> wrote:
>>
>>> Okay - it seems, after working my way through a bunch of the
>>> documentation and examples in /doc/uImage.FIT - I noticed a discrepancy
>>>
>>> /dts-v1/;
>>> /{
>>> description = "Configuration to load a Basic Kernel";
>>> #address-cells = <1>;
>>> images {
>>> linux_kernel at 1 {
>>> description = "Linux zImage";
>>> data = /incbin/("zImage");
>>> type = "kernel";
>>> arch = "arm";
>>> os = "linux";
>>> compression = "none";
>>> load =  <0x20000000>;
>>> entry = <0x20008000>;
>>> kernel-version = <1>;
>>> hash at 1 {
>>> algo = "sha256";
>>> };
>>> };
>>> fdt at 1 {
>>> description = "FDT blob";
>>> data = /incbin/("myboard.dtn");
>>> type = "flat_dt";
>>> arch = "arm";
>>> compression = "none";
>>> fdt-version = <1>;
>>> hash at 1{
>>> algo = "sha256";
>>> };
>>> };
>>> };
>>> configurations {
>>> default = "config at 1";
>>> config at 1{
>>> description = "Plain Linux";
>>> kernel = "linux_kernel at 1";
>>> fdt = "fdt at 1";
>>> signature at 1{
>>> algo = "sha256,rsa2048";
>>> key-name-hint = "dev_key";
>>> sign-images = "fdt", "kernel";
>>> };
>>> };
>>> };
>>> };
>>>
>>> Does NOT equal (for brevity - I just used the node)
>>>
>>> fdt at 1 {
>>> description = "FDT blob";
>>> data = /incbin/("myboard.dtn");
>>> type = "flat_dt";
>>> arch = "arm";
>>> compression = "none";
>>> fdt-version = <1>;
>>> hash at 1{
>>> algo = "sha256";
>>> };
>>> signature at 1{
>>> algo = "sha256,rsa2048";
>>> key-name-hint = "dev_key";
>>> };
>>> };
>>>
>>> Apparently, this causes the mkimage tooling in my particular instance to
>>> explain invalid blob messages.  The large example above indeed does work
>>> once this nuance was noticed.
>>>
>>> Next,  once the final CTRL FDT is created, how does one get it back into
>>> the actual u-boot binary.  Does/can mkimage insert it into the binary image
>>> at a particular offset?  What is the command to do so?
>>>
>>>
>>>
>>>
>>>
>>> On 23 February 2017 at 12:27, Rick Altherr <raltherr at google.com> wrote:
>>>
>>>>
>>>>
>>>> On Thu, Feb 23, 2017 at 7:48 AM, Ron Brash <ron.brash at gmail.com> wrote:
>>>>
>>>>> Hello all (and thanks Mr. Altherr for this insight),
>>>>>
>>>>> Excellent feedback and I agree that all of this needs to find a home
>>>>> either on the global docs on the website and/or the text-only
>>>>> documentation.  Regardless, this leads me to a few questions.
>>>>>
>>>>> NOTE: the use of a uboot control DTS, control DTB and control FTD even
>>>>> in Mr. Altherr's email is confusion provoking.  One term to rule them all
>>>>> is needed ;)
>>>>>
>>>>
>>>> Agreed.  Technically a flattened device tree (FDT) can be described in
>>>> an ASCII form (dts) or binary form (dtb).
>>>>
>>>>
>>>>>
>>>>> 1.)  What if a board doesn't have OR has ever been configured to use
>>>>> u-boot DTS (could we call this a UDTS or something friendly to
>>>>> differentiate that fact?); this was a point of misunderstanding until I
>>>>> started scampering around into arch/arm/dts/?
>>>>>
>>>>> * For example, my board is a derivative of an Atmel at91sam9g20.  It
>>>>> had a very generic implementation of a DTS that covered reference boards in
>>>>> the Linux kernel, but required a fair bit of modification to make it work.
>>>>> As the at91sam(legacy platform) isn't in u-boot's source tree for a DTS -
>>>>> what would someone like me need to do - do we have a barebones tutorial
>>>>> (again I don't mind publishing such with proofing)?  Is it even required if
>>>>> we have a platform/board already working in the traditional u-boot way?
>>>>>
>>>>> I believe (but have no verified) that if your board is supported by
>>>> U-Boot without a control FDT today, you can just create one that contains
>>>> only the public keys.  I've gathered from the mailing list that using a
>>>> control FDT and the driver model is how all new boards should be
>>>> implemented.
>>>>
>>>>
>>>>> 2.)  Just to summarise - everything winds up in two binaries: u-boot
>>>>> and the FIT image.  So the partition scheme would more or less would look
>>>>> like:
>>>>>
>>>>> /-----------------
>>>>> * Bootstrap/ROM (optional)
>>>>> /----------------
>>>>> * U-boot
>>>>> *    Control DTB
>>>>> *         Has keys
>>>>>
>>>>
>>>> Only the public keys.  The private keys are never stored on the target
>>>> device.
>>>>
>>>>
>>>>> *         Driver loadout/init
>>>>>
>>>> The control FDT only describes the hardware (see
>>>> https://www.devicetree.org/ and http://git.kernel.org/cgit/lin
>>>> ux/kernel/git/torvalds/linux.git/tree/Documentation/devicetr
>>>> ee/usage-model.txt).  U-Boot's driver model matches device drivers
>>>> against nodes in the FDT and starts them.
>>>>
>>>>
>>>>> /----------------
>>>>> * U-boot env
>>>>> *----------------
>>>>> * FIT image
>>>>>
>>>> The FIT shouldn't be in the U-Boot env section.  That's used by U-Boot
>>>> to store its persistent environment.  The FIT is a replacement for the
>>>> kernel image.  Keep a separate place allocated in the flash for kernel but
>>>> store the FIT there.
>>>>
>>>>
>>>>> *    ITS
>>>>>
>>>> I never really thought of it this way, but yes, that's true.  The ITS
>>>> is itself written in device tree syntax and gets compiled to binary form.
>>>>  dtb tends to get used only to describe device trees in binary form that
>>>> describe hardware.  Maybe we need to introduce ITB to clarify this is the
>>>> device tree in binary form describing the image.
>>>>
>>>>
>>>>> *    Kernel
>>>>> *    DTS
>>>>>
>>>>
>>>> Prefer the terms FDT or DTB.  Only the compiled form is stored in the
>>>> FIT.
>>>>
>>>>
>>>>> *    ....
>>>>> /---------------
>>>>> * Rootfs etc...
>>>>> * ...
>>>>> /---------------
>>>>>
>>>>>
>>>>> 3.)  What people used to use to load X address into Z location in
>>>>> memory is now removed by the usage of a DTB in u-boot correct?  I assume
>>>>> that the u-boot DTB now does this and bootarg/bootcmd is partially done
>>>>> away with - as its arguments are augmented by said file.
>>>>>
>>>>
>>>> Not quite.  bootarg/bootcmd is still used.  What is different is that
>>>> booting linux with a FDT with legacy images required multiple arguments to
>>>> bootm.  In that case, bootarg would be 'bootm <zimage_addr> - <fdt_addr>'.
>>>> With a FIT, you only provide the address of the FIT itself to bootm so
>>>> bootarg is set to 'bootm <fit_addr>'.
>>>>
>>>>
>>>>>
>>>>> Anybody have the spare cycles to organise a
>>>>> web-tutorial/presentation/recording with me on a play-by-play to make
>>>>> all of this make sense?  I'm aiming to be in Prague for the 2017 conference
>>>>> in October, might be a good place to showcase this fine-tuning.
>>>>>
>>>>>
>>>> I'm not clear on what you are asking.  I probably have time to review
>>>> docs and presentations and maybe a few phone or video conference meetings.
>>>>
>>>>
>>>>> Ron
>>>>>
>>>>> On 22 February 2017 at 13:51, Rick Altherr <raltherr at google.com>
>>>>> wrote:
>>>>>
>>>>>>
>>>>>> On Tue, Feb 21, 2017 at 10:08 AM, Ron Brash <ron.brash at gmail.com>
>>>>>> wrote:
>>>>>>
>>>>>>> Hello all,
>>>>>>>
>>>>>>> I am adding verified kernel support on a board we are using and I am
>>>>>>> struggling to fully understand all of the concepts and steps
>>>>>>> required to
>>>>>>> pull everything together (on ARM, using ZImages and booting with a
>>>>>>> working
>>>>>>> DTB on 4.4.3x).  I also looked at the test script inside of
>>>>>>> examples, but
>>>>>>> it left me with more questions than understanding.
>>>>>>>
>>>>>>> Please correct me where appropriate in my understanding, but if I am
>>>>>>> confused, likely others are too and I hope this helps everyone
>>>>>>> involved
>>>>>>> overall.
>>>>>>>
>>>>>>
>>>>>> You've asked some really good questions.  Hopefully this discussion
>>>>>> will end up with patches to clarify the docs.
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> Steps:
>>>>>>> ---------------------------------------------------------------
>>>>>>>
>>>>>>> First, u-boot needs to have the appropriate features enabled and to
>>>>>>> be
>>>>>>> built using them.  At a minimum, I suspect:
>>>>>>>
>>>>>>> CONFIG_RSA=y
>>>>>>> CONFIG_FIT=y
>>>>>>> CONFIG_FIT_SIGNATURE=y
>>>>>>> CONFIG_OF_CONTROL=y
>>>>>>>
>>>>>>>
>>>>>> Yup.  That looks right.
>>>>>>
>>>>>>
>>>>>>> Next, we need to derive the appropriate cryptographic
>>>>>>> primitives/keys.
>>>>>>>
>>>>>>> #Generate a private signing key (RSA2048):
>>>>>>> openssl genrsa -F4 -out \
>>>>>>> "${key_dir}"/"${key_name}".key 2048
>>>>>>>
>>>>>>> # Generate a public key:
>>>>>>> openssl req -batch -new -x509 \
>>>>>>> -key "${key_dir}"/"${key_name}".key \
>>>>>>> -out "${key_dir}"/"${key_name}".crt
>>>>>>>
>>>>>>>
>>>>>> So far so good.  In general, I suggest having multiple signing keys.
>>>>>> You can put all the public keys in your u-boot so an image signed with any
>>>>>> of those keys will be accepted.  If you happen to have a signing key
>>>>>> compromised, you can switch to one of the other ones.  With that other key,
>>>>>> you can sign an update the removes the compromised public key from future
>>>>>> images.
>>>>>>
>>>>>>
>>>>>>> Then we derive the ITS or image source file - a file that
>>>>>>> hints/describes
>>>>>>> the elements that will be verified and/or inside of the FIT image?
>>>>>>> Lets
>>>>>>> call this $FIT_ITS
>>>>>>>
>>>>>>> FIT is a container format.  Generally, you'll create a FIT that
>>>>>> contains the zImage, dtb, initramfs, etc.  With FIT support enabled in
>>>>>> u-boot, you only need to provide the single FIT image address to 'bootm'.
>>>>>>  u-boot will use the config section to find the individual elements, load
>>>>>> them into RAM as needed, and boot.
>>>>>>
>>>>>>
>>>>>>> / dts - v1 /;
>>>>>>> / {
>>>>>>> description = "Configuration to load a Xen Kernel";
>>>>>>> #address-cells = <1>;
>>>>>>> images {
>>>>>>> linux_kernel @ 1 {
>>>>>>> description = "Linux zImage";
>>>>>>> data = /incbin / ("pathToImage/zImage");
>>>>>>> type = "kernel";
>>>>>>> arch = "arm";
>>>>>>> os = "linux";
>>>>>>> compression = "none";
>>>>>>> load = <0xaf600000 >;
>>>>>>> entry = <0xaf600000 >;
>>>>>>> hash @ 1 {
>>>>>>> algo = "sha1";
>>>>>>> };
>>>>>>> };
>>>>>>> fdt @ 1 {
>>>>>>> description = "FDT blob";
>>>>>>> data = /incbin / ("PathToDTBUsedByBootingKernel/ex.dtb");
>>>>>>> type = "flat_dt";
>>>>>>> arch = "arm";
>>>>>>> compression = "none";
>>>>>>> load = <0xaec00000 >;
>>>>>>>
>>>>>>
>>>>>> You generally don't need a 'load' property for the FDT or an
>>>>>> initramfs.  Without one, U-Boot will allocate RAM dynamically, if needed,
>>>>>> and pass the relocated address to the kernel.
>>>>>>
>>>>>> hash @ 1 {
>>>>>>> algo = "sha1";
>>>>>>> };
>>>>>>> };
>>>>>>> };
>>>>>>> configurations {
>>>>>>> default = "config at 1";
>>>>>>> config @ 1 {
>>>>>>> description = "Plain Linux";
>>>>>>> kernel = "linux_kernel at 1";
>>>>>>> fdt = "fdt at 1";
>>>>>>> loadables = "linux_kernel at 1";
>>>>>>>
>>>>>>
>>>>>> 'loadables' is for other types of firmware.  You only need the
>>>>>> 'kernel' property for loading and booting the kernel.
>>>>>>
>>>>>>
>>>>>>> };
>>>>>>> };
>>>>>>> };
>>>>>>>
>>>>>>> Question: Does a signature section go into this as well? underneath
>>>>>>> the
>>>>>>> hash node for each value?
>>>>>>
>>>>>>
>>>>>>> signature at 1 {
>>>>>>>      algo = "sha1,rsa2048";
>>>>>>>      value = <...kernel signature 1...>
>>>>>>>  };
>>>>>>>
>>>>>>
>>>>>> You add a signature section to each image you want signed within the
>>>>>> FIT.  In your case, add one for both the kernel and FDT images.  Signatures
>>>>>> go _next_ to the hash section, not in it.  Omit the 'value' property as it
>>>>>> will be generated for you later.
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> Then using the device-tree-compiler (dtc), I create a DTB for
>>>>>>> u-boot.  This
>>>>>>> is the control FDT and this defines what keys are used etc..
>>>>>>>
>>>>>>
>>>>>> The control FDT is used for U-Boot's driver model _as well as_
>>>>>> providing public keys for verifying images.  Your board may not currently
>>>>>> use a control FDT in which case you create one from scratch.
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> #Assemble control FDT for U-Boot with space for public key:
>>>>>>> $DTC -p 0x1000 u-boot.dts -O dtb -o u-boot.dtb
>>>>>>>
>>>>>>> Question: What is required inside of the u-boot.dts for u-boot?  Is
>>>>>>> it
>>>>>>> simply the same .dts used by the booting kernel, but with a section
>>>>>>> proclaiming the keys?
>>>>>>>
>>>>>>
>>>>>> This depends on the board you are using.  For example, an AST2500
>>>>>> requires a DTB for U-Boot to load the right drivers.  The DTB used by
>>>>>> U-Boot is slightly different from that used by Linux as the Linux DTB often
>>>>>> includes addition configuration information.  When using verified boot, the
>>>>>> U-Boot DTB includes the public keys whereas the FDT/DTB stored in the FIT
>>>>>> does not as Linux doesn't need them.
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> Question:  Where will the compiled u-boot.dtb eventually go?  Is
>>>>>>> this put
>>>>>>> into a FIT image, or flashed onto the board alongside the u-boot
>>>>>>> bootloader
>>>>>>> itself?
>>>>>>>
>>>>>>
>>>>>> The U-Boot control FDT is compiled into the U-Boot binary.  The FDT
>>>>>> in the FIT is the FDT that is provided to Linux.
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> Next, given that the above steps are completed, I need to create a
>>>>>>> FIT
>>>>>>> image with space for the signature.
>>>>>>>
>>>>>>> # Generate fitImage with space for signature:
>>>>>>> $MKIMG -D "-I dts -O dtb -p 2000" \
>>>>>>> -f f$FIT_ITS $FIT_IMG
>>>>>>>
>>>>>>> Question: Is the FIT_IMAGE the actual zimage or is it an output
>>>>>>> image that
>>>>>>> contains all of the values contained within the ITS?
>>>>>>>
>>>>>>
>>>>>> The latter.  It will have a compiled version of the ITS as well as
>>>>>> the actual images specified in the ITS (kernel, fdt).
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> Next this FIT_IMAGE (assuming that this is the final FIT image that
>>>>>>> contains the FDT and zImage) needs to be signed and the public key
>>>>>>> added to
>>>>>>> it; given that that the key information is in the uboot.
>>>>>>>
>>>>>>
>>>>>> You sign the FIT_IMAGE and put the public keys in the control DTB.
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> # Sign fitImage and add public key into u-boot.dtb:
>>>>>>> $MKIMG -D "-I dts -O dtb -p 2000" -F \
>>>>>>> -k "${key dir}" -K u-boot.dtb -r $FIT_IMG
>>>>>>>
>>>>>>
>>>>>> This is putting the public keys used by the FIT image into the
>>>>>> control DTB
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> Then, we sign the subsequent fitImage again - correct?
>>>>>>>
>>>>>>> # Signing subsequent fitImage:
>>>>>>> $MKIMG -D "-I dts -O dtb -p 2000" \
>>>>>>> -k "${key dir}" -f $FIT_ITS -r $FIT_IMG
>>>>>>>
>>>>>>
>>>>>> This is generating signatures for the images in the FIT and storing
>>>>>> those signatures in the FIT.
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> Now that all of the above is done - we need to:
>>>>>>> 1. Write our uboot to the flash
>>>>>>> 2. Write our FIT_IMAGE to flash
>>>>>>>
>>>>>>> Question: Do we write anything else to persistent storage? The ITS?
>>>>>>> etc..
>>>>>>>
>>>>>>
>>>>>> No.  Everything is contained in the U-Boot binary (control FDT
>>>>>> including public keys) and the FIT (images, signatures)
>>>>>>
>>>>>>>
>>>>>>> Question: Do we just boot using anything else or just bootm
>>>>>>> 0xLocationOfTheFitImageInRAM
>>>>>>>
>>>>>>
>>>>>> The latter.  bootm will check the config section in the FIT and use
>>>>>> the kernel, fdt, etc specified there.
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> Greatly appreciate any assistance to all of these questions and I'm
>>>>>>> sure
>>>>>>> this threat will be of interest to anyone else too.
>>>>>>>
>>>>>>> Thanks!
>>>>>>
>>>>>> _______________________________________________
>>>>>>> U-Boot mailing list
>>>>>>> U-Boot at lists.denx.de
>>>>>>> http://lists.denx.de/mailman/listinfo/u-boot
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>>
>>> --
>>>
>>>
>>> Ron Brash
>>> CTO  & Co-founder of Atlants Embedded Inc.
>>> www.atlantsembedded.com
>>> ------------------------------------------------------------------
>>>
>>> Cell +1 438 880 6441 <(438)%20880-6441>
>>> Email  ron.brash at gmail.com
>>> Blog www.pacificsimplicity.ca
>>> LinkedIn ca.linkedin.com/in/ronbrash/
>>>
>>>
>>>
>>> This communication is intended for the use of the recipient to which it
>>> is
>>> addressed, and may contain confidential, personal, and or privileged
>>> information. Please contact the sender immediately if you are not the
>>> intended recipient of this communication, and do not copy, distribute, or
>>> take action relying on it. Any communication received in error, or
>>> subsequent reply, should be deleted or destroyed.
>>>
>>
>>
>
>
> --
>
>
> Ron Brash
> CTO  & Co-founder of Atlants Embedded Inc.
> www.atlantsembedded.com
> ------------------------------------------------------------------
>
> Cell +1 438 880 6441 <(438)%20880-6441>
> Email  ron.brash at gmail.com
> Blog www.pacificsimplicity.ca
> LinkedIn ca.linkedin.com/in/ronbrash/
>
>
>
> This communication is intended for the use of the recipient to which it is
> addressed, and may contain confidential, personal, and or privileged
> information. Please contact the sender immediately if you are not the
> intended recipient of this communication, and do not copy, distribute, or
> take action relying on it. Any communication received in error, or
> subsequent reply, should be deleted or destroyed.
>


More information about the U-Boot mailing list