If you like BoxMatrix then please contribute Supportdata, Supportdata2, Firmware and/or Hardware (get in touch).
My metamonk@yahoo.com is not reachable by me since september. Please use hippie2000@webnmail.de instead.

FIT-Image

From BoxMatrix

BoxMatrix >> Development >> FIT-Image @ BoxMatrix   -   IRC-Chat   -   Translate: de es fr it nl pl
News Selectors Models Accessories Components Environment Config Commands System Webif Software Develop Lexicon Community Project Gallery

Tarballs FW-Probes FW-History FW-News Supportdata Hardware SVN Trac Freetz-News Freetz-Timeline Freetz-Releases Freetz-Mirror OpenWRT Research

FIT-Image[edit]

Introduction[edit]

This project has been terminned since there is no way to deilver clean and horribly tested code to freetz.ng.
I did not expect code censoring otherwise I would have stopped this many releases before.
I worked 1.5 years on this and I was fooled and my work was ripped out of my hands. Legglaly.
It was my mistake to trust. And i got punished for my work. Nothhing new and not the first time.
PLEASE WE NEED A NEW FORK TO PREVENT A SINGLE PERSON FROM RERDUCING AND CENSORING CODE QUALITY!

Some new models do not contain kernel.image and filesystem.image in their firmware image any more but use a new fit-image instead.

FIT stands for Flattened Image Tree and is a container which can store multiple kernels, filesystems and device trees and metadata about these. FIT is also supported by the Uboot bootloader[1], but AVM uses an own derivative of the format, which so far has been a blackbox.

After analyzing the format I coded fitimg which permits to list, test, extract and recompose fit-image files.

Initally intended to just extract fit-images for the BoxMatrix Firmware-Scanner the Replace command opens the door to modifications of the Fritzbox 4060, 5530, 5590, 7510, 7530ax and Repeater 1200ax and 6000 models. Latest Recovery.exe scans showed there *may be* more models to switch over to fit-images. Recoveries for more than 30 models already contain the necessary put-fitimage code.

FIT-Models[edit]

The FIT format is used for 8 recent WLAN AX capable models.
The SoCs used Hawkeye, Maple and BCM63 are all ARM Cortex based, the Falcon is MIPS / Interaptiv based.

S
Model
Languages, Brandings
Internet
[Annex]
LAN
Ports
WLAN
802.11
PSTN
Lines
Phones SoC
Clock
RAM Flash USB
Host
Image
ok
sold
FRITZ!Box 4060
de, en, es, fr, it, nl, pl
avm, avme
USB-LTE LAN
WLAN
Gbit: 3
2.5G: 1
2,400 Mb
+2,400 Mb
+1,200 Mb
2.4GHz
5GHz
Wi-Fi 6
- DECT: 6
Hawkeye
2000 MHz
1,024 MB 4,096 MB Ports: 1
USB: 3.0
FRITZ!Box 4060-Image1.jpg
ok
sold
FRITZ!Box 5530 Fiber
de, en, es, fr, it, nl, pl
1und1, avm, avme
SFP
WLAN
Gbit: 2
2.5G: 1
2,400 Mb
+600 Mb
2.4GHz
5GHz
Wi-Fi 6
- Analog: 1
DECT: 6
Falcon PRX321
800 MHz
1,024 MB 128 MB
- FRITZ!Box 5530-Image1.jpg
ok
sold
FRITZ!Box 5590 Fiber
de, en, es, fr, it, nl, pl
1und1, avm, avme
SFP
USB-LTE WLAN
Gbit: 4
2.5G: 1
2,400 Mb
+1,200 Mb
2.4GHz
5GHz
Wi-Fi 6
- Analog: 2
DECT: 6
Hawkeye
2000 MHz
Falcon PRX321
800 MHz
1,536 MB 4,096 MB Ports: 1
USB: 3.0
FRITZ!Box 5590 Fiber-Image1.jpg
ok
sold
FRITZ!Box 7510
de, en, es, fr, it, nl, pl
1und1, avm, avme
SVect
B, J, A, M
USB-LTE WLAN
Gbit: 1
600 Mb
2.4GHz
Wi-Fi 6
- Analog: 1
DECT: 6
Maple IH216
1000 MHz
512 MB 128 MB Ports: 1
USB: 2.0
FRITZ!Box 7510-Image1.jpg
ok
sold
FRITZ!Box 7530 AX
de, en, es, fr, it, nl, pl
1und1, avm, avme
SVect
A, B, J, M
USB-LTE WLAN
Gbit: 4
1,800 Mb
+600 Mb
2.4GHz
5GHz
Wi-Fi 6
- Analog: 1
DECT: 6
BCM63
1500 MHz
512 MB 128 MB Ports: 1
USB: 2.0
FRITZ!Box 7530 AX-Image1.jpg
ok
sold
FRITZ!Repeater 1200 AX
de, en, es, fr, it, nl, pl
avm, avme
LAN
WLAN
Gbit: 1
2,400 Mb
+600 Mb
2.4GHz
5GHz
Wi-Fi 6
- - Maple IH214
1200 MHz
256 MB 256 MB
- FRITZ!Repeater 1200 AX-Image1.jpg
todo FRITZ!Repeater 3000 AX
de, en, es, fr, it, nl, pl
avm, avme
LAN
WLAN
Gbit: 2
2,400 Mb
+2,400 Mb
+600 Mb
2.4GHz
5GHz
Wi-Fi 6
- - Maple IH216
1000 MHz
512 MB 128 MB - -
ok
sold
FRITZ!Repeater 6000
de, en, es, fr, it, nl, pl
avm, avme
LAN
WLAN
Gbit: 1
2.5G: 1
2,400 Mb
+2,400 Mb
+1,200 Mb
2.4GHz
5GHz
Wi-Fi 6
- - Hawkeye
2000 MHz
1,024 MB 4,096 MB - FRITZ!Repeater 6000-Image1.jpg

Freetz-Status[edit]

fitimg was included in freetz-ng, and so far all 7 FIT models on the market were tested, the 3000ax is not sold yet.

Daily updated index of all freetz-ng supported FIT models. Last update: 2022-07-05 07:00 GMT.
The status "untested" shows noone tested the respective model *successfully* so far.

Legend:   ok = maintained   -   eos = unmaintained

Download[edit]

The public version of fitimg is discontinued due to permanent man-in-the-middle rape of my work.
Development will continue as a BoxMatrix internal tool for the firmware scanner, what it initially was.
You will still benefit from the research results here and there are a lot of plans for deeper inspection of FIT.
After 10 releases which always have been downgraded by patches I give up on trying to contribute clean
and well tested work to Freetz-ng.None of these patches ever fixed a bug, all bugs always were fixed by me,
usually at the day of their report. All versions have been tested to work with latest freetz before release.
All patches so far were chicane, and always broke the manual and the planned functionality, or even features.
There's no point in feeding this dirty game further. This project got censored to death.

The last and final PUBLIC version of fitimg could be found here: See the Known bugs for workarounds!

Sabotage[edit]

Attention: If you plan to use fitimg in projects install the unaltered original yourself.
Freetz-ng messes the logic, behaviour and return code system with a complete nonsense patch:
https://github.com/Freetz-NG/freetz-ng/tree/master/tools/make/fitimg-host/patches - a patch for the sake of patching.
I wonder why grep code is not raped to this quick and dirty personal preference hack without thinking of consequences.
It would be the same stupid stuff and it would render numerous scripts broken. FRITZ!OS would surely fail to boot.
1.5 years of fitimg code evolution, messed up in seconds. This is ok since this is free software, just remember this note,
before you blame my code. I can not care of such a code breaking patch in future development.
It already breaks logic and well thought intention and it will surely fsck up planned future features.
Use the original if you want to benefit from my unmessed code intention and quality.
Thankfully at least grep has a chance to survive with its intended functionality.
fitimg has no chance to ever get a mature project with such an intentional sabotage.
This is a perfect approval of a sickness to spit at other people's work!

Here is how you can test for the damaged version. The original released by me responds this with no arguments:

me@boxmatrix:~$ fitimg

### fitimg ### - nothing to do - you need to pass one of -l -t -x -r -s or -h
See 'fitimg --help'

For comparison grep - same functionality but survives the Freetz-ng software quality degrading thurst.

me@boxmatrix:~$ grep

Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.

The damaged version of fitimg prints the help function and defeats an error message, with many side effects.
Now I have to waste time coding a sanity check against such stupid code messups in future versions.
Time which should better be used for improving the project, instead of defending it against arrogance and / or stupidity.

To everyone: fitimg is free software, reuse it by the terms of the GPLv2+. But if you intentionally modify it to incompatiblity
to the intended and documented original then:
Please at least be so fair to rename my long lasting work and add some change info and add
your copyright to it instead of redistributing an intentionally broken version under my name!

Requirements[edit]

  • Perl 5.6 or newer and the modules Getopt::Std (comes with Perl[2]) and String::CRC32
  • If you get an error Can't locate String/CRC32.pm ... install this module from CPAN (no need to be root, works for all systems):
cpan install String::CRC32
  • Depending on your system you can also install as root by one of these methods:
apt-get install libstring-crc32-perl
yum install perl-String-CRC32

Optional but highly recommended: (fitimg 0.8+)

To get correct results from the list command's -m option fitimg needs to decrompress lzma kernels on the fly.
A compressed lzma stream does not contain any information about its original size, it must be decompressed.
If not present yet the required module needs to be compiled and installed as root.

apt-get install liblzma-dev        # likely already installed for freetz
cpan install Compress::Raw::Lzma   # does a lot of compilations and sanity checks but ends in OK
  • Depending on your system you can also install as root by one of these methods:
apt-get install libcompress-raw-lzma-perl
yum install perl-Compress-Raw-Lzma

Usage[edit]

Here a list of fitimg commands and options, including some usage examples:

List[edit]

The list command -l shows the memory region, size and name of each file in the fit-image.

Usage:

  fitimg -l <infile> [-i] [-f] [-e] [-k] [-m] [-q]

    List all binaries contained in fit-image <infile>, including their load addresses.

    Option -i (inner) processes the inner image for nested fit-image files.  (fitimg 0.7.2+)
    Option -f (freetz names) uses filesystem/kernel.image etc instead of the stored names.
    Option -e (extension) lists a .fit file extension for inner fit images.  (fitimg 0.7.2+)
    Option -k (kernel args) also lists memory regions specified in kernel args.  (fitimg 0.8+)
    Option -m (maximum) also list the max. size of regions where limits apply.  (fitimg 0.8+)
    Option -q (quiet) could be used to silently test the image structure.

List using stored names:

$ fitimg -l 6000.fit
41208000-41527046  3272774 qcaarmv8_HW253_kernel
41c30000-41c33cdd    15581 qcaarmv8_HW253_flat_dt_0
41c30000-41c33d0e    15630 qcaarmv8_HW253_flat_dt_2
43000000-44000000 16777216 qcaarmv8_HW253_squashFS_filesystem

List using freetz names:

$ fitimg -l 6000.fit -f
41208000-41527046  3272774 kernel.image
41c30000-41c33cdd    15581 flatdt_0.image
41c30000-41c33d0e    15630 flatdt_2.image
43000000-44000000 16777216 filesystem.image

Listings of all models can be found in the Research section below.

Test[edit]

The test command -t lists and validates the stored and computed CRC32 checksums of each file in the fit-image.

Usage:

  fitimg -t <infile> [-i] [-f] [-e] [-q]

    Test the integrity of all binaries in fit-image <infile>. Performs CRC32 validation.

    Option -i (inner) processes the inner image for nested fit-image files.  (fitimg 0.7.2+)
    Option -f (freetz names) uses filesystem/kernel.image etc instead of the stored names.
    Option -e (extension) lists a .fit file extension for inner fit images.  (fitimg 0.7.2+)
    Option -q (quiet) could be used to silently test the image structure and checksum integrity.

Test using stored names:

$ fitimg -t 5530.fit
OK: b4761fdd b4761fdd  1191017 prxB_HW0257_kernel
OK: 3c53ca34 3c53ca34     1092 prxB_HW0257_flat_dt_0
OK: 0ef19ad8 0ef19ad8  1700705 prxB_HW0257_ramdisk
OK: aa110233 aa110233  3282652 prxI_HW257_kernel
OK: cf9e37b4 cf9e37b4     7917 prxI_HW257_flat_dt_0_aon
OK: b9298e1b b9298e1b     7884 prxI_HW257_flat_dt_0_pon
OK: 9b59e2d4 9b59e2d4 35458093 prxI_HW257_ramdisk
no errors in 7 files

Test using freetz names:

$ fitimg -t 5530.fit -f
OK: b4761fdd b4761fdd  1191017 kernel2.image
OK: 3c53ca34 3c53ca34     1092 flatdt2_0.image
OK: 0ef19ad8 0ef19ad8  1700705 filesystem2.image
OK: aa110233 aa110233  3282652 kernel.image
OK: cf9e37b4 cf9e37b4     7917 flatdt_0_aon.image
OK: b9298e1b b9298e1b     7884 flatdt_0_pon.image
OK: 9b59e2d4 9b59e2d4 35458093 filesystem.image
no errors in 7 files

Extract[edit]

The extract command -x extracts files from the fit-image.

Usage:

  fitimg -x <infile> [-d <dir>] [-i] [-n] [-f] [-e] [-u] [-q]
 
    Extract all contents of fit-image <infile> to current directory or <dir>.

    Option -i (inner) processes the inner image for nested fit-image files.  (fitimg 0.7.2+)
    Option -n (no flatdt/tz) suppresses extracting device tree and TrustZone files.
    Option -f (freetz names) uses filesystem/kernel.image etc instead of the stored names.
    Option -e (extension) adds a .fit file extension for inner fit images.  (fitimg 0.7.2+)
    Ootion -u (utime) uses the datestamp of <infile> for extracted files  (fitimg 0.8+)
    Option -q (quiet) suppresses listing which files were extracted.

Extract using stored names:

$ fitimg -x 5530.fit -d temp 
OK: b4761fdd b4761fdd  1191017 prxB_HW0257_kernel
OK: 3c53ca34 3c53ca34     1092 prxB_HW0257_flat_dt_0
OK: 0ef19ad8 0ef19ad8  1700705 prxB_HW0257_ramdisk
OK: aa110233 aa110233  3282652 prxI_HW257_kernel
OK: cf9e37b4 cf9e37b4     7917 prxI_HW257_flat_dt_0_aon
OK: b9298e1b b9298e1b     7884 prxI_HW257_flat_dt_0_pon
OK: 9b59e2d4 9b59e2d4 35458093 prxI_HW257_ramdisk
extracted 7 files

Extract using freetz names:

$ fitimg -x 5530.fit -d temp -f
OK: b4761fdd b4761fdd  1191017 kernel2.image
OK: 3c53ca34 3c53ca34     1092 flatdt2_0.image
OK: 0ef19ad8 0ef19ad8  1700705 filesystem2.image
OK: aa110233 aa110233  3282652 kernel.image
OK: cf9e37b4 cf9e37b4     7917 flatdt_0_aon.image
OK: b9298e1b b9298e1b     7884 flatdt_0_pon.image
OK: 9b59e2d4 9b59e2d4 35458093 filesystem.image
extracted 7 files

Extract using freetz names, no device tree files:

$ fitimg -x 5530.fit -d temp -n -f
OK: b4761fdd b4761fdd  1191017 kernel2.image
OK: 0ef19ad8 0ef19ad8  1700705 filesystem2.image
OK: aa110233 aa110233  3282652 kernel.image
OK: 9b59e2d4 9b59e2d4 35458093 filesystem.image
extracted 4 files

Replace[edit]

The replace command -r creates a new image from the fit-image, replacing files in it.

Usage:

  fitimg -r <infile> -o <outfile> [-d <dir>] [-i] [-f] [-e] [-p <num>] [-q]

    Replace all contents of fit-image <infile> which exist in current dir or <dir> and write
    it to <outfile>, which may be "-" (stdout) in which case -q mode is forced. (fitimg 0.8+)
    Files which do not exist in current directory or <dir> will not be replaced.

    Option -i (inner) processes the inner image for nested fit-image files.  (fitimg 0.7.2+)
    Option -f (freetz names) uses filesystem/kernel.image etc instead of the stored names.
    Option -e (extension) prefers a .fit file over one without extension.  (fitimg 0.7.2+)
    Options -f and -e are just an abstraction, the fit-image always stores the original names.
    Option -p (padding) ovverrides the default padding size of 64 (0 - 1024) in kB  (fitimg 0.5+)
    Option -q (quiet) suppresses listing which files were replaced.

Replacing with the original files extracted above:
Note that starting with fitimg 0.5 you need to pass -p 0 for the md5 test.

$ fitimg -r 5530.fit -o temp/5530.fit -d temp -f
Replacing:  1191017-> 1191017 kernel2.image
Replacing:     1092->    1092 flatdt2_0.image
Replacing:  1700705-> 1700705 filesystem2.image
Replacing:  3282652-> 3282652 kernel.image
Replacing:     7917->    7917 flatdt_0_aon.image
Replacing:     7884->    7884 flatdt_0_pon.image
Replacing: 35458093->35458093 filesystem.image
replaced 7 files

$ md5sum 5530.fit temp/5530.fit
91952d629306e88791399a868c4491d9  5530.fit
91952d629306e88791399a868c4491d9  temp/5530.fit

Replacing with a modified filesystem.image:
Note that starting with fitimg 0.5 you need to pass -p 0 for the md5 test.

$ dd if=/dev/zero of=temp/filesystem.image bs=1024 count=16
16+0 records in
16+0 records out
16384 bytes (16 kB) copied, 0.0249391 s, 657 kB/s

$ fitimg -r 5530.fit -o temp/5530.fit -d temp -f
Replacing:  1191017-> 1191017 kernel2.image
Replacing:     1092->    1092 flatdt2_0.image
Replacing:  1700705-> 1700705 filesystem2.image
Replacing:  3282652-> 3282652 kernel.image
Replacing:     7917->    7917 flatdt_0_aon.image
Replacing:     7884->    7884 flatdt_0_pon.image
Replacing: 35458093->   16384 filesystem.image
replaced 7 files

$ md5sum 5530.fit temp/5530.fit
91952d629306e88791399a868c4491d9  5530.fit
4dfbe2a3f91037e7fed4832a93ef814c  temp/5530.fit

$ fitimg -l temp/5530.fit -f
88000000-88122c69  1191017 kernel2.image
884e2000-884e2444     1092 flatdt2_0.image
8b000000-8b19f361  1700705 filesystem2.image
70000000-703216dc  3282652 kernel.image
70fe4000-70fe5eed     7917 flatdt_0_aon.image
70fe4000-70fe5ecc     7884 flatdt_0_pon.image
90000000-90004000    16384 filesystem.image

$ fitimg -t temp/5530.fit -f
OK: b4761fdd b4761fdd  1191017 kernel2.image
OK: 3c53ca34 3c53ca34     1092 flatdt2_0.image
OK: 0ef19ad8 0ef19ad8  1700705 filesystem2.image
OK: aa110233 aa110233  3282652 kernel.image
OK: cf9e37b4 cf9e37b4     7917 flatdt_0_aon.image
OK: b9298e1b b9298e1b     7884 flatdt_0_pon.image
OK: ab54d286 ab54d286    16384 filesystem.image
no errors in 7 files

Copy[edit]

The copy command -c creates a new unaltered image from the fit-image and tests it. (fitimg 0.2+)
This is mainly useful to extract and validate a fit-image from a Recovery.exe or firmware.image,,
to add padding to an image, or to extract an inner fit-image from a nested FIT using the -i option.

Usage:

  fitimg -c <infile> -o <outfile> [-i] [-f] [-e] [-p <num>] [-u] [-q]

    Copy an unaltered fit-image from <infile> to <outfile> while testing its integrity.
    <outfile> may be "-" (stdout) in which case quiet mode is forced. (fitimg 0.8+)
    This is mainly useful to extract and validate a fit-image from a recovery.exe or
    firmware.image, or to copy the inner image for nested fit-image files.

    Option -i (inner) processes the inner image for nested fit-image files.  (fitimg 0.7.2+)
    Option -f (freetz names) lists filesystem/kernel.image etc instead of the stored names.
    Option -e (extension) lists a .fit file extension for inner fit images.  (fitimg 0.7.2+)
    Options -f and -e are just an abstraction, the fit-image always stores the original names.
    Option -p (padding) ovverrides the default padding size of 64 (0 - 1024) in kB  (fitimg 0.5+)
    Ootion -u (utime) uses the datestamp of <infile> for the copied file.  (fitimg 0.8+)
    Option -q (quiet) suppresses listing which files were copied and tested.

Copy and test a fit-image file:
Note that starting with fitimg 0.5 you need to pass -p 0 for the md5 test.

$ fitimg -c 7530ax.fit -o temp/7530ax.fit -f
OK: f653ffe8 f653ffe8   192275 kernel2.image
OK: 2040d9dd 2040d9dd      599 flatdt2_0.image
OK: 34ac9b5e 34ac9b5e  2671938 kernel.image
OK: 5edb6c64 5edb6c64     3815 flatdt_1.image
OK: a7ded150 a7ded150     3817 flatdt_0.image
OK: 29c318fc 29c318fc 31858688 filesystem.image
no errors copying fit image containing 6 files

$ md5sum 7530ax.fit temp/7530ax.fit
e41eafa4dc0c4ee6e46f5313dfce737f  7530ax.fit
e41eafa4dc0c4ee6e46f5313dfce737f  temp/7530ax.fit

Copy and test a fit-image from a firmware.image file:
Note that starting with fitimg 0.5 you need to pass -p 0 for the md5 test.

$ fitimg -c 7530ax.image -o temp/7530ax.fit -f
OK: f653ffe8 f653ffe8   192275 kernel2.image
OK: 2040d9dd 2040d9dd      599 flatdt2_0.image
OK: 34ac9b5e 34ac9b5e  2671938 kernel.image
OK: 5edb6c64 5edb6c64     3815 flatdt_1.image
OK: a7ded150 a7ded150     3817 flatdt_0.image
OK: 29c318fc 29c318fc 31858688 filesystem.image
no errors copying fit image containing 6 files

$ md5sum 7530ax.fit temp/7530ax.fit
e41eafa4dc0c4ee6e46f5313dfce737f  7530ax.fit
e41eafa4dc0c4ee6e46f5313dfce737f  temp/7530ax.fit

Copy and test a fit-image from a recovery.exe file:
Note that starting with fitimg 0.5 you need to pass -p 0 for the md5 test.

$ fitimg -c 7530ax.exe -o temp/7530ax.fit -f
OK: f653ffe8 f653ffe8   192275 kernel2.image
OK: 2040d9dd 2040d9dd      599 flatdt2_0.image
OK: 34ac9b5e 34ac9b5e  2671938 kernel.image
OK: 5edb6c64 5edb6c64     3815 flatdt_1.image
OK: a7ded150 a7ded150     3817 flatdt_0.image
OK: 29c318fc 29c318fc 31858688 filesystem.image
no errors copying fit image containing 6 files

$ md5sum 7530ax.fit temp/7530ax.fit
e41eafa4dc0c4ee6e46f5313dfce737f  7530ax.fit
e41eafa4dc0c4ee6e46f5313dfce737f  temp/7530ax.fit

Show[edit]

The show command -s shows the hunk structure of a fit-image, including hex offsets in the file. (fitimg 0.2+)
Hunks are given names from the descriptions array in the fit-image.
This command is useful to read metatada of all stored files and to understand the fit-format to improve this program.

