A 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
  • 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 here for more info on the SPL

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:

  • Pre-Built Bootloader
    • Installation instructions: JTAG Instructions
    • 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.

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 on the serial console look at the very first line, like so:
    U-Boot SPL 2015.04-g8a78625 (Apr 21 2015 - 07:24:40)
  • or, Once booted in Linux, use the command:
    strings /dev/mtd0 | grep U-Boot

To see a history of the pre-built bootloaders we host at see here


We host the sourcecode for the Ventana bootloader on Github here:

source branches:

  • gateworks_v2015.04 - based on u-boot-2015.04 release (Apr 2015) - Latest - Commits
  • 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


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 here.
  • or you can download a pre-built OpenWrt toolchain here

Step-by-Step Instructions for building U-Boot:

  1. Download U-Boot from Github
    > git clone
    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)
    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:
    > 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
  5. Create a JTAG binary suitable for programming via the Gateworks JTAG dongle and jtag_usbv4 software (Optional) using the mkimage_jtag script
    ./mkimage_jtag SPL u-boot.img > uboot_spl.bin
  6. Copy the binary artifacts (SPL, u-boot.img) to a http/tftp server (Optional)
    mkdir /tftpboot/ventana
    cp SPL u-boot.img /tftpboot/ventana/

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.

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 below.

The partitioning scheme Gateworks uses for NAND flash storage is as follows:

Start End Usage
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.

Updating SPL and bootloader via JTAG

* Recommended *

You can use JTAG on boards with NAND flash to program the u-boot_spl.bin downloaded from the 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 jtag_usbv4 software, you can update the entire bootloader via JTAG from a Linux PC (*Note this does not work on Windows for Ventana):

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 JTAG Page for more information about the JTAG programmer.

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 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
    cd /tmp
  3. execute kobs-ng with the following parameters
    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:
      # On system's with flash_erase:
      flash_erase /dev/mtd1 0 0
      # On system's with flash_eraseall only:
      flash_eraseall /dev/mtd1
    • from U-Boot:
      nand erase.part env # erase env partition forcing baked-in defaults on subsequent boots

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:
    tftp ${loadaddr} ventana/u-boot.img && \
      nand erase 0xe00000 0x200000 && \
      nand write ${loadaddr} 0xe00000 ${filesize}
  • Updating u-boot.img from Linux via mtd-utils:
    flash_erase /dev/mtd0 0xe00000 0 && \
      nandwrite --start=0xe00000 --pad /dev/mtd0 u-boot.img

micro-SD (boards without flash storage)

While the majority of Gateworks Ventana boards contain a NAND flash device they boot directly from (see above for instructions on updating NAND flash), there are certain models that instead have only a micro-SD socket.

The 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

SPL (Secondary Program Loader)

You can program the SPL from U-Boot or Linux:

  • from U-Boot:
    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):
    sudo dd if=SPL of=/dev/sdc bs=1K seek=1 oflag=sync # copy SPL to 1KB offset

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:
    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):
    sudo dd if=u-boot.img of=/dev/sdc bs=1K seek=69 oflag=sync # copy uboot.img to 69KB offset

root filesistem (The Operating System)

Using the partitioning scheme above for booting directly to micro-SD for NAND-less boards, you can create a root filesystem at a 1MiB offset as follows:

sudo sfdisk -uS ${BLOCK_DEV} <<EOF
sudo mkfs.ext4 -q -L rootfs ${BLOCK_DEV}1

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.

The most common env vars used for the Ventana bootloader are:

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 Disable PCI enumeration (defaulted to 1 - see below)
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)

You can use env commands to get or set env vars. For example:

  • Get a var:
    env print model
  • Set a var:
    env set quiet 1
  • Load default values (does not save):
    env default -f -a
  • Save current env:
    env save

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):

nand erase.part env

To do the same from within Linux:

flash_erase /dev/mtd1 0 0

U-Boot envtools (fw_printenv / fw_setenv)

The uboot-envtools package provides tools to allow reading and writing to U-Boot's env variables provided you have a proper configuration file.

Assuming your using a board with NAND flash as the primary boot device and the U-Boot env is in the 2nd partition the following shows a valid config file:

> cat /proc/mtd
dev:    size   erasesize  name
mtd0: 01000000 00040000 "uboot"
mtd1: 00100000 00040000 "env"
mtd2: 7ef00000 00040000 "rootfs"
> cat /etc/fw_env.config
/dev/mtd1 0x0 0x20000 0x40000
/dev/mtd1 0x80000 0x20000 0x40000

