forked from len0rd/rockbox
Make the Gigabeat-S bootloader dual-boot. The hold switch is used to choose what to boot - because it is a simple GPIO test.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15828 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
a8b388fb86
commit
4fb825eed9
2 changed files with 53 additions and 7 deletions
|
|
@ -292,7 +292,7 @@ SECTIONS
|
||||||
}
|
}
|
||||||
#elif (CONFIG_CPU==IMX31L)
|
#elif (CONFIG_CPU==IMX31L)
|
||||||
{
|
{
|
||||||
. = 0x88201000;
|
. = 0x8a000000;
|
||||||
.vectors :
|
.vectors :
|
||||||
{
|
{
|
||||||
KEEP(*(.vectors*));
|
KEEP(*(.vectors*));
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,12 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
/* New entry point for nk.bin - where our dualboot code is inserted */
|
||||||
|
#define NK_ENTRY_POINT 0x88200000
|
||||||
|
|
||||||
|
/* Entry point (and load address) for the main Rockbox bootloader */
|
||||||
|
#define BL_ENTRY_POINT 0x8a000000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Description of nk.bin from
|
Description of nk.bin from
|
||||||
|
|
@ -65,11 +71,30 @@ mknkboot.c appends two images:
|
||||||
#define O_BINARY 0
|
#define O_BINARY 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define DISABLE_ADDR 0x88065A10 /* in EBoot */
|
#define DISABLE_ADDR 0x88065A10 /* in EBoot */
|
||||||
#define DISABLE_INSN 0xe3a00001
|
#define DISABLE_INSN 0xe3a00001
|
||||||
#define DISABLE_SUM (0xe3+0xa0+0x00+0x01)
|
#define DISABLE_SUM (0xe3+0xa0+0x00+0x01)
|
||||||
|
|
||||||
|
/* Code to dual-boot - this is inserted at NK_ENTRY_POINT */
|
||||||
|
static uint32_t dualboot[] =
|
||||||
|
{
|
||||||
|
0xe59f900c, /* ldr r9, [pc, #12] -> 0x53fa4000 */
|
||||||
|
0xe5999000, /* ldr r9, [r9] */
|
||||||
|
0xe3190010, /* tst r9, #16 ; 0x10 */
|
||||||
|
#if 1
|
||||||
|
/* Branch to Rockbox if hold is on */
|
||||||
|
0x159ff004, /* ldrne pc, [pc, #4] -> 0x89000000 */
|
||||||
|
#else
|
||||||
|
/* Branch to Rockbox if hold is off */
|
||||||
|
0x059ff004, /* ldreq pc, [pc, #4] -> 0x89000000 */
|
||||||
|
#endif
|
||||||
|
/* Branch to original firmware */
|
||||||
|
0xea0003fa, /* b 0x1000 */
|
||||||
|
|
||||||
|
0x53fa4000, /* GPIO3_DR */
|
||||||
|
BL_ENTRY_POINT /* RB bootloader load address/entry point */
|
||||||
|
};
|
||||||
|
|
||||||
static void put_uint32le(uint32_t x, unsigned char* p)
|
static void put_uint32le(uint32_t x, unsigned char* p)
|
||||||
{
|
{
|
||||||
p[0] = x & 0xff;
|
p[0] = x & 0xff;
|
||||||
|
|
@ -105,6 +130,7 @@ int main(int argc, char *argv[])
|
||||||
int inlength,bootlength,newlength;
|
int inlength,bootlength,newlength;
|
||||||
unsigned char* buf;
|
unsigned char* buf;
|
||||||
unsigned char* boot;
|
unsigned char* boot;
|
||||||
|
unsigned char* boot2;
|
||||||
unsigned char* disable;
|
unsigned char* disable;
|
||||||
uint32_t sum;
|
uint32_t sum;
|
||||||
|
|
||||||
|
|
@ -133,9 +159,9 @@ int main(int argc, char *argv[])
|
||||||
bootlength = filesize(fdboot);
|
bootlength = filesize(fdboot);
|
||||||
|
|
||||||
/* Create buffer for original nk.bin, plus our bootloader (with 12
|
/* Create buffer for original nk.bin, plus our bootloader (with 12
|
||||||
byte header), plus the 16-byte "disable record" */
|
byte header), plus the 16-byte "disable record", plus our dual-boot code */
|
||||||
|
|
||||||
newlength = inlength + (bootlength + 12) + 16;
|
newlength = inlength + (bootlength + 12) + 16 + (12 + 28);
|
||||||
buf = malloc(newlength);
|
buf = malloc(newlength);
|
||||||
|
|
||||||
if (buf==NULL)
|
if (buf==NULL)
|
||||||
|
|
@ -156,6 +182,8 @@ int main(int argc, char *argv[])
|
||||||
/****** STEP 2 - Move EOF record to the new EOF */
|
/****** STEP 2 - Move EOF record to the new EOF */
|
||||||
memcpy(buf + newlength - 12, buf + inlength - 12, 12);
|
memcpy(buf + newlength - 12, buf + inlength - 12, 12);
|
||||||
|
|
||||||
|
/* Overwrite default entry point with NK_ENTRY_POINT */
|
||||||
|
put_uint32le(NK_ENTRY_POINT, buf + newlength - 8);
|
||||||
|
|
||||||
/****** STEP 3 - Create a record to disable the firmware signature
|
/****** STEP 3 - Create a record to disable the firmware signature
|
||||||
check in EBoot */
|
check in EBoot */
|
||||||
|
|
@ -177,17 +205,35 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
/****** STEP 5 - Create header for bootloader record */
|
/****** STEP 5 - Create header for bootloader record */
|
||||||
|
|
||||||
/* Calculate simple checksum */
|
/* Calculate checksum */
|
||||||
sum = 0;
|
sum = 0;
|
||||||
for (i = 0; i < bootlength; i++) {
|
for (i = 0; i < bootlength; i++) {
|
||||||
sum += boot[12 + i];
|
sum += boot[12 + i];
|
||||||
}
|
}
|
||||||
|
|
||||||
put_uint32le(0x88201000, boot); /* nk.exe start address */
|
put_uint32le(BL_ENTRY_POINT, boot); /* Our entry point */
|
||||||
put_uint32le(bootlength, boot + 4);
|
put_uint32le(bootlength, boot + 4);
|
||||||
put_uint32le(sum, boot + 8);
|
put_uint32le(sum, boot + 8);
|
||||||
|
|
||||||
/****** STEP 6 - Now write the output file */
|
/****** STEP 6 - Insert our dual-boot code */
|
||||||
|
boot2 = boot + bootlength + 12;
|
||||||
|
|
||||||
|
/* Copy dual-boot code in an endian-safe way */
|
||||||
|
for (i = 0; i < sizeof(dualboot) / 4; i++) {
|
||||||
|
put_uint32le(dualboot[i], boot2 + 12 + i*4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate checksum */
|
||||||
|
sum = 0;
|
||||||
|
for (i = 0; i < sizeof(dualboot); i++) {
|
||||||
|
sum += boot2[i+12];
|
||||||
|
}
|
||||||
|
|
||||||
|
put_uint32le(NK_ENTRY_POINT, boot2); /* New entry point for our nk.bin */
|
||||||
|
put_uint32le(sizeof(dualboot), boot2 + 4);
|
||||||
|
put_uint32le(sum, boot2 + 8);
|
||||||
|
|
||||||
|
/****** STEP 7 - Now write the output file */
|
||||||
|
|
||||||
fdout = open(outfile, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644);
|
fdout = open(outfile, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644);
|
||||||
if (fdout < 0)
|
if (fdout < 0)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue