[xrock]first commit

This commit is contained in:
JianjunJiang 2021-08-02 17:29:22 +08:00
commit 365f40a57e
15 changed files with 1203 additions and 0 deletions

15
.gitignore vendored Normal file
View File

@ -0,0 +1,15 @@
#
# Normal rules
#
*.d
*.o
*.map
*~
#
# Generated files
#
/.cproject
/.project
/.settings
/xrock

22
99-xrock.rules Normal file
View File

@ -0,0 +1,22 @@
# Copy this file to /etc/udev/rules.d/ or /usr/lib/udev/rules.d/
# If rules fail to reload automatically, you can refresh udev rules
# with the command "sudo udevadm control --reload"
SUBSYSTEM!="usb", GOTO="end_rules"
# RK3036
ATTRS{idVendor}=="2207", ATTRS{idProduct}=="301a", MODE="0666", GROUP="users"
# RK3128
ATTRS{idVendor}=="2207", ATTRS{idProduct}=="310c", MODE="0666", GROUP="users"
# RK3229
ATTRS{idVendor}=="2207", ATTRS{idProduct}=="320b", MODE="0666", GROUP="users"
# RK3288
ATTRS{idVendor}=="2207", ATTRS{idProduct}=="320a", MODE="0666", GROUP="users"
# RK3328
ATTRS{idVendor}=="2207", ATTRS{idProduct}=="320c", MODE="0666", GROUP="users"
# RK3368
ATTRS{idVendor}=="2207", ATTRS{idProduct}=="330a", MODE="0666", GROUP="users"
# RK3399
ATTRS{idVendor}=="2207", ATTRS{idProduct}=="330c", MODE="0666", GROUP="users"
LABEL="end_rules"

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright(c) 2007-2021 Jianjun Jiang <8192542@qq.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

76
Makefile Normal file
View File

@ -0,0 +1,76 @@
#
# Top makefile
#
CROSS ?=
AS := $(CROSS)gcc -x assembler-with-cpp
CC := $(CROSS)gcc
CXX := $(CROSS)g++
LD := $(CROSS)ld
AR := $(CROSS)ar
OC := $(CROSS)objcopy
OD := $(CROSS)objdump
RM := rm -fr
ASFLAGS := -g -ggdb -Wall -O3
CFLAGS := -g -ggdb -Wall -O3
CXXFLAGS := -g -ggdb -Wall -O3
LDFLAGS :=
ARFLAGS := -rcs
OCFLAGS := -v -O binary
ODFLAGS :=
MCFLAGS :=
LIBDIRS :=
LIBS := `pkg-config --libs libusb-1.0`
INCDIRS := -I . `pkg-config --cflags libusb-1.0`
SRCDIRS := . chips
SFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))
CFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))
CPPFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.cpp))
SDEPS := $(patsubst %, %, $(SFILES:.S=.o.d))
CDEPS := $(patsubst %, %, $(CFILES:.c=.o.d))
CPPDEPS := $(patsubst %, %, $(CPPFILES:.cpp=.o.d))
DEPS := $(SDEPS) $(CDEPS) $(CPPDEPS)
SOBJS := $(patsubst %, %, $(SFILES:.S=.o))
COBJS := $(patsubst %, %, $(CFILES:.c=.o))
CPPOBJS := $(patsubst %, %, $(CPPFILES:.cpp=.o))
OBJS := $(SOBJS) $(COBJS) $(CPPOBJS)
OBJDIRS := $(patsubst %, %, $(SRCDIRS))
NAME := xrock
VPATH := $(OBJDIRS)
.PHONY: all install clean
all : $(NAME)
$(NAME) : $(OBJS)
@echo [LD] Linking $@
@$(CC) $(LDFLAGS) $(LIBDIRS) -Wl,--cref,-Map=$@.map $^ -o $@ $(LIBS)
$(SOBJS) : %.o : %.S
@echo [AS] $<
@$(AS) $(ASFLAGS) -MD -MP -MF $@.d $(INCDIRS) -c $< -o $@
$(COBJS) : %.o : %.c
@echo [CC] $<
@$(CC) $(CFLAGS) -MD -MP -MF $@.d $(INCDIRS) -c $< -o $@
$(CPPOBJS) : %.o : %.cpp
@echo [CXX] $<
@$(CXX) $(CXXFLAGS) -MD -MP -MF $@.d $(INCDIRS) -c $< -o $@
install:
install -Dm0755 xrock /usr/local/bin/xrock
install -Dm0644 99-xrock.rules /etc/udev/rules.d/99-xrock.rules
install -Dm0644 LICENSE /usr/share/licenses/xrock/LICENSE
clean:
@$(RM) $(DEPS) $(OBJS) $(NAME).map $(NAME) *~

