mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-08-21 01:18:52 +09:00
![Tim Harvey](/assets/img/avatar_default.png)
NAND+MMC env support costs 12KB in the SPL which is fairly expensive just for the ability to specify whether or not to boot to uboot or directly to linux. The Ventana boards have plenty of EEPROM storage so we will use a byte there to signify if we should boot to the bootloader or to the OS. Signed-off-by: Tim Harvey <tharvey@gateworks.com>
316 lines
13 KiB
Plaintext
316 lines
13 KiB
Plaintext
U-Boot for the Gateworks Ventana Product Family boards
|
|
|
|
This file contains information for the port of U-Boot to the Gateworks
|
|
Ventana Product family boards.
|
|
|
|
The entire Ventana product family (http://www.gateworks.com/product#ventana)
|
|
is supported by a single bootloader build by using a common SPL and U-Boot
|
|
that dynamically determines the characterstics of the board at runtime via
|
|
information from an EEPROM on the board programmed at the factory and supports
|
|
all of the various boot mediums available.
|
|
|
|
1. Secondary Program Loader (SPL)
|
|
---------------------------------
|
|
|
|
The i.MX6 has a BOOT ROM PPL (Primary Program Loader) which supports loading
|
|
an executable image from various boot devices.
|
|
|
|
The Gateworks Ventana board config uses an SPL build configuration. This
|
|
will build the following artifacts from U-Boot source:
|
|
- SPL - Secondary Program Loader that the i.MX6 BOOT ROM (Primary Program
|
|
Loader) boots. This detects CPU/DRAM configuration, configures
|
|
The DRAM controller, loads u-boot.img from the detected boot device,
|
|
and jumps to it. As this is booted from the PPL, it has an IVT/DCD
|
|
table.
|
|
- u-boot.img - The main U-Boot core which is u-boot.bin with a image header.
|
|
|
|
|
|
2. Build
|
|
--------
|
|
|
|
To build U-Boot for the Gateworks Ventana product family:
|
|
|
|
make gwventana_config
|
|
make
|
|
|
|
|
|
3. Boot source:
|
|
---------------
|
|
|
|
The Gateworks Ventana boards support booting from NAND or micro-SD depending
|
|
on the board model. The IMX6 BOOT ROM will choose a boot media based on eFUSE
|
|
settings programmed at the factory.
|
|
|
|
Boards with NAND flash will always boot from NAND, and NAND-less boards will
|
|
always boot from micro-SD. However, it is possible to use the U-Boot bmode
|
|
command (or the technique it uses) to essentially bootstrap to another boot
|
|
media at runtime.
|
|
|
|
3.1. boot from NAND
|
|
-------------------
|
|
|
|
The i.MX6 BOOT ROM expects some structures that provide details of NAND layout
|
|
and bad block information (referred to as 'bootstreams') which are replicated
|
|
multiple times in NAND. The number of replications and their spacing (referred
|
|
to as search stride) is configurable through board strapping options and/or
|
|
eFUSE settings (BOOT_SEARCH_COUNT / Pages in block from BOOT_CFG2). In
|
|
addition, the i.MX6 BOOT ROM Flash Configuration Block (FCB) supports two
|
|
copies of a bootloader in flash in the case that a bad block has corrupted one.
|
|
The Freescale 'kobs-ng' application from the Freescale LTIB BSP, which runs
|
|
under Linux and operates on an MTD partition, must be used to program the
|
|
bootstream in order to setup this flash structure correctly.
|
|
|
|
The Gateworks Ventana boards with NAND flash have been factory programmed
|
|
such that their eFUSE settings expect 2 copies of the boostream (this is
|
|
specified by providing kobs-ng with the --search_exponent=1 argument). Once in
|
|
Linux with MTD support for the NAND on /dev/mtd0 you can program the SPL
|
|
with:
|
|
|
|
kobs-ng init -v -x --search_exponent=1 SPL
|
|
|
|
The kobs-ng application uses an imximage which contains the Image Vector Table
|
|
(IVT) and Device Configuration Data (DCD) structures that the i.MX6 BOOT ROM
|
|
requires to boot. The kobs-ng adds the Firmware Configuration Block (FCB) and
|
|
Discovered Bad Block Table (DBBT). The SPL build artifact from U-Boot is
|
|
an imximage.
|
|
|
|
The u-boot.img, which is the non SPL U-Boot binary appended to a U-Boot image
|
|
header must be programmed in the NAND flash boot device at an offset hard
|
|
coded in the SPL. For the Ventana boards, this has been chosen to be 14MB.
|
|
The image can be programmed from either U-Boot or Linux:
|
|
|
|
U-Boot:
|
|
Ventana > setenv mtdparts mtdparts=nand:14m(spl),2m(uboot),1m(env),-(rootfs)
|
|
Ventana > tftp ${loadaddr} u-boot.img && nand erase.part uboot && \
|
|
nand write ${loadaddr} uboot ${filesize}
|
|
|
|
Linux:
|
|
nandwrite /dev/mtd1 u-boot.img
|
|
|
|
The above assumes the default Ventana partitioning scheme which is configured
|
|
via the mtdparts env var:
|
|
- spl: 14MB
|
|
- uboot: 2M
|
|
- env: 1M
|
|
- rootfs: the rest
|
|
|
|
This information is taken from:
|
|
http://trac.gateworks.com/wiki/ventana/bootloader#nand
|
|
|
|
More details about the i.MX6 BOOT ROM can be found in the IMX6 reference manual.
|
|
|
|
3.1. boot from micro-SD
|
|
-----------------------
|
|
|
|
When the IMX6 eFUSE settings have been factory programmed to boot from
|
|
micro-SD the SPL will be loaded from offset 0x400 (1KB). Once the SPL is
|
|
booted, it will load and execute U-Boot (u-boot.img) from offset 69KB
|
|
on the micro-SD (defined by CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR).
|
|
|
|
While it is technically possible to enable the SPL to be able to load
|
|
U-Boot from a file on a FAT/EXT filesystem on the micro-SD, we chose to
|
|
use raw micro-SD access to keep the code-size and boot time of the SPL down.
|
|
|
|
For these reasons a micro-SD that will be used as an IMX6 primary boot
|
|
device must be carefully partitioned and prepared.
|
|
|
|
The following shell commands are executed on a Linux host (adjust DEV to the
|
|
block storage device of your micro-SD):
|
|
|
|
DEV=/dev/sdc
|
|
# zero out 1MB of device
|
|
sudo dd if=/dev/zero of=$DEV count=1 bs=1M oflag=sync status=none && sync
|
|
# copy SPL to 1KB offset
|
|
sudo dd if=SPL of=$DEV bs=1K seek=1 oflag=sync status=none && sync
|
|
# copy U-Boot to 69KB offset
|
|
sudo dd if=u-boot.img of=$DEV bs=1K seek=69 oflag=sync status=none && sync
|
|
# create a partition table with a single rootfs partition starting at 1MB
|
|
printf "1,,L\n" | sudo sfdisk --in-order --no-reread -L -uM $DEV && sync
|
|
# format partition
|
|
sudo mkfs.ext4 -L root ${DEV}1
|
|
# mount the partition
|
|
sudo udisks --mount ${DEV}1
|
|
# extract filesystem
|
|
sudo tar xvf rootfs.tar.gz -C /media/root
|
|
# flush and unmount
|
|
sync && sudo umount /media/root
|
|
|
|
The above assumes the default Ventana micro-SD partitioning scheme
|
|
- spl : 1KB-69KB (68KB) required by IMX6 BOOT ROM
|
|
- uboot : 69KB-709KB (640KB) defined by
|
|
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR
|
|
- env : 709KB-965KB (256KB) defined by
|
|
CONFIG_ENV_MMC_SIZE
|
|
CONFIG_ENV_MMC_OFFSET_REDUND
|
|
- rootfs : 1MB-
|
|
|
|
This information is taken from:
|
|
http://trac.gateworks.com/wiki/ventana/bootloader#microsd
|
|
|
|
More details about the i.MX6 BOOT ROM can be found in the IMX6 reference manual.
|
|
|
|
4. Falcon Mode
|
|
------------------------------
|
|
|
|
The Gateworks Ventana board config enables Falcon mode (CONFIG_SPL_OS_BOOT)
|
|
which allows the SPL to boot directly to an OS instead of to U-Boot
|
|
(u-boot.img) thus acheiving a faster overall boot time. The time savings
|
|
depends on your boot medium (ie NAND Flash vs micro-SD) and size/storage
|
|
of the OS. The time savings can be anywhere from 2 seconds (256MB NAND Flash
|
|
with ~1MB kernel) to 6 seconds or more (2GB NAND Flash with ~6 kernel)
|
|
|
|
The Gateworks Ventana board supports Falcon mode for the following boot
|
|
medium:
|
|
- NAND flash
|
|
- micro-SD
|
|
|
|
For all boot mediums, raw mode is used. While support of more complex storage
|
|
such as files on top of FAT/EXT filesystem is possible but not practical
|
|
as the size of the SPL is fairly limitted (to 64KB based on the smallest
|
|
size of available IMX6 iRAM) as well as the fact that this would increase
|
|
OS load time which defeats the purpose of Falcon mode in the first place.
|
|
|
|
The SPL decides to boot either U-Boot (u-boot.img) or the OS (args + kernel)
|
|
based on the return value of the spl_start_uboot() function. While often
|
|
this can simply be the state of a GPIO based pushbutton or DIP switch, for
|
|
Gateworks Ventana, we use an EEPROM register on i2c-0 at 0x50:0x00:
|
|
set to '0' will choose to boot to U-Boot and otherwise it will boot to OS.
|
|
|
|
To use Falcon mode it is required that you first 'prepare' the 'args' data
|
|
that is stored on your boot medium along with the kernel (which can be any
|
|
OS or bare-metal application). In the case of the Linux kernel the 'args'
|
|
is the flatenned device-tree which normally gets altered prior to booting linux
|
|
by U-Boot's 'bootm' command. To achieve this for SPL we use the
|
|
'spl export fdt' command in U-Boot after loading the kernel and dtb which
|
|
will go through the same process of modifying the device-tree for the board
|
|
being executed on but not jump to the kernel. This allows you to save the
|
|
args data to the location the SPL expects it and then enable Falcon mode.
|
|
|
|
It is important to realize that there are certain values in the dtb that
|
|
are board model specific (IMX6Q vs IMX6DL for example) and board specific
|
|
(board serial number, MAC addrs) so you do not want to use the 'args'
|
|
data prepared from one board on another board.
|
|
|
|
4.1. Falcon Mode on NAND flash
|
|
------------------------------
|
|
To prepare a Gateworks Ventana board that boots from NAND flash for Falcon
|
|
mode you must program your flash such that the 'args' and 'kernel' are
|
|
located where defined at compile time by the following:
|
|
CONFIG_CMD_SPL_NAND_OFS 17MB - offset of 'args'
|
|
CONFIG_SYS_NAND_SPL_KERNEL_OFFS 18MB - offset of 'kernel'
|
|
|
|
The location offsets defined above are defaults chosen by Gateworks and are
|
|
flexible if you want to re-define them.
|
|
|
|
The following steps executed in U-Boot will configure Falcon mode for NAND
|
|
using rootfs (ubi), kernel (uImage), and dtb from the network:
|
|
|
|
# change mtd partitions to the above mapping
|
|
Ventana > setenv mtdparts 'mtdparts=nand:14m(spl),2m(uboot),1m(env),1m(args),10m(kernel),-(rootfs)'
|
|
|
|
# flash rootfs (at 28MB)
|
|
Ventana > tftp ${loadaddr} rootfs_${flash_layout}.ubi && \
|
|
nand erase.part rootfs && nand write ${loadaddr} rootfs ${filesize}
|
|
|
|
# load the device-tree
|
|
Ventana > tftp ${fdt_addr} ventana/${fdt_file2}
|
|
|
|
# load the kernel
|
|
Ventana > tftp ${loadaddr} ventana/uImage
|
|
|
|
# flash kernel (at 18MB)
|
|
Ventana > nand erase.part kernel && nand write ${loadaddr} kernel ${filesize}
|
|
|
|
# set kernel args for the console and rootfs (used by spl export)
|
|
Ventana > setenv bootargs 'console=ttymxc1,115200 root=ubi0:rootfs ubi.mtd=5 rootfstype=ubifs quiet'
|
|
|
|
# create args based on env, board, EEPROM, and dtb
|
|
Ventana > spl export fdt ${loadaddr} - ${fdt_addr}
|
|
|
|
# flash args (at 17MB)
|
|
Ventana > nand erase.part args && nand write 18000000 args 100000
|
|
|
|
# set i2c register 0x50:0x00=0 to boot to Linux
|
|
Ventana > i2c dev 0 && i2c mw 0x50 0x00.0 0 1
|
|
|
|
Be sure to adjust 'bootargs' above to your OS needs (this will be different
|
|
for various distros such as OpenWrt, Yocto, Android, etc). You can use the
|
|
value obtained from 'cat /proc/cmdline' when booted to Linux.
|
|
|
|
This information is taken from:
|
|
http://trac.gateworks.com/wiki/ventana/bootloader/falcon-mode#nand
|
|
|
|
|
|
4.2. Falcon Mode on micro-SD card
|
|
---------------------------------
|
|
|
|
To prepare a Gateworks Ventana board with a primary boot device of micro-SD
|
|
you first need to make sure you build U-Boot with CONFIG_ENV_IS_IN_MMC
|
|
instead of CONFIG_ENV_IS_IN_NAND.
|
|
|
|
For micro-SD based Falcon mode you must program your micro-SD such that
|
|
the 'args' and 'kernel' are located where defined at compile time
|
|
by the following:
|
|
CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR 0x800 (1MB) - offset of 'args'
|
|
CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR 0x1000 (2MB) - offset of 'kernel'
|
|
|
|
The location offsets defined above are defaults chosen by Gateworks and are
|
|
flexible if you want to re-define them.
|
|
|
|
First you must prepare a micro-SD such that the SPL can be loaded by the
|
|
IMX6 BOOT ROM (fixed offset of 1KB), and U-Boot can be loaded by the SPL
|
|
(fixed offset of 69KB defined by CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR).
|
|
|
|
The following shell commands are executed on a Linux host (adjust DEV to the
|
|
block storage device of your micro-SD):
|
|
|
|
DEV=/dev/sdc
|
|
# zero out 1MB of device
|
|
sudo dd if=/dev/zero of=$DEV count=1 bs=1M oflag=sync status=none && sync
|
|
# copy SPL to 1KB offset
|
|
sudo dd if=SPL of=$DEV bs=1K seek=1 oflag=sync status=none && sync
|
|
# copy U-Boot to 69KB offset
|
|
sudo dd if=u-boot.img of=$DEV bs=1K seek=69 oflag=sync status=none && sync
|
|
# create a partition table with a single rootfs partition starting at 10MB
|
|
printf "10,,L\n" | sudo sfdisk --in-order --no-reread -L -uM $DEV && sync
|
|
# format partition
|
|
sudo mkfs.ext4 -L root ${DEV}1
|
|
# mount the partition
|
|
sudo udisks --mount ${DEV}1
|
|
# extract filesystem
|
|
sudo tar xvf rootfs.tar.gz -C /media/root
|
|
# flush and unmount
|
|
sync && sudo umount /media/root
|
|
|
|
Now that your micro-SD partitioning has been adjusted to leave room for the
|
|
raw 'args' and 'kernel' data boot the board with the prepared micro-SD, break
|
|
out in U-Boot and use the following to enable Falcon mode:
|
|
|
|
# load device-tree from rootfs
|
|
Ventana > ext2load mmc 0:1 ${fdt_addr} boot/${fdt_file2}
|
|
|
|
# load kernel from rootfs
|
|
Ventana > ext2load mmc 0:1 ${loadaddr} boot/uImage
|
|
|
|
# write kernel at 2MB offset
|
|
Ventana > mmc write ${loadaddr} 0x1000 0x4000
|
|
|
|
# setup kernel bootargs
|
|
Ventana > setenv bootargs 'console=ttymxc1,115200 root=/dev/mmcblk0p1 rootfstype=ext4 rootwait rw'
|
|
|
|
# prepare args
|
|
Ventana > spl export fdt ${loadaddr} - ${fdt_addr}
|
|
|
|
# write args 1MB data (0x800 sectors) to 1MB offset (0x800 sectors)
|
|
Ventana > mmc write 18000000 0x800 0x800
|
|
|
|
# set i2c register 0x50:0x00=0 to boot to Linux
|
|
Ventana > i2c dev 0 && i2c mw 0x50 0x00.0 0 1
|
|
|
|
Be sure to adjust 'bootargs' above to your OS needs (this will be different
|
|
for various distros such as OpenWrt, Yocto, Android, etc). You can use the
|
|
value obtained from 'cat /proc/cmdline' when booted to Linux.
|
|
|
|
This information is taken from:
|
|
http://trac.gateworks.com/wiki/ventana/bootloader/falcon-mode#microsd
|