summaryrefslogtreecommitdiff
path: root/firmware/target/arm/rk27xx
diff options
context:
space:
mode:
authorMarcin Bukat <marcin.bukat@gmail.com>2012-03-02 16:29:42 +0100
committerMarcin Bukat <marcin.bukat@gmail.com>2012-03-04 00:34:26 +0100
commit2f8b44aae2827a7280dc0a8e5b46a9f33e5eea60 (patch)
treee14606096fa23091db5568d5312e2bda1ba176f3 /firmware/target/arm/rk27xx
parentf35e300304388c30fdeb6493ec5e5e5bd52e3aab (diff)
downloadrockbox-2f8b44aae2827a7280dc0a8e5b46a9f33e5eea60.tar.gz
rockbox-2f8b44aae2827a7280dc0a8e5b46a9f33e5eea60.zip
Add RKW firmware file format loader
Change-Id: I5283fdcdb8d263fd9375a6d29396f82650aeb686
Diffstat (limited to 'firmware/target/arm/rk27xx')
-rw-r--r--firmware/target/arm/rk27xx/rkw-loader.c149
1 files changed, 149 insertions, 0 deletions
diff --git a/firmware/target/arm/rk27xx/rkw-loader.c b/firmware/target/arm/rk27xx/rkw-loader.c
new file mode 100644
index 0000000000..328ad127d0
--- /dev/null
+++ b/firmware/target/arm/rk27xx/rkw-loader.c
@@ -0,0 +1,149 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2012 Marcin Bukat
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 1
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#include "config.h"
22#include "rkw.h"
23#include "crc32-rkw.h"
24#include "file.h"
25#include "panic.h"
26
27/* error strings sorted by number */
28/* error 0 is empty */
29static const char *err_str[] = {
30 "Loading OK",
31 "Can't open RKW file",
32 "Can't read RKW header",
33 "Invalid RKW magic number",
34 "RKW header CRC error",
35 "RKW file too big",
36 "RKW Load address mismatch",
37 "Bad model number",
38 "Error Reading File",
39 "RKW firmware CRC error"
40};
41
42const char *rkw_strerror(int8_t errno)
43{
44 if (-errno >= sizeof(err_str)/sizeof(err_str[0]) || errno > 0)
45 return "Unknown error";
46
47 return err_str[-errno];
48}
49
50/* loosely based on load_firmware()
51 * on success we return size loaded image
52 * on error we return negative value which can be deciphered by means
53 * of rkw_strerror() function
54 */
55int load_rkw(unsigned char* buf, const char* filename, int buffer_size)
56{
57 int fd;
58 int rc;
59 int len;
60 int ret;
61 uint32_t crc, fw_crc;
62 struct rkw_header_t rkw_info;
63
64 fd = open(filename, O_RDONLY);
65
66 if(fd < 0)
67 return -1;
68
69 rc = read(fd, &rkw_info, sizeof(rkw_info));
70 if (rc < (int)sizeof(rkw_info))
71 {
72 ret = -2;
73 goto end;
74 }
75
76 /* check if RKW is valid */
77 if (rkw_info.magic_number != RKLD_MAGIC)
78 {
79 ret = -3;
80 goto end;
81 }
82
83 /* check header crc if present */
84 if (rkw_info.load_options & RKW_HEADER_CRC)
85 {
86 crc = crc32_rkw((uint8_t *)&rkw_info, sizeof(rkw_info)-sizeof(uint32_t));
87 if (rkw_info.crc != crc)
88 {
89 ret = -4;
90 goto end;
91 }
92 }
93
94 /* check image size */
95 len = rkw_info.load_limit - rkw_info.load_address;
96 if (len > buffer_size)
97 {
98 ret = -5;
99 goto end;
100 }
101
102 /* check load address - we support loading only at 0x60000000 */
103 if (rkw_info.load_address != 0x60000000)
104 {
105 ret = -6;
106 goto end;
107 }
108
109 /* rockbox extension - we use one of reserved fields to store
110 * model number information. This prevents from loading
111 * rockbox RKW for different player.
112 */
113 if (rkw_info.reserved0 != 0 && rkw_info.reserved0 != MODEL_NUMBER)
114 {
115 ret = -7;
116 goto end;
117 }
118
119 /* skip header */
120 lseek(fd, sizeof(rkw_info), SEEK_SET);
121
122 /* load image into buffer */
123 rc = read(fd, buf, len);
124
125 if(rc < len)
126 {
127 ret = -8;
128 goto end;
129 }
130
131 if (rkw_info.load_options & RKW_IMAGE_CRC)
132 {
133 rc = read(fd, &fw_crc, sizeof(uint32_t));
134
135 crc = crc32_rkw((uint8_t *)buf, len);
136
137 if (fw_crc != crc)
138 {
139 ret = -9;
140 goto end;
141 }
142 }
143
144 ret = len;
145end:
146 close(fd);
147 return ret;
148}
149