rockbox/flash/extract/extract.c
Daniel Stenberg 2acc0ac542 Updated our source code header to explicitly mention that we are GPL v2 or
later. We still need to hunt down snippets used that are not. 1324 modified
files...
http://www.rockbox.org/mail/archive/rockbox-dev-archive-2008-06/0060.shtml


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17847 a1c6a512-1295-4272-9138-f99709370657
2008-06-28 18:10:04 +00:00

147 lines
No EOL
3.9 KiB
C

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2003 by Jörg Hohensohn
*
* Tool to extract the scrambled image out of an Archos flash ROM dump
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#define UINT8 unsigned char
#define UINT16 unsigned short
#define UINT32 unsigned long
#define IMAGE_HEADER 0x6000 // a 32 byte header in front of the software image
#define IMAGE_START 0x6020 // software image position in Flash
// place a 32 bit value into memory, big endian
void Write32(UINT8* pByte, UINT32 value)
{
pByte[0] = (UINT8)(value >> 24);
pByte[1] = (UINT8)(value >> 16);
pByte[2] = (UINT8)(value >> 8);
pByte[3] = (UINT8)(value);
}
// read a 32 bit value from memory, big endian
UINT32 Read32(UINT8* pByte)
{
UINT32 value = 0;
value |= (UINT32)pByte[0] << 24;
value |= (UINT32)pByte[1] << 16;
value |= (UINT32)pByte[2] << 8;
value |= (UINT32)pByte[3];
return value;
}
// entry point
int main(int argc, char* argv[])
{
FILE* pInFile;
FILE* pOutFile;
UINT8 aHeader[6];
UINT8 aImage[256*1024];
UINT32 i;
UINT32 uiSize, uiStart;
UINT16 usChecksum = 0;
if (argc < 2)
{
printf("Extract the software image out of an original Archos Flash ROM dump.\n");
printf("Result is a scrambled file, use the descramble tool to get the binary,\n");
printf(" always without the -fm option, even if processing an FM software.\n\n");
printf("Usage: extract <flash dump file> <output file>\n");
printf("Example: extract internal_rom_2000000-203FFFF.bin archos.ajz\n");
exit(0);
}
pInFile = fopen(argv[1], "rb");
if (pInFile == NULL)
{
printf("Error opening input file %s\n", argv[1]);
exit(1);
}
if (fread(aImage, 1, sizeof(aImage), pInFile) != sizeof(aImage))
{
printf("Error reading input file %s, must be 256kB in size.\n", argv[1]);
fclose(pInFile);
exit(2);
}
fclose(pInFile);
// find out about the type
uiStart = Read32(aImage + 8);
uiSize = Read32(aImage + 12); // booted ROM image
if (uiStart == 0x02000100 && uiSize > 20000)
{ // Player has no loader, starts directly with the image
uiStart = 0x0100;
}
else
{ // Recorder / FM / V2 Recorder
uiStart = IMAGE_START;
uiSize = Read32(aImage + IMAGE_HEADER + 4); // size record of header
}
// sanity check
if (uiSize > sizeof(aImage) - uiStart || uiSize < 40000)
{
printf("Error: Impossible image size &d bytes.\n", uiSize);
exit(3);
}
// generate checksum
for (i=0; i<uiSize; i++)
{
UINT8 byte;
byte = aImage[uiStart + i];
byte = ~((byte >> 1) | ((byte << 7) & 0x80)); /* poor man's ROR */
usChecksum += byte;
}
// make header
Write32(aHeader + 2, usChecksum); // checksum in 5th and 6th byte
Write32(aHeader, uiSize); // size in first 4 bytes
pOutFile = fopen(argv[2], "wb");
if (pOutFile == NULL)
{
printf("Error opening output file %s\n", argv[2]);
exit(4);
}
if (fwrite(aHeader, 1, sizeof(aHeader), pOutFile) != sizeof(aHeader)
|| fwrite(aImage + uiStart, 1, uiSize, pOutFile) != uiSize)
{
printf("Write error\n");
fclose(pOutFile);
exit(5);
}
fclose(pOutFile);
return 0;
}