Assuming you are using a NAND-less board booting to micro-SD a valid config file looks like:

> cat /etc/fw_env.config
/dev/mmcblk0 0xb1400 0x20000 0x20000
/dev/mmcblk0 0xd1400 0x20000 0x20000

It is important to realize the meaning of the Warning: Bad CRC, using default environment message. This means that the non-volatile env area is empty or corrupt (Note that this is the way Gateworks boards ship by default) and that the built-in env within U-Boot will be used. This message will go away once the saveenv command is used in the bootloader.

If you use fw_setenv on an environment in this state it will properly set the variable you specify and all other variables will continue to use their built-in default values within U-Boot. Essentially you are 'overriding' the defaults as you would expect.

You can use fw_printenv from within Linux to view any bootloader variables.

root@OpenWrt:/# fw_printenv hwconfig

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 NAND Provisioning for more details

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.

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.


  • boot straight to mmc:
    setenv bootdevs mmc
  • try to boot off mmc before usb:
    setenv bootdevs mmc usb sata flash

USB Mass Storage Support

The Ventana U-Boot supports USB Mass Storage devices on both the EHCI port and the OTG port on applicable hardware. The usb subsystem will apply power to a USB device for a specific time according to the USB specification before it scans the device. Some USB storage devices have been found to not adhere to the USB specification and require longer warm-up times. You can set the usb_pgood_delay to the number of ms required for your device to work around this issue. If your USB Mass storage device fails to be detected when you do a usb start in U-Boot try setting this to a value of 2000 or larger (2 seconds+) and issue the command again to see if that helps:

General command:

setenv usb_pgood_delay 2000


Ventana > usb start
(Re)start USB...
USB0:   lowlevel init failed
USB1:   USB EHCI 1.00
scanning bus 1 for devices... 2 USB Device(s) found
       scanning usb for storage devices... 0 Storage Device(s) found
       scanning usb for ethernet devices... 0 Ethernet Device(s) found
Ventana > setenv usb_pgood_delay 2000
Ventana > usb start
(Re)start USB...
USB0:   lowlevel init failed
USB1:   USB EHCI 1.00
scanning bus 1 for devices... 2 USB Device(s) found
       scanning usb for storage devices... 1 Storage Device(s) found
       scanning usb for ethernet devices... 0 Ethernet Device(s) found

Be sure to run the saveenv command afterwards to save the setting:



The USB OTG host controller on the IMX6 is supported under U-Boot in both host and gadget mode.

Common uses in host mode include attaching to a:

  • USB Mass storage device
  • USB Network Interface (two common devices are supported - see below

Common uses in device mode include attaching to a PC:

  • emulating a USB Mass storage device - see below

USB Mass Storage emulation to a Host over OTG

One of the more handy features of USB OTG support is connecting to a PC and using the ums command to implement the USB Mass Storage device protocol thus allowing access from a PC to block storage devices (USB Mass Storage, micro-SD, mSATA) attached to the Ventana board.


  • IMX6 micro-SD host controller (this is on-board micro-SD, not a USB based micro-SD reader/writer such as the GW16103)
    ums 0 mmc 0
  • USB Mass Storage device:
    usb start && ums 0 usb 0
  • mSATA device:
    sata init && ums 0 sata 0

This feature is available in Gateworks U-Boot 2015.04

General Purpose IO (GPIO)

The gpio command provides the ability to list and configure board-specific GPIO's. The IMX6 has 7 banks of 32 GPIOs. The pin value used for the gpio command will match the Linux gpio, which follows the equation (bank-1) * 32 + io. The status command however will list the GPIO's as GPIO<bank>_<io> so when determining the pin value you need to do the math.

For example, on Ventana boards that support MSATA the MSATA enable is GPIO2_IO8 (bank2 io8) or gpio-40 ((2-1)*32 + 8) so the pin value of 40 is used.


  • List GPIO's:
    gpio status
  • set GPIO2_8 (gpio 40) (set to logic 1) (enables MSATA on boards that have it):
    gpio set 40
  • clear GPIO2_8 (gpio 40) (set to logic 0) (disables MSATA and selects PCI on boards that have it):
    gpio clear 40
  • set GPIO1_17 (gpio 17) as an input and get its value
    gpio input 17

This feature is available in Gateworks U-Boot 2015.04

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 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 here for details).

