Skip to content

Instantly share code, notes, and snippets.

@pfalcon
Forked from sarg/README.md
Created October 2, 2013 22:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pfalcon/6801504 to your computer and use it in GitHub Desktop.
Save pfalcon/6801504 to your computer and use it in GitHub Desktop.

Obtaining RK3066 boot ROM.

Here are my steps.

At first, I took a look to RK30xxLoader(L)_V1.18.bin. This file appears in update.img for my device. So, I unpacked update.img using rk29Kitchen.

strings on that file returns nothing interesting, so I assumed the file is crypted

Next step was to get IDA pro, and disassemble RKAndroidTool.fexe - utility from rockchip for flashing device firmware. In disassembly I found, that loader is scrambled using RC4. File is split to 0x200 chunks and every chunk is scrambled.

So, I wrote unpack_loader.pl script, which gave me output of 4 files.

1   14a  321c 30_LPDDR2_300MHz_DD
2  3366  c914 rk30usbplug
4  fc7a  3400 FlashData
4 1307a 1ac00 FlashBoot

Fortunately, there were meaningful names for those files in loader.bin.

30_LPDDR2_300MHz_DD is a dram init procedure FlashData is a copy of dram init procedure, aligned to 512 bytes (flash block size)

rk30usbplug is MaskRom mode handler FlashBoot is stage2 for booting from NAND, and also it contains handler for DFU mode.

Those files were disassembled too, and in FlashBoot I found that there is command in DFU mode to obtain data from any DDR RAM region. So, my idea was to inject code in FlashBoot, which will copy bootrom to some address, accessible in DFU mode. But there was a problem, FlashBoot is overwriting memory at address 0 - it is where bootrom is located at power on. So, all I need is to copy 0x2800 bytes (boot ROM size) starting from 0x0 before FlasfhBoot overwrites it, and there you are -> bootrom.bin

So I wrote a set of tools for that. patch_loader.sh injects code pack_loader.pl resembles lFoader from parts and sign it with rkcrc.

So, all was done with this script.

perl unpack_loader.pl RK30xxLoader\(L\)_V1.18.bin write
sh patch_loader.sh FlashBoot.bin
perl pack_loader.pl dram=30_LPDDR2_300MHz_DD.bin boot=FlashBoot.bin.patched data=FlashData.bin usbplug=rk30usbplug.bin out=patchedLoader.bin

Flash patchedLoader.bin with RKAndroidTool.exe, and obtain loader with rkflashtool m 0x64000000 0x2800 > bootrom.bin

I uploaded bootrom.hex. Execute xxd -rp bootrom.hex > bootrom.bin to get bootrom.bin

Now, when all parts of loader are descrambled and could be disassembled, it is matter of time to port u-boot to this SoC, and boot any OS native.

RK3066 boot sequence

At power, rk30 starts from 0x0 offset in bootrom.

bootrom copies itself to SRAM, and proceeds to find dram init handler in idbrom
bootrom loads dram init handler in memory and executes it
bootroms search for flashboot and load it to memory
if flashboot could not be found, bootrom search for usbplug and load it

flashboot init NAND, search for parameter file, load kernel to DRAM and boot it

