Firmware images and firmware updates

Firmware update images

A firmware update image is nothing more than a standard U-boot uImage file with a kernel and an embedded root filesystem.  An example of a firmware update image can be found here.

There is nothing additional in a firmware update image – no signature, encryption, etc.  Just a simple uImage file.

The mkimage utility (from the uboot-tools package) shows the following for the firmware image (U-boot uImage) referenced above:

$ mkimage -l A356_upgrade_00.10.011_20170221.img 
Image Name: Imogen-X860-I
Created: Tue Feb 21 00:42:01 2017
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 6712048 Bytes = 6554.73 kB = 6.40 MB
Load Address: 80008000
Entry Point: 80008000
$

The U-boot uImage file has a 64-byte header, which looks like the following:

$ hexdump -Cv -n 64 A356_upgrade_00.10.011_20170221.img|cut -c-58
00000000 27 05 19 56 9e 83 37 37 58 ab d3 29 00 66 6a f0
00000010 80 00 80 00 80 00 80 00 a1 48 48 d8 05 02 02 00
00000020 49 6d 6f 67 65 6e 2d 58 38 36 30 2d 49 00 00 00
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Immediately after the 64-byte uImage header is the kernel.  The kernel itself is XZ-compressed, so has a small program prepended to it which can decompress the kernel image and start the kernel.

The kernel has an embedded root filesystem (initramfs) which was linked-into the kernel at build time.  The initramfs is a cpio archive, which itself has also been XZ compressed and stored inside the kernel.

Two copies of the firmware (kernel)

As I mentioned in my previous post, there are two separate mtd partitions in the SPI flash used for firmware/kernel images – one is called “kernel0” (in mtd3), the other is “kernel1” (in mtd4).

One of the kernel partitions is “active” (the one that is running), and the other is “inactive”.  When a new firmware update image is installed, it is copied to the “inactive” mtd partition, then it is marked as the “active” image.  On the next boot, u-boot will load the new “active” image and run it.

Identifying active vs inactive kernel images

The last 4-bytes of the 64-byte uImage header are used as a ‘counter/version’.  The kernel image with the largest counter value is the ‘active’ partition.

As an example, here are hexdumps showing the first 64-bytes of my StuartCam’s current “kernel0” (mtd3) and “kernel1” (mtd4) partitions.

# dump kernel0/mtd3 header
$ hexdump -Cv -n 64 /dev/mtd3|cut -c-58
00000000 27 05 19 56 07 8a 66 8d 58 ab d3 29 00 66 6a f0
00000010 80 00 80 00 80 00 80 00 a1 48 48 d8 05 02 02 00
00000020 49 6d 6f 67 65 6e 2d 58 38 36 30 2d 49 00 00 00
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03

# dump kernel1/mtd4 header
$ hexdump -Cv -n 64 /dev/mtd4|cut -c-58
00000000 27 05 19 56 28 8b 40 5b 58 f7 ff 6b 00 66 6a f0
00000010 80 00 80 00 80 00 80 00 e1 59 88 12 05 02 02 00
00000020 49 6d 6f 67 65 6e 2d 58 38 36 30 2d 49 00 00 00
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04

Note that the last 4 bytes of “kernel0” are “00 00 00 03” (counter = 0x00000003) and the last 4 bytes of “kernel1” are “00 00 00 04” (counter = 0x00000004).  Since “kernel1” has a larger counter than “kernel0”, “kernel1” is the ‘active’ partition.

When U-boot starts up (on power-cycle or reboot), it looks at both headers.  In the above example, U-boot will choose to load/run “kernel1”, since it is the ‘active’ parition.

When a new firmware update image is installed, using the above example, it will choose to write the new firmware to the “kernel0” partition (since it is ‘inactive’).  Once the firmware is fully written, the firmware update process will write a new “counter” value to the last 4 bytes of the 64-byte header.  This counter value will be one larger than the currently active partition’s counter value.

So, the next update on this StuartCam will be written to “kernel0”, and the new counter value will be “00 00 00 05” (counter = 0x00000005). On next boot, U-boot will see this as the largest counter, and will boot it instead.

2 thoughts on “Firmware images and firmware updates”

  1. connect it up when its setup i want to find out if it can be access with a nvr either http or rtsp

  2. i’ve not been able to make it work with rtsp or http unfortunately. this was the purpose of my hacking endeavor in the first place – to not have to use their ****y mobile app!

Leave a Reply to Justin Cancel reply

Your email address will not be published. Required fields are marked *