EVA

EVA
EVA ist der neue AVM-Bootloader für Fritzboxen mit 2.6er Kernel und löst ADAM2 in den Fritzboxen nach und nach ab.
Konfiguration
EVA wird in den ersten 64kB des Flash gespeichert (mtd2, 0x90000000-0x90010000). In diesem Binary gibt es zwei Bereiche, die die grundlegende Konfiguration der Box "einfrieren". Bei Version 1203 (laut urlader-version aus dem Environment) liegt bei 0x90000AE0 der Defaultbereich und bei 0x90000580 der individuelle Bereich, der sich pro Box unterscheidet und unter anderem die MAC-Adressen enthält. Bei einer Box mit EVA kann man also durch zerstören des Environments seine MAC-Adressen nicht mehr verlieren, dafür aber auch nicht mehr so einfach ändern, da EVA die "eingefrorenen" Werte bei jedem Boot ggf. im Environment wieder auffrischt.
Wenn EVA nicht ab Werk installiert ist, sondern per Update auf die Box kommt, wird der individuelle Konfigbereich beim Update mit dem Utility urlader.setconfig24 erzeugt. Die Datei urlader.config im Update-Image enthält eine Liste mit Environmentnamen, die dabei "eingefroren" werden sollen (Liste aus dem 7050 Update 14.04.31, kann bei anderen Boxen evtl. abweichen):
maca overwrite macb overwrite macwlan overwrite macdsl overwrite usb_board_mac overwrite usb_rndis_mac overwrite bluetooth overwrite reserved overwrite HWRevision overwrite ProductID overwrite SerialNumber overwrite usb_device_id overwrite usb_revision_id overwrite usb_manufacturer_name overwrite annex overwrite
Der Konfigbereich selbst sieht in etwa so aus:
Offset | Länge | Bedeutung | Inhalt |
---|---|---|---|
0 | 4 | magic/version | 0x2 |
4 | 4 | EMIF[4] | 0x40000080 |
8 | 4 | EMIF[8] (SDRAM) | 0x00006021 |
12 | 4 | EMIF[12] (refresh) | 0x000003d5 |
16 | 4 | EMIF[32] (SDRAM 2) | 0x02215818 |
20 | 4 | EMIF[16] (CS0 flash) | 0x00b00581 |
24 | 4 | EMIF[20] (CS3) | 0x10908700 |
28 | 4 | EMIF[24] (CS4) | 0x05a62d34 |
32 | 4 | EMIF[28] (CS5) | 0x05a62d36 |
36 | 4 | RAM size | 0x02000000 |
40 | 4 | Flash size | 0x00400000 |
44 | 4 | unknown | 0x0 |
48 | 4 | unknown | 0x0 |
52 | 4 | MTD0 start | 0x90000000 |
56 | 4 | MTD0 length | 0x0 |
60 | 4 | MTD1 start | 0x90010000 |
64 | 4 | MTD1 length | 0x003b0000 |
68 | 4 | MTD2 start | 0x90000000 |
72 | 4 | MTD2 length | 0x00010000 |
76 | 4 | MTD3 start | 0x903c0000 |
80 | 4 | MTD3 length | 0x00020000 |
84 | 4 | MTD4 start | 0x903e0000 |
88 | 4 | MTD4 length | 0x00020000 |
92 | 4 | unknown | 0x0 |
96 | 4 | unknown | 0x0 |
100 | 4 | unknown | 0x9 |
104 | 4 | unknown | 0x0 |
108 | 4 | pointer to first free byte? | 0x90000670 |
112 | 4 | char * to first environment entry, more following | 0x9000096a |
... | 4 | end of pointer list | 0x0 |
... | ... | environment entry storage |
Es werden also die Einstellungen für den Memory Controller (EMIF), RAM und Flashgröße, MTD setup und ein paar wichtige, unveränderliche Environmentvariablen gespeichert.
Loaderformat für LZMA-komprimierte Binaries
Neben dem alten TI Binärformat unterstützt EVA auch LZMA-komprimierte Kernel ohne integrierten Entpacker. Diese Kernel werden von EVA vor dem Booten entpackt. Der neue Header sieht in etwa so aus:
magic: 0xfeed1281 32bit little endian
record: (wie TI-Format) length 32bit little endian loadaddress 32bit little endian data length bytes checksum Zweierkomplement der 32bit Summe über length (32bit Addition), loadaddress (32bit Addition), data (byteweise 8bit Addition)
lzma record: (innerhalb von data) 0x075a0201 32bit little endian (7'Z' 2.1?) unterscheidet/beschreibt evtl. den Record Inhalt? compressed length 32bit little endian uncompressed length 32bit little endian checksum 32bit little endian crc32 of compressed data compressed data compressed length + 8 bytes
lzma compressed data: lzma properties 8bit lzma dict size 32bit little endian alignment 24bit == 0x000000 packed data compressed length octets
entry record: (wie TI-Format) 0x0 32bit entryaddress 32bit little endian
Mit folgendem Perl-Skript lässt sich ein Kernel aus kernel.image entpacken:
#! /usr/bin/perl use Compress::unLZMA; use Archive::Zip; open INPUT, "<$ARGV[0]" or die "can't open $ARGV[0]: $!"; read INPUT, $buf, 4; $magic = unpack("V", $buf); if ($magic != 0xfeed1281) { die "bad magic"; } read INPUT, $buf, 4; $len = unpack("V", $buf); read INPUT, $buf, 4*2; # address, unknown read INPUT, $buf, 4; $clen = unpack("V", $buf); read INPUT, $buf, 4; $dlen = unpack("V", $buf); read INPUT, $buf, 4; $cksum = unpack("V", $buf); printf "Archive checksum: 0x%08x\n", $cksum; read INPUT, $buf, 1+4; # properties, dictionary size read INPUT, $dummy, 3; # alignment $buf .= pack('VV', $dlen, 0); # 8 bytes of real size #$buf .= pack('VV', -1, -1); # 8 bytes of real size read INPUT, $buf2, $clen; $crc = Archive::Zip::computeCRC32($buf2); printf "Input CRC32: 0x%08x\n", $crc; if ($cksum != $crc) { die "wrong checksum"; } $buf .= $buf2; $data = Compress::unLZMA::uncompress($buf); unless (defined $data) { die "uncompress: $@"; } open OUTPUT, ">$ARGV[1]" or die "can't write $ARGV[1]"; print OUTPUT $data; #truncate OUTPUT, $dlen;
Quellenangaben
http://www.wehavemorefun.de/fritzbox