The bootloader will display messages showing what was configured via hwconfig at bootup. For example:

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

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.

Ventana > setenv hwconfig "msata;${hwconfig}"
Ventana > saveenv
Ventana > reset

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 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:

Ventana > print hwconfig
Ventana > setenv hwconfig "usb_pcisel;${hwconfig}"
Ventana > print hwconfig
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)

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.

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 hexidecimal number with leading 0x with bit descriptions below (this is equivalent to the IMX6 PAD_CTL register definition):

Bits Description
This read-only field is reserved and always has the value 0
Hysteresis Enable Field:
- 0 DISABLED: CMOS input
- 1 ENABLED: Schmitt trigger input
Pull Up / Down Config:
- 00 100K_OHM_PD: 100K Ohm Pull Down
- 01 47K_OHM_PU: 47K Ohm Pull Up
- 10 100K_OHM_PU : 100K Ohm Pull Up
- 11 22K_OHM_PU: 22K Ohm Pull Up
Pull / Keep Select:
- 0 KEEP: Keeper Enabled
- 1 PULL: Pull Enabled
Pull / Keep Enable:
- 0 DISABLED: Pull / Keeper Disabled
- 1 ENABLED: Pull / Keeper Enabled
Open Drain Enable:
- 0 DISABLED: Output is CMOS
- 1 ENABLED: Output is Open Drain
This read-only field is reserved and always has the value 0
Speed Field:
- 00 Reserved
- 01 50MHZ: Low (50 MHz)
- 10 100MHZ: Medium (100 MHz)
- 11 200MHZ: Maximum (200 MHz)
Drive Strength:
- 000 HIZ: HI-Z
- 001 240_OHM
- 010 120_OHM
- 011 80_OHM
- 100 60_OHM
- 101 48_OHM
- 110 40_OHM
- 111 34_OHM
This read-only field is reserved and always has the value 0
Slew Rate:
- 0 SLOW: Slow Slew Rate
- 1 FAST: Fast Slew Rate

If unspecified the padctrl register is set to 0x1B0B9:

  • hysteresis
  • 100k pull-up
  • medium speed
  • fast slew rate
  • 34ohm DSE


  • to set DIO0, DIO1 to PWM and DIO2, DIO3 as a GPIO leaving the default padctrl:
    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:
    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:

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.


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):
    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:
    Ventana > setenv hwconfig 'rs232;dio0:mode=gpio;dio1:mode=pwm;dio2:mode=pwm;dio3:mode=gpio'
    Ventana > saveenv
    Ventana > reset

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)
  • IMX6 USB OTG network gadget - usbnet (network connection between Ventana USB OTG port and host PC)
  • USB Network devices (ASIX AX8817X, SMSC LAN95xx)

The following U-Boot environment variables affect networking:

  • ipaddr - local IP address
  • serverip - TFTP server IP
  • ethprime - controls which interface is used first
  • ethact - controls which interface is currently active
  • ethrotate - when set to 'no' uboot does not go through all available network interfaces and instead just stays at the currently selected interface (ethact)
  • netretry - when set to 'no' each network operation will either success or fail without retrying. When set to 'once' the operation will fail only when all available network interfaces have been tried once without success.
  • tftpsrcport - UDP source port (if not set uses default)
  • tftpdstport - UDP dest port (if not set uses well known port 69)
  • tftpblocksize - if not set will use TFTP server's default block size
  • tftptimeout - retransmission timeout for TFTP packets in ms (min value is 1000, default is 5000)

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:
    setenv usbnet_hostaddr 00:d0:12:00:00:01
    setenv usbnet_devaddr 00:d0:12:00:00:02
    setenv ipaddr
    setenv netmask
    • 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.
  1. 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 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.
  1. On the Ventana target specify the active network interface is usb_ether:
    setenv ethact usb_ether
  1. 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:
    tftpboot ${loadaddr} uImage

USB Ethernet Device support

There is support in U-Boot for a few USB chipsets that are commonly available in low-cost USB Ethernet dongles:

To use these use the following U-Boot configuration:

  1. scan USB bus for supported devices:
    usb start
    • If you have a supported USB device attached you will see a message to that effect
  2. set active ethernet device - for example an ASIX device:
    setenv ethact asx0
  3. Use networking as needed:
    tftp ${loadaddr} ${file}