53
README.md Normal file
View File

@ -0,0 +1,53 @@
***
# XROCK
The rockusb tools for rockchip SOC, support maskrom and loader mode for many chips.
## How to build
The xrock tools depends on the `libusb-1.0` library, you need to install `libusb-1.0-0-dev` before compile, for example in ubuntu:
```shell
sudo apt install libusb-1.0-0-dev
```
Then just type `make` at the root directory, you will see a binary program.
```shell
cd xrock
make
sudo make install
```
## Usage
```
xrock(v1.1.3) - https://github.com/xboot/xrock
usage:
xrock version - Show chip version
xrock hexdump <address> <length> - Dumps memory region in hex
xrock dump <address> <length> - Binary memory dump to stdout
xrock exec <address> - Call function address
xrock read32 <address> - Read 32-bits value from device memory
xrock write32 <address> <value> - Write 32-bits value to device memory
xrock read <address> <length> <file> - Read memory to file
xrock write <address> <file> - Write file to memory
xrock reset - Reset device using watchdog
xrock sid - Show sid information
xrock jtag - Enable jtag debug
xrock ddr [type] - Initial ddr controller with optional type
xrock spinor - Detect spi nor flash
xrock spinor read <address> <length> <file> - Read spi nor flash to file
xrock spinor write <address> <file> - Write file to spi nor flash
xrock spinand - Detect spi nand flash
xrock spinand read <address> <length> <file> - Read spi nand flash to file
xrock spinand write <address> <file> - Write file to spi nand flash
```
## Links
* [The rockchip rkdeveloptool](https://github.com/rockchip-linux/rkdeveloptool)
## License
This library is free software; you can redistribute it and or modify it under the terms of the MIT license. See [MIT License](LICENSE) for details.

45
crc16.c Normal file
View File

@ -0,0 +1,45 @@
#include <crc16.h>
static const uint16_t crc16_table[256] = {
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,
};
uint16_t crc16_sum(uint16_t crc, const uint8_t * buf, int len)
{
int i;
for(i = 0; i < len; i++)
crc = crc16_table[((crc >> 8) ^ *buf++) & 0xff] ^ (crc << 8);
return crc;
}

16
crc16.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef __CRC16_H__
#define __CRC16_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <x.h>
uint16_t crc16_sum(uint16_t crc, const uint8_t * buf, int len);
#ifdef __cplusplus
}
#endif
#endif /* __CRC16_H__ */

275
main.c Normal file
View File

