[U-Boot] Complete verified uboot example

Rick Altherr raltherr at google.com
Tue Feb 28 21:51:56 UTC 2017


I've never seen the kernel load address (the start address for copying
the kernel image into RAM) being the same as the entrypoint address
(where U-Boot jumps to begin executing the kernel).  I'd expect the
load address to be 0x23000000.

It looks like you are converting the zImage into a U-Boot legacy image
and then storing the legacy image in the FIT.  Don't do that.  Store
the zImage in the FIT directly.

On Tue, Feb 28, 2017 at 11:09 AM, Ron Brash <ron.brash at gmail.com> wrote:
> Hello,
>
> Still for some reason - there is an issue with booting from the FIT.  With a
> version of Uboot without the FIT related CONFIGs enabled; everything works.
>
> Here is me taking my zImage and converting it to a u-image ( I am not sure
> on the addresses)
>
> mkimage -A arm -O linux -C none -T kernel -a 0x23008000 -e 0x23008000 -n
> linux-4.4.36b \
> -d $(KDIR)/zImage $(BIN_DIR)/$(IMG_PREFIX)-zImage-nDTB2
>
>
> My .its:
>
> /dts-v1/;
> /{
> description = "Configuration to load a Basic Kernel";
> #address-cells = <1>;
> images {
> linux_kernel at 1 {
> description = "Linux zImage";
> data =
> /incbin/("../../../../bin/targets/myboard/legacy/myboard-legacy-zImage-nDTB2");
> type = "kernel";
> arch = "arm";
> os = "linux";
> compression = "none";
> load =  <0x23008000>;
> entry = <0x23008000>;
> kernel-version = <1>;
> hash at 1 {
> algo = "sha256";
> };
> };
> fdt at 1 {
> description = "FDT blob";
> data = /incbin/("../../../../bin/targets/myboard/legacy/myboard.dtb");
> type = "flat_dt";
> arch = "arm";
> compression = "none";
> load =  <0x28000000>;
> 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";
> };
> };
> };
> };
>
>
> Then
>
>
> set -ex
> key_dir="/tmp/keys"
> key_name="dev_key"
>
> rm -rf ${FIT_IMG}
> rm -rf ${key_dir}
> mkdir ${key_dir}
> rootdir="/home/dev/usr"
>
> MKIMG="${rootdir}/lede/staging_dir/host/bin/mkimage"
> DTC="/usr/bin/dtc"
> CPP="/usr/bin/cpp"
> OPENSSL="/usr/bin/openssl"
>
> #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
>
> # Control FDT (u-boot.dts) - hits uboot to have keys etc...
> BD_NAME="at91sam9260-plx35"
> PATH_TO_BIN="${rootdir}/lede/bin/targets/myboard/legacy"
>
> #
> # This is the uboot-nodtb.bin (just renamed)
> #
> UBOOT_NAME="lede-myboard.bin"
> UBOOT_WITH_DTB="${PATH_TO_BIN}/${UBOOT_NAME}"
>
> PATH_TO_CTRL_FDT="${rootdir}/lede/build_dir/target-arm_arm926ej-s_musl-1.1.15_eabi/linux-myboard/myboard-uboot-2016.05/arch/arm/dts/"
>
> CTRL_FDT="${PATH_TO_CTRL_FDT}${BD_NAME}"
>
> FIT_ITS="at91sam9260"
> FIT_IMG="${rootdir}/lede/bin/targets/myboard/legacy/lede-at91-image.fit"
>
> DOPTS="-I dts -O dtb -p 2000"
>
> # Generate fitImage with space for signature:
> echo "create FIT with space - no signing"
> echo " --------------------------------"
> $MKIMG -D "${DOPTS}" \
>  -f "${FIT_ITS}".its "${FIT_IMG}"
>
> echo ""
> echo ""
>
> # Now add them and sign them
> echo "Sign images with our keys"
> echo " --------------------------------"
> $MKIMG -D "${DOPTS}" -F \
> -k "${key_dir}" -K "${CTRL_FDT}".dtb -r "${FIT_IMG}"
>
> echo ""
> echo ""
>
> # Add FDT to image
> cp ${UBOOT_WITH_DTB} ${UBOOT_WITH_DTB}-wDTB
> cat ${PATH_TO_CTRL_FDT}/${BD_NAME}.dtb >> ${UBOOT_WITH_DTB}-wDTB
>
>
> Then I flash the uboot-WDTB to the board and also the FIT image.  Following
> that, then I load the FIT into RAM and execute it with the command:
>
>
> cp.b 0xD0084000 0x22000000 0x186A00;setenv my_bootcount 0; bootm 0x22000000
>
> Initial value for argc=3
> Final value for argc=3
> ## Current stack ends at 0x23f119b8 *  kernel: cmdline image address =
> 0x22000000
> ## 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: 0x23008000
>      Entry Point:  0x23008000
>      Hash node:    'hash at 1'
>      Hash algo:    sha256
>      Hash value:
> 52f8048436c3f62d9108957cb4f6f7d4e58c8c9931d68ea6f0121f4c661c7ffe
>      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:
> c7f32d039871d858dda8d397c3b6a685bc914c78cf70f03d1860f61ecfe9c689
>      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 [23008000, 2316dcc8]
>    kernel loaded at 0x23008000, end = 0x2316dcc8
> using: FDT
> ## initrd_high = 0x24000000, copy_to_ram = 1
>    ramdisk load start = 0x00000000, ramdisk load end = 0x00000000
> ## device tree at 28000000 ... 280054b0 (len=33969 [0x84B1])
>    Loading Device Tree to 23f08000, end 23f104b0 ... OK
> Initial value for argc=3
> Final value for argc=3
> ## Transferring control to Linux (at address 23008000)...
>
> Starting kernel ...
>
> undefined instruction
> pc : [<23008028>]          lr : [<23f44ca4>]
> reloc pc : [<20fc3028>]    lr : [<21effca4>]
> sp : 23f11980  ip : 23f9472c     fp : 00000000
> r10: 23f1e61c  r9 : 23f17ef0     r8 : 23f4585c
> r7 : 00000000  r6 : 23008000     r5 : 23f9b0f4  r4 : 00000081
> r3 : 000054b1  r2 : 23f08000     r1 : 00000658  r0 : 23900000
> Flags: nZCv  IRQs off  FIQs off  Mode SVC_32
> Resetting CPU ...
>
> With iminfo:
>
> #> cp.b 0xD0084000 0x22000000 0x186A00
> #> iminfo
>
> ## Checking Image at 22000000 ...
>    FIT image found
>    FIT description: Configuration to load a Basic Kernel
>     Image 0 (linux_kernel at 1)
>      Description:  Linux zImage
>      Type:         Kernel Image
>      Compression:  uncompressed
>      Data Start:   0x220000dc
>      Data Size:    1465544 Bytes = 1.4 MiB
>      Architecture: ARM
>      OS:           Linux
>      Load Address: 0x23008000
>      Entry Point:  0x23008000
>      Hash node:    'hash at 1'
>      Hash algo:    sha256
>      Hash value:
> 52f8048436c3f62d9108957cb4f6f7d4e58c8c9931d68ea6f0121f4c661c7ffe
>      Hash len:     32
>     Image 1 (fdt at 1)
>      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:
> c7f32d039871d858dda8d397c3b6a685bc914c78cf70f03d1860f61ecfe9c689
>      Hash len:     32
>     Default Configuration: 'config at 1'
>     Configuration 0 (config at 1)
>      Description:  Plain Linux
>      Kernel:       linux_kernel at 1
>      FDT:          fdt at 1
> ## Checking hash(es) for FIT Image at 22000000 ...
>    Hash(es) for Image 0 (linux_kernel at 1): sha256+
>    Hash(es) for Image 1 (fdt at 1): sha256+
>
>
> Any input?  This seems like offsets and not knowing where various components
> need to be looking.
>
>
>
>
>
>
> On 27 February 2017 at 16:53, Rick Altherr <raltherr at google.com> wrote:
>>
>> 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:
>>> 5dcf9a4328bca6fe5c3405e03b9a58402dce36f3a4f0c757e52091b050d2bcb2
>>>      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:
>>> c7f32d039871d858dda8d397c3b6a685bc914c78cf70f03d1860f61ecfe9c689
>>>      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/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/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
>>>>> 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
>>> 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
> 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