NetConsole (access U-Boot console from network)

U-Boot does not contain any TCP implementation and as such there is no 'telnet server' or 'telnetd' support. There is however something similar called 'NetConsole' which will allow stdin/stdout/stderr to be directed to a UDP network port. If you set this up you can use the Linux 'nc' or 'netcat' tool or use the the 'netconsole' shell script provided in tools/netconsole (which uses these tools) to talk to U-Boot's interpreter from a Linux host.

Using NetConsole, the paradigm is reversed from the telnet/ssh perspective a bit such that you need to configure U-Boot to listen to a specifc IP address of a server.

To enable NetConsole you must do the following:

  • U-Boot:
    • configure networking: For example have a network interface supported by U-boot, set ipaddr env variable and serverip env variable (make sure you can ping $serverip):
      setenv ipaddr # local ip
      setenv serverip # host ip running netcat/netconsole
    • set the ncip address to your server:
      setenv ncip ${serverip}
    • set stdin/stdout/stderr as desired to nc:
      setenv stdin nc; setenv stdout nc; setenv stderr nc
    • (optional) if you want these changed persistent, do a saveenv:
  • Linux host:
    • make sure you have netcat (either nc or netcat applications)
    • grab the netconsole shell script from U-Boot's tools directory:
      chmod +x netconsole
    • use netconsole to listen to your target IP address for input/output:
      • Note that netconsole remaps the interrupt from Cntl-C to Cntl-T so that you can use Cntl-C over the network console

For a bootloader configuration that sits waiting for network commands from a specific host but with a timeout you can use the preboot env variable to execute a script prior to bootcmd such as:

setenv serverip # your server ip
setenv ipaddr # your local ip
setenv netretry no
setenv preboot 'echo "Looking for server at $serverip..."; \
 if ping $serverip; then setenv ncip ${serverip}; setenv bootdelay 10; \
 echo "Starting NetConsole to ${ncip} and waiting for ${bootdelay} seconds..."; \
 setenv stdin nc; setenv stdout nc; setenv stderr nc; \
  • Note that we set netretry to 'no' which causes network operations to not retry (otherwise the ping will go forever). This could also be set to 'once' if you wish to cycle through all available network interfaces (such as on-board NIC's as well as USB nics) instead of just 'ethprime'.

This only pertains to input/output of the U-Boot environment. Once the bootloader jumps to the kernel, the kernel is in charge of what to do about its input/output, which is controlled via the 'console' kernel cmdline. Note that there is a CONFIG_NETCONSOLE option in the kernel that uses a 'netconsole' kernel cmdline however that option is not enabled in the Gateworks kernels by default


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)
  • none - any other string such as 'none' will disable display support in the bootloader

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.


  • display the bootloader splash and configure Linux OS for DLC800FIGT3:
    setenv panel DLC800FIGT3
    setenv display DLC800FIGT3
  • display the bootloader splash for DLC800FIGT3 but do not configure Linux OS
    setenv panel DLC800FIGT3
    setenv display none
  • disable bootloader splash but configure Linux OS for DLC800FIGT3:
    setenv panel none
    setenv display DLC800FIGT3

Some Linux OS's may behave differently or have additional features - please see OS specific notes on the respective wiki pages:

Bootloader Splash Screen

The Linux penguin usually was shown as part of the bootloader.

Gateworks has changed this to display the Gateworks logo.

Read more information here

GSC support

The Ventana u-boot bootloader has a gsc command that will show you information about the GSC on the target board.

This command was added in the U-Boot 2014.04-00177-gc1e54c4 (Jan 28 2015 - 11:33:55) release

GSC info (Firmware version, Board Temperature and Voltages, and Watchdog info)

The gsc command by itself with no arguments displays information about the GSC firmware version/crc and watchdog state (enabled or disabled and whether or not it caused a board power-cycle)


Ventana > gsc
GSC:   v45 0x30be WDT:disabled
Temp    :537
VIN     :16676
VBATT   :2797
VDD_3P3 :3320
VDD_ARM :1325
VDD_SOC :1330
VDD_DDR :1557
VDD_5P0 :5130
VDD_2P5 :2461
VDD_1P8 :1845
VDD_IO2 :3090
VDD_IO3 :invalid