@ -0,0 +1,275 @@
#include <rock.h>
static uint64_t file_save(const char * filename, void * buf, uint64_t len)
{
FILE * out = fopen(filename, "wb");
int r;
if(!out)
{
perror("Failed to open output file");
exit(-1);
}
r = fwrite(buf, len, 1, out);
fclose(out);
return r;
}
static void * file_load(const char * filename, uint64_t * len)
{
uint64_t offset = 0, bufsize = 8192;
char * buf = malloc(bufsize);
FILE * in;
if(strcmp(filename, "-") == 0)
in = stdin;
else
in = fopen(filename, "rb");
if(!in)
{
perror("Failed to open input file");
exit(-1);
}
while(1)
{
uint64_t len = bufsize - offset;
uint64_t n = fread(buf + offset, 1, len, in);
offset += n;
if(n < len)
break;
bufsize *= 2;
buf = realloc(buf, bufsize);
if(!buf)
{
perror("Failed to resize load_file() buffer");
exit(-1);
}
}
if(len)
*len = offset;
if(in != stdin)
fclose(in);
return buf;
}
static void hexdump(uint32_t addr, void * buf, size_t len)
{
unsigned char * p = buf;
size_t i, j;
for(j = 0; j < len; j += 16)
{
printf("%08zx: ", addr + j);
for(i = 0; i < 16; i++)
{
if(j + i < len)
printf("%02x ", p[j + i]);
else
printf(" ");
}
putchar(' ');
for(i = 0; i < 16; i++)
{
if(j + i >= len)
putchar(' ');
else
putchar(isprint(p[j + i]) ? p[j + i] : '.');
}
printf("\r\n");
}
}
static void usage(void)
{
printf("xrock(v1.0.0) - https://github.com/xboot/xrock\r\n");
printf("usage:\r\n");
printf(" xrock maskrom <ddr> <usbplug> - Initial chip using ddr and usbplug in maskrom mode\r\n");
printf(" xrock version - Show chip version\r\n");
printf(" xrock hexdump <address> <length> - Dumps memory region in hex\r\n");
printf(" xrock dump <address> <length> - Binary memory dump to stdout\r\n");
printf(" xrock exec <address> - Call function address\r\n");
printf(" xrock read32 <address> - Read 32-bits value from device memory\r\n");
printf(" xrock write32 <address> <value> - Write 32-bits value to device memory\r\n");
printf(" xrock read <address> <length> <file> - Read memory to file\r\n");
printf(" xrock write <address> <file> - Write file to memory\r\n");
printf(" xrock reset - Reset device using watchdog\r\n");
printf(" xrock sid - Show sid information\r\n");
printf(" xrock jtag - Enable jtag debug\r\n");
printf(" xrock ddr [type] - Initial ddr controller with optional type\r\n");
}
int main(int argc, char * argv[])
{
struct xrock_ctx_t ctx;
if(argc < 2)
{
usage();
return -1;
}
libusb_init(NULL);
if(!xrock_init(&ctx))
{
printf("ERROR: Can't found any rockchip chips\r\n");
if(ctx.hdl)
libusb_close(ctx.hdl);
libusb_exit(NULL);
return -1;
}
if(ctx.maskrom)
{
if(!strcmp(argv[1], "maskrom"))
{
argc -= 2;
argv += 2;
if(argc == 2)
{
rock_maskrom_init_ddr(&ctx, argv[0]);
rock_maskrom_init_usbplug(&ctx, argv[1]);
}
else
usage();
}
else
usage();
}
else
{
if(!strcmp(argv[1], "version"))
{
printf("%.8s soc=0x%08x(%s) 0x%08x ver=0x%04x 0x%02x 0x%02x scratchpad=0x%08x\r\n",
ctx.version.magic, ctx.version.id, ctx.chip->name, ctx.version.firmware,
ctx.version.protocol, ctx.version.dflag, ctx.version.dlength, ctx.version.scratchpad);
}
else if(!strcmp(argv[1], "hexdump"))
{
argc -= 2;
argv += 2;
if(argc == 2)
{
uint32_t addr = strtoul(argv[0], NULL, 0);
size_t len = strtoul(argv[1], NULL, 0);
char * buf = malloc(len);
if(buf)
{
fel_read(&ctx, addr, buf, len);
hexdump(addr, buf, len);
free(buf);
}
}
else
usage();
}
else if(!strcmp(argv[1], "dump"))
{
argc -= 2;
argv += 2;
if(argc == 2)
{
uint32_t addr = strtoul(argv[0], NULL, 0);
size_t len = strtoul(argv[1], NULL, 0);
char * buf = malloc(len);
if(buf)
{
fel_read(&ctx, addr, buf, len);
fwrite(buf, len, 1, stdout);
free(buf);
}
}
else
usage();
}
else if(!strcmp(argv[1], "exec"))
{
argc -= 2;
argv += 2;
if(argc == 1)
{
uint32_t addr = strtoul(argv[0], NULL, 0);
fel_exec(&ctx, addr);
}
else
usage();
}
else if(!strcmp(argv[1], "read32"))
{
argc -= 2;
argv += 2;
if(argc == 1)
{
uint32_t addr = strtoul(argv[0], NULL, 0);
printf("0x%08x\r\n", fel_read32(&ctx, addr));
}
else
usage();
}
else if(!strcmp(argv[1], "write32"))
{
argc -= 2;
argv += 2;
if(argc == 2)
{
uint32_t addr = strtoul(argv[0], NULL, 0);
size_t val = strtoul(argv[1], NULL, 0);
fel_write32(&ctx, addr, val);
}
else
usage();
}
else if(!strcmp(argv[1], "read"))
{
argc -= 2;
argv += 2;
if(argc == 3)
{
uint32_t addr = strtoul(argv[0], NULL, 0);
size_t len = strtoul(argv[1], NULL, 0);
char * buf = malloc(len);
if(buf)
{
fel_read_progress(&ctx, addr, buf, len);
file_save(argv[2], buf, len);
free(buf);
}
}
else
usage();
}
else if(!strcmp(argv[1], "write"))
{
argc -= 2;
argv += 2;
if(argc == 2)
{
uint32_t addr = strtoul(argv[0], NULL, 0);
size_t len;
void * buf = file_load(argv[1], &len);
if(buf)
{
fel_write_progress(&ctx, addr, buf, len);
free(buf);
}
}
else
usage();
}
else if(!strcmp(argv[1], "reset"))
{
}
else if(!strcmp(argv[1], "sid"))
{
}
else if(!strcmp(argv[1], "jtag"))
{
}
else
{
usage();
}
}
if(ctx.hdl)
libusb_close(ctx.hdl);
libusb_exit(NULL);
return 0;
}

