Понимание проверенного Uboot на встроенной плате

Я просмотрел презентации и документацию по проверенному u-boot и у меня есть несколько вопросов. Я постараюсь рассказать всем пользователям, где я нахожусь, поскольку я подозреваю, что я не единственный, у кого есть небольшие трудности с пониманием процесса проверки u-boot.

У меня есть скомпилированный zImage с рабочим внешним DTB для использования без проверки. Он загружается и работает (назовем это normal-board.dts)

Во-вторых, у меня есть u-boot, скомпилированный со следующими записями конфигурации:

CONFIG_ARM=y
CONFIG_ARCH_AT91=y
CONFIG_TARGET_AT91SAM9260EK=y
CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G20,SYS_USE_DATAFLASH_CS1"
CONFIG_SYS_PROMPT="#> "
# CONFIG_CMD_BDI is not set
CONFIG_CMD_IMI=y
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_LOADS is not set
# CONFIG_CMD_FPGA is not set
# CONFIG_CMD_SOURCE is not set
CONFIG_CMD_SETEXPR=y
CONFIG_DEFAULT_DEVICE_TREE="myboard"
CONFIG_CMD_MMC=y
CONFIG_CMD_FAT=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_RSA=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_OF_CONTROL=y

Моя плата имеет схему разделов, похожую на:

... boot strap, uboot and env
0xD00084000  (zImage)
0xD0020AA00  (normal-board.dtb)
The rootfs is on NAND (external to this chip)

Устройство можно загрузить в стандартной конфигурации с помощью такой команды, как:

cp.b 0xD0084000 0x22000000 0x186A00;cp.b 0xD020AA00 0x28000000 0x61A8;bootm 0x22000000 - 0x28000000

На данный момент я перекомпилировал u-boot, но номенклатура немного сбивает с толку, так как есть несколько элементов.

  • FIT Control DTS (я предполагаю, что он используется u-boot и должен находиться в отдельном разделе)
  • FIT DTB (такой же DTB более или менее как не-FIT (normal-board.dtb), но где-то с магией FIT)
  • Образ ядра FIT (я предполагаю, что здесь тоже добавляется какая-то магия в zImage?)

Увидев, что есть элемент управления uboot FIT FDT, нужен ли для него собственный раздел? и будет ли FIT DTB таким же, как DTB рабочего ядра (просто прошить его вместо неподходящего)???

Далее, учитывая этот скрипт, который я начал хэшировать из различной документации и слайдов, мы можем видеть, что u-boot.{dts,dtb} — это контрольный FDT, а файл ITS — тот, который подходит (я предполагаю, что это то же самое как normal-board.dts, НО добавлен узел FIT).

Например. u-boot.dts

/dts-v1/;

/ {
        model = "Keys";
        compatible = "myboard";
        signature {
                dev_key {
                        required = "conf";
                        algo = "sha1,rsa2048";
                        key-name-hint = "dev_key";
                };
        };
};

Теперь пример DTS для раздела myboard WITH THE FIT:

/dts-v1/;

/ {
    description = "Linux kernel2";
    #address-cells = <1>;
    images {
        kernel@1 {
            description = "Linux kernel";
            data = /incbin/("../linux/arch/arm/boot/zImage");
            arch = "arm";
            os = "linux";
            type = "kernel_noload";
            compression = "none";
            load = <0x80080000>;
            entry = <0x80080000>;
            kernel-version = <1>;
            hash@1 {
                algo = "sha1";
            };
        };
    };
    configurations {
        default = "conf@1";
        conf@1 {
            description = "Boot Linux kernel";
            kernel = "kernel@1";
            signature@1 {
                algo = "sha1, rsa2048 ";
                key-name-hint = "dev_key";
                sign-images = "kernel";
            };
        };
    };
};

Однако, что, черт возьми, такое fitImage (см. скрипт ниже — это из примеров)? это zImage? Я не смог найти никакой документации, описывающей его первое упоминание - что это такое, откуда оно взялось и т. д... или это вывод, сгенерированный ссылкой из ITS для incbin?

