3 extract_fw.c - extract the main firmware image from a Sansa V2 (AMS) firmware
6 Copyright (C) Dave Chapman 2008
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
28 #include <sys/types.h>
35 /* Win32 compatibility */
41 static off_t
filesize(int fd
) {
44 if (fstat(fd
,&buf
) < 0) {
45 perror("[ERR] Checking filesize of input file");
52 static uint32_t get_uint32le(unsigned char* p
)
54 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
59 printf("Usage: extract_fw <firmware file> <output file>\n");
64 int main(int argc
, char* argv
[])
66 char *infile
, *outfile
;
71 uint32_t firmware_size
;
80 /* Open the firmware file */
81 fdin
= open(infile
,O_RDONLY
|O_BINARY
);
84 fprintf(stderr
,"[ERR] Could not open %s for reading\n",infile
);
88 if ((len
= filesize(fdin
)) < 0)
91 /* We will need no more memory than the total size plus the bootloader size
92 padded to a boundary */
93 if ((buf
= malloc(len
)) == NULL
) {
94 fprintf(stderr
,"[ERR] Could not allocate buffer for input file (%d bytes)\n",(int)len
);
98 n
= read(fdin
, buf
, len
);
100 if (n
!= (uint32_t)len
) {
101 fprintf(stderr
,"[ERR] Could not read firmware file\n");
107 /* Get the firmware size */
108 if (get_uint32le(&buf
[0x04])==0x0000f000)
109 firmware_size
= get_uint32le(&buf
[0x10]); /* v2 format */
111 firmware_size
= get_uint32le(&buf
[0x0c]); /* v1 format */
113 fdout
= open(outfile
, O_CREAT
|O_TRUNC
|O_WRONLY
|O_BINARY
,0666);
116 fprintf(stderr
,"[ERR] Could not open %s for writing\n",outfile
);
120 n
= write(fdout
, buf
+ 0x400, firmware_size
);
122 if (n
!= (uint32_t)firmware_size
) {
123 fprintf(stderr
,"[ERR] Could not write firmware block\n");