Carambola2/Centipede/Lima/Rambutan boot loader (Caraboot/U-Boot) has USB boot/recovery functionality starting from version 2.0. Boot loader supports reading files from USB storage formatted with FAT32 file system and using them to boot Linux image or write to internal flash memory.
By default U-Boot will try to boot from USB storage only if 'USB boot button' is pressed for 3 seconds after system power up or reset.
Module | USB boot GPIO | USB boot button on devboard |
---|---|---|
Carambola2 | GPIO11 | S1 |
Centipede | GPIO11 | No button present |
Lima | GPIO16 | S1 |
Rambutan | GPIO18 | S2 |
After boot loader detects that USB boot is requested, it will find all USB storage devices and start searching for files named: "8dev_uimage.bin" (boot image) and "8dev_recovery.bin"(recovery image). Recovery image has priority over boot image – if both images are present, boot loader will do recovery. Search for files is done via USB storage devices (as they enumerated) and over partitions in each device (up to 15 partitions). Full device file system with no partition table is also supported.
Example: You have USB hub with SD card reader connected to module. There is SD card in hub's socket and flash drive connected to hub. SD card contains single FAT32 file system (no partition table), and have file "8dev_recovery.bin" in root folder. USB drive have two partitions: first – ext4 partition, second FAT32 partition containing "8dev_uimage.bin" file in root folder. Let's say USB drive enumerated as device0 and SD card as device1. U-Boot will try search boot files as follows:
SD card will not be checked, in this case. If USB flash stick is removed, then recovery from SD card would start after reboot.
If U-Boot does not find boot files in a USB storage or no storage is connected, it will proceed to boot from internal flash memory as usual.
When booting from USB, standard OpenWRT sysupgrade image may not work properly, since it uses internal flash memory for its root file system. It is recommended to use kernel image that has rootfs included in initramfs or mounts external partition as root file system.
When recovery image is found, it is written to flash memory at offset that depends on module's memory layout.
Module | Recovery image offset on flash | Maximum size of image |
---|---|---|
Carambola2 | 0x50000 | 16384000 bytes (0xFA0000) |
Centipede | 0x50000 | 16384000 bytes (0xFA0000) |
Lima | 0xc0000 | Dynamically detected flash size - 0xc0000 (for 32MB flash - 32768000 bytes (0x1F40000)) |
Rambutan | 0x600000 (start of ubi partition; configurable by mtdparts variable) | 122 MB (0x07a00000) |
After flashing boot loader waits 10 seconds (remove USB device with recovery image to avoid flashing again) and reboots.
USB boot functionality can be configured to suit specific needs, using U-Boot environment variables. More info on using U-Boot environment.
usbboot <mode> - boot mode (if variable does not exist will use 'gpio' mode) usbboot=force - always boot from USB regardless from GPIO value usbboot=never - never boot from USB regardless from GPIO value usbboot=gpio - boot from USB according to GPIO value (default) bootfile="filename" - file name for booting. Can include directories eg. "boot/vmlinux.uimage" (if variable does not exist “8dev_uimage.bin” default file name will be used.) recoveryfile="filename" - file name for recovery. (if variable does not exist “8dev_recovery.bin” default file name will be used.) bootdev=<device:partition> - device for booting, used to boot from specific device and partition, skipping partition scan (if variable does not exist will use automatic scan) "device" - is USB device number (starting from 0 "partition" - partition number (0 - full device) 1-16 (normal partitions)
Examples:
Enter these commands to U-Boot console:
setenv usbboot force setenv bootfile special_image.bin setenv recoveryfile special_recovery.bin setenv bootdev 1:2 saveenv
With this config U-Boot will only check second USB storage device's second partition (devices are counted from 0, so first is 0, second is 1, partitions are counted form 1). If file “special_recovery.bin” exists, recovery will start. If file “special_image.bin” exists, boot loader will boot it. If these files are not found in this partition, boot loader will boot from SPI flash.
Enter these commands to U-Boot console:
setenv usbboot never saveenv
U-Boot allows to save its configuration to a special partition called U-Boot environment. When using U-Boot console for the first time, note that it is not standard Bash shell, it lacks many functions but has power to brick your device – be very careful. For example U-Boot shell has no command history with UP key, HOME and END keys do not work (using them adds unwanted symbols to your command use CTRL+C to start over), pressing ENTER button on an empty line may repeat your last command.
To see all configuration variables type into U-Boot console:
printenv
To add new, or change existing variable type:
setenv variable_name variable_value
Note that when printing U-Boot uses equality sign: 'bootdelay=1', but when setting variable you must not use it. Use space to separate variable from its value instead. When you set variable it is only saved in memory. Save variables to flash memory using:
saveenv
You only need to saveenv once for all variables you changed.
Carambola2/Centipede/Lima U-Boot since firmware version 2.0, has an option to configure custom GPIO settings. It allows to use module with different motherboards.
Three environment variables controls GPIO settings:
More information about using U-Boot environment.
“gpio_config” variable contains a list of register addresses that need to be changed, together with two bit masks showing which bits need to be set or cleared. Address range is restricted to [0x18040000–0x18040044]
on Carambola2/Centipede and to [0x18040000–0x18040008] [0x18040014–0x18040070]
on Lima. For more information on GPIO registers refer to AR9331 data sheet.
gpio_config=ADDR:SET_MASK:CLEAR_MASK/ADDR2:SET_MASK2:CLEAR_MASK2/......(and so on) ADDR - register address (in hex) SET_MASK, CLEAR_MASK - bits to set/clear in register (in hex)
LED and button configuration are stored in C structure:
typedef struct gpio_led_desc { int id; int bit; //GPIO bit int polarity; //1 - high active; 0 - low active int disable; //1 - disable led, 0 - enable };
To use LEDs and buttons values different from default, override them with environment variables:
led_config=ID:GPIO:POLARITY:DISABLE/..(and so on) button_config=ID:GPIO:POLARITY:DISABLE/..(and so on)
ID - LED/Button ID, it may have predetermined meaning (eg. button ID1= USB boot mode jumper) (number in decimal) GPIO - which GPIO is used (number in decimal) POLARITY - active state (eg. 1= LED on/BUTTON pressed when GPIO is high) (0 or 1) DISABLE - do not use LED/BUTTON when enabled by default (0 or 1)
Default gpio/button config:
struct gpio_led_desc leds[]={ {// WLAN LED .id=0, .bit=0, .polarity=0, .disable=0}, {// ETH0_LED .id=1, .bit=13, .polarity=1, .disable=0}, {// ETH1_LED .id=2, .bit=14, .polarity=1, .disable=0}, {// Nothing .id=3, .bit=0, .polarity=0, .disable=1}, {// Nothing .id=4, .bit=0, .polarity=0, .disable=1} }; struct gpio_led_desc buttons[]={ {// USB Boot .id=0, .bit=11, .polarity=0, .disable=0}, {// Nothing .id=1,.bit=0, polarity=0, .disable=1}, {// Nothing .id=2,.bit=0, polarity=0, .disable=1}, {// Nothing .id=3,.bit=0, polarity=0, .disable=1}, {// Nothing .id=4,.bit=0, polarity=0, .disable=1}, };
Button ID=0 is reserved for USB boot selection, other button IDs do not have purpose yet. All enabled LED's are used in these boot indications:
Examples:
Since GPIO21 is configured as an input by default there is no need to change gpio_config variable, only button_config needs to be adjusted.
setenv button_config 0:21:0:0 saveenv
Explanation of parameter “0:21:0:0”: id=0 – USB boot button always has ID=0 gpio=21 – desired GPIO line polarity =0 – button will be active when GPIO input is low (depends on how button is connected) disable=0 – enables button
To turn on LEDs with GPIOs we need to configure them as outputs and set value to 1 (assuming LED's positive terminal is connected to GPIO). Output enable register is 0x18040000, where we want to set bit 20 and bit 22 = 0x500000. Then we want to set same bits in output value register (0x18040008).
setenv gpio_config 0x18040000:0x500000:0/0x18040008:0x500000:0 saveenv
There is no need to set led_config variable since we wanted only to light them up, not use them in any indications.