#!/bin/bash

key_dir=/tmp/keys
key_name=dev_key
FIT_IMG="fitImage"

rm -rf ${key_dir}
mkdir ${key_dir}

MKIMG="/home/dev/lede/staging_dir/host/bin/mkimage"
DTC="/usr/bin/dtc"

#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...
CTRL_FDT="u-boot.dts"

# FIT image ITS - describes the node
FIT_ITS="fit-image.its"

#Assemble control FDT for U-Boot with space for public key:
$DTC -p 0x1000 $CTRL_FDT -O dtb -o u-boot.dtb

# Generate fitImage with space for signature:
$MKIMG -D "-I dts -O dtb -p 2000" \
-f f$FIT_ITS $FIT_IMG

# 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

# Signing subsequent fitImage:
$MKIMG -D "-I dts -O dtb -p 2000" \
-k "${key dir}" -f $FIT_ITS -r $FIT_IMG

Iminfo заводит меня так далеко:

#> iminfo          

## Checking Image at 20000000 ...
   FIT image found
   FIT description: Configuration to load a Basic Kernel
    Image 0 (linux_kernel@1)
     Description:  Linux zImage
     Type:         Kernel Image
     Compression:  uncompressed
     Data Start:   0x200000dc
     Data Size:    1465544 Bytes = 1.4 MiB
     Architecture: ARM
     OS:           Linux
     Load Address: 0x20000000
     Entry Point:  0x20008000
     Hash node:    'hash@1'
     Hash algo:    sha256
     Hash value:   bf1d62a9ac777310746c443f2500cf197967f1e7c9cb56ff5c33206670e12d8f
     Hash len:     32
    Image 1 (fdt@1)
     Description:  FDT blob
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x20165ea4
     Data Size:    21681 Bytes = 21.2 KiB
     Architecture: ARM
     Hash node:    'hash@1'
     Hash algo:    sha256
     Hash value:   c7f32d039871d858dda8d397c3b6a685bc914c78cf70f03d1860f61ecfe9c689
     Hash len:     32
    Default Configuration: 'config@1'
    Configuration 0 (config@1)
     Description:  Plain Linux
     Kernel:       linux_kernel@1
     FDT:          fdt@1
## Checking hash(es) for FIT Image at 20000000 ...
   Hash(es) for Image 0 (linux_kernel@1): sha256+ 
   Hash(es) for Image 1 (fdt@1): sha256+ 

ZImage подготовлен (и это, вероятно, неправильный путь)

mkimage -A arm -O linux -C none -T kernel -a 0x22000000 -e 0x22008000 -n linux-4.4.36 \
    -d $(KDIR)/zImage $(BIN_DIR)/$(IMG_PREFIX)-zImage-nDTB

Даже в следующих строках (кажется, я понял, что мне делать с адресами - является ли перераспределение частью проблемы? Например, переменные fdt_high?)

#> bootm 0x23000000
## Current stack ends at 0x23f119b8 *  kernel: cmdline image address = 0x23000000
## Loading kernel from FIT Image at 23000000 ...
No configuration specified, trying default...
Found default configuration: 'config@1'
   Using 'config@1' configuration
   Trying 'linux_kernel@1' kernel subimage
     Description:  Linux zImage
     Type:         Kernel Image
     Compression:  uncompressed
     Data Start:   0x230000dc
     Data Size:    1465544 Bytes = 1.4 MiB
     Architecture: ARM
     OS:           Linux
     Load Address: 0x23000000
     Entry Point:  0x23000000
     Hash node:    'hash@1'
     Hash algo:    sha256
     Hash value:   bb397db1ec90ec8526c6d215c9ded2a1357a258c2145f97fda9898e810e847d7
     Hash len:     32
   Verifying Hash Integrity ... sha256+ OK
   kernel data at 0x230000dc, len = 0x00165cc8 (1465544)