Note that not all boards use all of the above voltage rails. For example the board above does not have an IO3 voltage rail.

GSC Watchdog Enable / Disable

The gsc command can be used to enable or disable the GSC hardware watchdog with the following usage:

gsc [wd enable [30|60]]|[wd disable]


  • Enable the watchdog for a 30 second timeout
    gsc wd enable 30
    • If the time is not specified it will default to 30 seconds
    • only 30 seconds and 60 seconds are valid
    • once enabled make sure you have something managing the watchdog in your OS
  • Disable the GSC watchdog
    gsc wd disable


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:

Ventana >  print fdt_file
Ventana >  print fdt_file1
Ventana >  print fdt_file2

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.


  • add an fdt fixup to disable pcie driver
    setenv fixfdt 'fdt addr ${fdt_addr}; fdt resize; fdt set /soc/pcie@0x01000000 status disabled'
  • To find the path on a running live system, run the following command to see the device tree on the target board:
    find /proc/device-tree
    • You can then grep for whatever item is needed:
      root@OpenWrt:/# find /proc/device-tree/ | grep lvds
    • The status field is typically what should be changed to 'disabled'
      root@OpenWrt:/# cat /proc/device-tree/soc/aips-bus@02000000/ldb@020e0008/lvds-channel@0/status
    • To disable this LVDS, it would look like
      setenv fixfdt 'fdt addr ${fdt_addr}; fdt resize; fdt set /soc/aips-bus@02000000/ldb@020e0008/lvds-channel@0 status disabled'

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:

setenv fdt_file my-custom.dtb

If you ever want to revert back, just erase your bootloader environment or unset the fdt_file by setting it to nothing:

setenv fdt_file

Don't forget that by default the loadfdt script assumes the dtb's are located on the rootfs in the /boot directory.

PCI Support

The Ventana bootloader has PCI support however an environment variable pcidisable is defaulted to 1 to disable it. This is because enabling the IMX6 PCIe controller in the bootloader can cause some issues in the kernel to do PERST# being asserted/desasserted multiple times, and the fact that the i.MX6 does not have a proper reset for its PCIe core:

  • IMX6 pcie driver init occasionally hangs
  • some cards fail to enumerate occasionally
  • GW16081 won't enumerate past the bridge

However, PCI support is needed in the bootloader for the following cases:

  • Any card that needs PERST# de-asserted for features necessary in the bootloader, such as USB access to the GW16103, GW16112, GW16113
  • GW16082 PCI interrupt mapping fixup required if using a GW16082 miniPCI expansion mezzanine
  • Using a mainline Linux kernel (not one from a Gateworks BSP) in order for the SKY2 GigE adapter used as eth1 on GW53xx / GW54xx to have its MAC address set from the value stored in the Gateworks EEPROM. Note that you can set this manually after bootup in userspace.
  • GW552x : Enabling ethernet in the bootloader for things such as flashing a new image over ethernet / TFTP.

To enable PCI in the bootloader, clear the pcidisable variable

setenv pcidisable; saveenv; reset;
  • Note, this is not the same as setting pcidisable to the value of '0'. The variable must simply be cleared.


Bootloader password

If you want U-Boot to auto-boot from bootcmd 'unless' a specific key or password is entered you can enable CONFIG_AUTOBOOT_KEYED then you can then either specify a password via the bootstopkey env variable (at runtime) or set the CONFIG_AUTOBOOT_STOP_STR for a hard-coded compile-time password. These options can be found in menuconfig under 'Command line interface -> Support U-Boot commands -> Autoboot options.

Disable Bootloader CLI

Furthermore if you want to disable the CLI completely you can disable CONFIG_CMDLINE (Command line interface -> Support U-Boot commands).

Disable Bootloader Serial Console

Additionally disabling the serial port completely is possible with a little hacking. In a pinch you can change CONFIG_MXC_UART_BASE in include/configs/gw_ventana.h to a non-used UART or otherwise consult on the U-Boot mailing list to find out how to disable the code completely.

Secure Boot

Note that the above methods are not very secure. If the user has read/write access to the boot device they can use their own software. Additionally if they have physical access to the board without too much difficulty they could use JTAG to program on their own software.

If you are looking for additional security such as allowing the IMX6 to only boot signed images you need to utilize the IMX6 High Assurance Boot.


Last modified 5 weeks ago Last modified on 05/26/17 10:15:38