94 lines
2.4 KiB
C
94 lines
2.4 KiB
C
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <libusb.h>
|
|
|
|
#include "rk27load.h"
|
|
#include "common.h"
|
|
#include "scramble.h"
|
|
#include "checksum.h"
|
|
#include "stage3_upload.h"
|
|
|
|
int upload_stage3_code(libusb_device_handle *hdev, char *fn_stage3)
|
|
{
|
|
FILE *f;
|
|
uint32_t codesize;
|
|
uint32_t remain;
|
|
uint8_t *code;
|
|
uint16_t send_size = 0x200;
|
|
uint32_t i = 0;
|
|
int ret, transfered;
|
|
|
|
if ((f = fopen(fn_stage3, "rb")) == NULL)
|
|
{
|
|
fprintf(stderr, "[error]: Could not open file \"%s\"\n", fn_stage3);
|
|
return -31;
|
|
}
|
|
|
|
codesize = filesize(f);
|
|
|
|
fprintf(stderr, "[stage3]: Loading user code (%d bytes)... ", codesize);
|
|
|
|
/* allocate buffer */
|
|
code = (uint8_t *) malloc(codesize + 0x204);
|
|
if (code == NULL)
|
|
{
|
|
fprintf(stderr, "\n[error]: Out of memory\n");
|
|
fclose(f);
|
|
return -32;
|
|
}
|
|
|
|
memset(code, 0, codesize + 0x204);
|
|
/* read usercode into buffer */
|
|
if (fread(&code[4], 1, codesize, f) != codesize)
|
|
{
|
|
fprintf(stderr, "\n[error]: I/O error\n");
|
|
fclose(f);
|
|
free(code);
|
|
return -33;
|
|
}
|
|
fprintf(stderr, "done\n");
|
|
|
|
fclose(f);
|
|
|
|
/* put code size at the first 4 bytes */
|
|
codesize += 4;
|
|
code[0] = codesize & 0xff;
|
|
code[1] = (codesize >> 8) & 0xff;
|
|
code[2] = (codesize >> 16) & 0xff;
|
|
code[3] = (codesize >> 24) & 0xff;
|
|
|
|
fprintf(stderr, "[stage3]: Uploading user code (%d bytes)... ", codesize);
|
|
|
|
remain = codesize;
|
|
|
|
while (remain > 0)
|
|
{
|
|
if (remain < 0x200)
|
|
send_size = remain;
|
|
|
|
ret = libusb_bulk_transfer(hdev, /* handle */
|
|
1, /* EP */
|
|
&code[i * 0x200], /* data */
|
|
send_size, /* length */
|
|
&transfered, /* xfered */
|
|
USB_TIMEOUT /* timeout */
|
|
);
|
|
|
|
if (ret != LIBUSB_SUCCESS)
|
|
{
|
|
fprintf(stderr, "\n[error]: Bulk transfer error (%d, %d)\n", ret, i);
|
|
free(code);
|
|
return -34;
|
|
}
|
|
|
|
remain -= send_size;
|
|
i++;
|
|
}
|
|
|
|
fprintf(stderr,"done (sent %d blocks)\n", i);
|
|
return 0;
|
|
}
|
|
|