dcf09fe5dcf09fe5dcf09fe5dcf09fe5dcf09fe5c8f09fe5d8f09fe5d8f0
9fe5dcf09fe5feffffeafeffffeafeffffeafeffffea04f05ee204e04ee2
ff5f2de900104fe106002de9930500eb0600bde801f06fe1ff9ffde8a000
9fe50110a0e3001080e5b01f10ee0f1001e2000051e30700000ad3f021e3
8c209fe5001090e5020051e102f02013fbffff1a74109fe500f091e5d2f0
21e374109fe5012ba0e3021081e001d0a0e1d3f021e3012ba0e3021081e0
01d0a0e158009fe5010050e1feffff3a50f09fe500000fe18000c0e300f0
2fe10ef0a0e1010050e2fdffff8a0ef0a0e1580000002400000028000000
2c00000034000000380000003000000004000810141e000008000810afbe
adde00000000a8020810000c0810200100001800a0e34f0000eb5c0000eb
100702e34f0000ebf20300eb350700ebfeffffea70402de90030a0e12140
01e3ff0f0fe3011041e2010071e30050d3158020a0137080bd08020910e3
8008a0e12008a0e104002010020015e104002010a220b0e101308302f6ff
ff1af0ffffeaf0402de90040a0e3bc509fe50430a0e1b0609fe5012c45e2
0f4004e20330c2e70470d6e7014084e20370c5e7013083e2010c53e30040
a0230430a021f5ffff3a0360d2e70370d5e7064084e0074084e0ff4004e2
0470d2e70370c2e7013083e2010c53e30030a0230460c2e70350a0210340
a021f1ffff3a0f0000ea013083e2ff3003e20360d2e7065085e0ff5005e2
0570d2e70370c2e70560c2e70370d2e7076086e0ff6006e20470d0e70660
d2e7076026e00460c0e7014084e2010054e1edffff3af080bde894220000
5401081038009fe5000090e51eff2fe12c109fe5000081e51eff2fe12010
9fe510402de9001091e5910000e02410a0e3f70700eb000050e31080bd08
1040bde88effffea00000810b0109fe50202a0e3062781e2481080e56c20
80e51eff2fe1f0412de90242a0e3000094e5030050e3040094051f005003
080094050f005003f081bd0880009fe574509fe574609fe50c5084e5607a
c6e1000084e5046084e5087084e50100a0e3dbffffeb5c009fe50286a0e3
0c8084e53c5084e5300084e5346084e5387084e50100a0e3d2ffffeb3c80
84e5fa0fa0e3cfffffeb34109fe52c209fe5410681e1482084e56c1084e5
400084e5c000a0e3f041bde8c3ffffea00000733200020001f00ff1f0300
0f3f07000f3f006100f300100030f05f2de90180a0e1e4129fe50090a0e1
d8429fe50100a0e302a0a0e10370a0e100b0a0e3041091e5080084e50c00
84e5016083e0000058e304009914018048120a00000a000484e50050a0e3
240094e5080010e30a00000a0100a0e3a7ffffeb015085e2020055e3f7ff
ff3a090000ea000056e3ff00a01301604612f0ffff1a050000ea000894e5
070056e10100ca34020055e3e6ffff3a01b0a0e30000a0e30c0084e50800
84e58200a0e393ffffeb0b00a0e1f09fbde830029fe50212a0e310402de9
7f28a0e3a82081e50210a0e3c12402e3101080e5002080e51a0940e21012
9fe5b81080e50100a0e383ffffebfc119fe50000a0e30000c1e51080bde8
08402de9ff00a0e30030a0e30110a0e300008de50320a0e10d00a0e1b7ff
ffeb7d0ea0e375ffffebc4119fe50100a0e30000c1e50000a0e30880bde8
f0432de90290a0e1a8619fe514d04de20180a0e10020d6e5010052e31a00
008a000052e30045a0e10370a0e32c00000a1300a0e3542ae7e75436e7e7
241ea0e10f008de80030a0e30320a0e10410a0e30d00a0e19affffeb0000
50e30a00001ac010a0e30f00a0e30050a0e3f000cde10130a0e310208de2
0210a0e30d00a0e18fffffeb000050e30200000a0100a0e314d08de2f083
bde81000dde5010010e30500000a015085e20a0055e30200a0230000c625
edffff3af3ffffeaff1004e200708de55404e3e70930a0e10820a0e1f400
cde10310a0e30d00a0e178ffffebeaffffea5408e7e75414e7e7ff2004e2
04408de200708de50930a0e1070084e80820a0e10410a0e3f2ffffea7040
2de90060a0e19c509fe50000a0e30140a0e12020a0e3040085e50600a0e1
b3ffffeb000050e30020a0030e00001a0410a0e10200d4e73b0050e30210
81000100d1058c0050030400001a0200d1e5dc0050e30300d105fc005003
0400000a012082e21c0052e3f0ffff9a0100a0e37080bde81c0052e30420
85e5faffff8a0410a0e10600a0e1022ca0e37040bde897ffffea0110a0e3
1100a0e1c000a0e10001a0e11eff2fe1000007200c00081000aa00ff1415
9fe50000c1e51eff2fe10c159fe510402de9002091e59026cde7002081e5
002091e59027cfe7002081e5002091e51027cee7002081e5004091e5310c
00e3dc249fe50330a0e3014884e3004081e5580181e5302181e5343181e5
1080bde8f0412de90233a0e3b8049fe5b8149fe5a8549fe5b4249fe5e410
80e5e82080e5503180e50100a0e3ddfeffeb000095e50060a0e380449fe5
010a80e3000085e50c60c4e50860c4e50460c4e5040095e51f00c0e30200
80e27e0ec0e3800080e23f0ac0e3020a80e2040085e5080095e50070a0e3
010080e3080085e5108702e3000095e5020c10e30400001a0500a0e3c3fe
ffeb017087e2080057e1f7ffff3a080800e3008085e0ff10a0e30070a0e3
001088e5fa0fa0e3b9feffeb000095e5020c10e30200001a017087e2fa0f
57e3f7ffff3a040800e39010a0e3002085e0001088e5006082e5001895e5
002895e5ff0001e2ff2002e2021090e12900000aff0050e30100001aff00
52e32500000a0f10a0e3b8339fe50000a0e30050d3e7020055e101008012
00005111faffff8a010050e10150a0e30000a023106042220700003a0170
80e00770d3e7020057e106005711010080120c50c40500005111f7ffff8a
020050e30850c425012ca0232020a033b021c4210400003a0400009a0600
50e30450c4e5012ba0230000003ab021c4e1011041e2010050e10100a083
0000a093f081bde8ff00a0e3f081bde8f05f2de90150a0e1fcb29fe50060
a0e1f8429fe50290a0e10c10dbe5000094e50070a0e307a0a0e11106cce7
000084e5000059e30080a0134200000a000094e5020c10e30400001a0500
a0e368feffeb018088e2fa0f58e3f7ffff3a000094e501e0a0e3041800e3
0080a0e3ff3006e226c4a0e1082800e31e00c7e726e8a0e1041081e00000
84e5027084e7007081e5003081e500c081e500e081e50500a0e353feffeb
000094e5020c10e30200001a018088e2190e58e3f7ffff3a020b84e20c10
dbe5000051e30020a0130900000a001090e5012082e2010c52e30110c5e4
2134a0e10130c5e4000090257080ff26f6ffff3a080000ea002090e50110
81e2020c51e30120c5e4faffff3a001090e5008090e5ff0001e21084dfe7
000094e51700c7e7000084e5021ca0e3020c45e2e2fdffeb000058e101a0
a0130160860201904902b9ffff0a0a00a0e1f09fbde8f05f2de901b0a0e1
aca19fe50270a0e1a8419fe50080a0e30810dae5000051e33200000a0010
94e50c20dae51216cce7001084e5003094e50160a0e394c19fe52021a0e1
0050a0e3ffe002e22294a0e11630c7e7440d4ce0003084e500508ce50050
80e5005080e500e080e5009080e50410dae5000051e32218a01100108015
3000a0e300008ce5710200e304feffeb0020dae50610a0e10500a0e11800
52e31110a0030100000a100052e3120ba013a72486e0080080e30c1084e5
010b80e3a220a0e19202c6e7040080e30060a0e3080084e500919fe50100
a0e3f0fdffeb080094e5010610e30700001a030000ea0b10a0e1a224a0e1
f05fbde86bffffea016086e2090056e1f2ffff3a000094e51500c7e70000
84e5200094e50310a0e3040010e30180a013a70451e10100008a020910e3
0180a0130720a0e1011a84e20b00a0e12a0500eb000294e514008ae50800
a0e1f09fbde870402de91020a0e354409fe50050a0e10160a0e10020c4e5
022ca0e3a1ffffeb000050e30800000a1820a0e30020c4e5022ca0e30610
a0e10500a0e199ffffeb000050e30100a0137080bd180000a0e37080bde8
08109fe5b011d1e1900100e01eff2fe11400081000005010010028000080
0020004000c055555555a422000008085010a086010070402de90202a0e3
d0119fe5741080e50150a0e3c8419fe5045084e5400780e1c0219fe50a12
80e2bc319fe5e41080e5ec2080e5503180e550030ce3a0fdffeba8019fe5
000084e5c800a0e39cfdffeb9c019fe5105084e52c0084e550030ce397fd
ffeb8c019fe50114a0e388519fe50020e0e30030a0e3140084e5201084e5
442084e52c5084e570019fe5083080e50300a0e17080bde844219fe5ce10
0ae330402de9440092e50030a0e3010010e148119fe50200a01300308115
3080bd18034900e3085091e5040055e10300a0833080bd88020c10e30700
000a440092e50140a0e3025c80e30000a0e3445082e5043081e5004081e5
3080bde8080091e5012080e20100a0e3082081e53080bde8f05f2de90160
a0e1e0509fe5003095e5000053e31700000a041095e5b0409fe522b1a0e1
60aa0ee3c2920ae3808361e00070a0e3440094e5090010e10700001a4800
94e5040010e30400000a0100a0e357fdffeb017087e207005ae1f4ffff8a
0a0057e10300002a441094e50400a0e1090011e10300000a0000a0e30000
85e50100a0e3f09fbde8041095e5000058e3011081e2041085e500029015
0180481200008615e1ffff1a000290e501b05be2040086e40000a003dcff
ff1af09fbde8022ca0e3cdffffea0000a0e31eff2fe1003f003f00c02110
28003c0000080008030000010020208040f09408002200812c000810f34f
2de90150a0e104d04de278839fe504009de5001180e068039fe501a180e0
070055e3c800008a080055e305f18f304b0000ea460000ea050000ea0e00
00ea180000ea1e0000ea210000ea2c0000ea330000ea34239fe50100a0e3
0030a0e3021ba0e30000c2e524239fe50000c2e520039fe50030c0e50700
00ea0c239fe50100a0e3011ca0e30000c2e500239fe50000c2e5fc229fe5
0000c2e5f8029fe5b010c0e12f0000eae0129fe50000a0e32020a0e30000
c1e5d4129fe50000c1e50a0000ea0000a0e30120a0e32010a0e3180000ea
b4329fe50100a0e30010a0e3012ca0e30000c3e5a4329fe50010c3e5a012
9fe50000c1e59c029fe5b020c0e1180000ea84329fe50100a0e30020a0e3
011ca0e30000c3e574029fe50020c0e5080000ea0100a0e3e6fdffeb0100
a0e30020a0e3021ba0e350329fe50000c3e54c329fe50000c3e548029fe5
0020c0e5d1ffffea04009de5000050e30650a0030000000afe50a0e300b0
a0e3710000ea0c109ae50b00a0e120429fe531ff2fe108209ae50060a0e1
0410a0e132ff2fe1000050e30000940504129f05010050016300001a021c
a0e30400a0e189fcffeb010c84e2fb3f07e3bc20d4e1bc7fd0e1ba9fd0e1
060082e000008de5051047e2030051e1040049e20a70a0233d0050e30300
002a090057e10100003a030019e30000000a0490a0e30000a0e30060a0e1
000088e5060057e14600009a000098e5000050e300009d05060080000000
981500109d15022ba0e304309ae5010080100410a0e133ff2fe1000050e3
3900001a021ca0e30400a0e162fcffeb021ca0e3020c84e25ffcffeb0000
56e31000001a38419fe53c019fe50020d4e50010d0e5010052e10110d405
0120d005020051010700001a0210d4e50220d0e5020051e10300d0050310
d405000051010400840230ff2f01021ca0e3010b84e249fcffeb021ca0e3
060c84e246fcffeb040049e2000056e1024b84121200001acc109fe5d000
9fe50030d1e50020d0e5020053e10120d1050130d005030052010d00001a
0220d1e50230d0e5030052e10300d0050320d105000052010600001a0400
81e230ff2fe10642a0e3000098e5010070e304608612b6ffff1a060057e1
0602a09330ff2f9101b08be210009ae50b0050e10150859235ffff9a88ff
ffeafe8fbde870402de90040a0e328609fe50350a0e3040184e0000196e7
30ff2fe10010a0e10400a0e121ffffeb014084e2050054e1f6ffff3a7080
bde8c4220000280008101c000810180008102000081024000810000c0810
3b8cdcfc9022000040009fe50010a0e310402de938409fe50010c0e53410
9fe5081080e5680100eb040094e5020080e3040084e5810100eb8b0100eb
040094e50200c0e3040084e51040bde8560100ea40000810000818106802
0810f0402de900159fe5c10881e1001091e5000090e5010000e0f0149fe5
2048b0e10000a0130150a013086b0013f080bd08150014e11900000a8032
81e0142800e30670b3e7022091e7072002e0010012e30900000a000050e3
005083e50600000aac749fe5b070d7e102c787e350cb81e540cb91e521c3
8ce340cb81e5020012e30270a01300708315040012e30470a01300708315
080012e30820a01300208315010080e2030050e3e0ffff3af080bde86004
9fe5181090e51c2090e5021001e00118a0e12118b0e11eff2f01102090e5
341090e5083190e5011001e2811382e1031001e02f0011e32f2001120821
8015800011e31010a013081180151eff2fe10c249fe54010a0e308049fe5
10402de9b010c2e1083090e5d340e1e7f8339fe5000054e3024ca003b040
c2010500000a010054e30300541300119015032081130810a0130100001a
002190e50320c2e3002180e5b010c3e1c0139fe5101380e5001390e50211
81e3001380e5041090e5011c81e3041080e51080bde8a0239fe50010a0e3
8c039fe50010c2e594239fe50010c2e5041090e50110c1e3041080e51eff
2fe180039fe50010d0e50120d0e5601011e20f2002e20200000a400051e3
0a00000a0b0000ea050052e30400000a060052e30300000a090052e30500
001a010000ea960100eaa70100eaf20100ea0c0052e30000000a9b0100ea
24139fe50020d1e5000052e30020a003ba20c0010120a0e30020c1e50413
9fe50020c1e5b610d0e1b810c0e1ba10d0e1000051e31eff2f11712400e3
b410d0e1020051e1e8129f050300000a722400e3020051e10612a0031eff
2f110c1080e51eff2fe1c4129fe50800a0e310402de9450100eb1040bde8
caffffeaf0412de90050a0e1a0029fe50000d0e5000050e3f081bd080070
a0e388629fe50000d6e5020050e30070c605f081bd08010050e3f081bd18
0500a0e178829fe5001098e5310100eb64429fe50520a0e1001098e50c00
94e5ed0200ebba00d4e1050080e07000ffe6ba00c4e1b810d4e1051041e0
0128a0e12228b0e1b820c4e10c1094e5051081e00c1084e5f081bd18002a
b0e12c00000a0126a0e3000a52e10300001a010040e2011041e2ba00c4e1
0c1084e50100a0e1ba10d4e1010040e0350200eb000050e31e00001a0c10
94e5ba20d4e1720400e3b430d4e1025041e0000053e10300001a0010a0e3
0100a0e1130100eb7b0000ebb400d4e1711400e3010050e10e00001ab001
9fe50010d5e50020d0e5020051e10110d5050120d005020051010600001a
0210d5e50220d0e5020051e10310d0050300d505010050010450850235ff
2fe1ba70c4e10200a0e30000c6e50010a0e3f041bde80100a0e1f70000ea
2c019fe5200090e50f0010e31eff2f11d038e3e744119fe5070053e34021
9fe503f18f301eff2fe11eff2fe11eff2fe1030000ea040000ea030000ea
1eff2fe1030000ea5002eae793ffffea001082e51eff2fe12002a0e10114
a0e3800a51e11eff2f1186ffffea70402de9c0409fe5140094e5181094e5
015010e07080bd08100015e30600000a180094e51000c0e3180084e5d9ff
ffeb180094e5100080e3180084e5200015e30500000a180094e5b0209fe5
0010a0e32000c0e3180084e5001082e5010a15e30200000a33ffffeb010a
a0e3140084e5020a15e30200000a0fffffeb020aa0e3140084e5010715e3
f7feff1b020715e3c9feff1b68009fe5050010e0140084157080bde81040
2de958409fe50c0094e5300050e31080bd18d0ffffeb3000a0e3100084e5
1080bde8180818100000181050000810000818104c000810400008203800
08104000081054020810000c0810480008109022000000800084000b1810
34081810c00c42c000c1131080009fe50118a0e3041180e51eff2fe17000
9fe50118a0e3841180e51eff2fe164009fe530002de9001090e5031081e3
001080e5002090e50f1c80e24c309fe5ff40a0e30850c2e30020e0e30050
80e5044080e5004093e50100a0e30240c4e3004083e5802181e5833e81e2
842181e5882181e58c2181e5000083e5000081e53000bde84efaffea00d0
131000c113100cdc131034029fe510402de90242a0e3200184e5100702e3
b0faffeb0105a0e3200184e5fa0fa0e31040bde8abfaffeaf0412de90010
a0e304029fe5103702e3102090e5020112e30200001a011081e2030051e1
f9ffff3a101090e5012081e30010a0e3102080e5102090e5012002e20000
52e30110811201005311f9ffff8a0010a0e3001e80e5004890e50340c4e3
004880e5004890e57f4ec4e3004880e5282090e51f20cfe7022c82e32820
80e5102090e5424e82e30120a0e1104080e5104090e5204004e2000054e3
0120821202005311f9ffff8a102090e5104082e30020a0e3104080e51040
90e5104004e2000054e30120821202005311f9ffff8a106090e5144900e3
087900e3143b00e3045080e0084b00e307c080e0147800e308e086e31888
00e31223a0e3003083e0004084e0076080e0087080e010e080e5002980e5
101980e51ce800e3001085e5ff50a0e300508ce5002b80e50020e0e3101b
80e5001083e52f30a0e30f10a0e3005084e5cc409fe5103880e5c8309fe5
001086e5002087e50e4080e7142080e5042080e5183080e5081090e50110
81e3081080e5f081bde894309fe50020a0e330402de9014a83e2020000ea
005094e5042082e2045081e4000052e17c009f25100b8325f8ffff3a3080
bde8f0402de95c209fe52c4092e5033080e27440ffe6230154e1f080bd38
2c3092e5ff0813e3f080bd08024780e30030a0e32163a0e33c509fe51070
45e2004085e5006087e5012a82e2020000ea044091e4043083e2004082e5
000053e1faffff3af080bde8400040000000181001000100103c0cc04000
0820100918100010a0e30100a0e1ddffffea80119fe578019fe5b210d1e1
002090e57f2ec2e3011282e1001080e50010a0e30100a0e1d3ffffea5401
9fe5001390e5021681e3001380e5001190e5021681e3001180e51eff2fe1
f0472de934619fe534719fe534919fe5002086e230819fe5b210d6e1b650
d2e1000097e52114a0e1010051e30900000a020051e32000000ae8ffffeb
b810d6e108019fe5000051e30210a0030110a0130010c0e5f087bde8f410
9fe5120055e31240a0e30540a0910420a0e1630100ebb000d9e1400050e3
00009705111ea003b210c001001097e50c1086e5b840c6e1b000d8e10000
54e10040a0810400a0e1a2ffffeb0c0096e5040080e00c0086e5b800d6e1
040040e01a0000ea94109fe5090055e32050a0830520a0e14b0100ebb000
d9e1400050e30500001a001097e54020a0e30030a0e3b621c1e11d20c1e5
1e30c1e5001097e50c1086e5b850c6e1b000d8e1000055e10050a0810500
a0e186ffffeb0c0096e5050080e00c0086e5b800d6e1050040e0b800c6e1
c2ffffea0010a0e30100a0e17cffffea0008181054020810480008105000
08104c00081038000810142300002823000010402de98300a0e310429fe5
0d10a0e30320a0e30c0084e5001084e50c2084e5fc019fe5fc119fe5b810
80e50100a0e3a8f9ffeb0100a0e3980084e51080bde8f0412de90160a0e1
d0519fe50080a0e1c000a0e3081095e5823082e0827363e00100d0e11200
001a0c0000ea7c0095e5080010e30400001a0100a0e395f9ffeb014084e2
870154e1f7ffff3a870154e10700002a000095e5016046e20100c8e40000
56e30040a0130000a003f4ffff1af081bde80100a0e3f081bde8f0412de9
0170a0e154419fe50060a0e1c000a0e3081094e50100d0e12000001a0700
00ea7c0094e5020010e31700000ac80055e31a00002a017047e20100d6e4
000084e5000057e30050a0e388630103f3ffff1a7c0094e5010010e30700
000a0100a0e36cf9ffeb7c0094e5080010e300009415015085e2060055e1
f4ffff3a060055e10000a033f081bd38040000ea0100a0e360f9ffeb0150
85e2c80055e3dfffff3a0100a0e3f081bde870402de90040a0e1a8509fe5
c000a0e3081095e50100d0e12400001a7c0095e5080010e32100000a1420
a0e31010a0e30400a0e1a7ffffeb000050e30000d405400050030100d405
0c0050030200000afa1fa0e30000a0e30e0000eab400d4e1711400e30100
50e172140013010050110000a003f5ffff1a7080bde8002095e5142095e5
080012e30200000a011051e2980085050200000a7c2095e5080012e3f5ff
ff1a0000c4e50100c4e5b400c4e10200a0e37080bde80040121000800020
0500050070402de90040a0e1010080e0025041e20510a0e1022050e50100
50e5020480e07060ffe60400a0e1d2f8ffeb000056e10100a0137080bd18
0510a0e10400a0e1dff8ffeb0000a0e37080bde8ff472de964fbffeb5eff
ffeb8c719fe50060a0e30640a0e1070000ea000056e30500000a0000d7e5
000050e35a00001a000054e31100001a0c0000ea7cfbffeb000050e30200
000a010050e3f7ffff0a020000ea0300a0e30010a0e3cffbffeb0ff9ffeb
b8fcffeb0160a0e3efffffea2c019fe50810a0e371ffffeb6440a0e37d0f
a0e3f5f8ffeb014044e20d00a0e196ffffeb000050e3dfffff1a00f9ffeb
00619fe5d290a0e3728400e3717400e3b440dde1070054e1ec509f050100
000a080054e10652a0030610a0e3b600dde1b290cde1b400cde10d00a0e1
58ffffeb08308de20500a0e1060093e835ffffeb000050e30400001a0810
9de50500a0e1abffffeb000050e30200000a5a00a0e3b200cde1180000ea
080054e10400001a0610a0e30d00a0e145ffffeb0500a0e1100000ea0700
54e10500a0e10010d5050020d605020051010a00001a0110d5e50120d6e5
020051e10210d5050220d605020051010300001a0310d6e50320d5e50100
52e10400850230ff2fe10610a0e30d00a0e12effffeb0d00a0e157ffffeb
000050e3fbffff1ac4ffffeaff87bde8400008104823000090220000000c
0810f0412de9202052e20b00003a800052e30500003a80f0d1f5f851b1e8
202042e2800052e3f851a0e8f9ffff2af851b1e8202052e2f851a0e8fbff
ff2a02ceb0e11850b1281850a0281800b1481800a048f041bde802cfb0e1
04309124043080241eff2f01822fb0e1b230d1200120d144b230c0200120
c0441eff2fe1030052e32100009a03c010e20800000a0130d1e402005ce3
0c2082e001c0d1940130c0e40130d13401c0c094042042e20130c0340330
11e2d1ffff0a482052e20600003a40f0d1f5043091e4082052e204c091e4
043080e404c080e4f7ffffea402092e20500003a043091e4082052e204c0
91e4043080e404c080e4f8ffffea042092e204309154043080540000a0e1
822fb0e10130d12401c0d1240120d1440130c02401c0c0240120c0441eff
2fe1013090e12100004a0020b0e3a03071e01a00003a203271e00f00003a
203471e00100003a00c0a0e3200000eaa03371e0810340200220b2e02033
71e0010340200220b2e0a03271e0810240200220b2e0203271e001024020
0220b2e0a03171e0810140200220b2e0203171e0010140200220b2e0a030
71e0810040200220b2e0011050e00010a0310200a2e01eff2fe1022111e2
0010614240c032e000006022203271e01d00003a203471e00f00003a0113
a0e1203471e03f2382e30b00003a0113a0e1203471e03f2682e30700003a
0113a0e1203471e03f2982e30113a0213f2c8223003071e21d00002a2113
a021a03371e0810340200220b2e0203371e0010340200220b2e0a03271e0
810240200220b2e0203271e0010240200220b2e0a03171e0810140200220
b2e0203171e0010140200220b2e0ebffff2aa03071e0810040200220b2e0
011050e00010a0310200a2e0cccfb0e100006042001061221eff2fe1cccf
b0e10000604201402de90000b0e30000a0e10280bde80020b0e3203171e0
baffff3aa03271e0afffff3a203471e0a4ffff3a00c0a0e3c3ffffea524b
33307c4e0304550509072d2c7b38170d17117679f1dadcd3d5d7d9486888
a8de3c4672b1babcb3b5b7b9b9b9b9b9b9b90000d0060000d0090000280b
00007c0b0000320000002c040000b0040000bc050000500600000d000000
74040000b0040000bc050000500600000d000000b00b0000c00c0000800d
0000880d000001000000120100020000004007220a300001000000010000
0902200001010080c80904000002ff060500070581020002000705020200
0200d2524b33303041d20000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000413030333131
30323131313131303156
use strict;
use 5.010;
if ($#ARGV == -1) {
say "$0 dram=DRAM_INIT usbplug=USB_PLUG boot=FLASHBOOT data=FLASHDATA out=NAME";
exit;
}
my @VALID = qw/dram usbplug boot data out/;
my $parts = { map { /^(.+?)=(.+)$/ } @ARGV };
if (@_ = grep { not exists $parts->{$_} } @VALID) {
say "Specify parts: ", join(',', @_);
exit;
}
my $KEY = q/7C4E0304550509072D2C7B38170D1711/;
my $SCRAMBLE = qq/openssl rc4 -K $KEY/;
my $SCRAMBLE_PARTS = qq/split -b 512 --filter='$SCRAMBLE'/;
my $to_write = [];
my $fn = $ARGV[0];
open FILE, '>', $parts->{out};
binmode(FILE);
my $header_len = 102;
my $recsize = 0x39;
print FILE
pack(
'@0A4' . # magic
'@4S' . # length
'@6L' . # version
'@10L' . # var2
'@14S' . # year
'@16C5' . # date
'@21L' . # var1
'CLC'x3, # num off size
'BOOT', $header_len, 0x0118, 0x1030000,
2012, 10, 19, 12, 2, 25,
#2012, 1, 1, 0, 0, 0,
0x60,
1, $header_len, $recsize,
1, $header_len+$recsize, $recsize,
2, $header_len+$recsize*2, $recsize
);
fill($header_len);
my $file_offset = 0x14a;
addPart(1, 'full', $parts->{dram});
addPart(2, 'full', $parts->{usbplug});
addPart(4, 'part', $parts->{data});
addPart(4, 'part', $parts->{boot});
fill(0x14a);
sub fill {
my $fill = $_[0] - tell FILE;
print FILE "\x0" x $fill if $fill > 0;
}
sub get_fn {
my $fn = shift;
$fn =~ s/\..+$//;
(join "\x00", split '', $fn),
}
sub addPart {
my ($no, $scramble, $fn) = @_;
my $fsize = -s $fn;
printf "%3d %5x %5x %s\n", $no, $file_offset, $fsize, $fn;
print FILE pack(
'@0C' . # len
'@1L' . # num
'@5a40' . # name
'@45LLL', # offset size unknown
$recsize, $no, get_fn($fn), $file_offset, $fsize, 0
);
$file_offset += $fsize;
push @$to_write, [ $fn, $scramble ];
}
close FILE;
for (@$to_write) {
my $cmd = qq/cat '$_->[0]' | /
. ($_->[1] eq 'part' ? $SCRAMBLE_PARTS : $SCRAMBLE)
. qq/ >> $parts->{out}/;
say $cmd;
system $cmd;
}
for ( qq[./rkcrc $parts->{out} $parts->{out}.crc],
qq[mv $parts->{out}.crc $parts->{out}] ) { say $_; system $_; }
#!/bin/bash
OFFSET=$((0xA0))
INJECT=$((0x224))
JUMP1=$(( (0x2B0 - (OFFSET + 3*4) - 8) / 4 ))
JUMP1=$(printf "0xEB00%04X" $JUMP1)
cat <<END_PATCH | arm-linux-gnueabi-as -mcpu=cortex-a9 -march=armv7-a -o _patch
MOV R0, #0
MOV R1, #0x64000000
ADD R2, R1, #0x2800
.word $JUMP1
LDR R0, =0x10080000
LDR PC, =0x60000228
END_PATCH
arm-linux-gnueabi-objcopy -O binary _patch _patch.bin
FN=$1
SIZE=$(stat -c %s $FN)
PATCHSIZE=$(stat -c %s _patch.bin)
PATCHED=$FN".patched"
JUMP=$(( 0xFFFFFF - (INJECT - OFFSET + 8) / 4 + 1))
JUMP=$(printf "%06X" $JUMP | sed 's/\(..\)\(..\)\(..\)/\3\2\1/')
dd if=$FN ibs=1 count=$OFFSET of=$PATCHED 2>&-
cat _patch.bin >> $PATCHED
dd if=$FN ibs=1 skip=$(( OFFSET+PATCHSIZE )) count=$(( INJECT - (OFFSET+PATCHSIZE) )) of=$PATCHED oflag=append conv=notrunc 2>&-
echo $JUMP | xxd -r -p >> $PATCHED
echo "EA" | xxd -r -p >> $PATCHED
dd if=$FN ibs=1 skip=$((INJECT+4)) of=$PATCHED oflag=append conv=notrunc 2>&-
rm _patch _patch.bin
/* rkflashtool - for RK2808, RK2818 and RK2918 based tablets
*
* Copyright (C) 2011 Ivo van Poorten (complete rewrite for libusb)
* Copyright (C) 2010 FUKAUMI Naoki (reverse engineering of protocol)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Build with:
*
* gcc -o rkflashtool rkflashtool.c -lusb-1.0 -O2 -W -Wall -s
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <libusb-1.0/libusb.h>
#define RKFLASHTOOL_VERSION 2
#define RKFT_BLOCKSIZE 0x4000 /* must be multiple of 512 */
#define RKFT_IDB_BLOCKSIZE 0x210
#define RKFT_IDB_INCR 0x20
#define RKFT_MEM_INCR 0x80
#define RKFT_OFF_INCR (RKFT_BLOCKSIZE>>9)
#define RKFT_CID 4
#define RKFT_FLAG 12
#define RKFT_COMMAND 13
#define RKFT_OFFSET 17
#define RKFT_SIZE 23
#define SETBE32(a, v) ((uint8_t*)a)[3] = v & 0xff; \
((uint8_t*)a)[2] = (v>>8 ) & 0xff; \
((uint8_t*)a)[1] = (v>>16) & 0xff; \
((uint8_t*)a)[0] = (v>>24) & 0xff
static uint8_t cmd[31] = { 'U', 'S', 'B', 'C', };
static uint8_t res[13];
static uint8_t buf[RKFT_BLOCKSIZE], cid;
static int tmp;
static const char *const strings[2] = { "info", "fatal" };
static void info_and_fatal(const int s, char *f, ...) {
va_list ap;
va_start(ap,f);
fprintf(stderr, "rkflashtool: %s: ", strings[s]);
vfprintf(stderr, f, ap);
va_end(ap);
if (s) exit(s);
}
#define info(...) info_and_fatal(0, __VA_ARGS__)
#define fatal(...) info_and_fatal(1, __VA_ARGS__)
static void usage(void) {
fatal("usage:\n"
"\trkflashtool b \treboot device\n"
"\trkflashtool m offset size >file \tread 0x80 bytes DRAM\n"
"\trkflashtool i offset blocks >file \tread IDB flash\n"
"\trkflashtool r offset size >file \tread flash\n"
"\trkflashtool w offset size <file \twrite flash\n\n"
"\toffset and size are in units of 512 bytes\n");
}
static void send_cmd(libusb_device_handle *h, int e, uint8_t flag,
uint32_t command, uint32_t offset, uint8_t size) {
cmd[RKFT_CID ] = cid++;
cmd[RKFT_FLAG] = flag;
cmd[RKFT_SIZE] = size;
SETBE32(&cmd[RKFT_COMMAND], command);
SETBE32(&cmd[RKFT_OFFSET ], offset );
libusb_bulk_transfer(h, e|LIBUSB_ENDPOINT_OUT, cmd, sizeof(cmd), &tmp, 0);
}
#define send_buf(h,e,s) libusb_bulk_transfer(h, e|LIBUSB_ENDPOINT_OUT, \
buf, s, &tmp, 0)
#define recv_res(h,e) libusb_bulk_transfer(h, e|LIBUSB_ENDPOINT_IN, \
res, sizeof(res), &tmp, 0)
#define recv_buf(h,e,s) libusb_bulk_transfer(h, e|LIBUSB_ENDPOINT_IN, \
buf, s, &tmp, 0)
#define NEXT do { argc--;argv++; }while(0)
int main(int argc, char **argv) {
libusb_context *c;
libusb_device_handle *h;
int offset = 0, size = 0;
char action;
NEXT; if (!argc) usage();
action = **argv; NEXT;
switch(action) {
case 'b': if (argc ) usage(); break;
case 'm': case 'i': case 'r': case 'w': if (argc!=2) usage();
offset = strtoul(argv[0], NULL, 0);
size = strtoul(argv[1], NULL, 0);
break;
default:
usage();
}
if (libusb_init(&c)) fatal("cannot init libusb\n");
libusb_set_debug(c, 3);
if (!(h = libusb_open_device_with_vid_pid(c, 0x2207, 0x300a)))
if (!(h = libusb_open_device_with_vid_pid(c, 0x2207, 0x281a)))
fatal("cannot open device\n");
if (libusb_kernel_driver_active(h, 0) == 1) {
info("kernel driver active\n");
if (!libusb_detach_kernel_driver(h, 0))
info("driver detached\n");
}
if (libusb_claim_interface(h, 0)<0) fatal("cannot claim interface\n");
info("interface claimed\n");
send_cmd(h, 2, 0x80, 0x00060000, 0x00000000, 0x00); // INIT
recv_res(h, 1);
usleep(20*1000);
switch(action) {
case 'b':
info("rebooting device...\n");
send_cmd(h, 2, 0x00, 0x0006ff00, 0x00000000, 0x00);
recv_res(h, 1);
break;
case 'm':
while (size > 0) {
int sizeRead = size > RKFT_MEM_INCR ? RKFT_MEM_INCR : size;
info("reading memory at offset 0x%08x size %x\n", offset, sizeRead);
send_cmd(h, 2, 0x80, 0x000a1700, offset-0x60000000, sizeRead);
recv_buf(h, 1, sizeRead);
recv_res(h, 1);
write(1, buf, sizeRead);
offset += sizeRead;
size -= sizeRead;
}
break;
case 'i':
while (size > 0) {
int sizeRead = size > RKFT_IDB_INCR ? RKFT_IDB_INCR : size;
info("reading IDB flash memory at offset 0x%08x\n", offset);
send_cmd(h, 2, 0x80, 0x000a0400, offset, sizeRead);
recv_buf(h, 1, RKFT_IDB_BLOCKSIZE * sizeRead);
recv_res(h, 1);
write(1, buf, RKFT_IDB_BLOCKSIZE * sizeRead);
offset += sizeRead;
size -= sizeRead;
}
break;
case 'r':
while (size>0) {
info("reading flash memory at offset 0x%08x\n", offset);
send_cmd(h, 2, 0x80, 0x000a1400, offset, RKFT_OFF_INCR);
recv_buf(h, 1, RKFT_BLOCKSIZE);
recv_res(h, 1);
write(1, buf, RKFT_BLOCKSIZE);
offset += RKFT_OFF_INCR;
size -= RKFT_OFF_INCR;
}
break;
case 'w':
while (size>0) {
info("writing flash memory at offset 0x%08x\n", offset);
memset(buf, 0, RKFT_BLOCKSIZE);
read(0, buf, RKFT_BLOCKSIZE);
send_cmd(h, 2, 0x80, 0x000a1500, offset, RKFT_OFF_INCR);
send_buf(h, 2, RKFT_BLOCKSIZE);
recv_res(h, 1);
offset += RKFT_OFF_INCR;
size -= RKFT_OFF_INCR;
}
break;
default:
break;
}
libusb_release_interface(h, 0);
libusb_close(h);
libusb_exit(c);
return 0;
}
use strict;
use 5.010;
if ($#ARGV == -1) {
say "unpack_loader.pl FILENAME [write]";
exit;
}
my $KEY = q/7C4E0304550509072D2C7B38170D1711/;
my $SCRAMBLE = qq/openssl rc4 -K $KEY/;
my $SCRAMBLE_PARTS = qq/split -b 512 --filter='$SCRAMBLE'/;
my $to_write = [];
my $fn = $ARGV[0];
my $WRITE = $ARGV[1];
open FILE, $fn;
binmode(FILE);
$/ = \0x64;
my ($magic, $len,
$vers, $var2, $year, $mon, $day, $h, $m, $s, $var1,
$c1, $o1, $s1,
$c2, $o2, $s2,
$c3, $o3, $s3) = unpack(
'@0L' . # magic
'@4S' . # length
'@6L' . # version
'@10L' . # var2
'@14S' . # year
'@16C5' . # date
'@21L' . # var1
'CLC'x3 # parts off size
, <FILE>);
printf "Version: %x.%02x\n", $vers >> 8, $vers & 0xFF;
say '=' x 15;
printf "Date: %02d/%02d/%4d %02d:%02d:%02d\n", $day, $mon, $year, $h, $m, $s;;
say '=' x 15;
printf "%3s %5s %5s %s\n", qw/no off size name/;
sub getAllParts { my ($c, $o, $s) = @_; map { getPart($o + $_*$s) } (0..$c-1) }
getAllParts($c1, $o1, $s1);
getAllParts($c2, $o2, $s2);
getAllParts($c3, $o3, $s3);
sub getPart {
my $s = shift;
$/ = \0x39;
seek(FILE, $s, 0);
my ($len, $no, $name, $offset, $size) = unpack
'@0C' . # len
'@1L' . # num
'@5a40' . # name
'@45LLL', <FILE>; # offset size unknown
$name =~ s/\x00//g;
printf "%3d %5x %5x %s\n", $no, $offset, $size, $name;
push @$to_write, [ $name, $offset, $size ];
}
close FILE;
say '=' x 15;
say;
say 'Script for unpacking';
say '=' x 15;
for my $w (@$to_write) {
my $str = qq/dd if='$fn' skip=$w->[1] count=$w->[2] bs=1 |\\\n /;
$str .= $w->[0] =~ /Flash/ ? $SCRAMBLE_PARTS : $SCRAMBLE;
$str .= " > $w->[0].bin";
say $str;
qx{$str} if ($WRITE);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment