mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-08 12:45:26 -05:00
Add RKW firmware file format loader
Change-Id: I5283fdcdb8d263fd9375a6d29396f82650aeb686
This commit is contained in:
parent
f35e300304
commit
2f8b44aae2
5 changed files with 337 additions and 0 deletions
149
firmware/target/arm/rk27xx/rkw-loader.c
Normal file
149
firmware/target/arm/rk27xx/rkw-loader.c
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
*
|
||||
* Copyright (C) 2012 Marcin Bukat
|
||||
*
|
||||
* 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 1
|
||||
* 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 "config.h"
|
||||
#include "rkw.h"
|
||||
#include "crc32-rkw.h"
|
||||
#include "file.h"
|
||||
#include "panic.h"
|
||||
|
||||
/* error strings sorted by number */
|
||||
/* error 0 is empty */
|
||||
static const char *err_str[] = {
|
||||
"Loading OK",
|
||||
"Can't open RKW file",
|
||||
"Can't read RKW header",
|
||||
"Invalid RKW magic number",
|
||||
"RKW header CRC error",
|
||||
"RKW file too big",
|
||||
"RKW Load address mismatch",
|
||||
"Bad model number",
|
||||
"Error Reading File",
|
||||
"RKW firmware CRC error"
|
||||
};
|
||||
|
||||
const char *rkw_strerror(int8_t errno)
|
||||
{
|
||||
if (-errno >= sizeof(err_str)/sizeof(err_str[0]) || errno > 0)
|
||||
return "Unknown error";
|
||||
|
||||
return err_str[-errno];
|
||||
}
|
||||
|
||||
/* loosely based on load_firmware()
|
||||
* on success we return size loaded image
|
||||
* on error we return negative value which can be deciphered by means
|
||||
* of rkw_strerror() function
|
||||
*/
|
||||
int load_rkw(unsigned char* buf, const char* filename, int buffer_size)
|
||||
{
|
||||
int fd;
|
||||
int rc;
|
||||
int len;
|
||||
int ret;
|
||||
uint32_t crc, fw_crc;
|
||||
struct rkw_header_t rkw_info;
|
||||
|
||||
fd = open(filename, O_RDONLY);
|
||||
|
||||
if(fd < 0)
|
||||
return -1;
|
||||
|
||||
rc = read(fd, &rkw_info, sizeof(rkw_info));
|
||||
if (rc < (int)sizeof(rkw_info))
|
||||
{
|
||||
ret = -2;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* check if RKW is valid */
|
||||
if (rkw_info.magic_number != RKLD_MAGIC)
|
||||
{
|
||||
ret = -3;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* check header crc if present */
|
||||
if (rkw_info.load_options & RKW_HEADER_CRC)
|
||||
{
|
||||
crc = crc32_rkw((uint8_t *)&rkw_info, sizeof(rkw_info)-sizeof(uint32_t));
|
||||
if (rkw_info.crc != crc)
|
||||
{
|
||||
ret = -4;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
/* check image size */
|
||||
len = rkw_info.load_limit - rkw_info.load_address;
|
||||
if (len > buffer_size)
|
||||
{
|
||||
ret = -5;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* check load address - we support loading only at 0x60000000 */
|
||||
if (rkw_info.load_address != 0x60000000)
|
||||
{
|
||||
ret = -6;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* rockbox extension - we use one of reserved fields to store
|
||||
* model number information. This prevents from loading
|
||||
* rockbox RKW for different player.
|
||||
*/
|
||||
if (rkw_info.reserved0 != 0 && rkw_info.reserved0 != MODEL_NUMBER)
|
||||
{
|
||||
ret = -7;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* skip header */
|
||||
lseek(fd, sizeof(rkw_info), SEEK_SET);
|
||||
|
||||
/* load image into buffer */
|
||||
rc = read(fd, buf, len);
|
||||
|
||||
if(rc < len)
|
||||
{
|
||||
ret = -8;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (rkw_info.load_options & RKW_IMAGE_CRC)
|
||||
{
|
||||
rc = read(fd, &fw_crc, sizeof(uint32_t));
|
||||
|
||||
crc = crc32_rkw((uint8_t *)buf, len);
|
||||
|
||||
if (fw_crc != crc)
|
||||
{
|
||||
ret = -9;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
ret = len;
|
||||
end:
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue