| | 76 | |
| | 77 | |
| | 78 | [=#distro-config] |
| | 79 | === Distro Config === |
| | 80 | The Newport Bootloader uses U-Boot's 'Distro Config' which is a well defined U-Boot env intended to make it easier for distro maintainers to develop compatible bootscripts. This primarily entails a set of 'boot scripts' and variables that control them. |
| | 81 | |
| | 82 | Ultimately this U-Boot environment is looking for a U-Boot [#bootscript boot script] on a 'bootable' partition (partitions with the 'boot' flag enabled). It searches in this order with these rules: |
| | 83 | - **boot_targets** - list of target device type/nums to search: defaults to mmc0 mmc1 usb0 sata0 |
| | 84 | - **devplist** - ''dynamically created'' list of all partitions flagged as 'bootable' |
| | 85 | - **boot_prefixes** - list of directories within a partition searched for bootscripts |
| | 86 | - **boot_scripts** - list of boot script names searched for |
| | 87 | |
| | 88 | |
| | 89 | [=#bootscript] |
| | 90 | === Boot Scripts === |
| | 91 | When writing bootscripts compatible with [#distro-config Distro Config] you can assume the following env variables: |
| | 92 | - **devtype** - the device type the script was loaded from (mmc|usb|sata) |
| | 93 | - **devnum** - the device number the script was loaded from (ie 0 for mmc0, 1 for mmc1, etc) |
| | 94 | - **distro_bootpart** - the partition number the script was loaded from (ie 0, 1, etc) |
| | 95 | - **fdtcontroladdr** - the address the device-tree is at (Note that the Newport bootloader does not load/manipulate the device-tree itself - this is done by the SPL which loads/manipulates the device-tree and passes it to the bootloader) |
| | 96 | - **kernel_addr_r** - address where kernel can be loaded |
| | 97 | - **bootargs** - default bootargs to pass to the kernel - you probably want to add to this and not overwrite it |
| | 98 | - **console** - the serial console device to pass to the kernel |
| | 99 | |
| | 100 | Additionally you should note the following: |
| | 101 | - use load/ls/save commands which support FAT/ext filesystem types automatically instead of the fs specific commands |
| | 102 | - if using a root filesystem that is not supported by the bootloader (ie F2FS or BTRFS) you can place your kernel image in the FAT12 filesystem on partition 1 of the boot device. This filesystem is part of the 16MB 'Boot Firmware' image. If doing so you will need to compress the kernel and package it into a [#fit FIT image] in order to fit it in the available space. |
| | 103 | |
| | 104 | The Distro-Config environment supports legacy uImage scripts (it does not support FIT images with scripts). You can create these with the {{{mkimage}}} tool from U-Boot as such: |
| | 105 | {{{#!bash |
| | 106 | mkimage -A arm64 -T script -C none -d ubuntu.txt newport.scr |
| | 107 | }}} |
| | 108 | |
| | 109 | You can then place the uImage {{{newport.scr}}} on a bootable partition such as the embedded FAT12 filesystem within the Newport boot firmware as such: |
| | 110 | {{{#!bash |
| | 111 | fatfs-tool -i firmware-newport.img cp newport.scr / |
| | 112 | }}} |
| | 113 | |
| | 114 | Alternatively this can be done at runtime on the target within Linux by mounting the FAT12 partition. For example: |
| | 115 | {{{#!bash |
| | 116 | mount /dev/mmcblk0p1 /mnt |
| | 117 | mkimage -A arm64 -T script -C none -d ubuntu.txt /mnt/newport.scr |
| | 118 | umount |
| | 119 | }}} |
| | 120 | |
| | 121 | |
| | 122 | [=#boot_targets] |
| | 123 | === Boot Device Order (boot_targets) === |
| | 124 | While the Newport product family can only boot its [wiki:newport/boot Boot Firmware] from an MMC device (ie eMMC or microSD), once you are booted to the bootloader you can choose from a wider variety of devices to boot the OS from. |
| | 125 | |
| | 126 | This OS boot device order is specified by the [#distro-config Distro Config] environment. Specifically it is controlled by the {{{boot_targets}}} env variable which defaults to {{{mmc0 mmc1 usb0 sata0}}}. |
| | 127 | |
| | 128 | For example, to limit OS booting to only SATA: |
| | 129 | {{{#!bash |
| | 130 | setenv boot_targets sata0 |
| | 131 | saveenv |
| | 132 | }}} |
| | 133 | |
| | 134 | |
| | 135 | [=#fit] |
| | 136 | == Flattened Image Tree (FIT) images == |
| | 137 | The U-Boot bootloader supports Flattened Image Tree (FIT) images which expand greatly on the legacy U-Boot image (uImage) format by allowing multiple binary blobs within an image. These blobs can be kernel images, ramdisk images, device-tree blobs, and bootloader scripts. Each image can also be optionally compressed (meaning U-Boot will decompress it) and check-sumed with a variety of hash mechanisms (meaning U-Boot will verify the image before using it). |
| | 138 | |
| | 139 | Quick summary of FIT Images: |
| | 140 | * introduced to resolve limitations with original single-image formats and follow-on multi-image format supported by UBoot bootm (boot memory) |
| | 141 | * uses power of the Device-Tree-Compiler (DTC) |
| | 142 | * FIT .itb files can be created with mkimage by passing in a .its file which in device-tree notation describes the images |
| | 143 | * U-Boot supports FIT with several commands: |
| | 144 | - {{{source <addr>:<name>}}} # source a script by name from FIT image in memory |
| | 145 | - {{{iminfo <fitaddress>}}} # print all the info contained in a FIT image in memory and verify (just not boot it) |
| | 146 | - {{{imextract <fitaddress> <item> <addr>}}} # extract item (ie kernel@1) to addr |
| | 147 | - {{{bootm <fitaddress>[#conf] - $fdtcontroladdr}}} # boot default or 'conf' configuration (ie #config@1) |
| | 148 | - {{{bootm start <fitaddress>[#conf] - $fdtcontroladdr}}} # boot from memory a specific configuration (or default configuration) from FIT image |
| | 149 | |
| | 150 | Example: |
| | 151 | * kernel.its with a single compressed kernel for ARM64 (used by Newport) |
| | 152 | {{{#!bash |
| | 153 | /dts-v1/; |
| | 154 | / { |
| | 155 | description = "Simple image with single Linux kernel"; |
| | 156 | #address-cells = <1>; |
| | 157 | images { |
| | 158 | kernel@1 { |
| | 159 | description = "ThunderX kernel"; |
| | 160 | data = /incbin/("./Image.gz"); |
| | 161 | type = "kernel"; |
| | 162 | arch = "arm64"; |
| | 163 | os = "linux"; |
| | 164 | compression = "gzip"; |
| | 165 | load = <0x40080000>; |
| | 166 | entry = <0x40080000>; |
| | 167 | hash@1 { |
| | 168 | algo = "sha256"; |
| | 169 | }; |
| | 170 | }; |
| | 171 | }; |
| | 172 | |
| | 173 | configurations { |
| | 174 | default = "conf@1"; |
| | 175 | conf@1 { |
| | 176 | description = "Boot Linux kernel"; |
| | 177 | kernel = "kernel@1"; |
| | 178 | }; |
| | 179 | }; |
| | 180 | }; |
| | 181 | }}} |
| | 182 | * create image: |
| | 183 | {{{#!bash |
| | 184 | cp arch/arm64/boot/Image . |
| | 185 | gzip Image |
| | 186 | mkimage -f kernel.its /tftpboot/kernel.itb |
| | 187 | }}} |
| | 188 | * boot the default configuration from U-Boot: |
| | 189 | {{{#!bash |
| | 190 | tftpboot $loadaddr kernel.itb && setenv bootargs 'console=ttyAMA0,115200n8 earlycon=pl011,0x87e028000000 coherent_poll=64M root=/dev/mmcblk2 rootfstype=f2fs' && bootm $loadaddr - $fdtcontroladdr |
| | 191 | }}} |
| | 192 | |
| | 193 | |
| | 194 | References: |
| | 195 | * [http://git.denx.de/?p=u-boot.git;a=tree;f=doc/uImage.FIT doc/uImage.FIT] |
| | 196 | * http://www.denx.de/wiki/pub/U-Boot/Documentation/multi_image_booting_scenarios.pdf |
| | 197 | * http://elinux.org/images/f/f4/Elc2013_Fernandes.pdf |