summaryrefslogtreecommitdiff
path: root/tools/mknkboot.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/mknkboot.c')
-rw-r--r--tools/mknkboot.c58
1 files changed, 52 insertions, 6 deletions
diff --git a/tools/mknkboot.c b/tools/mknkboot.c
index c5e89f6834..dfb3c99767 100644
--- a/tools/mknkboot.c
+++ b/tools/mknkboot.c
@@ -27,6 +27,12 @@
27#include <unistd.h> 27#include <unistd.h>
28#include <inttypes.h> 28#include <inttypes.h>
29 29
30/* New entry point for nk.bin - where our dualboot code is inserted */
31#define NK_ENTRY_POINT 0x88200000
32
33/* Entry point (and load address) for the main Rockbox bootloader */
34#define BL_ENTRY_POINT 0x8a000000
35
30/* 36/*
31 37
32Description of nk.bin from 38Description of nk.bin from
@@ -65,11 +71,30 @@ mknkboot.c appends two images:
65#define O_BINARY 0 71#define O_BINARY 0
66#endif 72#endif
67 73
68
69#define DISABLE_ADDR 0x88065A10 /* in EBoot */ 74#define DISABLE_ADDR 0x88065A10 /* in EBoot */
70#define DISABLE_INSN 0xe3a00001 75#define DISABLE_INSN 0xe3a00001
71#define DISABLE_SUM (0xe3+0xa0+0x00+0x01) 76#define DISABLE_SUM (0xe3+0xa0+0x00+0x01)
72 77
78/* Code to dual-boot - this is inserted at NK_ENTRY_POINT */
79static uint32_t dualboot[] =
80{
81 0xe59f900c, /* ldr r9, [pc, #12] -> 0x53fa4000 */
82 0xe5999000, /* ldr r9, [r9] */
83 0xe3190010, /* tst r9, #16 ; 0x10 */
84#if 1
85 /* Branch to Rockbox if hold is on */
86 0x159ff004, /* ldrne pc, [pc, #4] -> 0x89000000 */
87#else
88 /* Branch to Rockbox if hold is off */
89 0x059ff004, /* ldreq pc, [pc, #4] -> 0x89000000 */
90#endif
91 /* Branch to original firmware */
92 0xea0003fa, /* b 0x1000 */
93
94 0x53fa4000, /* GPIO3_DR */
95 BL_ENTRY_POINT /* RB bootloader load address/entry point */
96};
97
73static void put_uint32le(uint32_t x, unsigned char* p) 98static void put_uint32le(uint32_t x, unsigned char* p)
74{ 99{
75 p[0] = x & 0xff; 100 p[0] = x & 0xff;
@@ -105,6 +130,7 @@ int main(int argc, char *argv[])
105 int inlength,bootlength,newlength; 130 int inlength,bootlength,newlength;
106 unsigned char* buf; 131 unsigned char* buf;
107 unsigned char* boot; 132 unsigned char* boot;
133 unsigned char* boot2;
108 unsigned char* disable; 134 unsigned char* disable;
109 uint32_t sum; 135 uint32_t sum;
110 136
@@ -133,9 +159,9 @@ int main(int argc, char *argv[])
133 bootlength = filesize(fdboot); 159 bootlength = filesize(fdboot);
134 160
135 /* Create buffer for original nk.bin, plus our bootloader (with 12 161 /* Create buffer for original nk.bin, plus our bootloader (with 12
136 byte header), plus the 16-byte "disable record" */ 162 byte header), plus the 16-byte "disable record", plus our dual-boot code */
137 163
138 newlength = inlength + (bootlength + 12) + 16; 164 newlength = inlength + (bootlength + 12) + 16 + (12 + 28);
139 buf = malloc(newlength); 165 buf = malloc(newlength);
140 166
141 if (buf==NULL) 167 if (buf==NULL)
@@ -156,6 +182,8 @@ int main(int argc, char *argv[])
156 /****** STEP 2 - Move EOF record to the new EOF */ 182 /****** STEP 2 - Move EOF record to the new EOF */
157 memcpy(buf + newlength - 12, buf + inlength - 12, 12); 183 memcpy(buf + newlength - 12, buf + inlength - 12, 12);
158 184
185 /* Overwrite default entry point with NK_ENTRY_POINT */
186 put_uint32le(NK_ENTRY_POINT, buf + newlength - 8);
159 187
160 /****** STEP 3 - Create a record to disable the firmware signature 188 /****** STEP 3 - Create a record to disable the firmware signature
161 check in EBoot */ 189 check in EBoot */
@@ -177,17 +205,35 @@ int main(int argc, char *argv[])
177 205
178 /****** STEP 5 - Create header for bootloader record */ 206 /****** STEP 5 - Create header for bootloader record */
179 207
180 /* Calculate simple checksum */ 208 /* Calculate checksum */
181 sum = 0; 209 sum = 0;
182 for (i = 0; i < bootlength; i++) { 210 for (i = 0; i < bootlength; i++) {
183 sum += boot[12 + i]; 211 sum += boot[12 + i];
184 } 212 }
185 213
186 put_uint32le(0x88201000, boot); /* nk.exe start address */ 214 put_uint32le(BL_ENTRY_POINT, boot); /* Our entry point */
187 put_uint32le(bootlength, boot + 4); 215 put_uint32le(bootlength, boot + 4);
188 put_uint32le(sum, boot + 8); 216 put_uint32le(sum, boot + 8);
189 217
190 /****** STEP 6 - Now write the output file */ 218 /****** STEP 6 - Insert our dual-boot code */
219 boot2 = boot + bootlength + 12;
220
221 /* Copy dual-boot code in an endian-safe way */
222 for (i = 0; i < sizeof(dualboot) / 4; i++) {
223 put_uint32le(dualboot[i], boot2 + 12 + i*4);
224 }
225
226 /* Calculate checksum */
227 sum = 0;
228 for (i = 0; i < sizeof(dualboot); i++) {
229 sum += boot2[i+12];
230 }
231
232 put_uint32le(NK_ENTRY_POINT, boot2); /* New entry point for our nk.bin */
233 put_uint32le(sizeof(dualboot), boot2 + 4);
234 put_uint32le(sum, boot2 + 8);
235
236 /****** STEP 7 - Now write the output file */
191 237
192 fdout = open(outfile, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644); 238 fdout = open(outfile, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644);
193 if (fdout < 0) 239 if (fdout < 0)