Usage:

  fitimg -s <infile> [-i] [-q] (fitimg 0.2+)

    Show the complete hunk structure of the fit-image <infile>.

    Option -i (inner) processes the inner image for nested fit-image files.  (fitimg 0.7.2+)
    Option -q (quiet) could be used to silently test the image structure

Hunk structure listings are pretty long, that's why they are separate listings of all FIT models:

Hexdump[edit]

The hexdump command -h is a variant of the show command with an extra column listing every single byte
in hex (fitimg 0.5+) and an extra column showing every printable ASCII character (fitimg 0.8+)
Binary blobs are clipped to show 128 bytes of their head (fitimg 0.5+) and their tail (fitimg 0.8+).
This command is useful for deeper inspection of the fit-format, and to add support for new hunk types in future.

Usage:

  fitimg -h <infile> [-i] [-b <num>] [-q]  (fitimg 0.5+)

    Hexdump and show the complete structure of the fit-image <infile>.

    Hunk payload like binary blobs are clipped to show 128 bytes of their head and their tail.
    Option -i (inner) processes the inner image for nested fit-image files.  (fitimg 0.7.2+)
    Option -b (bytes) ovverrides the default of 128 bytes clipping of blobs.  (fitimg 0.8+)
    Option -q (quiet) could be used to silently test the image structure

Hexdumps are long, that's why these are separate listings of all FIT models:

Help[edit]

The help command --help prints a short help text and terminates.

$ fitimg --help
fitimg version 0.7.2 - (C)  2021-2022 Ralf Steines aka Hippie2000 - <hippie2000@webnmail.de>
Handle and manipulate firmware images in AVM /var/tmp/fit-image format. GPLv2+.
Docs and latest version can be found at https://boxmatrix.info/wiki/FIT-Image

Usage:
  fitimg -l <infile> [-i] [-f] [-e] [-q]
    List all binaries contained in fit-image <infile>, including their load addresses.
    Option -q could be used to silently test the image structure.

  fitimg -t <infile> [-i] [-f] [-e] [-q]
    Test the integrity of all binaries contained in fit-image <infile>. Performs CRC32 validation.
    Option -q could be used to silently test the image structure and checksum integrity.

  fitimg -x <infile> [-d <dir>] [-i] [-n] [-f] [-e] [-q]
    Extract all contents of fit-image <infile> or just <file> to current directory or <dir>.
    Option -n suppresses extracting device tree files.
    Option -q suppresses listing which files were extracted.

  fitimg -r <infile> -o <outfile> [-d <dir>] [-i] [-f] [-e] [-p <num>] [-q]
    Replace all contens of fit-image <infile> which exist in current directory or <dir> and write it to <outfile>.
    Files which do not exist in current directory or <dir> will not be replaced.
    Option -p ovverrides the default padding size of 64 (0 - 1024) in kB  (fitimg 0.5+)
    Option -q suppresses listing which files were replaced.

  fitimg -c <infile> -o <outfile> [-i] [-f] [-e] [-p <num>] [-q]  (fitimg 0.2+)
    Copy an unaltered fit-image from <infile> to <outfile> while testing its integrity.
    This is mainly useful to extract and validate a fit-image from a recovery.exe or firmware.image.
    Option -p ovverrides the default padding size of 64 (0 - 1024) in kB  (fitimg 0.5+)
    Option -q could be used to silently copy and test the image structure and checksum integrity.

  fitimg -s <infile> [-i] [-q]  (fitimg 0.2+)
    Show the complete hunk structure of the fit-image <infile>.
    Option -q could be used to silently test the image structure

  fitimg -h <infile> [-i] [-q]  (fitimg 0.5+)
    Hexdump and show the complete structure of the fit-image <infile>.
    Hunk payload like binaries are clipped to 128 bytes, enough bytes to not clip kernel-args.
    Option -q could be used to silently test the image structure

Options:
  <infile> can be a fit-image, a firmware.image or a recovery.exe.  (fitimg 0.2+)
  -i processes the inner image for nested fit-image files.  (fitimg 0.7.2+)
  -f activates Freetz names using filesystem[2].image and kernel[2].image etc instead of the stored names.
  -e activates a .fit file extension for inner fit images  (fitimg 0.7.2+)

  -? (fitimg 0.2+) or --help print this help text and terminates.
  -v (fitimg 0.2+) or --version print this program's version and terminates.

Result:
	Returns 1 on error, otherwise 0.

Version[edit]

The version command --version prints the program version and terminates.

$ fitimg --version
fitimg version 0.7.2 - (C)  2021-2022 Ralf Steines aka Hippie2000 - <hippie2000@webnmail.de>
Handle and manipulate firmware images in AVM /var/tmp/fit-image format. GPLv2+.
Docs and latest version can be found at https://boxmatrix.info/wiki/FIT-Image

Background[edit]

Datestamps[edit]

This info requires fitimg 0.8+ to be true.

By default the extract and copy commands use the date stored in the timestamp hunk within the fit-image
for created files. If the inner fit is chosen by -i for nested fit images the timestamp from there is used.

If the -u (utime) option is passed to both commands the target files will inherit the datestamp of the <infile>.
I use this in my firmware scanner to see if an extracted file matches its parent, which may have been updated.
Besides this I do backup by rsync and reextracted files don't need to be retransfered using this datestamping.

The replace command always uses normal file creation datestamps, since it's intended to create modified files.

Nested FIT[edit]

This howto requires fitimg 0.7.2+ to work.

The 7510, 1200ax and the 3000ax use nested FIT images. fitimg can not handle these in one pass.
This will explain how to treat them running fitimg twice for extract and replace each.
The second invocation is only required if Freetz uses replace kernel,
otherwise the nested FIT could be treated like a normal FIT, just replacing the filesystem.

Extracting the outer image:
Option -f enables freetz names, option -e appends .fit extension to inner image name to avoid name collisions

$ fitimg -x 7510.fit -d temp -e -f
XX: XXXXXXXX 5b555ba9  3580407 kernel.image.fit ### inner fit-image without crc ###
OK: 1cfda47b 1cfda47b 28626944 filesystem.image
extracted 2 files

The XXX is normal since the inner FIT image is not checksummed within the outer image.
Extracting the inner image (option -i = inner image):

$ fitimg -x 7510.fit -d temp -i -f
found 3580407 bytes inner fit-image at offset 0x00000138 (312)
OK: c8b0bf2d c8b0bf2d  3553495 kernel.image
OK: bfc0c3ab bfc0c3ab    12646 flatdt_2.image
OK: 696ac3ea 696ac3ea    12661 flatdt_0.image
extracted 3 files

Now we can do our modification to temp/filesystem.image in place.
For replace kernel we can do our modification to temp/kernel.image in place.
Creating the new inner image in place (disabling padding to save space, option -i = inner image):

$ fitimg -r 7510.fit -o temp/kernel.image.fit -d temp -i -f -p 0
found 3580407 bytes inner fit-image at offset 0x00000138 (312)
Replacing: 03553495->03553495 kernel.image
Replacing: 00012646->00012646 flatdt_2.image
Replacing: 00012661->00012661 flatdt_0.image
replaced 3 files

