Acer Iconia A500
This is an attempt to summarize and extend the current knowledge about the Acer Iconia A500 tablet.
TOC
- Hardware
- Partition layout
- Flashing
- Rooting
- Cross compiling
- Various
- Download
Hardware
- Name: Acer Iconia A500
- Code name: picasso
- Model: Tegra 250 T20
- CPU: 1 GHz dual-core ARM Cortex-A9
- Instruction set: ARMv7
- RAM: 1024MB
- Internal storage: 32GB eMMC
- Display resolution: 1280x800px
- Compass: AKM8975
- Light sensor: AL3000A
Tegra reserved memory: | ||
---|---|---|
LP0: | 1840c000 | 1840dfff |
Bootloader framebuffer: | 00000000 | ffffffff |
Framebuffer: | 2e700000 | 2eefffff |
2nd Framebuffer: | 2ef00000 | 2fefffff |
Carveout: | 2ff00000 | 3fefffff |
Kernel command line: nvmem=128M@384M mem=1024M@0M vmalloc=256M video=tegrafb console=none usbcore.old_scheme_first=1 lp0_vec=8192@0x1840c000 tegraboot=sdmmc gpt
Partition layout
The parition layout is in a NVIDIA proprietary format with no public official specification. It have however been reverse engineered based on the Toshiba AC100/Dynabook AZ: Patch nvtegra.c and here.
ID | Name | Type | Size | Image | Device | Mountpoint |
---|---|---|---|---|---|---|
2 | BCT | boot_config_table (basic) | 3145728 (3M) | |||
3 | PT | partition_table (basic) | 4096*128 (4K data repeated) | |||
4 | EBT | bootloader (basic) | 4194304 (4M) | bootloader.bin | ||
5 | GP1 | GP1 (basic) | 1048576 (1M) | |||
6 | SOS | data (basic) | 5242880 (5M) | recovery.img | mmcblk0p1 | |
7 | LNX | data (basic) | 8388608 (8M) | boot.img | mmcblk0p2 | |
8 | APP | data (ext4) | 629145600 (600M) | system.img | mmcblk0p3 | /system |
9 | CAC | data (ext3) | 1283457024 (1224M) | mmcblk0p4 | /cache | |
10 | MSC | data (ext3) | 4194304 (4M) | mmcblk0p5 | ||
11 | FLX | data (ext4) | 104857600 (100M) | flexrom.img | mmcblk0p6 | /system/vendor |
12 | AKB | data (basic) | 10485760 (10M) | mmcblk0p7 | ||
13 | UDA | data (ext3) | 29955719168 (28568M) | mmcblk0p8 | /data | |
14 | GPT | GPT (basic) | 0xFFFFFFFFFFFFFFFF |
/mnt/sdcard is fuse mounted from /data/media.
BCT and EBT are encrypted using the SBK.
Boot Config Table (BCT)
The Boot Config Table (BCT) contain quite a bit of information. There is a bct_dump tool available trough the chromium project, the source can be found in the cbootimage repository.
File layout
Offset | Size | Description |
---|---|---|
0x0 | 0x10 | Checksum - AES-CMAC of the rest of the file |
0x10 | 0x10 | All zero? |
0x20 | 0x4 | Version (0x20001) |
0x24 | 0x4 | Block size in log2 (14 => 2**14 = 0x4000) |
0x28 | 0x4 | Page size in log2 (9 => 2**9 = 0x200) |
0x2C | 0x4 | Partition size (0x1000000) |
0x30 | 0x4 | Number of parameter sets (0x4) |
0x34 | 0x4 | Device 1 type 0: None 1: NAND 3: SPI 4: SDMMC 5: MAX |
0x38 | 0x4 | Device 2 type |
0x3C | 0x4 | Device 3 type |
0x40 | 0x4 | Device 4 type |
0x44 | 0x10 | Device 1 params |
0x54 | 0x10 | Device 2 params |
0x64 | 0x10 | Device 3 params |
0x74 | 0x10 | Device 4 params |
0x84 | 0x4 | Number of SDRAM sets (0x4) |
0x88 | 0x200 | SDROM set 1? |
0x288 | 0x200 | SDROM set 2? |
0x488 | 0x200 | SDROM set 3? |
0x688 | 0x200 | SDROM set 4? |
0x888 | 0x? | Bad block table? |
0xA90 | 0x4 | Active Boot loader |
Boot loader 1 | ||
0xA94 | 0x4 | Boot loader version |
0xA98 | 0x4 | Boot loader start block |
0xA9C | 0x4 | Boot loader start page |
0xAA0 | 0x4 | Boot loader length |
0xAA4 | 0x4 | Boot loader load address |
0xAA8 | 0x4 | Boot loader entry point |
0xAAC | 0x4 | Boot loader attribute |
0xAB0 | 0x10 | Boot loader hash |
Boot loader 2 | ||
Boot loader 3 | ||
Boot loader 4 | ||
0xB44 | 0x4A8 | Customer Data |
0xFEC | 0x1 | Enable Fail Back |
0xFED | 0x3 | Reserved (padding) |
ODM Data
ODM Data is a 32bit value that can be found at offset 0xfe4 in the BCT.
The bitfield values for ODM Data is specified in tegra_devkit_custopt.h.
Bits | Use | Values |
---|---|---|
0-7 | PERSONALITY | ... |
8-10 | TRANSPORT | 0 = DEFAULT 1 = NONE 2 = UART 3 = USB 4 = ETHERNET |
11-12 | UART | 0 = DEFAULT 1 = A 2 = B 3 = C |
13-14 | ETHERNET | 0 = DEFAULT 1 = SPI |
15-17 | CONSOLE OPTION | 0 = UARTA (DEFAULT) 1 = UARTB ... 4 = UARTE |
18-19 | CONSOLE | 0 = DEFAULT 1 = NONE 2 = DCC 3 = UART |
20-22 | DISPLAY | 0 = EMBEDDED (DEFAULT) 1 = HDMI 3 = CRT |
23 | DHCP | 0 = DEFAULT 1 = ENABLED |
24-27 | ? | ... |
28-30 | MEMORY | 0 = 512MB 1 = 256MB 2 = 512MB 3 = 1024MB |
31 | LPSTATE | 0 = LP0 1 = LP1 |
So with ODM 0x300d8011 = 0 011 0000 0 000 11 011 00 00 000 00010001 we get
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
PERSONALITY | TRANSPORT | UART | ETH | CONSOLE | CONSOLE | DISPLAY | DHCP | ? | MEMORY | LPSTATE | |||||||||||||||||||||
1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 |
VOYAGER, eMMC, with TRACE | DEFAULT | DEFAULT | DEFAULT | UARTD | UART | EMBEDDED | DEFAULT | ? | 1024M | LP0 |
Partition Table (PT)
The custom Tegra partition table.
Booloader (EBT)
- Load address = 0x00108000
- Entry point = 0x00108000
- Attributes = 0x00000004 (?)
Boot verification... checking checksums, signing?
Boot Partitons (LNX and SOS)
The boot partitons LNX and SOS contain combined kernel and initrd images, following the format described in bootimg.h
AKB
Checksums for the rest of the partitions, and what more?
Seems to contain Widevine DRM key storage?
To trigger a rebuild of the checksums on boot replace 64 bytes at offset 0x84 with "00 FB 30 94 99 01 4F 97 2E 4C 2B A5 18 6B DD 06" x 4.
Flashing
When in APX mode the device can be flashed using NVIDIA's nvflash.
Secure Boot Key (SBK)
A description of what Secure Boot Key (SBK) is can be found at http://androidroot.mobi/technical/tf-secure-boot-key/.
The SBK used for the Iconia A500 is generated based on the UID of the device and thus unique for each device.
Getting the UID
From a working device
The UID is also the USB serial numer of the device.
The serial can be extracted from HAL:
hal-get-property --udi "$(hal-find-by-property --key 'info.product' --string 'Iconia tablet A500')" --key 'usb_device.serial'
From APX mode
The device will respond with the UID to the first read after it have been started in APX. See apxuid.
Generating the SBK
For clarification, as there seem to be some confusion, this describes a vendor/model specific algorithm that is used by a few Acer models.
To generate the SBK from the UID (assumign UID is a hexadecimal string)
- Discard any leading 0x in the UID
- Split the UID into four 4 character strings
- For each part, take the ascii values and multiply with 100 raised to the position.
e.g. "89AB" => 56*100**3 + 57*100**2 + 65*100**2 + 66*100**0 = 56576566. - xor
- If using a little-endian architecture, swap the byte order
- Print the key
A C implementation of the algorithm for generating the key can be found here.
Decrypting data encrypted with the SBK
The SBK is used to encrypt BCT and EBT AES128 CBC. A small tool to decrypt (libgcrypt based) can be found here.
APX Mode
APX mode is the NVIDIA Tegra recovery mode, when in APX mode the device will identify as a NVIDIA device 0955:7820. There are a few different ways to get the A500 into APX mode.
- Using a root shell:
- sync; sync; sync; echo 5 > /sys/EcControl/RecoveryMode
- Using cmdclient
- sync; sync; sync; cmdclient ec_recovery
- Using hardware:
- Unplug and power off the device
- Press the reset button
- Press the power button for 3 seconds
- Release the power button
- Wait 1 second, release the reset button
- Connect the USB cable
It might also be a good idea to create a udev rule to expand write access to the APX device.
cat /etc/udev/rules.d/51-android.rules
SUBSYSTEM=="usb", ATTR{idVendor}=="0502",ATTR{idProduct}=="3325", MODE="0666", SYMLINK+="a500" SUBSYSTEM=="usb", ATTR{idVendor}=="0955",ATTR{idProduct}=="7820", MODE="0666"
Acquiring nvflash
Nvflash is part of the Linux for Tegra package available from Tegra 250 & Tango Development Kits.
dmesg on the Iconia A500 says something about ventana, can we use the ventana fastboot.bin? The profile in the ODM Data points in another direction?
Extracting BCT
In here lies a dilemma, to extract the BCT using nvflash we need the BCT.
As root we can use dd from mmcblk0 and then decryp using the SBK, if we don't have root our only choice seems to be to find a matching BCT somewhere else...
$ cat /data/local/tmp/test.sh
#!/system/bin/sh echo test /system/bin/dd if=/dev/block/mmcblk0 bs=512 count=13312 of=/sdcard/mmcblk0_start
$ cmdclient ec_micswitch \`/data/local/tmp/test.sh\`
Then we can extract the bct from the dump
./sbkdecrypt --sbk 0x00000000 0x00000000 0x00000000 0x00000000 mmcblk0_start a500.bct 0x0 0xFF0
The first 16 bytes are not actually part of the encrypted data, they are a AES-CMAC checksum for the other 4064 bytes, so decrypting like this will actually not get the correct result for the first 32 bytes (as we are using CBC we mess up the decryption of the first block by decrypting the block before it). This does not really seem to matter in how it is used though.
And the odm data:
hexdump -n 4 -s 0xfe4 -e '1/4 "0x%08x\n"' a500.bct
0x300d8011
Extracting bootloader
The bootloader can also be extracted from the dump
./sbkdecrypt --sbk 0x00000000 0x00000000 0x00000000 0x00000000 mmcblk0_start bootloader.bin 0x280000 0xAE691
Using nvflash
./nvflash --bl acer.bin --sbk 0x00000000 0x00000000 0x00000000 0x00000000 --getpartitiontable test.txt
Fails due to "Bct file not found"
--getpartitiontable partitiontable.txt
./nvflash --bl bootloader.bin --getbct --bct backup.bct --go ./nvflash -r --getpartitiontable partition.txt ./nvflash -r --read 2 part2.imgThe APX Protocol
Undocumented. Could perhaps be a fun project to dump using wireshark and try to create an open alternative to nvflash.
Parts
- RCM - Used initially to get rcm version, upload miniloader, get some other device information
- Nv3p - Used after miniloader is uploaded to actually do stuff
Tracing a --getpartitiontable:
- Get UID
- Host does USB bulk read - Device returns USB serial/CPUID
- Get RCM version
- Host does USB bulk write of 1028 bytes - request for rcm version (?)
First 4B is Length, followed by a 16B hash, followed by the payload with some data inserted into.
In this case there is no payload so most of the data is zeros. - Host does USB bulk read - Device returns "01 00 02 00" = 0x20001 = rcm version
- Host does USB bulk write of 1028 bytes - request for rcm version (?)
- Upload miniloader
- Host does bulk writes, total of 4096*13 + 2980 = 56228 bytes
Same format as previous message but with the miniloader as payload, sending some MiniLoader, an image that is built info nvflash. - Host does USB bulk read - Device returns "00 00 00 00"
- Host does bulk writes, total of 4096*13 + 2980 = 56228 bytes
- Switch to using Nv3p messages
- Get System information
- Write 24B - Request for system information?
- Read 16B - Ack on the request
- Read 16B - system information? or just ack for the message?
- Read 48B - Starts with CPUID must be system information
- Read 4B - checksum for system information
- Write 16B - Ack
- ...
Rooting
Android 3.1 (Acer_A500_4.0.10.42_COM_GEN1) kernel 2.6.36.3
cmdclient can be exploited to run commands as root. For example cmdclient ec_micswitch \`mount -o remount,rw /system\`.
Cross compiling
Native binaries are always fun to have...
Acquiring a toolchain
There are a few choices on which toolchain to use, it seems using the one provided through the Android project may be easiest.
git clone git://github.com/android/platform_prebuilt.git
Building
blah blah
adb push <file> /data/local/tmp
Various
Mixed stuff that could be usefull.
USB Capture with WiresharkSome info on the ADB protocol
Download
- a500sbk
- sbkdecrypt
- apxuid (win32 source)