diff options
Diffstat (limited to 'tools/mknkboot.c')
-rw-r--r-- | tools/mknkboot.c | 186 |
1 files changed, 102 insertions, 84 deletions
diff --git a/tools/mknkboot.c b/tools/mknkboot.c index 87372500e5..f17d1e9070 100644 --- a/tools/mknkboot.c +++ b/tools/mknkboot.c | |||
@@ -45,6 +45,8 @@ | |||
45 | #include <unistd.h> | 45 | #include <unistd.h> |
46 | #include <inttypes.h> | 46 | #include <inttypes.h> |
47 | 47 | ||
48 | #include "mknkboot.h" | ||
49 | |||
48 | /* New entry point for nk.bin - where our dualboot code is inserted */ | 50 | /* New entry point for nk.bin - where our dualboot code is inserted */ |
49 | #define NK_ENTRY_POINT 0x88200000 | 51 | #define NK_ENTRY_POINT 0x88200000 |
50 | 52 | ||
@@ -113,6 +115,7 @@ static uint32_t dualboot[] = | |||
113 | BL_ENTRY_POINT /* RB bootloader load address/entry point */ | 115 | BL_ENTRY_POINT /* RB bootloader load address/entry point */ |
114 | }; | 116 | }; |
115 | 117 | ||
118 | |||
116 | static void put_uint32le(uint32_t x, unsigned char* p) | 119 | static void put_uint32le(uint32_t x, unsigned char* p) |
117 | { | 120 | { |
118 | p[0] = x & 0xff; | 121 | p[0] = x & 0xff; |
@@ -121,13 +124,6 @@ static void put_uint32le(uint32_t x, unsigned char* p) | |||
121 | p[3] = (x >> 24) & 0xff; | 124 | p[3] = (x >> 24) & 0xff; |
122 | } | 125 | } |
123 | 126 | ||
124 | static void usage(void) | ||
125 | { | ||
126 | printf("Usage: mknkboot <firmware file> <boot file> <output file>\n"); | ||
127 | |||
128 | exit(1); | ||
129 | } | ||
130 | |||
131 | static off_t filesize(int fd) { | 127 | static off_t filesize(int fd) { |
132 | struct stat buf; | 128 | struct stat buf; |
133 | 129 | ||
@@ -140,100 +136,62 @@ static off_t filesize(int fd) { | |||
140 | } | 136 | } |
141 | 137 | ||
142 | 138 | ||
143 | int mknkboot(const char* infile, const char* bootfile, const char* outfile) | 139 | int mknkboot(const struct filebuf *indata, const struct filebuf *bootdata, |
140 | struct filebuf *outdata) | ||
144 | { | 141 | { |
145 | int fdin, fdboot = -1, fdout = -1; | 142 | int i; |
146 | int i,n; | ||
147 | int inlength,bootlength,newlength; | ||
148 | unsigned char* buf = NULL; | ||
149 | unsigned char* boot; | 143 | unsigned char* boot; |
150 | unsigned char* boot2; | 144 | unsigned char* boot2; |
151 | unsigned char* disable; | 145 | unsigned char* disable; |
152 | uint32_t sum; | 146 | uint32_t sum; |
153 | int result = 0; | ||
154 | |||
155 | fdin = open(infile, O_RDONLY|O_BINARY); | ||
156 | if (fdin < 0) | ||
157 | { | ||
158 | perror(infile); | ||
159 | result = 1; | ||
160 | goto quit; | ||
161 | } | ||
162 | |||
163 | fdboot = open(bootfile, O_RDONLY|O_BINARY); | ||
164 | if (fdboot < 0) | ||
165 | { | ||
166 | perror(bootfile); | ||
167 | close(fdin); | ||
168 | result = 2; | ||
169 | goto quit; | ||
170 | } | ||
171 | |||
172 | inlength = filesize(fdin); | ||
173 | bootlength = filesize(fdboot); | ||
174 | 147 | ||
175 | /* Create buffer for original nk.bin, plus our bootloader (with 12 | 148 | /* Create buffer for original nk.bin, plus our bootloader (with 12 |
176 | byte header), plus the 16-byte "disable record", plus our dual-boot code */ | 149 | byte header), plus the 16-byte "disable record", plus our dual-boot code */ |
150 | outdata->len = indata->len + (bootdata->len + 12) + 16 + (12 + 28); | ||
151 | outdata->buf = malloc(outdata->len); | ||
177 | 152 | ||
178 | newlength = inlength + (bootlength + 12) + 16 + (12 + 28); | 153 | if (outdata->buf==NULL) |
179 | buf = malloc(newlength); | ||
180 | |||
181 | if (buf==NULL) | ||
182 | { | 154 | { |
183 | printf("[ERR] Could not allocate memory, aborting\n"); | 155 | printf("[ERR] Could not allocate memory, aborting\n"); |
184 | result = 3; | 156 | return -1; |
185 | goto quit; | ||
186 | } | 157 | } |
187 | 158 | ||
188 | /****** STEP 1 - Read original nk.bin into buffer */ | 159 | /****** STEP 1 - Read original nk.bin into buffer */ |
189 | 160 | memcpy(outdata->buf, indata->buf, indata->len); | |
190 | n = read(fdin, buf, inlength); | ||
191 | if (n != inlength) | ||
192 | { | ||
193 | printf("[ERR] Could not read from %s\n",infile); | ||
194 | result = 4; | ||
195 | goto quit; | ||
196 | } | ||
197 | 161 | ||
198 | /****** STEP 2 - Move EOF record to the new EOF */ | 162 | /****** STEP 2 - Move EOF record to the new EOF */ |
199 | memcpy(buf + newlength - 12, buf + inlength - 12, 12); | 163 | memcpy(outdata->buf + outdata->len - 12, outdata->buf + indata->len - 12, 12); |
200 | 164 | ||
201 | /* Overwrite default entry point with NK_ENTRY_POINT */ | 165 | /* Overwrite default entry point with NK_ENTRY_POINT */ |
202 | put_uint32le(NK_ENTRY_POINT, buf + newlength - 8); | 166 | put_uint32le(NK_ENTRY_POINT, outdata->buf + outdata->len - 8); |
203 | 167 | ||
204 | /****** STEP 3 - Create a record to disable the firmware signature | 168 | /****** STEP 3 - Create a record to disable the firmware signature |
205 | check in EBoot */ | 169 | check in EBoot */ |
206 | disable = buf + inlength - 12; | 170 | disable = outdata->buf + indata->len - 12; |
207 | 171 | ||
208 | put_uint32le(DISABLE_ADDR, disable); | 172 | put_uint32le(DISABLE_ADDR, disable); |
209 | put_uint32le(4, disable + 4); | 173 | put_uint32le(4, disable + 4); |
210 | put_uint32le(DISABLE_SUM, disable + 8); | 174 | put_uint32le(DISABLE_SUM, disable + 8); |
211 | put_uint32le(DISABLE_INSN, disable + 12); | 175 | put_uint32le(DISABLE_INSN, disable + 12); |
212 | 176 | ||
213 | /****** STEP 4 - Read the bootloader binary */ | 177 | /****** STEP 4 - Append the bootloader binary */ |
214 | boot = disable + 16; | 178 | boot = disable + 16; |
215 | n = read(fdboot, boot + 12, bootlength); | 179 | memcpy(boot + 12, bootdata->buf, bootdata->len); |
216 | if (n != bootlength) | ||
217 | { | ||
218 | printf("[ERR] Could not read from %s\n",bootfile); | ||
219 | result = 5; | ||
220 | goto quit; | ||
221 | } | ||
222 | 180 | ||
223 | /****** STEP 5 - Create header for bootloader record */ | 181 | /****** STEP 5 - Create header for bootloader record */ |
224 | 182 | ||
225 | /* Calculate checksum */ | 183 | /* Calculate checksum */ |
226 | sum = 0; | 184 | sum = 0; |
227 | for (i = 0; i < bootlength; i++) { | 185 | for (i = 0; i < bootdata->len; i++) { |
228 | sum += boot[12 + i]; | 186 | sum += boot[12 + i]; |
229 | } | 187 | } |
230 | 188 | ||
231 | put_uint32le(BL_ENTRY_POINT, boot); /* Our entry point */ | 189 | put_uint32le(BL_ENTRY_POINT, boot); /* Our entry point */ |
232 | put_uint32le(bootlength, boot + 4); | 190 | put_uint32le(bootdata->len, boot + 4); |
233 | put_uint32le(sum, boot + 8); | 191 | put_uint32le(sum, boot + 8); |
234 | 192 | ||
235 | /****** STEP 6 - Insert our dual-boot code */ | 193 | /****** STEP 6 - Insert our dual-boot code */ |
236 | boot2 = boot + bootlength + 12; | 194 | boot2 = boot + bootdata->len + 12; |
237 | 195 | ||
238 | /* Copy dual-boot code in an endian-safe way */ | 196 | /* Copy dual-boot code in an endian-safe way */ |
239 | for (i = 0; i < (signed int)sizeof(dualboot) / 4; i++) { | 197 | for (i = 0; i < (signed int)sizeof(dualboot) / 4; i++) { |
@@ -250,47 +208,107 @@ int mknkboot(const char* infile, const char* bootfile, const char* outfile) | |||
250 | put_uint32le(sizeof(dualboot), boot2 + 4); | 208 | put_uint32le(sizeof(dualboot), boot2 + 4); |
251 | put_uint32le(sum, boot2 + 8); | 209 | put_uint32le(sum, boot2 + 8); |
252 | 210 | ||
253 | /****** STEP 7 - Now write the output file */ | 211 | return 0; |
212 | } | ||
213 | |||
214 | #if !defined(BEASTPATCHER) | ||
215 | static void usage(void) | ||
216 | { | ||
217 | printf("Usage: mknkboot <firmware file> <boot file> <output file>\n"); | ||
218 | |||
219 | exit(1); | ||
220 | } | ||
221 | |||
222 | |||
223 | int main(int argc, char* argv[]) | ||
224 | { | ||
225 | char *infile, *bootfile, *outfile; | ||
226 | int fdin = -1, fdboot = -1, fdout = -1; | ||
227 | int n; | ||
228 | struct filebuf indata = {0, NULL}, bootdata = {0, NULL}, outdata = {0, NULL}; | ||
229 | int result = 0; | ||
230 | |||
231 | if(argc < 4) { | ||
232 | usage(); | ||
233 | } | ||
234 | |||
235 | infile = argv[1]; | ||
236 | bootfile = argv[2]; | ||
237 | outfile = argv[3]; | ||
238 | |||
239 | fdin = open(infile, O_RDONLY|O_BINARY); | ||
240 | if (fdin < 0) | ||
241 | { | ||
242 | perror(infile); | ||
243 | result = 2; | ||
244 | goto quit; | ||
245 | } | ||
246 | |||
247 | fdboot = open(bootfile, O_RDONLY|O_BINARY); | ||
248 | if (fdboot < 0) | ||
249 | { | ||
250 | perror(bootfile); | ||
251 | close(fdin); | ||
252 | result = 3; | ||
253 | goto quit; | ||
254 | } | ||
255 | |||
256 | indata.len = filesize(fdin); | ||
257 | bootdata.len = filesize(fdboot); | ||
258 | indata.buf = (unsigned char*)malloc(indata.len); | ||
259 | bootdata.buf = (unsigned char*)malloc(bootdata.len); | ||
260 | if(indata.buf == NULL || bootdata.buf == NULL) | ||
261 | { | ||
262 | printf("[ERR] Could not allocate memory, aborting\n"); | ||
263 | result = 4; | ||
264 | goto quit; | ||
265 | } | ||
266 | n = read(fdin, indata.buf, indata.len); | ||
267 | if (n != indata.len) | ||
268 | { | ||
269 | printf("[ERR] Could not read from %s\n",infile); | ||
270 | result = 5; | ||
271 | goto quit; | ||
272 | } | ||
273 | n = read(fdboot, bootdata.buf, bootdata.len); | ||
274 | if (n != bootdata.len) | ||
275 | { | ||
276 | printf("[ERR] Could not read from %s\n",bootfile); | ||
277 | result = 6; | ||
278 | goto quit; | ||
279 | } | ||
254 | 280 | ||
281 | result = mknkboot(&indata, &bootdata, &outdata); | ||
282 | if(result != 0) | ||
283 | { | ||
284 | goto quit; | ||
285 | } | ||
255 | fdout = open(outfile, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644); | 286 | fdout = open(outfile, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644); |
256 | if (fdout < 0) | 287 | if (fdout < 0) |
257 | { | 288 | { |
258 | perror(outfile); | 289 | perror(outfile); |
259 | result = 6; | 290 | result = 7; |
260 | goto quit; | 291 | goto quit; |
261 | } | 292 | } |
262 | 293 | ||
263 | n = write(fdout, buf, newlength); | 294 | n = write(fdout, outdata.buf, outdata.len); |
264 | if (n != newlength) | 295 | if (n != outdata.len) |
265 | { | 296 | { |
266 | printf("[ERR] Could not write output file %s\n",outfile); | 297 | printf("[ERR] Could not write output file %s\n",outfile); |
267 | result = 7; | 298 | result = 8; |
268 | goto quit; | 299 | goto quit; |
269 | } | 300 | } |
270 | 301 | ||
271 | quit: | 302 | quit: |
272 | if(buf != NULL) | 303 | free(bootdata.buf); |
273 | free(buf); | 304 | free(indata.buf); |
305 | free(outdata.buf); | ||
274 | close(fdin); | 306 | close(fdin); |
275 | close(fdboot); | 307 | close(fdboot); |
276 | close(fdout); | 308 | close(fdout); |
277 | |||
278 | return result; | ||
279 | } | ||
280 | 309 | ||
281 | 310 | return result; | |
282 | int main(int argc, char* argv[]) | ||
283 | { | ||
284 | char *infile, *bootfile, *outfile; | ||
285 | if(argc < 4) { | ||
286 | usage(); | ||
287 | } | ||
288 | |||
289 | infile = argv[1]; | ||
290 | bootfile = argv[2]; | ||
291 | outfile = argv[3]; | ||
292 | |||
293 | return mknkboot(infile, bootfile, outfile); | ||
294 | 311 | ||
295 | } | 312 | } |
313 | #endif | ||
296 | 314 | ||