summaryrefslogtreecommitdiffstats
path: root/rbutil
diff options
context:
space:
mode:
Diffstat (limited to 'rbutil')
-rw-r--r--rbutil/mknwzboot/Makefile9
-rw-r--r--rbutil/mknwzboot/install_script.sh51
-rw-r--r--rbutil/mknwzboot/main.c29
-rw-r--r--rbutil/mknwzboot/mknwzboot.c60
-rw-r--r--rbutil/mknwzboot/mknwzboot.h1
-rw-r--r--rbutil/mknwzboot/uninstall_script.sh122
6 files changed, 247 insertions, 25 deletions
diff --git a/rbutil/mknwzboot/Makefile b/rbutil/mknwzboot/Makefile
index 9530ac369e..fd80106b83 100644
--- a/rbutil/mknwzboot/Makefile
+++ b/rbutil/mknwzboot/Makefile
@@ -18,7 +18,7 @@ OUTPUT = mknwzboot
# inputs for lib
UPGTOOLS_SOURCES = misc.c upg.c fwp.c mg.cpp md5.cpp
-LIBSOURCES := mknwzboot.c install_script.c \
+LIBSOURCES := mknwzboot.c install_script.c uninstall_script.c \
$(addprefix $(UPGTOOLS_DIR),$(UPGTOOLS_SOURCES))
# inputs for binary only
SOURCES := $(LIBSOURCES) main.c
@@ -30,6 +30,9 @@ include ../libtools.make
install_script.c install_script.h: install_script.sh $(BIN2C)
$(BIN2C) install_script.sh install_script
+uninstall_script.c uninstall_script.h: uninstall_script.sh $(BIN2C)
+ $(BIN2C) uninstall_script.sh uninstall_script
+
# explicit dependencies on install_script.{c,h} and mknwzboot.h
-$(OBJDIR)mknwzboot.o: install_script.h install_script.c mknwzboot.h
-$(OBJDIR)main.o: install_script.h install_script.c main.c mknwzboot.h
+$(OBJDIR)mknwzboot.o: install_script.h install_script.c uninstall_script.h uninstall_script.c mknwzboot.h
+$(OBJDIR)main.o: main.c mknwzboot.h
diff --git a/rbutil/mknwzboot/install_script.sh b/rbutil/mknwzboot/install_script.sh
index 18296d257e..76bd12c4d5 100644
--- a/rbutil/mknwzboot/install_script.sh
+++ b/rbutil/mknwzboot/install_script.sh
@@ -1,5 +1,11 @@
#!/bin/sh
+# NOTE: busybox is using ash, a very posix and very pedantic shell, make sure
+# you test your scripts with
+# busybox sh -n <script>
+# and if you really, really don't want to download busybox to try it, then go
+# ahead and brick your device
+
# The updater script on the NWZ has a major bug/feature:
# it does NOT clear the update flag if the update scrit fails
# thus causing a update/reboot loop and a bricked device
@@ -13,14 +19,24 @@ cd /tmp
CONTENTS="/contents"
CONTENTS_PART=`mount | grep contents | awk '{ print $1 }'`
-lcdmsg -c -f /usr/local/bin/font_08x12.bmp -l 0,3 "Contents partition:\n$CONTENTS_PART"
+# print a message to the screen and also on the standard output
+# lcdprint x,y msg
+lcdprint ()
+{
+ echo $2
+ lcdmsg -f /usr/local/bin/font_08x12.bmp -l $1 "$2"
+}
+
+# clear screen
+lcdmsg -c ""
+lcdprint 0,3 "Contents partition:\n$CONTENTS_PART"
# We need to remount the contents partition in read-write mode be able to
# write something on it
-lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,6 "Remount $CONTENTS rw"
+lcdprint 0,6 "Remount $CONTENTS rw"
mount -o remount,rw $CONTENTS_PART $CONTENTS
if [ "$?" != 0 ]; then
- lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "ERROR: remount failed"
+ lcdprint 0,15 "ERROR: remount failed"
sleep 3
exit 0
fi
@@ -35,10 +51,10 @@ ROOTFS_TMP_DIR=/tmp/rootfs
SPIDERAPP_PATH=$ROOTFS_TMP_DIR/usr/local/bin/SpiderApp
# mount root partition
-lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,7 "Mount root filesystem"
+lcdprint 0,7 "Mount root filesystem"
mkdir $ROOTFS_TMP_DIR
if [ "$?" != 0 ]; then
- lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "ERROR: mkdir failed"
+ lcdprint 0,15 "ERROR: mkdir failed"
sleep 3
exit 0
fi
@@ -58,13 +74,13 @@ if [ "$?" != 0 ]; then
mount -t ext2 $COMMON_ROOTFS_PARTITION $ROOTFS_TMP_DIR
fi
if [ "$?" != 0 ]; then
- lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "ERROR: mount failed"
+ lcdprint 0,15 "ERROR: mount failed"
sleep 3
exit 0
fi
# rename the previous main application unless there is already a copy
-lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,8 "Backup OF"
+lcdprint 0,8 "Backup OF"
if [ ! -e $SPIDERAPP_PATH.of ]; then
mv $SPIDERAPP_PATH $SPIDERAPP_PATH.of
fi
@@ -75,12 +91,12 @@ fi
#
# we need a small trick here: we want to pipe directly the output of the decryption
# tool to tar, to avoid using space in /tmp/ or on the user partition
-lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,9 "Install rockbox"
+lcdprint 0,9 "Install rockbox"
FIFO_FILE=/tmp/rb.fifo
mkfifo $FIFO_FILE
if [ "$?" != 0 ]; then
umount "$ROOTFS_TMP_DIR"
- lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "ERROR: cannot create fifo"
+ lcdprint 0,15 "ERROR: cannot create fifo"
sleep 3
exit 0
fi
@@ -89,7 +105,7 @@ fwpchk -f /contents/$_UPDATE_FN_.UPG -c -1 $FIFO_FILE &
tar -C $ROOTFS_TMP_DIR -xvf $FIFO_FILE
if [ "$?" != 0 ]; then
umount "$ROOTFS_TMP_DIR"
- lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "ERROR: extraction failed"
+ lcdprint 0,15 "ERROR: extraction failed"
sleep 3
exit 0
fi
@@ -97,46 +113,45 @@ fi
wait
if [ "$?" != 0 ]; then
umount "$ROOTFS_TMP_DIR"
- lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "ERROR: no file to extract"
+ lcdprint 0,15 "ERROR: no file to extract"
sleep 3
exit 0
fi
# create a symlink from /.rockbox to /contents/.rockbox (see dualboot code
# for why)
-lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,10 "Create rockbox symlink"
+lcdprint 0,10 "Create rockbox symlink"
rm -f "$ROOTFS_TMP_DIR/.rockbox"
ln -s "$CONTENTS/.rockbox" "$ROOTFS_TMP_DIR/.rockbox"
if [ "$?" != 0 ]; then
umount "$ROOTFS_TMP_DIR"
- lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "ERROR: cannot create rockbox symlink"
+ lcdprint 0,15 "ERROR: cannot create rockbox symlink"
sleep 3
exit 0
fi
# unmount root partition
-lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,11 "Unmount root filesystem"
+lcdprint 0,11 "Unmount root filesystem"
sync
if [ "$?" != 0 ]; then
umount "$ROOTFS_TMP_DIR"
- lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "ERROR: sync failed"
+ lcdprint 0,15 "ERROR: sync failed"
sleep 3
exit 0
fi
umount $ROOTFS_TMP_DIR
if [ "$?" != 0 ]; then
- lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "ERROR: umount failed"
+ lcdprint 0,15 "ERROR: umount failed"
sleep 3
exit 0
fi
# Success screen
-lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "Rebooting in 3 seconds."
+lcdprint 0,15 "Rebooting in 3 seconds."
sleep 3
sync
echo "Installation successful"
# finish
exit 0
-
diff --git a/rbutil/mknwzboot/main.c b/rbutil/mknwzboot/main.c
index a36c24eaf5..491a18043b 100644
--- a/rbutil/mknwzboot/main.c
+++ b/rbutil/mknwzboot/main.c
@@ -34,6 +34,8 @@ static void usage(void)
printf(" -b <file> Set boot file\n");
printf(" -d/--debug Enable debug output\n");
printf(" -x Dump device informations\n");
+ printf(" -u Create uninstall update\n");
+ printf(" -m <model> Specify model\n");
exit(1);
}
@@ -42,6 +44,8 @@ int main(int argc, char *argv[])
char *outfile = NULL;
char *bootfile = NULL;
bool debug = false;
+ bool install = true;
+ const char *model = NULL;
if(argc == 1)
usage();
@@ -55,10 +59,12 @@ int main(int argc, char *argv[])
{"boot-file", required_argument, 0, 'b'},
{"debug", no_argument, 0, 'd'},
{"dev-info", no_argument, 0, 'x'},
+ {"uninstall", no_argument, 0, 'u'},
+ {"model", required_argument, 0, 'm'},
{0, 0, 0, 0}
};
- int c = getopt_long(argc, argv, "ho:b:dx", long_options, NULL);
+ int c = getopt_long(argc, argv, "ho:b:dxum:", long_options, NULL);
if(c == -1)
break;
switch(c)
@@ -77,6 +83,12 @@ int main(int argc, char *argv[])
break;
case 'x':
dump_nwz_dev_info("");
+ return 0;
+ case 'u':
+ install = false;
+ break;
+ case 'm':
+ model = optarg;
break;
default:
abort();
@@ -88,9 +100,14 @@ int main(int argc, char *argv[])
printf("You must specify an output file\n");
return 1;
}
- if(!bootfile)
+ if(install && !bootfile)
+ {
+ printf("You must specify a boot file for installation\n");
+ return 1;
+ }
+ if(!install && !model)
{
- printf("You must specify a boot file\n");
+ printf("You must provide a model for uninstallation\n");
return 1;
}
if(optind != argc)
@@ -99,7 +116,11 @@ int main(int argc, char *argv[])
return 1;
}
- int err = mknwzboot(bootfile, outfile, debug);
+ int err;
+ if(install)
+ err = mknwzboot(bootfile, outfile, debug);
+ else
+ err = mknwzboot_uninst(model, outfile, debug);
printf("Result: %d\n", err);
return err;
}
diff --git a/rbutil/mknwzboot/mknwzboot.c b/rbutil/mknwzboot/mknwzboot.c
index b41692c9fd..2e574a94d7 100644
--- a/rbutil/mknwzboot/mknwzboot.c
+++ b/rbutil/mknwzboot/mknwzboot.c
@@ -27,6 +27,7 @@
#include "upg.h"
#include "install_script.h"
+#include "uninstall_script.h"
struct nwz_model_desc_t
{
@@ -145,6 +146,24 @@ static int find_model(uint8_t *boot, size_t boot_size)
return model;
}
+static int find_model2(const char *model_str)
+{
+ /* since it can be confusing for the user, we accept both rbmodel and codename */
+ /* find model by comparing magic scramble value */
+ int model = 0;
+ for(; model < NR_NWZ_MODELS; model++)
+ if(strcmp(nwz_models[model].rb_model_name, model_str) == 0 ||
+ strcmp(nwz_models[model].codename, model_str) == 0)
+ break;
+ if(model == NR_NWZ_MODELS)
+ {
+ printf("[ERR] Unknown model: %s\n", model_str);
+ return -1;
+ }
+ printf("[INFO] Bootloader file for %s\n", nwz_models[model].model_name);
+ return model;
+}
+
static bool get_model_keysig(int model, char key[NWZ_KEY_SIZE], char sig[NWZ_SIG_SIZE])
{
const char *codename = nwz_models[model].codename;
@@ -231,3 +250,44 @@ int mknwzboot(const char *bootfile, const char *outfile, bool debug)
free(upg_buf);
return 0;
}
+
+int mknwzboot_uninst(const char *model_string, const char *outfile, bool debug)
+{
+ /* check that it is a valid scrambled file */
+ int model = find_model2(model_string);
+ if(model < 0)
+ {
+ printf("[ERR] Invalid model\n");
+ return 2;
+ }
+ /* find keys */
+ char key[NWZ_KEY_SIZE];
+ char sig[NWZ_SIG_SIZE];
+ if(!get_model_keysig(model, key, sig))
+ {
+ printf("[ERR][INTERNAL] Cannot get keys for model\n");
+ return 3;
+ }
+ /* create the upg file */
+ struct upg_file_t *upg = upg_new();
+ /* first file is the uninstall script: we have to copy data because upg_free()
+ * will free it */
+ upg_append(upg, memdup(uninstall_script, LEN_uninstall_script), LEN_uninstall_script);
+ /* write file to buffer */
+ size_t upg_size;
+ void *upg_buf = upg_write_memory(upg, key, sig, &upg_size, &debug, nwz_printf);
+ upg_free(upg);
+ if(upg_buf == NULL)
+ {
+ printf("[ERR] Cannot create UPG file\n");
+ return 4;
+ }
+ if(!write_file(outfile, upg_buf, upg_size))
+ {
+ free(upg_buf);
+ printf("[ERR] Cannpt write UPG file\n");
+ return 5;
+ }
+ free(upg_buf);
+ return 0;
+}
diff --git a/rbutil/mknwzboot/mknwzboot.h b/rbutil/mknwzboot/mknwzboot.h
index f46dd75d5c..31f2c6355e 100644
--- a/rbutil/mknwzboot/mknwzboot.h
+++ b/rbutil/mknwzboot/mknwzboot.h
@@ -33,6 +33,7 @@ extern "C" {
void dump_nwz_dev_info(const char *prefix);
/* return 0 on success */
int mknwzboot(const char *bootfile, const char *outfile, bool debug);
+int mknwzboot_uninst(const char *model, const char *outfile, bool debug);
#ifdef __cplusplus
}
diff --git a/rbutil/mknwzboot/uninstall_script.sh b/rbutil/mknwzboot/uninstall_script.sh
new file mode 100644
index 0000000000..0e409c63cd
--- /dev/null
+++ b/rbutil/mknwzboot/uninstall_script.sh
@@ -0,0 +1,122 @@
+#!/bin/sh
+
+# NOTE: busybox is using ash, a very posix and very pedantic shell, make sure
+# you test your scripts with
+# busybox sh -n <script>
+# and if you really, really don't want to download busybox to try it, then go
+# ahead and brick your device
+
+# The updater script on the NWZ has a major bug/feature:
+# it does NOT clear the update flag if the update scrit fails
+# thus causing a update/reboot loop and a bricked device
+# always clear to make sure we don't end up being screwed
+nvpflag fup 0xFFFFFFFF
+
+# go to /tmp
+cd /tmp
+
+# get content partition path
+CONTENTS="/contents"
+CONTENTS_PART=`mount | grep contents | awk '{ print $1 }'`
+
+# print a message to the screen and also on the standard output
+# lcdprint x,y msg
+lcdprint ()
+{
+ echo $2
+ lcdmsg -f /usr/local/bin/font_08x12.bmp -l $1 "$2"
+}
+
+# clear screen
+lcdmsg -c ""
+lcdprint 0,3 "Contents partition:\n$CONTENTS_PART"
+
+# We need to remount the contents partition in read-write mode be able to
+# write something on it
+lcdprint 0,6 "Remount $CONTENTS rw"
+mount -o remount,rw $CONTENTS_PART $CONTENTS
+if [ "$?" != 0 ]; then
+ lcdprint 0,15 "ERROR: remount failed"
+ sleep 3
+ exit 0
+fi
+
+# redirect all output to a log file
+exec > "$CONTENTS/uninstall_dualboot_log.txt" 2>&1
+
+# import constants
+. /install_script/constant.txt
+ROOTFS_TMP_DIR=/tmp/rootfs
+SPIDERAPP_PATH=$ROOTFS_TMP_DIR/usr/local/bin/SpiderApp
+
+# mount root partition
+lcdprint 0,7 "Mount root filesystem"
+mkdir $ROOTFS_TMP_DIR
+if [ "$?" != 0 ]; then
+ lcdprint 0,15 "ERROR: mkdir failed"
+ sleep 3
+ exit 0
+fi
+
+# If there is an ext4 mounter, try it. Otherwise or on failure, try ext3 and
+# then ext2.
+# NOTE some platforms probably use an mtd and this might need some fixing
+if [ -e /usr/local/bin/icx_mount.ext4 ]; then
+ /usr/local/bin/icx_mount.ext4 $COMMON_ROOTFS_PARTITION $ROOTFS_TMP_DIR
+else
+ false
+fi
+if [ "$?" != 0 ]; then
+ mount -t ext3 $COMMON_ROOTFS_PARTITION $ROOTFS_TMP_DIR
+fi
+if [ "$?" != 0 ]; then
+ mount -t ext2 $COMMON_ROOTFS_PARTITION $ROOTFS_TMP_DIR
+fi
+if [ "$?" != 0 ]; then
+ lcdprint 0,15 "ERROR: mount failed"
+ sleep 3
+ exit 0
+fi
+
+# the installer renames the OF to $SPIDERAPP_PATH.of so if it does not exists
+# print an error
+lcdprint 0,8 "Restore OF"
+if [ ! -e $SPIDERAPP_PATH.of ]; then
+ lcdprint 0,15 "ERROR: cannot find OF"
+ lcdprint 0,16 "ERROR: is Rockbox installed?"
+ sleep 3
+ exit 0
+fi
+# restore the OF
+mv $SPIDERAPP_PATH.of $SPIDERAPP_PATH
+if [ "$?" != 0 ]; then
+ lcdprint 0,15 "ERROR: restore failed"
+ sleep 3
+ exit 0
+fi
+
+# unmount root partition
+lcdprint 0,11 "Unmount root filesystem"
+sync
+if [ "$?" != 0 ]; then
+ umount "$ROOTFS_TMP_DIR"
+ lcdprint 0,15 "ERROR: sync failed"
+ sleep 3
+ exit 0
+fi
+
+umount $ROOTFS_TMP_DIR
+if [ "$?" != 0 ]; then
+ lcdprint 0,15 "ERROR: umount failed"
+ sleep 3
+ exit 0
+fi
+
+# Success screen
+lcdprint 0,15 "Rebooting in 3 seconds."
+sleep 3
+sync
+
+echo "Uninstallation successful"
+# finish
+exit 0