pax_global_header00006660000000000000000000000064126750653540014527gustar00rootroot0000000000000052 comment=094bd6410cb016e487e2ccb1050c59eeac2e6dd1 rkflashtool-0~20160324/000077500000000000000000000000001267506535400146005ustar00rootroot00000000000000rkflashtool-0~20160324/.gitignore000066400000000000000000000001061267506535400165650ustar00rootroot00000000000000rkflashtool rkcrc rkunpack *.zip *.tar.bz2 *.tar.gz *.tar.xz *~ *.swp rkflashtool-0~20160324/Makefile000066400000000000000000000064341267506535400162470ustar00rootroot00000000000000# Simple Makefile for RK Flash Tool CC = $(CROSSPREFIX)gcc LD = $(CC) CFLAGS = -O2 -W -Wall LDFLAGS = PREFIX ?= usr/local PKGCONFIG ?= $(shell pkg-config --exists libusb-1.0 && echo 1) ifeq ($(PKGCONFIG),1) CFLAGS += $(shell pkg-config --cflags libusb-1.0) LDFLAGS += $(shell pkg-config --libs libusb-1.0) else ifdef LIBUSB CFLAGS += -I$(LIBUSB)/include LDFLAGS += -L$(LIBUSB)/lib else CFLAGS += -I/usr/include/libusb-1.0 LDFLAGS += -lusb-1.0 endif MACH = $(shell $(CC) -dumpmachine) ifeq ($(findstring mingw,$(MACH)),mingw) LDFLAGS += -s -static -lmman USE_RES = 1 endif ifeq ($(findstring cygwin,$(MACH)),cygwin) LDFLAGS += -s USE_RES = 1 endif ifeq ($(USE_RES),1) RC = $(CROSSPREFIX)windres RCFLAGS = -O coff -i BINEXT = .exe RESFILE = %.res AWK = awk VERMAJ = $(shell $(AWK) '/define.*RKFLASHTOOL_VERSION_MAJOR/{print $$3}' version.h) VERMIN = $(shell $(AWK) '/define.*RKFLASHTOOL_VERSION_MINOR/{print $$3}' version.h) VERREV = 0 LCOPYR = 2010-2013 Ivo van Poorten, Fukaumi Naoki, Guenter Knauf, Ulrich Prinz, Steve Wilson FDESCR = Flashtool for RK2808, RK2818, RK2918, RK3066, RK3068 and RK3188 based tablets WWWURL = http://sourceforge.net/projects/rkflashtool/ ifeq ($(findstring /sh,$(SHELL)),/sh) DL = ' endif endif PROGS = $(patsubst %.c,%$(BINEXT), $(wildcard *.c)) SCRIPTS = rkunsign rkparametersblock rkmisc rkpad rkparameters all: $(PROGS) $(SCRIPTS) %$(BINEXT): %.c $(RESFILE) $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) install: $(PROGS) $(SCRIPTS) install -d -m 0755 $(DESTDIR)/$(PREFIX)/bin install -m 0755 $(PROGS) $(DESTDIR)/$(PREFIX)/bin install -m 0755 $(SCRIPTS) $(DESTDIR)/$(PREFIX)/bin clean: $(RM) $(PROGS) *.res *.rc *.zip *.tar.gz *.tar.bz2 *.tar.xz *~ *.exe uninstall: cd $(DESTDIR)/$(PREFIX)/bin && $(RM) -f $(PROGS) $(SCRIPTS) %.res: %.rc $(RC) $(RCFLAGS) $< -o $@ %.rc: Makefile @echo $(DL)1 VERSIONINFO $(DL)>$@ @echo $(DL) FILEVERSION $(VERMAJ),$(VERMIN),$(VERREV),0 $(DL)>>$@ @echo $(DL) PRODUCTVERSION $(VERMAJ),$(VERMIN),$(VERREV),0 $(DL)>>$@ @echo $(DL) FILEFLAGSMASK 0x3fL $(DL)>>$@ @echo $(DL) FILEOS 0x40004L $(DL)>>$@ @echo $(DL) FILEFLAGS 0x0L $(DL)>>$@ @echo $(DL) FILETYPE 0x1L $(DL)>>$@ @echo $(DL) FILESUBTYPE 0x0L $(DL)>>$@ @echo $(DL)BEGIN $(DL)>>$@ @echo $(DL) BLOCK "StringFileInfo" $(DL)>>$@ @echo $(DL) BEGIN $(DL)>>$@ @echo $(DL) BLOCK "040904E4" $(DL)>>$@ @echo $(DL) BEGIN $(DL)>>$@ @echo $(DL) VALUE "LegalCopyright","\251 $(LCOPYR)\\0" $(DL)>>$@ # @echo $(DL) VALUE "CompanyName","$(COMPANY)\\0" $(DL)>>$@ @echo $(DL) VALUE "ProductName","$(notdir $(@:.rc=)).exe\\0" $(DL)>>$@ @echo $(DL) VALUE "ProductVersion","$(VERMAJ).$(VERMIN).$(VERREV)\\0" $(DL)>>$@ @echo $(DL) VALUE "License","Released under BSD license.\\0" $(DL)>>$@ @echo $(DL) VALUE "FileDescription","$(FDESCR)\\0" $(DL)>>$@ @echo $(DL) VALUE "FileVersion","$(VERMAJ).$(VERMIN).$(VERREV)\\0" $(DL)>>$@ @echo $(DL) VALUE "InternalName","$(notdir $(@:.rc=))\\0" $(DL)>>$@ @echo $(DL) VALUE "OriginalFilename","$(notdir $(@:.rc=)).exe\\0" $(DL)>>$@ @echo $(DL) VALUE "WWW","$(WWWURL)\\0" $(DL)>>$@ @echo $(DL) END $(DL)>>$@ @echo $(DL) END $(DL)>>$@ @echo $(DL) BLOCK "VarFileInfo" $(DL)>>$@ @echo $(DL) BEGIN $(DL)>>$@ @echo $(DL) VALUE "Translation", 0x409, 1252 $(DL)>>$@ @echo $(DL) END $(DL)>>$@ @echo $(DL)END $(DL)>>$@ rkflashtool-0~20160324/README000066400000000000000000000077631267506535400154750ustar00rootroot00000000000000BUILD ===== Install libusb-1.0 and its development files and run: $ make For cross-compilation for win32/64 you need to install libusb-1.0. See at the end of this document for more information. After that, you can run: $ make MACH=mingw CROSSPREFIX=i686-w64-mingw32- or $ make MACH=mingw CROSSPREFIX=x86_64-w64-mingw32- USAGE ===== Read parameters: sudo ./rkflashtool p > parm.bin cat parm.bin The output will show 2 hex numbers and the partition name. (....,0x00008000@0x00010000(recovery),....) The first number is the size of the partition, the second number is the offset. So, to write the recovery image, use: sudo ./rkflashtool w 0x10000 0x8000 < recovery.img All available commands: rkflashtool b reboot device rkflashtool r partname >file read flash partition rkflashtool w partname file read flash rkflashtool w offset size file read 0x80 bytes DRAM rkflashtool i offset blocks >file read IDB flash rkflashtool p >file fetch parameters rkflashtool e partname erase flash (fill with 0xff) rkflashtool e offset size erase flash (fill with 0xff) offset and size are in units (blocks) of 512 bytes (!) Also included: rkcrc sign files with a cyclic redundency code and optionally add a KRNL or PARM + size header usage: rkcrc [-k|-p] infile outfile rkparameters generate a parameter file usage: rkparameters model fw_version partitionsfile > outfile model is found in the large case statement, e.g. arnova7g2 you can add your own and please send the information back to me (ivop@euronet.nl) for inclusion in future versions. fw_version is the version number, e.g. 1.2.3 partitionsfile is a file that specifies the kernel command line on the first line and describes all the partitions and their sizes. It skips the parameters block and starts with misc. See the example mtdparts.txt for details. rkparametersblock generate the parameters block usage: rkparametersblock parametersfile outfile parametersfile is the file you have generated with rkparameters. outfile is the file to be written, which can later be flashed to your device. rkparametersblock needs rkcrc to sign the parameter file. After that, it generates an empty 4MB file and pastes in the rkcrc'd file five times at the start of the first five NAND pages (it assumes the NAND page size is always 4096. Let me know if you run into something different). rkunpack unpack update.img files (not partition.img (!)) usage: rkunpack file supports both RKAF and RKFW (which contains an embedded RKAF file) rkpad pad file with zeroes usage: rkpad size infile outfile Copy infile to outfile and pad with zeroes up to the specified size. size is in blocks of 512 bytes (!) i.e. equal to the partition sizes. rkunsign remove KRNL/PARM header and crc footer usage: rkunsign infile outfile Notes on cross-compiling libusb-1.0 and mman-win32 on debian wheezy: sudo apt-get install mingw-w64 git clone http://git.libusb.org/libusb.git cd libusb ./autogen.sh make clean ./configure --host i686-w64-mingw32 --prefix=/usr/i686-w64-mingw32 make sudo make install Replace i686-w64-mingw32 with x86_64-w64-mingw32 to do a win64 build. Scripts on windows ------------------ To run the bash scripts (rkmisc, rkparameters, etc...) on Windows, you need to install MSYS (part of MinGW). The easiest way is through the MinGW installer. You need at least msys-bash and msys-coreutils (for dd). Make sure you have e.g. C:\MinGW\msys\1.0\bin and C:\rkflashtool in your %PATH% variable. The easiest way to run the scripts is from the bash command line. If you insist on using cmd.exe, you need to call bash with the script's full filename (including its path) as its first argument. You could turn that into a .bat file if you want. rkflashtool-0~20160324/doc/000077500000000000000000000000001267506535400153455ustar00rootroot00000000000000rkflashtool-0~20160324/doc/protocol.txt000066400000000000000000000056031267506535400177530ustar00rootroot00000000000000RK Protocol request ======= [00] 55 53 42 43 U S B C [04] 01 02 03 04 random value, echoed by device in response [08] 00 00 00 00 reserved [12] 80 flag [13] 00 reserved [14] 06 foo [15] 01 command [16] 00 bar [17] 01 02 03 04 address, in sectors, big endian [21] 00 [22] 01 02 number of sectors (512 bytes/sector), big endian or number of bytes (e.g. ReadSDRAM) [24] 00 00 used during ExecuteSDRAM [26] 00 reserved [27] 00 00 00 00 reserved 31 bytes notes: [17-20] and [22-25] seem to form a full 64-bit address to jump to [16-19] four fuses during WriteEfuse [20-23] zero or next four fuses response ======== [00] 55 53 42 53 U S B S [04] 01 02 03 04 random [08] 00 00 00 unknown [11] 06 unknown, sometimes 6, sometimes 0 [12] 01 error_flag, 0 = OK, 1 = ERROR 13 bytes notes: [08-11] are two 16-bit big endian words with an error code if error_flag == 1 12 14 15 flag foo cmd -------+-------+------- 0x80 0x06 0x00 TestUnitReady 0 0x80 0x06 0x01 ReadFlashID 5 bytes 0x80 0x06 0x1a ReadFlashInfo 11|512 bytes 0x80 0x06 0x1b ReadChipInfo 16 bytes 0x80 0x06 0x20 ReadEfuse 8 bytes 0x00 0x06 0x02 SetDeviceInfo 0 0x00 0x06 0x16 EraseSystemDisk 0 0x00 0x06 0x1e SetResetFlag 0 0x00 0x06 0xff ResetDevice 0 0x80 0x0a 0x03 TestBadBlock 64 bytes 0x80 0x0a 0x04 ReadSector 512|528 bytes 0x80 0x0a 0x14 ReadLBA n*512 bytes 0x80 0x0a 0x17 ReadSDRAM n bytes 0x80 0x0a 0x21 0x00 0x0a 0x05 WriteSector 512|528 bytes 0x00 0x0a 0x06 EraseSectors 0 0x00 0x0a 0x0b 0x00 0x0a 0x15 WriteLBA n*512 bytes 0x00 0x0a 0x18 WriteSDRAM n bytes 0x00 0x0a 0x19 ExecuteSDRAM 0 0x00 0x0a 0x1f WriteEfuse 0 (fuses are in command pkt) 0x00 0x0a 0x22 0x80 0x10 0x07 WriteSpare n bytes 0x80 0x10 0x08 ReadSpare n bytes 0x00 0x00 0x1c LowerFormat 0 0x00 0x00 0x30 write 16k to device 16k bytes, resp is 18 bytes 11|512 bytes of FlashInfo [0-511] --------------------------------- [0-3] = Number of sectors [4-5] = Page size [6] = [7-8] = [9] = 00 - Samsung 01 - Toshiba 02 - Hynix 03 - Infineon 04 - Renesas 05 - ST 06 - Intel [10] = rkflashtool-0~20160324/examples/000077500000000000000000000000001267506535400164165ustar00rootroot00000000000000rkflashtool-0~20160324/examples/mtdparts-arnova10g1-stock-fw1.1.7.txt000066400000000000000000000004701267506535400250130ustar00rootroot00000000000000CMDLINE: noinitrd console=ttyS1,115200n8n init=/init root=/dev/mtdblock2 mem=208M@0x60000000 mtdparts=rk28xxnand: misc 0x00002000 kernel 0x00004000 boot 0x00002000 recovery 0x00004000 system 0x00030000 backup 0x0003a000 cache 0x0003a000 userdata 0x00096000 user - rkflashtool-0~20160324/examples/mtdparts-arnova7g2-stock-fw0.2.3.txt000066400000000000000000000005231267506535400247350ustar00rootroot00000000000000CMDLINE: console=ttyS1,115200n8n androidboot.console=ttyS1 init=/init initrd=0x62000000,0x500000 mtdparts=rk29xxnand: misc 0x00002000 kernel 0x00004000 boot 0x00002000 recovery 0x00004000 system 0x00080000 backup 0x00082000 cache 0x0003a000 userdata 0x00080000 kpanic 0x00002000 user - rkflashtool-0~20160324/fixversion.sh000077500000000000000000000004151267506535400173330ustar00rootroot00000000000000#! /bin/sh MAJOR=`grep MAJOR version.h | { read A B C; echo $C; }` MINOR=`grep MINOR version.h | { read A B C; echo $C; }` for i in rkparameters rkparametersblock rkmisc rkpad rkunsign ; do sed -i "s/^\(MAJOR\)=.*/\1=$MAJOR/; s/.*\(MINOR\)=.*/\1=$MINOR/" $i done rkflashtool-0~20160324/release.sh000077500000000000000000000017571267506535400165710ustar00rootroot00000000000000#! /bin/sh MAJOR=`grep MAJOR version.h | { read A B C; echo $C; }` MINOR=`grep MINOR version.h | { read A B C; echo $C; }` NAME=rkflashtool-$MAJOR.$MINOR DIR=$NAME-src SCRIPTS="rkparameters rkparametersblock rkmisc rkpad rkunsign" rm -rf $DIR mkdir $DIR cp -a \ Makefile \ rkflashtool.c \ rkcrc.c \ rkcrc.h \ rkunpack.c \ version.h \ $SCRIPTS \ README \ examples \ $DIR tar cvzf $DIR.tar.gz $DIR tar cvjf $DIR.tar.bz2 $DIR tar cvJf $DIR.tar.xz $DIR zip -9r $DIR.zip $DIR rm -rf $DIR echo trying win32/win64 cross-builds... rm -f rkflashtool.exe rkcrc.exe rkunpack.exe make MACH=mingw CROSSPREFIX=i686-w64-mingw32- || exit 1 zip -9r $NAME-win32-bin.zip rkflashtool.exe rkcrc.exe rkunpack.exe $SCRIPTS \ examples rm -f rkflashtool.exe rkcrc.exe rkunpack.exe make MACH=mingw CROSSPREFIX=x86_64-w64-mingw32- || exit 1 zip -9r $NAME-win64-bin.zip rkflashtool.exe rkcrc.exe rkunpack.exe $SCRIPTS \ examples rm -f rkflashtool.exe rkcrc.exe rkunpack.exe rkflashtool-0~20160324/rkcrc.c000066400000000000000000000066571267506535400160660ustar00rootroot00000000000000/*- * Copyright (c) 2010, 2011 Fukaumi Naoki * Copyright (c) 2013 Ivo van Poorten * All rights reserved. * * 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. */ #include #include #include #include #include #include #include #include #include "rkcrc.h" #include "rkflashtool.h" #include "version.h" #ifndef _WIN32 #define O_BINARY 0 #endif static const char headers[2][4] = { "KRNL", "PARM" }; 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, "rkcrc: %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__) int main(int argc, char *argv[]) { struct stat st; ssize_t nr; uint32_t crc = 0; uint8_t buf[512]; char *progname = argv[0]; int ch, which = -1, in, out; while ((ch = getopt(argc, argv, "kp")) != -1) { switch (ch) { case 'k': which = 0; break; case 'p': which = 1; break; default: break; } } argc -= optind; argv += optind; if (argc != 2) fatal("rkcrc v%d.%d\nusage: %s [-k|-p] infile outfile\n", RKFLASHTOOL_VERSION_MAJOR, RKFLASHTOOL_VERSION_MINOR, progname); if ((in = open(argv[0], O_BINARY | O_RDONLY)) == -1) fatal("%s: %s\n", argv[0], strerror(errno)); if (fstat(in, &st) != 0) fatal("%s: %s\n", argv[0], strerror(errno)); if ((out = open(argv[1], O_BINARY | O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) fatal("%s: %s\n", argv[1], strerror(errno)); if (which >= 0) { memcpy(buf, headers[which], 4); PUT32LE(buf+4, st.st_size); if(write(out, buf, 8) != 8) fatal("%s: write error\n", argv[1]); } while ((nr = read(in, buf, sizeof(buf))) > 0) { crc = rkcrc32(crc, buf, nr); if(write(out, buf, nr) != nr) fatal("%s: write error\n", argv[1]); } PUT32LE(buf, crc); if(write(out, buf, 4) != 4) fatal("%s: write error\n", argv[1]); close(out); close(in); return 0; } rkflashtool-0~20160324/rkcrc.h000066400000000000000000000167111267506535400160630ustar00rootroot00000000000000/*- * Copyright (c) 2010,2014 FUKAUMI Naoki. * All rights reserved. * * 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. */ #ifndef _RKCRC_H_ #define _RKCRC_H_ #include #ifdef SLOW static inline uint16_t rkcrc16(uint16_t crc, uint8_t *buf, uint64_t size) { int i; while (size-- > 0) { crc ^= *buf++ << 8; for (i = 0; i < 8; i++) { if (crc & 0x8000) crc = (crc << 1) ^ 0x1021; else crc = (crc << 1); } } return crc; } static inline uint32_t rkcrc32(uint32_t crc, uint8_t *buf, uint64_t size) { int i; while (size-- > 0) { crc ^= *buf++ << 24; for (i = 0; i < 8; i++) { if (crc & 0x80000000) crc = (crc << 1) ^ 0x04c10db7; else crc = (crc << 1); } } return crc; } #else static uint16_t crc16table[] = { 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, }; static uint32_t crc32table[] = { 0x00000000, 0x04c10db7, 0x09821b6e, 0x0d4316d9, 0x130436dc, 0x17c53b6b, 0x1a862db2, 0x1e472005, 0x26086db8, 0x22c9600f, 0x2f8a76d6, 0x2b4b7b61, 0x350c5b64, 0x31cd56d3, 0x3c8e400a, 0x384f4dbd, 0x4c10db70, 0x48d1d6c7, 0x4592c01e, 0x4153cda9, 0x5f14edac, 0x5bd5e01b, 0x5696f6c2, 0x5257fb75, 0x6a18b6c8, 0x6ed9bb7f, 0x639aada6, 0x675ba011, 0x791c8014, 0x7ddd8da3, 0x709e9b7a, 0x745f96cd, 0x9821b6e0, 0x9ce0bb57, 0x91a3ad8e, 0x9562a039, 0x8b25803c, 0x8fe48d8b, 0x82a79b52, 0x866696e5, 0xbe29db58, 0xbae8d6ef, 0xb7abc036, 0xb36acd81, 0xad2ded84, 0xa9ece033, 0xa4aff6ea, 0xa06efb5d, 0xd4316d90, 0xd0f06027, 0xddb376fe, 0xd9727b49, 0xc7355b4c, 0xc3f456fb, 0xceb74022, 0xca764d95, 0xf2390028, 0xf6f80d9f, 0xfbbb1b46, 0xff7a16f1, 0xe13d36f4, 0xe5fc3b43, 0xe8bf2d9a, 0xec7e202d, 0x34826077, 0x30436dc0, 0x3d007b19, 0x39c176ae, 0x278656ab, 0x23475b1c, 0x2e044dc5, 0x2ac54072, 0x128a0dcf, 0x164b0078, 0x1b0816a1, 0x1fc91b16, 0x018e3b13, 0x054f36a4, 0x080c207d, 0x0ccd2dca, 0x7892bb07, 0x7c53b6b0, 0x7110a069, 0x75d1adde, 0x6b968ddb, 0x6f57806c, 0x621496b5, 0x66d59b02, 0x5e9ad6bf, 0x5a5bdb08, 0x5718cdd1, 0x53d9c066, 0x4d9ee063, 0x495fedd4, 0x441cfb0d, 0x40ddf6ba, 0xaca3d697, 0xa862db20, 0xa521cdf9, 0xa1e0c04e, 0xbfa7e04b, 0xbb66edfc, 0xb625fb25, 0xb2e4f692, 0x8aabbb2f, 0x8e6ab698, 0x8329a041, 0x87e8adf6, 0x99af8df3, 0x9d6e8044, 0x902d969d, 0x94ec9b2a, 0xe0b30de7, 0xe4720050, 0xe9311689, 0xedf01b3e, 0xf3b73b3b, 0xf776368c, 0xfa352055, 0xfef42de2, 0xc6bb605f, 0xc27a6de8, 0xcf397b31, 0xcbf87686, 0xd5bf5683, 0xd17e5b34, 0xdc3d4ded, 0xd8fc405a, 0x6904c0ee, 0x6dc5cd59, 0x6086db80, 0x6447d637, 0x7a00f632, 0x7ec1fb85, 0x7382ed5c, 0x7743e0eb, 0x4f0cad56, 0x4bcda0e1, 0x468eb638, 0x424fbb8f, 0x5c089b8a, 0x58c9963d, 0x558a80e4, 0x514b8d53, 0x25141b9e, 0x21d51629, 0x2c9600f0, 0x28570d47, 0x36102d42, 0x32d120f5, 0x3f92362c, 0x3b533b9b, 0x031c7626, 0x07dd7b91, 0x0a9e6d48, 0x0e5f60ff, 0x101840fa, 0x14d94d4d, 0x199a5b94, 0x1d5b5623, 0xf125760e, 0xf5e47bb9, 0xf8a76d60, 0xfc6660d7, 0xe22140d2, 0xe6e04d65, 0xeba35bbc, 0xef62560b, 0xd72d1bb6, 0xd3ec1601, 0xdeaf00d8, 0xda6e0d6f, 0xc4292d6a, 0xc0e820dd, 0xcdab3604, 0xc96a3bb3, 0xbd35ad7e, 0xb9f4a0c9, 0xb4b7b610, 0xb076bba7, 0xae319ba2, 0xaaf09615, 0xa7b380cc, 0xa3728d7b, 0x9b3dc0c6, 0x9ffccd71, 0x92bfdba8, 0x967ed61f, 0x8839f61a, 0x8cf8fbad, 0x81bbed74, 0x857ae0c3, 0x5d86a099, 0x5947ad2e, 0x5404bbf7, 0x50c5b640, 0x4e829645, 0x4a439bf2, 0x47008d2b, 0x43c1809c, 0x7b8ecd21, 0x7f4fc096, 0x720cd64f, 0x76cddbf8, 0x688afbfd, 0x6c4bf64a, 0x6108e093, 0x65c9ed24, 0x11967be9, 0x1557765e, 0x18146087, 0x1cd56d30, 0x02924d35, 0x06534082, 0x0b10565b, 0x0fd15bec, 0x379e1651, 0x335f1be6, 0x3e1c0d3f, 0x3add0088, 0x249a208d, 0x205b2d3a, 0x2d183be3, 0x29d93654, 0xc5a71679, 0xc1661bce, 0xcc250d17, 0xc8e400a0, 0xd6a320a5, 0xd2622d12, 0xdf213bcb, 0xdbe0367c, 0xe3af7bc1, 0xe76e7676, 0xea2d60af, 0xeeec6d18, 0xf0ab4d1d, 0xf46a40aa, 0xf9295673, 0xfde85bc4, 0x89b7cd09, 0x8d76c0be, 0x8035d667, 0x84f4dbd0, 0x9ab3fbd5, 0x9e72f662, 0x9331e0bb, 0x97f0ed0c, 0xafbfa0b1, 0xab7ead06, 0xa63dbbdf, 0xa2fcb668, 0xbcbb966d, 0xb87a9bda, 0xb5398d03, 0xb1f880b4, }; static inline uint16_t rkcrc16(uint16_t crc, uint8_t *buf, uint64_t size) { while (size-- > 0) crc = (crc << 8) ^ crc16table[(crc >> 8) ^ *buf++]; return crc; } static inline uint32_t rkcrc32(uint32_t crc, uint8_t *buf, uint64_t size) { while (size-- > 0) crc = (crc << 8) ^ crc32table[(crc >> 24) ^ *buf++]; return crc; } #endif #endif /* !_RKCRC_H_ */ rkflashtool-0~20160324/rkflashtool.c000066400000000000000000000545761267506535400173150ustar00rootroot00000000000000/* rkflashtool - for RockChip based devices. * (RK2808, RK2818, RK2918, RK2928, RK3066, RK3068, RK3126 and RK3188) * * Copyright (C) 2010-2014 by Ivo van Poorten, Fukaumi Naoki, Guenter Knauf, * Ulrich Prinz, Steve Wilson * * 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 AUTHORS ``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. */ #include #include #include #include #include #include #include #include /* hack to set binary mode for stdin / stdout on Windows */ #ifdef _WIN32 #include int _CRT_fmode = _O_BINARY; #endif #include "version.h" #include "rkcrc.h" #include "rkflashtool.h" #define RKFT_BLOCKSIZE 0x4000 /* must be multiple of 512 */ #define RKFT_IDB_DATASIZE 0x200 #define RKFT_IDB_BLOCKSIZE 0x210 #define RKFT_IDB_INCR 0x20 #define RKFT_MEM_INCR 0x80 #define RKFT_OFF_INCR (RKFT_BLOCKSIZE>>9) #define MAX_PARAM_LENGTH (128*512-12) /* cf. MAX_LOADER_PARAM in rkloader */ #define SDRAM_BASE_ADDRESS 0x60000000 #define RKFT_CMD_TESTUNITREADY 0x80000600 #define RKFT_CMD_READFLASHID 0x80000601 #define RKFT_CMD_READFLASHINFO 0x8000061a #define RKFT_CMD_READCHIPINFO 0x8000061b #define RKFT_CMD_READEFUSE 0x80000620 #define RKFT_CMD_SETDEVICEINFO 0x00000602 #define RKFT_CMD_ERASESYSTEMDISK 0x00000616 #define RKFT_CMD_SETRESETFLASG 0x0000061e #define RKFT_CMD_RESETDEVICE 0x000006ff #define RKFT_CMD_TESTBADBLOCK 0x80000a03 #define RKFT_CMD_READSECTOR 0x80000a04 #define RKFT_CMD_READLBA 0x80000a14 #define RKFT_CMD_READSDRAM 0x80000a17 #define RKFT_CMD_UNKNOWN1 0x80000a21 #define RKFT_CMD_WRITESECTOR 0x00000a05 #define RKFT_CMD_ERASESECTORS 0x00000a06 #define RKFT_CMD_UNKNOWN2 0x00000a0b #define RKFT_CMD_WRITELBA 0x00000a15 #define RKFT_CMD_WRITESDRAM 0x00000a18 #define RKFT_CMD_EXECUTESDRAM 0x00000a19 #define RKFT_CMD_WRITEEFUSE 0x00000a1f #define RKFT_CMD_UNKNOWN3 0x00000a22 #define RKFT_CMD_WRITESPARE 0x80001007 #define RKFT_CMD_READSPARE 0x80001008 #define RKFT_CMD_LOWERFORMAT 0x0000001c #define RKFT_CMD_WRITENKB 0x00000030 #define SETBE16(a, v) do { \ ((uint8_t*)a)[1] = v & 0xff; \ ((uint8_t*)a)[0] = (v>>8 ) & 0xff; \ } while(0) #define SETBE32(a, v) do { \ ((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; \ } while(0) static const struct t_pid { const uint16_t pid; const char name[8]; } pidtab[] = { { 0x281a, "RK2818" }, { 0x290a, "RK2918" }, { 0x292a, "RK2928" }, { 0x292c, "RK3026" }, { 0x300a, "RK3066" }, { 0x300b, "RK3168" }, { 0x301a, "RK3036" }, { 0x310a, "RK3066B" }, { 0x310b, "RK3188" }, { 0x310c, "RK312X" }, // Both RK3126 and RK3128 { 0x310d, "RK3126" }, { 0x320a, "RK3288" }, { 0x320b, "RK322X" }, // Both RK3228 and RK3229 { 0x330a, "RK3368" }, { 0, "" }, }; typedef struct { uint32_t flash_size; uint16_t block_size; uint8_t page_size; uint8_t ecc_bits; uint8_t access_time; uint8_t manufacturer_id; uint8_t chip_select; } nand_info; static const char* const manufacturer[] = { /* NAND Manufacturers */ "Samsung", "Toshiba", "Hynix", "Infineon", "Micron", "Renesas", "Intel", "UNKNOWN", /* Reserved */ "SanDisk", }; #define MAX_NAND_ID (sizeof manufacturer / sizeof(char *)) static uint8_t cmd[31], res[13], buf[RKFT_BLOCKSIZE]; static uint8_t ibuf[RKFT_IDB_BLOCKSIZE]; static libusb_context *c; static libusb_device_handle *h = NULL; static int tmp; static const char *const strings[2] = { "info", "fatal" }; static void info_and_fatal(const int s, const int cr, char *f, ...) { va_list ap; va_start(ap,f); fprintf(stderr, "%srkflashtool: %s: ", cr ? "\r" : "", strings[s]); vfprintf(stderr, f, ap); va_end(ap); if (s) exit(s); } #define info(...) info_and_fatal(0, 0, __VA_ARGS__) #define infocr(...) info_and_fatal(0, 1, __VA_ARGS__) #define fatal(...) info_and_fatal(1, 0, __VA_ARGS__) static void usage(void) { fatal("usage:\n" "\trkflashtool b [flag] \treboot device\n" "\trkflashtool l outfile \tread IDBlocks\n" "\trkflashtool j offset nsectors outfile \tread SDRAM\n" "\trkflashtool M offset nbytes outfile \tread flash partition\n" "\trkflashtool w partname outfile \tread flash\n" "\trkflashtool w offset nsectors outfile \tread fuses\n" // "\trkflashtool g file \tfetch parameters\n" "\trkflashtool P 1) usage(); else if (argc == 1) flag = strtoul(argv[0], NULL, 0); break; case 'l': case 'L': if (argc) usage(); break; case 'e': case 'r': case 'w': if (argc < 1 || argc > 2) usage(); if (argc == 1) { partname = argv[0]; } else { offset = strtoul(argv[0], NULL, 0); size = strtoul(argv[1], NULL, 0); } break; case 'm': case 'M': case 'B': case 'i': case 'j': if (argc != 2) usage(); offset = strtoul(argv[0], NULL, 0); size = strtoul(argv[1], NULL, 0); break; case 'n': case 'v': case 'p': case 'P': if (argc) usage(); offset = 0; size = 1024; break; default: usage(); } /* Initialize libusb */ if (libusb_init(&c)) fatal("cannot init libusb\n"); libusb_set_debug(c, 3); /* Detect connected RockChip device */ while ( !h && ppid->pid) { h = libusb_open_device_with_vid_pid(c, 0x2207, ppid->pid); if (h) { info("Detected %s...\n", ppid->name); break; } ppid++; } if (!h) fatal("cannot open device\n"); /* Connect to device */ 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"); if (libusb_get_device_descriptor(libusb_get_device(h), &desc) != 0) fatal("cannot get device descriptor\n"); if (desc.bcdUSB == 0x200) info("MASK ROM MODE\n"); switch(action) { case 'l': info("load DDR init\n"); crc16 = 0xffff; while ((nr = read(0, buf, 4096)) == 4096) { crc16 = rkcrc16(crc16, buf, nr); libusb_control_transfer(h, LIBUSB_REQUEST_TYPE_VENDOR, 12, 0, 1137, buf, nr, 0); } if (nr != -1) { crc16 = rkcrc16(crc16, buf, nr); buf[nr++] = crc16 >> 8; buf[nr++] = crc16 & 0xff; libusb_control_transfer(h, LIBUSB_REQUEST_TYPE_VENDOR, 12, 0, 1137, buf, nr, 0); } goto exit; case 'L': info("load USB loader\n"); crc16 = 0xffff; while ((nr = read(0, buf, 4096)) == 4096) { crc16 = rkcrc16(crc16, buf, nr); libusb_control_transfer(h, LIBUSB_REQUEST_TYPE_VENDOR, 12, 0, 1138, buf, nr, 0); } if (nr != -1) { crc16 = rkcrc16(crc16, buf, nr); buf[nr++] = crc16 >> 8; buf[nr++] = crc16 & 0xff; libusb_control_transfer(h, LIBUSB_REQUEST_TYPE_VENDOR, 12, 0, 1138, buf, nr, 0); } goto exit; } /* Initialize bootloader interface */ send_cmd(RKFT_CMD_TESTUNITREADY, 0, 0); recv_res(); usleep(20*1000); /* Parse partition name */ if (partname) { info("working with partition: %s\n", partname); /* Read parameters */ offset = 0; send_cmd(RKFT_CMD_READLBA, offset, RKFT_OFF_INCR); recv_buf(RKFT_BLOCKSIZE); recv_res(); /* Check parameter length */ uint32_t *p = (uint32_t*)buf+1; size = *p; if (size < 0 || size > MAX_PARAM_LENGTH) fatal("Bad parameter length!\n"); /* Search for mtdparts */ const char *param = (const char *)&buf[8]; const char *mtdparts = strstr(param, "mtdparts="); if (!mtdparts) { info("Error: 'mtdparts' not found in command line.\n"); goto exit; } /* Search for '(partition_name)' */ char partexp[256]; snprintf(partexp, 256, "(%s)", partname); char *par = strstr(mtdparts, partexp); if (!par) { info("Error: Partition '%s' not found.\n", partname); goto exit; } /* Cut string by NULL-ing just before (partition_name) */ par[0] = '\0'; /* Search for '@' sign */ char *arob = strrchr(mtdparts, '@'); if (!arob) { info("Error: Bad syntax in mtdparts.\n"); goto exit; } offset = strtoul(arob+1, NULL, 0); info("found offset: %#010x\n", offset); /* Cut string by NULL-ing just before '@' sign */ arob[0] = '\0'; /* Search for '-' sign (if last partition) */ char *minus = strrchr(mtdparts, '-'); if (minus) { /* Read size from NAND info */ send_cmd(RKFT_CMD_READFLASHINFO, 0, 0); recv_buf(512); recv_res(); nand_info *nand = (nand_info *) buf; size = nand->flash_size - offset; info("partition extends up to the end of NAND (size: 0x%08x).\n", size); goto action; } /* Search for ',' sign */ char *comma = strrchr(mtdparts, ','); if (comma) { size = strtoul(comma+1, NULL, 0); info("found size: %#010x\n", size); goto action; } /* Search for ':' sign (if first partition) */ char *colon = strrchr(mtdparts, ':'); if (colon) { size = strtoul(colon+1, NULL, 0); info("found size: %#010x\n", size); goto action; } /* Error: size not found! */ info("Error: Bad syntax for partition size.\n"); goto exit; } action: /* Check and execute command */ switch(action) { case 'b': /* Reboot device */ info("rebooting device...\n"); send_reset(flag); recv_res(); break; case 'r': /* Read FLASH */ while (size > 0) { infocr("reading flash memory at offset 0x%08x", offset); send_cmd(RKFT_CMD_READLBA, offset, RKFT_OFF_INCR); recv_buf(RKFT_BLOCKSIZE); recv_res(); if (write(1, buf, RKFT_BLOCKSIZE) <= 0) fatal("Write error! Disk full?\n"); offset += RKFT_OFF_INCR; size -= RKFT_OFF_INCR; } fprintf(stderr, "... Done!\n"); break; case 'w': /* Write FLASH */ while (size > 0) { infocr("writing flash memory at offset 0x%08x", offset); if (read(0, buf, RKFT_BLOCKSIZE) <= 0) { fprintf(stderr, "... Done!\n"); info("premature end-of-file reached.\n"); goto exit; } send_cmd(RKFT_CMD_WRITELBA, offset, RKFT_OFF_INCR); send_buf(RKFT_BLOCKSIZE); recv_res(); offset += RKFT_OFF_INCR; size -= RKFT_OFF_INCR; } fprintf(stderr, "... Done!\n"); break; case 'p': /* Retreive parameters */ { uint32_t *p = (uint32_t*)buf+1; info("reading parameters at offset 0x%08x\n", offset); send_cmd(RKFT_CMD_READLBA, offset, RKFT_OFF_INCR); recv_buf(RKFT_BLOCKSIZE); recv_res(); /* Check size */ size = *p; info("size: 0x%08x\n", size); if (size < 0 || size > MAX_PARAM_LENGTH) fatal("Bad parameter length!\n"); /* Check CRC */ uint32_t crc_buf = *(uint32_t *)(buf + 8 + size), crc = 0; crc = rkcrc32(crc, buf + 8, size); if (crc_buf != crc) fatal("bad CRC! (%#x, should be %#x)\n", crc_buf, crc); if (write(1, &buf[8], size) <= 0) fatal("Write error! Disk full?\n"); } break; case 'P': /* Write parameters */ { /* Header */ strncpy((char *)buf, "PARM", 4); /* Content */ int sizeRead; if ((sizeRead = read(0, buf + 8, RKFT_BLOCKSIZE - 8)) < 0) { info("read error: %s\n", strerror(errno)); goto exit; } /* Length */ *(uint32_t *)(buf + 4) = sizeRead; /* CRC */ uint32_t crc = 0; crc = rkcrc32(crc, buf + 8, sizeRead); PUT32LE(buf + 8 + sizeRead, crc); /* * The parameter file is written at 8 different offsets: * 0x0000, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00 */ for(offset = 0; offset < 0x2000; offset += 0x400) { infocr("writing flash memory at offset 0x%08x", offset); send_cmd(RKFT_CMD_WRITELBA, offset, RKFT_OFF_INCR); send_buf(RKFT_BLOCKSIZE); recv_res(); } } fprintf(stderr, "... Done!\n"); break; case 'm': /* Read RAM */ while (size > 0) { int sizeRead = size > RKFT_BLOCKSIZE ? RKFT_BLOCKSIZE : size; infocr("reading memory at offset 0x%08x size %x", offset, sizeRead); send_cmd(RKFT_CMD_READSDRAM, offset - SDRAM_BASE_ADDRESS, sizeRead); recv_buf(sizeRead); recv_res(); if (write(1, buf, sizeRead) <= 0) fatal("Write error! Disk full?\n"); offset += sizeRead; size -= sizeRead; } fprintf(stderr, "... Done!\n"); break; case 'M': /* Write RAM */ while (size > 0) { int sizeRead; if ((sizeRead = read(0, buf, RKFT_BLOCKSIZE)) <= 0) { info("premature end-of-file reached.\n"); goto exit; } infocr("writing memory at offset 0x%08x size %x", offset, sizeRead); send_cmd(RKFT_CMD_WRITESDRAM, offset - SDRAM_BASE_ADDRESS, sizeRead); send_buf(sizeRead); recv_res(); offset += sizeRead; size -= sizeRead; } fprintf(stderr, "... Done!\n"); break; case 'B': /* Exec RAM */ info("booting kernel...\n"); send_exec(offset - SDRAM_BASE_ADDRESS, size - SDRAM_BASE_ADDRESS); recv_res(); break; case 'i': /* Read IDB */ while (size > 0) { int sizeRead = size > RKFT_IDB_INCR ? RKFT_IDB_INCR : size; infocr("reading IDB flash memory at offset 0x%08x", offset); send_cmd(RKFT_CMD_READSECTOR, offset, sizeRead); recv_buf(RKFT_IDB_BLOCKSIZE * sizeRead); recv_res(); if (write(1, buf, RKFT_IDB_BLOCKSIZE * sizeRead) <= 0) fatal("Write error! Disk full?\n"); offset += sizeRead; size -= sizeRead; } fprintf(stderr, "... Done!\n"); break; case 'j': /* write IDB */ while (size > 0) { infocr("writing IDB flash memory at offset 0x%08x", offset); memset(ibuf, RKFT_IDB_BLOCKSIZE, 0xff); if (read(0, ibuf, RKFT_IDB_DATASIZE) <= 0) { fprintf(stderr, "... Done!\n"); info("premature end-of-file reached.\n"); goto exit; } send_cmd(RKFT_CMD_WRITESECTOR, offset, 1); libusb_bulk_transfer(h, 2|LIBUSB_ENDPOINT_OUT, ibuf, RKFT_IDB_BLOCKSIZE, &tmp, 0); recv_res(); offset += 1; size -= 1; } fprintf(stderr, "... Done!\n"); break; case 'e': /* Erase flash */ memset(buf, 0xff, RKFT_BLOCKSIZE); while (size > 0) { infocr("erasing flash memory at offset 0x%08x", offset); send_cmd(RKFT_CMD_WRITELBA, offset, RKFT_OFF_INCR); send_buf(RKFT_BLOCKSIZE); recv_res(); offset += RKFT_OFF_INCR; size -= RKFT_OFF_INCR; } fprintf(stderr, "... Done!\n"); break; case 'v': /* Read Chip Version */ send_cmd(RKFT_CMD_READCHIPINFO, 0, 0); recv_buf(16); recv_res(); info("chip version: %c%c%c%c-%c%c%c%c.%c%c.%c%c-%c%c%c%c\n", buf[ 3], buf[ 2], buf[ 1], buf[ 0], buf[ 7], buf[ 6], buf[ 5], buf[ 4], buf[11], buf[10], buf[ 9], buf[ 8], buf[15], buf[14], buf[13], buf[12]); break; case 'n': /* Read NAND Flash Info */ { send_cmd(RKFT_CMD_READFLASHID, 0, 0); recv_buf(5); recv_res(); info("Flash ID: %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3], buf[4]); send_cmd(RKFT_CMD_READFLASHINFO, 0, 0); recv_buf(512); recv_res(); nand_info *nand = (nand_info *) buf; uint8_t id = nand->manufacturer_id, cs = nand->chip_select; info("Flash Info:\n" "\tManufacturer: %s (%d)\n" "\tFlash Size: %dMB\n" "\tBlock Size: %dKB\n" "\tPage Size: %dKB\n" "\tECC Bits: %d\n" "\tAccess Time: %d\n" "\tFlash CS:%s%s%s%s\n", /* Manufacturer */ id < MAX_NAND_ID ? manufacturer[id] : "Unknown", id, nand->flash_size >> 11, /* Flash Size */ nand->block_size >> 1, /* Block Size */ nand->page_size >> 1, /* Page Size */ nand->ecc_bits, /* ECC Bits */ nand->access_time, /* Access Time */ /* Flash CS */ cs & 1 ? " <0>" : "", cs & 2 ? " <1>" : "", cs & 4 ? " <2>" : "", cs & 8 ? " <3>" : ""); } default: break; } exit: /* Disconnect and close all interfaces */ libusb_release_interface(h, 0); libusb_close(h); libusb_exit(c); return 0; } rkflashtool-0~20160324/rkflashtool.h000066400000000000000000000003071267506535400173010ustar00rootroot00000000000000#define PUT32LE(x, y) \ do { \ (x)[0] = ((y)>> 0) & 0xff; \ (x)[1] = ((y)>> 8) & 0xff; \ (x)[2] = ((y)>>16) & 0xff; \ (x)[3] = ((y)>>24) & 0xff; \ } while (0) rkflashtool-0~20160324/rkmisc000077500000000000000000000040511267506535400160160ustar00rootroot00000000000000#! /bin/sh # Copyright (C) 2013 Ivo van Poorten # All rights reserved # # 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 AUTHORS ``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. MAJOR=5 MINOR=2 test "$#" -eq 2 || { cat << __EOF__ rkmisc v$MAJOR.$MINOR usage: rkmisc action outfile generate a misc "partition" nothing wipe_all wipe_data wipe_cache wipe_userdata wipe_swap wipe_udisk wipe_pagecache clear_account update_image=%s recover_image=%s __EOF__ exit } dd if=/dev/zero of="$2" bs=4096 count=1024 case "$1" in nothing) ;; wipe_all|wipe_data|wipe_cache|wipe_userdata|wipe_swap|wipe_udisk|wipe_pagecache|clear_account|update_image=*|recover_image=*) echo -n "boot-recovery" | dd of="$2" bs=1 seek=$((0x4000)) conv=notrunc echo -ne "recovery\012--$1" | dd of="$2" bs=1 seek=$((0x4040)) conv=notrunc ;; *) echo "$0: unknown action $1" >&2 ;; esac rkflashtool-0~20160324/rkpad000077500000000000000000000032361267506535400156330ustar00rootroot00000000000000#! /bin/sh # Copyright (C) 2013 Ivo van Poorten # All rights reserved # # 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 AUTHORS ``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. MAJOR=5 MINOR=2 test "$#" -eq 3 || { cat << __EOF__ rkpad v$MAJOR.$MINOR usage: rkpad size infile outfile copy infile to outfile and pad with zeroes up to the specified size. size is in blocks of 512 bytes (!) i.e. equal to the partition sizes. e.g. rkpad 0x00002000 foo bar __EOF__ exit } dd if=/dev/zero of="$3" bs=512 count=$(($1)) dd if="$2" of="$3" conv=notrunc rkflashtool-0~20160324/rkparameters000077500000000000000000000052501267506535400172300ustar00rootroot00000000000000#! /bin/sh # Copyright (C) 2013 Ivo van Poorten # All rights reserved # # 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 AUTHORS ``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. MAJOR=5 MINOR=2 test "$#" -eq 3 || { cat << __EOF__ rkparameters v$MAJOR.$MINOR usage: rkparameters model fw_version partitionsfile > outfile e.g. rkparameters arnova7g2 1.2.3 mtdparts.txt > params mtdparts.txt: first line is the command line; the following lines contain the name of the partition and its size. the parameters partition is skipped __EOF__ exit } vars="FW_VERSION \ FIRMWARE_VER \ MACHINE_MODEL \ MACHINE_ID \ MANUFACTURER \ MAGIC \ ATAG \ MACHINE \ CHECK_MASK \ KERNEL_IMG \ COMBINATION_KEY \ CMDLINE" for i in $vars ; do eval $i= done MAGIC=0x5041524B ATAG=0x60000800 CHECK_MASK=0x80 KERNEL_IMG=0x60008000 case $1 in arnova10g1) FW_VERSION=$2 MACHINE=1616 COMBINATION_KEY=F,0,1 ;; arnova7g2|*) FIRMWARE_VER=$2 MACHINE_MODEL=AN7G2 MACHINE_ID=007 MANUFACTURER=RK29SDK MACHINE=2929 KERNEL_IMG=0x60408000 ;; esac for i in $vars ; do eval j=$i eval k=\$$j test -n "$k" && echo "$j: $k" done cat "$3" | { read CMDLINE echo -n "$CMDLINE" POS=0x00002000 # skip parameter block read NAME SIZE while test "$SIZE" != "-" ; do printf "0x%08x@0x%08x($NAME)," $SIZE $POS POS=$(($POS+$SIZE)) read NAME SIZE done printf -- "-@0x%08x($NAME)\n" $POS } rkflashtool-0~20160324/rkparametersblock000077500000000000000000000034771267506535400202540ustar00rootroot00000000000000#! /bin/sh # Copyright (C) 2013 Ivo van Poorten # All rights reserved # # 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 AUTHORS ``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. MAJOR=5 MINOR=2 test "$#" -eq 2 || { cat << __EOF__ rkparametersblock v$MAJOR.$MINOR usage: rkparametersblock parametersfile outfile needs rkcrc to function correctly parametersfile is created with rkparameters e.g. rkparametersblock params.txt outfile.bin __EOF__ exit } TEMPFILE=rkparametersblock-tmp-$USER locations="0x00000 0x04000 0x08000 0x0c000 0x10000" rkcrc -p "$1" "$TEMPFILE" dd if=/dev/zero of="$2" bs=4096 count=1024 for i in $locations ; do dd if="$TEMPFILE" of="$2" bs=1 seek=$(($i)) conv=notrunc done rm -f "$TEMPFILE" rkflashtool-0~20160324/rkunpack.c000066400000000000000000000150231267506535400165630ustar00rootroot00000000000000/* * Copyright (c) 2010 Fukaumi Naoki * Copyright (c) 2013 Ivo van Poorten * All rights reserved. * * 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include "version.h" #ifdef _WIN32 /* hack around non-posix behaviour */ #undef mkdir #define mkdir(a,b) _mkdir(a) int _mkdir(const char *); #include HANDLE fm; #else #define O_BINARY 0 #endif static uint8_t *buf; static off_t size; static unsigned int fsize, ioff, isize, noff; static int fd; static const char *const strings[2] = { "info", "fatal" }; static void info_and_fatal(const int s, const char *f, ...) { va_list ap; va_start(ap,f); fprintf(stderr, "rkunpack: %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__) #define GET32LE(x) ((x)[0] | (x)[1] << 8 | (x)[2] << 16 | (x)[3] << 24) static void write_file(const char *path, uint8_t *buffer, unsigned int length) { int img; if ((img = open(path, O_BINARY | O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1 || write(img, buffer, length) == -1 || close(img) == -1) fatal("%s: %s\n", path, strerror(errno)); } static void unpack_rkaf(void) { uint8_t *p; const char *name, *path, *sep; char dir[PATH_MAX]; int count; info("RKAF signature detected\n"); fsize = GET32LE(buf+4) + 4; if (fsize != (unsigned)size) info("invalid file size (should be %u bytes)\n", fsize); else info("file size matches (%u bytes)\n", fsize); info("manufacturer: %s\n", buf + 0x48); info("model: %s\n", buf + 0x08); count = GET32LE(buf+0x88); info("number of files: %d\n", count); for (p = &buf[0x8c]; count > 0; p += 0x70, count--) { name = (const char *)p; path = (const char *)p + 0x20; ioff = GET32LE(p+0x60); noff = GET32LE(p+0x64); isize = GET32LE(p+0x68); fsize = GET32LE(p+0x6c); if (memcmp(path, "SELF", 4) == 0) { info("skipping SELF entry\n"); } else { info("%08x-%08x %-26s (size: %d)\n", ioff, ioff + isize - 1, path, fsize); // strip header and footer of parameter file if (memcmp(name, "parameter", 9) == 0) { ioff += 8; fsize -= 12; } sep = path; while ((sep = strchr(sep, '/')) != NULL) { memcpy(dir, path, sep - path); dir[sep - path] = '\0'; if (mkdir(dir, 0755) == -1 && errno != EEXIST) fatal("%s: %s\n", dir, strerror(errno)); sep++; } write_file(path, buf+ioff, fsize); } } } static void unpack_rkfw(void) { const char *chip = NULL; info("RKFW signature detected\n"); info("version: %d.%d.%d\n", buf[9], buf[8], (buf[7]<<8)+buf[6]); info("date: %d-%02d-%02d %02d:%02d:%02d\n", (buf[0x0f]<<8)+buf[0x0e], buf[0x10], buf[0x11], buf[0x12], buf[0x13], buf[0x14]); switch(buf[0x15]) { case 0x50: chip = "rk29xx"; break; case 0x60: chip = "rk30xx"; break; case 0x70: chip = "rk31xx"; break; case 0x80: chip = "rk32xx"; break; case 0x41: chip = "rk3368"; break; default: info("You got a brand new chip (%#x), congratulations!!!\n", buf[0x15]); } info("family: %s\n", chip ? chip : "unknown"); ioff = GET32LE(buf+0x19); isize = GET32LE(buf+0x1d); if (memcmp(buf+ioff, "BOOT", 4)) fatal("cannot find BOOT signature\n"); info("%08x-%08x %-26s (size: %d)\n", ioff, ioff + isize -1, "BOOT", isize); write_file("BOOT", buf+ioff, isize); ioff = GET32LE(buf+0x21); isize = GET32LE(buf+0x25); if (memcmp(buf+ioff, "RKAF", 4)) fatal("cannot find embedded RKAF update.img\n"); info("%08x-%08x %-26s (size: %d)\n", ioff, ioff + isize -1, "embedded-update.img", isize); write_file("embedded-update.img", buf+ioff, isize); } int main(int argc, char *argv[]) { if (argc != 2) fatal("rkunpack v%d.%d\nusage: %s update.img\n", RKFLASHTOOL_VERSION_MAJOR, RKFLASHTOOL_VERSION_MINOR, argv[0]); if ((fd = open(argv[1], O_BINARY | O_RDONLY)) == -1) fatal("%s: %s\n", argv[1], strerror(errno)); if ((size = lseek(fd, 0, SEEK_END)) == -1) fatal("%s: %s\n", argv[1], strerror(errno)); #ifdef _WIN32 fm = CreateFileMapping((HANDLE)_get_osfhandle(fd), NULL, PAGE_READONLY, 0, 0, NULL); buf = MapViewOfFile(fm, FILE_MAP_READ, 0, 0, 0); if (!buf) fatal("%s: cannot create MapView of File\n", argv[1]); #else if ((buf = mmap(NULL, size, PROT_READ, MAP_SHARED | MAP_FILE, fd, 0)) == MAP_FAILED) fatal("%s: %s\n", argv[1], strerror(errno)); #endif if (!memcmp(buf, "RKAF", 4)) unpack_rkaf(); else if (!memcmp(buf, "RKFW", 4)) unpack_rkfw(); else fatal("%s: invalid signature\n", argv[1]); printf("unpacked\n"); #ifdef _WIN32 CloseHandle(fm); UnmapViewOfFile(buf); #else munmap(buf, size); #endif close(fd); return 0; } rkflashtool-0~20160324/rkunsign000077500000000000000000000032271267506535400163720ustar00rootroot00000000000000#! /bin/sh # Copyright (C) 2013 Ivo van Poorten # All rights reserved # # 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 AUTHORS ``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. MAJOR=5 MINOR=2 test "$#" -eq 2 || { cat << __EOF__ rkpad v$MAJOR.$MINOR usage: rkunsign infile outfile copy infile to outfile and strip the KRNL/PARM header and crc footer e.g. rkunsign signed-kernel.img unsigned-kernel.img __EOF__ exit } dd if=/dev/zero if="$1" of="$2" ibs=8 skip=1 SIZE=`stat -c %s "$2"` dd if=/dev/zero of="$2" obs=1 seek=$(($SIZE-4)) count=0 rkflashtool-0~20160324/version.h000066400000000000000000000002251267506535400164350ustar00rootroot00000000000000#ifndef RKFLASHTOOL_VERSION_H #define RKFLASHTOOL_VERSION_H #define RKFLASHTOOL_VERSION_MAJOR 5 #define RKFLASHTOOL_VERSION_MINOR 2 #endif