Skip to content

Resources

The flash layout

Here is how the Homeware flash layout typically looks like on newer ARM boards:

root@mygateway:~# cat /proc/mtd

Device Size Erasesize Name
mtd0 10000000 00020000 brcmnand.0
mtd1 02c60000 00020000 rootfs
mtd2 05920000 00020000 rootfs_data
mtd3 05000000 00020000 bank_1
mtd4 05000000 00020000 bank_2
mtd5 00020000 00020000 eripv2
mtd6 00040000 00020000 rawstorage

Apart from partition sizes and older MIPS boards where mtd2 is userfs instead, the above layout is usually always the same.
It may change for newer gateways in future.

These gateways reserve two flash partitions (bank_1 and bank_2) to store firmwares, which can be upgraded/used almost independently. The two banks contain read-only squashfs filesystem images, and that one being booted gets mounted as root /. They are digitally signed and the boot loader performs signature checking before boot, so you can't flip a single bit in the firmware image in either bank if you want to see your device booting. You may want to learn more about which bank is used by different methods of flashing firmwares and which one will be the booted bank.

The rootfs_data (formerly userfs) partition holds whatever file change (config and customized stuff) or deletion you perform on either of both firmwares. It gets formatted as JFFS2 filesystem on boot when it appears as empty. Such filesystem gets mounted into /overlay and is used for storing two folders, each named as the firmware bank it relates (i.e. /overlay/bank_1 and /overlay/bank_2). Their contents get applied on top of read-only firmwares banks as an overlay filesystem. The booted read-only image is also mounted into /rom and remains available after overlay is applied.

Hint

You can directly access /overlay folder in case you want to backup stuff or revert some change you made. Every change made to the root filesystem will immediately appear in there. Remember, original versions of modified file are permanently available from /rom, in case you would like to compare.

When a proper Reset to Factory Defaults (RTFD) is done, the overlay partition is not formatted, the only relevant /overlay/bank_* folder is deleted instead. You can learn more on such aspects by reading the Recovery page.

Devices with U-boot bootloader

Here is how the Homeware flash layout typically looks like on devices that use the U-boot bootloader:

root@CobraXh:~# cat /proc/mtd

Device Size Erasesize Name
mtd0 00200000 00040000 loader
mtd1 1fc00000 00040000 image
mtd2 00000500 0003e000 metadata1
mtd3 00000500 0003e000 metadata2
mtd4 008bd7b2 0003e000 bootfs1
mtd5 0599c000 0003e000 rootfs1
mtd6 008dc07a 0003e000 bootfs2
mtd7 0599c000 0003e000 rootfs2
mtd8 0083c000 0003e000 data
mtd9 0083c000 0003e000 defaults
mtd10 0003e000 0003e000 eripv2
mtd11 0c80c000 0003e000 rootfs_data

Firmware is stored in two partitions per bank: bootfs1 and rootfs1 are equivalent to bank_1, and bootfs2 and rootfs2 are equivalent to bank_2. The bootfs partitions contain the kernel, and the rootfs partitions contain the read-only filesystem images. The rootfs filesystems may be either UBIFS, or UBIFS within SQUASHFS filesystems, depending on the firmware version.

The rootfs_data partition is identical in use as described above, with the only difference being that it contains a UBIFS filesystem rather than JFFS2. The overlay folder and its bank_1 and bank_2 sub-folders are identical to previous usage.

It is important to note that UBIFS partitions cannot be overwritten by direct partition writing to the MTD device. They can be overwritten using the ubiupdatevol command through the associated UBI device, but this is only possible on unmounted partitions.

The boot process

There exist many versions of this bootloader stack. Here we describe one from a VBNT-O (ARMv7) board. Actual addresses or unpacking code may differ between board versions, still what you read here is quite general.

There are 4 different stages involved in the boot process:
boot0: BootROM (BTRM v1.6) - to be dumped

Boot memory is mapped to 0x80700000 with the following layout

Load Address Offset Name
0x80700000 - boot0 - BootRom (mapped from ROM)
0x80710000 0x10000 boot1-factory
0x80710000 0x20000 boot1-secure
0x00f00000 0x60000 boot2 (main loader)
- 0x80000 unknown