58
progress.c Normal file
View File

@ -0,0 +1,58 @@
#include <progress.h>
static inline double gettime(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + (double)tv.tv_usec / 1000000.0;
}
static inline const char * format_eta(double remaining)
{
static char result[6] = "";
int seconds = remaining + 0.5;
if(seconds >= 0 && seconds < 6000)
{
snprintf(result, sizeof(result), "%02d:%02d", seconds / 60, seconds % 60);
return result;
}
return "--:--";
}
void progress_start(struct progress_t * p, size_t total)
{
if(p && (total > 0))
{
p->total = total;
p->done = 0;
p->start = gettime();
}
}
void progress_update(struct progress_t * p, size_t bytes)
{
if(p)
{
p->done += bytes;
double ratio = p->total > 0 ? (double)p->done / (double)p->total : 0.0;
double speed = (double)p->done / (gettime() - p->start);
double eta = speed > 0 ? (p->total - p->done) / speed : 0;
int i, pos = 48 * ratio;
printf("\r%3.0f%% [", ratio * 100);
for(i = 0; i < pos; i++)
putchar('=');
for(i = pos; i < 48; i++)
putchar(' ');
if(p->done < p->total)
printf("]%6.1f kB/s, ETA %s ", speed / 1000.0, format_eta(eta));
else
printf("] %5.0f kB, %6.1f kB/s", p->done / 1000.0, speed / 1000.0);
fflush(stdout);
}
}
void progress_stop(struct progress_t * p)
{
if(p)
printf("\r\n");
}

24
progress.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef __PROGRESS_H__
#define __PROGRESS_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <x.h>
struct progress_t {
size_t total;
size_t done;
double start;
};
void progress_start(struct progress_t * p, size_t total);
void progress_update(struct progress_t * p, size_t bytes);
void progress_stop(struct progress_t * p);
#ifdef __cplusplus
}
#endif
#endif /* __PROGRESS_H__ */

42
rc4.c Normal file
View File

@ -0,0 +1,42 @@
#include <rc4.h>
void rc4_setkey(struct rc4_ctx_t * ctx, uint8_t * key, int len)
{
uint8_t * s = ctx->s;
uint8_t k[256], t;
int i, j;
for(i = 0; i < 256; i++)
{
s[i] = (uint8_t)i;
k[i] = key[i % len];
}
for(i = 0, j = 0; i < 256; i++)
{
j = (j + s[i] + k[i]) & 0xff;
t = s[i];
s[i] = s[j];
s[j] = t;
}
ctx->i = 0;
ctx->j = 0;
}
void rc4_crypt(struct rc4_ctx_t * ctx, uint8_t * buf, int len)
{
uint8_t * s = ctx->s;
uint8_t t;
int i, j, o;
for(i = ctx->i, j = ctx->j, o = 0; o < len; o++)
{
i = (i + 1) & 0xff;
j = (j + s[i]) & 0xff;
t = s[i];
s[i] = s[j];
s[j] = t;
buf[o] ^= s[(s[i] + s[j]) & 0xff];
}
ctx->i = i;
ctx->j = j;
}

