diff options
author | Linus Nielsen Feltzing <linus@haxx.se> | 2005-01-28 12:28:35 +0000 |
---|---|---|
committer | Linus Nielsen Feltzing <linus@haxx.se> | 2005-01-28 12:28:35 +0000 |
commit | abf3ea672aeaa928a3bc0ad87f35e9f2f4318895 (patch) | |
tree | 79d5db82c06e955ebce7833ff62aabcbe1e806aa | |
parent | 35c27b82c3cbe7060c371eb055119f1e8d65546a (diff) | |
download | rockbox-abf3ea672aeaa928a3bc0ad87f35e9f2f4318895.tar.gz rockbox-abf3ea672aeaa928a3bc0ad87f35e9f2f4318895.zip |
New tool to insert the rockbox boot loader into the original firmware (iRiver)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5690 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | tools/Makefile | 8 | ||||
-rw-r--r-- | tools/mkboot.c | 162 |
2 files changed, 168 insertions, 2 deletions
diff --git a/tools/Makefile b/tools/Makefile index 8e82d0f8ee..b98c269642 100644 --- a/tools/Makefile +++ b/tools/Makefile | |||
@@ -6,9 +6,10 @@ | |||
6 | # \/ \/ \/ \/ \/ | 6 | # \/ \/ \/ \/ \/ |
7 | # $Id$ | 7 | # $Id$ |
8 | # | 8 | # |
9 | CFLAGS := -O -ansi | 9 | CFLAGS := -O -ansi -g |
10 | LDFLAGS := -g | ||
10 | 11 | ||
11 | TARGETS := scramble descramble sh2d bmp2rb convbdf generate_rocklatin | 12 | TARGETS := scramble descramble sh2d bmp2rb convbdf generate_rocklatin mkboot |
12 | 13 | ||
13 | all: $(TARGETS) | 14 | all: $(TARGETS) |
14 | @echo "tools done" | 15 | @echo "tools done" |
@@ -25,6 +26,9 @@ sh2d: sh2d.c | |||
25 | bmp2rb: bmp2rb.c | 26 | bmp2rb: bmp2rb.c |
26 | $(CC) -DAPPLICATION_NAME=\"$@\" -g $+ -o $@ | 27 | $(CC) -DAPPLICATION_NAME=\"$@\" -g $+ -o $@ |
27 | 28 | ||
29 | mkboot: mkboot.c | ||
30 | $(CC) -g $+ -o $@ | ||
31 | |||
28 | convbdf: convbdf.c | 32 | convbdf: convbdf.c |
29 | $(CC) -g $+ -o $@ | 33 | $(CC) -g $+ -o $@ |
30 | 34 | ||
diff --git a/tools/mkboot.c b/tools/mkboot.c new file mode 100644 index 0000000000..e2d971d740 --- /dev/null +++ b/tools/mkboot.c | |||
@@ -0,0 +1,162 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2005 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include <stdio.h> | ||
20 | #include <stdlib.h> | ||
21 | |||
22 | void usage(void) | ||
23 | { | ||
24 | printf("usage: mkboot <firmware file> <boot file> <output file>\n"); | ||
25 | |||
26 | exit(1); | ||
27 | } | ||
28 | |||
29 | char image[0x200000 + 0x220 + 0x200000/0x200]; | ||
30 | |||
31 | int main(int argc, char *argv[]) | ||
32 | { | ||
33 | char *infile, *bootfile, *outfile; | ||
34 | FILE *f; | ||
35 | long pos; | ||
36 | int i; | ||
37 | int file_length; | ||
38 | int len; | ||
39 | int actual_length, total_length, binary_length, num_chksums; | ||
40 | |||
41 | if(argc < 3) { | ||
42 | usage(); | ||
43 | } | ||
44 | |||
45 | infile = argv[1]; | ||
46 | bootfile = argv[2]; | ||
47 | outfile = argv[3]; | ||
48 | |||
49 | memset(image, 0xff, sizeof(image)); | ||
50 | |||
51 | /* First, read the iriver original firmware into the image */ | ||
52 | f = fopen(infile, "rb"); | ||
53 | if(!f) { | ||
54 | perror(infile); | ||
55 | exit(1); | ||
56 | } | ||
57 | |||
58 | i = fread(image, 1, 16, f); | ||
59 | if(i < 16) { | ||
60 | perror(infile); | ||
61 | exit(1); | ||
62 | } | ||
63 | |||
64 | /* This is the length of the binary image without the scrambling | ||
65 | overhead (but including the ESTFBINR header) */ | ||
66 | binary_length = image[4] + (image[5] << 8) + | ||
67 | (image[6] << 16) + (image[7] << 24); | ||
68 | |||
69 | /* Read the rest of the binary data, but not the checksum block */ | ||
70 | len = binary_length+0x200-16; | ||
71 | i = fread(image+16, 1, len, f); | ||
72 | if(i < len) { | ||
73 | perror(infile); | ||
74 | exit(1); | ||
75 | } | ||
76 | |||
77 | fclose(f); | ||
78 | |||
79 | /* Now, read the boot loader into the image */ | ||
80 | f = fopen(bootfile, "rb"); | ||
81 | if(!f) { | ||
82 | perror(bootfile); | ||
83 | exit(1); | ||
84 | } | ||
85 | |||
86 | fseek(f, 0, SEEK_END); | ||
87 | len = ftell(f); | ||
88 | |||
89 | fseek(f, 0, SEEK_SET); | ||
90 | |||
91 | i = fread(image+0x220 + 0x1f0000, 1, len, f); | ||
92 | if(i < len) { | ||
93 | perror(bootfile); | ||
94 | exit(1); | ||
95 | } | ||
96 | |||
97 | fclose(f); | ||
98 | |||
99 | f = fopen(outfile, "wb"); | ||
100 | if(!f) { | ||
101 | perror(outfile); | ||
102 | exit(1); | ||
103 | } | ||
104 | |||
105 | /* Patch the reset vector to start the boot loader */ | ||
106 | image[0x220 + 4] = image[0x1f0000 + 0x220 + 4]; | ||
107 | image[0x220 + 5] = image[0x1f0000 + 0x220 + 5]; | ||
108 | image[0x220 + 6] = image[0x1f0000 + 0x220 + 6]; | ||
109 | image[0x220 + 7] = image[0x1f0000 + 0x220 + 7]; | ||
110 | |||
111 | /* This is the actual length of the binary, excluding all headers */ | ||
112 | actual_length = 0x1f0000 + len; | ||
113 | |||
114 | /* Patch the ESTFBINR header */ | ||
115 | image[0x20c] = (actual_length >> 24) & 0xff; | ||
116 | image[0x20d] = (actual_length >> 16) & 0xff; | ||
117 | image[0x20e] = (actual_length >> 8) & 0xff; | ||
118 | image[0x20f] = actual_length & 0xff; | ||
119 | |||
120 | image[0x21c] = (actual_length >> 24) & 0xff; | ||
121 | image[0x21d] = (actual_length >> 16) & 0xff; | ||
122 | image[0x21e] = (actual_length >> 8) & 0xff; | ||
123 | image[0x21f] = actual_length & 0xff; | ||
124 | |||
125 | /* This is the length of the binary, including the ESTFBINR header and | ||
126 | rounded up to the nearest 0x200 boundary */ | ||
127 | binary_length = (actual_length + 0x20 + 0x1ff) & 0xfffffe00; | ||
128 | |||
129 | /* The number of checksums, i.e number of 0x200 byte blocks */ | ||
130 | num_chksums = binary_length / 0x200; | ||
131 | |||
132 | /* The total file length, including all headers and checksums */ | ||
133 | total_length = binary_length + num_chksums + 0x200; | ||
134 | |||
135 | /* Patch the scrambler header with the new length info */ | ||
136 | image[0] = total_length & 0xff; | ||
137 | image[1] = (total_length >> 8) & 0xff; | ||
138 | image[2] = (total_length >> 16) & 0xff; | ||
139 | image[3] = (total_length >> 24) & 0xff; | ||
140 | |||
141 | image[4] = binary_length & 0xff; | ||
142 | image[5] = (binary_length >> 8) & 0xff; | ||
143 | image[6] = (binary_length >> 16) & 0xff; | ||
144 | image[7] = (binary_length >> 24) & 0xff; | ||
145 | |||
146 | image[8] = num_chksums & 0xff; | ||
147 | image[9] = (num_chksums >> 8) & 0xff; | ||
148 | image[10] = (num_chksums >> 16) & 0xff; | ||
149 | image[11] = (num_chksums >> 24) & 0xff; | ||
150 | |||
151 | i = fwrite(image, 1, total_length, f); | ||
152 | if(i < total_length) { | ||
153 | perror(outfile); | ||
154 | exit(1); | ||
155 | } | ||
156 | |||
157 | printf("Wrote 0x%x bytes in %s\n", total_length, outfile); | ||
158 | |||
159 | fclose(f); | ||
160 | |||
161 | return 0; | ||
162 | } | ||