[[PageOutline]] A [wiki:linux/bootloader bootloader] is responsible for configuring the DRAM controller and loading/executing the OS kernel. = Ventana Bootloader = The Ventana bootloader does the following: * configure DRAM controller per the memory configuration specified in the Gateworks EEPROM * configure enough of the chipset to load the kernel (uImage) and device-tree blob (DTB) from the boot media and execute the kernel with boot parameters. Gateworks Ventana uses a modern u-boot bootloader supporting a variety of nice features: * network support: * for eth0, supporting tftp, bootp, netconsole * USB gadget support: * networking over USB OTG device to PC host * flexible boot media support: * mmc * USB EHCI host * USB OTG * mSata * filesystem support: * fat/ext/ubi * commandline history and extended scripting support * [wiki:ventana/SPL SPL] support: * The BOOT ROM internal to the i.MX6 is the Primary Boot Loader (PBL) which loads the SPL * U-Boot builds the Secondary Boot Loader (SPL) which configures SDRAM and loads u-boot.img * U-Boot builds u-boot.img the main U-Boot app * This allows a single bootloader to support the entire Ventana product family instead of requiring a different static bootloader for each board/cpu/memory configuration * see [wiki:ventana/SPL here] for more info on the SPL [=#prebuilt] == Pre Built Bootloader == We encourage customers to use our prebuilt bootloader. Please only build the bootloader if you need to modify something and you know what you are doing. Pre-Built Bootloader: * [http://dev.gateworks.com/ventana/images/ Pre-Built Bootloader] * Installation instructions: [wiki:ventana/bootloader#UpdatingSPLandbootloaderviaJTAG JTAG Instructions] * [wiki:ventana/SPL SPL] - the 'Secondary Program Loader' which is loaded and executed by the internal i.MX6 BOOT ROM * {{{u-boot.img}}} - the main U-Boot * {{{u-boot_spl.bin}}} - A JTAG binary containing both the {{{SPL}}} and {{{u-boot.img}}} (the entire bootloader) suitable for updating with the Gateworks JTAG dongle and {{{jtag_usbv4}}} application. [=#versions] == Bootloader Version History == New feature support, occasional bugfixes, and support for new boards are continually being added to the bootloader. Please be sure to keep up with the most recent bootloader as needed. To determine your bootloader version: * Power on the board and look at the very first line, like so: {{{#!bash U-Boot SPL 2015.04-g8a78625 (Apr 21 2015 - 07:24:40) }}} [=#source] == Sourcecode == We host the sourcecode for the Ventana bootloader on Github here: https://github.com/Gateworks/u-boot-imx6 source branches: * gateworks_v2015.04 - based on u-boot-2015.04 release (Apr 2015) - Latest - Commits [https://github.com/Gateworks/u-boot-imx6/commits/gateworks_v2015.04] * gateworks_v2014.04 - based on u-boot-2014.04 release (Apr 2014) - deprecated * gateworks_v2014.01 - based on u-boot-2014.01 release (Jan 2014) - deprecated * gateworks_v2013.07 - based on u-boot-2013.07 release (Jul 2013) - deprecated * gateworks_v2013.04 - based on u-boot-2013.04 release (Mar 2013) - deprecated References: * [https://github.com/Gateworks/u-boot-imx6/commits/gateworks_v2014.04 Bootloader Commit Log] [=#building] == Building from Source == '''We encourage customers to use a prebuilt bootloader compiled by Gateworks. See above for Pre-Built Bootloaders and skip down to installation below [#ProgrammingInstallingu-boot] ''' Install an armv7 toolchain: * such as the one built from the OpenWrt BSP for the Ventana Family by following the step-by-step instructions [wiki:ventana/openwrt here]. * or you can download a pre-built OpenWrt toolchain [http://dev.gateworks.com/openwrt/14.08/imx6/OpenWrt-Toolchain-imx6-for-arm_cortex-a9+neon-gcc-4.8-linaro_uClibc-0.9.33.2_eabi.tar.bz2 here] Step-by-Step Instructions for building U-Boot: 1. Download U-Boot from Github {{{#!bash git clone https://github.com/Gateworks/u-boot-imx6.git Cloning into 'u-boot-imx6'... remote: Reusing existing pack: 244857, done. remote: Total 244857 (delta 0), reused 0 (delta 0) Receiving objects: 100% (244857/244857), 59.16 MiB | 9.61 MiB/s, done. Resolving deltas: 100% (197013/197013), done. cd u-boot-imx6 }}} 2. Configure Path of Toolchain (modify path below to contain the path from your OpenWrt {{{staging_dir}}} that contains {{{arm-openwrt-linux-gcc}}}) {{{#!bash export PATH=$PATH:/usr/src/jackson/builds/1602git/gateworks-openwrt/staging_dir/toolchain-arm_cortex-a9+neon_gcc-5.2.0_musl-1.1.12_eabi/bin export STAGING_DIR=/usr/src/jackson/builds/1602git/gateworks-openwrt/staging_dir export CROSS_COMPILE=arm-openwrt-linux- }}} 3. Configure U-Boot for the Ventana boards: {{{#!bash make gwventana_config Configuring for gwventana - Board: gw_ventana, Options: IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6QDL,SPL }}} 4. Build U-Boot. When done, it will create {{{SPL}}} and {{{u-boot.img}}} {{{#!bash make }}} * Optional: Once you know you're building successfully: {{{ vi ./include/configs/gw_ventana.h # vi or your favorite editing program }}} Make changes to environment you would like to see persistent across your installations of this image you are creating. Once changes are made save file then {{{ make }}} 5. Create a JTAG binary suitable for programming via the Gateworks JTAG dongle and {{{jtag_usbv4}}} software (Optional) using the [http://dev.gateworks.com/jtag/mkimage_jtag mkimage_jtag script] {{{#!bash ./mkimage_jtag SPL u-boot.img > uboot_spl.bin }}} 6. Copy the binary artifacts ({{{SPL}}}, {{{u-boot.img}}}) to a http/tftp server (Optional) {{{#!bash mkdir /tftpboot/ventana cp SPL u-boot.img /tftpboot/ventana/ }}} === Upstream mainline U-Boot Support === Gateworks is an active participant in the development of U-Boot in order to best support our products. By submitting code to the U-Boot project we ensure: - our code is peer reviewed - our users can keep up to date with the latest U-Boot bootloader even if we are not - nothing is kept proprietary The only patches that we have not mainlined is a small set of patches that allow combined NAND and MMC support in a single SPL/U-Boot. These patches need a bit more work before they would be considered elegant enough for the mainline U-Boot but also they do not add much value for the end user. The reason we use them is so that we can distribute a single SPL/U-Boot image which avoids user confusion determining if they need a **nand** version or **mmc** version of the bootloader. To build the upstream Bootloader you can following the [#building instructions above] with the following differences: 1. clone the mainline U-Boot repo: {{{#!bash git://git.denx.de/u-boot.git }}} 2. choose either the **nand** defconfig or the **emmc** defconfig depending on the flash storage on your Ventana board: * NAND based boards: GW54xx/GW53xx/GW52xx/GW51xx/GW551x/GW552x/GW553x {{{#!bash make gwventana_nand_defconfig }}} * eMMC based boards: {{{#!bash make gwventana_emmc_defconfig }}} The primary reasons for using the mainline U-Boot over the Gateworks branches would be: * if you need a newer feature * if you are using HAB for secure boot and need a smaller SPL for code signing purposes [=#flashing] == Programming / Installing U-Boot == The procedure for updating the bootloader depends on what part of the bootloader you wish to update, the {{{SPL}}}, {{{u-boot.img}}}, (or both) and what storage media you are upating to (ie NAND Flash, or micro-SD). The Secondary Program Loader ({{{SPL}}}) is firmware built by the Gateworks U-Boot bootloader source and is loaded and executed by the Primary Boot Loader (PBL) which is the i.MX6 BOOT ROM (firmware inside the i.MX6 SoC). It has the following responsibilities: * determine board info: memory width, memory size, board model * configure the i.MX6 SDRAM Controller (MMDC) for the particular memory configuration and board-specific calibration values * load the main bootloader ({{{u-boot.img}}}) from the boot media (usually NAND flash) and execute it. The U-Boot bootloader is also built from the Gateworks U-Boot bootloader source and is loaded and executed by the Secondary Program Loader ({{{SPL}}}). It has the following responsibilities: * provide a flexible configuration environment (menu or scriptable command interface) * load and execute the OS The {{{u-boot.img}}}, or main bootloader, handles everything the bootloader does other than SDRAM configuration. This is what is updated when new features are added to u-boot and therefore is what you would be updating more often than the {{{SPL}}}. For more information on flashing the linux userspace which is not included in the aforementioned {{{SPL}}} and {{{u-boot.img}}} binaries, see the [wiki:linux/ubi] and [wiki:linux/blockdev] wiki pages. [=#nand] === NAND Flash === The majority of Gateworks Ventana boards contain a NAND flash device and boot directly from that. For instructions on update a micro-SD for boards without flash see [#microsd below]. The partitioning scheme Gateworks uses for NAND flash storage is as follows: ||= Start =||= Len =||= Usage =|| || 0K || 14MB || SPL || || 14MB || 16MB || U-Boot || || 16MB || 17MB || env (2x redundant 128KB) || || 17MB || - || root partitions || * Note that while the {{{SPL}}} is certainly much smaller than 14MB (it actually needs to fit within the IMX6 iRAM and is less than 69KB) the reason for the excessive space has to do with redundantly storing the DCD table, the IVT table, and the {{{SPL}}} itself to deal with the possibility of bad blocks occuring in either of those data structures. It is this special layout requirement that presents the need for a special utility ({{{kobs-ng}}}) to program the {{{SPL}}} to flash. [=#nandjtag] ==== Updating SPL and bootloader via JTAG ==== You can use JTAG on boards with NAND flash to program the {{{u-boot_spl.bin}}} downloaded from the [wiki:ventana/bootloader#prebuilt pre-built] bootloaders or created by building the source above. This file contains both the {{{SPL}}} and the bootloader and thus both will be updated simultaneously. Using the Gateworks JTAG dongle and the Linux [http://dev.gateworks.com/jtag/jtag_usbv4 jtag_usbv4] software, you can update the entire bootloader via JTAG from a Linux PC: {{{#!bash sudo rmmod ftdi_sio sudo jtag_usbv4 -p u-boot_spl.bin }}} Note that programming {{{u-boot_spl.bin}}} will only erase the {{{SPL}}} and {{{u-boot.img}}} portions of flash (and not the bootloader environment settings or any other portion of flash). Please see the [wiki:jtag_instructions JTAG Page] for more information about the JTAG programmer. [=#nandspl] ==== SPL (Secondary Program Loader) ==== There is rarely a reason to update the {{{SPL}}}. Gateworks does not recommend downgrading the {{{SPL}}} (moving to an older version) because you may be missing important updates required to memory configuration for memory changes on the board. There are two main methods for flashing the SPL bootloader on a NAND flash. One is to use our {{{jtag_usbv4}}} program (see [#jtag above]) to update the entire bootloader using {{{u-boot_spl.bin}}} and the other is to use the {{{kobs-ng}}} utility from within Linux. In order to use the {{{kobs-ng}}} application to update the {{{SPL}}} bootloader, you must boot to Linux. As NAND devices can have bad blocks (this keeps the cost/density ratio low) the i.mx6 boot ROM allows for multiple copies of the bootloader+headers (referred to as the 'bootstream') to be placed on NAND flash. The {{{kobs-ng}}} application understands the flash layout and handles the gory details for you. 1. Boot to OpenWrt Linux ('''NOTE: This does not occur in the bootloader, boot all the way into Linux''') 2. fetch the {{{SPL}}} bootloader {{{#!bash cd /tmp wget http://dev.gateworks.com/ventana/images/SPL }}} 3. execute {{{kobs-ng}}} with the following parameters {{{#!bash kobs-ng init -v -x --search_exponent=1 --chip_0_size=0xe00000 SPL }}} * Note that you must have a version of {{{kobs-ng}}} that understands the {{{--chip_0_size}}} parameter, otherwise you need to adjust your mtd partitions such that {{{/dev/mtd0}}} is 14MB (0xe00000) in size and not 16MB (0x1000000). The Gateworks OpenWrt BSP has this version of {{{kobs-ng}}}. 4. You probably want to reset your U-Boot environment to use new scripts/defaults contained in the updated bootloader. You can do this in two ways: * from Linux: {{{#!bash flash_eraseall /dev/mtd1 }}} * from U-Boot: {{{#!bash env default -f -a #reset to defaults saveenv #save variables }}} [=#nanduboot] ==== u-boot.img (The main bootloader application) ==== Updating {{{u-boot.img}}} on a NAND flash device can be done within u-boot, or within Linux. * Updating {{{u-boot.img}}} from u-boot itself: {{{#!bash wget http://dev.gateworks.com/ventana/images/u-boot.img tftp ${loadaddr} ventana/u-boot.img && \ nand erase 0xe00000 0x200000 && \ nand write ${loadaddr} 0xe00000 ${filesize} }}} * Updating {{{u-boot.img}}} from Linux via {{{mtd-utils}}}: {{{#!bash wget http://dev.gateworks.com/ventana/images/u-boot.img flash_erase /dev/mtd0 0xe00000 0 && \ nandwrite --start=0xe00000 --pad /dev/mtd0 u-boot.img }}} [=#microsd] === micro-SD (boards without flash storage) === While the majority of Gateworks Ventana boards contain a NAND flash device they boot directly from (see [#nand above] for instructions on updating NAND flash), there are certain models that instead have only a micro-SD socket. The [wiki:ventana/SPL] supports loading the bootloader via a variety of methods including raw offset, raw partition, FAT filesystem, and EXT filesystem. The Gateworks default {{{SPL}}} is configured to load the the bootloader via a raw offset because this provides the fastest execution, simplest code, and is more in line with how we use NAND flash. The partitioning scheme Gateworks uses for micro-SD storage is as follows: ||= Start =||= Size =||= Sectors =||= Usage =|| || 0K || 1KB || 0 - 1 (2) || Partition Table etc || || 1KB || 68KB || 2 - 137 (136) || SPL || || 69KB || 640KB || 138 - 1279 (141) || U-Boot || || 709KB || 256KB || 1418 - 1929 (512) || env (2x redundant 128KB) || || 965KB || 59KB || 1930 - 2047 (117) || unused || || 1024KB || - || 2048 - || root partitions || [=#microsdspl] ==== SPL (Secondary Program Loader) ==== You can program the {{{SPL}}} from U-Boot or Linux: * from U-Boot: {{{#!bash tftp ${loadaddr} SPL && mmc erase 0x0 0x2 && mmc write ${loadaddr} 0x0 0x2 }}} * Note that U-Boot uses hex numbers thus the values above are the sector numbers and sizes in hex * from Linux via {{{mtd-utils}}} (assuming storage device is {{{/dev/sdc}}}): {{{#!bash sudo dd if=SPL of=/dev/sdc bs=1K seek=1 oflag=sync # copy SPL to 1KB offset }}} [=#microsduboot] ==== u-boot.img (The main bootloader application_) ==== Updating {{{u-boot.img}}} on a NAND flashs device can be done within u-boot, or within Linux. * Updating from U-boot: {{{#!bash tftp ${loadaddr} u-boot.img && mmc erase 0x8a 0x500 && mmc write ${loadaddr} 0x8a 0x500 }}} * from Linux via {{{mtd-utils}}} (assuming storage device is {{{/dev/sdc}}}): {{{#!bash sudo dd if=u-boot.img of=/dev/sdc bs=1K seek=69 oflag=sync # copy uboot.img to 69KB offset }}} [=#env] == environment variables == U-Boot uses many environment variables which are stored in persistent media and used to alter the boot. Some variables are actually scripts executed with the {{{run}}} command. Notable ventana U-Boot env vars: ||= Name =||= Purpose =|| || bootcmd || script executed at boot || || baudrate || baudrate of serial console || || bootdelay || number of seconds to wait for a key to abort automatic boot (if 0 will not wait) || || bootdevs || Used by ventana bootcmd script to specify the prioritized list of devices to boot from (usb mmc sata flash) || || console || device of serial console || || ethaddr || mac addr of first eth interface || || eth1addr || mac addr of second eth interface || || ethact || active ethernet device (current) || || athprime || primary ethernet device (used at boot) || || extra || Used by ventana boot scripts as extra info appended to the kernel bootargs || || fdt_addr || Address used to load flattened device-tree blob || || fdt_file || first choice of fdt file name (full board model and revision) || || fdt_file1 || second choice of fdt file name (full board model) || || fdt_file2 || third choice of fdt file name (board model family) || || flash_boot || Ventana boot script for booting from FLASH device || || ipaddr || local ip address || || loadaddr || Address used for tftp and load commands || || loadfdt || Ventana boot script to load flattened device tree || || mem_mb || Board memory size in MB's || || mmc_boot || Ventana boot script for booting from micro-SD || || model || board model || || mtdids || MTD device || || mtdparts || MTD partitions for mtd device (merged into device-tree) || || pcidisable || Setting to '1' will disable pci until booting to Linux || || quiet || if set to '1' will quiet down some of the bootloader output || || sata_boot || Ventana boot script for booting from SATA device || || serial# || board serial number || || serverip || ip address of server for tftp commands || || soctype || SoC type (imx6q or imx6dl) || || uimage || kernel image to load || When the bootloader boots it will load the environment from persistent storage (device and location based on the boot device). By default this data is blank so it is normal to see a message indicating there is a CRC error and that the '''default environment''' will be used. This means that the environment that was built into U-Boot at build time for the board is used. Note that some of the values above are dynamically set when the bootloader runs unless overridden by manually setting it ({{{ethaddr}}}, {{{eth1addr}}}, {{{mem_mb}}}, {{{model}}}, {{{serial#}}}, {{{fdt_file*}}} etc) If you want to erase the env so that the CRC fails and loads defaults (only useful over a {{{env default -f -a; env save}}} if you like to see the fact that its using defaults): {{{#!bash nand erase.part env }}} To do the same from within Linux: {{{#!bash flash_erase /dev/mtd1 0 0 }}} [=#nand-env] === extracting env storage (for provisioning) === When you provision boards (flashing your tailored firmware on the FLASH or creating tailored bootable media) you often want to use a modified env. After a board's U-Boot environment has been changed with {{{saveenv}}} you can read it back and store it in a file for re-deployment on another media. When extracting env be sure to clear the following vars which are usually meant to be board-specific: * {{{fdt_file}}} * {{{ethaddr}}} * {{{eth1addr}}} See [wiki:provisioning#nandprovisioning NAND Provisioning] for more details [=#memmap] == Memory Map == The IMX6 DRAM is physically addressed at 0x1000000 and has IRAM (internal RAM) addressed at 0x00907000. The SPL is loaded by the BOOT ROM to to 0x00908000 with 64K of code space and a 32K stack at 0x00918000. The SPL will load U-Boot to 0x1780000 which will re-locate itself to the top of DRAM with a stack and heap underneath it leaving the bottom of RAM usable by the bootloader. Because exception handlers exist at the base of DRAM the {{{loadaddr}}} is set to DRAM+32MB which is 0x1200000. [=#bootorder] == Boot order and boot scripts == u-boot by default executes the env var {{{bootcmd}}} as a script after initialization. The Ventana bootloader default bootcmd will iterate over {{{bootdevs}}} and attempt to boot off each device mentioned there. The default {{{bootdevs}}} is {{{usb mmc sata flash}}} * usb - USB Mass storage device * mmc - uSD card * sata - mSATA * flash - NAND/SPI flash In order to boot from one of the above devices there must be a {{{boot/uImage}}} on the filesystem (ext filesystem for usb/mmc/sata, and ubifs for NAND flash). It adds time to the bootup sequence to scan these devices so you may want to change {{{bootdevs}}} if you wish to speedup boot time. Booting from USB Mass Storage devices: * note that if you have multiple USB Mass Storage (UMS) devices and you want your boot device to be something other than the first detected UMS device you will need to alter the default {{{usb_boot}}} script as it assumes the first device ({{{usb dev 0}}}), ext2/3/4 filesystem and the first partition ({{{ext2load usb 0:1}}}). Filesystem types: * note that if you want to use a filesystem other than ext2/3/4 you will need to alter the default boot scripts as they use {{{ext2load}}} commands compatible with ext2/3/4 filesystems. Examples: * boot straight to mmc: {{{#!bash setenv bootdevs mmc saveenv }}} * try to boot off mmc before usb: {{{#!bash setenv bootdevs mmc usb sata flash saveenv }}} [=#enablepci] == Enabling PCI == To avoid PCI and PCIe related issues in Linux, the default bootloader behavior is to disable all pci until booting to Linux. In order to use any pci or pcie devices while in the bootloader, the {{{pcidisable}}} environment variable must be cleared. {{{ setenv pcidisable; saveenv; reset }}} Once cleared and after board reset, pci devices should enumerate as expected. You can further interact with the pci subsystem via the {{{pci}}} command in the bootloader. [=#hwconfig] == Hardware Configuration (hwconfig) == Several board configuration details are done by the bootloader at powerup such as: * DIO configuration: * pinmux: GPIO vs PWM (most of the Ventana user configurable DIO's can be configured as a PWM as well as a GPIO - see [wiki:ventana/DigitalIO#Mapping here] for details) * padctrl: The characteristics of the IO driver such as pull-up, pull-down, drive-strength etc * mSATA enabling: Board with mSATA support need to select if they wish to enable it (which disables PCIe to that socket) * rs232 driver enabling: The RS232 driver can be disabled to avoid contention between something driving the RX signal from the JTAG connector, and something driving the signal from the RS232 connector). The {{{hwconfig}}} env variable consists of a series of configurations separated by ';'. Use {{{setenv}}}/{{{printenv}}}/{{{saveenv}}} to modify them. Note that the board needs to be reset/power-cycled for the settings to take effect. Each DIO has a ''mode'' argument (controlling pinmux) and an optional ''padctrl'' (controlling padconf). The mode agument can be either ''gpio'' or ''pwm''. The pwm mode is only available for certain DIO's on various boards (see [wiki:ventana/DigitalIO#Mapping here] for details). The bootloader will display messages showing what was configured via {{{hwconfig}}} at bootup. For example: {{{#!bash U-Boot 2013.07-g5801172 (Jan 15 2014 - 08:13:16) CPU: Freescale i.MX6DL rev1.1 at 792 MHz ... MSATA: enabled RS232: enabled DIO0: GPIO1_IO16 (gpio-16) DIO1: GPIO1_IO19 (gpio-19) DIO2: GPIO1_IO17 (gpio-17) DIO3: GPIO1_IO20 (gpio-20) ... Ventana > print hwconfig hwconfig=msata;rs232;dio0:mode=gpio;dio1:mode=gpio;dio2:mode=gpio;dio3:mode=gpio }}} [=#msata] === mSATA enable === ''' mSATA requires a quad-core processor on Ventana''' On boards that support mSATA, the mSATA signals are muxed with PCIe signals on one PCIe socket of the board. Therefore the user needs to choose whether they want to use mSATA or PCI on that socket. This is done by adding 'msata' to {{{hwconfig}}} to enable mSATA or removing it from hwconfig to use PCIe in that socket. {{{#!bash Ventana > setenv hwconfig "msata;${hwconfig}" Ventana > saveenv Ventana > reset }}} ** NOTE: Booting from USB with msata enabled may result in failure to find init.** [=#usbrouting] === USB Front-panel vs PCIe socket routing === The GW52xx allows USB OTG to be routed to the front-panel connector or the J8 MiniPCIe socket (for use with a cellular modem or the [wiki:expansion/gw16103 GW16103] for example). The default routing is the front-panel connector. This can be changed to route USB OTG to the MiniPCIe J8 socket by setting the 'usb_pcisel' {{{hwconfig}}}. For example: {{{#!bash Ventana > print hwconfig hwconfig=rs232;dio0:mode=gpio;dio1:mode=gpio;dio2:mode=gpio;dio3:mode=gpio Ventana > setenv hwconfig "usb_pcisel;${hwconfig}" Ventana > print hwconfig hwconfig=usb_pcisel;rs232;dio0:mode=gpio;dio1:mode=gpio;dio2:mode=gpio;dio3:mode=gpio Ventana > saveenv Ventana > reset }}} * The board must be reset for this to take effect * This is only supported in the bootloader at this time (vs steering at runtime with GPIO). If you are trying to boot from a USB based device (or one on a USB bus off the MiniPCIe socket you will need to do this in the bootloader) [=#rs232enable] === rs232 driver enable === Most Ventana boards have a connector with RS232 using a UART that is shared with the one that also goes to the JTAG connector. This is UART2 ({{{/dev/ttymxc1}}}) on all Ventana boards. When you have hardware connected to both connectors at the same time you have a situation where two sources are driving the RX signal back to the i.MX6 at the same time and inconsistent results will occur (For example, the RS232 driver in the Gateworks JTAG dongle is a stronger driver than the one on the Ventana boards, so if you have the JTAG dongle connected you will receive characters sent from the JTAG connector serial port, but not from what is connected to the RS232 port). To avoid this contention you can disable the RS232 driver (Note this does not disable the TX signal but only the RX input to the i.MX6). To enable the driver, set the {{{rs232}}} variable, to disable it remove it. [=#dioconfig] === DIO configuration === The Ventana boards have 4 user controllable IO's from the i.MX6 going to a header. Depending on the board, some of these can be configured as GPIO ''or'' PWM (pulse-width-modulation) signals (where the PWM frequency/period is controlled by hardware). To configure a dio as a gpio, set its {{{mode=gpio}}}, and to configure it as a pwm set {{{mode=pwm}}}. The optional ''padctrl'' argument is a hexadecimal number with leading 0x with bit descriptions below (this is equivalent to the IMX6 PAD_CTL register definition): ||= Bits =||= Description =|| || 31-17[[BR]]reserved || This read-only field is reserved and always has the value 0 || || 16[[BR]]HYS || Hysteresis Enable Field:[[BR]]- 0 DISABLED: CMOS input[[BR]]- 1 ENABLED: Schmitt trigger input || || 15–14[[BR]]PUS || Pull Up / Down Config:[[BR]]- 00 100K_OHM_PD: 100K Ohm Pull Down[[BR]]- 01 47K_OHM_PU: 47K Ohm Pull Up[[BR]]- 10 100K_OHM_PU : 100K Ohm Pull Up[[BR]]- 11 22K_OHM_PU: 22K Ohm Pull Up || || 13[[BR]]PUE || Pull / Keep Select:[[BR]]- 0 KEEP: Keeper Enabled[[BR]]- 1 PULL: Pull Enabled || || 12[[BR]]PKE || Pull / Keep Enable:[[BR]]- 0 DISABLED: Pull / Keeper Disabled[[BR]]- 1 ENABLED: Pull / Keeper Enabled || || 11[[BR]]ODE || Open Drain Enable:[[BR]]- 0 DISABLED: Output is CMOS[[BR]]- 1 ENABLED: Output is Open Drain || || 10–8[[BR]]Reserved || This read-only field is reserved and always has the value 0 || || 7–6[[BR]]SPEED || Speed Field:[[BR]]- 00 Reserved[[BR]]- 01 50MHZ: Low (50 MHz)[[BR]]- 10 100MHZ: Medium (100 MHz)[[BR]]- 11 200MHZ: Maximum (200 MHz) || || 5–3[[BR]]DSE || Drive Strength:[[BR]]- 000 HIZ: HI-Z[[BR]]- 001 240_OHM[[BR]]- 010 120_OHM[[BR]]- 011 80_OHM[[BR]]- 100 60_OHM[[BR]]- 101 48_OHM[[BR]]- 110 40_OHM[[BR]]- 111 34_OHM || || 2–1[[BR]]Reserved || This read-only field is reserved and always has the value 0 || || 0[[BR]]SRE || Slew Rate:[[BR]]- 0 SLOW: Slow Slew Rate[[BR]]- 1 FAST: Fast Slew Rate || * for details consult the [http://cache.freescale.com/files/32bit/doc/ref_manual/IMX6DQRM.pdf IMX6DQRM] and [http://cache.freescale.com/files/32bit/doc/ref_manual/IMX6SDLRM.pdf IMX6SDLRM] depending on the CPU you are using. The GPIO blocks are described in section 28.4 which provides example configuration for various commonly used GPIO modes If unspecified the padctrl register is set to 0x1B0B9: * hysteresis * 100k pull-up * medium speed * fast slew rate * 34ohm DSE Examples: * to set DIO0, DIO1 to PWM and DIO2, DIO3 as a GPIO leaving the default padctrl: {{{#!bash setenv hwconfig 'rs232;dio0:mode=pwm;dio1:mode=pwm;dio2:mode=gpio;dio3:mode=gpio' }}} * and the same but removing the pull-up from all: {{{#!bash setenv hwconfig 'rs232;dio0:mode=pwm,padctrl=0x1a0b9;dio1:mode=pwm,padctrl=0x1a0b9;dio2:mode=gpio,padctrl=0x1a0b9;dio3:mode=gpio,padctrl=0x1a0b9' }}} By default, DIO's configured as PWM's register with the same driver the LED's use. This makes it easier to write PWM values to the pin. This can be accomplished by doing exactly what you would to an LED. Writing a value of 127 (the floor of 255/2) would yield a PWM signal at 50% duty cycle. The following would accomplish this write: {{{#!bash root@ventana:~# echo "127" > /sys/class/leds/user1/brightness }}} DIO's configured as GPIO's register with the gpio class driver and can be controlled via {{{/sys/class/gpio}}}. '''Note''' - GPIO's used as outputs will read back the value the IMX6 is driving them unless the mux_mode register SION bit is set, enabling the input path. When SION is set you will read back the actual state of the pin, instead of the state the IMX6 is trying to drive. Enabling the input path by setting the SION bit does increase power draw slightly and for this reason the bit is set only for GPIO's that we may want to read the current hardware state via {{{gpio_get_value}}} or {{{gpiolib}}}. === Examples === To help explain, here are some examples: * GW5400: enable mSATA on J11, enable RS232 driver, and set all DIO's to GPIO mode (the following example is with a Crucial M4-CT032M4SSD3 32GB mSATA disk): {{{#!bash Ventana > setenv hwconfig 'msata;rs232;dio0:mode=gpio;dio1:mode=gpio;dio2:mode=gpio;dio3:mode=gpio' Ventana > saveenv Ventana > reset ... Ventana > sata part AHCI 0001.0300 32 slots 1 ports 3 Gbps 0x1 impl SATA mode flags: ncq stag pm led clo only pmp pio slum part SATA Device Info: S/N: 00000000121903596B47 Product model number: M4-CT032M4SSD3 Firmware version: 04MH Capacity: 62533296 sectors Partition Map for SATA device 0 -- Partition Type: DOS Part Start Sector Num Sectors UUID Type 1 1 40959 00000000-01 83 Boot 2 40960 40960 00000000-02 83 3 81920 2097152 00000000-03 05 Extd 4 2179072 60352512 00000000-04 83 5 81921 1048575 00000000-05 83 6 1130497 102399 00000000-06 83 7 1232897 20479 00000000-07 83 8 1253377 20479 00000000-08 83 }}} * GW5400: disable mSATA (use PCIe on J11), enable RS232 driver, and set DIO1,2 to PWM: {{{#!bash Ventana > setenv hwconfig 'rs232;dio0:mode=gpio;dio1:mode=pwm;dio2:mode=pwm;dio3:mode=gpio' Ventana > saveenv Ventana > reset }}} [=#network] == Network Support == The Ventana U-Boot has support for the following network devices: * IMX6 FEC (eth0 on most Ventana boards) * Intel i210 (eth0 and eth1 on GW5520: must [#pcinet enable pci] to use in the bootloader) * IMX6 USB OTG network gadget - usbnet (network connection between Ventana USB OTG port and host PC) * USB Network devices (ASIX AX8817X, SMSC LAN95xx) [=#pcinet] === PCIe Network Devices === To use a network device relying on PCIe (i210, sky2, etc) in the bootloader, you must clear the {{{pcidisable}}} environment variable and reset. {{{ setenv pcidisable; saveenv; reset }}} See the above [#enablepci enabling pci] section for more information. [=#usbnet] === usbnet (USB OTG network Gadget support) === The Ventana bootloader supports usbnet which allows network connectivity to a PC host connected to a Ventana's USB OTG port using the CDC ethernet device standard, which is supported on Linux by the cdc-ether driver (and should be supported on other OS's as well). Because U-Boot is not a full fledged OS is does not support background Gadget drivers. Instead it brings up the gadget drivers when needed and takes them down when the necessary operation has completed. This means that simply connecting a PC USB host to the OTG port won't cause a new network device to appear on your host 'until' you use a U-Boot networking command such as {{{ping}}} or {{{tftpboot}}}. For this reason, its important to preconfigure your host OS for a networking port based on the MAC address that the OTG gadget driver will use (specified by the {{{usbnet_hostaddr}}} var) with an IPv4 configuration to talk to the target board. This is likely best explained by an example: 1. configure {{{usbnet}}} on the Ventana target board: {{{#!bash setenv usbnet_hostaddr 00:d0:12:00:00:01 setenv usbnet_devaddr 00:d0:12:00:00:02 setenv ipaddr 10.0.0.2 setenv netmask 255.255.255.0 }}} * this specifies that the MAC address the OTG gadget will present to the CDC ethernet host to use is '00:d0:12:00:00:01' (use a unique MAC address on your network as one is not allocated for the board to use for the OTG port) * similarly the MAC address the OTG gadget target side will respond to is specified by the {{{usbnet_devaddr}}} address and it also needs to be a unique MAC address on your network. 2. Configure your host PC with a network interface for the specific MAC addressed defined in the usbnet_hostaddr variable above and provide it with an IPv4 configuration with an IP/netmask of 10.0.0.1/255.255.255.0. For Ubuntu hosts, you can use the Network Manager icon to create a new Interface by going to Edit Connections -> Add -> Connection Type 'Ethernet' then specify Ethernet -> Device MAC address (matching the above usbnet_hostaddr MAC), then specifying the IP/netmask under the IPv4 Settings tab. 3. On the Ventana target specify the active network interface is {{{usb_ether}}}: {{{#!bash setenv ethact usb_ether }}} 4. On the Ventana target you can now use {{{ping}}} and {{{tftpboot}}} to communicate with the network device you created on the PC host. Note that the network interface won't 'appear' in your system until these commands start on the target: {{{#!bash ping 10.0.0.1 tftpboot ${loadaddr} uImage }}} [=#display] == Display support == The u-boot bootloader has some rudimentary support for displays including LVDS displays and HDMI monitors. The most recent Gateworks bootloader will display a Gateworks logo centered within the display (older versions would display a Linux 'tux' logo in the upper left hand corner along with the uboot version and build information). The {{{panel}}} env variable is used to set the display type in the bootloader and can be set to the following: - **HDMI** (1024x768 resolution - no EDID info used for monitor preferences) - **Hannstar-XGA** - Freescale MXC-LVDS1 (!HannStar HSD100PXN1-A00 w/ egalax touchscreen controller) - **DLC800FIGT3** - 8in XGA (1024x768) - **DLC700JMGT4** - 7in WSVGA (1024x600) - **DLC0700XDP21LF** - 7in WSVGA (1024x600) - **none** - any other string such as 'none' will disable display support in the bootloader See [wiki:ventana/LVDS#SupportedDisplays] for more information on supported LVDS displays. If the {{{panel}}} env variable is not set the display device will attempt to be detected by first looking to see if an HDMI monitor is connected to the HDMI phy, and next to see if an i2c device at 0x04 (touchscreen controller) which is assumed to be the Hannstar-XGA. The {{{display}}} env variable is used to configure the Gateworks kernel display timings (via device-tree properties). Additionally the boot scripts used for various OS's such as Yocto or Android configure kernel parameters for various display options. Examples: * display the bootloader splash and configure Linux OS for DLC800FIGT3: {{{#!bash setenv panel DLC800FIGT3 setenv display DLC800FIGT3 saveenv reset }}} * display the bootloader splash for DLC800FIGT3 but do not configure Linux OS {{{#!bash setenv panel DLC800FIGT3 setenv display none saveenv reset }}} * disable bootloader splash but configure Linux OS for DLC800FIGT3: {{{#!bash setenv panel none setenv display DLC800FIGT3 saveenv reset }}} Some Linux OS's may behave differently or have additional features - please see OS specific notes on the respective wiki pages: * [wiki:Yocto/Video_Out#bootscript Yocto or other third-party-linux distros using the Gateworks kernel] * [wiki:Android/Booting#display Android] [=#devicetree] == Flattened Device-Tree == The Ventana kernel (with the exception of the 3.0.35 kernel used in early Yocto v1.3 and Android jellybean BSP's) is a device-tree kernel. This means the bootloader is responsible for loading the device-tree blob (DTB) and adjusting it per bootloader configuration (and occasionally hardware errata). The {{{loadfdt}}} script is used to load the device-tree blob (dtb) in all standard boot cases for the Gateworks bootloader. This script attempts to load a dtb three times, each time with a more generic filename (from the {{{fdt_file}}}, {{{fdt_file1}}}, and {{{fdt_file2}}}) env variable which if not set (overridden) will get set per the board model defined in the Gateworks EEPROM. For example a GW5400-C would have the following: {{{#!bash Ventana > print fdt_file fdt_file=imx6q-gw5400-c.dtb Ventana > print fdt_file1 fdt_file1=imx6q-gw5400.dtb Ventana > print fdt_file2 fdt_file2=imx6q-gw54xx.dtb }}} The only dtb files we have required thus far is the most generic version specified by {{{fdt_file2}}}. You can see the dtb files in the boot directory of the root filesystem of our BSP's. === Using the fixfdt script to apply custom fdt fixups === The Ventana bootloader U-Boot scripts run a script called {{{fixfdt}}} to apply any custom fixups you may want to implement. Specifically this script is called from the {{{loadfdt}}} script. Example: * add an fdt fixup to disable pcie driver {{{#!bash setenv fixfdt 'fdt addr ${fdt_addr}; fdt resize; fdt set /soc/pcie@0x01000000 status disabled' saveenv }}} * To find the path on a running live system, run the following command to see the device tree on the target board: {{{#!bash find /proc/device-tree }}} * You can then grep for whatever item is needed: {{{#!bash root@OpenWrt:/# find /proc/device-tree/ | grep lvds /proc/device-tree/soc/aips-bus@02000000/ldb@020e0008/lvds-channel@1 /proc/device-tree/soc/aips-bus@02000000/ldb@020e0008/lvds-channel@1/name /proc/device-tree/soc/aips-bus@02000000/ldb@020e0008/lvds-channel@1/crtcs /proc/device-tree/soc/aips-bus@02000000/ldb@020e0008/lvds-channel@1/status }}} * The status field is typically what should be changed to 'disabled' {{{#!bash root@OpenWrt:/# cat /proc/device-tree/soc/aips-bus@02000000/ldb@020e0008/lvds-channel@0/status okay }}} * To disable this LVDS, it would look like {{{#!bash setenv fixfdt 'fdt addr ${fdt_addr}; fdt resize; fdt set /soc/aips-bus@02000000/ldb@020e0008/lvds-channel@0 status disabled' saveenv }}} This script is available in '''U-Boot 2014.04-00184-gf830d9d (Feb 24 2015 - 08:11:33)'''. === Specifying an alternate device-tree blob (DTB) === Knowing that the {{{loadfdt}}} attempts to load {{{fdt_file}}}, {{{fdt_file1}}}, {{{fdt_file2}}} in that order, you can override {{{fdt_file}}} to specify an alternate DTB. This would be useful if you need to alter the device-tree to add support for an off-board peripheral for example and i2c device. If you have built a dtb that you want loaded instead of the default model-based fdt you can specify it as follows in the bootloader: {{{#!bash setenv fdt_file my-custom.dtb saveenv }}} If you ever want to revert back, just erase your bootloader environment or unset the {{{fdt_file}}} by setting it to nothing: {{{#!bash setenv fdt_file saveenv }}} Don't forget that by default the {{{loadfdt}}} script assumes the dtb's are located on the rootfs in the {{{/boot}}} directory.