22
rc4.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef __RC4_H__
#define __RC4_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <x.h>
struct rc4_ctx_t {
uint8_t s[256];
int i, j;
};
void rc4_setkey(struct rc4_ctx_t * ctx, uint8_t * key, int len);
void rc4_crypt(struct rc4_ctx_t * ctx, uint8_t * buf, int len);
#ifdef __cplusplus
}
#endif
#endif /* __RC4_H__ */

388
rock.c Normal file
View File

@ -0,0 +1,388 @@
#include <rock.h>
static struct chip_t chips[] = {
{ 0x281a, "RK2818" },
{ 0x290a, "RK2918" },
{ 0x292a, "RK2928" },
{ 0x292c, "RK3026" },
{ 0x300a, "RK3066" },
{ 0x300b, "RK3168" },
{ 0x301a, "RK3036" },
{ 0x310a, "RK3066B" },
{ 0x310b, "RK3188" },
{ 0x310c, "RK312X" },
{ 0x320a, "RK3288" },
{ 0x320b, "RK322X" },
{ 0x320c, "RK3328" },
{ 0x330a, "RK3368" },
{ 0x330c, "RK3399" },
};
int xrock_init(struct xrock_ctx_t * ctx)
{
if(ctx)
{
struct libusb_device_descriptor desc;
libusb_device_handle * hdl;
int i;
ctx->hdl = NULL;
ctx->chip = NULL;
for(i = 0; i < ARRAY_SIZE(chips); i++)
{
hdl = libusb_open_device_with_vid_pid(NULL, 0x2207, chips[i].pid);
if(hdl)
{
ctx->hdl = hdl;
ctx->chip = &chips[i];
break;
}
}
if(ctx->hdl && ctx->chip)
{
if(libusb_kernel_driver_active(ctx->hdl, 0) == 1)
libusb_detach_kernel_driver(ctx->hdl, 0);
if(libusb_claim_interface(ctx->hdl, 0) == 0)
{
if(libusb_get_device_descriptor(libusb_get_device(ctx->hdl), &desc) == 0)
{
if((desc.bcdUSB & 0x0001) == 0x0000)
ctx->maskrom = 1;
else
ctx->maskrom = 0;
return 1;
}
}
}
}
return 0;
}
void rock_maskrom_init_ddr(struct xrock_ctx_t * ctx, const char * filename)
{
struct rc4_ctx_t rc4;
uint8_t key[16] = { 124, 78, 3, 4, 85, 5, 9, 7, 45, 44, 123, 56, 23, 13, 23, 17 };
uint16_t crc16 = 0xffff;
uint8_t buf[4096 + 2];
FILE * f;
int n;
rc4_setkey(&rc4, key, sizeof(key));
f = fopen(filename, "rb");
if(!f)
{
perror("Failed to open ddr file");
exit(-1);
}
while((n = fread(buf, 1, 4096, f)) == 4096)
{
rc4_crypt(&rc4, buf, n);
crc16 = crc16_sum(crc16, buf, n);
libusb_control_transfer(ctx->hdl, LIBUSB_REQUEST_TYPE_VENDOR, 12, 0, 1137, buf, n, 0);
}
fclose(f);
if(n >= 0)
{
rc4_crypt(&rc4, buf, n);
crc16 = crc16_sum(crc16, buf, n);
buf[n++] = crc16 >> 8;
buf[n++] = crc16 & 0xff;
libusb_control_transfer(ctx->hdl, LIBUSB_REQUEST_TYPE_VENDOR, 12, 0, 1137, buf, n, 0);
}
}
void rock_maskrom_init_usbplug(struct xrock_ctx_t * ctx, const char * filename)
{
struct rc4_ctx_t rc4;
uint8_t key[16] = { 124, 78, 3, 4, 85, 5, 9, 7, 45, 44, 123, 56, 23, 13, 23, 17 };
uint16_t crc16 = 0xffff;
uint8_t buf[4096 + 2];
FILE * f;
int n;
rc4_setkey(&rc4, key, sizeof(key));
f = fopen(filename, "rb");
if(!f)
{
perror("Failed to open usbplug file");
exit(-1);
}
while((n = fread(buf, 1, 4096, f)) == 4096)
{
rc4_crypt(&rc4, buf, n);
crc16 = crc16_sum(crc16, buf, n);
libusb_control_transfer(ctx->hdl, LIBUSB_REQUEST_TYPE_VENDOR, 12, 0, 1138, buf, n, 0);
}
fclose(f);
if(n >= 0)
{
rc4_crypt(&rc4, buf, n);
crc16 = crc16_sum(crc16, buf, n);
buf[n++] = crc16 >> 8;
buf[n++] = crc16 & 0xff;
libusb_control_transfer(ctx->hdl, LIBUSB_REQUEST_TYPE_VENDOR, 12, 0, 1138, buf, n, 0);
}
}
struct usb_request_t {
char magic[8];
uint32_t length;
uint32_t unknown1;
uint16_t request;
uint32_t length2;
char pad[10];
} __attribute__((packed));
struct fel_request_t {
uint32_t request;
uint32_t address;
uint32_t length;
uint32_t pad;
} __attribute__((packed));
static inline void usb_bulk_send(libusb_device_handle * hdl, int ep, const char * buf, size_t len)
{
size_t max_chunk = 128 * 1024;
size_t chunk;
int r, bytes;
while(len > 0)
{
chunk = len < max_chunk ? len : max_chunk;
r = libusb_bulk_transfer(hdl, ep, (void *)buf, chunk, &bytes, 10000);
if(r != 0)
{
printf("usb bulk send error\r\n");
exit(-1);
}
len -= bytes;
buf += bytes;
}
}
static inline void usb_bulk_recv(libusb_device_handle * hdl, int ep, char * buf, size_t len)
{
int r, bytes;
while(len > 0)
{
r = libusb_bulk_transfer(hdl, ep, (void *)buf, len, &bytes, 10000);
if(r != 0)
{
printf("usb bulk recv error\r\n");
exit(-1);
}
len -= bytes;
buf += bytes;
}
}
static inline void send_usb_request(struct xrock_ctx_t * ctx, int type, size_t length)
{
struct usb_request_t req = {
.magic = "AWUC",
.request = cpu_to_le16(type),
.length = cpu_to_le32(length),
.unknown1 = cpu_to_le32(0x0c000000)
};
req.length2 = req.length;
usb_bulk_send(ctx->hdl, ctx->epout, (const char *)&req, sizeof(struct usb_request_t));
}
static inline void read_usb_response(struct xrock_ctx_t * ctx)
{
char buf[13];
usb_bulk_recv(ctx->hdl, ctx->epin, (char *)buf, sizeof(buf));
assert(strcmp(buf, "AWUS") == 0);
}
static inline void usb_write(struct xrock_ctx_t * ctx, const void * buf, size_t len)
{
send_usb_request(ctx, 0x12, len);
usb_bulk_send(ctx->hdl, ctx->epout, (const char *)buf, len);
read_usb_response(ctx);
}
static inline void usb_read(struct xrock_ctx_t * ctx, const void * data, size_t len)
{
send_usb_request(ctx, 0x11, len);
usb_bulk_send(ctx->hdl, ctx->epin, (const char *)data, len);
read_usb_response(ctx);
}
static inline void send_fel_request(struct xrock_ctx_t * ctx, int type, uint32_t addr, uint32_t length)
{
struct fel_request_t req = {
.request = cpu_to_le32(type),
.address = cpu_to_le32(addr),
.length = cpu_to_le32(length)
};
usb_write(ctx, &req, sizeof(struct fel_request_t));
}
static inline void read_fel_status(struct xrock_ctx_t * ctx)
{
char buf[8];
usb_read(ctx, buf, sizeof(buf));
}
static inline void fel_version(struct xrock_ctx_t * ctx)
{
int i;
send_fel_request(ctx, 0x001, 0, 0);
usb_read(ctx, &ctx->version, sizeof(ctx->version));
read_fel_status(ctx);
ctx->version.id = le32_to_cpu(ctx->version.id);
ctx->version.firmware = le32_to_cpu(ctx->version.firmware);
ctx->version.protocol = le16_to_cpu(ctx->version.protocol);
ctx->version.scratchpad = le32_to_cpu(ctx->version.scratchpad);
ctx->chip = NULL;
for(i = 0; i < ARRAY_SIZE(chips); i++)
{
/* if(chips[i]->id == ctx->version.id)
{
ctx->chip = chips[i];
break;
}*/
}
}
int fel_init(struct xrock_ctx_t * ctx)
{
if(ctx && ctx->hdl)
{
struct libusb_config_descriptor * config;
int if_idx, set_idx, ep_idx;
const struct libusb_interface * iface;
const struct libusb_interface_descriptor * setting;
const struct libusb_endpoint_descriptor * ep;
if(libusb_claim_interface(ctx->hdl, 0) == 0)
{
if(libusb_get_active_config_descriptor(libusb_get_device(ctx->hdl), &config) == 0)
{
for(if_idx = 0; if_idx < config->bNumInterfaces; if_idx++)
{
iface = config->interface + if_idx;
for(set_idx = 0; set_idx < iface->num_altsetting; set_idx++)
{
setting = iface->altsetting + set_idx;
for(ep_idx = 0; ep_idx < setting->bNumEndpoints; ep_idx++)
{
ep = setting->endpoint + ep_idx;
if((ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) != LIBUSB_TRANSFER_TYPE_BULK)
continue;
if((ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN)
ctx->epin = ep->bEndpointAddress;
else
ctx->epout = ep->bEndpointAddress;
}
}
}
libusb_free_config_descriptor(config);
fel_version(ctx);
return 1;
}
}
}
return 0;
}
void fel_exec(struct xrock_ctx_t * ctx, uint32_t addr)
{
send_fel_request(ctx, 0x102, addr, 0);
read_fel_status(ctx);
}
static inline void fel_read_raw(struct xrock_ctx_t * ctx, uint32_t addr, void * buf, size_t len)
{
send_fel_request(ctx, 0x103, addr, len);
usb_read(ctx, buf, len);
read_fel_status(ctx);
}
static inline void fel_write_raw(struct xrock_ctx_t * ctx, uint32_t addr, void * buf, size_t len)
{
send_fel_request(ctx, 0x101, addr, len);
usb_write(ctx, buf, len);
read_fel_status(ctx);
}
uint32_t fel_read32(struct xrock_ctx_t * ctx, uint32_t addr)
{
uint32_t val;
fel_read_raw(ctx, addr, &val, sizeof(uint32_t));
return val;
}
void fel_write32(struct xrock_ctx_t * ctx, uint32_t addr, uint32_t val)
{
fel_write_raw(ctx, addr, &val, sizeof(uint32_t));
}
void fel_read(struct xrock_ctx_t * ctx, uint32_t addr, void * buf, size_t len)
{
size_t n;
while(len > 0)
{
n = len > 65536 ? 65536 : len;
fel_read_raw(ctx, addr, buf, n);
addr += n;
buf += n;
len -= n;
}
}
void fel_write(struct xrock_ctx_t * ctx, uint32_t addr, void * buf, size_t len)
{
size_t n;
while(len > 0)
{
n = len > 65536 ? 65536 : len;
fel_write_raw(ctx, addr, buf, n);
addr += n;
buf += n;
len -= n;
}
}
void fel_read_progress(struct xrock_ctx_t * ctx, uint32_t addr, void * buf, size_t len)
{
struct progress_t p;
size_t n;
progress_start(&p, len);
while(len > 0)
{
n = len > 65536 ? 65536 : len;
fel_read_raw(ctx, addr, buf, n);
addr += n;
buf += n;
len -= n;
progress_update(&p, n);
}
progress_stop(&p);
}
void fel_write_progress(struct xrock_ctx_t * ctx, uint32_t addr, void * buf, size_t len)
{
struct progress_t p;
size_t n;
progress_start(&p, len);
while(len > 0)
{
n = len > 65536 ? 65536 : len;
fel_write_raw(ctx, addr, buf, n);
addr += n;
buf += n;
len -= n;
progress_update(&p, n);
}
progress_stop(&p);
}

46
rock.h Normal file
View File

@ -0,0 +1,46 @@
#ifndef __ROCK_H__
#define __ROCK_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <x.h>
#include <rc4.h>
#include <crc16.h>
#include <progress.h>
struct chip_t {
uint16_t pid;
char * name;
};
struct xrock_ctx_t {
libusb_device_handle * hdl;
struct chip_t * chip;
int maskrom;
int epout;
int epin;
struct {
char magic[8];
uint32_t id;
uint32_t firmware;
uint16_t protocol;
uint8_t dflag;
uint8_t dlength;
uint32_t scratchpad;
uint8_t pad[8];
} version;
};
int xrock_init(struct xrock_ctx_t * ctx);
void rock_maskrom_init_ddr(struct xrock_ctx_t * ctx, const char * filename);
void rock_maskrom_init_usbplug(struct xrock_ctx_t * ctx, const char * filename);
#ifdef __cplusplus
}
#endif
#endif /* __ROCK_H__ */