boot0

boot0 is a mask ROM embedded in the CPU
Its job is to initialize the system and load the next stage.
The next stage is apparently chosen depending on the secure boot state (it's unverified, tho)

  • no secure boot: boot1-factory
  • secure boot: boot1-secure

While booting the next stage, boot0 makes available the BEK and the MCV key starting from address 0x8073F000
Both the ROM and the BEK/MCV keys are wiped at the end of the boot process, and are thus inaccessible from the OS.

boot1-factory

boot1 variant that is ran only once, in factory
it's job is to burn the Market ID and the Secure Boot configuration in the CPU.
once it has ran, the system won't accept unsigned software anymore

boot1-secure

boot1 variant that is ran once secure boot has been enabled
it's signed and verified by BootROM

It can be interrupted by holding 'a' on the UART console while booting up
This allows to enter the CFE ABORT menu with the following options

  • c - continue
  • s - DDR safe mode

No other option is available

It initializes the DDR memory, decompresses boot2, verifies it, and jumps to it

boot2

boot2 is compressed with LZMA. It's decompressed by boot1 and ran at 0x00f00000
boot2 contains a factory menu that is ran in factory by sending a special DHCP/BOOTP packet while booting.
Once started, the menu awaits for commands on UDP port 11138.

DHCP packet structure

The dhcp packet must contain vendor specific options (id 43)
Encoding seems similar to rfc1048, with the addition of a header

Values in Big Endian order

Offset Size Description
0 2 Magic (0x5354 or 'ST')
2 1 Body length (without header magic)
3 * Options (rfc1048 encoding: u8 code, u8 length, ...data)

Options table (by code)
Size excludes code and size fields

Code Size Description
0x1 1 must hold the value 0xD5 for the menu to spawn
0x2 2 must hold the value 63381 (0xF795) for the menu to spawn
0x3 4 unknown

I couldn't get the menu to appear yet.
TODO: verify if the menu is accessible, or if it's locked out once out of factory

Commands available within this menu regard the device lock-down and don't seem to allow arbitrary code execution

Known commands

Command Description
I Print Device Information
N unknown
T 5 Program Chip ID and JTAG Password
T 6 Flash Factory Date
T 8 Fuse JTAG and OTP locks
T 9 Flash RIP2 image
X Exit from menu

Since boot2 is derived from CFE, it holds some of the code that would handle the CFE command line menu, and has the string "CFE>" included in the binary.
However, the code to spawn the shell seems to be removed. It's as such impossible to enter the CFE shell.

Bootloader unlocking

boot2 can be unlocked to load unsigned linux kernels. However, this requires a signed RIP_ID_UNLOCK_TAG to be present in the RIP storage. Such tag is valid only for the specific device it was issued for as it's based on some device-unique parameters such as the S/N and Chip ID, and must be issued by the platform privete keys owner (e.g. Technicolor).

Device specific parameters can be obtained from

  • /proc/efu
  • /proc/otp

JTAG unlocking

JTAG seems to be enabled by boot2 when there's no software to boot, to allow recovery of bricked devices
Unlocking JTAG is accomplished by writing 0x2 to the JTAG/OTP register 0xFFFEB614

TODO: verify if JTAG is accessible

Administering OpenWRT

From Windows

There are a number of tools such as cmder, SmarTTY, PuTTY, and WinSCP as described in the OpenWRT SSH Administration for Newcomers page.

From Linux

As a Linux user, you're supposed to know how administer another Linux machine via SSH.

Handy commands

Check firmware flashed and what is active:

  • find /proc/banktable -type f -print -exec cat {} ';'

Show processes that are running:

  • ps

Show programs that are listening as network services:

  • netstat -tuplen

Show everything that's listening on sockets (TCP, UPD, Unix etc):

  • netstat -lenp

Free (NAND) space:

  • df -h

Dump entire config (~7700+ lines to console):

  • uci show

Example to filter lines with password:

  • uci show | grep password

Access logs for most services (which use syslog):

  • logread -f

Access logs for most services (which use syslog). Pass an argument of -e nginx to match log entries just related to Nginx, which is perfect for debugging errors in the Web GUI. Pass an argument of -e nginx to match log entries just related to Nginx, which is perfect for debugging errors in the Web GUI. Remove -f flag for all time logs (erased every reboot).

Display status of all init.d scripts:

  • for F in /etc/init.d/* ; do $F enabled && echo $F on || echo $F **disabled**; done

Switch active bank and reboot - UNSAFE:

  • /rom/usr/lib/cwmpd/transfers/switchover.sh

Set bank_1 as active, replace with bank_2 for the opposite:

  • echo bank_1 > /proc/banktable/active

OpenWrt Release metadata:

  • cat /etc/openwrt_release

eg, from VANT-F:

DISTRIB_ID='OpenWrt'
DISTRIB_RELEASE='Chaos Calmer'
DISTRIB_REVISION='r46610'
DISTRIB_CODENAME='chaos_calmer'
DISTRIB_TARGET='brcm63xx-tch/VANTF'
DISTRIB_DESCRIPTION='OpenWrt Chaos Calmer 15.05.1'
DISTRIB_TAINTS='no-all busybox'

Notable files

Lua/HTML Web Interface source files:

  • /www/*

UCI config source files, pehaps more readable than uci show:

  • /etc/config/*

Various executables, many custom-written for this hardware:

  • /sbin/*.sh, /usr/bin/*.sh, /usr/sbin/*.sh

Services present; May or may not be enabled or running:

  • /etc/init.d/*

Different methods of flashing firmware's

Depending on the situation, you are usually asked to perform firmware flashing in different ways. Here is a short summary of them and some background details to better understand the big picture.

You can get a firmware image flashed by using one of the following modes:

Mode Pros Cons
Bootloader Recovery Always available unless bootloader has been nuked No Bank switch occurs
Direct Partition Writing Can use bank dumps as well as RBI's No Bank switch occurs and the process requires root access
Sysupgrade Command Bank switch occurs and so does a basic factory reset Process requires root access

Mode step outline

Bootloader recovery

  • Loads RBI firmware images using BOOTP flashing.
  • The firmware is transferred to the gateway via TFTP from your PC.
  • RBI file is decrypted, unpacked and, if signature check passed, flashed into the bank_1 partition then marked as correctly flashed.

Direct partition writing

Devices that use ubifs filesystems

Devices that have ubifs filesystems (instead of the more common jffs2 filesystems) cannot use direct partition writing to modify the active bank. The ubifs file system cannot be written whilst mounted.

  • The firmware is usually transferred to the gateway temp filesystem via SSH/SCP or USB drive.
  • The firmware image is directly written to the bank you specify on the command line.
  • This flashing method requires root access to a booted firmware.

Sysupgrade

  • The firmware is transferred to the gateway in various ways (WebUI, CWMP, SSH/SCP, USB, ...).
  • RBI firmware is decrypted, unpacked, validated, simultaneously signature checked and flashed into the inactive bank partition and marked as correctly flashed.
  • If all checks pass, a switchover is done, which means the active bank is switched and some operations on config like validation and migration is attempted.
  • This flashing method is suited for firmware upgrades only, may not allow or correctly handle downgrades.
  • This flashing method availability depends on a lot of different things, including firmware version and ISP's customisation, of course it requires a working booted firmware and it's always available if you have root access.
  • Sysupgrade scripts are based on the original OpenWrt implementation with RBI, dual-bank, and switchover support implemented by Technicolor.
  • Sysupgrade and switchover scripts may have been patched by a custom mod you installed to behave differently.
  • AutoFlashGUI exploits this flashing method.

Decrypting RBI firmware

RBI files usually contains encrypted BLI images. You can easily decrypt them using Decrypt_RBI_Firmware_Utility on any platform (Java Required). If you cannot find your OSCK and your device is rooted, then extract it and share it. See secr tools for further details about keys usage and extraction.

Checking RBI firmware signature

RBI files are digitally signed by OSIK, which is the public portion of an asymmetric key. This means if you flip a single bit of your RBI file it will be detected as invalid, and won't get flashed. For instance, editing the board name inside an RBI file header to match that one of your board will cause signcheck to fail. Nothing bad happens if you try flashing a bad one, it will simply get refused. Keep in mind that RBI signcheck against OSIK happens before RBI decryption through OSCK. OSIK is the same across multiple board models, but OSCK is different for each one. You can also check by yourself wether an RBI file integrity is compromised or not according to the OSIK for your device. You can do this from your rooted gateway, or from your PC, for any available firmware with known OSIK.

From the router, just run:

signature_checker -b /tmp/firmware_to_check.rbi [-k /tmp/other_board_to_check.osik]

From your PC (requires: linux/WSL, binwalk and qemu-static), decrypt any available RBI for any board (not necessarily that one you are going to check), then run:

binwalk -e any_decrypted_firmware.bin
mv firmware_to_check.rbi pubkey_to_check.osik _any_decrypted_firmware.bin.extracted/squashfs-root/tmp/
cd _any_decrypted_firmware.bin.extracted/squashfs-root
cp $(which qemu-arm-static) .
sudo chroot . ./qemu-arm-static /usr/bin/signature_checker -b /tmp/firmware_to_check.rbi -k /tmp/pubkey_to_check.osik

If it doesn't print Signature incorrect, then the image is good. You can double check everything is actually working by altering some bytes inside the RBI you are checking, then repeat the check: this time it will report the signature is incorrect.

Backup/restore bit-for-bit dumps

This guide will show you how to dump a bit-for-bit clone of any partition and reflash it.

Decrypted RBI v.s. bank dumps

Decrypted RBI firmwares are the same as bank_1 or bank_2 dumps except for their first four bytes. A correctly decrypted RBI starts with a sequence of four 0xFF. You can edit these bytes to 0x00 and use the resulting file as a bank dump to be restored.

Devices that use ubifs filesystems

You cannot use these commands on partitions that contain ubifs filesystems.

Making dumps

bank_1 is usually mapped to the mtd3 partition and bank_2 is usually mapped to mtd4, you do not really need to backup firmware banks if you already have an RBI file for that same firmware available.

If you are not sure you already have the same firmware saved somewhere, you can extract the RBI file, mark the first 4 bytes of the resulting binary to 0x00 and compare its checksum against output of md5sum /dev/mtd* (this may take a while to compute, be patient).

You definitely need instead to backup all other partitions, especially the eripv2 one, and all the others. You can get the full partition list with cat /proc/mtd

It is good practice to keep moving dumped partitions out of the gateway memory as soon as you complete one in order to minimise the chance of filling the ram, and causing an out-of-memory crash and reboot. Here we show how to do that by using an USB drive attached to the gateway. Alternatively, you can also move them out using SCP in case your device has no USB ports or you don0t have an USB drive available.

  1. If you are going to usa an USB drive, you will need to know its mountpoint. Plug it in and run: ls -la /mnt/usb

    • Take note of that path the arrow is pointing to. Example output:
root@mygateway:~# ls -la /mnt/usb/
drwxr-xr-x    2 root     root     0 Jan 16 12:31 .
drwxrwxrwx    1 root     root     0 Jan 16 10:55 ..
lrwxrwxrwx    1 root     root     0 Jan 16 12:31 USB-A1 -> /tmp/run/mountd/sda1
  1. To backup a partition, run: dd if=/dev/mtd<X> of=/tmp/mtd<X>.dump.

    • Replace <X> with any block device number.
  2. Move the dumped partition into USB drive by running: mv /tmp/mtd<X>.dump /tmp/run/mountd/<usb-path>/.

    • Replace <usb-path> with your USB drive, see Step 1. In the example the USB path name is sda1.
  3. Make sure to compare checksums of dumped bank_1, bank_2 and eripv2 partitions to ensure the dump is a 1:1 exact copy.

    • Other partitions include flash portions which are currently mounted with enabled write access, their checksums are constantly changing
  4. Repeat from Step 2 for every partition you would like to dump.

Restoring dumps

To restore a partition dump, run: mtd write /mnt/usb/<usb-path>/mtd<X>.dump <partition_name>

  • Replace <usb-path> with your USB drive path

  • Replace <X> with the block number

  • Replace <partition_name> with the partition name you want to flash to (names are shown in /proc/mtd too)

Raw firmware dumps (which are not RBI files) are flashed this way to matching devices.

Backing up configuration

Your a Super Modder. You flash your Gateway on a daily basis.

Backing up your current state it's all about backing up overlay contents. Keep in mind that copying overlay folder's content is not as effective as a bit-for-bit overlay partition (mtd2) backup: you will loose any deletion or renaming. However this is good enough in most cases.

Use the command below to manually create an archive with all your modified files from both firmware banks:

tar -C /overlay -cz -f /tmp/overlay-files-backup-$(date -I).tar.gz bank_1 bank_2

If you prefer, you can rely on sysupgrade to achieve a similar result for the booted bank only.

To save the Config:

sysupgrade -i -b /tmp/sysupgrade-backup-$(date -I).tar.gz

To restore the Config:

sysupgrade -f /tmp/sysupgrade-backup-*.tar.gz

Copy a new file to /www/docroot/img/logo.gif – will be updated next time page is displayed.
technicolor.gif

LED management

Directly accessing /sys/class/leds is a BAD practice...

List available LEDs:

  • ls -1 /sys/class/leds/

Show LED triggers available and the current trigger.

  • cat /sys/class/leds/<led>:<colour>/trigger

Replace LED with the name of the LED and colour with the colour:

  • eg. cat /sys/class/leds/dect:green/trigger

Reset LED trigger to default:

  • echo "default-on" > /sys/class/leds/power:green/trigger

List all LED packages used:

  • opkg list | grep led

Examples:

Turn on LED:

echo 1 > /sys/class/leds/power:green/brightness

Turn off LED:

echo 0 > /sys/class/leds/power:red/brightness

IPv6 issues

IPv6 is problematic in older Homeware builds since Chaos Calmer had broken IPv6 Support. It also depends on the ISP's configuration. See more.

BusyBox (ash)

The gateway runs BusyBox as it's terminal emulator, designed for Embedded Linux systems.

root@mygateway:~# busybox --help
BusyBox v1.23.2 (2017-08-22 01:34:50 UTC) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2012.
Licensed under GPLv2. See source distribution for detailed
copyright notices.

Usage: busybox function arguments...
   or: busybox --list
   or: function arguments...

        BusyBox is a multi-call binary that combines many common Unix
        utilities into a single executable.  Most people will create a
        link to busybox for each function they wish to use and BusyBox
        will act like whatever it was invoked as.

Currently defined functions:
        , , addgroup, arping, ash, awk, base64, basename, bunzip2, bzcat,
        cat, chgrp, chmod, chown, chpasswd, chroot, chrt, clear, cmp, cp,
        crond, crontab, cut, date, dd, df, dirname, dmesg, du, echo, egrep,
        env, expr, false, fgrep, find, free, fsync, grep, gunzip, gzip, halt,
        head, hexdump, hostid, hwclock, id, ifconfig, insmod, kill, killall,
        less, ln, lock, logger, login, ls, lsmod, lsusb, md5sum, mkdir, mkfifo,
        mknod, mktemp, mount, mv, nc, netmsg, netstat, nice, nslookup, ntpd,
        passwd, pgrep, pidof, ping, ping6, pivot_root, poweroff, printf, ps,
        pwd, readlink, reboot, reset, rm, rmdir, rmmod, route, sed, seq, sh,
        sha256sum, sleep, sort, start-stop-daemon, strings, switch_root, sync,
        sysctl, tail, tar, taskset, tee, telnet, test, time, timeout, top,
        touch, tr, traceroute, traceroute6, true, udhcpd, umount, uname, uniq,
        uptime, vconfig, vi, wc, wget, which, xargs, yes, zcat

BusyBox (ash) scripting

In practical terms it can be thought of as a stripped down version of bash, so write bash script and fix the errors for features not supported.

A basic ash Guide

Lua

All of the web interface and some of the daemons are written in Lua.

lua -v
Lua 5.1.5  Copyright (C) 1994-2012 Lua.org, PUC-Rio (double int32)

Lua 5.1 Reference
Lua Tutorial - Tutorialspoint