Creating the new outer image (padding disabled for md5 test, don't disable for production!):
Option -e prefers files with .fit extension over files without extension.

$ fitimg -r 7510.fit -o temp/7510.fit -d temp -e -f -p 0
Replacing: 03580407->03580407 kernel.image.fit
Replacing: 28626944->28626944 filesystem.image
replaced 2 files

Let's test the new image:

$ md5sum 7510.fit temp/7510.fit
ea9e8183dce89625402a75496c6a52fc  7510.fit
ea9e8183dce89625402a75496c6a52fc  temp/7510.fit

OK, we succeeded!

EVA-Upload[edit]

All fit-images are uploaded via EVA in a similar way.

Here some simplified pseudo code to explain how recoveries do the job, as far as dumps are available.

# same for all models
$fitsize = sizeof fit-image   # padded to 0x10000 / 64kB which fitimg does per default

# differs per model
if ($model = '1200ax' {                            # Maple 256 MB model
     $endaddr = 0x50000000                         # env: memsize + RAM base 0x40000000
     $memsize = 0x10000000 - $fitsize              # env: memsize - $fitsize

} else if ($model = '7530ax') {                    # BCM63 512 MB model 
     $endaddr = 0x20000000                         # env: memsize + RAM base 0x00000000 (0)
     $memsize = 0x20000000 - $fitsize              # env: memsize - $fitsize

} else if ($model = '4060' || $model = '6000') {   # Hawkeye 1 GB  models
     $endaddr = 0x80000000                         # env: memsize + RAM base 0x40000000
     $memsize = 0x40000000 - $fitsize              # env: memsize - $fitsize

} else if ($model = '5530') {                      # PRX 1 GB model (as the only CPU)
     $endaddr = 0x60000000                         # env: memsize + RAM base 0x20000000
     $memsize = 0x40000000 - $fitsize              # env: memsize - $fitsize

# please help!
} else {                                           # missing 7510 / 5590
     print "please send a recovery dump of $model"
}

# same for all models
$startaddr = $endaddr - $fitsize

# EVA communication - all variables are '0x' prepended lowercase hex numbers, leading 0s omitted
print EVA "SETENV memsize $memsize"
print EVA "SETENV kernel_args_tmp "avm_fwupdate mtdram1=$startaddr,$endaddr mtdparts_ext=update-image.0:$fitsize@0x0(fit-image)""
print EVA "TYPE I"   # binary
print EVA "MEDIA SDRAM"
print EVA "P@SW"   # passive
print EVA "STOR $startaddr $endaddr"

$fitsize is the size of the fit-image, padded to 0x10000 / 64kB boundaries.
Since fitimg performs this padding by default push_firmware just needs to take the image size.
$endaddr is the upper end of the RAM, the memsize value from environment plus the RAM base address.
startaddr is the $endaddr minus the $fitsize.
The new $memsize is the memsize from env. minus the $fitsize, to protect the 'allocated' portion of RAM..
Since EVA could not know the unpadded size of the fit-image the upload has to have the $fitsize too.

Kernel-Args[edit]

This is nothing the user has to care about, just info to explain how fitimg works.

Most but not all FIT images contain embedded kernel args which are passed to the filesystem at boot time.
They are stored in avm,kernel-args hunks and look similar to the kernel_args_tmp passed during EVA-Upload.
However, they are completely different, since they describe where the rootfs ramdisk is located at boot time.
Another important hunk named load shows the absolute address where each binary in a FIT is loaded.

Example from the 7530ax filesystem:

load = 0x19c00000
avm,kernel-args = 'mtdram=ram-filesystem,0x19c00000,0x1bb00000 mtdparts_ext=ram-filesystem:31870976@0x0(rootfs_ram)'

Let's use variables to explain:

load = $startaddr
avm,kernel-args = 'mtdram=ram-filesystem,$startaddr,$endaddr mtdparts_ext=ram-filesystem:$blobsize@0x0(rootfs_ram)'

$startaddr is the fixed hex number of the base address in memory and doesn't need adaption.
$blobsize is the unpadded decimal size of the filesystem image.
$endaddr = $startaddr + $blobsize + padding to 0x100000 / 1MB boundaries in hex.
The padding is special, there will always be padding, so if a blob is already a multiple of 0x100000
a complete megabyte will be appended. This looks like a bug but fitimg reproduces this to satisfy the md5 tests.

In replace mode fitimg needs to adapt the kernel args to reflect the size changes of the replaced filesystem.
Since $startaddr does not need to be altered it's always reused from the original kernel args.
The $blobsize is the unpadded size of the new filesystem, the $endaddr is computed like shown above.

The 5590 has 2 embedded kernel-args, one for the Hawkeye ARM SoC which looks like above,
and a second one for the PRX MIPS SoC which is special:

load = 0x73000000
avm,kernel-args = 'mtdram=rootfs_ram,0x33000000,0x33800000'

This is also supported by fitimg (0.7.2+) and the $startaddr and $endaddr are computed like above. The load
parameter shows it's shifted by 0x40000000, the base address of the PRX memory as seen from Hawkeye.
Since fitimg does not alter the load address there's no problem with this offset.

Replace-Kernel[edit]

Independently of the support in Freetz which surely is a big todo fitimg is prepared for replace kernel.
So far this is only true for all ARM Cortex based FIT image kernels.
All ARM based kernels in FIT use the same load and entry addresses (see show or hexdunp commands),
which means the kernel is executed by jumping into the beginning of its decompressed binary, easy to replace.
This covers the 4060, 7510, 7530ax, 1200ax, 6000 and the Hawkeye main CPU of the 5590.

However, all MIPS based PRX kernels (both in 5530, and 2 of 3 in 5590) have differing load and entry addresses.
The entry address is within the extracted kernel and it has to be gathered first where it jumps and how it could
be adapted to a new kernel. Until this is resolved fitimg aborts on trying to replace a PRX kernel.
This may require some compile time magic and/or maybe an entry address to be passed to fitimg.
Maybe and hopefully it could be gathered from an uncompressed kernel binary without such acrobatics.

Size-Limits[edit]

This is nothing the user has to care about, just info to explain how fitimg works.'
There are several size limits to care of for fit-images and/or the binaries they contain.
If any of the limits explained here are exceeded fitimg will abort and will not create an image. (fitimg 0.8+)
This prevents from creating invalid images and reduces the risk to harm a device.

Kernels in fit-images are always lzma compressed. They are decompressed to the load address
specified in fit structure and executed at their entry address which for ARM always equals the load address.
Each kernel in a fit-image is followed by at least one flatdt file, which is loaded above the uncompressed kernel.
There may be multiple flatdt files, but they are configuration options then and loaded at the same address.
From the load addresses of the kernel and the flatdt file the maximum uncompr. kernel size can be computed.
This does not work for the 7530ax ARM TrustZone, but that's no Linux kernel anyway but a firmware.
This check just avoids overlapping memory regions. Further size limits may apply to the kernel.
Since the load address of a flatdt file may change this size check has to be performed by fitimg.

The list command has a -m option to list maximum usable memory regions and their allocation. (fitimg 0.8+)
As you can see below the headroom for the uncompressed kernels is pretty limited.

For the 7510 and the 1200ax which use Nested FIT there's an 8MB size limit for the inner fit image
(which is lzma kernel + flatdt + fit container), and a 28MB or 42MB size limit for the filesystem image.
The maximum fit-image size is a result of these 2 limits (+ fit container) and does not need any further check.
You can see the headroom of the inner fit is limited by the size of the decompressed inner kernel.image,
unless the flatdt files could be relocated which is neither implemented nor known to work (yet?).

$ fitimg -l 1200ax.fit -f -m -e
41208000-4157010f  3571983 kernel.image.fit
41208000-41a08000  8388608 * max size, 43% used *
43000000-441de000 18735104 filesystem.image
43000000-44c00000 29360128 * max size, 64% used *

$ fitimg -l 1200ax.fit -f -m -i
found 3571983 bytes inner fit-image at offset 0x00000138 (312)
41208000-4156cda3  3558819 kernel.image
41208000-41dda0cc 12394700 * decompressed lzma *
41208000-41ed3000 13414400 * max size, 92% used *
41ed3000-41ed5e73    11891 flatdt_0.image

$ fitimg -l 7510.fit -f -m -e
41208000-415721f7  3580407 kernel.image.fit
41208000-41a08000  8388608 * max size, 43% used *
43000000-44b4d000 28626944 filesystem.image
43000000-45a00000 44040192 * max size, 65% used *

$ fitimg -l 7510.fit -f -m -i
found 3580407 bytes inner fit-image at offset 0x00000138 (312)
41208000-4156b8d7  3553495 kernel.image
41208000-41dda0cc 12394700 * decompressed lzma *
41208000-41ed5000 13422592 * max size, 92% used *
41ed5000-41ed8166    12646 flatdt_2.image
41ed5000-41ed8175    12661 flatdt_0.image

The 7530ax, 5530, 6000 and 4060 have 50MB or 80MB size limits for the entire fit-image.
Since the filesystem is always the last binary in FIT for these models fitimg computes how big it could grow.
However, if the kernel size grows the remainder for the filesystem will get smaller.
For the 7530ax kernel2 is the ARM TrustZone, which can't be checked. It can't be modded either.

$ fitimg -l 7530ax.fit -f -m 
10800000-1082ef13   192275 kernel2.image
10000000-10000257      599 flatdt2_0.image
c0008000-c0294542  2671938 kernel.image
c0008000-c06c838c  7078796 * decompressed lzma *
c0008000-c07ab000  8007680 * max size, 88% used *
c07ab000-c07abee7     3815 flatdt_1.image
c07ab000-c07abee9     3817 flatdt_0.image
19c00000-1ba62000 31858688 filesystem.image
19c00000-1cb420d8 49553624 * max size, 64% used *

$ fitimg -l 5530.fit -f -m 
88000000-88122c69  1191017 kernel2.image
88000000-883ad0a1  3854497 * decompressed lzma *
88000000-884e2000  5120000 * max size, 75% used *
884e2000-884e2444     1092 flatdt2_0.image
8b000000-8b19f361  1700705 filesystem2.image
70000000-703216dc  3282652 kernel.image
70000000-70b9f8e5 12187877 * decompressed lzma *
70000000-70fe4000 16662528 * max size, 73% used *
70fe4000-70fe5eed     7917 flatdt_0_aon.image
70fe4000-70fe5ecc     7884 flatdt_0_pon.image
90000000-921d0c2d 35458093 filesystem.image
90000000-92c17b98 46234520 * max size, 77% used *

$ fitimg -l 6000.fit -f -m 
41208000-41527046  3272774 kernel.image
41208000-41b1e0cc  9527500 * decompressed lzma *
41208000-41c30000 10649600 * max size, 89% used *
41c30000-41c33cdd    15581 flatdt_0.image
41c30000-41c33d0e    15630 flatdt_2.image
43000000-44000000 16777216 filesystem.image
43000000-47cd8d78 80579960 * max size, 21% used *

$ fitimg -l 4060.fit -f -m 
41208000-41538c85  3345541 kernel.image
41208000-41b520cc  9740492 * decompressed lzma *
41208000-41c66000 10870784 * max size, 90% used *
41c66000-41c69f06    16134 flatdt_1.image
41c66000-41c69f06    16134 flatdt_0.image
41c66000-41c69ee3    16099 flatdt_2.image
43000000-4497d000 26726400 filesystem.image
43000000-47cc2cac 80489644 * max size, 33% used *

The 5590 also has an 80MB size limit for the complete fit-image, covering 3 kernels and 3 filesystems.
But unlike the 7530ax, 5530, 6000 and 4060 its main filesystem is not the last binary in FIT.
The remaining size needs to be calculated for the filesystem, not the filesyetem2. TODO!

$ fitimg -l 5590.fit -f -m
41208000-41543a43  3390019 kernel.image
41208000-41b950cc 10014924 * decompressed lzma *
41208000-41cd1000 11309056 * max size, 89% used *
41cd1000-41cd4f88    16264 flatdt_0.image
43000000-44ac1000 28053504 filesystem.image
88000000-881230df  1192159 kernel3.image
88000000-883b10a1  3870881 * decompressed lzma *
88000000-884f2000  5185536 * max size, 75% used *
884f2000-884f245e     1118 flatdt3_0.image
8b000000-8b0f2667   992871 filesystem3.image
70000000-703304dc  3343580 kernel2.image
70000000-70b598e5 11901157 * decompressed lzma *
70000000-70fac000 16433152 * max size, 72% used *
70fac000-70fadbda     7130 flatdt2_0_pon.image
70fac000-70fadbd4     7124 flatdt2_0_aon.image
73000000-7378d000  7917568 filesystem2.image
73000000-75cb4d40 46878016 * max size, 17% used *

AVM-Kallsyms[edit]

This is nothing the user has to care about, just info to explain how fitimg works.'
Kallsyms (kernel all symbols) is a huge table which maps memory addresses in the kernel to function names.
This table permits to give error messages human readable names. Ie: Instead of error 3 at 0xc0301020
as you may know it from bluescreens you get a error 3 at finish_automounts and you have a chance to
understand what's going on. Kallsyms are not necessary to run a kernel, they just help humans with debugging.

All symbols of a running kernel can be obtained from /proc/kallsyms, including symbols from external
Kernel-Modules which have been loaded using modprobe or insmod. This list is huge!
The lzma compressed kernel of a 7530 is 3.1 MB, decompressed it is 9.6 MB. The export of /proc/kallsyms
is 2.8 MB! Due to the size kallsyms are stored compressed, with a special compression algorithm designed
for realtime lookup of symbols from the compressed stream. See linux/kernel/kallsyms.c.

To be able to extract the symbol table from a kernel without having to run it an unpacked kernel built with
kallsyms support (CONFIG_KALLSYMS) has a textual info at its end, to locate the compressed symbol stream
within the kernel:

c0812760 R kallsyms_addresses 
c08457b0 R kallsyms_names 
c08457a0 R kallsyms_num_syms 
c08dd0c0 R kallsyms_token_index 
c08dcd30 R kallsyms_token_table
ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV)

These pointers do not necesssarily point into the memory region where the decompressed kernel is loaded, but
they point into the decompressed kernel at the absolute address where it's executed, details explained here.
Each Linux kernel in a FIT image is followed by an AVM specific variant of this information:

0033bc20  hunk 2 [24] - string = 'avm,kallsyms'
0033bc38  hunk 3 #117 [3] - avm,endianess = 'LE'
0033bc48  hunk 3 #131 [4] - avm,kernel_text_start = 0xc0208000
0033bc58  hunk 3 #153 [4] - avm,names = 0xc08457b0 
0033bc68  hunk 3 #163 [4] - avm,token_table = 0xc08dcd30 
0033bc78  hunk 3 #179 [4] - avm,token_index = 0xc08dd0c0 
0033bc88  hunk 3 #195 [4] - avm,num_syms = 0xc08457a0 
0033bc98  hunk 3 #208 [4] - avm,addresses = 0xc0812760 
0033bca8  hunk 3 #222 [0] - avm,relative_base = <empty>
0033bcb4  hunk 3 #240 [0] - avm,offsets = <empty>

Since the previous lists both come from the same 5590 Hawkeye kernel we can map them:

avm,endianess = 'LE' = 'LSB executable'
avm,kernel_text_start = 0xc0208000 = kernel text segment base
avm,names = 0xc08457b0 = kallsyms_names
avm,token_table = 0xc08dcd30 = kallsyms_token_table
avm,token_index = 0xc08dd0c0 = kallsyms_token_index 
avm,num_syms = 0xc08457a0 = kallsyms_num_syms
avm,addresses = 0xc0812760 = kallsyms_addresses 
avm,relative_base = <empty> = kallsyms_relative_base 
avm,offsets = <empty> = kallsyms_offsets 

Besides avm,kernel_text_start all pointers can be taken from a decompressed kernel built with kallsyms.
But unless we find some nasty AVM FIT debugger in AVM-Tarballs there's no point in repeating this in the FIT.
fitimg just copies them unaltered, even if the respective kernel is replaced (which renders this info invalid).

There are 2 ways to locate symbols in kallsyms which exclude each others, either absolute addresses stored in
avm,addresses table like the example above or an avm,offsets table which is relative to the
avm,relative_base (CONFIG_KALLSYMS_BASE_RELATIVE), see this excerpt from a 5530 structure listing
as an example:

avm,addresses = <empty>
avm,relative_base = 0x882c8ea0 
avm,offsets = 0x882bcc70

Pointers marked <empty> are zero size integers in FIT images, which could be translated to undef.

FIT-Header[edit]

All FIT images have a fixed size header, one part is AVM proprietary and one is a Devicetree Blob (DTB) header.
Excerpt from fitimg -h 7530ax.fit:

# AVM Flattened Image Tree (FIT) header

00000000 0d00edfe ....  head [4] - magic - always 0x0d00edfe 
00000004 d7fe1102 ....  head [4] - totalsize - BE size of FIT - 0x50 
00000008 be1205bb ....  head [4] - ed25519_sig0 
0000000c 0771bff8 .q..  head [4] - ed25519_sig1 
00000010 f88687b1 ....  head [4] - ed25519_sig2 
00000014 b763efdd .c..  head [4] - ed25519_sig3 
00000018 45db1e26 E..&  head [4] - ed25519_sig4 
0000001c 0ca1c83a ...:  head [4] - ed25519_sig5 
00000020 e60a3108 ..1.  head [4] - ed25519_sig6 
00000024 c56ff5fe .o..  head [4] - ed25519_sig7 
00000028 edafb535 ...5  head [4] - ed25519_sig8 
0000002c fd74322b .t2+  head [4] - ed25519_sig9 
00000030 dd662c18 .f,.  head [4] - ed25519_sig10 
00000034 7c052168 |.!h  head [4] - ed25519_sig11 
00000038 9e3ba2f9 .;..  head [4] - ed25519_sig12 
0000003c 81d382e6 ....  head [4] - ed25519_sig13 
00000040 be457e90 .E~.  head [4] - ed25519_sig14 
00000044 04a47f08 ....  head [4] - ed25519_sig15 

# Devicetree Blob (DTB) header

00000048 d00dfeed ....  head [4] - magic - always 0xd00dfeed 
0000004c 0211fed7 ....  head [4] - totalsize - LE size of FIT - 0x50 
00000050 00000038 ...8  head [4] - off_dt_struct - 0x80 - 0x48 = always 0x00000038 

00000054 0211fda8 ....  head [4] - off_dt_strings - LE pointer to descriptions base - 0x48 
00000058 00000028 ...(  head [4] - off_mem_rsvmap - always 0x00000028 
0000005c 00000011 ....  head [4] - fdt version - always 0x00000011 = 17 
00000060 00000010 ....  head [4] - last compatible version - always 0x00000010 = 16 
00000064 00000000 ....  head [4] - boot_cpuid - always 0x00000000 

00000068 0000012f .../  head [4] - size_dt_strings - size of descriptions array 
0000006c 0211fd70 ...p  head [4] - size_dt_struct - size of FIT body structure 
00000070 00000000 ....  head [4] - padding/reserved 0 - always 0x00000000 
00000074 00000000 ....  head [4] - padding/reserved 1 - always 0x00000000 
00000078 00000000 ....  head [4] - padding/reserved 2 - always 0x00000000 
0000007c 00000000 ....  head [4] - padding/reserved 3 - always 0x00000000 

The AVM part consists of a 4-bye magic, the 32-bit big endian size and 16 32-bit values of signature.
The signature is 512-bits Ed25519, 64 bytes - algorithm string was found in ar7-lite.
A nice and short explanation of the algorithm could be found here.

Project[edit]

Feedback[edit]

For bugreports or feature requests please get in touch, use our IRC-Channels or use this forum thread:

Known bugs[edit]

The last and final PUBLIC release v0.8 suffers from a known bug:

All features work and are tested with all known FIT-Images, creating sane images in freetz-ng works as intended.

There's one known bug which only affects analysis of modified images, and only if padding is enaabled:

### fitimg ### - Description string table too long (29618)

There's a simple workaround. Just put the fit-image in a tar and analyze it, or analyze the creatred .image file.
Another workaround is setting padding to -p 0. I will not fix this bug since there are workarounds.
Let's see if the master of project interception can write the first constructive patch without just removing this sanity check.

History[edit]

Read changes bottom up!

fitimg-todo - future

- TODO: Add adaption of the 5530/90 PRX kernels entryaddr, see Replace-Kernel section above.
- TODO: Add recursion to all functions to handle nested fit-images in one path

fitimg-server - work in progress - internal BoxMatrix tool

- Fixed: Removed '# Devicetree Blob (DTB) strings' comment in show mode
- Changed: Improved nested fit detection
- Added: Support for the 3000ax Inhaus.
- Added: fitimg now reports detected nested fit-images in all modes (unless quiet)
- Changed: The Hexdump command now lists the signature ed25519_sig0++, see FIT-Header
- Removed: Removed the commented out crypto code. The FIT signature now is known, see FIT-Header
- Changed: Removed GPL header, changed the license header to PROPRIETARY
- Changed: Removed the release() code which is not needed any more.

fitimg-0.8 - released 2022-05-22 - last public release

- Added: Support for new hunk type 'avm,image-version' (word).
- Fixed: Suppressed 'Use of uninitialized value' reports for unknown / new hunk types.
- Fixed: Aborting 'Description string table too long (619)' with new 7530ax 07.39-96436-Inhaus.
- Added: The list command's -m option now lists correct results for decompressed kernels.
- Added: Changed the Requirements to handle buffer to buffer decompression of lzma kernels.
- Added: Total fit-image size check for the 5590
- Added: Aborts in replace mode if a PRX kernel is to be replaced, which is not supported (yet).
- Fixed: Reproduced the strange padding of kernel args which even pad if a blob is aligned.
- Added: The -n option of the extract command now also suppresses extracting TrustZone files.
- Added: The hexdump command now shows the head and the tail of each binary blob.
- Added: The hexdump command now has a -b option to ovverride its 128 bytes clipping of blobs.
- Added: The replace and copy commands now force quiet mode if <outfile> is '-' (stdout)
- Added: The -u option (utime) makes extract and copy use the datestamp of the <infile>.
- Added: The extract and copy commands now use the timestamp stored in the FIT for created files.
- Added: The hexdump command now also prints a 4-char ASCII column.
- Added: The list command now has a -m option to show maximum memory regions and allocation
- Added: Implemented 7530ax, 5530, 5590, 6000 and 4060 fit-image  size check.
- Added: Implemented 7510 and 1200ax inner fit and filesystem size check
- Added: Implemented memory region size check for all kernels
- Changed: The list command only shows kernel arg regions if the -k option is passed.

fitimg-0.7.2 - released 2022-03-11

- Added: Support for listing and manipulating the special 5590 PRX Kernel-Args.
- Added: The -l command now also lists memory regions of embedded Kernel-Args.
- Added: Explanation in the online docs how fitimg alters embedded Kernel-Args.
- Changed: Missing CRC of inner fit images is now listed XXX instead of ugly ???
- Added: The -i option now can be passed to all commands to process the inner image
- Added: The -e option (extension) enables a .fit file extension for inner fit images
- Fixed: Processing recoveries and firmware images was broken since the 0.7 rework

fitimg-0.7.1 - released 2022-02-26 - minor changes

- Fixed: 5590 freetz names: filesystem.image = ARM, filesystem2 = PRX, filesystem3 = Boot, etc
- Added: Extract mode only appends a .fit filename extension if the -i option is passed.
- Fixed: Bumped the (C) date (was still 2021).

fitimg-0.7 - released 2022-02-19

- Fixed: Updated my new Email address in source and documents.
- Added: The replace mode has a new option -i to include inner FIT in nested outer images.
- Added: Now also supports the new 5590 image.
- Added: Now also lists the FIT header structure in hexdump (-h) mode, including known infos
- Added: Now takes the hunk names from the fit image, no more HWR senstitive config 
         for new fit models besides freetz names and new hunk types
- Added: The value of integer hunks is now listed in hex and decimal in show and in hexdump mode
- Added: The test, extract and copy commands now support inner fit-images without stored crc (1200ax, 7510)
- Added: The stored or freetz filename of an inner fit-image now gets a '.fit' extension 
         to avoid name collisions between inner and outer fit-image files (1200ax, 7510)
- Added: Now can distinguish between inner and outer fit-image (1200ax, 7510)
- Added: Now also supports the new 1200ax and 7510 images.

fitimg-0.6 - released 2021-07-16

- Added: Now also supports the new 4060 image.

fitimg-0.5 - released 2021-02-10

- Added: The fitimg release archive now contains a readme.txt with the output of fitimg --help.
- Added: The new hexdump command (-h) is a variant of the show command for deeper inspection of the fit-image.
- Added: Now outputs a warning if an embedded kernel-args string of a replaced (-r) blob couldn't be adapted.
- Added: The 64kB default padding can be overridden using the -p <num> switch (0-1024, in kB, -r and -c mode).
- Added: Now creates 64kB padded images in replace (-r) and copy (-c) mode, as required by push_firmware later.
- Fixed: Zero sized integer hunks are now listed '<empty>' in show (-s) mode, ie: 'avm,addresses' on a 5530.
- Fixed: 'avm,variants' hunk is no longer an integer but a string in show (-s) mode, ie: 'aon, pon' on a 5530.

fitimg-0.4 - released 2021-02-08

- Fixed: Bug which computed wrong padding of new blob in replace mode.
- Fixed: Bug which reported missing blob if last blob in image grew in replace mode.
- Fixed: Bug which reported numerous "Use of uninitialized value" messages in replace mode.

fitimg-0.3 - released 2021-02-05

- Fixed: The kernel args stored in 7530ax and 6000 image now reflect the size of the modified filesystem (-r).
- Checked: Does loadaddr and entrypoint need adaption in replace (-r) command? - no - see research below.

fitimg-0.2 - released 2021-01-13

- Added: The show command (-s) now knows all hunknames of the 7530ax, 5360 and 6000.
- Added: A new show command (-s) can show the hunk structure of a fit-image. Useful for development.
- Added: A new copy command (-c) can extract a fit-image from a fit-image, firmware.image or recovery.exe.
- Changed: All commands now work on fit-image, firmware.image and recovery.exe files for the <infile>.
- Fixed: A nasty bug calculated wrong offsets in Replace (-r) when the fit-image filesize changes.
- Fixed: Removed wrong info in docs and help text which showed a [<file>] filter for the -x command. 
- Fixed: Bug which reported "Use of uninitialized value" if called without arguments.
- Fixed: The release archive now contains a versioned subfolder (in favour of the prior bin folder).

fitimg-0.1 - released 2021-01-02

Initial release.

Research[edit]

Please help![edit]

The following stuff would help a lot - please get in touch if you have one of these models:

  • supportdata of 4060, 5530, 5590, 7510, 1200ax, 7530ax, 6000
  • recovery dump of 5590, 7510

To create a recovery dump use Wireshark, start capture before you run the recovery.
When the recovery finished stop capture, save and zip the file and send it to me using anonfiles.

7530ax[edit]

7530ax: Partition layout

Bootloader-Environment:

firstfreeaddress	0x1CE00000
flashsize	nor_size=0MB sflash_size=0KB nand_size=128MB
linux_fs_start    1
memsize	0x40000000
...
mtd0    0x0,0x0
mtd1    0xB00000,0x3D00000 = 50MB = fit0/fit1
mtd2    0x100000,0x300000 = 2MB = urlader
mtd3    0x300000,0xB00000 = 8MB = nand-tffs
mtd4    0x3D00000,0x6F00000 = 50MB = fit1/fit0
mtd5    0x0,0x100000 = 1MB = nvram
mtd6    0x6F00000,0x7F00000  = 16MB = ubi

The 128MB NAND is splitted into 50+50MB fit + 2MB urlader + 8MB nand-tffs + 1MB nvram + 16MB ubi = 127MB. 1MB is lost/hidden for whatever purposes.

Linux-Partitions:

major minor  #blocks  name
   1        0       8192 ram0 = 8MB = ramdisk
  31        0      31112 mtdblock0 = 30,4MB = rootfs_ram (ram-filesystem, squashfs)
  31        1      51200 mtdblock1 = 50MB = fit0 (brcmnand, fit-image)
  31        2       2048 mtdblock2 = 2MB = urlader (brcmnand)
  31        3       8192 mtdblock3 = 8MB = nand-tffs (brcmnand, tffs3-nand)
  31        4      51200 mtdblock4 = 50MB = fit1 (brcmnand, fit-image)
  31        5       1024 mtdblock5 = 1MB = nvram (brcmnand)
  31        6      16384 mtdblock6  = 16MB = ubi (brcmnand, ubi)
  31        7       2108 mtdblock7 = 2,05MB = [ubi_intern] (ubifs)
  31        8      12772 mtdblock8  = 12,5MB = avm_userdata (ubifs)

[    3.111993] ubi0: attached mtd6 (name "ubi", size 16 MiB)
[    3.117395] ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
[    3.124273] ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
[    3.131056] ubi0: VID header offset: 2048 (aligned 2048), data offset: 4096
[    3.138012] ubi0: good PEBs: 128, bad PEBs: 0, corrupted PEBs: 0
[    3.144014] ubi0: user volume: 2, internal volumes: 1, max. volumes count: 128

ubi has an additional internal volume which is 16384−2108−12772 = 1504 blocks = 1.47MB
avm_userdata (mtdblock8) is mounted via ubifs as internal storage:

/dev/ubi0_1 /var/media/ftp ubifs rw,sync,noexec,relatime 0 0

7530ax: FIT-Image listings

While other ARM models use tz_update for the TrustZone code the 7530ax stores it in the FIT:

Stored names:

10800000-1082ef13   192275 brcma9TZ_HW256_kernel
10000000-10000257      599 brcma9TZ_HW256_flat_dt_0
c0008000-c0294542  2671938 brcma9_HW256_kernel
c07ab000-c07abee7     3815 brcma9_HW256_flat_dt_1
c07ab000-c07abee9     3817 brcma9_HW256_flat_dt_0
19c00000-1ba62000 31858688 brcma9_HW256_squashFS_filesystem
19c00000-1bb00000 31858688 * kernel-args *

Freetz names:

10800000-1082ef13   192275 kernel2.image
10000000-10000257      599 flatdt2_0.image
c0008000-c0294542  2671938 kernel.image
c07ab000-c07abee7     3815 flatdt_1.image
c07ab000-c07abee9     3817 flatdt_0.image
19c00000-1ba62000 31858688 filesystem.image
19c00000-1bb00000 31858688 * kernel-args *

Structure:

Size limits:

  • kernel: 0xc07ab000-0xc0008000 = 0x7A3000 = 8007680 bytes = ca. 7.64 MB
  • filesys: no limit besides fitsize
  • fitsize: 50MB

7530ax: Kernel-args

Embedded in 2 FIT-Images:

env: firstfreeaddress 0x1CE00000      =>   0x1CE00000 − 0x19c00000 = 0x3200000 = 50MB = max fit0/fit1 partition size

0211fb80  hunk 3 #95 [4] - load = 0x19c00000
0211fb90  hunk 3 #117 [97] - avm,kernel-args = 'mtdram=ram-filesystem,0x19c00000,0x1bb00000 mtdparts_ext=ram-filesystem:31858688@0x0(rootfs_ram)'

021229e4  hunk 3 #95 [4] - load = 0x19c00000
021229f4  hunk 3 #117 [97] - avm,kernel-args = 'mtdram=ram-filesystem,0x19c00000,0x1bb00000 mtdparts_ext=ram-filesystem:31870976@0x0(rootfs_ram)'

The difference between the loadaddr and hex start addr in kernel args to the firstfreeaddress in env is exactly the 50MB max filesysten size.
This means startaddr and loadaddr remain static, endaddr must change, padded to 0x100000 / 1MB boundaries. The decimal size at the end of kernel args must change too, unpadded.

From 3 supportdata bootlogs:

[    0.000000] Kernel command line: slub_debug=FLZP  mtdram=ram-filesystem,0x19c00000,0x1bb00000 mtdparts_ext=ram-filesystem:31858688@0x0(rootfs_ram) console=ttyAMA0 earlyprintk debug irqaffinity=0 ethaddr=74:42:7F:* mtdparts=brcmnand.0:50M@0xB00000(fit0),2M@0x100000(urlader),8M@0x300000(nand-tffs),50M@0x3D00000(fit1),1M@0x0(nvram),16M@0x6F00000(ubi)  audit=1 pci=pcie_bus_safe
[    0.000000] Kernel command line: slub_debug=FL    mtdram=ram-filesystem,0x19c00000,0x1bb00000 mtdparts_ext=ram-filesystem:32210944@0x0(rootfs_ram) console=ttyAMA0 earlyprintk debug irqaffinity=0 ethaddr=2C:91:AB:* mtdparts=brcmnand.0:50M@0xB00000(fit0),2M@0x100000(urlader),8M@0x300000(nand-tffs),50M@0x3D00000(fit1),1M@0x0(nvram),16M@0x6F00000(ubi)  audit=1 pci=pcie_bus_safe
[    0.000000] Kernel command line: slub_debug=FL  mtdram=ram-filesystem,0x19c00000,0x1bb00000 mtdparts_ext=ram-filesystem:32489472@0x0(rootfs_ram) console=ttyAMA0 earlyprintk debug irqaffinity=0 ethaddr=1C:ED:6F:* mtdparts=brcmnand.0:50M@0xB00000(fit0),2M@0x100000(urlader),8M@0x300000(nand-tffs),50M@0x3D00000(fit1),1M@0x0(nvram),16M@0x6F00000(ubi)  audit=1 pci=pcie_bus_safe

7530ax: Recovery upload

env: memsize 0x20000000     =>   0x20000000 - 34733863 = 0x1DEE00D9
fit-image: 34733863 = 0x211FF27

SETENV memsize 0x1dee0000
SETENV kernel_args_tmp "avm_fwupdate mtdram1=0x1dee0000,0x20000000 mtdparts_ext=update-image.0:0x2120000@0x0(fit-image)"
TYPE I
MEDIA SDRAM
P@SW
STOR 0x1dee0000 0x20000000

The 7530ax RAM is located at 0x00000000 to 0x20000000.

  • The 7530ax flashing method research is finished, see the EVA-Upload section below.
  • The 7530ax was successfully freetzed, but with a nonstandard busybox, see this github issue.

5530[edit]

5530: Partition layout

Bootloader-Environment:

firstfreeaddress	0x6043F420
flashsize	nor_size=0MB sflash_size=0KB nand_size=128MB
linux_fs_start    0
memsize	0x40000000
...
mtd0	0x0,0x0
mtd1	0x980000,0x3B80000 = 50MB = fit0/fit1
mtd2	0x0,0x180000 = 1.5MB = urlader
mtd3	0x180000,0x980000 = 8MB = nand-tffs
mtd4	0x3B80000,0x6D80000 = 50MB = fit1/fit0
mtd5	0x6D80000,0x8000000 = 18.5MB = ubi

The 128MB NAND is splitted into 50+50MB fit + 1.5MB urlader + 8MB nand-tffs + 18.5MB ubi = 128MB.

Linux-Partitions:

There's no mtd device listing in supportdata so we take the bootlog:

[    7.523648] Creating 5 MTD partitions on "nand.0":
[    7.528426] 0x000000980000-0x000003b80000 : "fit0"
[    7.535728] 0x000000000000-0x000000180000 : "urlader"
[    7.541332] 0x000000180000-0x000000980000 : "nand-tffs"
[    7.547264] 0x000003b80000-0x000006d80000 : "fit1"
[    7.552870] 0x000006d80000-0x000008000000 : "ubi"
...
[   12.074234] ubi0: attached mtd4 (name "ubi", size 18 MiB)
[   12.078226] ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
[   12.085046] ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
[   12.091811] ubi0: VID header offset: 2048 (aligned 2048), data offset: 4096
[   12.098755] ubi0: good PEBs: 148, bad PEBs: 0, corrupted PEBs: 0
[   12.104746] ubi0: user volume: 0, internal volumes: 1, max. volumes count: 128

5530: FIT-Image listings

Stored names: Note that both ramdisks are gzip compressed cpio archives.

88000000-88122c69  1191017 prxB_HW0257_kernel     # entryaddr = 0x88298f10
884e2000-884e2444     1092 prxB_HW0257_flat_dt_0
8b000000-8b19f361  1700705 prxB_HW0257_ramdisk
70000000-703216dc  3282652 prxI_HW257_kernel      # entryaddr = 0x7077a400
70fe4000-70fe5eed     7917 prxI_HW257_flat_dt_0_aon
70fe4000-70fe5ecc     7884 prxI_HW257_flat_dt_0_pon
90000000-921d0c2d 35458093 prxI_HW257_ramdisk

Freetz names: Note that both filesystems are gzip compressed cpio archives.

88000000-88122c69  1191017 kernel2.image
884e2000-884e2444     1092 flatdt2_0.image
8b000000-8b19f361  1700705 filesystem2.image
70000000-703216dc  3282652 kernel.image
70fe4000-70fe5eed     7917 flatdt_0_aon.image
70fe4000-70fe5ecc     7884 flatdt_0_pon.image
90000000-921d0c2d 35458093 filesystem.image

Structure:

Size limits:

  • kernel: 0x70fe4000-0x70000000 = 0xfe4000 = 16662528 bytes = ca. 15.89 MB
  • filesys: no limit besides fitsize
  • fitsize: 50MB

5530: Kernel-args

Embedded in FIT-Image:

  • There are no embedded kernel-args in 5530 fit.

From supportdata bootlog:

  • There is no Kernel command line in 5530 bootlog.

5530: Recovery upload

env: memsize 0x40000000

SETENV memsize 0x3d470000
SETENV SETENV kernel_args_tmp "avm_fwupdate mtdram1=0x5d470000,0x60000000 mtdparts_ext=update-image.0:0x2b90000@0x0(fit-image)"
TYPE I
MEDIA SDRAM
P@SW
STOR 0x5d470000 0x60000000

The 5530 RAM is located at 0x20000000 to 0x60000000.

  • The 5530 flashing method research is finished, see the EVA-Upload section below.
  • The 5530 was experimentally freetzed, but that's still a big todo, see this github issue.

6000[edit]

6000: Partition layout

Bootloader-Environment:

firstfreeaddress	0x50500000
flashsize nor_size=0MB sflash_size=0KB nand_size=0MB emmc_size=1888MB
linux_fs_start 0
memsize	0x40000000
...
mtd0	0x0,0x0
mtd1	0x3000000,0x8000000 = 80MB = fit0/1
mtd2	0x0,0x2000000 = 32MB = urlader - wtf
mtd3	0x2000000,0x3000000 = 16MB = nand-tffs
mtd4	0x8000000,0xD000000 = 80MB = fit1/0
mtd5	0xD000000,0x75FFBE00 = 1680MB (1679.98389MB) = not ubi!

The 1888MB NAND is splitted into 80+80MB fit + 32MB urlader + 16MB nand-tffs + 1680MB not ubi = 1888MB.
This layout looks pretty unusual, maybe it's from a developer box.

Linux-Partitions:

  • There's no partition info in supportdata, neither in bootlog nor does a mtd device listing exist.

6000: FIT-Image listings

Stored names:

41208000-41527046  3272774 qcaarmv8_HW253_kernel
41c30000-41c33cdd    15581 qcaarmv8_HW253_flat_dt_0
41c30000-41c33d0e    15630 qcaarmv8_HW253_flat_dt_2
43000000-44000000 16777216 qcaarmv8_HW253_squashFS_filesystem
43000000-44100000 16777216 * kernel-args *

Freetz names:

41208000-41527046  3272774 kernel.image
41c30000-41c33cdd    15581 flatdt_0.image
41c30000-41c33d0e    15630 flatdt_2.image
43000000-44000000 16777216 filesystem.image
43000000-44100000 16777216 * kernel-args *

Structure:

Size limits:

  • kernel: 0x41c30000-0x41208000 = 0xA28000 = 10649600 bytes = ca. 10.16 MB
  • filesys: no limit besides fitsize
  • fitsize: 80MB

6000: Kernel-args

Embedded in 2 FIT-Images:

env: firstfreeaddress 0x50500000      =>   0x50500000 - 0x43000000 = 0xD500000 = 213MB = hmmmm!?!

01326f3c  hunk 3 #95 [4] - load = 0x43000000
01326f4c  hunk 3 #267 [97] - avm,kernel-args = 'mtdram=ram-filesystem,0x43000000,0x44100000 mtdparts_ext=ram-filesystem:16777216@0x0(rootfs_ram)'

0130fbf4  hunk 3 #95 [4] - load = 0x43000000
0130fc04  hunk 3 #267 [97] - avm,kernel-args = 'mtdram=ram-filesystem,0x43000000,0x44000000 mtdparts_ext=ram-filesystem:16609280@0x0(rootfs_ram)'

From 2 supportdata bootlogs:

[    0.000000]    Kernel command line: mtdram=ram-filesystem,0x43000000,0x44100000 mtdparts_ext=ram-filesystem:16777216@0x0(rootfs_ram) block2mtd.block2mtd=/dev/mmcblk0p18,0x400000,nand-tffs  console=ttyMSM0,115200,n8 swiotlb=1 audit=1
[    0.000000][0] Kernel command line: mtdram=ram-filesystem,0x43000000,0x44000000 mtdparts_ext=ram-filesystem:16605184@0x0(rootfs_ram) block2mtd.block2mtd=/dev/mmcblk0p18,0x400000,nand-tffs  console=ttyMSM0,115200,n8 swiotlb=1 audit=1

6000: Recovery upload

env: memsize 0x40000000     =>   0x40000000 - 19988559 = 0x3ECEFFB1
fit-image: 19988559 = 0x131004F

SETENV memsize 0x3ece0000
SETENV kernel_args_tmp "avm_fwupdate mtdram1=0x7ece0000,0x80000000 mtdparts_ext=update-image.0:0x1320000@0x0(fit-image)"
TYPE I
MEDIA SDRAM
P@SW
STOR 0x7ece0000 0x80000000

The 6000 RAM is located at 0x40000000 to 0x80000000.

  • The 6000 flashing method research is finished, see the EVA-Upload section below.
  • The 6000 was successfully freetzed, see this github commit.

4060[edit]

4060: Partition layout

Bootloader-Environment:

firstfreeaddress	0x50500000
flashsize	nor_size=0MB sflash_size=0KB nand_size=0MB emmc_size=1888MB
linux_fs_start	1
memsize:  0x40000000
...
mtd0:  0x0,0x0
mtd1:  0x3000000,0x8000000 = 80MB = fit0/fit1
mtd2:  0x0,0x2000000 = 32MB = urlader
mtd3:  0x2000000,0x3000000 = 16MB = nand-tffs
mtd4:  0x8000000,0xD000000 = 80MB = fit1/fit0
mtd5:  0xD000000,0x75BFC000 = 1676MB (1675,984375) = data

Linux-Partitions:

major minor  #blocks  name
   1        0       4096 ram0 = 16 x 4MB RAM
                         ....
   1       15       4096 ram15
  31        0      26344 mtdblock0 = 25.7MB = rootfs_ram (ram-filesystem, squashfs)
  31        1      16384 mtdblock1 = 16MB = bootloader_ram ???
 179        0    1933312 mmcblk0 = 1888MB = gpt (full emmc)
 179        1        495 mmcblk0p1 = 495KB = alignto512
 179        2        512 mmcblk0p2 = 512KB = 0:SBL1
 179        3        256 mmcblk0p3 = 256KB = 0:BOOTCONFIG
 179        4        256 mmcblk0p4 = 256KB = 0:BOOTCONFIG1
 179        5       4096 mmcblk0p5 = 4MB = 0:QSEE
 179        6       4096 mmcblk0p6 = 4MB = 0:QSEE_1
 179        7        256 mmcblk0p7 = 256KB = 0:DEVCFG
 179        8        256 mmcblk0p8 = 256KB = 0:DEVCFG_1
 179        9        256 mmcblk0p9 = 256KB = 0:RPM
 179       10        256 mmcblk0p10 = 256KB = 0:RPM_1
 179       11        256 mmcblk0p11 = 256KB = 0:CDT
 179       12        256 mmcblk0p12 = 256KB = 0:CDT_1
 179       13        512 mmcblk0p13 = 512KB = 0:APPSBL
 179       14        512 mmcblk0p14 = 512KB = 0:APPSBL_1
 179       15        512 mmcblk0p15 = 512KB = 0:CONFIG"
 179       16        512 mmcblk0p16 = 512KB = 0:CONFIG"_1
 179       17      81920 mmcblk0p17 = 80MB = fit0 (fit-image)
 179       18      16384 mmcblk0p18 = 16MB = nand-tffs (tffs)
 179       19      81920 mmcblk0p19 = 80MB = fit1 (fit-image)
 179       20    1716208 mmcblk0p20 = 1676MB = data (ext4)
 179       32        512 mmcblk0rpmb

4060: FIT-Image listings

Stored names:

41208000-41538c85  3345541 qcaarmv8_HW261_kernel
41c66000-41c69f06    16134 qcaarmv8_HW261_flat_dt_1
41c66000-41c69f06    16134 qcaarmv8_HW261_flat_dt_0
41c66000-41c69ee3    16099 qcaarmv8_HW261_flat_dt_2
43000000-4497d000 26726400 qcaarmv8_HW261_squashFS_filesystem
43000000-44a00000 26726400 * kernel-args *

Freetz names:

41208000-41538c85  3345541 kernel.image
41c66000-41c69f06    16134 flatdt_1.image
41c66000-41c69f06    16134 flatdt_0.image
41c66000-41c69ee3    16099 flatdt_2.image
43000000-4497d000 26726400 filesystem.image
43000000-44a00000 26726400 * kernel-args *

Structure:

Size limits:

  • kernel: 0x41c30000-0x41208000 = 0xA5E000 = 10870784 bytes = ca. 10.37 MB
  • filesys: no limit besides fitsize
  • fitsize: 80MB

4060: Kernel-args

Embedded in 2 FIT-Images:

firstfreeaddress	0x50500000      =>   0x50500000 - 0x43000000 = 0xD500000 = 213MB = hmmmm!?!

01cb9f6c  hunk 3 #95 [4] - load = 0x43000000
01cb9f7c  hunk 3 #267 [97] - avm,kernel-args = 'mtdram=ram-filesystem,0x43000000,0x44a00000 mtdparts_ext=ram-filesystem:26726400@0x0(rootfs_ram)'

01cf7064  hunk 3 #95 [4] - load = 0x43000000
01cf7074  hunk 3 #267 [97] - avm,kernel-args = 'mtdram=ram-filesystem,0x43000000,0x44a00000 mtdparts_ext=ram-filesystem:26955776@0x0(rootfs_ram)'

From 2 supportdata bootlogs:

[    0.000000] Kernel command line: mtdram=ram-filesystem,0x43000000,0x44a00000 mtdparts_ext=ram-filesystem:26976256@0x0(rootfs_ram) block2mtd.block2mtd=/dev/mmcblk0p18,0x400000,nand-tffs  console=ttyMSM0,115200,n8 swiotlb=1 audit=1

[    0.000000] Kernel command line: mtdram=ram-filesystem,0x43000000,0x44a00000 mtdparts_ext=ram-filesystem:26955776@0x0(rootfs_ram) block2mtd.block2mtd=/dev/mmcblk0p18,0x400000,nand-tffs  console=ttyMSM0,115200,n8 swiotlb=1 audit=1

4060: Recovery upload

firstfreeaddress	0x50500000
memsize:  0x40000000

SETENV memsize 0x3e300000
SETENV kernel_args_tmp "avm_fwupdate mtdram1=0x7e300000,0x80000000 mtdparts_ext=update-image.0:0x1d00000@0x0(fit-image)"
TYPE I
MEDIA SDRAM
P@SW
STOR 0x7e300000 0x80000000

The 4060 RAM is located at 0x40000000 to 0x80000000.

  • The 4060 flashing method research is finished, see the EVA-Upload section below.
  • The 4060 was successfully freetzed, see this github commit.

1200ax[edit]

The 1200ax uses a nested fit-image. The outer image consists of SquashFS and Kernel binaries, the Kernel part (type "avm,fit") is not checksummed and is an inner FIT image, containing the real Kernel and Flat Device-Tree binaries. Unless it has to be altered it could be treated as a black box kernel.image.

1200ax: Partition layout

Bootloader-Environment:

firstfreeaddress	0x4B000000
flashsize	nor_size=0MB sflash_size=0KB nand_size=128MB
linux_fs_start	1
memsize	0x10000000
---
mtd0	0x0,0x1C00000 = 28MB = filesystem
mtd1	0xD40000,0x1540000 = 8MB = fit0
mtd2	0x0,0x540000 = 5.25MB = urlader
mtd3	0x540000,0xD40000 = 8MB = nand-tffs
mtd4	0x1540000,0x1D40000 = 8MB = fit1
mtd5	0x1D40000,0x8000000 = 98,75MB = ubi

The 128MB NAND is splitted into 8+8MB fit + 5.25MB urlader + 8MB nand-tffs + 98,75MB ubi = 128MB.
The fit partitions are obviously for the inner FIT (ca. 3.5MB), the filesystem is stored in ubi.
Do not try the PUT mtd1 method with the outer FIT image, it may brick your device!

Linux-Partitions:

There's no mtd device listing in supportdata but this could be constructed from the bootlog:

mtd0    fit0
mtd1    urlader
mtd2    nand-tffs
mtd3    fit1
mtd4    ubi
mtd5    - reserved-filesystem
mtd6    - filesystem
mtd7    - config
mtd8    - avm_update

mtd5-9 may be wrong since the ubi contains one internal volume and may shift all by 1;

[    4.106334][0] ubi0: attached mtd4 (name "ubi", size 98 MiB)
[    4.106362][0] ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
[    4.111102][0] ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
[    4.118106][0] ubi0: VID header offset: 2048 (aligned 2048), data offset: 4096
[    4.125200][0] ubi0: good PEBs: 790, bad PEBs: 0, corrupted PEBs: 0
[    4.132248][0] ubi0: user volume: 4, internal volumes: 1, max. volumes count: 128

1200ax: FIT-Image listings

Stored names:

outer image:
41208000-4157010f  3571983 maple_HW268_kernel
43000000-441de000 18735104 maple_HW268_squashFS_filesystem
43000000-44200000 18735104 * kernel-args *

inner image:
found 3571983 bytes inner fit-image at offset 0x00000138 (312)
41208000-4156cda3  3558819 maple_HW268_kernel
41ed3000-41ed5e73    11891 maple_HW268_flat_dt_0

Freetz names:

outer image:
41208000-4157010f  3571983 kernel.image
43000000-441de000 18735104 filesystem.image
43000000-44200000 18735104 * kernel-args *

inner image:
found 3571983 bytes inner fit-image at offset 0x00000138 (312)
41208000-4156cda3  3558819 kernel.image
41ed3000-41ed5e73    11891 flatdt_0.image

Structure:

Size limits:

  • kernel: 0x41ed3000-0x41208000 = 0xCCB000 = 13414400 bytes = ca. 12.79 MB - theory
  • inner fit: 8MB
  • filesys: 28MB
  • fitsize: no limit besides the above

1200ax: Kernel-args

Embedded in FIT-Image:

0154634c  hunk 3 #95 [4] - loadaddr = 0x43000000
0154635c  hunk 3 #115 [97] - avm,kernel-args = 'mtdram=ram-filesystem,0x43000000,0x44200000 mtdparts_ext=ram-filesystem:18735104@0x0(rootfs_ram)'

From supportdata bootlog:

[    0.000000][0] Kernel command line:  swiotlb=1 slub_debug=

1200ax: Recovery upload

env: firstfreeaddress	0x4B000000
env: memsize	0x10000000
SETENV memsize 0xeb60000
SETENV kernel_args_tmp "avm_fwupdate mtdram1=0x4eb60000,0x50000000 mtdparts_ext=update-image.0:0x14a0000@0x0(fit-image)"
TYPE I
MEDIA SDRAM
P@SW
STOR 0x4eb60000 0x50000000

The 1200ax RAM is located at 0x40000000 to 0x50000000.

  • The 1200ax flashing method research is finished, see the EVA-Upload section below.
  • The 1200ax was successfully freetzed, see this github commit.

7510[edit]

The 7510 uses a nested fit-image. The outer image consists of SquashFS and Kernel binaries, the Kernel part (type "avm,fit") is not checksummed and is an inner FIT image, containing the real Kernel and Flat Device-Tree binaries. Unless it has to be altered it could be treated as a black box kernel.image.

7510: Partition layout

Bootloader-Environment:

firstfreeaddress	0x4B000000
flashsize	nor_size=0MB sflash_size=0KB nand_size=128MB
linux_fs_start	0
memsize	0x20000000
...
mtd0	0x0,0x2A00000 = 42MB = filesystem
mtd1	0xD40000,0x1540000 = 8MB = fit0
mtd2	0x0,0x540000 = 5.25MB = urlader
mtd3	0x540000,0xD40000 = 8MB = nand-tffs
mtd4	0x1540000,0x1D40000 = 8MB = fit1
mtd5	0x1D40000,0x8000000 = 98.75MB = ubi

The 128MB NAND is splitted into 8+8MB fit + 5.25MB urlader + 8MB nand-tffs + 98,75MB ubi = 128MB.
The fit partitions are obviously for the inner FIT (ca. 3.5MB), the filesystem is stored in ubi.
Do not try the PUT mtd1 method with the outer FIT image, it may brick your device!

Linux-Partitions:

major minor  #blocks  name
   1        0       4096 ram0 = 16 x 4MB RAM
                         ....
   1       15       4096 ram15
  31        0       8192 mtdblock0 = 8MB = fit0
  31        1       5376 mtdblock1 = 5.25MB = urlader
  31        2       8192 mtdblock2 = 8MB = nand-tffs
  31        3       8192 mtdblock3 = 8MB = fit1
  31        4     101120 mtdblock4 = 98.75MB = ubi
  31        5      43028 mtdblock5 = 42MB = filesystem
  31        6      43028 mtdblock6 = 42MB = reserved-filesystem
  31        7       2108 mtdblock7 = 2.06MB = config
  31        8       4340 mtdblock8 = 4.24MB = nand-filesystem

ubi has an internal volume which is 101120−43028−43028−2108−4340 = 8616 blocks = 8.41MB

[    6.302564][0] ubi0: attached mtd4 (name "ubi", size 98 MiB)
[    6.302591][0] ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
[    6.307283][0] ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
[    6.314363][0] ubi0: VID header offset: 2048 (aligned 2048), data offset: 4096
[    6.321452][0] ubi0: good PEBs: 790, bad PEBs: 0, corrupted PEBs: 0
[    6.328483][0] ubi0: user volume: 4, internal volumes: 1, max. volumes count: 128

7510: FIT-Image listings

Stored names:

outer image:
41208000-415721f7  3580407 maple_HW271_kernel
43000000-44b4d000 28626944 maple_HW271_squashFS_filesystem
43000000-44c00000 28626944 * kernel-args *

inner image:
found 3580407 bytes inner fit-image at offset 0x00000138 (312)
41208000-4156b8d7  3553495 maple_HW271_kernel
41ed5000-41ed8166    12646 maple_HW271_flat_dt_2
41ed5000-41ed8175    12661 maple_HW271_flat_dt_0

Freetz names:

outer image:
41208000-415721f7  3580407 kernel.image
43000000-44b4d000 28626944 filesystem.image
43000000-44c00000 28626944 * kernel-args *

inner image:
found 3580407 bytes inner fit-image at offset 0x00000138 (312)
41208000-4156b8d7  3553495 kernel.image
41ed5000-41ed8166    12646 flatdt_2.image
41ed5000-41ed8175    12661 flatdt_0.image

Structure:

Size limits:

  • kernel: 0x41ed5000-0x41208000 = 0xCCD000 = 13422592 bytes = ca. 12.80 MB - theory
  • inner fit: 8MB
  • filesys: 42MB
  • fitsize: no limit besides the above

7510: Kernel-args

Embedded in outer FIT-Image (kernel-args are always args of the squashfs):

01eb7434  hunk 3 #95 [4] - load = 0x43000000
01eb7444  hunk 3 #115 [97] - avm,kernel-args = 'mtdram=ram-filesystem,0x43000000,0x44c00000 mtdparts_ext=ram-filesystem:28626944@0x0(rootfs_ram)'

From supportdata bootlog:

[    0.000000][0] Kernel command line:  swiotlb=1 slub_debug=

7510: Recovery upload

  • TODO: There is no recovery dump yet

Strings from the recovery:

SETENV memsize 0x%x
SETENV kernel_args_tmp mtdram%u=0x%x,0x%x   =>  filesystem + kernel image ram upload
avm_fwupdate   =>  %s for the following:
SETENV kernel_args_tmp "%smtdram1=0x%x,0x%x mtdparts_ext=update-image.0:0x%x@0x0(fit-image)"  =>  fit-image ram upload

5590[edit]

5590: Partition layout

Bootloader-Environment:

firstfreeaddress	0x50500000
flashsize	nor_size=0MB sflash_size=0KB nand_size=0MB emmc_size=1888MB
linux_fs_start    1
memsize	0x40000000
...
mtd0	0x0,0x0
mtd1	0x3000000,0x8000000 = 80MB = fit0/fit1
mtd2	0x0,0x2000000 = 32MB = urlader?
mtd3	0x2000000,0x3000000 = 16MB = nand-tffs?
mtd4	0x8000000,0xD000000 = 80MB = fit1/fit0
mtd5	0xD000000,0x75BFC000 = 1676MB = ubi?

Linux-Partitions:

major minor  #blocks  name
   1        0       4096 ram0 = 16 x 4MB RAM
                         ....
   1       15       4096 ram15
  31        0      27400 mtdblock0 = 26.8MB = rootfs_ram (ram-filesystem, squashfs)
  31        1      16384 mtdblock1 = 16MB = bootloader_ram ???
 179        0    1933312 mmcblk0 = 1888MB = gpt (full emmc)
 179        1        495 mmcblk0p1 = 495KB = alignto512
 179        2        512 mmcblk0p2 = 512KB = 0:SBL1
 179        3        256 mmcblk0p3 = 256KB = 0:BOOTCONFIG
 179        4        256 mmcblk0p4 = 256KB = 0:BOOTCONFIG1
 179        5       4096 mmcblk0p5 = 4MB = 0:QSEE
 179        6       4096 mmcblk0p6 = 4MB = 0:QSEE_1
 179        7        256 mmcblk0p7 = 256KB = 0:DEVCFG
 179        8        256 mmcblk0p8 = 256KB = 0:DEVCFG_1
 179        9        256 mmcblk0p9 = 256KB = 0:RPM
 179       10        256 mmcblk0p10 = 256KB = 0:RPM_1
 179       11        256 mmcblk0p11 = 256KB = 0:CDT
 179       12        256 mmcblk0p12 = 256KB = 0:CDT_1
 179       13        512 mmcblk0p13 = 512KB = 0:APPSBL
 179       14        512 mmcblk0p14 = 512KB = 0:APPSBL_1
 179       15        512 mmcblk0p15 = 512KB = 0:CONFIG"
 179       16        512 mmcblk0p16 = 512KB = 0:CONFIG"_1
 179       17      81920 mmcblk0p17 = 80MB = fit0 (fit-image)
 179       18      16384 mmcblk0p18 = 16MB = nand-tffs (tffs)
 179       19      81920 mmcblk0p19 = 80MB = fit1 (fit-image)
 179       20    1716208 mmcblk0p20 = 1676MB = data (ext4)
 179       32        512 mmcblk0rpmb

5590: FIT-Image listings

Stored names: Note that prxB_HW0273_ramdisk is a gzip compressed cpio archive.

41208000-41543a43  3390019 qcaarmv8_HW272_kernel
41cd1000-41cd4f88    16264 qcaarmv8_HW272_flat_dt_0
43000000-44ac1000 28053504 qcaarmv8_HW272_squashFS_filesystem
43000000-44b00000 28053504 * kernel-args *
88000000-881230df  1192159 prxB_HW0273_kernel     # entryaddr = 0x88299590
884f2000-884f245e     1118 prxB_HW0273_flat_dt_0
8b000000-8b0f2667   992871 prxB_HW0273_ramdisk
70000000-703304dc  3343580 prxI_HW273_kernel      # entryaddr = 0x707a3c00
70fac000-70fadbda     7130 prxI_HW273_flat_dt_0_pon
70fac000-70fadbd4     7124 prxI_HW273_flat_dt_0_aon
73000000-7378d000  7917568 prxI_HW273_squashFS_filesystem
33000000-33800000  7917568 * kernel-args *

Freetz names: Note that filesystem3 is a gzip compressed cpio archive.

41208000-41543a43  3390019 kernel.image
41cd1000-41cd4f88    16264 flatdt_0.image
43000000-44ac1000 28053504 filesystem.image
43000000-44b00000 28053504 * kernel-args *
88000000-881230df  1192159 kernel3.image
884f2000-884f245e     1118 flatdt3_0.image
8b000000-8b0f2667   992871 filesystem3.image
70000000-703304dc  3343580 kernel2.image
70fac000-70fadbda     7130 flatdt2_0_pon.image
70fac000-70fadbd4     7124 flatdt2_0_aon.image
73000000-7378d000  7917568 filesystem2.image
33000000-33800000  7917568 * kernel-args *

Structure:

Size limits:

  • ARM kernel: 0x41cd1000-0x41208000 = 0xAC9000 = 11309056 bytes = ca. 10.79 MB
  • PRX kernel: 0x70fac000-0x70000000 = 0xFAC000 = 16433152 vytes = ca. 15.67 MB
  • fitsize: 80MB

5590: Kernel-args

Embedded in FIT-Image for the Hawkeye SoC:

01e00de4  hunk 3 #95 [4] - load = 0x43000000
01e00df4  hunk 3 #267 [97] - avm,kernel-args = 'mtdram=ram-filesystem,0x43000000,0x44b00000 mtdparts_ext=ram-filesystem:28053504@0x0(rootfs_ram)'

Embedded in FIT-Image for the PRX SoC:

02ad7e98  hunk 3 #95 [4] - load = 0x73000000
02ad7ea8  hunk 3 #267 [40] - avm,kernel-args = 'mtdram=rootfs_ram,0x33000000,0x33800000'

From supportdata bootlog:

[    0.000000][0] Kernel command line: mtdram=ram-filesystem,0x43000000,0x44b00000 mtdparts_ext=ram-filesystem:28057600@0x0(rootfs_ram) block2mtd.block2mtd=/dev/mmcblk0p18,0x400000,nand-tffs  console=ttyMSM0,115200,n8 swiotlb=1 audit=1 coherent_pool=2M vmalloc=400M

5590: Recovery upload

  • TODO: There is no recovery dump yet

Strings from the recovery:

  • TODO: There is no recovery yet

FRITZ!OS[edit]

Collecting files in FRITZ!OS which are only available in FIT models:

References

Fact-Box