[U-Boot] Complete verified uboot example

Ron Brash ron.brash at gmail.com
Thu Feb 23 15:48:10 UTC 2017


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 ;)

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?

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
*         Driver loadout/init
/----------------
* U-boot env
*----------------
* FIT image
*    ITS
*    Kernel
*    DTS
*    ....
/---------------
* 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.

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.

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
>>
>
>


More information about the U-Boot mailing list