summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rbutil/jztool/Makefile2
-rw-r--r--rbutil/jztool/README.md85
-rw-r--r--rbutil/jztool/include/jztool.h41
-rw-r--r--rbutil/jztool/jztool.c79
-rw-r--r--rbutil/jztool/src/device_info.c72
-rw-r--r--rbutil/jztool/src/identify_file.c37
-rw-r--r--rbutil/jztool/src/ucl_unpack.c128
-rw-r--r--rbutil/jztool/src/usb.c40
-rw-r--r--rbutil/jztool/src/x1000.c (renamed from rbutil/jztool/src/fiiom3k.c)149
9 files changed, 408 insertions, 225 deletions
diff --git a/rbutil/jztool/Makefile b/rbutil/jztool/Makefile
index 5e397c59aa..d1bbae578c 100644
--- a/rbutil/jztool/Makefile
+++ b/rbutil/jztool/Makefile
@@ -15,7 +15,7 @@ CFLAGS += -O0 -ggdb
15endif 15endif
16 16
17LIBSOURCES := src/buffer.c src/context.c src/device_info.c \ 17LIBSOURCES := src/buffer.c src/context.c src/device_info.c \
18 src/identify_file.c src/fiiom3k.c src/usb.c 18 src/identify_file.c src/ucl_unpack.c src/usb.c src/x1000.c
19SOURCES := $(LIBSOURCES) jztool.c 19SOURCES := $(LIBSOURCES) jztool.c
20EXTRADEPS := libucl.a libmicrotar.a 20EXTRADEPS := libucl.a libmicrotar.a
21 21
diff --git a/rbutil/jztool/README.md b/rbutil/jztool/README.md
index 2c4dd4992c..72c630c6c3 100644
--- a/rbutil/jztool/README.md
+++ b/rbutil/jztool/README.md
@@ -1,26 +1,45 @@
1# jztool -- Ingenic device utility & bootloader installer 1# jztool -- Ingenic device utility & bootloader installer
2 2
3The `jztool` utility can help install, backup, and restore the bootloader on 3The `jztool` utility can help install, backup, and restore the bootloader on
4Rockbox players based on a supported Ingenic SoC. 4Rockbox players based on a supported Ingenic SoC (currently only the X1000).
5 5
6## FiiO M3K 6## Running jztool
7 7
8First, get a copy of the `bootloader.m3k` file, either by downloading it 8### Getting a bootloader
9from <https://rockbox.org>, or by compiling it yourself (choose 'B'ootloader
10build when configuring your build).
11 9
12The first time you install Rockbox, you need to load the Rockbox bootloader 10To use `jztool` you need to compile or download a bootloader for your player.
13over USB by entering USB boot mode. The easiest way to do this is by plugging 11It's recommended to use only official released bootloaders, since bootloaders
14in the microUSB cable to the M3K and holding the VOL- button while plugging 12compiled from Git are not tested and might be buggy.
15the USB into your computer. If you entered USB boot mode, the button light
16will turn on but the LCD will remain black.
17 13
18Copy the `bootloader.m3k` next to the `jztool` executable and follow the 14You can download released bootloaders from <https://download.rockbox.org/>.
19instructions below which are appropriate to your OS.
20 15
21### Running jztool 16The bootloader file is named after the target: for example, the FiiO M3K
17bootloader is called `bootloader.m3k`. The FiiO M3K is used as an example
18here, but the instructions apply to all X1000-based players.
22 19
23#### Linux/Mac 20Use `jztool --help` to find out the model name of your player.
21
22### Entering USB boot mode
23
24USB boot mode is a low-level mode provided by the CPU which allows a computer
25to load firmware onto the device. You need to put your player into this mode
26manually before using `jztool` (unfortunately, it can't be done automatically.)
27
28To connect the player in USB boot mode, follow these steps:
29
301. Ensure the player is fully powered off.
312. Plug one end of the USB cable into your player.
323. Hold down your player's USB boot key (see below).
334. Plug the other end of the USB cable into your computer.
345. Let go of the USB boot key.
35
36The USB boot key depends on your player:
37
38- FiiO M3K: Volume Down
39- Shanling Q1: Play
40- Eros Q: Menu
41
42### Linux/Mac
24 43
25Run the following command in a terminal. Note that on Linux, you will need to 44Run the following command in a terminal. Note that on Linux, you will need to
26have root access to allow libusb to access the USB device. 45have root access to allow libusb to access the USB device.
@@ -32,9 +51,9 @@ have root access to allow libusb to access the USB device.
32$ ./jztool fiiom3k load bootloader.m3k 51$ ./jztool fiiom3k load bootloader.m3k
33``` 52```
34 53
35#### Windows 54### Windows
36 55
37To allow `jztool` access to the M3K in USB boot mode, you need to install 56To allow `jztool` access to your player in USB boot mode, you need to install
38the WinUSB driver. The recommended way to install it is using Zadig, which 57the WinUSB driver. The recommended way to install it is using Zadig, which
39may be downloaded from its homepage <https://zadig.akeo.ie>. Please note 58may be downloaded from its homepage <https://zadig.akeo.ie>. Please note
40this is 3rd party software not maintained or supported by Rockbox developers. 59this is 3rd party software not maintained or supported by Rockbox developers.
@@ -42,10 +61,10 @@ this is 3rd party software not maintained or supported by Rockbox developers.
42 61
43When running Zadig you must select the WinUSB driver; the other driver options 62When running Zadig you must select the WinUSB driver; the other driver options
44will not work properly with `jztool`. You will have to select the correct USB 63will not work properly with `jztool`. You will have to select the correct USB
45device in Zadig -- the name and USB IDs of the M3K in USB boot mode are listed 64device in Zadig. All X1000-based players use the same USB ID while in USB boot
46below. NOTE: the device name may show only as "X" and a hollow square in Zadig. 65mode, listed below. NOTE: the device name may show only as "X" and a hollow
47The IDs will not change, so those are the most reliable way to confirm you have 66square in Zadig. The IDs will not change, so those are the most reliable way
48selected the correct device. 67to confirm you have selected the correct device.
49 68
50``` 69```
51Name: Ingenic Semiconductor Co.,Ltd X1000 70Name: Ingenic Semiconductor Co.,Ltd X1000
@@ -63,21 +82,27 @@ Type the following command to load the Rockbox bootloader:
63$ jztool.exe fiiom3k load bootloader.m3k 82$ jztool.exe fiiom3k load bootloader.m3k
64``` 83```
65 84
66### Further instructions 85## Using the recovery menu
67 86
68After running `jztool` successfully your M3K will display the recovery menu 87If `jztool` runs successfully your player will display the Rockbox bootloader's
69of the Rockbox bootloader. If you want to permanently install Rockbox to your 88recovery menu. If you want to permanently install Rockbox to your device, copy
70M3K, copy `bootloader.m3k` to the root of an SD card, insert it to your device, 89the bootloader file you downloaded to the root of your SD card, insert the SD
71then choose "Install/update bootloader" from the menu. 90card to your player, and choose "Install/update bootloader" from the menu.
72 91
73It is _highly_ recommended that you take a backup of your existing bootloader 92It is _highly_ recommended that you take a backup of your existing bootloader
74in case of any trouble -- choose "Backup bootloader" from the recovery menu. 93in case of any trouble -- choose "Backup bootloader" from the recovery menu.
75The backup file is called "fiiom3k-boot.bin" and will be saved to the root of 94The backup file is called `PLAYER-boot.bin`, where `PLAYER` is the model name.
76the SD card. If you need to restore it, simply place the file at the root of 95(Example: `fiiom3k-boot.bin`.)
77your SD card and select "Restore bootloader". 96
97You can restore the backup later by putting it on the root of your SD card and
98selecting "Restor bootloader" in the recovery menu.
99
100After installing the Rockbox bootloader, you can access the recovery menu by
101holding a key while booting:
78 102
79In the future if you want to backup, restore, or update the bootloader, you 103- FiiO M3K: Volume Up
80can access the Rockbox bootloader's recovery menu by holding VOL+ when booting. 104- Shanling Q1: Next (button on the lower left)
105- Eros Q: Volume Up
81 106
82### Known issues 107### Known issues
83 108
diff --git a/rbutil/jztool/include/jztool.h b/rbutil/jztool/include/jztool.h
index df51fe9f44..9d3c08c5bc 100644
--- a/rbutil/jztool/include/jztool.h
+++ b/rbutil/jztool/include/jztool.h
@@ -33,9 +33,12 @@ extern "C" {
33 * Types, enumerations, etc 33 * Types, enumerations, etc
34 */ 34 */
35 35
36#define JZ_CPUINFO_BUFLEN 9
37
36typedef struct jz_context jz_context; 38typedef struct jz_context jz_context;
37typedef struct jz_usbdev jz_usbdev; 39typedef struct jz_usbdev jz_usbdev;
38typedef struct jz_device_info jz_device_info; 40typedef struct jz_device_info jz_device_info;
41typedef struct jz_cpu_info jz_cpu_info;
39typedef struct jz_buffer jz_buffer; 42typedef struct jz_buffer jz_buffer;
40 43
41typedef enum jz_error jz_error; 44typedef enum jz_error jz_error;
@@ -77,19 +80,46 @@ enum jz_log_level {
77 80
78enum jz_device_type { 81enum jz_device_type {
79 JZ_DEVICE_FIIOM3K, 82 JZ_DEVICE_FIIOM3K,
83 JZ_DEVICE_SHANLINGQ1,
84 JZ_DEVICE_EROSQ,
85 JZ_NUM_DEVICES,
80}; 86};
81 87
82enum jz_cpu_type { 88enum jz_cpu_type {
83 JZ_CPU_X1000, 89 JZ_CPU_X1000,
90 JZ_NUM_CPUS,
84}; 91};
85 92
86struct jz_device_info { 93struct jz_device_info {
94 /* internal device name and file extension */
87 const char* name; 95 const char* name;
96 const char* file_ext;
97
98 /* human-readable name */
88 const char* description; 99 const char* description;
100
101 /* device and CPU type */
89 jz_device_type device_type; 102 jz_device_type device_type;
90 jz_cpu_type cpu_type; 103 jz_cpu_type cpu_type;
104
105 /* USB IDs of the device in mass storage mode */
106 uint16_t vendor_id;
107 uint16_t product_id;
108};
109
110struct jz_cpu_info {
111 /* CPU info string, as reported by the boot ROM */
112 const char* info_str;
113
114 /* USB IDs of the boot ROM */
91 uint16_t vendor_id; 115 uint16_t vendor_id;
92 uint16_t product_id; 116 uint16_t product_id;
117
118 /* default addresses for running binaries */
119 uint32_t stage1_load_addr;
120 uint32_t stage1_exec_addr;
121 uint32_t stage2_load_addr;
122 uint32_t stage2_exec_addr;
93}; 123};
94 124
95struct jz_buffer { 125struct jz_buffer {
@@ -119,11 +149,13 @@ void jz_sleepms(int ms);
119 * Device and file info 149 * Device and file info
120 */ 150 */
121 151
122int jz_get_num_device_info(void);
123const jz_device_info* jz_get_device_info(jz_device_type type); 152const jz_device_info* jz_get_device_info(jz_device_type type);
124const jz_device_info* jz_get_device_info_named(const char* name); 153const jz_device_info* jz_get_device_info_named(const char* name);
125const jz_device_info* jz_get_device_info_indexed(int index); 154const jz_device_info* jz_get_device_info_indexed(int index);
126 155
156const jz_cpu_info* jz_get_cpu_info(jz_cpu_type type);
157const jz_cpu_info* jz_get_cpu_info_named(const char* info_str);
158
127int jz_identify_x1000_spl(const void* data, size_t len); 159int jz_identify_x1000_spl(const void* data, size_t len);
128int jz_identify_scramble_image(const void* data, size_t len); 160int jz_identify_scramble_image(const void* data, size_t len);
129 161
@@ -139,15 +171,16 @@ int jz_usb_recv(jz_usbdev* dev, uint32_t addr, size_t len, void* data);
139int jz_usb_start1(jz_usbdev* dev, uint32_t addr); 171int jz_usb_start1(jz_usbdev* dev, uint32_t addr);
140int jz_usb_start2(jz_usbdev* dev, uint32_t addr); 172int jz_usb_start2(jz_usbdev* dev, uint32_t addr);
141int jz_usb_flush_caches(jz_usbdev* dev); 173int jz_usb_flush_caches(jz_usbdev* dev);
174int jz_usb_get_cpu_info(jz_usbdev* dev, char* buffer, size_t buflen);
142 175
143/****************************************************************************** 176/******************************************************************************
144 * Rockbox loader (all functions are model-specific, see docs) 177 * Rockbox loader (all functions are model-specific, see docs)
145 */ 178 */
146 179
147int jz_fiiom3k_boot(jz_usbdev* dev, const char* filename); 180int jz_x1000_boot(jz_usbdev* dev, jz_device_type type, const char* filename);
148 181
149/****************************************************************************** 182/******************************************************************************
150 * Simple buffer API 183 * Buffer API and other functions
151 */ 184 */
152 185
153jz_buffer* jz_buffer_alloc(size_t size, const void* data); 186jz_buffer* jz_buffer_alloc(size_t size, const void* data);
@@ -156,6 +189,8 @@ void jz_buffer_free(jz_buffer* buf);
156int jz_buffer_load(jz_buffer** buf, const char* filename); 189int jz_buffer_load(jz_buffer** buf, const char* filename);
157int jz_buffer_save(jz_buffer* buf, const char* filename); 190int jz_buffer_save(jz_buffer* buf, const char* filename);
158 191
192jz_buffer* jz_ucl_unpack(const uint8_t* src, uint32_t src_len, uint32_t* dst_len);
193
159/****************************************************************************** 194/******************************************************************************
160 * END 195 * END
161 */ 196 */
diff --git a/rbutil/jztool/jztool.c b/rbutil/jztool/jztool.c
index 5fb6dc173f..dcd78137b3 100644
--- a/rbutil/jztool/jztool.c
+++ b/rbutil/jztool/jztool.c
@@ -28,49 +28,63 @@
28jz_context* jz = NULL; 28jz_context* jz = NULL;
29jz_usbdev* usbdev = NULL; 29jz_usbdev* usbdev = NULL;
30const jz_device_info* dev_info = NULL; 30const jz_device_info* dev_info = NULL;
31const jz_cpu_info* cpu_info = NULL;
31 32
32void usage_fiiom3k(void) 33void usage_x1000(void)
33{ 34{
34 printf("Usage:\n" 35 printf(
35 " jztool fiiom3k load <bootloader.m3k>\n" 36"Usage:\n"
36 "\n" 37" jztool fiiom3k load <bootloader.m3k>\n"
37 "The 'load' command is used to boot the Rockbox bootloader in\n" 38" jztool shanlingq1 load <bootloader.q1>\n"
38 "recovery mode, which allows you to install the Rockbox bootloader\n" 39" jztool erosq load <bootloader.erosq>\n"
39 "and backup or restore bootloader images. You need to connect the\n" 40"\n"
40 "M3K in USB boot mode in order to use this tool.\n" 41"The 'load' command is used to boot the Rockbox bootloader in recovery\n"
41 "\n" 42"mode, which allows you to install the Rockbox bootloader and backup or\n"
42 "On Windows, you will need to install the WinUSB driver for the M3K\n" 43"restore bootloader images. You need to connect your player in USB boot\n"
43 "using a 3rd-party tool such as Zadig <https://zadig.akeo.ie>. For\n" 44"mode in order to use this tool.\n"
44 "more details check the jztool README.md file or the Rockbox wiki at\n" 45"\n"
45 "<https://rockbox.org/wiki/FiioM3K>.\n" 46"To connect the player in USB boot mode, follow these steps:\n"
46 "\n" 47"\n"
47 "To connect the M3K in USB boot mode, plug the microUSB into the\n" 48"1. Ensure the player is fully powered off.\n"
48 "M3K, and hold the VOL- button while plugging the USB into your\n" 49"2. Plug one end of the USB cable into your player.\n"
49 "computer. If successful, the button light will turn on and the\n" 50"3. Hold down your player's USB boot key (see below).\n"
50 "LCD will remain black. If you encounter any errors and need to\n" 51"4. Plug the other end of the USB cable into your computer.\n"
51 "reconnect the device, you must force a power off by holding POWER\n" 52"5. Let go of the USB boot key.\n"
52 "for more than 10 seconds.\n" 53"\n"
53 "\n" 54"USB boot keys:\n"
54 "Once the Rockbox bootloader is installed on your M3K, you can\n" 55"\n"
55 "access the recovery menu by holding VOL+ while powering on the\n" 56" FiiO M3K - Volume Down\n"
56 "device.\n"); 57" Shanling Q1 - Play\n"
58" Eros Q - Menu\n"
59"\n"
60"Not all players give a visible indication that they are in USB boot mode.\n"
61"If you're having trouble connecting your player, try resetting it by\n"
62"holding the power button for 10 seconds, and try the above steps again.\n"
63"\n"
64"Note for Windows users: you need to install the WinUSB driver using a\n"
65"3rd-party tool such as Zadig <https://zadig.akeo.ie> before this tool\n"
66"can access your player in USB boot mode. You need to run Zadig while the\n"
67"player is plugged in and in USB boot mode. For more details check the\n"
68"jztool README.md file or visit <https://rockbox.org/wiki/IngenicX1000>.\n"
69"\n");
70
57 exit(4); 71 exit(4);
58} 72}
59 73
60int cmdline_fiiom3k(int argc, char** argv) 74int cmdline_x1000(int argc, char** argv)
61{ 75{
62 if(argc < 2 || strcmp(argv[0], "load")) { 76 if(argc < 2 || strcmp(argv[0], "load")) {
63 usage_fiiom3k(); 77 usage_x1000();
64 return 2; 78 return 2;
65 } 79 }
66 80
67 int rc = jz_usb_open(jz, &usbdev, dev_info->vendor_id, dev_info->product_id); 81 int rc = jz_usb_open(jz, &usbdev, cpu_info->vendor_id, cpu_info->product_id);
68 if(rc < 0) { 82 if(rc < 0) {
69 jz_log(jz, JZ_LOG_ERROR, "Cannot open USB device: %d", rc); 83 jz_log(jz, JZ_LOG_ERROR, "Cannot open USB device: %d", rc);
70 return 1; 84 return 1;
71 } 85 }
72 86
73 rc = jz_fiiom3k_boot(usbdev, argv[1]); 87 rc = jz_x1000_boot(usbdev, dev_info->device_type, argv[1]);
74 if(rc < 0) { 88 if(rc < 0) {
75 jz_log(jz, JZ_LOG_ERROR, "Boot failed: %d", rc); 89 jz_log(jz, JZ_LOG_ERROR, "Boot failed: %d", rc);
76 return 1; 90 return 1;
@@ -90,8 +104,7 @@ void usage(void)
90 " -v, --verbose Display detailed logging output\n\n"); 104 " -v, --verbose Display detailed logging output\n\n");
91 105
92 printf("Supported devices:\n\n"); 106 printf("Supported devices:\n\n");
93 int n = jz_get_num_device_info(); 107 for(int i = 0; i < JZ_NUM_DEVICES; ++i) {
94 for(int i = 0; i < n; ++i) {
95 const jz_device_info* info = jz_get_device_info_indexed(i); 108 const jz_device_info* info = jz_get_device_info_indexed(i);
96 printf(" %s - %s\n", info->name, info->description); 109 printf(" %s - %s\n", info->name, info->description);
97 } 110 }
@@ -182,11 +195,15 @@ int main(int argc, char** argv)
182 exit(2); 195 exit(2);
183 } 196 }
184 197
198 cpu_info = jz_get_cpu_info(dev_info->cpu_type);
199
185 /* Dispatch to device handler */ 200 /* Dispatch to device handler */
186 --argc, ++argv; 201 --argc, ++argv;
187 switch(dev_info->device_type) { 202 switch(dev_info->device_type) {
188 case JZ_DEVICE_FIIOM3K: 203 case JZ_DEVICE_FIIOM3K:
189 return cmdline_fiiom3k(argc, argv); 204 case JZ_DEVICE_SHANLINGQ1:
205 case JZ_DEVICE_EROSQ:
206 return cmdline_x1000(argc, argv);
190 207
191 default: 208 default:
192 jz_log(jz, JZ_LOG_ERROR, "INTERNAL ERROR: unhandled device type"); 209 jz_log(jz, JZ_LOG_ERROR, "INTERNAL ERROR: unhandled device type");
diff --git a/rbutil/jztool/src/device_info.c b/rbutil/jztool/src/device_info.c
index 5ce3899262..cc431959ca 100644
--- a/rbutil/jztool/src/device_info.c
+++ b/rbutil/jztool/src/device_info.c
@@ -22,39 +22,58 @@
22#include "jztool.h" 22#include "jztool.h"
23#include <string.h> 23#include <string.h>
24 24
25static const jz_device_info infotable[] = { 25static const jz_device_info infotable[JZ_NUM_DEVICES] = {
26 { 26 [JZ_DEVICE_FIIOM3K] = {
27 .name = "fiiom3k", 27 .name = "fiiom3k",
28 .file_ext = "m3k",
28 .description = "FiiO M3K", 29 .description = "FiiO M3K",
29 .device_type = JZ_DEVICE_FIIOM3K, 30 .device_type = JZ_DEVICE_FIIOM3K,
30 .cpu_type = JZ_CPU_X1000, 31 .cpu_type = JZ_CPU_X1000,
32 .vendor_id = 0x2972,
33 .product_id = 0x0003,
34 },
35 [JZ_DEVICE_SHANLINGQ1] = {
36 .name = "shanlingq1",
37 .file_ext = "q1",
38 .description = "Shanling Q1",
39 .device_type = JZ_DEVICE_SHANLINGQ1,
40 .cpu_type = JZ_CPU_X1000,
41 .vendor_id = 0x0525,
42 .product_id = 0xa4a5,
43 },
44 [JZ_DEVICE_EROSQ] = {
45 .name = "erosq",
46 .file_ext = "erosq",
47 .description = "AIGO Eros Q",
48 .device_type = JZ_DEVICE_EROSQ,
49 .cpu_type = JZ_CPU_X1000,
50 .vendor_id = 0xc502,
51 .product_id = 0x0023,
52 },
53};
54
55static const jz_cpu_info cputable[JZ_NUM_CPUS] = {
56 [JZ_CPU_X1000] = {
57 .info_str = "X1000_v1",
31 .vendor_id = 0xa108, 58 .vendor_id = 0xa108,
32 .product_id = 0x1000, 59 .product_id = 0x1000,
60 .stage1_load_addr = 0xf4001000,
61 .stage1_exec_addr = 0xf4001800,
62 .stage2_load_addr = 0x80004000,
63 .stage2_exec_addr = 0x80004000,
33 }, 64 },
34}; 65};
35 66
36static const int infotable_size = sizeof(infotable)/sizeof(struct jz_device_info);
37
38/** \brief Get the number of entries in the device info list */
39int jz_get_num_device_info(void)
40{
41 return infotable_size;
42}
43
44/** \brief Lookup info for a device by type, returns NULL if not found. */ 67/** \brief Lookup info for a device by type, returns NULL if not found. */
45const jz_device_info* jz_get_device_info(jz_device_type type) 68const jz_device_info* jz_get_device_info(jz_device_type type)
46{ 69{
47 for(int i = 0; i < infotable_size; ++i) 70 return jz_get_device_info_indexed(type);
48 if(infotable[i].device_type == type)
49 return &infotable[i];
50
51 return NULL;
52} 71}
53 72
54/** \brief Lookup info for a device by name, returns NULL if not found. */ 73/** \brief Lookup info for a device by name, returns NULL if not found. */
55const jz_device_info* jz_get_device_info_named(const char* name) 74const jz_device_info* jz_get_device_info_named(const char* name)
56{ 75{
57 for(int i = 0; i < infotable_size; ++i) 76 for(int i = 0; i < JZ_NUM_DEVICES; ++i)
58 if(!strcmp(infotable[i].name, name)) 77 if(!strcmp(infotable[i].name, name))
59 return &infotable[i]; 78 return &infotable[i];
60 79
@@ -64,8 +83,27 @@ const jz_device_info* jz_get_device_info_named(const char* name)
64/** \brief Get a device info entry by index, returns NULL if out of range. */ 83/** \brief Get a device info entry by index, returns NULL if out of range. */
65const jz_device_info* jz_get_device_info_indexed(int index) 84const jz_device_info* jz_get_device_info_indexed(int index)
66{ 85{
67 if(index < infotable_size) 86 if(index < JZ_NUM_DEVICES)
68 return &infotable[index]; 87 return &infotable[index];
69 else 88 else
70 return NULL; 89 return NULL;
71} 90}
91
92/** \brief Lookup info for a CPU, returns NULL if not found. */
93const jz_cpu_info* jz_get_cpu_info(jz_cpu_type type)
94{
95 if(type < JZ_NUM_CPUS)
96 return &cputable[type];
97 else
98 return NULL;
99}
100
101/** \brief Lookup info for a CPU by info string, returns NULL if not found. */
102const jz_cpu_info* jz_get_cpu_info_named(const char* info_str)
103{
104 for(int i = 0; i < JZ_NUM_CPUS; ++i)
105 if(!strcmp(cputable[i].info_str, info_str))
106 return &cputable[i];
107
108 return NULL;
109}
diff --git a/rbutil/jztool/src/identify_file.c b/rbutil/jztool/src/identify_file.c
index e735075687..e475d98a3b 100644
--- a/rbutil/jztool/src/identify_file.c
+++ b/rbutil/jztool/src/identify_file.c
@@ -118,43 +118,52 @@ int jz_identify_x1000_spl(const void* data, size_t len)
118static const struct scramble_model_info { 118static const struct scramble_model_info {
119 const char* name; 119 const char* name;
120 int model_num; 120 int model_num;
121 size_t offset_crc;
122 size_t offset_name;
123 size_t offset_data;
121} scramble_models[] = { 124} scramble_models[] = {
122 {"fiio", 114}, 125 {"fiio", 114, 0, 4, 8},
123 {NULL, 0}, 126 {"shq1", 115, 0, 4, 8},
127 {"eros", 116, 0, 4, 8},
128 {NULL, 0, 0, 0, 0},
124}; 129};
125 130
126/** \brief Identify a file as a Rockbox `scramble` image 131/** \brief Identify a file as a Rockbox `scramble` image
127 * \param data File data buffer 132 * \param data File data buffer
128 * \param len Length of file 133 * \param len Length of file
129 * \return JZ_SUCCESS if file looks correct, or one of the following errors 134 * \return JZ_SUCCESS if file looks correct, or one of the following errors
130 * \retval JZ_IDERR_WRONG_SIZE file too small to be valid
131 * \retval JZ_IDERR_UNRECOGNIZED_MODEL unsupported/unknown model type 135 * \retval JZ_IDERR_UNRECOGNIZED_MODEL unsupported/unknown model type
132 * \retval JZ_IDERR_BAD_CHECKSUM checksum mismatch 136 * \retval JZ_IDERR_BAD_CHECKSUM checksum mismatch
133 */ 137 */
134int jz_identify_scramble_image(const void* data, size_t len) 138int jz_identify_scramble_image(const void* data, size_t len)
135{ 139{
136 /* 4 bytes checksum + 4 bytes player model */ 140 const uint8_t* dat;
137 if(len < 8) 141 const struct scramble_model_info* model_info;
138 return JZ_IDERR_WRONG_SIZE; 142 uint32_t sum, file_sum;
143
144 dat = (const uint8_t*)data;
145 model_info = &scramble_models[0];
139 146
140 /* Look up the model number */ 147 /* Look up the model number */
141 const uint8_t* dat = (const uint8_t*)data; 148 for(; model_info->name != NULL; ++model_info) {
142 const struct scramble_model_info* model_info = &scramble_models[0]; 149 if(model_info->offset_name + 4 > len)
143 for(; model_info->name != NULL; ++model_info) 150 continue;
144 if(!memcmp(&dat[4], model_info->name, 4)) 151 if(!memcmp(&dat[model_info->offset_name], model_info->name, 4))
145 break; 152 break;
153 }
146 154
147 if(model_info->name == NULL) 155 if(model_info->name == NULL)
148 return JZ_IDERR_UNRECOGNIZED_MODEL; 156 return JZ_IDERR_UNRECOGNIZED_MODEL;
149 157
150 /* Compute the checksum */ 158 /* Compute the checksum */
151 uint32_t sum = model_info->model_num; 159 sum = model_info->model_num;
152 for(size_t i = 8; i < len; ++i) 160 for(size_t i = model_info->offset_data; i < len; ++i)
153 sum += dat[i]; 161 sum += dat[i];
154 162
155 /* Compare with file's checksum, it's stored in big-endian form */ 163 /* Compare with file's checksum, it's stored in big-endian form */
156 uint32_t fsum = (dat[0] << 24) | (dat[1] << 16) | (dat[2] << 8) | dat[3]; 164 dat += model_info->offset_crc;
157 if(sum != fsum) 165 file_sum = (dat[0] << 24) | (dat[1] << 16) | (dat[2] << 8) | dat[3];
166 if(sum != file_sum)
158 return JZ_IDERR_BAD_CHECKSUM; 167 return JZ_IDERR_BAD_CHECKSUM;
159 168
160 return JZ_SUCCESS; 169 return JZ_SUCCESS;
diff --git a/rbutil/jztool/src/ucl_unpack.c b/rbutil/jztool/src/ucl_unpack.c
new file mode 100644
index 0000000000..3b199c7008
--- /dev/null
+++ b/rbutil/jztool/src/ucl_unpack.c
@@ -0,0 +1,128 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2021 Aidan MacDonald
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 "jztool.h"
23#include "ucl/ucl.h"
24
25static uint32_t xread32(const uint8_t* d)
26{
27 uint32_t r = 0;
28 r |= d[0] << 24;
29 r |= d[1] << 16;
30 r |= d[2] << 8;
31 r |= d[3] << 0;
32 return r;
33}
34
35/* adapted from firmware/common/ucl_decompress.c */
36jz_buffer* jz_ucl_unpack(const uint8_t* src, uint32_t src_len, uint32_t* dst_len)
37{
38 static const uint8_t magic[8] =
39 {0x00, 0xe9, 0x55, 0x43, 0x4c, 0xff, 0x01, 0x1a};
40
41 jz_buffer* buffer = NULL;
42
43 /* make sure there are enough bytes for the header */
44 if(src_len < 18)
45 goto error;
46
47 /* avoid memcmp for reasons of code size */
48 for(size_t i = 0; i < sizeof(magic); ++i)
49 if(src[i] != magic[i])
50 goto error;
51
52 /* read the other header fields */
53 /* uint32_t flags = xread32(&src[8]); */
54 uint8_t method = src[12];
55 /* uint8_t level = src[13]; */
56 uint32_t block_size = xread32(&src[14]);
57
58 /* check supported compression method */
59 if(method != 0x2e)
60 goto error;
61
62 /* validate */
63 if(block_size < 1024 || block_size > 8*1024*1024)
64 goto error;
65
66 src += 18;
67 src_len -= 18;
68
69 /* Calculate amount of space that we might need & allocate a buffer:
70 * - subtract 4 to account for end of file marker
71 * - each block is block_size bytes + 8 bytes of header
72 * - add one to nr_blocks to account for case where file size < block size
73 * - total size = max uncompressed size of block * nr_blocks
74 */
75 uint32_t nr_blocks = (src_len - 4) / (8 + block_size) + 1;
76 uint32_t max_size = nr_blocks * (block_size + block_size/8 + 256);
77 buffer = jz_buffer_alloc(max_size, NULL);
78 if(!buffer)
79 goto error;
80
81 /* perform the decompression */
82 uint32_t dst_ilen = buffer->size;
83 uint8_t* dst = buffer->data;
84 while(1) {
85 if(src_len < 4)
86 goto error;
87
88 uint32_t out_len = xread32(src); src += 4, src_len -= 4;
89 if(out_len == 0)
90 break;
91
92 if(src_len < 4)
93 goto error;
94
95 uint32_t in_len = xread32(src); src += 4, src_len -= 4;
96 if(in_len > block_size || out_len > block_size ||
97 in_len == 0 || in_len > out_len)
98 goto error;
99
100 if(src_len < in_len)
101 goto error;
102
103 if(in_len < out_len) {
104 uint32_t actual_out_len = dst_ilen;
105 int rc = ucl_nrv2e_decompress_safe_8(src, in_len, dst, &actual_out_len, NULL);
106 if(rc != UCL_E_OK)
107 goto error;
108 if(actual_out_len != out_len)
109 goto error;
110 } else {
111 for(size_t i = 0; i < in_len; ++i)
112 dst[i] = src[i];
113 }
114
115 src += in_len;
116 src_len -= in_len;
117 dst += out_len;
118 dst_ilen -= out_len;
119 }
120
121 /* subtract leftover number of bytes to get size of compressed output */
122 *dst_len = buffer->size - dst_ilen;
123 return buffer;
124
125 error:
126 jz_buffer_free(buffer);
127 return NULL;
128}
diff --git a/rbutil/jztool/src/usb.c b/rbutil/jztool/src/usb.c
index c101f2be77..cfc3ba60cb 100644
--- a/rbutil/jztool/src/usb.c
+++ b/rbutil/jztool/src/usb.c
@@ -22,6 +22,7 @@
22#include "jztool_private.h" 22#include "jztool_private.h"
23#include <stdlib.h> 23#include <stdlib.h>
24#include <stdbool.h> 24#include <stdbool.h>
25#include <string.h>
25 26
26#define VR_GET_CPU_INFO 0 27#define VR_GET_CPU_INFO 0
27#define VR_SET_DATA_ADDRESS 1 28#define VR_SET_DATA_ADDRESS 1
@@ -145,11 +146,12 @@ void jz_usb_close(jz_usbdev* dev)
145 146
146// Does an Ingenic-specific vendor request 147// Does an Ingenic-specific vendor request
147// Written with X1000 in mind but other Ingenic CPUs have the same commands 148// Written with X1000 in mind but other Ingenic CPUs have the same commands
148static int jz_usb_vendor_req(jz_usbdev* dev, int req, uint32_t arg) 149static int jz_usb_vendor_req(jz_usbdev* dev, int req, uint32_t arg,
150 void* buffer, int buflen)
149{ 151{
150 int rc = libusb_control_transfer(dev->handle, 152 int rc = libusb_control_transfer(dev->handle,
151 LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 153 LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
152 req, arg >> 16, arg & 0xffff, NULL, 0, 1000); 154 req, arg >> 16, arg & 0xffff, buffer, buflen, 1000);
153 155
154 if(rc < 0) { 156 if(rc < 0) {
155 jz_log(dev->jz, JZ_LOG_ERROR, "libusb_control_transfer: %s", libusb_strerror(rc)); 157 jz_log(dev->jz, JZ_LOG_ERROR, "libusb_control_transfer: %s", libusb_strerror(rc));
@@ -200,11 +202,11 @@ static int jz_usb_sendrecv(jz_usbdev* dev, bool write, uint32_t addr,
200 size_t len, void* data) 202 size_t len, void* data)
201{ 203{
202 int rc; 204 int rc;
203 rc = jz_usb_vendor_req(dev, VR_SET_DATA_ADDRESS, addr); 205 rc = jz_usb_vendor_req(dev, VR_SET_DATA_ADDRESS, addr, NULL, 0);
204 if(rc < 0) 206 if(rc < 0)
205 return rc; 207 return rc;
206 208
207 rc = jz_usb_vendor_req(dev, VR_SET_DATA_LENGTH, len); 209 rc = jz_usb_vendor_req(dev, VR_SET_DATA_LENGTH, len, NULL, 0);
208 if(rc < 0) 210 if(rc < 0)
209 return rc; 211 return rc;
210 212
@@ -242,7 +244,7 @@ int jz_usb_recv(jz_usbdev* dev, uint32_t addr, size_t len, void* data)
242 */ 244 */
243int jz_usb_start1(jz_usbdev* dev, uint32_t addr) 245int jz_usb_start1(jz_usbdev* dev, uint32_t addr)
244{ 246{
245 return jz_usb_vendor_req(dev, VR_PROGRAM_START1, addr); 247 return jz_usb_vendor_req(dev, VR_PROGRAM_START1, addr, NULL, 0);
246} 248}
247 249
248/** \brief Execute stage2 program jumping to the specified address 250/** \brief Execute stage2 program jumping to the specified address
@@ -252,7 +254,7 @@ int jz_usb_start1(jz_usbdev* dev, uint32_t addr)
252 */ 254 */
253int jz_usb_start2(jz_usbdev* dev, uint32_t addr) 255int jz_usb_start2(jz_usbdev* dev, uint32_t addr)
254{ 256{
255 return jz_usb_vendor_req(dev, VR_PROGRAM_START2, addr); 257 return jz_usb_vendor_req(dev, VR_PROGRAM_START2, addr, NULL, 0);
256} 258}
257 259
258/** \brief Ask device to flush CPU caches 260/** \brief Ask device to flush CPU caches
@@ -261,5 +263,29 @@ int jz_usb_start2(jz_usbdev* dev, uint32_t addr)
261 */ 263 */
262int jz_usb_flush_caches(jz_usbdev* dev) 264int jz_usb_flush_caches(jz_usbdev* dev)
263{ 265{
264 return jz_usb_vendor_req(dev, VR_FLUSH_CACHES, 0); 266 return jz_usb_vendor_req(dev, VR_FLUSH_CACHES, 0, NULL, 0);
267}
268
269/** \brief Ask device for CPU info string
270 * \param dev USB device
271 * \param buffer Buffer to hold the info string
272 * \param buflen Size of the buffer, in bytes
273 * \return either JZ_SUCCESS on success or a failure code
274 *
275 * The buffer will always be null terminated, but to ensure the info string is
276 * not truncated the buffer needs to be at least `JZ_CPUINFO_BUFLEN` byes long.
277 */
278int jz_usb_get_cpu_info(jz_usbdev* dev, char* buffer, size_t buflen)
279{
280 char tmpbuf[JZ_CPUINFO_BUFLEN];
281 int rc = jz_usb_vendor_req(dev, VR_GET_CPU_INFO, 0, tmpbuf, 8);
282 if(rc != JZ_SUCCESS)
283 return rc;
284
285 if(buflen > 0) {
286 strncpy(buffer, tmpbuf, buflen);
287 buffer[buflen - 1] = 0;
288 }
289
290 return JZ_SUCCESS;
265} 291}
diff --git a/rbutil/jztool/src/fiiom3k.c b/rbutil/jztool/src/x1000.c
index 72e25a1220..aacad0ef01 100644
--- a/rbutil/jztool/src/fiiom3k.c
+++ b/rbutil/jztool/src/x1000.c
@@ -22,117 +22,11 @@
22#include "jztool.h" 22#include "jztool.h"
23#include "jztool_private.h" 23#include "jztool_private.h"
24#include "microtar.h" 24#include "microtar.h"
25#include "ucl/ucl.h"
26#include <stdbool.h> 25#include <stdbool.h>
27#include <string.h> 26#include <string.h>
28 27
29static uint32_t xread32(const uint8_t* d) 28/* TODO: these functions could be refactored to be CPU-agnostic */
30{ 29static int run_stage1(jz_usbdev* dev, jz_buffer* buf)
31 uint32_t r = 0;
32 r |= d[0] << 24;
33 r |= d[1] << 16;
34 r |= d[2] << 8;
35 r |= d[3] << 0;
36 return r;
37}
38
39/* adapted from firmware/common/ucl_decompress.c */
40static jz_buffer* ucl_unpack(const uint8_t* src, uint32_t src_len,
41 uint32_t* dst_len)
42{
43 static const uint8_t magic[8] =
44 {0x00, 0xe9, 0x55, 0x43, 0x4c, 0xff, 0x01, 0x1a};
45
46 jz_buffer* buffer = NULL;
47
48 /* make sure there are enough bytes for the header */
49 if(src_len < 18)
50 goto error;
51
52 /* avoid memcmp for reasons of code size */
53 for(size_t i = 0; i < sizeof(magic); ++i)
54 if(src[i] != magic[i])
55 goto error;
56
57 /* read the other header fields */
58 /* uint32_t flags = xread32(&src[8]); */
59 uint8_t method = src[12];
60 /* uint8_t level = src[13]; */
61 uint32_t block_size = xread32(&src[14]);
62
63 /* check supported compression method */
64 if(method != 0x2e)
65 goto error;
66
67 /* validate */
68 if(block_size < 1024 || block_size > 8*1024*1024)
69 goto error;
70
71 src += 18;
72 src_len -= 18;
73
74 /* Calculate amount of space that we might need & allocate a buffer:
75 * - subtract 4 to account for end of file marker
76 * - each block is block_size bytes + 8 bytes of header
77 * - add one to nr_blocks to account for case where file size < block size
78 * - total size = max uncompressed size of block * nr_blocks
79 */
80 uint32_t nr_blocks = (src_len - 4) / (8 + block_size) + 1;
81 uint32_t max_size = nr_blocks * (block_size + block_size/8 + 256);
82 buffer = jz_buffer_alloc(max_size, NULL);
83 if(!buffer)
84 goto error;
85
86 /* perform the decompression */
87 uint32_t dst_ilen = buffer->size;
88 uint8_t* dst = buffer->data;
89 while(1) {
90 if(src_len < 4)
91 goto error;
92
93 uint32_t out_len = xread32(src); src += 4, src_len -= 4;
94 if(out_len == 0)
95 break;
96
97 if(src_len < 4)
98 goto error;
99
100 uint32_t in_len = xread32(src); src += 4, src_len -= 4;
101 if(in_len > block_size || out_len > block_size ||
102 in_len == 0 || in_len > out_len)
103 goto error;
104
105 if(src_len < in_len)
106 goto error;
107
108 if(in_len < out_len) {
109 uint32_t actual_out_len = dst_ilen;
110 int rc = ucl_nrv2e_decompress_safe_8(src, in_len, dst, &actual_out_len, NULL);
111 if(rc != UCL_E_OK)
112 goto error;
113 if(actual_out_len != out_len)
114 goto error;
115 } else {
116 for(size_t i = 0; i < in_len; ++i)
117 dst[i] = src[i];
118 }
119
120 src += in_len;
121 src_len -= in_len;
122 dst += out_len;
123 dst_ilen -= out_len;
124 }
125
126 /* subtract leftover number of bytes to get size of compressed output */
127 *dst_len = buffer->size - dst_ilen;
128 return buffer;
129
130 error:
131 jz_buffer_free(buffer);
132 return NULL;
133}
134
135static int m3k_stage1(jz_usbdev* dev, jz_buffer* buf)
136{ 30{
137 int rc = jz_usb_send(dev, 0xf4001000, buf->size, buf->data); 31 int rc = jz_usb_send(dev, 0xf4001000, buf->size, buf->data);
138 if(rc < 0) 32 if(rc < 0)
@@ -141,7 +35,7 @@ static int m3k_stage1(jz_usbdev* dev, jz_buffer* buf)
141 return jz_usb_start1(dev, 0xf4001800); 35 return jz_usb_start1(dev, 0xf4001800);
142} 36}
143 37
144static int m3k_stage2(jz_usbdev* dev, jz_buffer* buf) 38static int run_stage2(jz_usbdev* dev, jz_buffer* buf)
145{ 39{
146 int rc = jz_usb_send(dev, 0x80004000, buf->size, buf->data); 40 int rc = jz_usb_send(dev, 0x80004000, buf->size, buf->data);
147 if(rc < 0) 41 if(rc < 0)
@@ -154,8 +48,8 @@ static int m3k_stage2(jz_usbdev* dev, jz_buffer* buf)
154 return jz_usb_start2(dev, 0x80004000); 48 return jz_usb_start2(dev, 0x80004000);
155} 49}
156 50
157static int m3k_get_file(jz_context* jz, mtar_t* tar, const char* file, 51static int get_file(jz_context* jz, mtar_t* tar, const char* file,
158 bool decompress, jz_buffer** buf) 52 bool decompress, jz_buffer** buf)
159{ 53{
160 jz_buffer* buffer = NULL; 54 jz_buffer* buffer = NULL;
161 mtar_header_t h; 55 mtar_header_t h;
@@ -180,7 +74,7 @@ static int m3k_get_file(jz_context* jz, mtar_t* tar, const char* file,
180 74
181 if(decompress) { 75 if(decompress) {
182 uint32_t dst_len; 76 uint32_t dst_len;
183 jz_buffer* nbuf = ucl_unpack(buffer->data, buffer->size, &dst_len); 77 jz_buffer* nbuf = jz_ucl_unpack(buffer->data, buffer->size, &dst_len);
184 jz_buffer_free(buffer); 78 jz_buffer_free(buffer);
185 if(!nbuf) { 79 if(!nbuf) {
186 jz_log(jz, JZ_LOG_ERROR, "error decompressing %s in boot file", file); 80 jz_log(jz, JZ_LOG_ERROR, "error decompressing %s in boot file", file);
@@ -196,7 +90,7 @@ static int m3k_get_file(jz_context* jz, mtar_t* tar, const char* file,
196 return JZ_SUCCESS; 90 return JZ_SUCCESS;
197} 91}
198 92
199static int m3k_show_version(jz_context* jz, jz_buffer* info_file) 93static int show_version(jz_context* jz, jz_buffer* info_file)
200{ 94{
201 /* Extract the version string and log it for informational purposes */ 95 /* Extract the version string and log it for informational purposes */
202 char* boot_version = (char*)info_file->data; 96 char* boot_version = (char*)info_file->data;
@@ -211,17 +105,28 @@ static int m3k_show_version(jz_context* jz, jz_buffer* info_file)
211 return JZ_SUCCESS; 105 return JZ_SUCCESS;
212} 106}
213 107
214/** \brief Load the Rockbox bootloader on the FiiO M3K 108/** \brief Load the Rockbox bootloader on an X1000 device
215 * \param dev USB device freshly returned by jz_usb_open() 109 * \param dev USB device freshly returned by jz_usb_open()
216 * \param filename Path to the "bootloader.m3k" file 110 * \param filename Path to the "bootloader.target" file
217 * \return either JZ_SUCCESS or an error code 111 * \return either JZ_SUCCESS or an error code
218 */ 112 */
219int jz_fiiom3k_boot(jz_usbdev* dev, const char* filename) 113int jz_x1000_boot(jz_usbdev* dev, jz_device_type type, const char* filename)
220{ 114{
115 const jz_device_info* dev_info;
116 char spl_filename[32];
221 jz_buffer* spl = NULL, *bootloader = NULL, *info_file = NULL; 117 jz_buffer* spl = NULL, *bootloader = NULL, *info_file = NULL;
222 mtar_t tar; 118 mtar_t tar;
223 int rc; 119 int rc;
224 120
121 /* In retrospect using a model-dependent archive format was not a good
122 * idea, but it's not worth fixing just yet... */
123 dev_info = jz_get_device_info(type);
124 if(!dev_info)
125 return JZ_ERR_OTHER;
126 /* use of sprintf is safe since file_ext is short */
127 sprintf(spl_filename, "spl.%s", dev_info->file_ext);
128
129 /* Now open the archive */
225 rc = mtar_open(&tar, filename, "r"); 130 rc = mtar_open(&tar, filename, "r");
226 if(rc != MTAR_ESUCCESS) { 131 if(rc != MTAR_ESUCCESS) {
227 jz_log(dev->jz, JZ_LOG_ERROR, "cannot open file %s (tar error: %d)", filename, rc); 132 jz_log(dev->jz, JZ_LOG_ERROR, "cannot open file %s (tar error: %d)", filename, rc);
@@ -229,25 +134,25 @@ int jz_fiiom3k_boot(jz_usbdev* dev, const char* filename)
229 } 134 }
230 135
231 /* Extract all necessary files */ 136 /* Extract all necessary files */
232 rc = m3k_get_file(dev->jz, &tar, "spl.m3k", false, &spl); 137 rc = get_file(dev->jz, &tar, spl_filename, false, &spl);
233 if(rc != JZ_SUCCESS) 138 if(rc != JZ_SUCCESS)
234 goto error; 139 goto error;
235 140
236 rc = m3k_get_file(dev->jz, &tar, "bootloader.ucl", true, &bootloader); 141 rc = get_file(dev->jz, &tar, "bootloader.ucl", true, &bootloader);
237 if(rc != JZ_SUCCESS) 142 if(rc != JZ_SUCCESS)
238 goto error; 143 goto error;
239 144
240 rc = m3k_get_file(dev->jz, &tar, "bootloader-info.txt", false, &info_file); 145 rc = get_file(dev->jz, &tar, "bootloader-info.txt", false, &info_file);
241 if(rc != JZ_SUCCESS) 146 if(rc != JZ_SUCCESS)
242 goto error; 147 goto error;
243 148
244 /* Display the version string */ 149 /* Display the version string */
245 rc = m3k_show_version(dev->jz, info_file); 150 rc = show_version(dev->jz, info_file);
246 if(rc != JZ_SUCCESS) 151 if(rc != JZ_SUCCESS)
247 goto error; 152 goto error;
248 153
249 /* Stage1 boot of SPL to set up hardware */ 154 /* Stage1 boot of SPL to set up hardware */
250 rc = m3k_stage1(dev, spl); 155 rc = run_stage1(dev, spl);
251 if(rc != JZ_SUCCESS) 156 if(rc != JZ_SUCCESS)
252 goto error; 157 goto error;
253 158
@@ -256,7 +161,7 @@ int jz_fiiom3k_boot(jz_usbdev* dev, const char* filename)
256 161
257 /* Stage2 boot into the bootloader's recovery menu 162 /* Stage2 boot into the bootloader's recovery menu
258 * User has to take manual action from there */ 163 * User has to take manual action from there */
259 rc = m3k_stage2(dev, bootloader); 164 rc = run_stage2(dev, bootloader);
260 if(rc != JZ_SUCCESS) 165 if(rc != JZ_SUCCESS)
261 goto error; 166 goto error;
262 167