summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--utils/nwztools/plattools/Makefile5
-rw-r--r--utils/nwztools/plattools/dualboot.c181
-rw-r--r--utils/nwztools/plattools/nwz_lib.c39
-rw-r--r--utils/nwztools/plattools/nwz_lib.h5
-rw-r--r--utils/nwztools/scripts/Makefile6
-rw-r--r--utils/nwztools/scripts/exec_file.sh4
-rw-r--r--utils/nwztools/scripts/install_dualboot.sh129
7 files changed, 363 insertions, 6 deletions
diff --git a/utils/nwztools/plattools/Makefile b/utils/nwztools/plattools/Makefile
index 8251afaf0a..f4e88cd778 100644
--- a/utils/nwztools/plattools/Makefile
+++ b/utils/nwztools/plattools/Makefile
@@ -7,7 +7,7 @@ INCLUDES=-I.
7LIB_FILES=nwz_lib.c nwz_lib_devlist.c 7LIB_FILES=nwz_lib.c nwz_lib_devlist.c
8TOOL_FILES=dest_tool.c test_adc.c test_adc.c test_bl.c test_display.c \ 8TOOL_FILES=dest_tool.c test_adc.c test_adc.c test_bl.c test_display.c \
9 test_keys.c test_power.c test_ts.c 9 test_keys.c test_power.c test_ts.c
10ALL_ELF=$(patsubst %.c,%.elf,$(TOOL_FILES)) all_tools.elf 10ALL_ELF=$(patsubst %.c,%.elf,$(TOOL_FILES)) all_tools.elf dualboot.elf
11 11
12all: $(ALL_ELF) 12all: $(ALL_ELF)
13 13
@@ -17,5 +17,8 @@ all: $(ALL_ELF)
17all_tools.elf: all_tools.c $(TOOL_FILES) $(LIB_FILES) 17all_tools.elf: all_tools.c $(TOOL_FILES) $(LIB_FILES)
18 $(CC) $(CFLAGS) -DNWZ_EMBED_TOOLS $(INCLUDES) -o $@ $^ 18 $(CC) $(CFLAGS) -DNWZ_EMBED_TOOLS $(INCLUDES) -o $@ $^
19 19
20dualboot.elf: dualboot.c all_tools.c $(TOOL_FILES) $(LIB_FILES)
21 $(CC) $(CFLAGS) -DNWZ_DUALBOOT -DNWZ_EMBED_TOOLS $(INCLUDES) -o $@ $^
22
20clean: 23clean:
21 rm -rf $(ALL_ELF) 24 rm -rf $(ALL_ELF)
diff --git a/utils/nwztools/plattools/dualboot.c b/utils/nwztools/plattools/dualboot.c
new file mode 100644
index 0000000000..965fabed72
--- /dev/null
+++ b/utils/nwztools/plattools/dualboot.c
@@ -0,0 +1,181 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Amaury Pouly
11 *
12 * Based on Rockbox iriver bootloader by Linus Nielsen Feltzing
13 * and the ipodlinux bootloader by Daniel Palffy and Bernard Leach
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24#include "nwz_lib.h"
25#include "nwz_plattools.h"
26#include <time.h>
27
28/* Important Note: this bootloader is carefully written so that in case of
29 * error, the OF is run. This seems like the safest option since the OF is
30 * always there and might do magic things. */
31
32bool boot_rockbox(void)
33{
34 /* get time */
35 struct timeval deadline;
36 if(gettimeofday(&deadline, NULL) != 0)
37 {
38 nwz_lcdmsg(false, 0, 2, "Cannot get time");
39 sleep(2);
40 return false;
41 }
42 /* open input device */
43 int input_fd = nwz_key_open();
44 if(input_fd < 0)
45 {
46 nwz_lcdmsg(false, 0, 2, "Cannot open input device");
47 sleep(2);
48 return false;
49 }
50 deadline.tv_sec += 5;
51 /* wait for user action */
52 bool boot_rb = false;
53 while(true)
54 {
55 /* get time */
56 struct timeval cur_time;
57 if(gettimeofday(&cur_time, NULL) != 0)
58 {
59 nwz_lcdmsg(false, 0, 4, "Cannot get time");
60 sleep(2);
61 break;
62 }
63 /* check timeout */
64 if(cur_time.tv_sec > deadline.tv_sec)
65 break;
66 if(cur_time.tv_sec == deadline.tv_sec && cur_time.tv_usec >= deadline.tv_usec)
67 break;
68 /* print message */
69 int sec_left = deadline.tv_sec - cur_time.tv_sec;
70 sec_left += (deadline.tv_usec - cur_time.tv_usec + 999999) / 1000000; /* round up */
71 nwz_lcdmsgf(false, 0, 2, "Booting OF in %d seconds ", sec_left);
72 nwz_lcdmsg(false, 0, 3, "Press BACK to boot RB");
73 /* wait for a key (1s) */
74 int ret = nwz_key_wait_event(input_fd, 1000000);
75 if(ret != 1)
76 continue;
77 struct input_event evt;
78 if(nwz_key_read_event(input_fd, &evt) != 1)
79 continue;
80 if(nwz_key_event_get_keycode(&evt) == NWZ_KEY_BACK && !nwz_key_event_is_press(&evt))
81 {
82 boot_rb = true;
83 break;
84 }
85 }
86 nwz_key_close(input_fd);
87 return boot_rb;
88}
89
90static char *boot_rb_argv[] =
91{
92 "lcdmsg",
93 "-c",
94 "-l",
95 "0,3",
96 "Hello from RB",
97 NULL
98};
99
100static void wait_key(void)
101{
102 int input_fd = nwz_key_open();
103 /* display input state in a loop */
104 while(1)
105 {
106 /* wait for event (10ms) */
107 int ret = nwz_key_wait_event(input_fd, 10000);
108 if(ret != 1)
109 continue;
110 struct input_event evt;
111 if(nwz_key_read_event(input_fd, &evt) != 1)
112 continue;
113 if(nwz_key_event_get_keycode(&evt) == NWZ_KEY_BACK && !nwz_key_event_is_press(&evt))
114 break;
115 }
116 /* finish nicely */
117 nwz_key_close(input_fd);
118}
119
120int NWZ_TOOL_MAIN(all_tools)(int argc, char **argv);
121
122int main(int argc, char **argv)
123{
124#if 0
125 nwz_lcdmsg(true, 0, 0, "dualboot");
126 if(boot_rockbox())
127 {
128 /* boot rockox */
129 nwz_lcdmsg(true, 0, 3, "Booting rockbox...");
130 execvp("/usr/local/bin/lcdmsg", boot_rb_argv);
131 nwz_lcdmsg(false, 0, 4, "failed.");
132 sleep(5);
133 }
134 /* if for some reason, running rockbox failed, then try to run the OF */
135 /* boot OF */
136 nwz_lcdmsg(true, 0, 3, "Booting OF...");
137 execvp("/usr/local/bin/SpiderApp.of", argv);
138 nwz_lcdmsg(false, 0, 4, "failed.");
139 sleep(5);
140 /* if we reach this point, everything failed, so return an error so that
141 * sysmgrd knows something is wrong */
142 return 1;
143#elif 0
144 const char *args_mount[] = {"mount", NULL};
145 int status;
146 char *output = nwz_run_pipe("mount", args_mount, &status);
147 nwz_lcdmsgf(true, 0, 0, "%d\n%s", status, output);
148 free(output);
149 wait_key();
150 const char *args_ls[] = {"ls", "/var", NULL};
151 output = nwz_run_pipe("ls", args_ls, &status);
152 nwz_lcdmsgf(true, 0, 0, "%d\n%s", status, output);
153 free(output);
154 wait_key();
155 const char *args_glogctl[] = {"glogctl", "flush", NULL};
156 output = nwz_run_pipe("/usr/local/bin/glogctl", args_glogctl, &status);
157 nwz_lcdmsgf(true, 0, 0, "%d\n%s", status, output);
158 free(output);
159 wait_key();
160 system("cp /var/GEMINILOG* /contents/");
161 sync();
162 execvp("/usr/local/bin/SpiderApp.of", argv);
163 return 0;
164#else
165 /* make sure backlight is on */
166 int fb_fd = nwz_fb_open(true);
167 if(fb_fd >= 0)
168 {
169 struct nwz_fb_brightness bl;
170 nwz_fb_get_brightness(fb_fd, &bl);
171 bl.level = NWZ_FB_BL_MAX_LEVEL;
172 nwz_fb_set_brightness(fb_fd, &bl);
173 nwz_fb_close(fb_fd);
174 }
175 /* run all tools menu */
176 NWZ_TOOL_MAIN(all_tools)(argc, argv);
177 /* run OF */
178 execvp("/usr/local/bin/SpiderApp.of", argv);
179 return 0;
180#endif
181}
diff --git a/utils/nwztools/plattools/nwz_lib.c b/utils/nwztools/plattools/nwz_lib.c
index 4f49bec909..087db8834a 100644
--- a/utils/nwztools/plattools/nwz_lib.c
+++ b/utils/nwztools/plattools/nwz_lib.c
@@ -30,7 +30,7 @@ const char *nwz_get_model_name(unsigned long model_id)
30 return NULL; 30 return NULL;
31} 31}
32 32
33void nwz_run(const char *file, const char *args[], bool wait) 33int nwz_run(const char *file, const char *args[], bool wait)
34{ 34{
35 pid_t child_pid = fork(); 35 pid_t child_pid = fork();
36 if(child_pid != 0) 36 if(child_pid != 0)
@@ -39,7 +39,10 @@ void nwz_run(const char *file, const char *args[], bool wait)
39 { 39 {
40 int status; 40 int status;
41 waitpid(child_pid, &status, 0); 41 waitpid(child_pid, &status, 0);
42 return status;
42 } 43 }
44 else
45 return 0;
43 } 46 }
44 else 47 else
45 { 48 {
@@ -48,6 +51,40 @@ void nwz_run(const char *file, const char *args[], bool wait)
48 } 51 }
49} 52}
50 53
54char *nwz_run_pipe(const char *file, const char *args[], int *status)
55{
56 int pipe_fds[2];
57 pipe(pipe_fds);
58 pid_t child_pid = fork();
59 if(child_pid == 0)
60 {
61 dup2(pipe_fds[1], 1); /* redirect stdout */
62 dup2(pipe_fds[1], 2); /* redirect stderr */
63 close(pipe_fds[0]); /* close reading */
64 close(pipe_fds[1]); /* close writing */
65 execvp(file, (char * const *)args);
66 _exit(1);
67 }
68 else
69 {
70 close(pipe_fds[1]); /* close writing */
71 char buffer[1024];
72 char *output = malloc(1);
73 ssize_t count;
74 size_t size = 0;
75 while((count = read(pipe_fds[0], buffer, sizeof(buffer))) > 0)
76 {
77 output = realloc(output, size + count + 1);
78 memcpy(output + size, buffer, count);
79 size += count;
80 }
81 close(pipe_fds[0]);
82 output[size] = 0;
83 waitpid(child_pid, status, 0);
84 return output;
85 }
86}
87
51void nwz_lcdmsg(bool clear, int x, int y, const char *msg) 88void nwz_lcdmsg(bool clear, int x, int y, const char *msg)
52{ 89{
53 const char *path_lcdmsg = "/usr/local/bin/lcdmsg"; 90 const char *path_lcdmsg = "/usr/local/bin/lcdmsg";
diff --git a/utils/nwztools/plattools/nwz_lib.h b/utils/nwztools/plattools/nwz_lib.h
index 90d122003a..df0105a13d 100644
--- a/utils/nwztools/plattools/nwz_lib.h
+++ b/utils/nwztools/plattools/nwz_lib.h
@@ -30,6 +30,7 @@
30#include <linux/input.h> 30#include <linux/input.h>
31#include <fcntl.h> 31#include <fcntl.h>
32#include <string.h> 32#include <string.h>
33#include <stdlib.h>
33 34
34#include "nwz_keys.h" 35#include "nwz_keys.h"
35#include "nwz_fb.h" 36#include "nwz_fb.h"
@@ -47,7 +48,9 @@ const char *nwz_get_model_name(unsigned long model_id);
47 48
48/* run a program and exit with nonzero status in case of error 49/* run a program and exit with nonzero status in case of error
49 * argument list must be NULL terminated */ 50 * argument list must be NULL terminated */
50void nwz_run(const char *file, const char *args[], bool wait); 51int nwz_run(const char *file, const char *args[], bool wait);
52/* run a program and return program output */
53char *nwz_run_pipe(const char *file, const char *args[], int *status);
51 54
52/* invoke /usr/bin/lcdmsg to display a message using the small font, optionally 55/* invoke /usr/bin/lcdmsg to display a message using the small font, optionally
53 * clearing the screen before */ 56 * clearing the screen before */
diff --git a/utils/nwztools/scripts/Makefile b/utils/nwztools/scripts/Makefile
index 207534a006..345fd0f4cb 100644
--- a/utils/nwztools/scripts/Makefile
+++ b/utils/nwztools/scripts/Makefile
@@ -11,6 +11,7 @@ all:
11 @echo "- exec_file: craft an upgrade that embeds and execute a file" 11 @echo "- exec_file: craft an upgrade that embeds and execute a file"
12 @echo "- exec_file_extern: craft an upgrade that execute a file on the user partition" 12 @echo "- exec_file_extern: craft an upgrade that execute a file on the user partition"
13 @echo "- list_targets: produce of list of available targets" 13 @echo "- list_targets: produce of list of available targets"
14 @echo "- install_dualboot"
14 15
15ifndef UPG 16ifndef UPG
16want_upg: 17want_upg:
@@ -33,7 +34,7 @@ endif
33ifndef NWZ_TARGET 34ifndef NWZ_TARGET
34want_target: 35want_target:
35 $(info Please set NWZ_TARGET to your target. For example:) 36 $(info Please set NWZ_TARGET to your target. For example:)
36 $(info make dump_rootfs NWZ_TARGET=nwz-e463) 37 $(info make dump_rootfs NWZ_TARGET=nwz-e460)
37 $(info Run 'make list_targets' to get a list of all targets) 38 $(info Run 'make list_targets' to get a list of all targets)
38 $(error "") 39 $(error "")
39else 40else
@@ -72,6 +73,9 @@ UPGPACK=$(upgtool) -c -m $(NWZ_TARGET) $(UPG) $(1)
72exec_file: want_target want_exec want_upg 73exec_file: want_target want_exec want_upg
73 $(call UPGPACK, exec_file.sh $(EXEC)) 74 $(call UPGPACK, exec_file.sh $(EXEC))
74 75
76install_dualboot: want_target want_exec want_upg
77 $(call UPGPACK, install_dualboot.sh $(EXEC))
78
75exec_file_extern.tmp: want_exec want_upg want_log 79exec_file_extern.tmp: want_exec want_upg want_log
76 cat exec_file_extern.sh.in | sed "s|NWZ_EXEC_THIS|$(EXEC)|" |\ 80 cat exec_file_extern.sh.in | sed "s|NWZ_EXEC_THIS|$(EXEC)|" |\
77 sed "s|NWZ_LOG_THIS|$(LOG)|" > $@ 81 sed "s|NWZ_LOG_THIS|$(LOG)|" > $@
diff --git a/utils/nwztools/scripts/exec_file.sh b/utils/nwztools/scripts/exec_file.sh
index a624e4df35..b005156c37 100644
--- a/utils/nwztools/scripts/exec_file.sh
+++ b/utils/nwztools/scripts/exec_file.sh
@@ -20,7 +20,7 @@ CONTENTS_PART=`mount | grep contents | awk '{ print $1 }'`
20 20
21lcdmsg -c -f /usr/local/bin/font_08x12.bmp -l 0,3 "Contents partition:\n$CONTENTS_PART" 21lcdmsg -c -f /usr/local/bin/font_08x12.bmp -l 0,3 "Contents partition:\n$CONTENTS_PART"
22 22
23# 2) We need to remount the contents partition in read-write mode be able to 23# We need to remount the contents partition in read-write mode be able to
24# write something on it 24# write something on it
25lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,6 "Remount $CONTENTS rw" 25lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,6 "Remount $CONTENTS rw"
26if ! mount -o remount,rw $CONTENTS_PART $CONTENTS 26if ! mount -o remount,rw $CONTENTS_PART $CONTENTS
@@ -55,7 +55,7 @@ fi
55lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,7 "Running file..." 55lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,7 "Running file..."
56/tmp/exec >$CONTENTS/exec.txt 2>&1 56/tmp/exec >$CONTENTS/exec.txt 2>&1
57 57
58# 4) Success screen 58# Success screen
59lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "Rebooting in 3 seconds." 59lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "Rebooting in 3 seconds."
60sleep 3 60sleep 3
61sync 61sync
diff --git a/utils/nwztools/scripts/install_dualboot.sh b/utils/nwztools/scripts/install_dualboot.sh
new file mode 100644
index 0000000000..ece5b9e3a3
--- /dev/null
+++ b/utils/nwztools/scripts/install_dualboot.sh
@@ -0,0 +1,129 @@
1#!/bin/sh
2
3# The updater script on the NWZ has a major bug/feature:
4# it does NOT clear the update flag if the update scrit fails
5# thus causing a update/reboot loop and a bricked device
6# always clear to make sure we don't end up being screwed
7nvpflag fup 0xFFFFFFFF
8
9#
10# FIXME document this
11#
12
13
14# go to /tmp
15cd /tmp
16
17# get content partition path
18CONTENTS="/contents"
19CONTENTS_PART=`mount | grep contents | awk '{ print $1 }'`
20
21lcdmsg -c -f /usr/local/bin/font_08x12.bmp -l 0,3 "Contents partition:\n$CONTENTS_PART"
22
23# We need to remount the contents partition in read-write mode be able to
24# write something on it
25lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,6 "Remount $CONTENTS rw"
26mount -o remount,rw $CONTENTS_PART $CONTENTS
27if [ "$?" != 0 ]; then
28 lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "ERROR: remount failed"
29 sleep 3
30 exit 0
31fi
32
33# import constants
34. /install_script/constant.txt
35_UPDATE_FN_=`nvpstr ufn`
36ROOTFS_TMP_DIR=/tmp/rootfs
37ROCKBOX_NAME=Rockbox
38ROCKBOX_PATH=$ROOTFS_TMP_DIR/usr/local/bin/$ROCKBOX_NAME
39SPIDERAPP_PATH=$ROOTFS_TMP_DIR/usr/local/bin/SpiderApp
40
41# mount root partition
42lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,7 "Mount root filesystem"
43mkdir $ROOTFS_TMP_DIR
44if [ "$?" != 0 ]; then
45 lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "ERROR: mkdir failed"
46 sleep 3
47 exit 0
48fi
49
50# NOTE some platforms use ext3 and some ext4 with a custom mount program
51# (/usr/local/bin/icx_mount.ext4), some probably use an mtd too
52mount -t ext2 $COMMON_ROOTFS_PARTITION $ROOTFS_TMP_DIR
53if [ "$?" != 0 ]; then
54 lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "ERROR: mount failed"
55 sleep 3
56 exit 0
57fi
58
59# rename the previous main application unless there is already a copy
60lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,8 "Backup OF"
61if [ ! -e $SPIDERAPP_PATH.of ]; then
62 mv $SPIDERAPP_PATH $SPIDERAPP_PATH.of
63fi
64
65# extract our payload executable
66lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,9 "Install rockbox"
67fwpchk -f /contents/$_UPDATE_FN_.UPG -c -1 $SPIDERAPP_PATH
68if [ "$?" != 0 ]; then
69 lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "ERROR: no file to extract"
70 sleep 3
71 exit 0
72fi
73
74# make it executable and change user/group
75chmod 775 $SPIDERAPP_PATH
76if [ "$?" != 0 ]; then
77 lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "ERROR: cannot make it executable"
78 sleep 3
79 exit 0
80fi
81chown 500:500 $SPIDERAPP_PATH
82if [ "$?" != 0 ]; then
83 lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "ERROR: cannot change owner"
84 sleep 3
85 exit 0
86fi
87
88# # change main application
89# lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,9 "Modify app list"
90# sed -i 's/Rockbox/SpiderApp/' $ROOTFS_TMP_DIR/etc/AppList.conf
91# if [ "$?" != 0 ]; then
92# lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,14 "ERROR: sed failed"
93# sleep 3
94# exit 0
95# fi
96# # and fix ownership
97# chown 500:500 $ROOTFS_TMP_DIR/etc/AppList.conf
98# if [ "$?" != 0 ]; then
99# lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,14 "ERROR: cannot change group"
100# sleep 3
101# exit 0
102# fi
103cat $ROOTFS_TMP_DIR/etc/AppList.conf >$CONTENTS/AppList.conf
104ls -l $ROOTFS_TMP_DIR/usr/local/bin/ >$CONTENTS/ls.txt
105ls -l $ROOTFS_TMP_DIR/etc/ >$CONTENTS/ls2.txt
106
107# unmount root partition
108lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,10 "Unmount root filesystem"
109sync
110if [ "$?" != 0 ]; then
111 lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "ERROR: sync failed"
112 sleep 3
113 exit 0
114fi
115
116umount $ROOTFS_TMP_DIR
117if [ "$?" != 0 ]; then
118 lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "ERROR: umount failed"
119 sleep 3
120 exit 0
121fi
122
123# Success screen
124lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "Rebooting in 3 seconds."
125sleep 3
126sync
127
128# finish
129exit 0