*  ramdisk: using config 'config@1' from image at 0x23000000
*  ramdisk: no 'ramdisk' in config
*  fdt: using config 'config@1' from image at 0x23000000
## Checking for 'FDT'/'FDT Image' at 23000000
## Loading fdt from FIT Image at 23000000 ...
   Using 'config@1' configuration
   Trying 'fdt@1' fdt subimage
     Description:  FDT blob
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x23165ea4
     Data Size:    21681 Bytes = 21.2 KiB
     Architecture: ARM
     Hash node:    'hash@1'
     Hash algo:    sha256
     Hash value:   c7f32d039871d858dda8d397c3b6a685bc914c78cf70f03d1860f61ecfe9c689
     Hash len:     32
   Verifying Hash Integrity ... sha256+ OK
Can't get 'load' property from FIT 0x23000000, node: offset 1465916, name fdt@1 (FDT_ERR_NOTFOUND)
   Booting using the fdt blob at 0x23165ea4
   of_flat_tree at 0x23165ea4 size 0x000054b1
Initial value for argc=3
Final value for argc=3
   Loading Kernel Image ... OK
CACHE: Misaligned operation at range [23000000, 23165cc8]
   kernel loaded at 0x23000000, end = 0x23165cc8
images.os.start = 0x23000000, images.os.end = 0x2316c911
images.os.load = 0x23000000, load_end = 0x23165cc8
ERROR: new format image overwritten - must RESET the board to recover

person mcdoomington    schedule 12.02.2017    source источник


Ответы (2)


Итак, в приведенном выше вопросе много всего, и я попытаюсь ответить на несколько вещей, которые должны помочь прояснить ситуацию:

  1. Бинарный файл U-Boot должен содержать открытый ключ. Таким образом, в этом случае дерево устройств «myboard», которое вы перечислили, — это то место, где это должно закончиться. Он находится в двоичном файле, а не в отдельном разделе во флэш-памяти.
  2. Следующее, что изображение FIT представляет собой контейнер, который можно открыть разными способами. FitImage содержит zImage и normal-board.dtb и логику, так что вы можете сказать, что каждая из этих частей должна быть подписана определенным открытым ключом. Таким образом, в этом случае вместо флэш-раздела для zImage и другого для normal-board.dtb у вас есть один раздел для размещения fitImage. Это результат предоставления «своего» файла для mkimage. Это похоже на то, как "uImage" является результатом передачи "zImage" в mkimage.
person Tom Rini    schedule 16.02.2017
comment
Спасибо, Том. Следующий вопрос, который у меня есть, касается адресов, загрузки и т. д. Я обновил свой ответ, чтобы показать, как я зашел так далеко. - person mcdoomington; 01.03.2017

После многих человеко-часов изучения, чтения и попыток я создал полную статью в блоге о том, как работает проверенный uboot и как DTB (обе формы) объединяются при создании окончательных образов.

Этот статью можно найти здесь

Тем не менее, ключевые моменты, на которые стоит обратить внимание, это действительно то, что сказал Том, и вот еще несколько (после цитирования моей статьи):

  • Существует два типа DTB (ядро и uboot DTBS).
  • Существует файл под названием ITS — он описывает образ FIT, который необходимо построить.
  • Вам понадобится асинхронная пара ключей
  • Вам понадобится версия mkimage, которая поддерживает проверенные uboot/DTB.
  • Вашему загрузчику потребуется поддержка. Подтверждено, что uboot включен.
  • Uboot и ядро ​​Linux должны знать о DTB
  • Несмотря на то, что вы подписываете свои образы, копия открытого ключа и другая криптографическая информация потребуется в окончательном загрузчике.

Это был увлекательный процесс :)

person mcdoomington    schedule 23.11.2017
comment
Исходная ссылка кажется битой. Вот кешированная версия с сайта обратная машина. - person Omer Anson; 05.03.2020