summaryrefslogtreecommitdiff
path: root/rbutil/mkrk27boot
diff options
context:
space:
mode:
Diffstat (limited to 'rbutil/mkrk27boot')
-rw-r--r--rbutil/mkrk27boot/Makefile77
-rw-r--r--rbutil/mkrk27boot/ata-sim.c122
-rw-r--r--rbutil/mkrk27boot/autoconf.h37
-rw-r--r--rbutil/mkrk27boot/main.c55
-rw-r--r--rbutil/mkrk27boot/mkrk27boot.c281
-rw-r--r--rbutil/mkrk27boot/mkrk27boot.h36
6 files changed, 608 insertions, 0 deletions
diff --git a/rbutil/mkrk27boot/Makefile b/rbutil/mkrk27boot/Makefile
new file mode 100644
index 0000000000..cd1b7800de
--- /dev/null
+++ b/rbutil/mkrk27boot/Makefile
@@ -0,0 +1,77 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id$
8#
9
10FIRMWARE = ../../firmware/
11
12DRIVERS = $(FIRMWARE)drivers/
13EXPORT = $(FIRMWARE)export/
14
15BUILDDATE=$(shell date -u +'-DYEAR=%Y -DMONTH=%m -DDAY=%d')
16INCLUDE = -I$(EXPORT) -I$(FIRMWARE)include -I$(FIRMWARE)target/hosted -I$(FIRMWARE)target/hosted/sdl
17DEFINES = -DTEST_FAT -DDISK_WRITE -DHAVE_FAT16SUPPORT -D__PCTOOL__
18
19SIM_FLAGS = -Wall -g -std=gnu99 -Wno-pointer-sign $(DEFINES) $(BUILDDATE) -I. $(INCLUDE) -I$(FIRMWARE)/libc/include
20FLAGS = -Wall -g -std=gnu99 -Wno-pointer-sign $(DEFINES) -I. $(INCLUDE)
21
22OUTPUT = mkrk27boot
23
24
25# inputs
26LIBSOURCES := $(DRIVERS)fat.c $(FIRMWARE)libc/ctype.c $(FIRMWARE)libc/strtok.c \
27 $(FIRWARE)libc/errno.c$(FIRMWARE)common/strlcpy.c $(FIRMWARE)common/unicode.c \
28 $(FIRMWARE)common/file.c $(FIRMWARE)common/dir_uncached.c $(FIRMWARE)common/disk.c ata-sim.c mkrk27boot.c
29
30SOURCES := $(LIBSOURCES) main.c
31
32include ../libtools.make
33
34define sim_compile
35 @echo CC $<
36 $(SILENT)mkdir -p $(dir $@)
37 $(SILENT)$(CROSS)$(CC) $(SIM_FLAGS) -c -o $@ $<
38endef
39
40define compile
41 @echo CC $<
42 $(SILENT)mkdir -p $(dir $@)
43 $(SILENT)$(CROSS)$(CC) $(FLAGS) -c -o $@ $<
44endef
45
46$(OBJDIR)fat.o: $(DRIVERS)fat.c $(EXPORT)fat.h $(EXPORT)ata.h autoconf.h
47 $(sim_compile)
48
49$(OBJDIR)ctype.o: $(FIRMWARE)libc/ctype.c autoconf.h
50 $(sim_compile)
51
52$(OBJDIR)strtok.o: $(FIRMWARE)libc/strtok.c $(FIRMWARE)libc/include/string.h autoconf.h
53 $(sim_compile)
54
55$(OBJDIR)errno.o: $(FIRMWARE)libc/errno.c $(FIRMWARE)libc/include/errno.h autoconf.h
56 $(sim_compile)
57
58$(OBJDIR)disk.o: $(FIRMWARE)common/disk.c autoconf.h
59 $(sim_compile)
60
61$(OBJDIR)dir_uncached.o: $(FIRMWARE)common/dir_uncached.c autoconf.h
62 $(sim_compile)
63
64$(OBJDIR)file.o: $(FIRMWARE)common/file.c $(FIRMWARE)/include/file.h autoconf.h
65 $(sim_compile)
66
67$(OBJDIR)unicode.o: $(FIRMWARE)common/unicode.c autoconf.h
68 $(sim_compile)
69
70$(OBJDIR)strlcpy.o: $(FIRMWARE)common/strlcpy.c autoconf.h
71 $(sim_compile)
72
73$(OBJDIR)ata-sim.o: ata-sim.c $(EXPORT)ata.h autoconf.h
74 $(compile)
75
76$(OBJDIR)mkrk27boot.o: mkrk27boot.c mkrk27boot.h autoconf.h
77 $(compile)
diff --git a/rbutil/mkrk27boot/ata-sim.c b/rbutil/mkrk27boot/ata-sim.c
new file mode 100644
index 0000000000..129c4b36a9
--- /dev/null
+++ b/rbutil/mkrk27boot/ata-sim.c
@@ -0,0 +1,122 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2012 by Andrew Ryabinin
11 *
12 * major portion of code is taken from firmware/test/fat/ata-sim.c
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <stdarg.h>
28#include "debug.h"
29#include "dir.h"
30
31#define BLOCK_SIZE 512
32
33static FILE* file;
34
35extern char *img_filename;
36
37void mutex_init(struct mutex* l) {}
38void mutex_lock(struct mutex* l) {}
39void mutex_unlock(struct mutex* l) {}
40
41void panicf( char *fmt, ...) {
42 va_list ap;
43 va_start( ap, fmt );
44 fprintf(stderr,"***PANIC*** ");
45 vfprintf(stderr, fmt, ap );
46 va_end( ap );
47 exit(1);
48}
49
50void debugf(const char *fmt, ...) {
51 va_list ap;
52 va_start( ap, fmt );
53 fprintf(stderr,"DEBUGF: ");
54 vfprintf( stderr, fmt, ap );
55 va_end( ap );
56}
57
58void ldebugf(const char* file, int line, const char *fmt, ...) {
59 va_list ap;
60 va_start( ap, fmt );
61 fprintf( stderr, "%s:%d ", file, line );
62 vfprintf( stderr, fmt, ap );
63 va_end( ap );
64}
65
66int storage_read_sectors(unsigned long start, int count, void* buf)
67{
68 if ( count > 1 )
69 DEBUGF("[Reading %d blocks: 0x%lx to 0x%lx]\n",
70 count, start, start+count-1);
71 else
72 DEBUGF("[Reading block 0x%lx]\n", start);
73
74 if(fseek(file,start*BLOCK_SIZE,SEEK_SET)) {
75 perror("fseek");
76 return -1;
77 }
78 if(!fread(buf,BLOCK_SIZE,count,file)) {
79 DEBUGF("ata_write_sectors(0x%lx, 0x%x, %p)\n", start, count, buf );
80 perror("fread");
81 panicf("Disk error\n");
82 }
83 return 0;
84}
85
86int storage_write_sectors(unsigned long start, int count, void* buf)
87{
88 if ( count > 1 )
89 DEBUGF("[Writing %d blocks: 0x%lx to 0x%lx]\n",
90 count, start, start+count-1);
91 else
92 DEBUGF("[Writing block 0x%lx]\n", start);
93
94 if (start == 0)
95 panicf("Writing on sector 0!\n");
96
97 if(fseek(file,start*BLOCK_SIZE,SEEK_SET)) {
98 perror("fseek");
99 return -1;
100 }
101 if(!fwrite(buf,BLOCK_SIZE,count,file)) {
102 DEBUGF("ata_write_sectors(0x%lx, 0x%x, %p)\n", start, count, buf );
103 perror("fwrite");
104 panicf("Disk error\n");
105 }
106 return 0;
107}
108
109int ata_init(void)
110{
111 file=fopen(img_filename,"rb+");
112 if(!file) {
113 fprintf(stderr, "read_disk() - Could not find \"%s\"\n",img_filename);
114 return -1;
115 }
116 return 0;
117}
118
119void ata_exit(void)
120{
121 fclose(file);
122}
diff --git a/rbutil/mkrk27boot/autoconf.h b/rbutil/mkrk27boot/autoconf.h
new file mode 100644
index 0000000000..a4907d4599
--- /dev/null
+++ b/rbutil/mkrk27boot/autoconf.h
@@ -0,0 +1,37 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2012 by Andrew Ryabinin
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef __BUILD_AUTOCONF_H
22#define __BUILD_AUTOCONF_H
23
24/* assume little endian for now */
25#define ROCKBOX_LITTLE_ENDIAN 1
26
27#define ROCKBOX_DIR "../../"
28
29/* Rename rockbox API functions which may conflict with system's functions.
30 This will allow to link libmkrk27boot with rbutil safely. */
31#define read(x,y,z) mkrk27_read(x,y,z)
32#define write(x,y,z) mkrk27_write(x,y,z)
33
34/* This should resolve confilict with ipodpatcher's filesize function. */
35#define filesize(x) mkrk27_filesize(x)
36
37#endif
diff --git a/rbutil/mkrk27boot/main.c b/rbutil/mkrk27boot/main.c
new file mode 100644
index 0000000000..5ba69b5a98
--- /dev/null
+++ b/rbutil/mkrk27boot/main.c
@@ -0,0 +1,55 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2012 by Andrew Ryabinin
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include<stdio.h>
23#include "mkrk27boot.h"
24
25
26int main(int argc, char **argv)
27{
28 char* img_file = NULL;
29 char* rkw_file = NULL;
30 char* out_img_file = NULL;
31 char* out_rkw_file = NULL;
32
33 if (argc == 4) {
34 img_file = argv[1];
35 rkw_file = argv[2];
36 out_img_file = argv[3];
37 out_rkw_file = "BASE.RKW";
38 } else if (argc == 5) {
39 img_file = argv[1];
40 rkw_file = argv[2];
41 out_img_file = argv[3];
42 out_rkw_file = argv[4];
43 } else {
44 fprintf(stdout, "\tusage: mkrk27boot <img file> <rkw file> <output img file> [<output rkw file>]\n");
45 fprintf(stdout, "\tIf output rkw file is not specified, the default is to put rkw file to BASE.RKW\n");
46 return -1;
47 }
48 if (mkrk27_patch(img_file, rkw_file, out_img_file, out_rkw_file)) {
49 fprintf(stdout, "%s\n", mkrk27_get_error());
50 return -1;
51 }
52 fprintf(stdout, "Success!\n");
53 return 0;
54}
55
diff --git a/rbutil/mkrk27boot/mkrk27boot.c b/rbutil/mkrk27boot/mkrk27boot.c
new file mode 100644
index 0000000000..4b51e281c7
--- /dev/null
+++ b/rbutil/mkrk27boot/mkrk27boot.c
@@ -0,0 +1,281 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2012 by Andrew Ryabinin
11 *
12 * based on firmware/test/fat/main.c
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <stdarg.h>
28#include <time.h>
29#include <errno.h>
30#include "disk.h"
31#include "dir.h"
32#include "file.h"
33#include "ata.h"
34#include "storage.h"
35#include "mkrk27boot.h"
36
37
38const char *img_filename;
39static char mkrk27_error_msg[256];
40
41static void mkrk27_set_error(const char *msg, ...) {
42 va_list ap;
43 va_start(ap, msg);
44 snprintf(mkrk27_error_msg, sizeof(mkrk27_error_msg), msg, ap);
45 va_end(ap);
46 return;
47}
48
49
50
51/* Extracts in_file from FAT image to out_file */
52static int extract_file(const char *in_file, const char* out_file) {
53 char buf[81920];
54 int nread;
55
56 int fd = open(in_file, O_RDONLY);
57 if (fd < 0) {
58 mkrk27_set_error("Failed to open file %s. ", in_file);
59 return -1;
60 }
61
62 FILE *file = fopen(out_file, "wb");
63 if (!file) {
64 mkrk27_set_error("Failed to open file %s. ", out_file);
65 close(fd);
66 return -1;
67 }
68
69 while (nread = read(fd, buf, sizeof buf), nread > 0) {
70 char *out_ptr = buf;
71 int nwritten;
72
73 do {
74 nwritten = fwrite(buf, 1, nread, file);
75
76 if (nwritten >= 0) {
77 nread -= nwritten;
78 out_ptr += nwritten;
79 } else if (errno != EINTR) {
80 mkrk27_set_error("Writting to file %s failed.", out_file);
81 goto exit;
82 }
83 } while(nread > 0);
84 }
85
86 if (nread == 0) {
87 fclose(file);
88 close(fd);
89 return 0;
90 } else {
91 mkrk27_set_error("Copy from %s to %s failed.", out_file, in_file);
92 }
93exit:
94 fclose(file);
95 close(fd);
96 return -1;
97}
98
99/* Replace out_file in FAT image with in_file */
100static int replace_file(const char *in_file, const char *out_file) {
101 char buf[81920];
102 int fd;
103 int nread;
104
105 fd = creat(out_file, 0666);
106 if (fd < 0) {
107 mkrk27_set_error("Failed to open file %s. ", out_file);
108 return -1;
109 }
110
111 FILE *file = fopen(in_file, "rb");
112 if (!file) {
113 mkrk27_set_error("Failed to open file %s. ", in_file);
114 close(fd);
115 return -1;
116 }
117
118 while (nread = fread(buf, 1, sizeof buf, file), nread > 0) {
119 char *out_ptr = buf;
120 int nwritten;
121
122 do {
123 nwritten = write(fd, buf, nread);
124 if (nwritten >= 0) {
125 nread -= nwritten;
126 out_ptr += nwritten;
127 } else {
128 mkrk27_set_error("Writting to file %s failed.", out_file);
129 goto exit;
130 }
131 } while(nread > 0);
132 }
133
134 if (nread == 0) {
135 fclose(file);
136 close(fd);
137 return 0;
138 } else {
139 mkrk27_set_error("Replacing %s with %s failed.", out_file, in_file);
140 }
141
142exit:
143 fclose(file);
144 close(fd);
145 return -1;
146}
147
148static int mkrk27_init(const char *filename) {
149 int i;
150 int rc;
151 srand(clock());
152
153 img_filename = filename;
154
155 if(ata_init()) {
156 mkrk27_set_error("Warning! The disk is uninitialized\n");
157 return -1;
158 }
159
160 struct partinfo *pinfo = disk_init();
161
162 if (!pinfo) {
163 mkrk27_set_error("Failed reading partitions\n");
164 return -1;
165 }
166
167 for ( i=0; i<4; i++ ) {
168 if ( pinfo[i].type == PARTITION_TYPE_FAT32
169#ifdef HAVE_FAT16SUPPORT
170 || pinfo[i].type == PARTITION_TYPE_FAT16
171#endif
172 ) {
173 rc = fat_mount(IF_MV2(0,) IF_MD2(0,) pinfo[i].start);
174 if(rc) {
175 mkrk27_set_error("mount: %d",rc);
176 return -1;
177 }
178 break;
179 }
180 }
181 if ( i==4 ) {
182 if(fat_mount(IF_MV2(0,) IF_MD2(0,) 0)) {
183 mkrk27_set_error("FAT32 partition!");
184 return -1;
185 }
186 }
187 return 0;
188}
189
190extern void ata_exit(void);
191
192static void mkrk27_deinit(void) {
193 ata_exit();
194}
195
196/* copy file */
197static int copy(const char *to, const char *from) {
198 FILE* fd_to, *fd_from;
199 char buf[4096];
200 ssize_t nread;
201
202 if (to == from) {
203 return 0;
204 }
205
206 fd_from = fopen(from, "rb");
207 if (!fd_from) {
208 mkrk27_set_error("Failed to open file %s.", from);
209 return -1;
210 }
211
212 fd_to = fopen(to, "wb");
213 if (!fd_to) {
214 mkrk27_set_error("Failed to open file %s.", to);
215 goto out_error;
216 }
217
218 while (nread = fread(buf, 1, sizeof buf, fd_from), nread > 0) {
219 char *out_ptr = buf;
220 ssize_t nwritten;
221
222 do {
223 nwritten = fwrite(out_ptr, 1, nread, fd_to);
224
225 if (nwritten >= 0)
226 {
227 nread -= nwritten;
228 out_ptr += nwritten;
229 }
230 else if (errno != EINTR)
231 {
232 mkrk27_set_error( "Writing to file %s failed.", to);
233 goto out_error;
234 }
235 } while (nread > 0);
236 }
237
238 if (nread == 0) {
239 fclose(fd_to);
240 fclose(fd_from);
241 return 0;
242 } else {
243 mkrk27_set_error("Copy from %s to %s failed.", from, to);
244 }
245
246out_error:
247
248 fclose(fd_from);
249 fclose(fd_to);
250
251 return -1;
252}
253
254char* mkrk27_get_error(void) {
255 return mkrk27_error_msg;
256}
257
258
259/* Patch rk27 firmware.
260 - img_file - original FAT image file, containing OF,
261 - rkw_file - rkw file which will replace BASE.RKW from OF,
262 - out_img_file - patched img file,
263 - out_rkw_file - BASE.RKW extracted from OF.
264*/
265int mkrk27_patch(const char* img_file, const char* rkw_file, const char* out_img_file, const char* out_rkw_file) {
266 if (copy(out_img_file, img_file)) {
267 return -1;
268 }
269 if (mkrk27_init(out_img_file)) {
270 return -1;
271 }
272 if (extract_file("/SYSTEM/BASE.RKW", out_rkw_file)) {
273 return -1;
274 }
275 if (replace_file(rkw_file, "/SYSTEM/BASE.RKW") ||
276 replace_file(rkw_file, "/SYSTEM00/BASE.RKW")) {
277 return -1;
278 }
279 mkrk27_deinit();
280 return 0;
281}
diff --git a/rbutil/mkrk27boot/mkrk27boot.h b/rbutil/mkrk27boot/mkrk27boot.h
new file mode 100644
index 0000000000..dc8c2e8133
--- /dev/null
+++ b/rbutil/mkrk27boot/mkrk27boot.h
@@ -0,0 +1,36 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2012 by Andrew Ryabinin
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef _MKRK27BOOT_H
22#define _MKRK27BOOT_H
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28int mkrk27_patch(const char* img_file, const char* rkw_file, const char* out_img_file, const char* out_rkw_file);
29char *mkrk27_get_error(void);
30
31#ifdef __cplusplus
32}
33#endif
34
35
36#endif