100
x.h Normal file
View File

@ -0,0 +1,100 @@
#ifndef __X_H__
#define __X_H__
#ifdef __cplusplus
extern "C" {
#endif
#if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) && !defined(__WINDOWS__)
# define __WINDOWS__
#endif
#if defined(__linux__) || defined(__CYGWIN__)
# include <endian.h>
#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
# include <sys/endian.h>
#elif defined(__WINDOWS__)
# include <winsock2.h>
# include <sys/param.h>
#else
# error "platform not supported!"
#endif
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <assert.h>
#include <unistd.h>
#include <libusb.h>
static inline uint16_t __swab16(uint16_t x)
{
return ( (x<<8) | (x>>8) );
}
static inline uint32_t __swab32(uint32_t x)
{
return ( (x<<24) | (x>>24) | \
((x & (uint32_t)0x0000ff00UL)<<8) | \
((x & (uint32_t)0x00ff0000UL)>>8) );
}
static inline uint64_t __swab64(uint64_t x)
{
return ( (x<<56) | (x>>56) | \
((x & (uint64_t)0x000000000000ff00ULL)<<40) | \
((x & (uint64_t)0x0000000000ff0000ULL)<<24) | \
((x & (uint64_t)0x00000000ff000000ULL)<< 8) | \
((x & (uint64_t)0x000000ff00000000ULL)>> 8) | \
((x & (uint64_t)0x0000ff0000000000ULL)>>24) | \
((x & (uint64_t)0x00ff000000000000ULL)>>40) );
}
static inline uint32_t __swahw32(uint32_t x)
{
return ( ((x & (uint32_t)0x0000ffffUL)<<16) | ((x & (uint32_t)0xffff0000UL)>>16) );
}
static inline uint32_t __swahb32(uint32_t x)
{
return ( ((x & (uint32_t)0x00ff00ffUL)<<8) | ((x & (uint32_t)0xff00ff00UL)>>8) );
}
#if BYTE_ORDER == BIG_ENDIAN
#define cpu_to_le64(x) (__swab64((uint64_t)(x)))
#define le64_to_cpu(x) (__swab64((uint64_t)(x)))
#define cpu_to_le32(x) (__swab32((uint32_t)(x)))
#define le32_to_cpu(x) (__swab32((uint32_t)(x)))
#define cpu_to_le16(x) (__swab16((uint16_t)(x)))
#define le16_to_cpu(x) (__swab16((uint16_t)(x)))
#define cpu_to_be64(x) ((uint64_t)(x))
#define be64_to_cpu(x) ((uint64_t)(x))
#define cpu_to_be32(x) ((uint32_t)(x))
#define be32_to_cpu(x) ((uint32_t)(x))
#define cpu_to_be16(x) ((uint16_t)(x))
#define be16_to_cpu(x) ((uint16_t)(x))
#else
#define cpu_to_le64(x) ((uint64_t)(x))
#define le64_to_cpu(x) ((uint64_t)(x))
#define cpu_to_le32(x) ((uint32_t)(x))
#define le32_to_cpu(x) ((uint32_t)(x))
#define cpu_to_le16(x) ((uint16_t)(x))
#define le16_to_cpu(x) ((uint16_t)(x))
#define cpu_to_be64(x) (__swab64((uint64_t)(x)))
#define be64_to_cpu(x) (__swab64((uint64_t)(x)))
#define cpu_to_be32(x) (__swab32((uint32_t)(x)))
#define be32_to_cpu(x) (__swab32((uint32_t)(x)))
#define cpu_to_be16(x) (__swab16((uint16_t)(x)))
#define be16_to_cpu(x) (__swab16((uint16_t)(x)))
#endif
#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
#define X(...) ("" #__VA_ARGS__ "")
#ifdef __cplusplus
}
#endif
#endif /* __X_H__ */