summaryrefslogtreecommitdiff
path: root/utils/nwztools/plattools
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2016-11-01 17:04:26 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2016-11-01 17:09:07 +0100
commitd492f25c54b4134fd6632156efee07670ab4004f (patch)
tree318919b264876a3906d15ecd8781ad0a1e15b3fb /utils/nwztools/plattools
parentb045e4da34165a878c7acc9a82e76b447fe992a7 (diff)
downloadrockbox-d492f25c54b4134fd6632156efee07670ab4004f.tar.gz
rockbox-d492f25c54b4134fd6632156efee07670ab4004f.zip
nwztools: add preliminary dualboot and dualboot install script
At the moment, the script install_duaboot does the following: - rename SpiderApp to SpiderApp.of (unless it already exists) - install payload as SpiderApp - fixes permissions Since SpiderApp is the main app, it will execute instead of the OF. The current dualboot code (dualboot.c) is still a preliminary but the current version displays an "all tools" menu to choose for. When exitting the menu using BACK, it will run the OF. With the modifications made by the install script, it should not be possible to break the device. In the worst case scenario, the dualboot code crashes and it restarted by the sysmgrd, or hangs. A safe way to recover is to plug the USB cable and reset the device: the system manager will then start the USB app and one can reflash the device if necessary. Change-Id: Id9edab0347538ad2a8651a28aea7fd083feaa626
Diffstat (limited to 'utils/nwztools/plattools')
-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
4 files changed, 227 insertions, 3 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 */