7f31d4f4c79c3b6bdc6d74af66e1fc2581727f59
9 * Fw Header Layout for Netgear / Sercomm devices
11 static const char *magic
= "sErCoMm"; /* 7 */
12 /* 7-11: version control/download control ? */
13 unsigned char version
[4] = {0x00, 0x01, 0x00, 0x00};
14 char *hwID
= ""; /* 11-43 , ASCII/HEX */
15 char *hwVer
= ""; /* 44-57 , ASCII/HEX */
16 char *swVer
= ""; /* 58-62 , ASCII/HEX */
19 #define HEADER_SIZE 71
21 /* null bytes until 511 */
22 u_int32_t checksum
= 0xFF; /* checksum */
23 /* 512 onwards -> ZIP containing rootfs with the same Header */
26 /* appended on rootfs for the Header. */
27 const int footer_size
= 128;
30 char *file_name
; /* name of the file */
31 char *file_data
; /* data of the file in memory */
32 u_int32_t file_size
; /* length of the file */
35 u_int8_t
getCheckSum(char *data
, int len
)
41 for (u_int32_t i
= 0; i
< len
; i
++) {
42 new = (data
[i
] + previous
) % 256;
43 previous
= new | previous
& -256;
45 return (u_int8_t
) new;
48 void *bufferFile(struct file_info
*finfo
, int dontload
)
54 printf("Opening file: %s\n", finfo
->file_name
);
56 f
= fopen(finfo
->file_name
, "rb");
62 fseek(f
, 0L, SEEK_END
);
67 printf("Filesize: %i .\n", fs
);
70 finfo
->file_size
= fs
;
76 char *data
= malloc(fs
);
77 finfo
->file_data
= data
;
79 int read
= fread(data
, fs
, 1, f
);
82 printf("Error reading file %s.", finfo
->file_name
);
87 printf("File: read successfully %i bytes.\n", read
*fs
);
92 void *writeFile(struct file_info
*finfo
)
96 printf("Writing file: %s.\n", finfo
->file_name
);
99 FILE *fout
= fopen(finfo
->file_name
, "w");
101 if (!fwrite(finfo
->file_data
, finfo
->file_size
, 1, fout
)) {
102 printf("Wanted to write, but something went wrong.\n");
109 void *rmFile(struct file_info
*finfo
)
111 remove(finfo
->file_name
);
112 free(finfo
->file_data
);
113 finfo
->file_size
= 0;
116 void *usage(char *argv
[])
118 printf("Usage: %s <sysupgradefile> <kernel_offset> <HWID> <HWVER> <SWID>\n"
119 "All are positional arguments ... \n"
120 " sysupgradefile: File with the kernel uimage at 0\n"
121 " kernel_offset: Offset in Hex where the kernel is located\n"
122 " HWID: Hardware ID, ASCII\n"
123 " HWVER: Hardware Version, ASCII\n"
124 " SWID: Software Version, Hex\n"
129 int main(int argc
, char *argv
[])
131 printf("Building fw image for sercomm devices.\n");
134 struct file_info myfile
= {argv
[1], 0, 0};
135 bufferFile(&myfile
, 0);
136 char chksum
= getCheckSum(myfile
.file_data
, myfile
.file_size
);
137 printf("Checksum for File: %X.\n", chksum
);
148 struct file_info sysupgrade
= {argv
[1], 0, 0};
149 bufferFile(&sysupgrade
, 0);
151 int kernel_offset
= 0x90000; /* offset for the kernel inside the rootfs, default val */
152 sscanf(argv
[2], "%X", &kernel_offset
);
154 printf("Kernel_offset: at %X/%i bytes.\n", kernel_offset
, kernel_offset
);
156 char *hwID
= argv
[3];
157 char *hwVer
= argv
[4];
159 sscanf(argv
[5],"%4X",&swVer
);
160 swVer
= bswap_32(swVer
);
162 char *rootfsname
= malloc(2*strlen(sysupgrade
.file_name
) + 8);
163 sprintf(rootfsname
, "%s.rootfs", sysupgrade
.file_name
);
165 char *zipfsname
= malloc(2*strlen(rootfsname
) + 5);
166 sprintf(zipfsname
, "%s.zip", rootfsname
);
170 printf("Building header: %s %s %2X %s.\n", hwID
, hwVer
, swVer
, magic
);
172 /* Construct the firmware header/magic */
173 struct file_info header
= {0, 0, 0};
174 header
.file_size
= HEADER_SIZE
;
175 header
.file_data
= malloc(HEADER_SIZE
);
176 bzero(header
.file_data
, header
.file_size
);
178 char *tg
= header
.file_data
;
180 memcpy(tg
+7, version
, 4*sizeof(char));
182 strcpy(tg
+45, hwVer
);
183 memcpy(tg
+55, &swVer
,sizeof(u_int32_t
));
184 strcpy(tg
+63, magic
);
187 printf("Header done, now creating rootfs.");
189 /* Construct a rootfs */
190 struct file_info rootfs
= {0, 0, 0};
191 rootfs
.file_size
= sysupgrade
.file_size
+ kernel_offset
+ footer_size
;
192 rootfs
.file_data
= malloc(rootfs
.file_size
);
193 bzero(rootfs
.file_data
, rootfs
.file_size
);
194 rootfs
.file_name
= rootfsname
;
196 /* copy Owrt image to Kernel location */
197 memcpy(rootfs
.file_data
+kernel_offset
, sysupgrade
.file_data
, sysupgrade
.file_size
);
199 /* 22 added to get away from sysup image, no other reason.
200 * updater searches for magic anyway */
201 tg
= rootfs
.file_data
+ kernel_offset
+ sysupgrade
.file_size
+22;
203 memcpy(tg
, header
.file_data
, header
.file_size
);
207 printf("Preparing to zip.\n");
209 /* now that we got the rootfs, repeat the whole thing again(sorta):
210 * 1. zip the rootfs */
211 char *zipper
= malloc(5 + 2*strlen(rootfs
.file_name
) + 4);
212 sprintf(zipper
, "%s %s %s", "zip ", zipfsname
, rootfs
.file_name
);
213 int ret
= system(zipper
);
215 /* clear rootfs file */
218 /* and load zipped fs */
219 struct file_info zippedfs
= {zipfsname
, 0, 0};
220 bufferFile(&zippedfs
, 0);
223 printf("Creating Image.\n");
226 /* 2. create new file 512+rootfs size */
227 struct file_info image
= {argv
[1], 0, 0};
228 image
.file_data
= malloc(zippedfs
.file_size
+ 512);
229 image
.file_size
= zippedfs
.file_size
+ 512;
231 /* 3. copy zipfile at loc 512 */
232 memcpy(image
.file_data
+512, zippedfs
.file_data
, zippedfs
.file_size
);
235 /* 4. add header to file */
236 memcpy(image
.file_data
, header
.file_data
, header
.file_size
);
238 /* 5. do a checksum run, and compute checksum */
239 char chksum
= getCheckSum(image
.file_data
, image
.file_size
);
241 printf("Checksum for Image: %X.\n", chksum
);
244 /* 6. write the checksum invert into byte 511 to bring it to 0 */
245 chksum
= (chksum
^ 0xFF) + 1;
246 memcpy(image
.file_data
+511, &chksum
, 1);
248 chksum
= getCheckSum(image
.file_data
, image
.file_size
);
250 printf("Checksum for after fix: %X.\n", chksum
);
252 /* 7. pray that the updater will accept the file */