summaryrefslogtreecommitdiff
path: root/rbutil/mktccboot/mktccboot.c
diff options
context:
space:
mode:
Diffstat (limited to 'rbutil/mktccboot/mktccboot.c')
-rw-r--r--rbutil/mktccboot/mktccboot.c174
1 files changed, 115 insertions, 59 deletions
diff --git a/rbutil/mktccboot/mktccboot.c b/rbutil/mktccboot/mktccboot.c
index e135b7e506..2c6b08890e 100644
--- a/rbutil/mktccboot/mktccboot.c
+++ b/rbutil/mktccboot/mktccboot.c
@@ -81,7 +81,7 @@ void usage(void)
81 exit(1); 81 exit(1);
82} 82}
83 83
84off_t filesize(int fd) { 84static off_t filesize(int fd) {
85 struct stat buf; 85 struct stat buf;
86 86
87 if (fstat(fd,&buf) < 0) { 87 if (fstat(fd,&buf) < 0) {
@@ -92,16 +92,97 @@ off_t filesize(int fd) {
92 } 92 }
93} 93}
94 94
95#define DRAMORIG 0x20000000
96/* Injects a bootloader into a Telechips 77X/78X firmware file */
97unsigned char *patch_firmware_tcc(unsigned char *of_buf, int of_size,
98 unsigned char *boot_buf, int boot_size, int *patched_size)
99{
100 unsigned char *patched_buf;
101 uint32_t ldr, old_ep_offset, new_ep_offset;
102 int of_offset;
103
104 patched_buf = malloc(of_size + boot_size);
105 if (!patched_buf)
106 return NULL;
107
108 memcpy(patched_buf, of_buf, of_size);
109 memcpy(patched_buf + of_size, boot_buf, boot_size);
110
111 ldr = get_uint32le(patched_buf);
112
113 /* TODO: Verify it's a LDR instruction */
114 of_offset = (ldr & 0xfff) + 8;
115 old_ep_offset = get_uint32le(patched_buf + of_offset);
116 new_ep_offset = DRAMORIG + of_size;
117
118 printf("OF entry point: 0x%08x\n", old_ep_offset);
119 printf("New entry point: 0x%08x\n", new_ep_offset + 8);
120
121 /* Save the OF entry point at the start of the bootloader image */
122 put_uint32le(old_ep_offset, patched_buf + of_size);
123 put_uint32le(new_ep_offset, patched_buf + of_size + 4);
124
125 /* Change the OF entry point to the third word in our bootloader */
126 put_uint32le(new_ep_offset + 8, patched_buf + of_offset);
127
128 telechips_encode_crc(patched_buf, of_size + boot_size);
129 *patched_size = of_size + boot_size;
130
131 return patched_buf;
132}
133
134unsigned char *file_read(char *filename, int *size)
135{
136 unsigned char *buf = NULL;
137 int n, fd = -1;
138
139 /* Open file for reading */
140 fd = open(filename, O_RDONLY|O_BINARY);
141 if (fd < 0)
142 {
143 printf("[ERR] Could open file for reading, aborting\n");
144 perror(filename);
145 goto error;
146 }
147
148 /* Get file size, and allocate a buffer of that size */
149 *size = filesize(fd);
150 buf = malloc(*size);
151 if (buf == NULL)
152 {
153 printf("[ERR] Could not allocate memory, aborting\n");
154 goto error;
155 }
156
157 /* Read the file's content to the buffer */
158 n = read(fd, buf, *size);
159 if (n != *size)
160 {
161 printf("[ERR] Could not read from %s\n", filename);
162 goto error;
163 }
164
165 return buf;
95 166
167error:
168 if (fd >= 0)
169 close(fd);
170
171 if (buf)
172 free(buf);
173
174 return NULL;
175}
176
177#ifndef LIB
96int main(int argc, char *argv[]) 178int main(int argc, char *argv[])
97{ 179{
98 char *infile, *bootfile, *outfile; 180 char *infile, *bootfile, *outfile;
99 int fdin = -1, fdboot = -1, fdout = -1; 181 int fdout = -1;
100 int n; 182 int n, of_size, boot_size, patched_size;
101 int inlength,bootlength; 183 unsigned char *of_buf;
102 uint32_t ldr; 184 unsigned char *boot_buf = NULL;
103 unsigned char* image; 185 unsigned char* image = NULL;
104 int origoffset;
105 int ret = 0; 186 int ret = 0;
106 187
107 if(argc < 3) { 188 if(argc < 3) {
@@ -112,79 +193,50 @@ int main(int argc, char *argv[])
112 bootfile = argv[2]; 193 bootfile = argv[2];
113 outfile = argv[3]; 194 outfile = argv[3];
114 195
115 fdin = open(infile, O_RDONLY|O_BINARY); 196 /* Read OF and boot files */
116 if (fdin < 0) 197 of_buf = file_read(infile, &of_size);
198 if (!of_buf)
117 { 199 {
118 perror(infile);
119 ret = 1; 200 ret = 1;
120 goto error_exit; 201 goto error_exit;
121 } 202 }
122 203
123 fdboot = open(bootfile, O_RDONLY|O_BINARY); 204 boot_buf = file_read(bootfile, &boot_size);
124 if (fdboot < 0) 205 if (!boot_buf)
125 {
126 perror(bootfile);
127 ret = 2;
128 goto error_exit;
129 }
130
131 inlength = filesize(fdin);
132 bootlength = filesize(fdboot);
133
134 image = malloc(inlength + bootlength);
135
136 if (image==NULL)
137 { 206 {
138 printf("[ERR] Could not allocate memory, aborting\n");
139 ret = 3; 207 ret = 3;
140 goto error_exit; 208 goto error_exit;
141 } 209 }
142 210
143 n = read(fdin, image, inlength); 211 /* Allocate buffer for patched firmware */
144 if (n != inlength) 212 image = malloc(of_size + boot_size);
213 if (image == NULL)
145 { 214 {
146 printf("[ERR] Could not read from %s\n",infile); 215 printf("[ERR] Could not allocate memory, aborting\n");
147 ret = 4; 216 ret = 4;
148 goto error_exit; 217 goto error_exit;
149 } 218 }
150 219
151 n = read(fdboot, image + inlength, bootlength); 220 /* Create the patched firmware */
152 if (n != bootlength) 221 image = patch_firmware_tcc(of_buf, of_size, boot_buf, boot_size,
222 &patched_size);
223 if (!image)
153 { 224 {
154 printf("[ERR] Could not read from %s\n",bootfile); 225 printf("[ERR] Error creating patched firmware, aborting\n");
155 ret = 5; 226 ret = 5;
156 goto error_exit; 227 goto error_exit;
157 } 228 }
158 229
159 ldr = get_uint32le(image);
160
161 /* TODO: Verify it's a LDR instruction */
162 origoffset = (ldr&0xfff) + 8;
163
164 printf("original firmware entry point: 0x%08x\n",
165 (unsigned int) get_uint32le(image + origoffset));
166 printf("New entry point: 0x%08x\n",0x20000000 + inlength + 8);
167
168 /* Save the original firmware entry point at the start of the bootloader image */
169 put_uint32le(get_uint32le(image + origoffset),image+inlength);
170 put_uint32le(0x20000000 + inlength,image + inlength + 4);
171
172 /* Change the original firmware entry point to the third word in our bootloader */
173 put_uint32le(0x20000000 + inlength + 8,image+origoffset);
174
175
176 telechips_encode_crc(image, inlength + bootlength);
177
178 fdout = open(outfile, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644); 230 fdout = open(outfile, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644);
179 if (fdout < 0) 231 if (fdout < 0)
180 { 232 {
181 perror(bootfile); 233 perror(outfile);
182 ret = 6; 234 ret = 6;
183 goto error_exit; 235 goto error_exit;
184 } 236 }
185 237
186 n = write(fdout, image, inlength + bootlength); 238 n = write(fdout, image, patched_size);
187 if (n != inlength + bootlength) 239 if (n != patched_size)
188 { 240 {
189 printf("[ERR] Could not write output file %s\n",outfile); 241 printf("[ERR] Could not write output file %s\n",outfile);
190 ret = 7; 242 ret = 7;
@@ -193,14 +245,18 @@ int main(int argc, char *argv[])
193 245
194error_exit: 246error_exit:
195 247
196 if (fdin >= 0)
197 close(fdin);
198
199 if (fdboot >= 0)
200 close(fdboot);
201
202 if (fdout >= 0) 248 if (fdout >= 0)
203 close(fdout); 249 close(fdout);
204 250
251 if (of_buf)
252 free(of_buf);
253
254 if (boot_buf)
255 free(boot_buf);
256
257 if (image)
258 free(image);
259
205 return ret; 260 return ret;
206} 261}
262#endif