8 * Fw Header Layout for Netgear / Sercomm devices
10 static const char *magic
= "sErCoMm"; /* 7 */
11 /* 7-11: version control/download control ? */
12 unsigned char version
[4] = {0x00, 0x01, 0x00, 0x00};
13 char *hwID
= ""; /* 11-43 , ASCII/HEX */
14 char *hwVer
= ""; /* 44-57 , ASCII/HEX */
15 char *swVer
= ""; /* 58-62 , ASCII/HEX */
18 #define HEADER_SIZE 71
20 /* null bytes until 511 */
21 u_int32_t checksum
= 0xFF; /* checksum */
22 /* 512 onwards -> ZIP containing rootfs with the same Header */
25 /* appended on rootfs for the Header. */
26 const int footer_size
= 128;
29 char *file_name
; /* name of the file */
30 char *file_data
; /* data of the file in memory */
31 u_int32_t file_size
; /* length of the file */
34 u_int8_t
getCheckSum(char *data
, int len
)
40 for (u_int32_t i
= 0; i
< len
; i
++) {
41 new = (data
[i
] + previous
) % 256;
42 previous
= new | previous
& -256;
44 return (u_int8_t
) new;
47 void *bufferFile(struct file_info
*finfo
, int dontload
)
53 printf("Opening file: %s\n", finfo
->file_name
);
55 f
= fopen(finfo
->file_name
, "rb");
61 fseek(f
, 0L, SEEK_END
);
66 printf("Filesize: %i .\n", fs
);
69 finfo
->file_size
= fs
;
75 char *data
= malloc(fs
);
76 finfo
->file_data
= data
;
78 int read
= fread(data
, fs
, 1, f
);
81 printf("Error reading file %s.", finfo
->file_name
);
86 printf("File: read successfully %i bytes.\n", read
*fs
);
91 void *writeFile(struct file_info
*finfo
)
95 printf("Writing file: %s.\n", finfo
->file_name
);
98 FILE *fout
= fopen(finfo
->file_name
, "w");
100 if (!fwrite(finfo
->file_data
, finfo
->file_size
, 1, fout
)) {
101 printf("Wanted to write, but something went wrong.\n");
108 void *rmFile(struct file_info
*finfo
)
110 remove(finfo
->file_name
);
111 free(finfo
->file_data
);
112 finfo
->file_size
= 0;
115 void *usage(char *argv
[])
117 printf("Usage: %s <sysupgradefile> <kernel_offset> <HWID> <HWVER> <SWID>\n"
118 "All are positional arguments ... \n"
119 " sysupgradefile: File with the kernel uimage at 0\n"
120 " kernel_offset: Offset in Hex where the kernel is located\n"
121 " HWID: Hardware ID, ASCII\n"
122 " HWVER: Hardware Version, ASCII\n"
123 " SWID: Software Version, Hex\n"
128 int main(int argc
, char *argv
[])
130 printf("Building fw image for sercomm devices.\n");
133 struct file_info myfile
= {argv
[1], 0, 0};
134 bufferFile(&myfile
, 0);
135 char chksum
= getCheckSum(myfile
.file_data
, myfile
.file_size
);
136 printf("Checksum for File: %X.\n", chksum
);
147 struct file_info sysupgrade
= {argv
[1], 0, 0};
148 bufferFile(&sysupgrade
, 0);
150 int kernel_offset
= 0x90000; /* offset for the kernel inside the rootfs, default val */
151 sscanf(argv
[2], "%X", &kernel_offset
);
153 printf("Kernel_offset: at %X/%i bytes.\n", kernel_offset
, kernel_offset
);
155 char *hwID
= argv
[3];
156 char *hwVer
= argv
[4];
158 sscanf(argv
[5],"%4X",&swVer
);
159 swVer
= bswap_32(swVer
);
161 char *rootfsname
= malloc(2*strlen(sysupgrade
.file_name
) + 8);
162 sprintf(rootfsname
, "%s.rootfs", sysupgrade
.file_name
);
164 char *zipfsname
= malloc(2*strlen(rootfsname
) + 5);
165 sprintf(zipfsname
, "%s.zip", rootfsname
);
169 printf("Building header: %s %s %2X %s.\n", hwID
, hwVer
, swVer
, magic
);
171 /* Construct the firmware header/magic */
172 struct file_info header
= {0, 0, 0};
173 header
.file_size
= HEADER_SIZE
;
174 header
.file_data
= malloc(HEADER_SIZE
);
175 bzero(header
.file_data
, header
.file_size
);
177 char *tg
= header
.file_data
;
179 memcpy(tg
+7, version
, 4*sizeof(char));
181 strcpy(tg
+45, hwVer
);
182 memcpy(tg
+55, &swVer
,sizeof(u_int32_t
));
183 strcpy(tg
+63, magic
);
186 printf("Header done, now creating rootfs.");
188 /* Construct a rootfs */
189 struct file_info rootfs
= {0, 0, 0};
190 rootfs
.file_size
= sysupgrade
.file_size
+ kernel_offset
+ footer_size
;
191 rootfs
.file_data
= malloc(rootfs
.file_size
);
192 bzero(rootfs
.file_data
, rootfs
.file_size
);
193 rootfs
.file_name
= rootfsname
;
195 /* copy Owrt image to Kernel location */
196 memcpy(rootfs
.file_data
+kernel_offset
, sysupgrade
.file_data
, sysupgrade
.file_size
);
198 /* 22 added to get away from sysup image, no other reason.
199 * updater searches for magic anyway */
200 tg
= rootfs
.file_data
+ kernel_offset
+ sysupgrade
.file_size
+22;
202 memcpy(tg
, header
.file_data
, header
.file_size
);
206 printf("Preparing to zip.\n");
208 /* now that we got the rootfs, repeat the whole thing again(sorta):
209 * 1. zip the rootfs */
210 char *zipper
= malloc(5 + 2*strlen(rootfs
.file_name
) + 4);
211 sprintf(zipper
, "%s %s %s", "zip ", zipfsname
, rootfs
.file_name
);
212 int ret
= system(zipper
);
214 /* clear rootfs file */
217 /* and load zipped fs */
218 struct file_info zippedfs
= {zipfsname
, 0, 0};
219 bufferFile(&zippedfs
, 0);
222 printf("Creating Image.\n");
225 /* 2. create new file 512+rootfs size */
226 struct file_info image
= {argv
[1], 0, 0};
227 image
.file_data
= malloc(zippedfs
.file_size
+ 512);
228 image
.file_size
= zippedfs
.file_size
+ 512;
230 /* 3. copy zipfile at loc 512 */
231 memcpy(image
.file_data
+512, zippedfs
.file_data
, zippedfs
.file_size
);
234 /* 4. add header to file */
235 memcpy(image
.file_data
, header
.file_data
, header
.file_size
);
237 /* 5. do a checksum run, and compute checksum */
238 char chksum
= getCheckSum(image
.file_data
, image
.file_size
);
240 printf("Checksum for Image: %X.\n", chksum
);
243 /* 6. write the checksum invert into byte 511 to bring it to 0 */
244 chksum
= (chksum
^ 0xFF) + 1;
245 memcpy(image
.file_data
+511, &chksum
, 1);
247 chksum
= getCheckSum(image
.file_data
, image
.file_size
);
249 printf("Checksum for after fix: %X.\n", chksum
);
251 /* 7. pray that the updater will accept the file */