Tim Harvey | 59189a8 | 2014-03-06 07:46:30 -0800 | [diff] [blame] | 1 | U-Boot for the Gateworks Ventana Product Family boards |
| 2 | |
| 3 | This file contains information for the port of U-Boot to the Gateworks |
| 4 | Ventana Product family boards. |
| 5 | |
Tim Harvey | 40e999c | 2015-05-21 08:42:04 -0700 | [diff] [blame] | 6 | The entire Ventana product family (http://www.gateworks.com/product#ventana) |
| 7 | is supported by a single bootloader build by using a common SPL and U-Boot |
| 8 | that dynamically determines the characterstics of the board at runtime via |
| 9 | information from an EEPROM on the board programmed at the factory and supports |
| 10 | all of the various boot mediums available. |
| 11 | |
Tim Harvey | 0cc11de | 2014-06-02 16:13:27 -0700 | [diff] [blame] | 12 | 1. Secondary Program Loader (SPL) |
| 13 | --------------------------------- |
| 14 | |
| 15 | The i.MX6 has a BOOT ROM PPL (Primary Program Loader) which supports loading |
| 16 | an executable image from various boot devices. |
| 17 | |
| 18 | The Gateworks Ventana board config uses an SPL build configuration. This |
| 19 | will build the following artifacts from u-boot source: |
| 20 | - SPL - Secondary Program Loader that the i.MX6 BOOT ROM (Primary Program |
| 21 | Loader) boots. This detects CPU/DRAM configuration, configures |
| 22 | The DRAM controller, loads u-boot.img from the detected boot device, |
| 23 | and jumps to it. As this is booted from the PPL, it has an IVT/DCD |
| 24 | table. |
| 25 | - u-boot.img - The main u-boot core which is u-boot.bin with a image header. |
| 26 | |
| 27 | |
| 28 | 2. Build |
| 29 | -------- |
| 30 | |
| 31 | To build U-Boot for the Gateworks Ventana product family: |
| 32 | |
| 33 | make gwventana_config |
| 34 | make |
| 35 | |
| 36 | |
Tim Harvey | 40e999c | 2015-05-21 08:42:04 -0700 | [diff] [blame] | 37 | 3. Boot source: |
| 38 | --------------- |
| 39 | |
| 40 | The Gateworks Ventana boards support booting from NAND or micro-SD depending |
| 41 | on the board model. The IMX6 BOOT ROM will choose a boot media based on eFUSE |
| 42 | settings programmed at the factory. |
| 43 | |
| 44 | Boards with NAND flash will always boot from NAND, and NAND-less boards will |
| 45 | always boot from micro-SD. However, it is possible to use the U-Boot bmode |
| 46 | command (or the technique it uses) to essentially bootstrap to another boot |
| 47 | media at runtime. |
| 48 | |
| 49 | 3.1. boot from NAND |
| 50 | ------------------- |
Tim Harvey | 59189a8 | 2014-03-06 07:46:30 -0800 | [diff] [blame] | 51 | |
| 52 | The i.MX6 BOOT ROM expects some structures that provide details of NAND layout |
| 53 | and bad block information (referred to as 'bootstreams') which are replicated |
Tim Harvey | 0cc11de | 2014-06-02 16:13:27 -0700 | [diff] [blame] | 54 | multiple times in NAND. The number of replications and their spacing (referred |
| 55 | to as search stride) is configurable through board strapping options and/or |
| 56 | eFUSE settings (BOOT_SEARCH_COUNT / Pages in block from BOOT_CFG2). In |
| 57 | addition, the i.MX6 BOOT ROM Flash Configuration Block (FCB) supports two |
| 58 | copies of a bootloader in flash in the case that a bad block has corrupted one. |
| 59 | The Freescale 'kobs-ng' application from the Freescale LTIB BSP, which runs |
| 60 | under Linux and operates on an MTD partition, must be used to program the |
| 61 | bootstream in order to setup this flash structure correctly. |
Tim Harvey | 59189a8 | 2014-03-06 07:46:30 -0800 | [diff] [blame] | 62 | |
| 63 | The Gateworks Ventana boards with NAND flash have been factory programmed |
| 64 | such that their eFUSE settings expect 2 copies of the boostream (this is |
| 65 | specified by providing kobs-ng with the --search_exponent=1 argument). Once in |
Tim Harvey | 0cc11de | 2014-06-02 16:13:27 -0700 | [diff] [blame] | 66 | Linux with MTD support for the NAND on /dev/mtd0 you can program the SPL |
Tim Harvey | 59189a8 | 2014-03-06 07:46:30 -0800 | [diff] [blame] | 67 | with: |
| 68 | |
Tim Harvey | 0cc11de | 2014-06-02 16:13:27 -0700 | [diff] [blame] | 69 | kobs-ng init -v -x --search_exponent=1 SPL |
Tim Harvey | 59189a8 | 2014-03-06 07:46:30 -0800 | [diff] [blame] | 70 | |
Tim Harvey | 0cc11de | 2014-06-02 16:13:27 -0700 | [diff] [blame] | 71 | The kobs-ng application uses an imximage which contains the Image Vector Table |
| 72 | (IVT) and Device Configuration Data (DCD) structures that the i.MX6 BOOT ROM |
| 73 | requires to boot. The kobs-ng adds the Firmware Configuration Block (FCB) and |
| 74 | Discovered Bad Block Table (DBBT). The SPL build artifact from u-boot is |
| 75 | an imximage. |
| 76 | |
| 77 | The u-boot.img, which is the non SPL u-boot binary appended to a u-boot image |
| 78 | header must be programmed in the NAND flash boot device at an offset hard |
| 79 | coded in the SPL. For the Ventana boards, this has been chosen to be 14MB. |
| 80 | The image can be programmed from either u-boot or Linux: |
| 81 | |
| 82 | u-boot: |
| 83 | Ventana > setenv mtdparts mtdparts=nand:14m(spl),2m(uboot),1m(env),-(rootfs) |
| 84 | Ventana > tftp ${loadaddr} u-boot.img && nand erase.part uboot && \ |
| 85 | nand write ${loadaddr} uboot ${filesize} |
| 86 | |
| 87 | Linux: |
| 88 | nandwrite /dev/mtd1 u-boot.img |
| 89 | |
| 90 | The above assumes the default Ventana partitioning scheme which is configured |
| 91 | via the mtdparts env var: |
| 92 | - spl: 14MB |
| 93 | - uboot: 2M |
| 94 | - env: 1M |
| 95 | - rootfs: the rest |
Tim Harvey | 59189a8 | 2014-03-06 07:46:30 -0800 | [diff] [blame] | 96 | |
| 97 | This information is taken from: |
Tim Harvey | 40e999c | 2015-05-21 08:42:04 -0700 | [diff] [blame] | 98 | http://trac.gateworks.com/wiki/ventana/bootloader#nand |
| 99 | |
| 100 | More details about the i.MX6 BOOT ROM can be found in the IMX6 reference manual. |
| 101 | |
| 102 | 3.1. boot from micro-SD |
| 103 | ----------------------- |
| 104 | |
| 105 | When the IMX6 eFUSE settings have been factory programmed to boot from |
| 106 | micro-SD the SPL will be loaded from offset 0x400 (1KB). Once the SPL is |
| 107 | booted, it will load and execute U-boot (u-boot.img) from offset 69KB |
| 108 | on the micro-SD (defined by CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR). |
| 109 | |
| 110 | While it is technically possible to enable the SPL to be able to load |
| 111 | U-Boot from a file on a FAT/EXT filesystem on the micro-SD, we chose to |
| 112 | use raw micro-SD access to keep the code-size and boot time of the SPL down. |
| 113 | |
| 114 | For these reasons a micro-SD that will be used as an IMX6 primary boot |
| 115 | device must be carefully partitioned and prepared. |
| 116 | |
| 117 | The following shell commands are executed on a Linux host (adjust DEV to the |
| 118 | block storage device of your micro-SD): |
| 119 | |
| 120 | DEV=/dev/sdc |
| 121 | # zero out 1MB of device |
| 122 | sudo dd if=/dev/zero of=$DEV count=1 bs=1M oflag=sync status=none && sync |
| 123 | # copy SPL to 1KB offset |
| 124 | sudo dd if=SPL of=$DEV bs=1K seek=1 oflag=sync status=none && sync |
| 125 | # copy U-Boot to 69KB offset |
| 126 | sudo dd if=u-boot.img of=$DEV bs=1K seek=69 oflag=sync status=none && sync |
| 127 | # create a partition table with a single rootfs partition starting at 1MB |
| 128 | printf "1,,L\n" | sudo sfdisk --in-order --no-reread -L -uM $DEV && sync |
| 129 | # format partition |
| 130 | sudo mkfs.ext4 -L root ${DEV}1 |
| 131 | # mount the partition |
| 132 | sudo udisks --mount ${DEV}1 |
| 133 | # extract filesystem |
| 134 | sudo tar xvf rootfs.tar.gz -C /media/root |
| 135 | # flush and unmount |
| 136 | sync && sudo umount /media/root |
| 137 | |
| 138 | The above assumes the default Ventana micro-SD partitioning scheme |
| 139 | - spl : 1KB-69KB (68KB) required by IMX6 BOOT ROM |
| 140 | - uboot : 69KB-709KB (640KB) defined by |
| 141 | CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR |
| 142 | - env : 709KB-965KB (256KB) defined by |
| 143 | CONFIG_ENV_MMC_SIZE |
| 144 | CONFIG_ENV_MMC_OFFSET_REDUND |
| 145 | - rootfs : 1MB- |
| 146 | |
| 147 | This information is taken from: |
| 148 | http://trac.gateworks.com/wiki/ventana/bootloader#microsd |
Tim Harvey | 59189a8 | 2014-03-06 07:46:30 -0800 | [diff] [blame] | 149 | |
| 150 | More details about the i.MX6 BOOT ROM can be found in the IMX6 reference manual. |
| 151 | |
Tim Harvey | 6122f0d | 2015-05-21 15:59:48 -0700 | [diff] [blame] | 152 | 4. Falcon Mode |
| 153 | ------------------------------ |
| 154 | |
| 155 | The Gateworks Ventana board config enables Falcon mode (CONFIG_SPL_OS_BOOT) |
| 156 | which allows the SPL to boot directly to an OS instead of to U-Boot |
| 157 | (u-boot.img) thus acheiving a faster overall boot time. The time savings |
| 158 | depends on your boot medium (ie NAND Flash vs micro-SD) and size/storage |
| 159 | of the OS. The time savings can be anywhere from 2 seconds (256MB NAND Flash |
| 160 | with ~1MB kernel) to 6 seconds or more (2GB NAND Flash with ~6 kernel) |
| 161 | |
| 162 | The Gateworks Ventana board supports Falcon mode for the following boot |
| 163 | medium: |
| 164 | - NAND flash |
| 165 | - micro-SD |
| 166 | |
| 167 | For all boot mediums, raw mode is used. While support of more complex storage |
| 168 | such as files on top of FAT/EXT filesystem is possible but not practical |
| 169 | as the size of the SPL is fairly limitted (to 64KB based on the smallest |
| 170 | size of available IMX6 iRAM) as well as the fact that this would increase |
| 171 | OS load time which defeats the purpose of Falcon mode in the first place. |
| 172 | |
| 173 | The SPL decides to boot either U-Boot (u-boot.img) or the OS (args + kernel) |
| 174 | based on the return value of the spl_start_uboot() function. While often |
| 175 | this can simply be the state of a GPIO based pushbutton or DIP switch, for |
| 176 | Gateworks Ventana, we use the U-Boot environment 'boot_os' variable which if |
| 177 | set to '1' will choose to boot the OS rather than U-Boot. While the choice |
| 178 | of adding env support to the SPL adds a little bit of time to the boot |
| 179 | process as well as (significant really) SPL code space this was deemed most |
| 180 | flexible as within the large variety of Gateworks Ventana boards not all of |
| 181 | them have a user pushbutton and that pushbutton may be configured as a hard |
| 182 | reset per user configuration. |
| 183 | |
| 184 | To use Falcon mode it is required that you first 'prepare' the 'args' data |
| 185 | that is stored on your boot medium along with the kernel (which can be any |
| 186 | OS or bare-metal application). In the case of the Linux kernel the 'args' |
| 187 | is the flatenned device-tree which normally gets altered prior to booting linux |
| 188 | by U-Boot's 'bootm' command. To achieve this for SPL we use the |
| 189 | 'spl export fdt' command in U-Boot after loading the kernel and dtb which |
| 190 | will go through the same process of modifying the device-tree for the board |
| 191 | being executed on but not jump to the kernel. This allows you to save the |
| 192 | args data to the location the SPL expects it and then enable Falcon mode. |
| 193 | |
| 194 | It is important to realize that there are certain values in the dtb that |
| 195 | are board model specific (IMX6Q vs IMX6DL for example) and board specific |
| 196 | (board serial number, MAC addrs) so you do not want to use the 'args' |
| 197 | data prepared from one board on another board. |
| 198 | |
| 199 | 4.1. Falcon Mode on NAND flash |
| 200 | ------------------------------ |
| 201 | To prepare a Gateworks Ventana board that boots from NAND flash for Falcon |
| 202 | mode you must program your flash such that the 'args' and 'kernel' are |
| 203 | located where defined at compile time by the following: |
| 204 | CONFIG_CMD_SPL_NAND_OFS 17MB - offset of 'args' |
| 205 | CONFIG_SYS_NAND_SPL_KERNEL_OFFS 18MB - offset of 'kernel' |
| 206 | |
| 207 | The location offsets defined above are defaults chosen by Gateworks and are |
| 208 | flexible if you want to re-define them. |
| 209 | |
| 210 | The following steps executed in U-Boot will configure Falcon mode for NAND |
| 211 | using rootfs (ubi), kernel (uImage), and dtb from the network: |
| 212 | |
| 213 | # change mtd partitions to the above mapping |
| 214 | Ventana > setenv mtdparts 'mtdparts=nand:14m(spl),2m(uboot),1m(env),1m(args),10m(kernel),-(rootfs)' |
| 215 | |
| 216 | # flash rootfs (at 28MB) |
| 217 | Ventana > tftp ${loadaddr} rootfs_${flash_layout}.ubi && \ |
| 218 | nand erase.part rootfs && nand write ${loadaddr} rootfs ${filesize} |
| 219 | |
| 220 | # load the device-tree |
| 221 | Ventana > tftp ${fdt_addr} ventana/${fdt_file2} |
| 222 | |
| 223 | # load the kernel |
| 224 | Ventana > tftp ${loadaddr} ventana/uImage |
| 225 | |
| 226 | # flash kernel (at 18MB) |
| 227 | Ventana > nand erase.part kernel && nand write ${loadaddr} kernel ${filesize} |
| 228 | |
| 229 | # set kernel args for the console and rootfs (used by spl export) |
| 230 | Ventana > setenv bootargs 'console=ttymxc1,115200 root=ubi0:rootfs ubi.mtd=5 rootfstype=ubifs quiet' |
| 231 | |
| 232 | # create args based on env, board, EEPROM, and dtb |
| 233 | Ventana > spl export fdt ${loadaddr} - ${fdt_addr} |
| 234 | |
| 235 | # flash args (at 17MB) |
| 236 | Ventana > nand erase.part args && nand write 18000000 args 100000 |
| 237 | |
| 238 | # set boot_os env var to enable booting to Linux |
| 239 | Ventana > setenv boot_os 1 && saveenv |
| 240 | |
| 241 | Be sure to adjust 'bootargs' above to your OS needs (this will be different |
| 242 | for various distros such as OpenWrt, Yocto, Android, etc). You can use the |
| 243 | value obtained from 'cat /proc/cmdline' when booted to Linux. |
| 244 | |
| 245 | This information is taken from: |
| 246 | http://trac.gateworks.com/wiki/ventana/bootloader/falcon-mode#nand |
| 247 | |
| 248 | |
| 249 | 4.2. Falcon Mode on micro-SD card |
| 250 | --------------------------------- |
| 251 | |
| 252 | To prepare a Gateworks Ventana board with a primary boot device of micro-SD |
| 253 | you first need to make sure you build U-Boot with CONFIG_ENV_IS_IN_MMC |
| 254 | instead of CONFIG_ENV_IS_IN_NAND. |
| 255 | |
| 256 | For micro-SD based Falcon mode you must program your micro-SD such that |
| 257 | the 'args' and 'kernel' are located where defined at compile time |
| 258 | by the following: |
| 259 | CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR 0x800 (1MB) - offset of 'args' |
| 260 | CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR 0x1000 (2MB) - offset of 'kernel' |
| 261 | |
| 262 | The location offsets defined above are defaults chosen by Gateworks and are |
| 263 | flexible if you want to re-define them. |
| 264 | |
| 265 | First you must prepare a micro-SD such that the SPL can be loaded by the |
| 266 | IMX6 BOOT ROM (fixed offset of 1KB), and U-Boot can be loaded by the SPL |
| 267 | (fixed offset of 69KB defined by CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR). |
| 268 | |
| 269 | The following shell commands are executed on a Linux host (adjust DEV to the |
| 270 | block storage device of your micro-SD): |
| 271 | |
| 272 | DEV=/dev/sdc |
| 273 | # zero out 1MB of device |
| 274 | sudo dd if=/dev/zero of=$DEV count=1 bs=1M oflag=sync status=none && sync |
| 275 | # copy SPL to 1KB offset |
| 276 | sudo dd if=SPL of=$DEV bs=1K seek=1 oflag=sync status=none && sync |
| 277 | # copy U-Boot to 69KB offset |
| 278 | sudo dd if=u-boot.img of=$DEV bs=1K seek=69 oflag=sync status=none && sync |
| 279 | # create a partition table with a single rootfs partition starting at 10MB |
| 280 | printf "10,,L\n" | sudo sfdisk --in-order --no-reread -L -uM $DEV && sync |
| 281 | # format partition |
| 282 | sudo mkfs.ext4 -L root ${DEV}1 |
| 283 | # mount the partition |
| 284 | sudo udisks --mount ${DEV}1 |
| 285 | # extract filesystem |
| 286 | sudo tar xvf rootfs.tar.gz -C /media/root |
| 287 | # flush and unmount |
| 288 | sync && sudo umount /media/root |
| 289 | |
| 290 | Now that your micro-SD partitioning has been adjusted to leave room for the |
| 291 | raw 'args' and 'kernel' data boot the board with the prepared micro-SD, break |
| 292 | out in U-Boot and use the following to enable Falcon mode: |
| 293 | |
| 294 | # load device-tree from rootfs |
| 295 | Ventana > ext2load mmc 0:1 ${fdt_addr} boot/${fdt_file2} |
| 296 | |
| 297 | # load kernel from rootfs |
| 298 | Ventana > ext2load mmc 0:1 ${loadaddr} boot/uImage |
| 299 | |
| 300 | # write kernel at 2MB offset |
| 301 | Ventana > mmc write ${loadaddr} 0x1000 0x4000 |
| 302 | |
| 303 | # setup kernel bootargs |
| 304 | Ventana > setenv bootargs 'console=ttymxc1,115200 root=/dev/mmcblk0p1 rootfstype=ext4 rootwait rw' |
| 305 | |
| 306 | # prepare args |
| 307 | Ventana > spl export fdt ${loadaddr} - ${fdt_addr} |
| 308 | |
| 309 | # write args 1MB data (0x800 sectors) to 1MB offset (0x800 sectors) |
| 310 | Ventana > mmc write 18000000 0x800 0x800 |
| 311 | |
| 312 | # set boot_os to enable falcon mode |
| 313 | Ventana > setenv boot_os 1 && saveenv |
| 314 | |
| 315 | Be sure to adjust 'bootargs' above to your OS needs (this will be different |
| 316 | for various distros such as OpenWrt, Yocto, Android, etc). You can use the |
| 317 | value obtained from 'cat /proc/cmdline' when booted to Linux. |
| 318 | |
| 319 | This information is taken from: |
| 320 | http://trac.gateworks.com/wiki/ventana/bootloader/falcon-mode#microsd |