summaryrefslogtreecommitdiff
path: root/utils/mknwzboot
diff options
context:
space:
mode:
Diffstat (limited to 'utils/mknwzboot')
-rw-r--r--utils/mknwzboot/Makefile52
-rw-r--r--utils/mknwzboot/install_script.sh157
-rw-r--r--utils/mknwzboot/main.c126
-rw-r--r--utils/mknwzboot/mknwzboot.c294
-rw-r--r--utils/mknwzboot/mknwzboot.h42
-rw-r--r--utils/mknwzboot/uninstall_script.sh122
6 files changed, 793 insertions, 0 deletions
diff --git a/utils/mknwzboot/Makefile b/utils/mknwzboot/Makefile
new file mode 100644
index 0000000000..3cbb2ef9dd
--- /dev/null
+++ b/utils/mknwzboot/Makefile
@@ -0,0 +1,52 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7
8# We use the SB code available in the Rockbox utils/sbtools directory
9UPGTOOLS_DIR=../../utils/nwztools/upgtools/
10CFLAGS += -I$(UPGTOOLS_DIR) -Wall
11# std=gnu99 is required by MinGW on Windows (c99 is sufficient for Linux / MXE)
12CFLAGS += -std=gnu99 -g -O3
13# dependencies
14# FIXME make it work for windows and maybe embed crypto++
15
16# Location to pkg-config binary.
17PKGCONFIG := pkg-config
18
19# Distros could use different names for the crypto library. We try a list
20# of candidate names, only one of them should be the valid one.
21LIBCRYPTO_NAMES = libcryptopp libcrypto++ cryptopp crypto++
22
23$(foreach l,$(LIBCRYPTO_NAMES),\
24 $(eval LDOPTS += $(shell $(PKGCONFIG) --silence-errors --libs $(l))))
25$(foreach l,$(LIBCRYPTO_NAMES),\
26 $(eval CFLAGS += $(shell $(PKGCONFIG) --silence-errors --cflags $(l))))
27$(foreach l,$(LIBCRYPTO_NAMES),\
28 $(eval CXXFLAGS += $(shell $(PKGCONFIG) --silence-errors --cflags $(l))))
29LDOPTS += -lpthread
30
31OUTPUT = mknwzboot
32
33# inputs for lib
34UPGTOOLS_SOURCES = misc.c upg.c fwp.c mg.cpp md5.cpp
35LIBSOURCES := mknwzboot.c install_script.c uninstall_script.c \
36 $(addprefix $(UPGTOOLS_DIR),$(UPGTOOLS_SOURCES))
37# inputs for binary only
38SOURCES := $(LIBSOURCES) main.c
39# dependencies for binary
40EXTRADEPS :=
41
42include ../libtools.make
43
44install_script.c install_script.h: install_script.sh $(BIN2C)
45 $(BIN2C) install_script.sh install_script
46
47uninstall_script.c uninstall_script.h: uninstall_script.sh $(BIN2C)
48 $(BIN2C) uninstall_script.sh uninstall_script
49
50# explicit dependencies on install_script.{c,h} and mknwzboot.h
51$(OBJDIR)mknwzboot.o: install_script.h install_script.c uninstall_script.h uninstall_script.c mknwzboot.h
52$(OBJDIR)main.o: main.c mknwzboot.h
diff --git a/utils/mknwzboot/install_script.sh b/utils/mknwzboot/install_script.sh
new file mode 100644
index 0000000000..76bd12c4d5
--- /dev/null
+++ b/utils/mknwzboot/install_script.sh
@@ -0,0 +1,157 @@
1#!/bin/sh
2
3# NOTE: busybox is using ash, a very posix and very pedantic shell, make sure
4# you test your scripts with
5# busybox sh -n <script>
6# and if you really, really don't want to download busybox to try it, then go
7# ahead and brick your device
8
9# The updater script on the NWZ has a major bug/feature:
10# it does NOT clear the update flag if the update scrit fails
11# thus causing a update/reboot loop and a bricked device
12# always clear to make sure we don't end up being screwed
13nvpflag fup 0xFFFFFFFF
14
15# go to /tmp
16cd /tmp
17
18# get content partition path
19CONTENTS="/contents"
20CONTENTS_PART=`mount | grep contents | awk '{ print $1 }'`
21
22# print a message to the screen and also on the standard output
23# lcdprint x,y msg
24lcdprint ()
25{
26 echo $2
27 lcdmsg -f /usr/local/bin/font_08x12.bmp -l $1 "$2"
28}
29
30# clear screen
31lcdmsg -c ""
32lcdprint 0,3 "Contents partition:\n$CONTENTS_PART"
33
34# We need to remount the contents partition in read-write mode be able to
35# write something on it
36lcdprint 0,6 "Remount $CONTENTS rw"
37mount -o remount,rw $CONTENTS_PART $CONTENTS
38if [ "$?" != 0 ]; then
39 lcdprint 0,15 "ERROR: remount failed"
40 sleep 3
41 exit 0
42fi
43
44# redirect all output to a log file
45exec > "$CONTENTS/install_dualboot_log.txt" 2>&1
46
47# import constants
48. /install_script/constant.txt
49_UPDATE_FN_=`nvpstr ufn`
50ROOTFS_TMP_DIR=/tmp/rootfs
51SPIDERAPP_PATH=$ROOTFS_TMP_DIR/usr/local/bin/SpiderApp
52
53# mount root partition
54lcdprint 0,7 "Mount root filesystem"
55mkdir $ROOTFS_TMP_DIR
56if [ "$?" != 0 ]; then
57 lcdprint 0,15 "ERROR: mkdir failed"
58 sleep 3
59 exit 0
60fi
61
62# If there is an ext4 mounter, try it. Otherwise or on failure, try ext3 and
63# then ext2.
64# NOTE some platforms probably use an mtd and this might need some fixing
65if [ -e /usr/local/bin/icx_mount.ext4 ]; then
66 /usr/local/bin/icx_mount.ext4 $COMMON_ROOTFS_PARTITION $ROOTFS_TMP_DIR
67else
68 false
69fi
70if [ "$?" != 0 ]; then
71 mount -t ext3 $COMMON_ROOTFS_PARTITION $ROOTFS_TMP_DIR
72fi
73if [ "$?" != 0 ]; then
74 mount -t ext2 $COMMON_ROOTFS_PARTITION $ROOTFS_TMP_DIR
75fi
76if [ "$?" != 0 ]; then
77 lcdprint 0,15 "ERROR: mount failed"
78 sleep 3
79 exit 0
80fi
81
82# rename the previous main application unless there is already a copy
83lcdprint 0,8 "Backup OF"
84if [ ! -e $SPIDERAPP_PATH.of ]; then
85 mv $SPIDERAPP_PATH $SPIDERAPP_PATH.of
86fi
87
88# extract our payload: the second file in the upgrade is a tar file
89# the files in the archive have paths of the form ./absolute/path and we extract
90# it at the rootfs mount it, so it can create/overwrite any file
91#
92# we need a small trick here: we want to pipe directly the output of the decryption
93# tool to tar, to avoid using space in /tmp/ or on the user partition
94lcdprint 0,9 "Install rockbox"
95FIFO_FILE=/tmp/rb.fifo
96mkfifo $FIFO_FILE
97if [ "$?" != 0 ]; then
98 umount "$ROOTFS_TMP_DIR"
99 lcdprint 0,15 "ERROR: cannot create fifo"
100 sleep 3
101 exit 0
102fi
103fwpchk -f /contents/$_UPDATE_FN_.UPG -c -1 $FIFO_FILE &
104#tar -tvf $FIFO_FILE
105tar -C $ROOTFS_TMP_DIR -xvf $FIFO_FILE
106if [ "$?" != 0 ]; then
107 umount "$ROOTFS_TMP_DIR"
108 lcdprint 0,15 "ERROR: extraction failed"
109 sleep 3
110 exit 0
111fi
112# wait for fwpchk
113wait
114if [ "$?" != 0 ]; then
115 umount "$ROOTFS_TMP_DIR"
116 lcdprint 0,15 "ERROR: no file to extract"
117 sleep 3
118 exit 0
119fi
120
121# create a symlink from /.rockbox to /contents/.rockbox (see dualboot code
122# for why)
123lcdprint 0,10 "Create rockbox symlink"
124rm -f "$ROOTFS_TMP_DIR/.rockbox"
125ln -s "$CONTENTS/.rockbox" "$ROOTFS_TMP_DIR/.rockbox"
126if [ "$?" != 0 ]; then
127 umount "$ROOTFS_TMP_DIR"
128 lcdprint 0,15 "ERROR: cannot create rockbox symlink"
129 sleep 3
130 exit 0
131fi
132
133# unmount root partition
134lcdprint 0,11 "Unmount root filesystem"
135sync
136if [ "$?" != 0 ]; then
137 umount "$ROOTFS_TMP_DIR"
138 lcdprint 0,15 "ERROR: sync failed"
139 sleep 3
140 exit 0
141fi
142
143umount $ROOTFS_TMP_DIR
144if [ "$?" != 0 ]; then
145 lcdprint 0,15 "ERROR: umount failed"
146 sleep 3
147 exit 0
148fi
149
150# Success screen
151lcdprint 0,15 "Rebooting in 3 seconds."
152sleep 3
153sync
154
155echo "Installation successful"
156# finish
157exit 0
diff --git a/utils/mknwzboot/main.c b/utils/mknwzboot/main.c
new file mode 100644
index 0000000000..491a18043b
--- /dev/null
+++ b/utils/mknwzboot/main.c
@@ -0,0 +1,126 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Amaury Pouly
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 <getopt.h>
23#include <stdlib.h>
24#include <stdio.h>
25#include <string.h>
26#include "mknwzboot.h"
27
28static void usage(void)
29{
30 printf("Usage: mknwzboot [options | file]...\n");
31 printf("Options:\n");
32 printf(" -h/--help Display this message\n");
33 printf(" -o <file> Set output file\n");
34 printf(" -b <file> Set boot file\n");
35 printf(" -d/--debug Enable debug output\n");
36 printf(" -x Dump device informations\n");
37 printf(" -u Create uninstall update\n");
38 printf(" -m <model> Specify model\n");
39 exit(1);
40}
41
42int main(int argc, char *argv[])
43{
44 char *outfile = NULL;
45 char *bootfile = NULL;
46 bool debug = false;
47 bool install = true;
48 const char *model = NULL;
49
50 if(argc == 1)
51 usage();
52
53 while(1)
54 {
55 static struct option long_options[] =
56 {
57 {"help", no_argument, 0, 'h'},
58 {"out-file", required_argument, 0, 'o'},
59 {"boot-file", required_argument, 0, 'b'},
60 {"debug", no_argument, 0, 'd'},
61 {"dev-info", no_argument, 0, 'x'},
62 {"uninstall", no_argument, 0, 'u'},
63 {"model", required_argument, 0, 'm'},
64 {0, 0, 0, 0}
65 };
66
67 int c = getopt_long(argc, argv, "ho:b:dxum:", long_options, NULL);
68 if(c == -1)
69 break;
70 switch(c)
71 {
72 case 'd':
73 debug = true;
74 break;
75 case 'h':
76 usage();
77 break;
78 case 'o':
79 outfile = optarg;
80 break;
81 case 'b':
82 bootfile = optarg;
83 break;
84 case 'x':
85 dump_nwz_dev_info("");
86 return 0;
87 case 'u':
88 install = false;
89 break;
90 case 'm':
91 model = optarg;
92 break;
93 default:
94 abort();
95 }
96 }
97
98 if(!outfile)
99 {
100 printf("You must specify an output file\n");
101 return 1;
102 }
103 if(install && !bootfile)
104 {
105 printf("You must specify a boot file for installation\n");
106 return 1;
107 }
108 if(!install && !model)
109 {
110 printf("You must provide a model for uninstallation\n");
111 return 1;
112 }
113 if(optind != argc)
114 {
115 printf("Extra arguments on command line\n");
116 return 1;
117 }
118
119 int err;
120 if(install)
121 err = mknwzboot(bootfile, outfile, debug);
122 else
123 err = mknwzboot_uninst(model, outfile, debug);
124 printf("Result: %d\n", err);
125 return err;
126}
diff --git a/utils/mknwzboot/mknwzboot.c b/utils/mknwzboot/mknwzboot.c
new file mode 100644
index 0000000000..22885674d8
--- /dev/null
+++ b/utils/mknwzboot/mknwzboot.c
@@ -0,0 +1,294 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Amaury Pouly
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#include <stdio.h>
22#include <stdlib.h>
23#include <stdarg.h>
24#include <string.h>
25#include <ctype.h>
26#include "mknwzboot.h"
27#include "upg.h"
28
29#include "install_script.h"
30#include "uninstall_script.h"
31
32struct nwz_model_desc_t
33{
34 /* Descriptive name of this model */
35 const char *model_name;
36 /* Model name used in the Rockbox header in ".sansa" files - these match the
37 -add parameter to the "scramble" tool */
38 const char *rb_model_name;
39 /* Model number used to initialise the checksum in the Rockbox header in
40 ".sansa" files - these are the same as MODEL_NUMBER in config-target.h */
41 const int rb_model_num;
42 /* Codename used in upgtool */
43 const char *codename;
44};
45
46static const struct nwz_model_desc_t nwz_models[] =
47{
48 { "Sony NWZ-E350 Series", "e350", 109, "nwz-e350" },
49 { "Sony NWZ-E450 Series", "e450", 100, "nwz-e450" },
50 { "Sony NWZ-E460 Series", "e460", 101, "nwz-e460" },
51 { "Sony NWZ-E470 Series", "e470", 103, "nwz-e470" },
52 { "Sony NWZ-E580 Series", "e580", 102, "nwz-e580" },
53 { "Sony NWZ-A10 Series", "a10", 104, "nwz-a10" },
54 { "Sony NW-A20 Series", "a20", 106, "nw-a20" },
55 { "Sony NWZ-A860 Series", "a860", 107, "nwz-a860" },
56 { "Sony NWZ-S750 Series", "s750", 108, "nwz-s750" },
57};
58
59#define NR_NWZ_MODELS (sizeof(nwz_models) / sizeof(nwz_models[0]))
60
61void dump_nwz_dev_info(const char *prefix)
62{
63 printf("%smknwzboot models:\n", prefix);
64 for(int i = 0; i < NR_NWZ_MODELS; i++)
65 {
66 printf("%s %s: rb_model=%s rb_num=%d codename=%s\n", prefix,
67 nwz_models[i].model_name, nwz_models[i].rb_model_name,
68 nwz_models[i].rb_model_num, nwz_models[i].codename);
69 }
70}
71
72/* read a file to a buffer */
73static void *read_file(const char *file, size_t *size)
74{
75 FILE *f = fopen(file, "rb");
76 if(f == NULL)
77 {
78 printf("[ERR] Cannot open file '%s' for reading: %m\n", file);
79 return NULL;
80 }
81 fseek(f, 0, SEEK_END);
82 *size = ftell(f);
83 fseek(f, 0, SEEK_SET);
84 void *buffer = malloc(*size);
85 if(fread(buffer, *size, 1, f) != 1)
86 {
87 free(buffer);
88 fclose(f);
89 printf("[ERR] Cannot read file '%s': %m\n", file);
90 return NULL;
91 }
92 fclose(f);
93 return buffer;
94}
95
96/* write a file from a buffer */
97static bool write_file(const char *file, void *buffer, size_t size)
98{
99 FILE *f = fopen(file, "wb");
100 if(f == NULL)
101 {
102 printf("[ERR] Cannot open file '%s' for writing: %m\n", file);
103 return false;
104 }
105 if(fwrite(buffer, size, 1, f) != 1)
106 {
107 fclose(f);
108 printf("[ERR] Cannot write file '%s': %m\n", file);
109 return false;
110 }
111 fclose(f);
112 return true;
113}
114
115static unsigned int be2int(unsigned char* buf)
116{
117 return ((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]);
118}
119
120static int find_model(uint8_t *boot, size_t boot_size)
121{
122 if(boot_size < 8)
123 {
124 printf("[ERR] Boot file is too small to be valid\n");
125 return -1;
126 }
127 /* find model by comparing magic scramble value */
128 int model = 0;
129 for(; model < NR_NWZ_MODELS; model++)
130 if(memcmp(boot + 4, nwz_models[model].rb_model_name, 4) == 0)
131 break;
132 if(model == NR_NWZ_MODELS)
133 {
134 printf("[ERR] This player is not supported: %.4s\n", boot + 4);
135 return -1;
136 }
137 printf("[INFO] Bootloader file for %s\n", nwz_models[model].model_name);
138 /* verify checksum */
139 uint32_t sum = nwz_models[model].rb_model_num;
140 for(int i = 8; i < boot_size; i++)
141 sum += boot[i];
142 if(sum != be2int(boot))
143 {
144 printf("[ERR] Checksum mismatch\n");
145 return -1;
146 }
147 return model;
148}
149
150static int find_model2(const char *model_str)
151{
152 /* since it can be confusing for the user, we accept both rbmodel and codename */
153 /* find model by comparing magic scramble value */
154 int model = 0;
155 for(; model < NR_NWZ_MODELS; model++)
156 if(strcmp(nwz_models[model].rb_model_name, model_str) == 0 ||
157 strcmp(nwz_models[model].codename, model_str) == 0)
158 break;
159 if(model == NR_NWZ_MODELS)
160 {
161 printf("[ERR] Unknown model: %s\n", model_str);
162 return -1;
163 }
164 printf("[INFO] Bootloader file for %s\n", nwz_models[model].model_name);
165 return model;
166}
167
168static bool get_model_keysig(int model, char key[NWZ_KEY_SIZE], char sig[NWZ_SIG_SIZE])
169{
170 const char *codename = nwz_models[model].codename;
171 for(int i = 0; g_model_list[i].model; i++)
172 if(strcmp(g_model_list[i].model, codename) == 0)
173 {
174 if(decrypt_keysig(g_model_list[i].kas, key, sig) == 0)
175 return true;
176 printf("[ERR] Cannot decrypt kas '%s'\n", g_model_list[i].kas);
177 return false;
178 }
179 printf("[ERR] Codename '%s' matches to entry in upg database\n", codename);
180 return false;
181}
182
183void nwz_printf(void *u, bool err, color_t c, const char *f, ...)
184{
185 (void)err;
186 (void)c;
187 bool *debug = u;
188 va_list args;
189 va_start(args, f);
190 if(err || *debug)
191 vprintf(f, args);
192 va_end(args);
193}
194
195static void *memdup(void *data, size_t size)
196{
197 void *buf = malloc(size);
198 memcpy(buf, data, size);
199 return buf;
200}
201
202int mknwzboot(const char *bootfile, const char *outfile, bool debug)
203{
204 size_t boot_size;
205 uint8_t *boot = read_file(bootfile, &boot_size);
206 if(boot == NULL)
207 {
208 printf("[ERR] Cannot open boot file\n");
209 return 1;
210 }
211 /* check that it is a valid scrambled file */
212 int model = find_model(boot, boot_size);
213 if(model < 0)
214 {
215 free(boot);
216 printf("[ERR] Invalid boot file\n");
217 return 2;
218 }
219 /* find keys */
220 char key[NWZ_KEY_SIZE];
221 char sig[NWZ_SIG_SIZE];
222 if(!get_model_keysig(model, key, sig))
223 {
224 printf("[ERR][INTERNAL] Cannot get keys for model\n");
225 return 3;
226 }
227 /* create the upg file */
228 struct upg_file_t *upg = upg_new();
229 /* first file is the install script: we have to copy data because upg_free()
230 * will free it */
231 upg_append(upg, memdup(install_script, LEN_install_script), LEN_install_script);
232 /* second file is the bootloader content (expected to be a tar file): we have
233 * to copy data because upg_free() will free it */
234 upg_append(upg, memdup(boot + 8, boot_size - 8), boot_size - 8);
235 free(boot);
236 /* write file to buffer */
237 size_t upg_size;
238 void *upg_buf = upg_write_memory(upg, key, sig, &upg_size, &debug, nwz_printf);
239 upg_free(upg);
240 if(upg_buf == NULL)
241 {
242 printf("[ERR] Cannot create UPG file\n");
243 return 4;
244 }
245 if(!write_file(outfile, upg_buf, upg_size))
246 {
247 free(upg_buf);
248 printf("[ERR] Cannpt write UPG file\n");
249 return 5;
250 }
251 free(upg_buf);
252 return 0;
253}
254
255int mknwzboot_uninst(const char *model_string, const char *outfile, bool debug)
256{
257 /* check that it is a valid scrambled file */
258 int model = find_model2(model_string);
259 if(model < 0)
260 {
261 printf("[ERR] Invalid model\n");
262 return 2;
263 }
264 /* find keys */
265 char key[NWZ_KEY_SIZE];
266 char sig[NWZ_SIG_SIZE];
267 if(!get_model_keysig(model, key, sig))
268 {
269 printf("[ERR][INTERNAL] Cannot get keys for model\n");
270 return 3;
271 }
272 /* create the upg file */
273 struct upg_file_t *upg = upg_new();
274 /* first file is the uninstall script: we have to copy data because upg_free()
275 * will free it */
276 upg_append(upg, memdup(uninstall_script, LEN_uninstall_script), LEN_uninstall_script);
277 /* write file to buffer */
278 size_t upg_size;
279 void *upg_buf = upg_write_memory(upg, key, sig, &upg_size, &debug, nwz_printf);
280 upg_free(upg);
281 if(upg_buf == NULL)
282 {
283 printf("[ERR] Cannot create UPG file\n");
284 return 4;
285 }
286 if(!write_file(outfile, upg_buf, upg_size))
287 {
288 free(upg_buf);
289 printf("[ERR] Cannpt write UPG file\n");
290 return 5;
291 }
292 free(upg_buf);
293 return 0;
294}
diff --git a/utils/mknwzboot/mknwzboot.h b/utils/mknwzboot/mknwzboot.h
new file mode 100644
index 0000000000..31f2c6355e
--- /dev/null
+++ b/utils/mknwzboot/mknwzboot.h
@@ -0,0 +1,42 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Amaury Pouly
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#ifndef MKIMXBOOT_H
23#define MKIMXBOOT_H
24
25#include <stdbool.h>
26#include <stdint.h>
27#include <sys/types.h>
28
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33void dump_nwz_dev_info(const char *prefix);
34/* return 0 on success */
35int mknwzboot(const char *bootfile, const char *outfile, bool debug);
36int mknwzboot_uninst(const char *model, const char *outfile, bool debug);
37
38#ifdef __cplusplus
39}
40#endif
41#endif
42
diff --git a/utils/mknwzboot/uninstall_script.sh b/utils/mknwzboot/uninstall_script.sh
new file mode 100644
index 0000000000..0e409c63cd
--- /dev/null
+++ b/utils/mknwzboot/uninstall_script.sh
@@ -0,0 +1,122 @@
1#!/bin/sh
2
3# NOTE: busybox is using ash, a very posix and very pedantic shell, make sure
4# you test your scripts with
5# busybox sh -n <script>
6# and if you really, really don't want to download busybox to try it, then go
7# ahead and brick your device
8
9# The updater script on the NWZ has a major bug/feature:
10# it does NOT clear the update flag if the update scrit fails
11# thus causing a update/reboot loop and a bricked device
12# always clear to make sure we don't end up being screwed
13nvpflag fup 0xFFFFFFFF
14
15# go to /tmp
16cd /tmp
17
18# get content partition path
19CONTENTS="/contents"
20CONTENTS_PART=`mount | grep contents | awk '{ print $1 }'`
21
22# print a message to the screen and also on the standard output
23# lcdprint x,y msg
24lcdprint ()
25{
26 echo $2
27 lcdmsg -f /usr/local/bin/font_08x12.bmp -l $1 "$2"
28}
29
30# clear screen
31lcdmsg -c ""
32lcdprint 0,3 "Contents partition:\n$CONTENTS_PART"
33
34# We need to remount the contents partition in read-write mode be able to
35# write something on it
36lcdprint 0,6 "Remount $CONTENTS rw"
37mount -o remount,rw $CONTENTS_PART $CONTENTS
38if [ "$?" != 0 ]; then
39 lcdprint 0,15 "ERROR: remount failed"
40 sleep 3
41 exit 0
42fi
43
44# redirect all output to a log file
45exec > "$CONTENTS/uninstall_dualboot_log.txt" 2>&1
46
47# import constants
48. /install_script/constant.txt
49ROOTFS_TMP_DIR=/tmp/rootfs
50SPIDERAPP_PATH=$ROOTFS_TMP_DIR/usr/local/bin/SpiderApp
51
52# mount root partition
53lcdprint 0,7 "Mount root filesystem"
54mkdir $ROOTFS_TMP_DIR
55if [ "$?" != 0 ]; then
56 lcdprint 0,15 "ERROR: mkdir failed"
57 sleep 3
58 exit 0
59fi
60
61# If there is an ext4 mounter, try it. Otherwise or on failure, try ext3 and
62# then ext2.
63# NOTE some platforms probably use an mtd and this might need some fixing
64if [ -e /usr/local/bin/icx_mount.ext4 ]; then
65 /usr/local/bin/icx_mount.ext4 $COMMON_ROOTFS_PARTITION $ROOTFS_TMP_DIR
66else
67 false
68fi
69if [ "$?" != 0 ]; then
70 mount -t ext3 $COMMON_ROOTFS_PARTITION $ROOTFS_TMP_DIR
71fi
72if [ "$?" != 0 ]; then
73 mount -t ext2 $COMMON_ROOTFS_PARTITION $ROOTFS_TMP_DIR
74fi
75if [ "$?" != 0 ]; then
76 lcdprint 0,15 "ERROR: mount failed"
77 sleep 3
78 exit 0
79fi
80
81# the installer renames the OF to $SPIDERAPP_PATH.of so if it does not exists
82# print an error
83lcdprint 0,8 "Restore OF"
84if [ ! -e $SPIDERAPP_PATH.of ]; then
85 lcdprint 0,15 "ERROR: cannot find OF"
86 lcdprint 0,16 "ERROR: is Rockbox installed?"
87 sleep 3
88 exit 0
89fi
90# restore the OF
91mv $SPIDERAPP_PATH.of $SPIDERAPP_PATH
92if [ "$?" != 0 ]; then
93 lcdprint 0,15 "ERROR: restore failed"
94 sleep 3
95 exit 0
96fi
97
98# unmount root partition
99lcdprint 0,11 "Unmount root filesystem"
100sync
101if [ "$?" != 0 ]; then
102 umount "$ROOTFS_TMP_DIR"
103 lcdprint 0,15 "ERROR: sync failed"
104 sleep 3
105 exit 0
106fi
107
108umount $ROOTFS_TMP_DIR
109if [ "$?" != 0 ]; then
110 lcdprint 0,15 "ERROR: umount failed"
111 sleep 3
112 exit 0
113fi
114
115# Success screen
116lcdprint 0,15 "Rebooting in 3 seconds."
117sleep 3
118sync
119
120echo "Uninstallation successful"
121# finish
122exit 0