diff options
Diffstat (limited to 'rbutil/jztool/jztool.c')
-rw-r--r-- | rbutil/jztool/jztool.c | 162 |
1 files changed, 65 insertions, 97 deletions
diff --git a/rbutil/jztool/jztool.c b/rbutil/jztool/jztool.c index 5aae8d7457..5fb6dc173f 100644 --- a/rbutil/jztool/jztool.c +++ b/rbutil/jztool/jztool.c | |||
@@ -26,21 +26,68 @@ | |||
26 | #include <stdbool.h> | 26 | #include <stdbool.h> |
27 | 27 | ||
28 | jz_context* jz = NULL; | 28 | jz_context* jz = NULL; |
29 | jz_usbdev* usbdev = NULL; | ||
29 | const jz_device_info* dev_info = NULL; | 30 | const jz_device_info* dev_info = NULL; |
30 | int dev_action = -1; | 31 | |
31 | jz_paramlist* action_params = NULL; | 32 | void usage_fiiom3k(void) |
33 | { | ||
34 | printf("Usage:\n" | ||
35 | " jztool fiiom3k load <bootloader.m3k>\n" | ||
36 | "\n" | ||
37 | "The 'load' command is used to boot the Rockbox bootloader in\n" | ||
38 | "recovery mode, which allows you to install the Rockbox bootloader\n" | ||
39 | "and backup or restore bootloader images. You need to connect the\n" | ||
40 | "M3K in USB boot mode in order to use this tool.\n" | ||
41 | "\n" | ||
42 | "On Windows, you will need to install the WinUSB driver for the M3K\n" | ||
43 | "using a 3rd-party tool such as Zadig <https://zadig.akeo.ie>. For\n" | ||
44 | "more details check the jztool README.md file or the Rockbox wiki at\n" | ||
45 | "<https://rockbox.org/wiki/FiioM3K>.\n" | ||
46 | "\n" | ||
47 | "To connect the M3K in USB boot mode, plug the microUSB into the\n" | ||
48 | "M3K, and hold the VOL- button while plugging the USB into your\n" | ||
49 | "computer. If successful, the button light will turn on and the\n" | ||
50 | "LCD will remain black. If you encounter any errors and need to\n" | ||
51 | "reconnect the device, you must force a power off by holding POWER\n" | ||
52 | "for more than 10 seconds.\n" | ||
53 | "\n" | ||
54 | "Once the Rockbox bootloader is installed on your M3K, you can\n" | ||
55 | "access the recovery menu by holding VOL+ while powering on the\n" | ||
56 | "device.\n"); | ||
57 | exit(4); | ||
58 | } | ||
59 | |||
60 | int cmdline_fiiom3k(int argc, char** argv) | ||
61 | { | ||
62 | if(argc < 2 || strcmp(argv[0], "load")) { | ||
63 | usage_fiiom3k(); | ||
64 | return 2; | ||
65 | } | ||
66 | |||
67 | int rc = jz_usb_open(jz, &usbdev, dev_info->vendor_id, dev_info->product_id); | ||
68 | if(rc < 0) { | ||
69 | jz_log(jz, JZ_LOG_ERROR, "Cannot open USB device: %d", rc); | ||
70 | return 1; | ||
71 | } | ||
72 | |||
73 | rc = jz_fiiom3k_boot(usbdev, argv[1]); | ||
74 | if(rc < 0) { | ||
75 | jz_log(jz, JZ_LOG_ERROR, "Boot failed: %d", rc); | ||
76 | return 1; | ||
77 | } | ||
78 | |||
79 | return 0; | ||
80 | } | ||
32 | 81 | ||
33 | void usage(void) | 82 | void usage(void) |
34 | { | 83 | { |
35 | printf("Usage:\n" | 84 | printf("Usage:\n" |
36 | " jztool [global options] <device> <action> [action options]\n" | 85 | " jztool [global options] <device> <command> [command arguments]\n" |
37 | "\n" | 86 | "\n" |
38 | "Global options:\n" | 87 | "Global options:\n" |
39 | "\n" | ||
40 | " -h, --help Display this help\n" | 88 | " -h, --help Display this help\n" |
41 | " -q, --quiet Don't log anything except errors\n" | 89 | " -q, --quiet Don't log anything except errors\n" |
42 | " -v, --verbose Display detailed logging output\n" | 90 | " -v, --verbose Display detailed logging output\n\n"); |
43 | " -l, --loglevel LEVEL Set log level\n"); | ||
44 | 91 | ||
45 | printf("Supported devices:\n\n"); | 92 | printf("Supported devices:\n\n"); |
46 | int n = jz_get_num_device_info(); | 93 | int n = jz_get_num_device_info(); |
@@ -49,39 +96,17 @@ void usage(void) | |||
49 | printf(" %s - %s\n", info->name, info->description); | 96 | printf(" %s - %s\n", info->name, info->description); |
50 | } | 97 | } |
51 | 98 | ||
52 | printf( | 99 | printf("\n" |
53 | "\n" | 100 | "For device-specific help run 'jztool DEVICE' without arguments,\n" |
54 | "Available actions for fiiom3k:\n" | 101 | "eg. 'jztool fiiom3k' will display help for the FiiO M3K.\n"); |
55 | "\n" | ||
56 | " install --spl <spl.m3k> --bootloader <bootloader.m3k>\n" | ||
57 | " [--without-backup yes] [--backup IMAGE]\n" | ||
58 | " Install or update the Rockbox bootloader on a device.\n" | ||
59 | "\n" | ||
60 | " If --backup is given, back up the current bootloader to IMAGE before\n" | ||
61 | " installing the new bootloader. The installer will normally refuse to\n" | ||
62 | " overwrite your current bootloader; pass '--without-backup yes' if you\n" | ||
63 | " really want to proceed without taking a backup.\n" | ||
64 | "\n" | ||
65 | " WARNING: it is NOT RECOMMENDED to install the Rockbox bootloader\n" | ||
66 | " without taking a backup of the original firmware bootloader. It may\n" | ||
67 | " be very difficult or impossible to recover your player without one.\n" | ||
68 | " At least one M3Ks is known to not to work with the Rockbox bootloader,\n" | ||
69 | " so it is very important to take a backup.\n" | ||
70 | "\n" | ||
71 | " backup --image IMAGE\n" | ||
72 | " Backup the current bootloader to the file IMAGE\n" | ||
73 | "\n" | ||
74 | " restore --image IMAGE\n" | ||
75 | " Restore a bootloader image backup from the file IMAGE\n" | ||
76 | "\n"); | ||
77 | 102 | ||
78 | exit(4); | 103 | exit(4); |
79 | } | 104 | } |
80 | 105 | ||
81 | void cleanup(void) | 106 | void cleanup(void) |
82 | { | 107 | { |
83 | if(action_params) | 108 | if(usbdev) |
84 | jz_paramlist_free(action_params); | 109 | jz_usb_close(usbdev); |
85 | if(jz) | 110 | if(jz) |
86 | jz_context_destroy(jz); | 111 | jz_context_destroy(jz); |
87 | } | 112 | } |
@@ -157,71 +182,14 @@ int main(int argc, char** argv) | |||
157 | exit(2); | 182 | exit(2); |
158 | } | 183 | } |
159 | 184 | ||
160 | /* Read the action */ | 185 | /* Dispatch to device handler */ |
161 | --argc, ++argv; | ||
162 | if(argc == 0) { | ||
163 | jz_log(jz, JZ_LOG_ERROR, "No action specified (try jztool --help)"); | ||
164 | exit(2); | ||
165 | } | ||
166 | |||
167 | for(dev_action = 0; dev_action < dev_info->num_actions; ++dev_action) | ||
168 | if(!strcmp(*argv, dev_info->action_names[dev_action])) | ||
169 | break; | ||
170 | |||
171 | if(dev_action == dev_info->num_actions) { | ||
172 | jz_log(jz, JZ_LOG_ERROR, "Unknown action '%s' (try jztool --help)", *argv); | ||
173 | exit(2); | ||
174 | } | ||
175 | |||
176 | /* Parse the action options */ | ||
177 | action_params = jz_paramlist_new(); | ||
178 | if(!action_params) { | ||
179 | jz_log(jz, JZ_LOG_ERROR, "Out of memory: can't create paramlist"); | ||
180 | exit(1); | ||
181 | } | ||
182 | |||
183 | const char* const* allowed_params = dev_info->action_params[dev_action]; | ||
184 | |||
185 | --argc, ++argv; | 186 | --argc, ++argv; |
186 | while(argc > 0 && argv[0][0] == '-') { | 187 | switch(dev_info->device_type) { |
187 | if(argv[0][1] != '-') { | 188 | case JZ_DEVICE_FIIOM3K: |
188 | jz_log(jz, JZ_LOG_ERROR, "Invalid option '%s' for action", *argv); | 189 | return cmdline_fiiom3k(argc, argv); |
189 | exit(2); | ||
190 | } | ||
191 | 190 | ||
192 | bool bad_option = true; | 191 | default: |
193 | for(int i = 0; allowed_params[i] != NULL; ++i) { | 192 | jz_log(jz, JZ_LOG_ERROR, "INTERNAL ERROR: unhandled device type"); |
194 | if(!strcmp(&argv[0][2], allowed_params[i])) { | 193 | return 1; |
195 | ++argv; | ||
196 | if(--argc == 0) { | ||
197 | jz_log(jz, JZ_LOG_ERROR, "Missing argument for parameter '%s'", *argv); | ||
198 | exit(2); | ||
199 | } | ||
200 | |||
201 | int rc = jz_paramlist_set(action_params, allowed_params[i], *argv); | ||
202 | if(rc < 0) { | ||
203 | jz_log(jz, JZ_LOG_ERROR, "Out of memory"); | ||
204 | exit(1); | ||
205 | } | ||
206 | |||
207 | bad_option = false; | ||
208 | } | ||
209 | } | ||
210 | |||
211 | if(bad_option) { | ||
212 | jz_log(jz, JZ_LOG_ERROR, "Invalid option '%s' for action", *argv); | ||
213 | exit(2); | ||
214 | } | ||
215 | |||
216 | --argc, ++argv; | ||
217 | } | ||
218 | |||
219 | if(argc != 0) { | ||
220 | jz_log(jz, JZ_LOG_ERROR, "Excess arguments on command line"); | ||
221 | exit(2); | ||
222 | } | 194 | } |
223 | |||
224 | /* Invoke action handler */ | ||
225 | int rc = dev_info->action_funcs[dev_action](jz, action_params); | ||
226 | return (rc < 0) ? 1 : 0; | ||
227 | } | 195 | } |