summaryrefslogtreecommitdiff
path: root/utils/mks5lboot
diff options
context:
space:
mode:
Diffstat (limited to 'utils/mks5lboot')
-rw-r--r--utils/mks5lboot/.gitignore5
-rw-r--r--utils/mks5lboot/Makefile43
-rw-r--r--utils/mks5lboot/README228
-rw-r--r--utils/mks5lboot/dualboot.c664
-rw-r--r--utils/mks5lboot/dualboot.h4
-rw-r--r--utils/mks5lboot/dualboot/.gitignore3
-rw-r--r--utils/mks5lboot/dualboot/Makefile97
-rw-r--r--utils/mks5lboot/dualboot/autoconf.h74
-rw-r--r--utils/mks5lboot/dualboot/bin2c.c140
-rw-r--r--utils/mks5lboot/dualboot/dualboot.c287
-rw-r--r--utils/mks5lboot/dualboot/dualboot.lds59
-rw-r--r--utils/mks5lboot/dualboot/init.S43
-rw-r--r--utils/mks5lboot/ipoddfu.c1061
-rw-r--r--utils/mks5lboot/main.c296
-rw-r--r--utils/mks5lboot/mkdfu.c318
-rw-r--r--utils/mks5lboot/mks5lboot.h129
16 files changed, 3451 insertions, 0 deletions
diff --git a/utils/mks5lboot/.gitignore b/utils/mks5lboot/.gitignore
new file mode 100644
index 0000000000..9b9b1de6ab
--- /dev/null
+++ b/utils/mks5lboot/.gitignore
@@ -0,0 +1,5 @@
1buildposix/
2buildmingw/
3builddarwin/
4mks5lboot
5mks5lboot.exe
diff --git a/utils/mks5lboot/Makefile b/utils/mks5lboot/Makefile
new file mode 100644
index 0000000000..72ea521d5f
--- /dev/null
+++ b/utils/mks5lboot/Makefile
@@ -0,0 +1,43 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7CC := gcc
8CFLAGS += -Wall -Wextra
9
10OUTPUT = mks5lboot
11
12# inputs for lib
13LIBSOURCES := dualboot.c mkdfu.c ipoddfu.c
14# inputs for binary only
15SOURCES := $(LIBSOURCES) main.c
16# dependencies for binary
17EXTRADEPS :=
18
19CPPDEFINES := $(shell echo foo | $(CROSS)$(CC) -dM -E -)
20
21ifeq ($(findstring WIN32,$(CPPDEFINES)),WIN32)
22LDOPTS += -lsetupapi
23# optional libusb support (needed for WinUSB and libusbK drivers)
24ifeq ($(findstring MINGW,$(CPPDEFINES)),MINGW)
25ifeq ($(USE_LIBUSBAPI),1)
26CFLAGS += -DUSE_LIBUSBAPI
27LDOPTS += -Wl,-Bstatic -lusb-1.0
28endif
29endif
30else
31ifeq ($(findstring APPLE,$(CPPDEFINES)),APPLE)
32LDOPTS += -L/usr/local/lib -framework IOKit -framework CoreFoundation
33else # Linux
34CFLAGS += -DUSE_LIBUSBAPI
35LDOPTS += -lusb-1.0
36endif
37endif
38
39include ../libtools.make
40
41# explicit dependencies on dualboot.{c,h} and mks5lboot.h
42$(OBJDIR)mks5lboot.o: dualboot.h dualboot.c mks5lboot.h
43$(OBJDIR)main.o: dualboot.h dualboot.c main.c mks5lboot.h
diff --git a/utils/mks5lboot/README b/utils/mks5lboot/README
new file mode 100644
index 0000000000..c424f7e617
--- /dev/null
+++ b/utils/mks5lboot/README
@@ -0,0 +1,228 @@
1mks5lboot
2---------
3
4A tool to install/uninstall a dual bootloader into a s5l8702 based
5device:
6
7 - iPod Classic 6G
8 - iPod Nano 3G (WIP)
9
10
11Usage
12-----
13
14 mks5lboot --bl-inst <bootloader.ipod> [-p <pid>] [--single]
15 --bl-uninst <platform> [-p <pid>]
16 --dfuscan [--loop [<sec>]] [-p <pid>]
17 --dfusend <infile.dfu> [-p <pid>]
18 --dfureset [--loop [<sec>]] [-p <pid>]
19 --mkdfu-inst <bootloader.ipod> <outfile.dfu> [--single]
20 --mkdfu-uninst <platform> <outfile.dfu>
21 --mkdfu-raw <filename.bin> <outfile.dfu>
22
23Commands:
24 --bl-inst Install file <bootloader.ipod> into an iPod device
25 (same as --mkdfu-inst and --dfusend).
26 --bl-uninst Remove a bootloader from an iPod device (same as
27 --mkdfu-uninst and --dfusend).
28
29 --dfuscan scan for DFU USB devices and outputs the status.
30 --dfusend send DFU image <infile.dfu> to the device.
31 --dfureset reset DFU USB device bus.
32
33 --mkdfu-inst Build a DFU image containing an installer for
34 <bootloader.ipod>, save it as <outfile.dfu>.
35 --mkdfu-uninst Build a DFU image containing an uninstaler for
36 <platform> devices, save it as <outfile.dfu>.
37 --mkdfu-raw Build a DFU image containing raw executable
38 code, save it as <outfile.dfu>. <infile.bin>
39 is the code you want to run, it is loaded at
40 address 0x2200030c and executed.
41
42 <bootloader.ipod> is the rockbox bootloader that you want to
43 install (previously scrambled with tools/scramble utility).
44
45 <platform> is the name of the platform (type of device) for
46 which the DFU uninstaller will be built. Currently supported
47 platform names are:
48 ipod6g: iPod Classic 6G
49
50Options:
51 -p, --pid <pid> Use a specific <pid> (Product Id) USB device,
52 if this option is ommited then it uses the
53 first USB DFU device found.
54 -l, --loop <sec> Run the command every <sec> seconds, default
55 period (<sec> ommited) is 1 seconds.
56 -S, --single Be careful using this option. The bootloader
57 is installed for single boot, the original
58 Apple NOR boot is destroyed (if it exists),
59 and only Rockbox can be used.
60
61
62Dual bootloader installation
63----------------------------
64
65Prerequisites:
66
67 - An iPod Classic 6th with Apple firmware installed and running, current
68 supported FW versions for existing models:
69
70 Classic 6th 80/160 Late 2007 (1G): 1.1.2
71 Classic 6th 120 Late 2008 (2G): 2.0.1
72 Classic 6th 160 Late 2009 (3G): 2.0.4
73 Classic 6th 160 Late 2012 (4G): 2.0.5
74
75 - If your iPod is formated using Apple partitions you must convert this
76 ipod to FAT32 format (aka a "winpod"), see http://www.rockbox.org/
77 wiki/IpodConversionToFAT32
78
79 - It is recommended to install the RB firmware before installing the dual
80 bootloader for the first time. Install Rockbox using RockboxUtility or
81 download the latest daily build and uncompress it into the root folder
82 of the iPod.
83
84 Windows only:
85
86 - If iTunes is installed:
87 . Configure iTunes: Summary -> Options -> check "Enable disk use".
88
89 - If iTunes is not installed:
90 . You need a DFU USB driver for your device. To check if there is a
91 valid USB driver installed, put your device on DFU mode and choose
92 one of either:
93 a) Use Windows Device Manager to verify if you USB DFU device is
94 present.
95 b) Use mks5lboot tool running "mks5lboot --dfuscan", common output:
96 . When the DFU device is found and a valid driver is installed:
97 [INFO] DFU device state: 2
98 . When the device is found but there is no driver installed:
99 [ERR] Could not open USB device: LIBUSB_ERROR_NOT_SUPPORTED
100 . When the device is found but driver is not valid (probably a
101 libusb-win32 driver is installed):
102 [ERR] Could not set USB configuration: LIBUSB_ERROR_NOT_FOUND
103 . If there is no valid DFU driver installed, try one of these:
104 a) Use Zadig (http://zadig.akeo.ie/) to build and install a WinUSB
105 (libusb.info) or libusbK driver for your device. Note that
106 libusb-win32 (libusb0) drivers are not valid for mks5lboot.
107 b) Use Apple Mobile Device USB driver (included with iTunes). To
108 install this driver without iTunes see https://www.freemyipod.org
109 /wiki/EmCORE_Installation/iPodClassic/InstalliTunesDrivers
110
111Command line install:
112
113 - If you are using iTunes on Windows, close iTunes and kill (or pause)
114 iTunesHelper.exe before entering DFU mode.
115
116 - If you are using iTunes on Mac, quit iTunes and kill (or pause) the
117 iTunesHelper process before entering DFU mode.
118 You can use "ps x | grep iTunesHelper" to locate the process <PID>,
119 use "kill -STOP <PID>" to suspend the process and "kill -CONT <PID>"
120 to resume it once the bootloader is installed.
121
122 - Put you device on DFU mode by pressing and holding SELECT+MENU buttons
123 for about 12 seconds.
124
125 You can notice when the device enters DFU mode running the next command
126 to scan the USB bus every second (press Ctrl-C to abort the scan):
127 ./mks5lboot --dfuscan --loop
128
129 - To install or update a bootloader, build the DFU installer and send it
130 to the device:
131 ./mks5lboot --bl-inst path/to/bootloader-ipod6g.ipod
132
133 When the DFU image is loaded and executed, the device emits an 'alive'
134 tone (2000Hz/100ms). When the bootloader is successfully installed then
135 a dual tone beep sounds (1000Hz/100ms+2000Hz/150ms) and the device
136 reboots. If something went bad then 330Hz/500ms tone is emited and the
137 device reboots. When three 330Hz tones sounds, it means that the NOR
138 got corrupted and the device must be restored using iTunes (should not
139 happen).
140
141 - To remove a previously installed bootloader, build the DFU uninstaler
142 and send it to the device:
143 ./mks5lboot --bl-uninst ipod6g
144
145 Notes:
146
147 - If USB access is denied, try to run the mks5lboot tool using a privileged
148 user (i.e. Administrator or root).
149
150 - On Windows, use 'mks5lboot' or 'mks5lboot.exe' instead of './mks5lboot'.
151
152
153
154Dual-Boot
155---------
156
157The purpose of this program is to provide dual-boot between the original
158firmware and the new (rockbox) firmware.
159
160The button press check is done ~800 ms. after power-up or reboot, then:
161
162 SELECT + MENU: resets the device after ~5 seconds, then if SELECT+MENU
163 remains pressed the device enters DFU mode after an
164 additional period of ~8 seconds.
165 SELECT + LEFT: enter OF diagnostics (after ~7 seconds).
166 SELECT + PLAY: enter OF diskmode (after ~7 seconds).
167 SELECT + RIGHT: enter bootloader USB mode.
168 MENU: enter OF
169 Hold Switch locked: enter OF (see below for details).
170 Any other combination: launch Rockbox.
171
172Switch current firmware:
173
174 Tries to behave like ipod Video, see http://download.rockbox.org/manual/
175 rockbox-ipodvideo/rockbox-buildch3.html#x5-290003.1.3
176
177 Apple is the current FW:
178 - Stop playback and wait a few seconds for hard disk spin-down.
179 - Press and hold SELECT+MENU, after ~5 seconds the player hard resets,
180 release the buttons when the screen goes black.
181
182 Rockbox is the current FW:
183 - Shut down the device using "Long Play" key press.
184 - Once the device is powered off, there are three ways to enter OF:
185 1) Press and hold MENU button for at least ~800 ms.
186 2) Turn on the Hold switch immediately after turning the player on,
187 it must be done before "Loading Rockbox..." message appears (~3
188 seconds from power-on). Be careful, if the hold switch is locked
189 when Rockbox starts then your RB settings will be cleared!
190 3) You can also load the original firmware by shutting down the
191 device, then clicking the Hold switch on and connecting the iPod
192 to your computer.
193
194
195Single-Boot
196-----------
197
198Use --single option if the Apple firmware is not installed on your iPod
199and/or you want to force the installation of the bootloader to use Rockbox
200as unique firmware. The single-boot installer writes the bootloader on the
201NOR with no previous check, the original Apple NOR boot is destroyed if it
202exists.
203
204To build the DFU single-boot installer and send it to the device:
205 mks5lboot --bl-inst --single /path/to/bootloader-ipod6g.ipod
206
207
208Build
209-----
210
211To build type 'make'.
212
213Linux needs libusb >= 1.0, use your package manager to install libusb.
214
215For Windows, to build with libusb support type 'make USE_LIBUSBAPI=1'.
216
217Tested on:
218 Linux: gcc-4.9.2 + libusb-1.0.19
219 Windows XP: mingw32-gcc-4.8.1 + libusbx-1.0.15
220 OS X 10.11: clang-7.3.0 + libusb-1.0.20
221 MXE: i686-w64-mingw32.static-gcc 5.4.0 + libusb-1.0.21
222
223
224Hacking
225-------
226
227See comments in mkdfu.c, ipoddfu.c, dualboot.c and bootloader/ipod6g.c for
228more information.
diff --git a/utils/mks5lboot/dualboot.c b/utils/mks5lboot/dualboot.c
new file mode 100644
index 0000000000..4c1608fc41
--- /dev/null
+++ b/utils/mks5lboot/dualboot.c
@@ -0,0 +1,664 @@
1/* Generated by bin2c */
2
3#include "dualboot.h"
4
5unsigned char dualboot_install_ipod6g[5396] = {
6 0xd7, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x24, 0xd0, 0x9f, 0xe5, 0xdb, 0x00, 0xa0, 0xe3,
7 0x00, 0xf0, 0x21, 0xe1, 0x18, 0xd0, 0x9f, 0xe5, 0xd3, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1,
8 0x10, 0xd0, 0x9f, 0xe5, 0x05, 0x08, 0xa0, 0xe3, 0x78, 0x00, 0x80, 0xe3, 0x10, 0x0f, 0x01, 0xee,
9 0x1d, 0x00, 0x00, 0xeb, 0x0c, 0x03, 0x00, 0x22, 0x0c, 0x03, 0x00, 0x22, 0x7f, 0x40, 0x2d, 0xe9,
10 0x5c, 0x10, 0x9f, 0xe5, 0x10, 0x20, 0xa0, 0xe3, 0x0d, 0x00, 0xa0, 0xe1, 0xea, 0x04, 0x00, 0xeb,
11 0x00, 0x00, 0xa0, 0xe3, 0x02, 0x10, 0xa0, 0xe3, 0x0d, 0x20, 0xa0, 0xe1, 0x10, 0x30, 0xa0, 0xe3,
12 0x8d, 0x04, 0x00, 0xeb, 0x3c, 0x60, 0x9f, 0xe5, 0x0d, 0x40, 0xa0, 0xe1, 0x00, 0x50, 0xa0, 0xe3,
13 0x06, 0x10, 0xa0, 0xe1, 0x0d, 0x00, 0xa0, 0xe1, 0x10, 0x20, 0xa0, 0xe3, 0x77, 0x00, 0x00, 0xeb,
14 0x10, 0x60, 0x86, 0xe2, 0x00, 0x00, 0x50, 0xe3, 0x02, 0x00, 0x00, 0x0a, 0x01, 0x50, 0x85, 0xe2,
15 0x04, 0x00, 0x55, 0xe3, 0xf5, 0xff, 0xff, 0x1a, 0x05, 0x00, 0xa0, 0xe1, 0x10, 0xd0, 0x8d, 0xe2,
16 0x70, 0x80, 0xbd, 0xe8, 0x10, 0x00, 0x02, 0x22, 0x54, 0x17, 0x00, 0x22, 0x70, 0x40, 0x2d, 0xe9,
17 0xae, 0x00, 0x00, 0xeb, 0x7c, 0x41, 0x9f, 0xe5, 0x7c, 0x01, 0x9f, 0xe5, 0xa3, 0x04, 0x00, 0xeb,
18 0x00, 0x00, 0xa0, 0xe3, 0x04, 0x10, 0xa0, 0xe3, 0xc4, 0x00, 0x00, 0xeb, 0x0e, 0x30, 0xd4, 0xe5,
19 0x0d, 0x00, 0xd4, 0xe5, 0x0c, 0x10, 0xd4, 0xe5, 0x0f, 0x20, 0xd4, 0xe5, 0x03, 0x38, 0xa0, 0xe1,
20 0x00, 0x34, 0x83, 0xe1, 0x01, 0x30, 0x83, 0xe1, 0x02, 0x2c, 0x83, 0xe1, 0x40, 0x50, 0xd4, 0xe5,
21 0x02, 0x00, 0xa0, 0xe3, 0x02, 0x1b, 0x84, 0xe2, 0x10, 0x30, 0x84, 0xe2, 0xee, 0x01, 0x00, 0xeb,
22 0x40, 0x20, 0xa0, 0xe3, 0x02, 0x00, 0xa0, 0xe3, 0x04, 0x10, 0xa0, 0xe1, 0x02, 0x30, 0x84, 0xe0,
23 0xe9, 0x01, 0x00, 0xeb, 0x00, 0x00, 0x55, 0xe3, 0x08, 0x00, 0x00, 0x0a, 0x04, 0x10, 0xa0, 0xe1,
24 0x02, 0x09, 0xa0, 0xe3, 0x62, 0x03, 0x00, 0xeb, 0x10, 0x31, 0x9f, 0xe5, 0x10, 0x21, 0x9f, 0xe5,
25 0x00, 0x00, 0x50, 0xe3, 0x02, 0x00, 0xa0, 0x11, 0x03, 0x00, 0xa0, 0x01, 0x33, 0x00, 0x00, 0xea,
26 0x02, 0x09, 0xa0, 0xe3, 0xfc, 0x10, 0x9f, 0xe5, 0xfc, 0x20, 0x9f, 0xe5, 0x77, 0x03, 0x00, 0xeb,
27 0x00, 0x00, 0x50, 0xe3, 0x2c, 0x00, 0x00, 0x1a, 0xb7, 0xff, 0xff, 0xeb, 0x04, 0x00, 0x50, 0xe3,
28 0x0a, 0x00, 0x00, 0x1a, 0xdc, 0x00, 0x9f, 0xe5, 0xc5, 0x01, 0x00, 0xeb, 0xd4, 0x10, 0x9f, 0xe5,
29 0xd4, 0x20, 0x9f, 0xe5, 0x02, 0x09, 0x80, 0xe2, 0x6c, 0x03, 0x00, 0xeb, 0x00, 0x00, 0x50, 0xe3,
30 0x21, 0x00, 0x00, 0x1a, 0xac, 0xff, 0xff, 0xeb, 0x04, 0x00, 0x50, 0xe3, 0x1e, 0x00, 0x00, 0x0a,
31 0xa0, 0x00, 0x9f, 0xe5, 0xba, 0x01, 0x00, 0xeb, 0x00, 0x40, 0xa0, 0xe1, 0x23, 0x03, 0x00, 0xeb,
32 0x04, 0x00, 0x50, 0xe1, 0xa4, 0x00, 0x9f, 0x35, 0x18, 0x00, 0x00, 0x3a, 0x02, 0x09, 0x84, 0xe2,
33 0x90, 0x10, 0x9f, 0xe5, 0x3e, 0x03, 0x00, 0xeb, 0x00, 0x00, 0x50, 0xe3, 0x05, 0x00, 0x00, 0x0a,
34 0x02, 0x09, 0xa0, 0xe3, 0x6c, 0x10, 0x9f, 0xe5, 0x39, 0x03, 0x00, 0xeb, 0x00, 0x00, 0x50, 0xe3,
35 0x6c, 0x00, 0x9f, 0x15, 0x0d, 0x00, 0x00, 0x1a, 0x6c, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0xa0, 0xe3,
36 0x60, 0x10, 0x9f, 0xe5, 0xc8, 0x01, 0x00, 0xeb, 0x02, 0x09, 0xa0, 0xe3, 0x54, 0x10, 0x9f, 0xe5,
37 0x2f, 0x03, 0x00, 0xeb, 0x58, 0x30, 0x9f, 0xe5, 0x0c, 0x20, 0x83, 0xe2, 0x00, 0x00, 0x50, 0xe3,
38 0x03, 0x00, 0xa0, 0x01, 0x02, 0x00, 0xa0, 0x11, 0x00, 0x00, 0x00, 0xea, 0x2c, 0x00, 0x9f, 0xe5,
39 0x40, 0x20, 0x9f, 0xe5, 0x40, 0x30, 0x9f, 0xe5, 0xb4, 0x10, 0x92, 0xe5, 0x03, 0x00, 0x51, 0xe1,
40 0xfc, 0xff, 0xff, 0x9a, 0x49, 0x04, 0x00, 0xeb, 0x01, 0x26, 0xa0, 0xe3, 0xf2, 0x35, 0xa0, 0xe3,
41 0x00, 0x20, 0x83, 0xe5, 0xfe, 0xff, 0xff, 0xea, 0xd0, 0x17, 0x00, 0x22, 0x94, 0x17, 0x00, 0x22,
42 0x4c, 0x17, 0x00, 0x22, 0x9c, 0x17, 0x00, 0x22, 0x00, 0x00, 0x02, 0x22, 0x00, 0x08, 0x02, 0x22,
43 0x46, 0x17, 0x00, 0x22, 0x40, 0x17, 0x00, 0x22, 0x00, 0x00, 0x70, 0x3c, 0x7f, 0x84, 0x1e, 0x00,
44 0x10, 0x40, 0x2d, 0xe9, 0x00, 0x30, 0xa0, 0xe3, 0x07, 0x00, 0x00, 0xea, 0x03, 0x40, 0xd0, 0xe7,
45 0x03, 0xc0, 0xd1, 0xe7, 0x01, 0x20, 0x42, 0xe2, 0x0c, 0x00, 0x54, 0xe1, 0x01, 0x30, 0x83, 0xe2,
46 0x01, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x6c, 0xe0, 0x10, 0x80, 0xbd, 0xe8, 0x00, 0x00, 0x52, 0xe3,
47 0xf5, 0xff, 0xff, 0x1a, 0x02, 0x00, 0xa0, 0xe1, 0x10, 0x80, 0xbd, 0xe8, 0x1f, 0x30, 0x00, 0xe2,
48 0x01, 0x20, 0xa0, 0xe3, 0xc0, 0x02, 0xa0, 0xe1, 0x00, 0x00, 0x51, 0xe3, 0x12, 0x33, 0xa0, 0xe1,
49 0x02, 0x20, 0x00, 0xe0, 0x08, 0x00, 0x00, 0x0a, 0x3c, 0x10, 0x9f, 0xe5, 0x3c, 0x00, 0x9f, 0xe5,
50 0x00, 0x00, 0x52, 0xe3, 0x00, 0x20, 0xa0, 0x11, 0x01, 0x20, 0xa0, 0x01, 0x00, 0x10, 0x92, 0xe5,
51 0x03, 0x30, 0xc1, 0xe1, 0x00, 0x30, 0x82, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x18, 0x10, 0x9f, 0xe5,
52 0x18, 0x00, 0x9f, 0xe5, 0x00, 0x00, 0x52, 0xe3, 0x01, 0x00, 0xa0, 0x01, 0x00, 0x20, 0x90, 0xe5,
53 0x03, 0x30, 0x82, 0xe1, 0x00, 0x30, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x48, 0x00, 0x50, 0x3c,
54 0x4c, 0x00, 0x50, 0x3c, 0x70, 0x40, 0x2d, 0xe9, 0x10, 0x50, 0x9d, 0xe5, 0x01, 0x30, 0x43, 0xe2,
55 0x01, 0x50, 0x45, 0xe2, 0x03, 0x60, 0x02, 0xe2, 0x0f, 0x30, 0x03, 0xe2, 0x05, 0x52, 0xa0, 0xe1,
56 0x03, 0xc0, 0xc0, 0xe3, 0xff, 0x50, 0x05, 0xe2, 0x06, 0x36, 0x83, 0xe1, 0x00, 0x40, 0x9c, 0xe5,
57 0x05, 0x30, 0x83, 0xe1, 0x30, 0x50, 0x9f, 0xe5, 0x02, 0x20, 0x00, 0xe2, 0x82, 0x21, 0xa0, 0xe1,
58 0x00, 0x00, 0x51, 0xe3, 0x02, 0x19, 0xa0, 0x03, 0x00, 0x10, 0xa0, 0x13, 0x35, 0x42, 0x04, 0xe0,
59 0x01, 0x30, 0x83, 0xe1, 0x13, 0x22, 0x84, 0xe1, 0x00, 0x20, 0x8c, 0xe5, 0xb0, 0x20, 0xd0, 0xe1,
60 0x03, 0x00, 0x52, 0xe1, 0xfc, 0xff, 0xff, 0x1a, 0x70, 0x80, 0xbd, 0xe8, 0x00, 0x00, 0xff, 0xff,
61 0x5c, 0xc0, 0x9f, 0xe5, 0x13, 0x40, 0x2d, 0xe9, 0x44, 0xe0, 0x9c, 0xe5, 0x01, 0x40, 0xa0, 0xe3,
62 0x01, 0xec, 0xce, 0xe3, 0x00, 0x20, 0xa0, 0xe3, 0x04, 0x30, 0xa0, 0xe1, 0x44, 0xe0, 0x8c, 0xe5,
63 0x40, 0x00, 0x9f, 0xe5, 0x04, 0x10, 0xa0, 0xe1, 0x00, 0x40, 0x8d, 0xe5, 0xd8, 0xff, 0xff, 0xeb,
64 0x04, 0x10, 0xa0, 0xe1, 0x25, 0x00, 0xa0, 0xe3, 0xbb, 0xff, 0xff, 0xeb, 0x28, 0x30, 0x9f, 0xe5,
65 0x11, 0x2d, 0xa0, 0xe3, 0xa0, 0x20, 0x83, 0xe5, 0x0b, 0x20, 0xa0, 0xe3, 0xb0, 0x20, 0x83, 0xe5,
66 0x00, 0x20, 0xe0, 0xe3, 0xa8, 0x20, 0x83, 0xe5, 0x04, 0x20, 0x82, 0xe2, 0xa4, 0x20, 0x83, 0xe5,
67 0x1c, 0x80, 0xbd, 0xe8, 0x00, 0x00, 0x50, 0x3c, 0x12, 0x00, 0x50, 0x3c, 0x00, 0x00, 0x70, 0x3c,
68 0x04, 0x30, 0x9f, 0xe5, 0x00, 0x11, 0x83, 0xe7, 0x1e, 0xff, 0x2f, 0xe1, 0xac, 0x17, 0x00, 0x22,
69 0x80, 0x20, 0x9f, 0xe5, 0x00, 0x00, 0x51, 0xe3, 0x7c, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x11,
70 0x01, 0x00, 0x50, 0xe3, 0x0a, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x50, 0xe3, 0x0f, 0x00, 0x00, 0x0a,
71 0x00, 0x00, 0x50, 0xe3, 0x1e, 0xff, 0x2f, 0x11, 0x60, 0x10, 0x9f, 0xe5, 0x00, 0x20, 0x91, 0xe5,
72 0x22, 0x28, 0xa0, 0xe1, 0x02, 0x28, 0xa0, 0xe1, 0x02, 0x30, 0x83, 0xe1, 0x00, 0x30, 0x81, 0xe5,
73 0x1e, 0xff, 0x2f, 0xe1, 0x44, 0x10, 0x9f, 0xe5, 0xc0, 0x20, 0x91, 0xe5, 0x02, 0x28, 0xa0, 0xe1,
74 0x22, 0x28, 0xa0, 0xe1, 0x03, 0x38, 0x82, 0xe1, 0xc0, 0x30, 0x81, 0xe5, 0x1e, 0xff, 0x2f, 0xe1,
75 0x28, 0x00, 0x9f, 0xe5, 0xc0, 0x21, 0x90, 0xe5, 0xff, 0x24, 0xc2, 0xe3, 0x03, 0x2c, 0x82, 0xe1,
76 0xc0, 0x21, 0x80, 0xe5, 0xe0, 0x21, 0x90, 0xe5, 0xff, 0x20, 0xc2, 0xe3, 0x23, 0x34, 0x82, 0xe1,
77 0xe0, 0x31, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x22, 0x22, 0x00, 0x00, 0xef, 0xee, 0x00, 0x00,
78 0x00, 0x00, 0xf0, 0x3c, 0x01, 0x00, 0x50, 0xe3, 0x01, 0x10, 0x21, 0xe2, 0x06, 0x00, 0x00, 0x0a,
79 0x02, 0x00, 0x50, 0xe3, 0x06, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x50, 0xe3, 0x24, 0x30, 0x9f, 0x05,
80 0x0e, 0x10, 0x81, 0x03, 0x00, 0x12, 0x83, 0x05, 0x1e, 0xff, 0x2f, 0xe1, 0x18, 0x30, 0x9f, 0xe5,
81 0x00, 0x00, 0x00, 0xea, 0x14, 0x30, 0x9f, 0xe5, 0x08, 0x20, 0x9f, 0xe5, 0x03, 0x30, 0x81, 0xe1,
82 0x00, 0x32, 0x82, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0xf0, 0x3c, 0x0e, 0x04, 0x06, 0x00,
83 0x0e, 0x06, 0x0e, 0x00, 0x02, 0x00, 0x50, 0xe3, 0x10, 0x40, 0x2d, 0xe9, 0xbc, 0x30, 0x9f, 0x05,
84 0x03, 0x00, 0x00, 0x0a, 0xb8, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3, 0xb4, 0x30, 0x9f, 0xe5,
85 0x02, 0x30, 0xa0, 0x01, 0xb0, 0x40, 0x9f, 0xe5, 0xb0, 0xc0, 0x9f, 0xe5, 0x01, 0x20, 0xa0, 0xe3,
86 0x00, 0x20, 0x83, 0xe5, 0x02, 0x00, 0x50, 0xe3, 0xa4, 0x30, 0x9f, 0x05, 0x02, 0x00, 0x00, 0x0a,
87 0x01, 0x00, 0x50, 0xe3, 0x04, 0x30, 0xa0, 0x01, 0x0c, 0x30, 0xa0, 0x11, 0x00, 0x30, 0x93, 0xe5,
88 0x1f, 0x3e, 0x03, 0xe2, 0x01, 0x0c, 0x53, 0xe3, 0xf5, 0xff, 0xff, 0x0a, 0x02, 0x00, 0x50, 0xe3,
89 0x80, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0x7c, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3,
90 0x78, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0x5c, 0xc0, 0x9f, 0xe5, 0x5c, 0x20, 0x9f, 0xe5,
91 0x00, 0x10, 0x83, 0xe5, 0x02, 0x00, 0x50, 0xe3, 0x54, 0x30, 0x9f, 0x05, 0x02, 0x00, 0x00, 0x0a,
92 0x01, 0x00, 0x50, 0xe3, 0x0c, 0x30, 0xa0, 0x01, 0x02, 0x30, 0xa0, 0x11, 0x00, 0x30, 0x93, 0xe5,
93 0x3e, 0x0c, 0x13, 0xe3, 0xf6, 0xff, 0xff, 0x0a, 0x02, 0x00, 0x50, 0xe3, 0x40, 0x00, 0x9f, 0x05,
94 0x04, 0x00, 0x00, 0x0a, 0x3c, 0x30, 0x9f, 0xe5, 0x3c, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3,
95 0x02, 0x00, 0xa0, 0x01, 0x03, 0x00, 0xa0, 0x11, 0x00, 0x00, 0x90, 0xe5, 0x10, 0x80, 0xbd, 0xe8,
96 0x34, 0x00, 0x20, 0x3d, 0x34, 0x00, 0xe0, 0x3c, 0x34, 0x00, 0x30, 0x3c, 0x08, 0x00, 0xe0, 0x3c,
97 0x08, 0x00, 0x30, 0x3c, 0x08, 0x00, 0x20, 0x3d, 0x10, 0x00, 0x20, 0x3d, 0x10, 0x00, 0xe0, 0x3c,
98 0x10, 0x00, 0x30, 0x3c, 0x20, 0x00, 0x20, 0x3d, 0x20, 0x00, 0x30, 0x3c, 0x20, 0x00, 0xe0, 0x3c,
99 0x02, 0x00, 0x50, 0xe3, 0xf0, 0x40, 0x2d, 0xe9, 0xd8, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a,
100 0xd4, 0xc0, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3, 0xd0, 0x30, 0x9f, 0xe5, 0x0c, 0x30, 0xa0, 0x01,
101 0x02, 0x00, 0x50, 0xe3, 0x00, 0x10, 0x83, 0xe5, 0xc4, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a,
102 0xc0, 0xc0, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3, 0xbc, 0x30, 0x9f, 0xe5, 0x0c, 0x30, 0xa0, 0x01,
103 0x00, 0x40, 0x93, 0xe5, 0x00, 0xc0, 0xa0, 0xe3, 0x01, 0x40, 0x84, 0xe3, 0x00, 0x40, 0x83, 0xe5,
104 0xa8, 0x70, 0x9f, 0xe5, 0xa8, 0x60, 0x9f, 0xe5, 0xa8, 0x50, 0x9f, 0xe5, 0xa8, 0x40, 0x9f, 0xe5,
105 0x12, 0x00, 0x00, 0xea, 0x02, 0x00, 0x50, 0xe3, 0xa0, 0x30, 0x9f, 0x05, 0x02, 0x00, 0x00, 0x0a,
106 0x01, 0x00, 0x50, 0xe3, 0x07, 0x30, 0xa0, 0x01, 0x06, 0x30, 0xa0, 0x11, 0x00, 0x30, 0x93, 0xe5,
107 0x3e, 0x0c, 0x13, 0xe3, 0xf6, 0xff, 0xff, 0x0a, 0x02, 0x00, 0x50, 0xe3, 0x80, 0x30, 0x9f, 0x05,
108 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x05, 0x30, 0xa0, 0x01, 0x04, 0x30, 0xa0, 0x11,
109 0x00, 0x30, 0x93, 0xe5, 0x01, 0x10, 0x41, 0xe2, 0x0c, 0x30, 0xc2, 0xe7, 0x01, 0xc0, 0x8c, 0xe2,
110 0x00, 0x00, 0x51, 0xe3, 0xea, 0xff, 0xff, 0x1a, 0x02, 0x00, 0x50, 0xe3, 0x30, 0x00, 0x9f, 0x05,
111 0x04, 0x00, 0x00, 0x0a, 0x2c, 0x30, 0x9f, 0xe5, 0x2c, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3,
112 0x02, 0x00, 0xa0, 0x11, 0x03, 0x00, 0xa0, 0x01, 0x00, 0x30, 0x90, 0xe5, 0x01, 0x30, 0xc3, 0xe3,
113 0x00, 0x30, 0x80, 0xe5, 0xf0, 0x80, 0xbd, 0xe8, 0x34, 0x00, 0x20, 0x3d, 0x34, 0x00, 0xe0, 0x3c,
114 0x34, 0x00, 0x30, 0x3c, 0x04, 0x00, 0x20, 0x3d, 0x04, 0x00, 0xe0, 0x3c, 0x04, 0x00, 0x30, 0x3c,
115 0x08, 0x00, 0xe0, 0x3c, 0x08, 0x00, 0x30, 0x3c, 0x20, 0x00, 0xe0, 0x3c, 0x20, 0x00, 0x30, 0x3c,
116 0x08, 0x00, 0x20, 0x3d, 0x20, 0x00, 0x20, 0x3d, 0x02, 0x00, 0x50, 0xe3, 0x2e, 0x00, 0x80, 0x02,
117 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x2b, 0x00, 0xa0, 0x03, 0x22, 0x00, 0xa0, 0x13,
118 0x00, 0x10, 0xa0, 0xe3, 0xe4, 0xfe, 0xff, 0xea, 0x02, 0x00, 0x50, 0xe3, 0x10, 0x40, 0x2d, 0xe9,
119 0x00, 0x40, 0xa0, 0xe1, 0x30, 0x00, 0xa0, 0x03, 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x54, 0xe3,
120 0x2b, 0x00, 0xa0, 0x03, 0x22, 0x00, 0xa0, 0x13, 0x01, 0x10, 0xa0, 0xe3, 0xda, 0xfe, 0xff, 0xeb,
121 0x02, 0x00, 0x54, 0xe3, 0x04, 0x31, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0x00, 0x21, 0x9f, 0xe5,
122 0x01, 0x00, 0x54, 0xe3, 0xfc, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0x02, 0x00, 0x54, 0xe3,
123 0x0f, 0x20, 0xa0, 0xe3, 0x00, 0x20, 0x83, 0xe5, 0xec, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a,
124 0xe8, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3, 0xe4, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01,
125 0x00, 0x20, 0x93, 0xe5, 0x02, 0x00, 0x54, 0xe3, 0x0c, 0x20, 0x82, 0xe3, 0x00, 0x20, 0x83, 0xe5,
126 0xd0, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0xcc, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3,
127 0xc8, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0xc4, 0x20, 0x9f, 0xe5, 0x02, 0x00, 0x54, 0xe3,
128 0x04, 0x21, 0x92, 0xe7, 0x00, 0x20, 0x83, 0xe5, 0xb8, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a,
129 0xb4, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3, 0xb0, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01,
130 0x02, 0x00, 0x54, 0xe3, 0x06, 0x20, 0xa0, 0xe3, 0x00, 0x20, 0x83, 0xe5, 0xa0, 0x30, 0x9f, 0x05,
131 0x03, 0x00, 0x00, 0x0a, 0x9c, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3, 0x98, 0x30, 0x9f, 0xe5,
132 0x02, 0x30, 0xa0, 0x01, 0x94, 0x20, 0x9f, 0xe5, 0x02, 0x00, 0x54, 0xe3, 0x00, 0x20, 0x83, 0xe5,
133 0x54, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0x50, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3,
134 0x4c, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0x00, 0x20, 0x93, 0xe5, 0x02, 0x00, 0x54, 0xe3,
135 0x0c, 0x20, 0x82, 0xe3, 0x00, 0x20, 0x83, 0xe5, 0x2c, 0x40, 0x9f, 0x05, 0x04, 0x00, 0x00, 0x0a,
136 0x2c, 0x30, 0x9f, 0xe5, 0x24, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3, 0x02, 0x40, 0xa0, 0x01,
137 0x03, 0x40, 0xa0, 0x11, 0x01, 0x30, 0xa0, 0xe3, 0x00, 0x30, 0x84, 0xe5, 0x10, 0x80, 0xbd, 0xe8,
138 0x08, 0x00, 0x20, 0x3d, 0x08, 0x00, 0xe0, 0x3c, 0x08, 0x00, 0x30, 0x3c, 0x00, 0x00, 0x20, 0x3d,
139 0x00, 0x00, 0xe0, 0x3c, 0x00, 0x00, 0x30, 0x3c, 0x30, 0x00, 0x20, 0x3d, 0x30, 0x00, 0xe0, 0x3c,
140 0x30, 0x00, 0x30, 0x3c, 0xac, 0x17, 0x00, 0x22, 0x0c, 0x00, 0x20, 0x3d, 0x0c, 0x00, 0xe0, 0x3c,
141 0x0c, 0x00, 0x30, 0x3c, 0x04, 0x00, 0x20, 0x3d, 0x04, 0x00, 0xe0, 0x3c, 0x04, 0x00, 0x30, 0x3c,
142 0x18, 0x06, 0x01, 0x00, 0x0c, 0x30, 0x80, 0xe2, 0x02, 0xc0, 0xd3, 0xe5, 0x01, 0x10, 0xd3, 0xe5,
143 0x0c, 0x20, 0xd0, 0xe5, 0x03, 0x30, 0xd3, 0xe5, 0x0c, 0x08, 0xa0, 0xe1, 0x01, 0x04, 0x80, 0xe1,
144 0x02, 0x00, 0x80, 0xe1, 0x03, 0x0c, 0x80, 0xe1, 0x5f, 0x0d, 0x80, 0xe2, 0x3f, 0x00, 0x80, 0xe2,
145 0xff, 0x0e, 0xc0, 0xe3, 0x0f, 0x00, 0xc0, 0xe3, 0x1e, 0xff, 0x2f, 0xe1, 0x70, 0x40, 0x2d, 0xe9,
146 0x18, 0xd0, 0x4d, 0xe2, 0x04, 0x40, 0x8d, 0xe2, 0x03, 0x50, 0xa0, 0xe1, 0x00, 0x60, 0xa0, 0xe1,
147 0x01, 0x00, 0xa0, 0xe1, 0x02, 0x10, 0xa0, 0xe1, 0x04, 0x20, 0xa0, 0xe1, 0xf5, 0x01, 0x00, 0xeb,
148 0x04, 0x10, 0xa0, 0xe1, 0x05, 0x00, 0xa0, 0xe1, 0x10, 0x20, 0xa0, 0xe3, 0xc2, 0x02, 0x00, 0xeb,
149 0x06, 0x10, 0xa0, 0xe1, 0x05, 0x20, 0xa0, 0xe1, 0x01, 0x00, 0xa0, 0xe3, 0x10, 0x30, 0xa0, 0xe3,
150 0x65, 0x02, 0x00, 0xeb, 0x18, 0xd0, 0x8d, 0xe2, 0x70, 0x80, 0xbd, 0xe8, 0x01, 0x00, 0x50, 0xe3,
151 0xf0, 0x47, 0x2d, 0xe9, 0x0c, 0x50, 0xd1, 0xe5, 0x0c, 0x30, 0x81, 0xe2, 0x00, 0x40, 0xa0, 0xe1,
152 0x01, 0x00, 0xa0, 0x03, 0x02, 0x00, 0xa0, 0x13, 0x03, 0x80, 0xd3, 0xe5, 0x02, 0x70, 0xd3, 0xe5,
153 0x01, 0x60, 0xd3, 0xe5, 0x02, 0xa0, 0xa0, 0xe1, 0x07, 0x00, 0xc1, 0xe5, 0x40, 0x30, 0x81, 0xe2,
154 0x02, 0x00, 0xa0, 0xe3, 0x40, 0x20, 0xa0, 0xe3, 0xdb, 0xff, 0xff, 0xeb, 0x07, 0x78, 0xa0, 0xe1,
155 0x06, 0x64, 0x87, 0xe1, 0x05, 0x50, 0x86, 0xe1, 0x08, 0x3c, 0x85, 0xe1, 0x04, 0x00, 0xa0, 0xe1,
156 0x0a, 0x20, 0xa0, 0xe1, 0x02, 0x10, 0xa0, 0xe3, 0xf0, 0x47, 0xbd, 0xe8, 0x4a, 0x02, 0x00, 0xea,
157 0x10, 0x40, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
158 0xbf, 0xfe, 0xff, 0xeb, 0x05, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0xd0, 0xfe, 0xff, 0xeb,
159 0xff, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0xcd, 0xfe, 0xff, 0xeb, 0x00, 0x10, 0xa0, 0xe3,
160 0x01, 0x30, 0x10, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x00, 0x00, 0x0a, 0xb4, 0xfe, 0xff, 0xeb,
161 0xf0, 0xff, 0xff, 0xea, 0x04, 0x00, 0xa0, 0xe1, 0x03, 0x10, 0xa0, 0xe1, 0x10, 0x40, 0xbd, 0xe8,
162 0xaf, 0xfe, 0xff, 0xea, 0x70, 0x40, 0x2d, 0xe9, 0x00, 0x50, 0x51, 0xe2, 0x00, 0x40, 0xa0, 0xe1,
163 0x07, 0x00, 0x00, 0x1a, 0x01, 0x10, 0x81, 0xe2, 0xa9, 0xfe, 0xff, 0xeb, 0x04, 0x10, 0xa0, 0xe3,
164 0x04, 0x00, 0xa0, 0xe1, 0xba, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x05, 0x10, 0xa0, 0xe1,
165 0xa3, 0xfe, 0xff, 0xeb, 0x01, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0xa0, 0xfe, 0xff, 0xeb,
166 0x50, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0xb1, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
167 0x00, 0x10, 0xa0, 0xe3, 0x9a, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
168 0x97, 0xfe, 0xff, 0xeb, 0x01, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0xa8, 0xfe, 0xff, 0xeb,
169 0x00, 0x00, 0x55, 0xe3, 0x1c, 0x10, 0xa0, 0x03, 0x00, 0x10, 0xa0, 0x13, 0x04, 0x00, 0xa0, 0xe1,
170 0xa3, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0x8c, 0xfe, 0xff, 0xeb,
171 0x00, 0x00, 0x55, 0xe3, 0x70, 0x80, 0xbd, 0x08, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
172 0x87, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x06, 0x10, 0xa0, 0xe3, 0x98, 0xfe, 0xff, 0xeb,
173 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0x70, 0x40, 0xbd, 0xe8, 0x80, 0xfe, 0xff, 0xea,
174 0x70, 0x40, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x01, 0x50, 0xa0, 0xe1, 0x1d, 0xff, 0xff, 0xeb,
175 0x04, 0x00, 0xa0, 0xe1, 0xb5, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
176 0xc7, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0x74, 0xfe, 0xff, 0xeb,
177 0x04, 0x00, 0xa0, 0xe1, 0x20, 0x10, 0xa0, 0xe3, 0x85, 0xfe, 0xff, 0xeb, 0x25, 0x18, 0xa0, 0xe1,
178 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x81, 0xfe, 0xff, 0xeb, 0x25, 0x14, 0xa0, 0xe1,
179 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x7d, 0xfe, 0xff, 0xeb, 0xff, 0x10, 0x05, 0xe2,
180 0x04, 0x00, 0xa0, 0xe1, 0x7a, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3,
181 0x63, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0xb0, 0xff, 0xff, 0xeb,
182 0x04, 0x00, 0xa0, 0xe1, 0x70, 0x40, 0xbd, 0xe8, 0xf6, 0xfe, 0xff, 0xea, 0xf0, 0x45, 0x2d, 0xe9,
183 0x00, 0x40, 0xa0, 0xe1, 0x24, 0xd0, 0x4d, 0xe2, 0x02, 0x50, 0xa0, 0xe1, 0x03, 0x70, 0xa0, 0xe1,
184 0x01, 0x60, 0xa0, 0xe1, 0xf7, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x8f, 0xff, 0xff, 0xeb,
185 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0x51, 0xfe, 0xff, 0xeb, 0x03, 0x10, 0xa0, 0xe3,
186 0x04, 0x00, 0xa0, 0xe1, 0x62, 0xfe, 0xff, 0xeb, 0x26, 0x18, 0xa0, 0xe1, 0xff, 0x10, 0x01, 0xe2,
187 0x04, 0x00, 0xa0, 0xe1, 0x5e, 0xfe, 0xff, 0xeb, 0x26, 0x14, 0xa0, 0xe1, 0xff, 0x10, 0x01, 0xe2,
188 0x04, 0x00, 0xa0, 0xe1, 0x5a, 0xfe, 0xff, 0xeb, 0xff, 0x10, 0x06, 0xe2, 0x04, 0x00, 0xa0, 0xe1,
189 0x57, 0xfe, 0xff, 0xeb, 0x00, 0x60, 0xa0, 0xe3, 0x0d, 0x80, 0xa0, 0xe1, 0x15, 0x00, 0x00, 0xea,
190 0x20, 0x00, 0x57, 0xe3, 0x07, 0xa0, 0xa0, 0xb1, 0x20, 0xa0, 0xa0, 0xa3, 0x04, 0x00, 0xa0, 0xe1,
191 0x0a, 0x10, 0xa0, 0xe1, 0x0d, 0x20, 0xa0, 0xe1, 0x8c, 0xfe, 0xff, 0xeb, 0x05, 0x00, 0xa0, 0xe1,
192 0x0d, 0x10, 0xa0, 0xe1, 0x0a, 0x20, 0xa0, 0xe1, 0xac, 0xfd, 0xff, 0xeb, 0x00, 0x30, 0xa0, 0xe3,
193 0x00, 0x00, 0x50, 0xe3, 0x01, 0x60, 0x86, 0x13, 0x03, 0x20, 0xd8, 0xe7, 0x02, 0x30, 0x83, 0xe2,
194 0xff, 0x00, 0x52, 0xe3, 0x02, 0x60, 0x86, 0x13, 0x0a, 0x00, 0x53, 0xe1, 0xf9, 0xff, 0xff, 0xba,
195 0x20, 0x50, 0x85, 0xe2, 0x20, 0x70, 0x47, 0xe2, 0x00, 0x00, 0x57, 0xe3, 0xe7, 0xff, 0xff, 0xca,
196 0x00, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0x25, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
197 0xbc, 0xfe, 0xff, 0xeb, 0x06, 0x00, 0xa0, 0xe1, 0x24, 0xd0, 0x8d, 0xe2, 0xf0, 0x85, 0xbd, 0xe8,
198 0xf0, 0x4f, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x14, 0xd0, 0x4d, 0xe2, 0x01, 0x50, 0xa0, 0xe1,
199 0x02, 0x70, 0xa0, 0xe1, 0x03, 0x80, 0xa0, 0xe1, 0x53, 0x00, 0x00, 0xea, 0x05, 0x6a, 0xa0, 0xe1,
200 0x26, 0x6a, 0xa0, 0xe1, 0x01, 0x6a, 0x66, 0xe2, 0x08, 0x00, 0x56, 0xe1, 0x08, 0x60, 0xa0, 0xa1,
201 0x04, 0x00, 0xa0, 0xe1, 0x05, 0x10, 0xa0, 0xe1, 0x07, 0x20, 0xa0, 0xe1, 0x06, 0x30, 0xa0, 0xe1,
202 0xb1, 0xff, 0xff, 0xeb, 0x01, 0x00, 0x10, 0xe3, 0x44, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x10, 0xe3,
203 0x03, 0x00, 0x00, 0x0a, 0xff, 0x1e, 0xc5, 0xe3, 0x0f, 0x10, 0xc1, 0xe3, 0x04, 0x00, 0xa0, 0xe1,
204 0x86, 0xff, 0xff, 0xeb, 0x00, 0x30, 0xa0, 0xe3, 0x03, 0x20, 0xd7, 0xe7, 0x07, 0x90, 0xa0, 0xe1,
205 0xff, 0x00, 0x52, 0xe3, 0x01, 0x30, 0x83, 0xe2, 0x02, 0x00, 0x00, 0x1a, 0x06, 0x00, 0x53, 0xe1,
206 0xf8, 0xff, 0xff, 0xba, 0x35, 0x00, 0x00, 0xea, 0x04, 0x00, 0xa0, 0xe1, 0x9d, 0xfe, 0xff, 0xeb,
207 0x04, 0x00, 0xa0, 0xe1, 0x35, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
208 0x47, 0xff, 0xff, 0xeb, 0x25, 0x34, 0xa0, 0xe1, 0xff, 0x30, 0x03, 0xe2, 0x25, 0x28, 0xa0, 0xe1,
209 0xff, 0x20, 0x02, 0xe2, 0x08, 0x30, 0x8d, 0xe5, 0x06, 0xa0, 0xa0, 0xe1, 0xff, 0x30, 0x05, 0xe2,
210 0x01, 0xb0, 0xa0, 0xe3, 0x04, 0x20, 0x8d, 0xe5, 0x0c, 0x30, 0x8d, 0xe5, 0x04, 0x00, 0xa0, 0xe1,
211 0x01, 0x10, 0xa0, 0xe3, 0xea, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0xad, 0x10, 0xa0, 0xe3,
212 0xfb, 0xfd, 0xff, 0xeb, 0x00, 0x00, 0x5b, 0xe3, 0x00, 0xb0, 0xa0, 0xe3, 0x08, 0x00, 0x00, 0x0a,
213 0x04, 0x10, 0x9d, 0xe5, 0x04, 0x00, 0xa0, 0xe1, 0xf5, 0xfd, 0xff, 0xeb, 0x08, 0x10, 0x9d, 0xe5,
214 0x04, 0x00, 0xa0, 0xe1, 0xf2, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x0c, 0x10, 0x9d, 0xe5,
215 0xef, 0xfd, 0xff, 0xeb, 0x00, 0x10, 0xd9, 0xe5, 0x04, 0x00, 0xa0, 0xe1, 0xec, 0xfd, 0xff, 0xeb,
216 0x01, 0x10, 0xd9, 0xe5, 0x04, 0x00, 0xa0, 0xe1, 0xe9, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
217 0x00, 0x10, 0xa0, 0xe3, 0xd2, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x0b, 0xff, 0xff, 0xeb,
218 0x02, 0xa0, 0x5a, 0xe2, 0x02, 0x90, 0x89, 0xe2, 0xdf, 0xff, 0xff, 0x1a, 0x04, 0x00, 0xa0, 0xe1,
219 0x0a, 0x10, 0xa0, 0xe1, 0x1a, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x61, 0xfe, 0xff, 0xeb,
220 0x08, 0x80, 0x66, 0xe0, 0x06, 0x70, 0x87, 0xe0, 0x06, 0x50, 0x85, 0xe0, 0x00, 0x00, 0x58, 0xe3,
221 0xa9, 0xff, 0xff, 0xca, 0x14, 0xd0, 0x8d, 0xe2, 0xf0, 0x8f, 0xbd, 0xe8, 0xf0, 0x41, 0x2d, 0xe9,
222 0x00, 0x40, 0xa0, 0xe1, 0x03, 0x50, 0xa0, 0xe1, 0x02, 0x70, 0xa0, 0xe1, 0x01, 0x60, 0xa0, 0xe1,
223 0x5c, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0xf4, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
224 0x01, 0x10, 0xa0, 0xe3, 0xb6, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x03, 0x10, 0xa0, 0xe3,
225 0xc7, 0xfd, 0xff, 0xeb, 0x26, 0x18, 0xa0, 0xe1, 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1,
226 0xc3, 0xfd, 0xff, 0xeb, 0x26, 0x14, 0xa0, 0xe1, 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1,
227 0xbf, 0xfd, 0xff, 0xeb, 0xff, 0x10, 0x06, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0xbc, 0xfd, 0xff, 0xeb,
228 0x04, 0x00, 0xa0, 0xe1, 0x07, 0x10, 0xa0, 0xe1, 0x05, 0x20, 0xa0, 0xe1, 0xf7, 0xfd, 0xff, 0xeb,
229 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0xa1, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
230 0xf0, 0x41, 0xbd, 0xe8, 0x37, 0xfe, 0xff, 0xea, 0x00, 0x10, 0xa0, 0xe3, 0x77, 0xfd, 0xff, 0xea,
231 0x10, 0x40, 0x2d, 0xe9, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x40, 0xa0, 0xe1, 0x73, 0xfd, 0xff, 0xeb,
232 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0x10, 0x40, 0xbd, 0xe8, 0x94, 0xfd, 0xff, 0xea,
233 0xf0, 0x40, 0x2d, 0xe9, 0x6c, 0x40, 0x9f, 0xe5, 0x2c, 0xd0, 0x4d, 0xe2, 0x00, 0x00, 0xa0, 0xe3,
234 0xf2, 0xff, 0xff, 0xeb, 0x60, 0x70, 0x9f, 0xe5, 0x04, 0x50, 0xa0, 0xe1, 0x0d, 0x60, 0xa0, 0xe1,
235 0x04, 0x10, 0xa0, 0xe1, 0x28, 0x20, 0xa0, 0xe3, 0x0d, 0x30, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3,
236 0xc5, 0xff, 0xff, 0xeb, 0x0d, 0x00, 0xa0, 0xe1, 0x40, 0x10, 0x9f, 0xe5, 0x04, 0x20, 0xa0, 0xe3,
237 0xfa, 0xfc, 0xff, 0xeb, 0x28, 0x40, 0x84, 0xe2, 0x00, 0x00, 0x50, 0xe3, 0x04, 0x00, 0x00, 0x1a,
238 0x0c, 0x30, 0x9d, 0xe5, 0x03, 0x00, 0x55, 0xe1, 0x03, 0x50, 0xa0, 0x21, 0x07, 0x00, 0x54, 0xe1,
239 0xee, 0xff, 0xff, 0x1a, 0x00, 0x00, 0xa0, 0xe3, 0xda, 0xff, 0xff, 0xeb, 0x0a, 0x09, 0x45, 0xe2,
240 0x2c, 0xd0, 0x8d, 0xe2, 0xf0, 0x80, 0xbd, 0xe8, 0x00, 0xfe, 0x0f, 0x00, 0xe0, 0xff, 0x0f, 0x00,
241 0xb8, 0x17, 0x00, 0x22, 0x0c, 0x30, 0x81, 0xe2, 0x70, 0x40, 0x2d, 0xe9, 0x02, 0x50, 0xd3, 0xe5,
242 0x01, 0x40, 0xa0, 0xe1, 0x01, 0x10, 0xd3, 0xe5, 0x0c, 0x20, 0xd4, 0xe5, 0x03, 0x30, 0xd3, 0xe5,
243 0x05, 0x58, 0xa0, 0xe1, 0x01, 0x54, 0x85, 0xe1, 0x02, 0x50, 0x85, 0xe1, 0x03, 0x5c, 0x85, 0xe1,
244 0x00, 0x60, 0xa0, 0xe1, 0x02, 0x5b, 0x85, 0xe2, 0x00, 0x00, 0xa0, 0xe3, 0xc7, 0xff, 0xff, 0xeb,
245 0x06, 0x10, 0xa0, 0xe1, 0x04, 0x20, 0xa0, 0xe1, 0x05, 0x30, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3,
246 0x3e, 0xff, 0xff, 0xeb, 0x04, 0x20, 0xa0, 0xe1, 0x06, 0x10, 0xa0, 0xe1, 0x05, 0x30, 0xa0, 0xe1,
247 0x00, 0x00, 0xa0, 0xe3, 0xfc, 0xfe, 0xff, 0xeb, 0x00, 0x40, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3,
248 0xb8, 0xff, 0xff, 0xeb, 0x01, 0x00, 0x24, 0xe2, 0x01, 0x00, 0x00, 0xe2, 0x70, 0x80, 0xbd, 0xe8,
249 0xf0, 0x45, 0x2d, 0xe9, 0x01, 0x40, 0xa0, 0xe1, 0x14, 0xd0, 0x4d, 0xe2, 0x00, 0x80, 0xa0, 0xe1,
250 0x00, 0x00, 0xa0, 0xe3, 0x02, 0x60, 0xa0, 0xe1, 0xb0, 0xff, 0xff, 0xeb, 0x08, 0x10, 0xa0, 0xe1,
251 0x02, 0x2b, 0xa0, 0xe3, 0x04, 0x30, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3, 0x86, 0xff, 0xff, 0xeb,
252 0x00, 0x00, 0xa0, 0xe3, 0xa7, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x40, 0x11, 0x9f, 0xe5,
253 0x04, 0x20, 0xa0, 0xe3, 0xb9, 0xfc, 0xff, 0xeb, 0x00, 0x00, 0x50, 0xe3, 0x00, 0x00, 0xe0, 0x13,
254 0x49, 0x00, 0x00, 0x1a, 0x04, 0x10, 0xa0, 0xe1, 0x40, 0x20, 0xa0, 0xe3, 0x0d, 0x30, 0xa0, 0xe1,
255 0x02, 0x00, 0xa0, 0xe3, 0x48, 0xfe, 0xff, 0xeb, 0x0d, 0x00, 0xa0, 0xe1, 0x40, 0x10, 0x84, 0xe2,
256 0x10, 0x20, 0xa0, 0xe3, 0xad, 0xfc, 0xff, 0xeb, 0x0d, 0x50, 0xa0, 0xe1, 0x00, 0x70, 0x50, 0xe2,
257 0x01, 0x00, 0xe0, 0x13, 0x3c, 0x00, 0x00, 0x1a, 0x0c, 0x30, 0x84, 0xe2, 0x02, 0x50, 0xd3, 0xe5,
258 0x01, 0x10, 0xd3, 0xe5, 0x0c, 0x20, 0xd4, 0xe5, 0x05, 0x58, 0xa0, 0xe1, 0x03, 0x30, 0xd3, 0xe5,
259 0x01, 0x54, 0x85, 0xe1, 0x02, 0x50, 0x85, 0xe1, 0x03, 0x5c, 0x85, 0xe1, 0x7e, 0x0b, 0x55, 0xe3,
260 0x2e, 0x00, 0x00, 0x8a, 0x08, 0x30, 0x84, 0xe2, 0x02, 0xc0, 0xd3, 0xe5, 0x01, 0xa0, 0xd3, 0xe5,
261 0x08, 0x10, 0xd4, 0xe5, 0x03, 0x20, 0xd3, 0xe5, 0x0c, 0xc8, 0xa0, 0xe1, 0x0a, 0x34, 0x8c, 0xe1,
262 0x01, 0x30, 0x83, 0xe1, 0x02, 0x3c, 0x83, 0xe1, 0x05, 0x00, 0x53, 0xe1, 0x23, 0x00, 0x00, 0x8a,
263 0x07, 0x30, 0xd4, 0xe5, 0x01, 0x30, 0x43, 0xe2, 0x01, 0x00, 0x53, 0xe3, 0x03, 0x00, 0xe0, 0x83,
264 0x21, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x56, 0xe3, 0x1e, 0x00, 0x00, 0x0a, 0x77, 0xff, 0xff, 0xeb,
265 0x06, 0x30, 0xa0, 0xe1, 0x07, 0x00, 0xa0, 0xe1, 0x02, 0x1b, 0x88, 0xe2, 0x05, 0x20, 0xa0, 0xe1,
266 0x4d, 0xff, 0xff, 0xeb, 0x07, 0x00, 0xa0, 0xe1, 0x6e, 0xff, 0xff, 0xeb, 0x07, 0x30, 0xd4, 0xe5,
267 0x01, 0x00, 0x53, 0xe3, 0x03, 0x00, 0x00, 0x1a, 0x07, 0x00, 0xa0, 0xe1, 0x04, 0x10, 0xa0, 0xe1,
268 0x06, 0x20, 0xa0, 0xe1, 0x28, 0xfe, 0xff, 0xeb, 0x06, 0x10, 0xa0, 0xe1, 0x05, 0x20, 0xa0, 0xe1,
269 0x0d, 0x30, 0xa0, 0xe1, 0x02, 0x00, 0xa0, 0xe3, 0x0f, 0xfe, 0xff, 0xeb, 0x0d, 0x00, 0xa0, 0xe1,
270 0x10, 0x10, 0x84, 0xe2, 0x10, 0x20, 0xa0, 0xe3, 0x74, 0xfc, 0xff, 0xeb, 0x0d, 0x70, 0xa0, 0xe1,
271 0x00, 0x00, 0x50, 0xe3, 0x04, 0x00, 0xe0, 0x13, 0x02, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x00, 0xea,
272 0x02, 0x00, 0xe0, 0xe3, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0xa0, 0xe3, 0x14, 0xd0, 0x8d, 0xe2,
273 0xf0, 0x85, 0xbd, 0xe8, 0xbd, 0x17, 0x00, 0x22, 0xf0, 0x4f, 0x2d, 0xe9, 0x00, 0x50, 0xa0, 0xe1,
274 0x54, 0xd0, 0x4d, 0xe2, 0x01, 0x40, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3, 0x01, 0x10, 0xa0, 0xe3,
275 0x02, 0x60, 0xa0, 0xe1, 0x70, 0xfc, 0xff, 0xeb, 0x0e, 0x23, 0xa0, 0xe3, 0x01, 0x10, 0xa0, 0xe3,
276 0x02, 0xc0, 0xa0, 0xe1, 0x10, 0x30, 0x8d, 0xe2, 0x04, 0x10, 0x82, 0xe5, 0x00, 0x00, 0x9c, 0xe5,
277 0x0e, 0x23, 0xa0, 0xe3, 0x01, 0x00, 0x10, 0xe2, 0xfb, 0xff, 0xff, 0x1a, 0x40, 0xc0, 0x64, 0xe2,
278 0xa4, 0x72, 0xa0, 0xe1, 0x84, 0xe1, 0xa0, 0xe1, 0x7c, 0x81, 0x9f, 0xe5, 0xa4, 0xaa, 0xa0, 0xe1,
279 0xa4, 0x96, 0xa0, 0xe1, 0xff, 0x70, 0x07, 0xe2, 0xff, 0xe0, 0x0e, 0xe2, 0x0c, 0xc0, 0x65, 0xe0,
280 0xff, 0x90, 0x09, 0xe2, 0x04, 0x70, 0x8d, 0xe5, 0x00, 0xe0, 0x8d, 0xe5, 0x0c, 0xc0, 0x8d, 0xe5,
281 0x02, 0x10, 0xa0, 0xe1, 0xff, 0xa0, 0x0a, 0xe2, 0x00, 0x70, 0xa0, 0xe1, 0xa4, 0x4e, 0xa0, 0xe1,
282 0x10, 0xc0, 0x8d, 0xe2, 0x02, 0xe0, 0xa0, 0xe1, 0x04, 0x00, 0x82, 0xe5, 0x08, 0x90, 0x8d, 0xe5,
283 0x00, 0x00, 0x82, 0xe5, 0x0c, 0x20, 0x9d, 0xe5, 0x02, 0x00, 0x85, 0xe0, 0x00, 0x00, 0x50, 0xe3,
284 0x25, 0x00, 0x00, 0xda, 0x00, 0x20, 0xa0, 0xe3, 0x02, 0x70, 0x8c, 0xe7, 0x04, 0x20, 0x82, 0xe2,
285 0x40, 0x00, 0x52, 0xe3, 0xfb, 0xff, 0xff, 0x1a, 0x40, 0x00, 0x50, 0xe3, 0x07, 0x20, 0xa0, 0xd1,
286 0x40, 0x90, 0x60, 0xd2, 0x03, 0x00, 0x00, 0xda, 0x09, 0x00, 0x00, 0xea, 0x02, 0xb0, 0xd5, 0xe7,
287 0x02, 0xb0, 0xcc, 0xe7, 0x01, 0x20, 0x82, 0xe2, 0x09, 0x00, 0x52, 0xe1, 0xfa, 0xff, 0xff, 0xba,
288 0x07, 0x00, 0x50, 0xe3, 0x7f, 0x20, 0xe0, 0xe3, 0x09, 0x20, 0xc3, 0xe7, 0x00, 0x00, 0xa0, 0xd3,
289 0x08, 0x00, 0x00, 0xda, 0x3b, 0x40, 0xc3, 0xe5, 0x3c, 0xa0, 0xc3, 0xe5, 0x08, 0x20, 0x9d, 0xe5,
290 0x01, 0x00, 0xa0, 0xe3, 0x3d, 0x20, 0xc3, 0xe5, 0x04, 0x20, 0x9d, 0xe5, 0x3e, 0x20, 0xc3, 0xe5,
291 0x00, 0x20, 0x9d, 0xe5, 0x3f, 0x20, 0xc3, 0xe5, 0xb0, 0x20, 0x9f, 0xe5, 0x02, 0x90, 0x8c, 0xe0,
292 0x32, 0x93, 0x89, 0xe2, 0x40, 0x90, 0x49, 0xe2, 0x00, 0x90, 0x99, 0xe5, 0x04, 0x90, 0x82, 0xe4,
293 0x08, 0x00, 0x52, 0xe1, 0xf8, 0xff, 0xff, 0x1a, 0x09, 0x00, 0x00, 0xea, 0x8c, 0x20, 0x9f, 0xe5,
294 0x02, 0x00, 0x85, 0xe0, 0x32, 0x03, 0x80, 0xe2, 0x40, 0x00, 0x40, 0xe2, 0x00, 0x00, 0x90, 0xe5,
295 0x04, 0x00, 0x82, 0xe4, 0x08, 0x00, 0x52, 0xe1, 0xf8, 0xff, 0xff, 0x1a, 0x40, 0x50, 0x85, 0xe2,
296 0x00, 0x00, 0xa0, 0xe3, 0x00, 0x20, 0x91, 0xe5, 0x02, 0x20, 0x82, 0xe3, 0x00, 0x20, 0x81, 0xe5,
297 0x00, 0x20, 0x91, 0xe5, 0x01, 0x00, 0x12, 0xe3, 0xfc, 0xff, 0xff, 0x1a, 0x00, 0x20, 0x9e, 0xe5,
298 0x00, 0x00, 0x50, 0xe3, 0x08, 0x20, 0x82, 0xe3, 0x00, 0x20, 0x8e, 0xe5, 0xc0, 0xff, 0xff, 0x0a,
299 0x3c, 0x30, 0x9f, 0xe5, 0x3c, 0x10, 0x9f, 0xe5, 0x03, 0x20, 0xa0, 0xe1, 0x06, 0x00, 0x92, 0xe6,
300 0x04, 0x30, 0x83, 0xe2, 0x32, 0x23, 0x82, 0xe2, 0x20, 0x20, 0x42, 0xe2, 0x01, 0x00, 0x53, 0xe1,
301 0x00, 0x00, 0x82, 0xe5, 0xf7, 0xff, 0xff, 0x1a, 0x00, 0x00, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe1,
302 0x05, 0xfc, 0xff, 0xeb, 0x54, 0xd0, 0x8d, 0xe2, 0xf0, 0x8f, 0xbd, 0xe8, 0x80, 0x00, 0x00, 0x38,
303 0x40, 0x00, 0x00, 0x38, 0x20, 0x00, 0x00, 0x38, 0x34, 0x00, 0x00, 0x38, 0xf0, 0x47, 0x2d, 0xe9,
304 0x00, 0x40, 0xa0, 0xe1, 0x01, 0x50, 0xa0, 0xe1, 0x0a, 0x00, 0xa0, 0xe3, 0x01, 0x10, 0xa0, 0xe3,
305 0xe3, 0x85, 0xa0, 0xe3, 0x03, 0x60, 0xa0, 0xe1, 0x02, 0x70, 0xa0, 0xe1, 0x01, 0xa0, 0xa0, 0xe3,
306 0xf5, 0xfb, 0xff, 0xeb, 0x00, 0x30, 0xa0, 0xe3, 0x74, 0x30, 0x88, 0xe5, 0x78, 0x30, 0x88, 0xe5,
307 0x7c, 0x30, 0x88, 0xe5, 0x80, 0x30, 0x88, 0xe5, 0x08, 0xa0, 0x88, 0xe5, 0x08, 0x30, 0x88, 0xe5,
308 0x00, 0xa0, 0x88, 0xe5, 0x10, 0x30, 0x88, 0xe5, 0x6c, 0x50, 0x88, 0xe5, 0x6c, 0x20, 0x98, 0xe5,
309 0x0a, 0x00, 0x54, 0xe1, 0x09, 0x40, 0xa0, 0x03, 0x08, 0x40, 0xa0, 0x13, 0x02, 0x20, 0xe0, 0xe1,
310 0x88, 0x20, 0x88, 0xe5, 0x8c, 0x30, 0x88, 0xe5, 0x14, 0x40, 0x88, 0xe5, 0x18, 0x60, 0x88, 0xe5,
311 0x20, 0x70, 0x88, 0xe5, 0x24, 0x60, 0x88, 0xe5, 0x28, 0x70, 0x88, 0xe5, 0x2c, 0x60, 0x88, 0xe5,
312 0x30, 0x70, 0x88, 0xe5, 0x34, 0x60, 0x88, 0xe5, 0x3c, 0x00, 0x00, 0xeb, 0x08, 0x30, 0xa0, 0xe1,
313 0x04, 0xa0, 0x88, 0xe5, 0x0c, 0x20, 0x93, 0xe5, 0x0f, 0x00, 0x12, 0xe3, 0xfc, 0xff, 0xff, 0x0a,
314 0x0a, 0x00, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0xf0, 0x47, 0xbd, 0xe8, 0xd2, 0xfb, 0xff, 0xea,
315 0x98, 0x30, 0x9f, 0xe5, 0xf0, 0x45, 0x2d, 0xe9, 0x94, 0xc0, 0x9f, 0xe5, 0xfa, 0x4f, 0xa0, 0xe3,
316 0x03, 0x60, 0xa0, 0xe1, 0x8c, 0x50, 0x9f, 0xe5, 0x1c, 0x00, 0x00, 0xea, 0xb4, 0x10, 0x93, 0xe5,
317 0xb2, 0x80, 0xd0, 0xe1, 0xa2, 0xa0, 0xa0, 0xe1, 0x94, 0x18, 0x27, 0xe0, 0x00, 0x20, 0xa0, 0xe3,
318 0x09, 0x00, 0x00, 0xea, 0x01, 0x20, 0x22, 0xe2, 0x06, 0x1c, 0x82, 0xe3, 0x0e, 0x10, 0x81, 0xe3,
319 0x00, 0x12, 0x8c, 0xe5, 0xb4, 0x10, 0x93, 0xe5, 0x01, 0x10, 0x8a, 0xe0, 0xb4, 0x80, 0x93, 0xe5,
320 0x08, 0x80, 0x61, 0xe0, 0x00, 0x00, 0x58, 0xe3, 0xfb, 0xff, 0xff, 0xba, 0xb4, 0x10, 0x93, 0xe5,
321 0x01, 0x10, 0x67, 0xe0, 0x00, 0x00, 0x51, 0xe3, 0xf1, 0xff, 0xff, 0xba, 0x00, 0x52, 0x8c, 0xe5,
322 0xb4, 0x70, 0xd0, 0xe1, 0xb4, 0x10, 0x96, 0xe5, 0x94, 0x17, 0x22, 0xe0, 0xb4, 0x10, 0x93, 0xe5,
323 0x01, 0x10, 0x62, 0xe0, 0x00, 0x00, 0x51, 0xe3, 0xfb, 0xff, 0xff, 0xba, 0x06, 0x00, 0x80, 0xe2,
324 0xb0, 0x20, 0xd0, 0xe1, 0x00, 0x00, 0x52, 0xe3, 0xdf, 0xff, 0xff, 0x1a, 0xf0, 0x85, 0xbd, 0xe8,
325 0x00, 0x00, 0x70, 0x3c, 0x00, 0x00, 0xf0, 0x3c, 0x0e, 0x06, 0x00, 0x00, 0x00, 0x30, 0xa0, 0xe3,
326 0x02, 0x00, 0x00, 0xea, 0x03, 0xc0, 0xd1, 0xe7, 0x03, 0xc0, 0xc0, 0xe7, 0x01, 0x30, 0x83, 0xe2,
327 0x00, 0x00, 0x52, 0xe3, 0x01, 0x20, 0x42, 0xe2, 0xf9, 0xff, 0xff, 0x1a, 0x1e, 0xff, 0x2f, 0xe1,
328 0x7e, 0xff, 0x17, 0xee, 0xfd, 0xff, 0xff, 0x1a, 0x00, 0x10, 0xa0, 0xe3, 0x9a, 0x1f, 0x07, 0xee,
329 0x1e, 0xff, 0x2f, 0xe1, 0xb8, 0x0b, 0xf4, 0x01, 0xf4, 0x01, 0xb8, 0x0b, 0xf4, 0x01, 0xf4, 0x01,
330 0xb8, 0x0b, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x76, 0xdc, 0x1d, 0x32, 0xb2, 0x46,
331 0xa6, 0xc9, 0x7d, 0x5a, 0x61, 0xd3, 0x49, 0x4c, 0x1e, 0xf0, 0xd9, 0xde, 0xc2, 0x7e, 0xec, 0x02,
332 0x7c, 0x15, 0x76, 0xbb, 0x5c, 0x4f, 0x2d, 0x95, 0x06, 0x85, 0xdf, 0x28, 0xe4, 0xd7, 0xf4, 0x82,
333 0xc0, 0x73, 0xb0, 0x53, 0x26, 0xfc, 0xb0, 0xfe, 0x60, 0x80, 0x7d, 0x33, 0xa8, 0xde, 0xf8, 0x49,
334 0xbb, 0xbe, 0x01, 0x45, 0xff, 0x62, 0x40, 0x19, 0xf4, 0x01, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00,
335 0xe8, 0x03, 0x64, 0x00, 0x00, 0x00, 0xf4, 0x01, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
336 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x68, 0x73, 0x6c, 0x66,
337 0x00, 0x38, 0x37, 0x30, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
338 0x00, 0x00, 0x00, 0x00, 0x38, 0x37, 0x30, 0x32, 0x31, 0x2e, 0x30, 0x02, 0x00, 0x00, 0x00, 0x00,
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
343 0x00, 0x00, 0x00, 0x00
344};
345unsigned char dualboot_uninstall_ipod6g[5076] = {
346 0xd7, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x24, 0xd0, 0x9f, 0xe5, 0xdb, 0x00, 0xa0, 0xe3,
347 0x00, 0xf0, 0x21, 0xe1, 0x18, 0xd0, 0x9f, 0xe5, 0xd3, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1,
348 0x10, 0xd0, 0x9f, 0xe5, 0x05, 0x08, 0xa0, 0xe3, 0x78, 0x00, 0x80, 0xe3, 0x10, 0x0f, 0x01, 0xee,
349 0x1d, 0x00, 0x00, 0xeb, 0x0c, 0x03, 0x00, 0x22, 0x0c, 0x03, 0x00, 0x22, 0x7f, 0x40, 0x2d, 0xe9,
350 0x5c, 0x10, 0x9f, 0xe5, 0x10, 0x20, 0xa0, 0xe3, 0x0d, 0x00, 0xa0, 0xe1, 0xaf, 0x04, 0x00, 0xeb,
351 0x00, 0x00, 0xa0, 0xe3, 0x02, 0x10, 0xa0, 0xe3, 0x0d, 0x20, 0xa0, 0xe1, 0x10, 0x30, 0xa0, 0xe3,
352 0x52, 0x04, 0x00, 0xeb, 0x3c, 0x60, 0x9f, 0xe5, 0x0d, 0x40, 0xa0, 0xe1, 0x00, 0x50, 0xa0, 0xe3,
353 0x06, 0x10, 0xa0, 0xe1, 0x0d, 0x00, 0xa0, 0xe1, 0x10, 0x20, 0xa0, 0xe3, 0x50, 0x00, 0x00, 0xeb,
354 0x10, 0x60, 0x86, 0xe2, 0x00, 0x00, 0x50, 0xe3, 0x02, 0x00, 0x00, 0x0a, 0x01, 0x50, 0x85, 0xe2,
355 0x04, 0x00, 0x55, 0xe3, 0xf5, 0xff, 0xff, 0x1a, 0x05, 0x00, 0xa0, 0xe1, 0x10, 0xd0, 0x8d, 0xe2,
356 0x70, 0x80, 0xbd, 0xe8, 0x10, 0x00, 0x02, 0x22, 0x68, 0x16, 0x00, 0x22, 0x70, 0x40, 0x2d, 0xe9,
357 0x87, 0x00, 0x00, 0xeb, 0xe8, 0x00, 0x9f, 0xe5, 0x69, 0x04, 0x00, 0xeb, 0x00, 0x00, 0xa0, 0xe3,
358 0x04, 0x10, 0xa0, 0xe3, 0x9e, 0x00, 0x00, 0xeb, 0x02, 0x09, 0xa0, 0xe3, 0xd4, 0x10, 0x9f, 0xe5,
359 0x00, 0x20, 0xa0, 0xe3, 0x5a, 0x03, 0x00, 0xeb, 0x00, 0x00, 0x50, 0xe3, 0x25, 0x00, 0x00, 0x1a,
360 0xd5, 0xff, 0xff, 0xeb, 0x04, 0x00, 0x50, 0xe3, 0x20, 0x00, 0x00, 0x1a, 0xb4, 0x00, 0x9f, 0xe5,
361 0xbc, 0x01, 0x00, 0xeb, 0xac, 0x10, 0x9f, 0xe5, 0xac, 0x20, 0x9f, 0xe5, 0x00, 0x50, 0xa0, 0xe1,
362 0x02, 0x09, 0x80, 0xe2, 0x4e, 0x03, 0x00, 0xeb, 0x00, 0x40, 0x50, 0xe2, 0x19, 0x00, 0x00, 0x1a,
363 0xc9, 0xff, 0xff, 0xeb, 0x04, 0x00, 0x50, 0xe3, 0x16, 0x00, 0x00, 0x0a, 0x01, 0x00, 0xa0, 0xe3,
364 0x80, 0x10, 0x9f, 0xe5, 0x80, 0x20, 0x9f, 0xe5, 0xd0, 0x01, 0x00, 0xeb, 0x02, 0x09, 0xa0, 0xe3,
365 0x70, 0x10, 0x9f, 0xe5, 0x23, 0x03, 0x00, 0xeb, 0x00, 0x00, 0x50, 0xe3, 0x6c, 0x00, 0x9f, 0x05,
366 0x0d, 0x00, 0x00, 0x0a, 0x04, 0x00, 0xa0, 0xe1, 0x16, 0x03, 0x00, 0xeb, 0x54, 0x00, 0x9f, 0xe5,
367 0xa4, 0x01, 0x00, 0xeb, 0x25, 0x26, 0xa0, 0xe1, 0x02, 0x19, 0x80, 0xe2, 0x21, 0x16, 0xa0, 0xe1,
368 0x04, 0x00, 0xa0, 0xe1, 0x41, 0x02, 0x00, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x0b, 0x03, 0x00, 0xeb,
369 0x3c, 0x00, 0x9f, 0xe5, 0x00, 0x00, 0x00, 0xea, 0x38, 0x00, 0x9f, 0xe5, 0x38, 0x20, 0x9f, 0xe5,
370 0x38, 0x30, 0x9f, 0xe5, 0xb4, 0x10, 0x92, 0xe5, 0x03, 0x00, 0x51, 0xe1, 0xfc, 0xff, 0xff, 0x9a,
371 0x33, 0x04, 0x00, 0xeb, 0x01, 0x26, 0xa0, 0xe3, 0xf2, 0x35, 0xa0, 0xe3, 0x00, 0x20, 0x83, 0xe5,
372 0xfe, 0xff, 0xff, 0xea, 0xa8, 0x16, 0x00, 0x22, 0x00, 0x00, 0x02, 0x22, 0x00, 0x08, 0x02, 0x22,
373 0x54, 0x16, 0x00, 0x22, 0xb0, 0x16, 0x00, 0x22, 0x60, 0x16, 0x00, 0x22, 0x00, 0x00, 0x70, 0x3c,
374 0x7f, 0x84, 0x1e, 0x00, 0x10, 0x40, 0x2d, 0xe9, 0x00, 0x30, 0xa0, 0xe3, 0x07, 0x00, 0x00, 0xea,
375 0x03, 0x40, 0xd0, 0xe7, 0x03, 0xc0, 0xd1, 0xe7, 0x01, 0x20, 0x42, 0xe2, 0x0c, 0x00, 0x54, 0xe1,
376 0x01, 0x30, 0x83, 0xe2, 0x01, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x6c, 0xe0, 0x10, 0x80, 0xbd, 0xe8,
377 0x00, 0x00, 0x52, 0xe3, 0xf5, 0xff, 0xff, 0x1a, 0x02, 0x00, 0xa0, 0xe1, 0x10, 0x80, 0xbd, 0xe8,
378 0x1f, 0x30, 0x00, 0xe2, 0x01, 0x20, 0xa0, 0xe3, 0xc0, 0x02, 0xa0, 0xe1, 0x00, 0x00, 0x51, 0xe3,
379 0x12, 0x33, 0xa0, 0xe1, 0x02, 0x20, 0x00, 0xe0, 0x08, 0x00, 0x00, 0x0a, 0x3c, 0x10, 0x9f, 0xe5,
380 0x3c, 0x00, 0x9f, 0xe5, 0x00, 0x00, 0x52, 0xe3, 0x00, 0x20, 0xa0, 0x11, 0x01, 0x20, 0xa0, 0x01,
381 0x00, 0x10, 0x92, 0xe5, 0x03, 0x30, 0xc1, 0xe1, 0x00, 0x30, 0x82, 0xe5, 0x1e, 0xff, 0x2f, 0xe1,
382 0x18, 0x10, 0x9f, 0xe5, 0x18, 0x00, 0x9f, 0xe5, 0x00, 0x00, 0x52, 0xe3, 0x01, 0x00, 0xa0, 0x01,
383 0x00, 0x20, 0x90, 0xe5, 0x03, 0x30, 0x82, 0xe1, 0x00, 0x30, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1,
384 0x48, 0x00, 0x50, 0x3c, 0x4c, 0x00, 0x50, 0x3c, 0x70, 0x40, 0x2d, 0xe9, 0x10, 0x50, 0x9d, 0xe5,
385 0x01, 0x30, 0x43, 0xe2, 0x01, 0x50, 0x45, 0xe2, 0x03, 0x60, 0x02, 0xe2, 0x0f, 0x30, 0x03, 0xe2,
386 0x05, 0x52, 0xa0, 0xe1, 0x03, 0xc0, 0xc0, 0xe3, 0xff, 0x50, 0x05, 0xe2, 0x06, 0x36, 0x83, 0xe1,
387 0x00, 0x40, 0x9c, 0xe5, 0x05, 0x30, 0x83, 0xe1, 0x30, 0x50, 0x9f, 0xe5, 0x02, 0x20, 0x00, 0xe2,
388 0x82, 0x21, 0xa0, 0xe1, 0x00, 0x00, 0x51, 0xe3, 0x02, 0x19, 0xa0, 0x03, 0x00, 0x10, 0xa0, 0x13,
389 0x35, 0x42, 0x04, 0xe0, 0x01, 0x30, 0x83, 0xe1, 0x13, 0x22, 0x84, 0xe1, 0x00, 0x20, 0x8c, 0xe5,
390 0xb0, 0x20, 0xd0, 0xe1, 0x03, 0x00, 0x52, 0xe1, 0xfc, 0xff, 0xff, 0x1a, 0x70, 0x80, 0xbd, 0xe8,
391 0x00, 0x00, 0xff, 0xff, 0x5c, 0xc0, 0x9f, 0xe5, 0x13, 0x40, 0x2d, 0xe9, 0x44, 0xe0, 0x9c, 0xe5,
392 0x01, 0x40, 0xa0, 0xe3, 0x01, 0xec, 0xce, 0xe3, 0x00, 0x20, 0xa0, 0xe3, 0x04, 0x30, 0xa0, 0xe1,
393 0x44, 0xe0, 0x8c, 0xe5, 0x40, 0x00, 0x9f, 0xe5, 0x04, 0x10, 0xa0, 0xe1, 0x00, 0x40, 0x8d, 0xe5,
394 0xd8, 0xff, 0xff, 0xeb, 0x04, 0x10, 0xa0, 0xe1, 0x25, 0x00, 0xa0, 0xe3, 0xbb, 0xff, 0xff, 0xeb,
395 0x28, 0x30, 0x9f, 0xe5, 0x11, 0x2d, 0xa0, 0xe3, 0xa0, 0x20, 0x83, 0xe5, 0x0b, 0x20, 0xa0, 0xe3,
396 0xb0, 0x20, 0x83, 0xe5, 0x00, 0x20, 0xe0, 0xe3, 0xa8, 0x20, 0x83, 0xe5, 0x04, 0x20, 0x82, 0xe2,
397 0xa4, 0x20, 0x83, 0xe5, 0x1c, 0x80, 0xbd, 0xe8, 0x00, 0x00, 0x50, 0x3c, 0x12, 0x00, 0x50, 0x3c,
398 0x00, 0x00, 0x70, 0x3c, 0x04, 0x30, 0x9f, 0xe5, 0x00, 0x11, 0x83, 0xe7, 0x1e, 0xff, 0x2f, 0xe1,
399 0xc0, 0x16, 0x00, 0x22, 0x80, 0x20, 0x9f, 0xe5, 0x00, 0x00, 0x51, 0xe3, 0x7c, 0x30, 0x9f, 0xe5,
400 0x02, 0x30, 0xa0, 0x11, 0x01, 0x00, 0x50, 0xe3, 0x0a, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x50, 0xe3,
401 0x0f, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x50, 0xe3, 0x1e, 0xff, 0x2f, 0x11, 0x60, 0x10, 0x9f, 0xe5,
402 0x00, 0x20, 0x91, 0xe5, 0x22, 0x28, 0xa0, 0xe1, 0x02, 0x28, 0xa0, 0xe1, 0x02, 0x30, 0x83, 0xe1,
403 0x00, 0x30, 0x81, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x44, 0x10, 0x9f, 0xe5, 0xc0, 0x20, 0x91, 0xe5,
404 0x02, 0x28, 0xa0, 0xe1, 0x22, 0x28, 0xa0, 0xe1, 0x03, 0x38, 0x82, 0xe1, 0xc0, 0x30, 0x81, 0xe5,
405 0x1e, 0xff, 0x2f, 0xe1, 0x28, 0x00, 0x9f, 0xe5, 0xc0, 0x21, 0x90, 0xe5, 0xff, 0x24, 0xc2, 0xe3,
406 0x03, 0x2c, 0x82, 0xe1, 0xc0, 0x21, 0x80, 0xe5, 0xe0, 0x21, 0x90, 0xe5, 0xff, 0x20, 0xc2, 0xe3,
407 0x23, 0x34, 0x82, 0xe1, 0xe0, 0x31, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x22, 0x22, 0x00, 0x00,
408 0xef, 0xee, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3c, 0x01, 0x00, 0x50, 0xe3, 0x01, 0x10, 0x21, 0xe2,
409 0x06, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x50, 0xe3, 0x06, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x50, 0xe3,
410 0x24, 0x30, 0x9f, 0x05, 0x0e, 0x10, 0x81, 0x03, 0x00, 0x12, 0x83, 0x05, 0x1e, 0xff, 0x2f, 0xe1,
411 0x18, 0x30, 0x9f, 0xe5, 0x00, 0x00, 0x00, 0xea, 0x14, 0x30, 0x9f, 0xe5, 0x08, 0x20, 0x9f, 0xe5,
412 0x03, 0x30, 0x81, 0xe1, 0x00, 0x32, 0x82, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0xf0, 0x3c,
413 0x0e, 0x04, 0x06, 0x00, 0x0e, 0x06, 0x0e, 0x00, 0x02, 0x00, 0x50, 0xe3, 0x10, 0x40, 0x2d, 0xe9,
414 0xbc, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0xb8, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3,
415 0xb4, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0xb0, 0x40, 0x9f, 0xe5, 0xb0, 0xc0, 0x9f, 0xe5,
416 0x01, 0x20, 0xa0, 0xe3, 0x00, 0x20, 0x83, 0xe5, 0x02, 0x00, 0x50, 0xe3, 0xa4, 0x30, 0x9f, 0x05,
417 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x04, 0x30, 0xa0, 0x01, 0x0c, 0x30, 0xa0, 0x11,
418 0x00, 0x30, 0x93, 0xe5, 0x1f, 0x3e, 0x03, 0xe2, 0x01, 0x0c, 0x53, 0xe3, 0xf5, 0xff, 0xff, 0x0a,
419 0x02, 0x00, 0x50, 0xe3, 0x80, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0x7c, 0x20, 0x9f, 0xe5,
420 0x01, 0x00, 0x50, 0xe3, 0x78, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0x5c, 0xc0, 0x9f, 0xe5,
421 0x5c, 0x20, 0x9f, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x02, 0x00, 0x50, 0xe3, 0x54, 0x30, 0x9f, 0x05,
422 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x0c, 0x30, 0xa0, 0x01, 0x02, 0x30, 0xa0, 0x11,
423 0x00, 0x30, 0x93, 0xe5, 0x3e, 0x0c, 0x13, 0xe3, 0xf6, 0xff, 0xff, 0x0a, 0x02, 0x00, 0x50, 0xe3,
424 0x40, 0x00, 0x9f, 0x05, 0x04, 0x00, 0x00, 0x0a, 0x3c, 0x30, 0x9f, 0xe5, 0x3c, 0x20, 0x9f, 0xe5,
425 0x01, 0x00, 0x50, 0xe3, 0x02, 0x00, 0xa0, 0x01, 0x03, 0x00, 0xa0, 0x11, 0x00, 0x00, 0x90, 0xe5,
426 0x10, 0x80, 0xbd, 0xe8, 0x34, 0x00, 0x20, 0x3d, 0x34, 0x00, 0xe0, 0x3c, 0x34, 0x00, 0x30, 0x3c,
427 0x08, 0x00, 0xe0, 0x3c, 0x08, 0x00, 0x30, 0x3c, 0x08, 0x00, 0x20, 0x3d, 0x10, 0x00, 0x20, 0x3d,
428 0x10, 0x00, 0xe0, 0x3c, 0x10, 0x00, 0x30, 0x3c, 0x20, 0x00, 0x20, 0x3d, 0x20, 0x00, 0x30, 0x3c,
429 0x20, 0x00, 0xe0, 0x3c, 0x02, 0x00, 0x50, 0xe3, 0xf0, 0x40, 0x2d, 0xe9, 0xd8, 0x30, 0x9f, 0x05,
430 0x03, 0x00, 0x00, 0x0a, 0xd4, 0xc0, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3, 0xd0, 0x30, 0x9f, 0xe5,
431 0x0c, 0x30, 0xa0, 0x01, 0x02, 0x00, 0x50, 0xe3, 0x00, 0x10, 0x83, 0xe5, 0xc4, 0x30, 0x9f, 0x05,
432 0x03, 0x00, 0x00, 0x0a, 0xc0, 0xc0, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3, 0xbc, 0x30, 0x9f, 0xe5,
433 0x0c, 0x30, 0xa0, 0x01, 0x00, 0x40, 0x93, 0xe5, 0x00, 0xc0, 0xa0, 0xe3, 0x01, 0x40, 0x84, 0xe3,
434 0x00, 0x40, 0x83, 0xe5, 0xa8, 0x70, 0x9f, 0xe5, 0xa8, 0x60, 0x9f, 0xe5, 0xa8, 0x50, 0x9f, 0xe5,
435 0xa8, 0x40, 0x9f, 0xe5, 0x12, 0x00, 0x00, 0xea, 0x02, 0x00, 0x50, 0xe3, 0xa0, 0x30, 0x9f, 0x05,
436 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x07, 0x30, 0xa0, 0x01, 0x06, 0x30, 0xa0, 0x11,
437 0x00, 0x30, 0x93, 0xe5, 0x3e, 0x0c, 0x13, 0xe3, 0xf6, 0xff, 0xff, 0x0a, 0x02, 0x00, 0x50, 0xe3,
438 0x80, 0x30, 0x9f, 0x05, 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x05, 0x30, 0xa0, 0x01,
439 0x04, 0x30, 0xa0, 0x11, 0x00, 0x30, 0x93, 0xe5, 0x01, 0x10, 0x41, 0xe2, 0x0c, 0x30, 0xc2, 0xe7,
440 0x01, 0xc0, 0x8c, 0xe2, 0x00, 0x00, 0x51, 0xe3, 0xea, 0xff, 0xff, 0x1a, 0x02, 0x00, 0x50, 0xe3,
441 0x30, 0x00, 0x9f, 0x05, 0x04, 0x00, 0x00, 0x0a, 0x2c, 0x30, 0x9f, 0xe5, 0x2c, 0x20, 0x9f, 0xe5,
442 0x01, 0x00, 0x50, 0xe3, 0x02, 0x00, 0xa0, 0x11, 0x03, 0x00, 0xa0, 0x01, 0x00, 0x30, 0x90, 0xe5,
443 0x01, 0x30, 0xc3, 0xe3, 0x00, 0x30, 0x80, 0xe5, 0xf0, 0x80, 0xbd, 0xe8, 0x34, 0x00, 0x20, 0x3d,
444 0x34, 0x00, 0xe0, 0x3c, 0x34, 0x00, 0x30, 0x3c, 0x04, 0x00, 0x20, 0x3d, 0x04, 0x00, 0xe0, 0x3c,
445 0x04, 0x00, 0x30, 0x3c, 0x08, 0x00, 0xe0, 0x3c, 0x08, 0x00, 0x30, 0x3c, 0x20, 0x00, 0xe0, 0x3c,
446 0x20, 0x00, 0x30, 0x3c, 0x08, 0x00, 0x20, 0x3d, 0x20, 0x00, 0x20, 0x3d, 0x02, 0x00, 0x50, 0xe3,
447 0x2e, 0x00, 0x80, 0x02, 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x2b, 0x00, 0xa0, 0x03,
448 0x22, 0x00, 0xa0, 0x13, 0x00, 0x10, 0xa0, 0xe3, 0xe4, 0xfe, 0xff, 0xea, 0x02, 0x00, 0x50, 0xe3,
449 0x10, 0x40, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x30, 0x00, 0xa0, 0x03, 0x02, 0x00, 0x00, 0x0a,
450 0x01, 0x00, 0x54, 0xe3, 0x2b, 0x00, 0xa0, 0x03, 0x22, 0x00, 0xa0, 0x13, 0x01, 0x10, 0xa0, 0xe3,
451 0xda, 0xfe, 0xff, 0xeb, 0x02, 0x00, 0x54, 0xe3, 0x04, 0x31, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a,
452 0x00, 0x21, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3, 0xfc, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01,
453 0x02, 0x00, 0x54, 0xe3, 0x0f, 0x20, 0xa0, 0xe3, 0x00, 0x20, 0x83, 0xe5, 0xec, 0x30, 0x9f, 0x05,
454 0x03, 0x00, 0x00, 0x0a, 0xe8, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3, 0xe4, 0x30, 0x9f, 0xe5,
455 0x02, 0x30, 0xa0, 0x01, 0x00, 0x20, 0x93, 0xe5, 0x02, 0x00, 0x54, 0xe3, 0x0c, 0x20, 0x82, 0xe3,
456 0x00, 0x20, 0x83, 0xe5, 0xd0, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0xcc, 0x20, 0x9f, 0xe5,
457 0x01, 0x00, 0x54, 0xe3, 0xc8, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0xc4, 0x20, 0x9f, 0xe5,
458 0x02, 0x00, 0x54, 0xe3, 0x04, 0x21, 0x92, 0xe7, 0x00, 0x20, 0x83, 0xe5, 0xb8, 0x30, 0x9f, 0x05,
459 0x03, 0x00, 0x00, 0x0a, 0xb4, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3, 0xb0, 0x30, 0x9f, 0xe5,
460 0x02, 0x30, 0xa0, 0x01, 0x02, 0x00, 0x54, 0xe3, 0x06, 0x20, 0xa0, 0xe3, 0x00, 0x20, 0x83, 0xe5,
461 0xa0, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0x9c, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3,
462 0x98, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0x94, 0x20, 0x9f, 0xe5, 0x02, 0x00, 0x54, 0xe3,
463 0x00, 0x20, 0x83, 0xe5, 0x54, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0x50, 0x20, 0x9f, 0xe5,
464 0x01, 0x00, 0x54, 0xe3, 0x4c, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0x00, 0x20, 0x93, 0xe5,
465 0x02, 0x00, 0x54, 0xe3, 0x0c, 0x20, 0x82, 0xe3, 0x00, 0x20, 0x83, 0xe5, 0x2c, 0x40, 0x9f, 0x05,
466 0x04, 0x00, 0x00, 0x0a, 0x2c, 0x30, 0x9f, 0xe5, 0x24, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3,
467 0x02, 0x40, 0xa0, 0x01, 0x03, 0x40, 0xa0, 0x11, 0x01, 0x30, 0xa0, 0xe3, 0x00, 0x30, 0x84, 0xe5,
468 0x10, 0x80, 0xbd, 0xe8, 0x08, 0x00, 0x20, 0x3d, 0x08, 0x00, 0xe0, 0x3c, 0x08, 0x00, 0x30, 0x3c,
469 0x00, 0x00, 0x20, 0x3d, 0x00, 0x00, 0xe0, 0x3c, 0x00, 0x00, 0x30, 0x3c, 0x30, 0x00, 0x20, 0x3d,
470 0x30, 0x00, 0xe0, 0x3c, 0x30, 0x00, 0x30, 0x3c, 0xc0, 0x16, 0x00, 0x22, 0x0c, 0x00, 0x20, 0x3d,
471 0x0c, 0x00, 0xe0, 0x3c, 0x0c, 0x00, 0x30, 0x3c, 0x04, 0x00, 0x20, 0x3d, 0x04, 0x00, 0xe0, 0x3c,
472 0x04, 0x00, 0x30, 0x3c, 0x18, 0x06, 0x01, 0x00, 0x0c, 0x30, 0x80, 0xe2, 0x02, 0xc0, 0xd3, 0xe5,
473 0x01, 0x10, 0xd3, 0xe5, 0x0c, 0x20, 0xd0, 0xe5, 0x03, 0x30, 0xd3, 0xe5, 0x0c, 0x08, 0xa0, 0xe1,
474 0x01, 0x04, 0x80, 0xe1, 0x02, 0x00, 0x80, 0xe1, 0x03, 0x0c, 0x80, 0xe1, 0x5f, 0x0d, 0x80, 0xe2,
475 0x3f, 0x00, 0x80, 0xe2, 0xff, 0x0e, 0xc0, 0xe3, 0x0f, 0x00, 0xc0, 0xe3, 0x1e, 0xff, 0x2f, 0xe1,
476 0x70, 0x40, 0x2d, 0xe9, 0x18, 0xd0, 0x4d, 0xe2, 0x04, 0x40, 0x8d, 0xe2, 0x03, 0x50, 0xa0, 0xe1,
477 0x00, 0x60, 0xa0, 0xe1, 0x01, 0x00, 0xa0, 0xe1, 0x02, 0x10, 0xa0, 0xe1, 0x04, 0x20, 0xa0, 0xe1,
478 0xe1, 0x01, 0x00, 0xeb, 0x04, 0x10, 0xa0, 0xe1, 0x05, 0x00, 0xa0, 0xe1, 0x10, 0x20, 0xa0, 0xe3,
479 0xae, 0x02, 0x00, 0xeb, 0x06, 0x10, 0xa0, 0xe1, 0x05, 0x20, 0xa0, 0xe1, 0x01, 0x00, 0xa0, 0xe3,
480 0x10, 0x30, 0xa0, 0xe3, 0x51, 0x02, 0x00, 0xeb, 0x18, 0xd0, 0x8d, 0xe2, 0x70, 0x80, 0xbd, 0xe8,
481 0x01, 0x00, 0x50, 0xe3, 0xf0, 0x47, 0x2d, 0xe9, 0x0c, 0x50, 0xd1, 0xe5, 0x0c, 0x30, 0x81, 0xe2,
482 0x00, 0x40, 0xa0, 0xe1, 0x01, 0x00, 0xa0, 0x03, 0x02, 0x00, 0xa0, 0x13, 0x03, 0x80, 0xd3, 0xe5,
483 0x02, 0x70, 0xd3, 0xe5, 0x01, 0x60, 0xd3, 0xe5, 0x02, 0xa0, 0xa0, 0xe1, 0x07, 0x00, 0xc1, 0xe5,
484 0x40, 0x30, 0x81, 0xe2, 0x02, 0x00, 0xa0, 0xe3, 0x40, 0x20, 0xa0, 0xe3, 0xdb, 0xff, 0xff, 0xeb,
485 0x07, 0x78, 0xa0, 0xe1, 0x06, 0x64, 0x87, 0xe1, 0x05, 0x50, 0x86, 0xe1, 0x08, 0x3c, 0x85, 0xe1,
486 0x04, 0x00, 0xa0, 0xe1, 0x0a, 0x20, 0xa0, 0xe1, 0x02, 0x10, 0xa0, 0xe3, 0xf0, 0x47, 0xbd, 0xe8,
487 0x36, 0x02, 0x00, 0xea, 0x10, 0x40, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x04, 0x00, 0xa0, 0xe1,
488 0x01, 0x10, 0xa0, 0xe3, 0xbf, 0xfe, 0xff, 0xeb, 0x05, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1,
489 0xd0, 0xfe, 0xff, 0xeb, 0xff, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0xcd, 0xfe, 0xff, 0xeb,
490 0x00, 0x10, 0xa0, 0xe3, 0x01, 0x30, 0x10, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x00, 0x00, 0x0a,
491 0xb4, 0xfe, 0xff, 0xeb, 0xf0, 0xff, 0xff, 0xea, 0x04, 0x00, 0xa0, 0xe1, 0x03, 0x10, 0xa0, 0xe1,
492 0x10, 0x40, 0xbd, 0xe8, 0xaf, 0xfe, 0xff, 0xea, 0x70, 0x40, 0x2d, 0xe9, 0x00, 0x50, 0x51, 0xe2,
493 0x00, 0x40, 0xa0, 0xe1, 0x07, 0x00, 0x00, 0x1a, 0x01, 0x10, 0x81, 0xe2, 0xa9, 0xfe, 0xff, 0xeb,
494 0x04, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0xba, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
495 0x05, 0x10, 0xa0, 0xe1, 0xa3, 0xfe, 0xff, 0xeb, 0x01, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1,
496 0xa0, 0xfe, 0xff, 0xeb, 0x50, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0xb1, 0xfe, 0xff, 0xeb,
497 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0x9a, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
498 0x01, 0x10, 0xa0, 0xe3, 0x97, 0xfe, 0xff, 0xeb, 0x01, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1,
499 0xa8, 0xfe, 0xff, 0xeb, 0x00, 0x00, 0x55, 0xe3, 0x1c, 0x10, 0xa0, 0x03, 0x00, 0x10, 0xa0, 0x13,
500 0x04, 0x00, 0xa0, 0xe1, 0xa3, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3,
501 0x8c, 0xfe, 0xff, 0xeb, 0x00, 0x00, 0x55, 0xe3, 0x70, 0x80, 0xbd, 0x08, 0x04, 0x00, 0xa0, 0xe1,
502 0x01, 0x10, 0xa0, 0xe3, 0x87, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x06, 0x10, 0xa0, 0xe3,
503 0x98, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0x70, 0x40, 0xbd, 0xe8,
504 0x80, 0xfe, 0xff, 0xea, 0x70, 0x40, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x01, 0x50, 0xa0, 0xe1,
505 0x1d, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0xb5, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
506 0x01, 0x10, 0xa0, 0xe3, 0xc7, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
507 0x74, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x20, 0x10, 0xa0, 0xe3, 0x85, 0xfe, 0xff, 0xeb,
508 0x25, 0x18, 0xa0, 0xe1, 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x81, 0xfe, 0xff, 0xeb,
509 0x25, 0x14, 0xa0, 0xe1, 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x7d, 0xfe, 0xff, 0xeb,
510 0xff, 0x10, 0x05, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x7a, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
511 0x00, 0x10, 0xa0, 0xe3, 0x63, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3,
512 0xb0, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x70, 0x40, 0xbd, 0xe8, 0xf6, 0xfe, 0xff, 0xea,
513 0x70, 0x40, 0x2d, 0xe9, 0x00, 0x50, 0xa0, 0xe1, 0x01, 0x46, 0xa0, 0xe1, 0x02, 0x60, 0xa0, 0xe1,
514 0x00, 0x00, 0x00, 0xea, 0xd6, 0xff, 0xff, 0xeb, 0x00, 0x00, 0x56, 0xe3, 0x04, 0x10, 0xa0, 0xe1,
515 0x05, 0x00, 0xa0, 0xe1, 0x01, 0x4a, 0x84, 0xe2, 0x01, 0x60, 0x46, 0xe2, 0xf8, 0xff, 0xff, 0x1a,
516 0x70, 0x80, 0xbd, 0xe8, 0xf0, 0x45, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x24, 0xd0, 0x4d, 0xe2,
517 0x02, 0x50, 0xa0, 0xe1, 0x03, 0x70, 0xa0, 0xe1, 0x01, 0x60, 0xa0, 0xe1, 0xea, 0xfe, 0xff, 0xeb,
518 0x04, 0x00, 0xa0, 0xe1, 0x82, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
519 0x44, 0xfe, 0xff, 0xeb, 0x03, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0x55, 0xfe, 0xff, 0xeb,
520 0x26, 0x18, 0xa0, 0xe1, 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x51, 0xfe, 0xff, 0xeb,
521 0x26, 0x14, 0xa0, 0xe1, 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x4d, 0xfe, 0xff, 0xeb,
522 0xff, 0x10, 0x06, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x4a, 0xfe, 0xff, 0xeb, 0x00, 0x60, 0xa0, 0xe3,
523 0x0d, 0x80, 0xa0, 0xe1, 0x15, 0x00, 0x00, 0xea, 0x20, 0x00, 0x57, 0xe3, 0x07, 0xa0, 0xa0, 0xb1,
524 0x20, 0xa0, 0xa0, 0xa3, 0x04, 0x00, 0xa0, 0xe1, 0x0a, 0x10, 0xa0, 0xe1, 0x0d, 0x20, 0xa0, 0xe1,
525 0x7f, 0xfe, 0xff, 0xeb, 0x05, 0x00, 0xa0, 0xe1, 0x0d, 0x10, 0xa0, 0xe1, 0x0a, 0x20, 0xa0, 0xe1,
526 0x9f, 0xfd, 0xff, 0xeb, 0x00, 0x30, 0xa0, 0xe3, 0x00, 0x00, 0x50, 0xe3, 0x01, 0x60, 0x86, 0x13,
527 0x03, 0x20, 0xd8, 0xe7, 0x02, 0x30, 0x83, 0xe2, 0xff, 0x00, 0x52, 0xe3, 0x02, 0x60, 0x86, 0x13,
528 0x0a, 0x00, 0x53, 0xe1, 0xf9, 0xff, 0xff, 0xba, 0x20, 0x50, 0x85, 0xe2, 0x20, 0x70, 0x47, 0xe2,
529 0x00, 0x00, 0x57, 0xe3, 0xe7, 0xff, 0xff, 0xca, 0x00, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1,
530 0x18, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0xaf, 0xfe, 0xff, 0xeb, 0x06, 0x00, 0xa0, 0xe1,
531 0x24, 0xd0, 0x8d, 0xe2, 0xf0, 0x85, 0xbd, 0xe8, 0xf0, 0x4f, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1,
532 0x14, 0xd0, 0x4d, 0xe2, 0x01, 0x50, 0xa0, 0xe1, 0x02, 0x70, 0xa0, 0xe1, 0x03, 0x80, 0xa0, 0xe1,
533 0x53, 0x00, 0x00, 0xea, 0x05, 0x6a, 0xa0, 0xe1, 0x26, 0x6a, 0xa0, 0xe1, 0x01, 0x6a, 0x66, 0xe2,
534 0x08, 0x00, 0x56, 0xe1, 0x08, 0x60, 0xa0, 0xa1, 0x04, 0x00, 0xa0, 0xe1, 0x05, 0x10, 0xa0, 0xe1,
535 0x07, 0x20, 0xa0, 0xe1, 0x06, 0x30, 0xa0, 0xe1, 0xb1, 0xff, 0xff, 0xeb, 0x01, 0x00, 0x10, 0xe3,
536 0x44, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x10, 0xe3, 0x03, 0x00, 0x00, 0x0a, 0xff, 0x1e, 0xc5, 0xe3,
537 0x0f, 0x10, 0xc1, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0x79, 0xff, 0xff, 0xeb, 0x00, 0x30, 0xa0, 0xe3,
538 0x03, 0x20, 0xd7, 0xe7, 0x07, 0x90, 0xa0, 0xe1, 0xff, 0x00, 0x52, 0xe3, 0x01, 0x30, 0x83, 0xe2,
539 0x02, 0x00, 0x00, 0x1a, 0x06, 0x00, 0x53, 0xe1, 0xf8, 0xff, 0xff, 0xba, 0x35, 0x00, 0x00, 0xea,
540 0x04, 0x00, 0xa0, 0xe1, 0x90, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x28, 0xff, 0xff, 0xeb,
541 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0x3a, 0xff, 0xff, 0xeb, 0x25, 0x34, 0xa0, 0xe1,
542 0xff, 0x30, 0x03, 0xe2, 0x25, 0x28, 0xa0, 0xe1, 0xff, 0x20, 0x02, 0xe2, 0x08, 0x30, 0x8d, 0xe5,
543 0x06, 0xa0, 0xa0, 0xe1, 0xff, 0x30, 0x05, 0xe2, 0x01, 0xb0, 0xa0, 0xe3, 0x04, 0x20, 0x8d, 0xe5,
544 0x0c, 0x30, 0x8d, 0xe5, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0xdd, 0xfd, 0xff, 0xeb,
545 0x04, 0x00, 0xa0, 0xe1, 0xad, 0x10, 0xa0, 0xe3, 0xee, 0xfd, 0xff, 0xeb, 0x00, 0x00, 0x5b, 0xe3,
546 0x00, 0xb0, 0xa0, 0xe3, 0x08, 0x00, 0x00, 0x0a, 0x04, 0x10, 0x9d, 0xe5, 0x04, 0x00, 0xa0, 0xe1,
547 0xe8, 0xfd, 0xff, 0xeb, 0x08, 0x10, 0x9d, 0xe5, 0x04, 0x00, 0xa0, 0xe1, 0xe5, 0xfd, 0xff, 0xeb,
548 0x04, 0x00, 0xa0, 0xe1, 0x0c, 0x10, 0x9d, 0xe5, 0xe2, 0xfd, 0xff, 0xeb, 0x00, 0x10, 0xd9, 0xe5,
549 0x04, 0x00, 0xa0, 0xe1, 0xdf, 0xfd, 0xff, 0xeb, 0x01, 0x10, 0xd9, 0xe5, 0x04, 0x00, 0xa0, 0xe1,
550 0xdc, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0xc5, 0xfd, 0xff, 0xeb,
551 0x04, 0x00, 0xa0, 0xe1, 0xfe, 0xfe, 0xff, 0xeb, 0x02, 0xa0, 0x5a, 0xe2, 0x02, 0x90, 0x89, 0xe2,
552 0xdf, 0xff, 0xff, 0x1a, 0x04, 0x00, 0xa0, 0xe1, 0x0a, 0x10, 0xa0, 0xe1, 0x0d, 0xff, 0xff, 0xeb,
553 0x04, 0x00, 0xa0, 0xe1, 0x54, 0xfe, 0xff, 0xeb, 0x08, 0x80, 0x66, 0xe0, 0x06, 0x70, 0x87, 0xe0,
554 0x06, 0x50, 0x85, 0xe0, 0x00, 0x00, 0x58, 0xe3, 0xa9, 0xff, 0xff, 0xca, 0x14, 0xd0, 0x8d, 0xe2,
555 0xf0, 0x8f, 0xbd, 0xe8, 0xf0, 0x41, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x03, 0x50, 0xa0, 0xe1,
556 0x02, 0x70, 0xa0, 0xe1, 0x01, 0x60, 0xa0, 0xe1, 0x4f, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
557 0xe7, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0xa9, 0xfd, 0xff, 0xeb,
558 0x04, 0x00, 0xa0, 0xe1, 0x03, 0x10, 0xa0, 0xe3, 0xba, 0xfd, 0xff, 0xeb, 0x26, 0x18, 0xa0, 0xe1,
559 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0xb6, 0xfd, 0xff, 0xeb, 0x26, 0x14, 0xa0, 0xe1,
560 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0xb2, 0xfd, 0xff, 0xeb, 0xff, 0x10, 0x06, 0xe2,
561 0x04, 0x00, 0xa0, 0xe1, 0xaf, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x07, 0x10, 0xa0, 0xe1,
562 0x05, 0x20, 0xa0, 0xe1, 0xea, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3,
563 0x94, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0xf0, 0x41, 0xbd, 0xe8, 0x2a, 0xfe, 0xff, 0xea,
564 0x00, 0x10, 0xa0, 0xe3, 0x6a, 0xfd, 0xff, 0xea, 0x10, 0x40, 0x2d, 0xe9, 0x01, 0x10, 0xa0, 0xe3,
565 0x00, 0x40, 0xa0, 0xe1, 0x66, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3,
566 0x10, 0x40, 0xbd, 0xe8, 0x87, 0xfd, 0xff, 0xea, 0x0c, 0x30, 0x81, 0xe2, 0x70, 0x40, 0x2d, 0xe9,
567 0x02, 0x50, 0xd3, 0xe5, 0x01, 0x40, 0xa0, 0xe1, 0x01, 0x10, 0xd3, 0xe5, 0x0c, 0x20, 0xd4, 0xe5,
568 0x03, 0x30, 0xd3, 0xe5, 0x05, 0x58, 0xa0, 0xe1, 0x01, 0x54, 0x85, 0xe1, 0x02, 0x50, 0x85, 0xe1,
569 0x03, 0x5c, 0x85, 0xe1, 0x00, 0x60, 0xa0, 0xe1, 0x02, 0x5b, 0x85, 0xe2, 0x00, 0x00, 0xa0, 0xe3,
570 0xe8, 0xff, 0xff, 0xeb, 0x06, 0x10, 0xa0, 0xe1, 0x04, 0x20, 0xa0, 0xe1, 0x05, 0x30, 0xa0, 0xe1,
571 0x00, 0x00, 0xa0, 0xe3, 0x5f, 0xff, 0xff, 0xeb, 0x04, 0x20, 0xa0, 0xe1, 0x06, 0x10, 0xa0, 0xe1,
572 0x05, 0x30, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3, 0x1d, 0xff, 0xff, 0xeb, 0x00, 0x40, 0xa0, 0xe1,
573 0x00, 0x00, 0xa0, 0xe3, 0xd9, 0xff, 0xff, 0xeb, 0x01, 0x00, 0x24, 0xe2, 0x01, 0x00, 0x00, 0xe2,
574 0x70, 0x80, 0xbd, 0xe8, 0xf0, 0x45, 0x2d, 0xe9, 0x01, 0x40, 0xa0, 0xe1, 0x14, 0xd0, 0x4d, 0xe2,
575 0x00, 0x80, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3, 0x02, 0x60, 0xa0, 0xe1, 0xd1, 0xff, 0xff, 0xeb,
576 0x08, 0x10, 0xa0, 0xe1, 0x02, 0x2b, 0xa0, 0xe3, 0x04, 0x30, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3,
577 0xa7, 0xff, 0xff, 0xeb, 0x00, 0x00, 0xa0, 0xe3, 0xc8, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
578 0x40, 0x11, 0x9f, 0xe5, 0x04, 0x20, 0xa0, 0xe3, 0xcd, 0xfc, 0xff, 0xeb, 0x00, 0x00, 0x50, 0xe3,
579 0x00, 0x00, 0xe0, 0x13, 0x49, 0x00, 0x00, 0x1a, 0x04, 0x10, 0xa0, 0xe1, 0x40, 0x20, 0xa0, 0xe3,
580 0x0d, 0x30, 0xa0, 0xe1, 0x02, 0x00, 0xa0, 0xe3, 0x5c, 0xfe, 0xff, 0xeb, 0x0d, 0x00, 0xa0, 0xe1,
581 0x40, 0x10, 0x84, 0xe2, 0x10, 0x20, 0xa0, 0xe3, 0xc1, 0xfc, 0xff, 0xeb, 0x0d, 0x50, 0xa0, 0xe1,
582 0x00, 0x70, 0x50, 0xe2, 0x01, 0x00, 0xe0, 0x13, 0x3c, 0x00, 0x00, 0x1a, 0x0c, 0x30, 0x84, 0xe2,
583 0x02, 0x50, 0xd3, 0xe5, 0x01, 0x10, 0xd3, 0xe5, 0x0c, 0x20, 0xd4, 0xe5, 0x05, 0x58, 0xa0, 0xe1,
584 0x03, 0x30, 0xd3, 0xe5, 0x01, 0x54, 0x85, 0xe1, 0x02, 0x50, 0x85, 0xe1, 0x03, 0x5c, 0x85, 0xe1,
585 0x7e, 0x0b, 0x55, 0xe3, 0x2e, 0x00, 0x00, 0x8a, 0x08, 0x30, 0x84, 0xe2, 0x02, 0xc0, 0xd3, 0xe5,
586 0x01, 0xa0, 0xd3, 0xe5, 0x08, 0x10, 0xd4, 0xe5, 0x03, 0x20, 0xd3, 0xe5, 0x0c, 0xc8, 0xa0, 0xe1,
587 0x0a, 0x34, 0x8c, 0xe1, 0x01, 0x30, 0x83, 0xe1, 0x02, 0x3c, 0x83, 0xe1, 0x05, 0x00, 0x53, 0xe1,
588 0x23, 0x00, 0x00, 0x8a, 0x07, 0x30, 0xd4, 0xe5, 0x01, 0x30, 0x43, 0xe2, 0x01, 0x00, 0x53, 0xe3,
589 0x03, 0x00, 0xe0, 0x83, 0x21, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x56, 0xe3, 0x1e, 0x00, 0x00, 0x0a,
590 0x98, 0xff, 0xff, 0xeb, 0x06, 0x30, 0xa0, 0xe1, 0x07, 0x00, 0xa0, 0xe1, 0x02, 0x1b, 0x88, 0xe2,
591 0x05, 0x20, 0xa0, 0xe1, 0x6e, 0xff, 0xff, 0xeb, 0x07, 0x00, 0xa0, 0xe1, 0x8f, 0xff, 0xff, 0xeb,
592 0x07, 0x30, 0xd4, 0xe5, 0x01, 0x00, 0x53, 0xe3, 0x03, 0x00, 0x00, 0x1a, 0x07, 0x00, 0xa0, 0xe1,
593 0x04, 0x10, 0xa0, 0xe1, 0x06, 0x20, 0xa0, 0xe1, 0x3c, 0xfe, 0xff, 0xeb, 0x06, 0x10, 0xa0, 0xe1,
594 0x05, 0x20, 0xa0, 0xe1, 0x0d, 0x30, 0xa0, 0xe1, 0x02, 0x00, 0xa0, 0xe3, 0x23, 0xfe, 0xff, 0xeb,
595 0x0d, 0x00, 0xa0, 0xe1, 0x10, 0x10, 0x84, 0xe2, 0x10, 0x20, 0xa0, 0xe3, 0x88, 0xfc, 0xff, 0xeb,
596 0x0d, 0x70, 0xa0, 0xe1, 0x00, 0x00, 0x50, 0xe3, 0x04, 0x00, 0xe0, 0x13, 0x02, 0x00, 0x00, 0x0a,
597 0x02, 0x00, 0x00, 0xea, 0x02, 0x00, 0xe0, 0xe3, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0xa0, 0xe3,
598 0x14, 0xd0, 0x8d, 0xe2, 0xf0, 0x85, 0xbd, 0xe8, 0xd1, 0x16, 0x00, 0x22, 0xf0, 0x4f, 0x2d, 0xe9,
599 0x00, 0x50, 0xa0, 0xe1, 0x54, 0xd0, 0x4d, 0xe2, 0x01, 0x40, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3,
600 0x01, 0x10, 0xa0, 0xe3, 0x02, 0x60, 0xa0, 0xe1, 0x84, 0xfc, 0xff, 0xeb, 0x0e, 0x23, 0xa0, 0xe3,
601 0x01, 0x10, 0xa0, 0xe3, 0x02, 0xc0, 0xa0, 0xe1, 0x10, 0x30, 0x8d, 0xe2, 0x04, 0x10, 0x82, 0xe5,
602 0x00, 0x00, 0x9c, 0xe5, 0x0e, 0x23, 0xa0, 0xe3, 0x01, 0x00, 0x10, 0xe2, 0xfb, 0xff, 0xff, 0x1a,
603 0x40, 0xc0, 0x64, 0xe2, 0xa4, 0x72, 0xa0, 0xe1, 0x84, 0xe1, 0xa0, 0xe1, 0x7c, 0x81, 0x9f, 0xe5,
604 0xa4, 0xaa, 0xa0, 0xe1, 0xa4, 0x96, 0xa0, 0xe1, 0xff, 0x70, 0x07, 0xe2, 0xff, 0xe0, 0x0e, 0xe2,
605 0x0c, 0xc0, 0x65, 0xe0, 0xff, 0x90, 0x09, 0xe2, 0x04, 0x70, 0x8d, 0xe5, 0x00, 0xe0, 0x8d, 0xe5,
606 0x0c, 0xc0, 0x8d, 0xe5, 0x02, 0x10, 0xa0, 0xe1, 0xff, 0xa0, 0x0a, 0xe2, 0x00, 0x70, 0xa0, 0xe1,
607 0xa4, 0x4e, 0xa0, 0xe1, 0x10, 0xc0, 0x8d, 0xe2, 0x02, 0xe0, 0xa0, 0xe1, 0x04, 0x00, 0x82, 0xe5,
608 0x08, 0x90, 0x8d, 0xe5, 0x00, 0x00, 0x82, 0xe5, 0x0c, 0x20, 0x9d, 0xe5, 0x02, 0x00, 0x85, 0xe0,
609 0x00, 0x00, 0x50, 0xe3, 0x25, 0x00, 0x00, 0xda, 0x00, 0x20, 0xa0, 0xe3, 0x02, 0x70, 0x8c, 0xe7,
610 0x04, 0x20, 0x82, 0xe2, 0x40, 0x00, 0x52, 0xe3, 0xfb, 0xff, 0xff, 0x1a, 0x40, 0x00, 0x50, 0xe3,
611 0x07, 0x20, 0xa0, 0xd1, 0x40, 0x90, 0x60, 0xd2, 0x03, 0x00, 0x00, 0xda, 0x09, 0x00, 0x00, 0xea,
612 0x02, 0xb0, 0xd5, 0xe7, 0x02, 0xb0, 0xcc, 0xe7, 0x01, 0x20, 0x82, 0xe2, 0x09, 0x00, 0x52, 0xe1,
613 0xfa, 0xff, 0xff, 0xba, 0x07, 0x00, 0x50, 0xe3, 0x7f, 0x20, 0xe0, 0xe3, 0x09, 0x20, 0xc3, 0xe7,
614 0x00, 0x00, 0xa0, 0xd3, 0x08, 0x00, 0x00, 0xda, 0x3b, 0x40, 0xc3, 0xe5, 0x3c, 0xa0, 0xc3, 0xe5,
615 0x08, 0x20, 0x9d, 0xe5, 0x01, 0x00, 0xa0, 0xe3, 0x3d, 0x20, 0xc3, 0xe5, 0x04, 0x20, 0x9d, 0xe5,
616 0x3e, 0x20, 0xc3, 0xe5, 0x00, 0x20, 0x9d, 0xe5, 0x3f, 0x20, 0xc3, 0xe5, 0xb0, 0x20, 0x9f, 0xe5,
617 0x02, 0x90, 0x8c, 0xe0, 0x32, 0x93, 0x89, 0xe2, 0x40, 0x90, 0x49, 0xe2, 0x00, 0x90, 0x99, 0xe5,
618 0x04, 0x90, 0x82, 0xe4, 0x08, 0x00, 0x52, 0xe1, 0xf8, 0xff, 0xff, 0x1a, 0x09, 0x00, 0x00, 0xea,
619 0x8c, 0x20, 0x9f, 0xe5, 0x02, 0x00, 0x85, 0xe0, 0x32, 0x03, 0x80, 0xe2, 0x40, 0x00, 0x40, 0xe2,
620 0x00, 0x00, 0x90, 0xe5, 0x04, 0x00, 0x82, 0xe4, 0x08, 0x00, 0x52, 0xe1, 0xf8, 0xff, 0xff, 0x1a,
621 0x40, 0x50, 0x85, 0xe2, 0x00, 0x00, 0xa0, 0xe3, 0x00, 0x20, 0x91, 0xe5, 0x02, 0x20, 0x82, 0xe3,
622 0x00, 0x20, 0x81, 0xe5, 0x00, 0x20, 0x91, 0xe5, 0x01, 0x00, 0x12, 0xe3, 0xfc, 0xff, 0xff, 0x1a,
623 0x00, 0x20, 0x9e, 0xe5, 0x00, 0x00, 0x50, 0xe3, 0x08, 0x20, 0x82, 0xe3, 0x00, 0x20, 0x8e, 0xe5,
624 0xc0, 0xff, 0xff, 0x0a, 0x3c, 0x30, 0x9f, 0xe5, 0x3c, 0x10, 0x9f, 0xe5, 0x03, 0x20, 0xa0, 0xe1,
625 0x06, 0x00, 0x92, 0xe6, 0x04, 0x30, 0x83, 0xe2, 0x32, 0x23, 0x82, 0xe2, 0x20, 0x20, 0x42, 0xe2,
626 0x01, 0x00, 0x53, 0xe1, 0x00, 0x00, 0x82, 0xe5, 0xf7, 0xff, 0xff, 0x1a, 0x00, 0x00, 0xa0, 0xe3,
627 0x00, 0x10, 0xa0, 0xe1, 0x19, 0xfc, 0xff, 0xeb, 0x54, 0xd0, 0x8d, 0xe2, 0xf0, 0x8f, 0xbd, 0xe8,
628 0x80, 0x00, 0x00, 0x38, 0x40, 0x00, 0x00, 0x38, 0x20, 0x00, 0x00, 0x38, 0x34, 0x00, 0x00, 0x38,
629 0xf0, 0x47, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x01, 0x50, 0xa0, 0xe1, 0x0a, 0x00, 0xa0, 0xe3,
630 0x01, 0x10, 0xa0, 0xe3, 0xe3, 0x85, 0xa0, 0xe3, 0x03, 0x60, 0xa0, 0xe1, 0x02, 0x70, 0xa0, 0xe1,
631 0x01, 0xa0, 0xa0, 0xe3, 0x09, 0xfc, 0xff, 0xeb, 0x00, 0x30, 0xa0, 0xe3, 0x74, 0x30, 0x88, 0xe5,
632 0x78, 0x30, 0x88, 0xe5, 0x7c, 0x30, 0x88, 0xe5, 0x80, 0x30, 0x88, 0xe5, 0x08, 0xa0, 0x88, 0xe5,
633 0x08, 0x30, 0x88, 0xe5, 0x00, 0xa0, 0x88, 0xe5, 0x10, 0x30, 0x88, 0xe5, 0x6c, 0x50, 0x88, 0xe5,
634 0x6c, 0x20, 0x98, 0xe5, 0x0a, 0x00, 0x54, 0xe1, 0x09, 0x40, 0xa0, 0x03, 0x08, 0x40, 0xa0, 0x13,
635 0x02, 0x20, 0xe0, 0xe1, 0x88, 0x20, 0x88, 0xe5, 0x8c, 0x30, 0x88, 0xe5, 0x14, 0x40, 0x88, 0xe5,
636 0x18, 0x60, 0x88, 0xe5, 0x20, 0x70, 0x88, 0xe5, 0x24, 0x60, 0x88, 0xe5, 0x28, 0x70, 0x88, 0xe5,
637 0x2c, 0x60, 0x88, 0xe5, 0x30, 0x70, 0x88, 0xe5, 0x34, 0x60, 0x88, 0xe5, 0x3c, 0x00, 0x00, 0xeb,
638 0x08, 0x30, 0xa0, 0xe1, 0x04, 0xa0, 0x88, 0xe5, 0x0c, 0x20, 0x93, 0xe5, 0x0f, 0x00, 0x12, 0xe3,
639 0xfc, 0xff, 0xff, 0x0a, 0x0a, 0x00, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0xf0, 0x47, 0xbd, 0xe8,
640 0xe6, 0xfb, 0xff, 0xea, 0x98, 0x30, 0x9f, 0xe5, 0xf0, 0x45, 0x2d, 0xe9, 0x94, 0xc0, 0x9f, 0xe5,
641 0xfa, 0x4f, 0xa0, 0xe3, 0x03, 0x60, 0xa0, 0xe1, 0x8c, 0x50, 0x9f, 0xe5, 0x1c, 0x00, 0x00, 0xea,
642 0xb4, 0x10, 0x93, 0xe5, 0xb2, 0x80, 0xd0, 0xe1, 0xa2, 0xa0, 0xa0, 0xe1, 0x94, 0x18, 0x27, 0xe0,
643 0x00, 0x20, 0xa0, 0xe3, 0x09, 0x00, 0x00, 0xea, 0x01, 0x20, 0x22, 0xe2, 0x06, 0x1c, 0x82, 0xe3,
644 0x0e, 0x10, 0x81, 0xe3, 0x00, 0x12, 0x8c, 0xe5, 0xb4, 0x10, 0x93, 0xe5, 0x01, 0x10, 0x8a, 0xe0,
645 0xb4, 0x80, 0x93, 0xe5, 0x08, 0x80, 0x61, 0xe0, 0x00, 0x00, 0x58, 0xe3, 0xfb, 0xff, 0xff, 0xba,
646 0xb4, 0x10, 0x93, 0xe5, 0x01, 0x10, 0x67, 0xe0, 0x00, 0x00, 0x51, 0xe3, 0xf1, 0xff, 0xff, 0xba,
647 0x00, 0x52, 0x8c, 0xe5, 0xb4, 0x70, 0xd0, 0xe1, 0xb4, 0x10, 0x96, 0xe5, 0x94, 0x17, 0x22, 0xe0,
648 0xb4, 0x10, 0x93, 0xe5, 0x01, 0x10, 0x62, 0xe0, 0x00, 0x00, 0x51, 0xe3, 0xfb, 0xff, 0xff, 0xba,
649 0x06, 0x00, 0x80, 0xe2, 0xb0, 0x20, 0xd0, 0xe1, 0x00, 0x00, 0x52, 0xe3, 0xdf, 0xff, 0xff, 0x1a,
650 0xf0, 0x85, 0xbd, 0xe8, 0x00, 0x00, 0x70, 0x3c, 0x00, 0x00, 0xf0, 0x3c, 0x0e, 0x06, 0x00, 0x00,
651 0x00, 0x30, 0xa0, 0xe3, 0x02, 0x00, 0x00, 0xea, 0x03, 0xc0, 0xd1, 0xe7, 0x03, 0xc0, 0xc0, 0xe7,
652 0x01, 0x30, 0x83, 0xe2, 0x00, 0x00, 0x52, 0xe3, 0x01, 0x20, 0x42, 0xe2, 0xf9, 0xff, 0xff, 0x1a,
653 0x1e, 0xff, 0x2f, 0xe1, 0x7e, 0xff, 0x17, 0xee, 0xfd, 0xff, 0xff, 0x1a, 0x00, 0x10, 0xa0, 0xe3,
654 0x9a, 0x1f, 0x07, 0xee, 0x1e, 0xff, 0x2f, 0xe1, 0xb8, 0x0b, 0xf4, 0x01, 0xf4, 0x01, 0xb8, 0x0b,
655 0xf4, 0x01, 0xf4, 0x01, 0xb8, 0x0b, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x76, 0xdc,
656 0x1d, 0x32, 0xb2, 0x46, 0xa6, 0xc9, 0x7d, 0x5a, 0x61, 0xd3, 0x49, 0x4c, 0x1e, 0xf0, 0xd9, 0xde,
657 0xc2, 0x7e, 0xec, 0x02, 0x7c, 0x15, 0x76, 0xbb, 0x5c, 0x4f, 0x2d, 0x95, 0x06, 0x85, 0xdf, 0x28,
658 0xe4, 0xd7, 0xf4, 0x82, 0xc0, 0x73, 0xb0, 0x53, 0x26, 0xfc, 0xb0, 0xfe, 0x60, 0x80, 0x7d, 0x33,
659 0xa8, 0xde, 0xf8, 0x49, 0xbb, 0xbe, 0x01, 0x45, 0xff, 0x62, 0x40, 0x19, 0xf4, 0x01, 0x64, 0x00,
660 0x00, 0x00, 0x00, 0x00, 0xe8, 0x03, 0x64, 0x00, 0x00, 0x00, 0xf4, 0x01, 0x96, 0x00, 0x00, 0x00,
661 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
662 0x68, 0x73, 0x6c, 0x66, 0x00, 0x38, 0x37, 0x30, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
663 0x00, 0x00, 0x00, 0x00
664};
diff --git a/utils/mks5lboot/dualboot.h b/utils/mks5lboot/dualboot.h
new file mode 100644
index 0000000000..c8952a4c07
--- /dev/null
+++ b/utils/mks5lboot/dualboot.h
@@ -0,0 +1,4 @@
1/* Generated by bin2c */
2
3extern unsigned char dualboot_install_ipod6g[5396];
4extern unsigned char dualboot_uninstall_ipod6g[5076];
diff --git a/utils/mks5lboot/dualboot/.gitignore b/utils/mks5lboot/dualboot/.gitignore
new file mode 100644
index 0000000000..34c53b3c82
--- /dev/null
+++ b/utils/mks5lboot/dualboot/.gitignore
@@ -0,0 +1,3 @@
1build/
2*.arm-bin
3bin2c
diff --git a/utils/mks5lboot/dualboot/Makefile b/utils/mks5lboot/dualboot/Makefile
new file mode 100644
index 0000000000..51ce816ca0
--- /dev/null
+++ b/utils/mks5lboot/dualboot/Makefile
@@ -0,0 +1,97 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id$
8#
9ifndef V
10SILENT = @
11endif
12
13CC = gcc
14LD = ld
15OC = objcopy
16CROSS ?= arm-elf-eabi-
17
18ROOTDIR = ../../..
19FIRMDIR = $(ROOTDIR)/firmware
20FWARM = $(FIRMDIR)/target/arm
21FW8702 = $(FWARM)/s5l8702
22BUILDDIR = build/
23LINKFILE = dualboot.lds
24
25# Edit the following variables when adding a new target.
26# mks5lboot.c also needs to be edited to refer to these
27# To add a new target x you need to:
28# 1) add x to the list in TARGETS
29# 2) create a variable named OPT_x of the form:
30# OPT_x=target specific defines
31TARGETS = ipod6g
32OPT_ipod6g = -DIPOD_6G -DMEMORYSIZE=64
33
34LOADERS = install uninstall
35OPT_install =
36OPT_uninstall = -DDUALBOOT_UNINSTALL
37
38# target/loader specific options
39$(foreach l, $(LOADERS),$(foreach t, $(TARGETS),\
40 $(eval OPT_$(l)_$(t) = $(OPT_$(l)) $(OPT_$(t)))))
41
42DEFINES = -DBOOTLOADER
43
44SOURCES = init.S dualboot.c
45SOURCES += $(ROOTDIR)/lib/arm_support/support-arm.S
46SOURCES += $(wildcard $(FIRMDIR)/asm/mem*.c $(FIRMDIR)/libc/mem*.c)
47SOURCES += $(addprefix $(FWARM)/, mmu-arm.S)
48SOURCES += $(addprefix $(FW8702)/, clocking-s5l8702.c spi-s5l8702.c nor-s5l8702.c crypto-s5l8702.c)
49# target/loader specific sources
50SRCTARGET = piezo-.c
51$(foreach l, $(LOADERS), $(foreach t, $(TARGETS),\
52 $(eval SRC_$(l)_$(t) = $(addprefix $(FW8702)/$(t)/, $(subst -.,-$(subst ipod,,$(t)).,$(SRCTARGET))))))
53
54INCLUDES += -I. -I.. -I$(FIRMDIR) -I$(FWARM) -I$(FW8702)
55INCLUDES += $(addprefix -I$(FIRMDIR)/, export include libc/include kernel/include)
56# target/loader specific includes
57$(foreach l,$(LOADERS),$(foreach t,$(TARGETS),$(eval INC_$(l)_$(t) = -I$(FW8702)/$(t))))
58
59CFLAGS = $(INCLUDES) -mcpu=arm926ej-s -std=gnu99 -nostdlib -ffreestanding -Os -W -Wall\
60 -Wundef -Wstrict-prototypes -ffunction-sections -fdata-sections -Wl,--gc-sections $(DEFINES)
61
62# Build filenames prefix
63PFX = dualboot_
64
65BOOTBINS = $(foreach l, $(LOADERS),$(foreach t, $(TARGETS),$(PFX)$(l)_$(t).arm-bin))
66
67OUTPUTDUALBOOT = ../dualboot.h ../dualboot.c
68OUTPUTDEBUG = $(BOOTBINS:%.arm-bin=$(BUILDDIR)%.arm-elf) $(BOOTBINS:%.arm-bin=$(BUILDDIR)%.lds)
69
70
71all: $(BUILDDIR) $(OUTPUTDUALBOOT)
72
73$(BUILDDIR)$(PFX)%.lds: $(LINKFILE)
74 @echo Creating $@
75 $(SILENT)$(CROSS)$(CC) $(INC_$*) $(CFLAGS) $(OPT_$*) -E -x c - < $< | sed '/#/d' > $@
76
77$(BUILDDIR)$(PFX)%.arm-elf: $(BUILDDIR)$(PFX)%.lds $(SOURCES)
78 @echo CC -T $(notdir $^ $(SRC_$*))
79 $(SILENT)$(CROSS)$(CC) $(INC_$*) $(CFLAGS) $(OPT_$*) -o $@ -T$^ $(SRC_$*)
80
81$(PFX)%.arm-bin: $(BUILDDIR)$(PFX)%.arm-elf
82 @echo OC $<
83 $(SILENT)$(CROSS)$(OC) -O binary $< $@
84
85bin2c: bin2c.c
86 $(CC) -o $@ $<
87
88$(OUTPUTDUALBOOT): bin2c $(BOOTBINS)
89 ./bin2c ../dualboot $(BOOTBINS)
90
91$(BUILDDIR):
92 mkdir -p $@
93
94clean:
95 rm -rf bin2c $(BOOTBINS) $(BUILDDIR)
96
97.PRECIOUS: $(OUTPUTDEBUG)
diff --git a/utils/mks5lboot/dualboot/autoconf.h b/utils/mks5lboot/dualboot/autoconf.h
new file mode 100644
index 0000000000..cd5b3f9aeb
--- /dev/null
+++ b/utils/mks5lboot/dualboot/autoconf.h
@@ -0,0 +1,74 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2012 by Andrew Ryabinin
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#ifndef __BUILD_AUTOCONF_H
22#define __BUILD_AUTOCONF_H
23
24/* lower case names match the what's exported in the Makefile
25 * upper case name looks nicer in the code */
26
27#define arch_none 0
28#define ARCH_NONE 0
29
30#define arch_sh 1
31#define ARCH_SH 1
32
33#define arch_m68k 2
34#define ARCH_M68K 2
35
36#define arch_arm 3
37#define ARCH_ARM 3
38
39#define arch_mips 4
40#define ARCH_MIPS 4
41
42#define arch_x86 5
43#define ARCH_X86 5
44
45#define arch_amd64 6
46#define ARCH_AMD64 6
47
48/* Define target machine architecture */
49#define ARCH arch_arm
50/* Optionally define architecture version */
51#define ARCH_VERSION 5
52
53/* Define endianess for the target or simulator platform */
54#define ROCKBOX_LITTLE_ENDIAN 1
55
56/* Define this if you build rockbox to support the logf logging and display */
57#undef ROCKBOX_HAS_LOGF
58
59/* Define this if you want logf to output to the serial port */
60#undef LOGF_SERIAL
61
62/* Define this to record a chart with timings for the stages of boot */
63#undef DO_BOOTCHART
64
65/* the threading backend we use */
66#define ASSEMBLER_THREADS
67
68/* root of Rockbox */
69#define ROCKBOX_DIR "/.rockbox"
70#define ROCKBOX_SHARE_PATH ""
71#define ROCKBOX_BINARY_PATH ""
72#define ROCKBOX_LIBRARY_PATH ""
73
74#endif /* __BUILD_AUTOCONF_H */
diff --git a/utils/mks5lboot/dualboot/bin2c.c b/utils/mks5lboot/dualboot/bin2c.c
new file mode 100644
index 0000000000..4d74a19696
--- /dev/null
+++ b/utils/mks5lboot/dualboot/bin2c.c
@@ -0,0 +1,140 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 Dave Chapman
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 <stdio.h>
23#include <string.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <unistd.h>
27#include <fcntl.h>
28#include <stdlib.h>
29#include <libgen.h>
30
31#ifndef O_BINARY
32#define O_BINARY 0
33#endif
34
35static off_t filesize(int fd)
36{
37 struct stat buf;
38
39 fstat(fd,&buf);
40 return buf.st_size;
41}
42
43static void write_cfile(const unsigned char* buf, off_t len, FILE* fp, const char *name)
44{
45 int i;
46
47 fprintf(fp,"unsigned char %s[%ld] = {",name,len);
48
49 for (i=0;i<len;i++) {
50 if ((i % 16) == 0) {
51 fprintf(fp,"\n ");
52 }
53 if (i == (len-1)) {
54 fprintf(fp,"0x%02x",buf[i]);
55 } else if ((i % 16) == 15) {
56 fprintf(fp,"0x%02x,",buf[i]);
57 } else {
58 fprintf(fp,"0x%02x, ",buf[i]);
59 }
60 }
61 fprintf(fp,"\n};\n");
62}
63
64int main (int argc, char* argv[])
65{
66 char* cname;
67 int i;
68 FILE *cfile, *hfile;
69 char cfilename[256], hfilename[256];
70
71 if (argc < 3) {
72 fprintf(stderr,"Usage: bin2c cname file1 [file2 [file3 ...]]\n");
73 return 1;
74 }
75
76 cname=argv[1];
77
78 snprintf(cfilename,256,"%s.c",cname);
79 cfile = fopen(cfilename,"w+");
80 if (cfile == NULL) {
81 fprintf(stderr,"Couldn't open %s\n",cfilename);
82 return 2;
83 }
84
85 snprintf(hfilename,256,"%s.h",cname);
86 hfile = fopen(hfilename,"w+");
87 if (hfile == NULL) {
88 fprintf(stderr,"Couldn't open %s\n",hfilename);
89 fclose(cfile);
90 return 3;
91 }
92
93 fprintf(cfile,"/* Generated by bin2c */\n\n");
94 fprintf(cfile,"#include \"%s\"\n\n", basename(hfilename));
95 fprintf(hfile,"/* Generated by bin2c */\n\n");
96
97 for(i=0; i < argc - 2; i++) {
98 unsigned char* buf;
99 off_t len;
100 off_t orig_len;
101 char *ext;
102 char *array = argv[2+i];
103
104 int fd = open(array,O_RDONLY|O_BINARY);
105 if (fd < 0) {
106 fprintf(stderr,"Can not open %s\n",argv[2+i]);
107 fclose(cfile);
108 fclose(hfile);
109 return 4;
110 }
111
112 orig_len = filesize(fd);
113 /* pad to 32bit */
114 len = (orig_len + 3) & ~3;
115
116 buf = malloc(len);
117 if (read(fd,buf,orig_len) < orig_len) {
118 fprintf(stderr,"Short read, aborting\n");
119 return 5;
120 }
121
122 /* pad to 32bit with zeros */
123 if (len > orig_len)
124 memset(buf+orig_len, 0, len-orig_len);
125
126 /* remove file extension */
127 ext = strchr (array, '.');
128 if (ext != NULL)
129 *ext = '\0';
130 write_cfile (buf, len, cfile, array);
131 fprintf(hfile,"extern unsigned char %s[%ld];\n",array,len);
132
133 close(fd);
134 }
135
136 fclose(cfile);
137 fclose(hfile);
138
139 return 0;
140}
diff --git a/utils/mks5lboot/dualboot/dualboot.c b/utils/mks5lboot/dualboot/dualboot.c
new file mode 100644
index 0000000000..b8167ec124
--- /dev/null
+++ b/utils/mks5lboot/dualboot/dualboot.c
@@ -0,0 +1,287 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2015 by Cástor Muñoz
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#include <stdint.h>
22#include <string.h>
23
24#include "config.h"
25#include "system.h"
26#include "button.h"
27
28#include "s5l8702.h"
29#include "clocking-s5l8702.h"
30#include "spi-s5l8702.h"
31#include "nor-target.h"
32#include "piezo.h"
33
34/* How it works:
35 *
36 * - dualboot-installer: installs or updates a RB bootloader, the bootloader
37 * to install/update is already included into dualboot-installer.dfu file,
38 * once it is executed by the iPod device:
39 *
40 * 1) locates an original NORBOOT (ONB): first it looks at offset=32KB, if
41 * a NORBOOT is found but it is not an ONB then it is supposed it is a
42 * RB bootloader (that should be updated), then the ONB is loaded from
43 * offset=32KB+old_BLSIZE).
44 * 2) write ONB at 32KB+new_BLSIZE, if it fails then:
45 * 2a) try to restore ONB to its 'pristine' place (offset=32KB), if it
46 * also fails then the NOR got corrupted (ONB probably destroyed)
47 * and iTunes should be used to restore the iPod.
48 * 3) write new (included) RB bootloader at offset=32KB, it it fails then
49 * goto 2a)
50 *
51 * - dualboot-uninstaller: uninstall RB bootloader from NOR, leaving it at
52 * it's previous (pristine) state.
53 *
54 * See bootloader/ipod6g.c for notes on how the RB bootloader works.
55 *
56 *
57 * Pristine NOR Rockboxed NOR
58 * 1MB ______________
59 * | |
60 * | flsh DIR |
61 * 1MB-0x200 |______________|
62 * | |
63 * | File 1 |
64 * |..............|
65 * | |
66 * . .
67 * . .
68 * . .
69 * | |
70 * |..............|
71 * | | . .
72 * | File N | . .
73 * |______________| |______________|
74 * | | | |
75 * | | | |
76 * | | | Unused |
77 * | | | |
78 * | Unused | 160KB+BLSZ |______________|
79 * | | | |
80 * | | | Original |
81 * | | | NOR boot |
82 * 160KB |______________| | (decrypted) |
83 * | | | |
84 * | | 32KB+BLSZ |______________|
85 * | Original | | |
86 * | NOR boot | | Decrypted |
87 * | (encrypted) | | Rockbox |
88 * | | | Bootloader |
89 * 32KB |______________| 32KB |______________|
90 * | | | |
91 * | | . .
92 * | | . .
93 * |______________|
94 * | |
95 * | SysCfg |
96 * 0 |______________|
97 *
98 */
99
100#define OF_LOADADDR IRAM1_ORIG
101
102/* tone sequences: period (uS), duration (ms), silence (ms) */
103static uint16_t alive[] = { 500,100,0, 0 };
104static uint16_t happy[] = { 1000,100,0, 500,150,0, 0 };
105static uint16_t fatal[] = { 3000,500,500, 3000,500,500, 3000,500,0, 0 };
106#define sad2 (&fatal[3])
107#define sad (&fatal[6])
108
109/* iPod Classic: decrypted hashes for known OFs */
110static unsigned char of_sha[][SIGN_SZ] = {
111 "\x66\x66\x76\xDC\x1D\x32\xB2\x46\xA6\xC9\x7D\x5A\x61\xD3\x49\x4C", /* v1.1.2 */
112 "\x1E\xF0\xD9\xDE\xC2\x7E\xEC\x02\x7C\x15\x76\xBB\x5C\x4F\x2D\x95", /* v2.0.1 */
113 "\x06\x85\xDF\x28\xE4\xD7\xF4\x82\xC0\x73\xB0\x53\x26\xFC\xB0\xFE", /* v2.0.4 */
114 "\x60\x80\x7D\x33\xA8\xDE\xF8\x49\xBB\xBE\x01\x45\xFF\x62\x40\x19" /* v2.0.5 */
115};
116#define N_OF (int)(sizeof(of_sha)/SIGN_SZ)
117
118/* we can assume that unknown FW is a RB bootloader */
119#define FW_RB N_OF
120
121static int identify_fw(struct Im3Info *hinfo)
122{
123 unsigned char hash[SIGN_SZ];
124 int of;
125
126 /* decrypt hash to identify OF */
127 memcpy(hash, hinfo->u.enc12.data_sign, SIGN_SZ);
128 hwkeyaes(HWKEYAES_DECRYPT, HWKEYAES_UKEY, hash, SIGN_SZ);
129
130 for (of = 0; of < N_OF; of++)
131 if (memcmp(hash, of_sha[of], SIGN_SZ) == 0)
132 break;
133
134 return of;
135}
136
137#ifdef DUALBOOT_UNINSTALL
138/* Uninstall RB bootloader */
139void main(void)
140{
141 struct Im3Info *hinfo;
142 void *fw_addr;
143 uint16_t *status;
144 unsigned bl_nor_sz;
145
146 usec_timer_init();
147 piezo_seq(alive);
148 spi_clkdiv(SPI_PORT, 4); /* SPI clock = 27/5 MHz. */
149
150 hinfo = (struct Im3Info*)OF_LOADADDR;
151 fw_addr = (void*)hinfo + IM3HDR_SZ;
152
153 if (im3_read(NORBOOT_OFF, hinfo, NULL) != 0) {
154 status = sad;
155 goto bye; /* no FW found */
156 }
157
158 if (identify_fw(hinfo) != FW_RB) {
159 status = happy;
160 goto bye; /* RB bootloader not installed, nothing to do */
161 }
162
163 /* if found FW is a RB bootloader, OF should start just behind it */
164 bl_nor_sz = im3_nor_sz(hinfo);
165 if ((im3_read(NORBOOT_OFF + bl_nor_sz, hinfo, fw_addr) != 0)
166 || (identify_fw(hinfo) == FW_RB)) {
167 status = sad;
168 goto bye; /* OF not found */
169 }
170
171 /* decrypted OF correctly loaded, encrypt it before restoration */
172 im3_crypt(HWKEYAES_ENCRYPT, hinfo, fw_addr);
173
174 /* restore OF to it's original place */
175 if (!im3_write(NORBOOT_OFF, hinfo)) {
176 status = fatal;
177 goto bye; /* corrupted NOR, use iTunes to restore */
178 }
179
180 /* erase freed NOR blocks */
181 bootflash_init(SPI_PORT);
182 bootflash_erase_blocks(SPI_PORT,
183 (NORBOOT_OFF + im3_nor_sz(hinfo)) >> 12, bl_nor_sz >> 12);
184 bootflash_close(SPI_PORT);
185
186 status = happy;
187
188bye:
189 /* minimum time between the initial and the final beeps */
190 while (USEC_TIMER < 2000000);
191 piezo_seq(status);
192 WDTCON = 0x100000; /* WDT reset */
193 while (1);
194}
195
196#else
197/* Install RB bootloader */
198struct Im3Info bl_hinfo __attribute__((section(".im3info.data"))) =
199{
200 .ident = IM3_IDENT,
201 .version = IM3_VERSION,
202 .enc_type = 2,
203};
204
205static uint32_t get_uint32le(unsigned char *p)
206{
207 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
208}
209
210void main(void)
211{
212 uint16_t *status = happy;
213 int single_boot;
214 struct Im3Info *hinfo;
215 void *fw_addr;
216 unsigned bl_nor_sz;
217
218 usec_timer_init();
219 piezo_seq(alive);
220 spi_clkdiv(SPI_PORT, 4); /* SPI clock = 27/5 MHz. */
221
222 /* check for single boot installation, is is configured when
223 mks5lboot.exe builds the .dfu image */
224 single_boot = bl_hinfo.info_sign[0];
225
226 /* sign RB bootloader (data and header), but don't encrypt it,
227 use current decrypted image for faster load */
228 im3_sign(HWKEYAES_UKEY, (void*)&bl_hinfo + IM3HDR_SZ,
229 get_uint32le(bl_hinfo.data_sz), bl_hinfo.u.enc12.data_sign);
230 im3_sign(HWKEYAES_UKEY, &bl_hinfo, IM3INFOSIGN_SZ, bl_hinfo.info_sign);
231
232 if (single_boot) {
233 if (!im3_write(NORBOOT_OFF, &bl_hinfo))
234 status = sad;
235 goto bye;
236 }
237
238 hinfo = (struct Im3Info*)OF_LOADADDR;
239 fw_addr = (void*)hinfo + IM3HDR_SZ;
240
241 if (im3_read(NORBOOT_OFF, hinfo, fw_addr) != 0) {
242 status = sad;
243 goto bye; /* no FW found */
244 }
245
246 if (identify_fw(hinfo) == FW_RB) {
247 /* FW found, but not OF, assume it is a RB bootloader,
248 already decrypted OF should be located just behind */
249 int nor_offset = NORBOOT_OFF + im3_nor_sz(hinfo);
250 if ((im3_read(nor_offset, hinfo, fw_addr) != 0)
251 || (identify_fw(hinfo) == FW_RB)) {
252 status = sad;
253 goto bye; /* OF not found, use iTunes to restore */
254 }
255 }
256
257 bl_nor_sz = im3_nor_sz(&bl_hinfo);
258 /* safety check - verify we are not going to overwrite useful data */
259 if (flsh_get_unused() < bl_nor_sz) {
260 status = sad2;
261 goto bye; /* no space if flash, use iTunes to restore */
262 }
263
264 /* write decrypted OF and RB bootloader, if any of these fails we
265 will try to retore OF to its original place */
266 if (!im3_write(NORBOOT_OFF + bl_nor_sz, hinfo)
267 || !im3_write(NORBOOT_OFF, &bl_hinfo)) {
268 im3_crypt(HWKEYAES_ENCRYPT, hinfo, fw_addr);
269 if (!im3_write(NORBOOT_OFF, hinfo)) {
270 /* corrupted NOR, use iTunes to restore */
271 status = fatal;
272 }
273 else {
274 /* RB bootloader not succesfully intalled, but device
275 was restored and should be working as before */
276 status = sad;
277 }
278 }
279
280bye:
281 /* minimum time between the initial and the final beeps */
282 while (USEC_TIMER < 2000000);
283 piezo_seq(status);
284 WDTCON = 0x100000; /* WDT reset */
285 while (1);
286}
287#endif /* DUALBOOT_UNINSTALL */
diff --git a/utils/mks5lboot/dualboot/dualboot.lds b/utils/mks5lboot/dualboot/dualboot.lds
new file mode 100644
index 0000000000..cb92e2a286
--- /dev/null
+++ b/utils/mks5lboot/dualboot/dualboot.lds
@@ -0,0 +1,59 @@
1#define ASM
2#include "config.h"
3#include "cpu.h"
4#include "mks5lboot.h"
5
6ENTRY(_start)
7OUTPUT_FORMAT(elf32-littlearm)
8OUTPUT_ARCH(arm)
9
10#define BIN_ORIG DFU_LOADADDR + BIN_OFFSET
11#define BIN_SIZE MAX_PAYLOAD
12
13MEMORY
14{
15 IRAM : ORIGIN = BIN_ORIG, LENGTH = BIN_SIZE
16}
17
18SECTIONS
19{
20 .text : {
21 *(.init.text*)
22 *(.text*)
23 *(.icode*)
24 . = ALIGN(4);
25 } > IRAM
26
27 /* include initialized BSS (if any) into DFU image */
28 .bss : {
29 *(.bss*)
30 *(.ibss*)
31 *(COMMON)
32 . = ALIGN(4);
33 } > IRAM
34
35#if 1
36 /* reuse pwnage as stack, 0x30c bytes available */
37 _exception_stack = BIN_ORIG;
38 _supervisor_stack = _exception_stack;
39#else
40 /* include stack into DFU image */
41 .stack : {
42 . += 0x400;
43 _supervisor_stack = .;
44 . += 0x200;
45 _exception_stack = .;
46 } > IRAM
47#endif
48
49 .data : {
50 *(.data*)
51 *(.rodata*)
52 *(.idata*)
53 *(.irodata*)
54 /* place bootloader IM3 header at the end, mkdfu
55 will concatenate the bootloader binary here */
56 . = ALIGN(16);
57 *(.im3info.data*)
58 } > IRAM
59}
diff --git a/utils/mks5lboot/dualboot/init.S b/utils/mks5lboot/dualboot/init.S
new file mode 100644
index 0000000000..bd049515f4
--- /dev/null
+++ b/utils/mks5lboot/dualboot/init.S
@@ -0,0 +1,43 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:
9 *
10 * Copyright © 2009 Michael Sparmann
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 .section .init.text, "ax", %progbits
23 .global _start
24
25_start:
26 mov r0, #0xD7
27 msr CPSR_c, r0 @ Abort mode, IRQs/FIQs disabled
28 ldr sp, =_exception_stack
29
30 mov r0, #0xDB
31 msr CPSR_c, r0 @ Undefined Instruction mode, IRQs/FIQs disabled
32 ldr sp, =_exception_stack
33
34 mov r0, #0xD3
35 msr CPSR_c, r0 @ Supervisor mode, IRQs/FIQs disabled
36 ldr sp, =_supervisor_stack
37
38 MOV R0, #0x00050000
39 ORR R0, #0x00000078
40 MCR p15, 0, R0, c1, c0, 0 @ Get rid of some CPU "features" likely to cause trouble
41
42 bl main
43 .ltorg
diff --git a/utils/mks5lboot/ipoddfu.c b/utils/mks5lboot/ipoddfu.c
new file mode 100644
index 0000000000..5e2914af4b
--- /dev/null
+++ b/utils/mks5lboot/ipoddfu.c
@@ -0,0 +1,1061 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2015 by Cástor Muñoz
11 *
12 * based on:
13 * ipoddfu_c by user890104
14 * xpwn/pwnmetheus2
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
20 *
21 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22 * KIND, either express or implied.
23 *
24 ****************************************************************************/
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <unistd.h>
29#include <stdbool.h>
30#include <string.h>
31#ifdef WIN32
32#include <windows.h>
33#include <setupapi.h>
34#endif
35#ifdef USE_LIBUSBAPI
36#include <libusb-1.0/libusb.h>
37#endif
38#ifdef __APPLE__
39#include <CoreFoundation/CoreFoundation.h>
40#include <IOKit/IOCFPlugIn.h>
41#include <IOKit/usb/IOUSBLib.h>
42#endif
43
44#include "mks5lboot.h"
45
46
47#ifdef WIN32
48#define sleep_ms(ms) Sleep(ms)
49#else
50#include <time.h>
51static void sleep_ms(unsigned int ms)
52{
53 struct timespec req;
54 req.tv_sec = ms / 1000;
55 req.tv_nsec = (ms % 1000) * 1000000;
56 nanosleep(&req, NULL);
57}
58#endif
59
60static void put_uint32le(unsigned char* p, uint32_t x)
61{
62 p[0] = x & 0xff;
63 p[1] = (x >> 8) & 0xff;
64 p[2] = (x >> 16) & 0xff;
65 p[3] = (x >> 24) & 0xff;
66}
67
68/*
69 * CRC32 functions
70 * Based on public domain implementation by Finn Yannick Jacobs.
71 *
72 * Written and copyright 1999 by Finn Yannick Jacobs
73 * No rights were reserved to this, so feel free to
74 * manipulate or do with it, what you want or desire :)
75 */
76
77/* crc32table[] built by crc32_init() */
78static uint32_t crc32table[256];
79
80/* Calculate crc32 */
81static uint32_t crc32(void *data, unsigned int len, uint32_t previousCrc32)
82{
83 uint32_t crc = ~previousCrc32;
84 unsigned char *d = (unsigned char*) data;
85 while (len--)
86 crc = (crc >> 8) ^ crc32table[(crc & 0xFF) ^ *d++];
87 return ~crc;
88}
89
90/* Calculate crc32table */
91static void crc32_init()
92{
93 uint32_t poly = 0xEDB88320L;
94 uint32_t crc;
95 int i, j;
96 for (i = 0; i < 256; ++i)
97 {
98 crc = i;
99 for (j = 0; j < 8; ++j)
100 crc = (crc >> 1) ^ ((crc & 1) ? poly : 0);
101 crc32table[i] = crc;
102 }
103}
104
105/* USB */
106#define APPLE_VID 0x05AC
107
108struct pid_info {
109 int pid;
110 int mode; /* 0->DFU, 1->WTF */
111 char *desc;
112};
113
114struct pid_info known_pids[] =
115{
116 /* DFU */
117 { 0x1220, 0, "Nano 2G" },
118 { 0x1223, 0, "Nano 3G / Classic" },
119 { 0x1224, 0, "Shuffle 3G" },
120 { 0x1225, 0, "Nano 4G" },
121 { 0x1231, 0, "Nano 5G" },
122 { 0x1232, 0, "Nano 6G" },
123 { 0x1233, 0, "Shuffle 4G" },
124 { 0x1234, 0, "Nano 7G" },
125 /* WTF */
126 { 0x1240, 1, "Nano 2G" },
127 { 0x1241, 1, "Classic 1G" },
128 { 0x1242, 1, "Nano 3G" },
129 { 0x1243, 1, "Nano 4G" },
130 { 0x1245, 1, "Classic 2G" },
131 { 0x1246, 1, "Nano 5G" },
132 { 0x1247, 1, "Classic 3G" },
133 { 0x1248, 1, "Nano 6G" },
134 { 0x1249, 1, "Nano 7G" },
135 { 0x124a, 1, "Nano 7G" },
136 { 0x1250, 1, "Classic 4G" },
137};
138#define N_KNOWN_PIDS (sizeof(known_pids)/sizeof(struct pid_info))
139
140struct usbControlSetup {
141 uint8_t bmRequestType;
142 uint8_t bRequest;
143 uint16_t wValue;
144 uint16_t wIndex;
145 uint16_t wLength;
146} __attribute__ ((packed));
147#define USB_CS_SZ (sizeof(struct usbControlSetup))
148
149struct usbStatusData {
150 uint8_t bStatus;
151 uint8_t bwPollTimeout0;
152 uint8_t bwPollTimeout1;
153 uint8_t bwPollTimeout2;
154 uint8_t bState;
155 uint8_t iString;
156} __attribute__ ((packed));
157
158
159/*
160 * DFU API
161 */
162#define DFU_PKT_SZ 2048 /* must be pow2 <= wTransferSize (2048) */
163
164/* DFU 1.1 specs */
165typedef enum {
166 appIDLE = 0,
167 appDETACH = 1,
168 dfuIDLE = 2,
169 dfuDNLOAD_SYNC = 3,
170 dfuDNBUSY = 4,
171 dfuDNLOAD_IDLE = 5,
172 dfuMANIFEST_SYNC = 6,
173 dfuMANIFEST = 7,
174 dfuMANIFEST_WAIT_RESET = 8,
175 dfuUPLOAD_IDLE = 9,
176 dfuERROR = 10
177} DFUState;
178
179typedef enum {
180 errNONE = 0,
181 errTARGET = 1,
182 errFILE = 2,
183 errWRITE = 3,
184 errERASE = 4,
185 errCHECK_ERASED = 5,
186 errPROG = 6,
187 errVERIFY = 7,
188 errADDRESS = 8,
189 errNOTDONE = 9,
190 errFIRMWARE = 10,
191 errVENDOR = 11,
192 errUSBR = 12,
193 errPOR = 13,
194 errUNKNOWN = 14,
195 errSTALLEDPKT = 15
196} DFUStatus;
197
198typedef enum {
199 DFU_DETACH = 0,
200 DFU_DNLOAD = 1,
201 DFU_UPLOAD = 2,
202 DFU_GETSTATUS = 3,
203 DFU_CLRSTATUS = 4,
204 DFU_GETSTATE = 5,
205 DFU_ABORT = 6
206} DFURequest;
207
208typedef enum {
209 DFUAPIFail = 0,
210 DFUAPISuccess,
211} dfuAPIResult;
212
213struct dfuDev {
214 struct dfuAPI *api;
215 int found_pid;
216 int detached;
217 char descr[256];
218 dfuAPIResult res;
219 char err[256];
220 /* API private */
221#ifdef WIN32
222 HANDLE fh;
223 HANDLE ph;
224 DWORD ec; /* winapi error code */
225#endif
226#ifdef USE_LIBUSBAPI
227 libusb_context* ctx;
228 libusb_device_handle* devh;
229 int rc; /* libusb return code */
230#endif
231#ifdef __APPLE__
232 IOUSBDeviceInterface** dev;
233 kern_return_t kr;
234#endif
235};
236
237struct dfuAPI {
238 char *name;
239 dfuAPIResult (*open_fn)(struct dfuDev*, int*);
240 dfuAPIResult (*dfureq_fn)(struct dfuDev*, struct usbControlSetup*, void*);
241 dfuAPIResult (*reset_fn)(struct dfuDev*);
242 void (*close_fn)(struct dfuDev*);
243};
244
245
246/*
247 * DFU API low-level (specific) functions
248 */
249static bool dfu_check_id(int vid, int pid, int *pid_list)
250{
251 int *p;
252 if (vid != APPLE_VID)
253 return 0;
254 for (p = pid_list; *p; p++)
255 if (*p == pid)
256 return 1;
257 return 0;
258}
259
260/* adds extra DFU request error info */
261static void dfu_add_reqerrstr(struct dfuDev *dfuh, struct usbControlSetup *cs)
262{
263 snprintf(dfuh->err + strlen(dfuh->err),
264 sizeof(dfuh->err) - strlen(dfuh->err), " (cs=%02x/%d/%d/%d/%d)",
265 cs->bmRequestType, cs->bRequest, cs->wValue, cs->wIndex, cs->wLength);
266}
267
268#ifdef WIN32
269static bool dfu_winapi_chkrc(struct dfuDev *dfuh, char *str, bool success)
270{
271 dfuh->res = (success) ? DFUAPISuccess : DFUAPIFail;
272 if (!success) {
273 dfuh->ec = GetLastError();
274 snprintf(dfuh->err, sizeof(dfuh->err), "%s error %ld", str, dfuh->ec);
275 }
276 return success;
277}
278
279static dfuAPIResult dfu_winapi_request(struct dfuDev *dfuh,
280 struct usbControlSetup* cs, void* data)
281{
282 unsigned char buf[USB_CS_SZ + DFU_PKT_SZ];
283 DWORD rdwr;
284 bool rc;
285
286 memcpy(buf, cs, USB_CS_SZ);
287
288 if (cs->bmRequestType & 0x80)
289 {
290 rc = ReadFile(dfuh->ph, buf, USB_CS_SZ + cs->wLength, &rdwr, NULL);
291 memcpy(data, buf+USB_CS_SZ, cs->wLength);
292 dfu_winapi_chkrc(dfuh, "DFU request failed: ReadFile()", rc);
293 }
294 else
295 {
296 memcpy(buf+USB_CS_SZ, data, cs->wLength);
297 rc = WriteFile(dfuh->ph, buf, USB_CS_SZ + cs->wLength, &rdwr, NULL);
298 dfu_winapi_chkrc(dfuh, "DFU request failed: WriteFile()", rc);
299 }
300 if (!rc)
301 dfu_add_reqerrstr(dfuh, cs);
302
303 return dfuh->res;
304}
305
306static dfuAPIResult dfu_winapi_reset(struct dfuDev *dfuh)
307{
308 DWORD bytesReturned;
309 bool rc = DeviceIoControl(dfuh->fh,
310 0x22000c, NULL, 0, NULL, 0, &bytesReturned, NULL);
311 dfu_winapi_chkrc(dfuh,
312 "Could not reset USB device: DeviceIoControl()", rc);
313 return dfuh->res;
314}
315
316static void dfu_winapi_close(struct dfuDev *dfuh)
317{
318 if (dfuh->fh != INVALID_HANDLE_VALUE) {
319 CloseHandle(dfuh->fh);
320 dfuh->fh = INVALID_HANDLE_VALUE;
321 }
322 if (dfuh->ph != INVALID_HANDLE_VALUE) {
323 CloseHandle(dfuh->ph);
324 dfuh->ph = INVALID_HANDLE_VALUE;
325 }
326}
327
328static const GUID GUID_AAPLDFU =
329 { 0xB8085869L, 0xFEB9, 0x404B, {0x8C, 0xB1, 0x1E, 0x5C, 0x14, 0xFA, 0x8C, 0x54}};
330
331static dfuAPIResult dfu_winapi_open(struct dfuDev *dfuh, int *pid_list)
332{
333 const GUID *guid = &GUID_AAPLDFU;
334 HDEVINFO devinfo = NULL;
335 SP_DEVICE_INTERFACE_DETAIL_DATA_A* details = NULL;
336 SP_DEVICE_INTERFACE_DATA iface;
337 char *path = NULL;
338 DWORD i, size;
339 bool rc;
340
341 dfuh->fh =
342 dfuh->ph = INVALID_HANDLE_VALUE;
343 dfuh->found_pid = 0;
344 dfuh->res = DFUAPISuccess;
345 dfuh->ec = 0;
346
347 /* Get DFU path */
348 devinfo = SetupDiGetClassDevsA(guid, NULL, NULL,
349 DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
350 if (!dfu_winapi_chkrc(dfuh, "SetupDiGetClassDevsA()",
351 (devinfo != INVALID_HANDLE_VALUE)))
352 goto error;
353
354 iface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
355
356 for (i = 0; SetupDiEnumDeviceInterfaces(devinfo, NULL, guid, i, &iface); i++)
357 {
358 int vid, pid;
359
360 SetupDiGetDeviceInterfaceDetailA(devinfo, &iface, NULL, 0, &size, NULL);
361
362 if (details) free(details);
363 details = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc(size);
364 details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
365 rc = SetupDiGetDeviceInterfaceDetailA(devinfo, &iface, details, size, NULL, NULL);
366 if (!dfu_winapi_chkrc(dfuh, "SetupDiGetDeviceInterfaceDetailA()", rc))
367 goto error;
368
369 CharUpperA(details->DevicePath);
370 if (sscanf(details->DevicePath, "%*4cUSB#VID_%04x&PID_%04x%*s", &vid, &pid) != 2)
371 continue;
372 if (!dfu_check_id(vid, pid, pid_list))
373 continue;
374
375 if (path) free(path);
376 path = malloc(size - sizeof(DWORD) + 16);
377 memcpy(path, details->DevicePath, size - sizeof(DWORD));
378
379 dfuh->fh = CreateFileA(path, GENERIC_READ|GENERIC_WRITE,
380 FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
381 if (!dfu_winapi_chkrc(dfuh, "CreateFileA(fh)", (dfuh->fh != INVALID_HANDLE_VALUE)))
382 goto error;
383
384 strcat(path, "\\PIPE0");
385 dfuh->ph = CreateFileA(path, GENERIC_READ|GENERIC_WRITE,
386 FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
387 if (!dfu_winapi_chkrc(dfuh, "CreateFileA(ph)", (dfuh->ph != INVALID_HANDLE_VALUE)))
388 goto error;
389
390 /* ok */
391 snprintf(dfuh->descr, sizeof(dfuh->descr), "%s", details->DevicePath);
392 dfuh->found_pid = pid;
393 goto bye;
394 }
395
396 if (!dfu_winapi_chkrc(dfuh, "SetupDiEnumDeviceInterfaces()",
397 (GetLastError() == ERROR_NO_MORE_ITEMS)))
398 goto error;
399
400 /* no devices found */
401
402bye:
403 if (path) free(path);
404 if (details) free(details);
405 if (devinfo) SetupDiDestroyDeviceInfoList(devinfo);
406 return dfuh->res;
407
408error:
409 dfu_winapi_close(dfuh);
410 goto bye;
411}
412#endif /* WIN32 */
413
414#ifdef USE_LIBUSBAPI
415static bool dfu_libusb_chkrc(struct dfuDev *dfuh, char *str)
416{
417 dfuh->res = (dfuh->rc < LIBUSB_SUCCESS) ? DFUAPIFail : DFUAPISuccess;
418 if (dfuh->res == DFUAPIFail)
419 snprintf(dfuh->err, sizeof(dfuh->err),
420 "%s: %s", str, libusb_error_name(dfuh->rc));
421 return (dfuh->res == DFUAPISuccess);
422}
423
424static dfuAPIResult dfu_libusb_request(struct dfuDev *dfuh,
425 struct usbControlSetup *cs, void *data)
426{
427 dfuh->rc = libusb_control_transfer(dfuh->devh, cs->bmRequestType,
428 cs->bRequest, cs->wValue, cs->wIndex, data, cs->wLength, 500);
429 if (!dfu_libusb_chkrc(dfuh, "DFU request failed"))
430 dfu_add_reqerrstr(dfuh, cs);
431 return dfuh->res;
432}
433
434static dfuAPIResult dfu_libusb_reset(struct dfuDev *dfuh)
435{
436 dfuh->rc = libusb_reset_device(dfuh->devh);
437 dfu_libusb_chkrc(dfuh, "Could not reset USB device");
438 return dfuh->res;
439}
440
441static void dfu_libusb_close(struct dfuDev *dfuh)
442{
443 if (dfuh->devh) {
444 libusb_release_interface(dfuh->devh, 0);
445 if (dfuh->detached)
446 libusb_attach_kernel_driver(dfuh->devh, 0);
447 libusb_close(dfuh->devh);
448 dfuh->devh = NULL;
449 }
450 if (dfuh->ctx) {
451 libusb_exit(dfuh->ctx);
452 dfuh->ctx = NULL;
453 }
454}
455
456static dfuAPIResult dfu_libusb_open(struct dfuDev *dfuh, int *pid_list)
457{
458 struct libusb_device_descriptor desc;
459 libusb_device **devs = NULL, *dev;
460 int n_devs, i;
461
462 dfuh->devh = NULL;
463 dfuh->found_pid = 0;
464 dfuh->detached = 0;
465 dfuh->res = DFUAPISuccess;
466
467 dfuh->rc = libusb_init(&(dfuh->ctx));
468 if (!dfu_libusb_chkrc(dfuh, "Could not init USB library")) {
469 dfuh->ctx = NULL; /* invalidate ctx (if any) */
470 goto error;
471 }
472
473 n_devs =
474 dfuh->rc = libusb_get_device_list(dfuh->ctx, &devs);
475 if (!dfu_libusb_chkrc(dfuh, "Could not get USB device list"))
476 goto error;
477
478 for (i = 0; i < n_devs; ++i)
479 {
480 dev = devs[i];
481
482 /* Note: since libusb-1.0.16 (LIBUSB_API_VERSION >= 0x01000102)
483 this function always succeeds. */
484 if (libusb_get_device_descriptor(dev, &desc) != LIBUSB_SUCCESS)
485 continue; /* Unable to get device descriptor */
486
487 if (!dfu_check_id(desc.idVendor, desc.idProduct, pid_list))
488 continue;
489
490 dfuh->rc = libusb_open(dev, &(dfuh->devh));
491 if (!dfu_libusb_chkrc(dfuh, "Could not open USB device"))
492 goto error;
493
494 dfuh->rc = libusb_set_configuration(dfuh->devh, 1);
495 if (!dfu_libusb_chkrc(dfuh, "Could not set USB configuration"))
496 goto error;
497
498 dfuh->rc = libusb_kernel_driver_active(dfuh->devh, 0);
499 if (dfuh->rc != LIBUSB_ERROR_NOT_SUPPORTED) {
500 if (!dfu_libusb_chkrc(dfuh, "Could not get USB driver status"))
501 goto error;
502 if (dfuh->rc == 1) {
503 dfuh->rc = libusb_detach_kernel_driver(dfuh->devh, 0);
504 if (!dfu_libusb_chkrc(dfuh, "Could not detach USB driver"))
505 goto error;
506 dfuh->detached = 1;
507 }
508 }
509
510 dfuh->rc = libusb_claim_interface(dfuh->devh, 0);
511 if (!dfu_libusb_chkrc(dfuh, "Could not claim USB interface"))
512 goto error;
513
514 /* ok */
515 snprintf(dfuh->descr, sizeof(dfuh->descr),
516 "[%04x:%04x] at bus %d, device %d, USB ver. %04x",
517 desc.idVendor, desc.idProduct, libusb_get_bus_number(dev),
518 libusb_get_device_address(dev), desc.bcdUSB);
519 dfuh->found_pid = desc.idProduct;
520 break;
521 }
522
523bye:
524 if (devs)
525 libusb_free_device_list(devs, 1);
526 if (!dfuh->found_pid)
527 dfu_libusb_close(dfuh);
528 return dfuh->res;
529
530error:
531 goto bye;
532}
533#endif /* USE_LIBUSBAPI */
534
535#ifdef __APPLE__
536static bool dfu_iokit_chkrc(struct dfuDev *dfuh, char *str)
537{
538 dfuh->res = (dfuh->kr == kIOReturnSuccess) ? DFUAPISuccess : DFUAPIFail;
539 if (dfuh->res == DFUAPIFail)
540 snprintf(dfuh->err, sizeof(dfuh->err),
541 "%s: error %08x", str, dfuh->kr);
542 return (dfuh->res == DFUAPISuccess);
543}
544
545static dfuAPIResult dfu_iokit_request(struct dfuDev *dfuh,
546 struct usbControlSetup *cs, void *data)
547{
548 IOUSBDevRequest req;
549 req.bmRequestType = cs->bmRequestType;
550 req.bRequest = cs->bRequest;
551 req.wValue = cs->wValue;
552 req.wIndex = cs->wIndex;
553 req.wLength = cs->wLength;
554 req.pData = data;
555
556 dfuh->kr = (*(dfuh->dev))->DeviceRequest(dfuh->dev, &req);
557 if (!dfu_iokit_chkrc(dfuh, "DFU request failed"))
558 dfu_add_reqerrstr(dfuh, cs);
559
560 return dfuh->res;
561}
562
563static dfuAPIResult dfu_iokit_reset(struct dfuDev *dfuh)
564{
565 dfuh->kr = (*(dfuh->dev))->ResetDevice(dfuh->dev);
566#if 0
567 /* On 10.11+ ResetDevice() returns no error but does not perform
568 * any reset, just a kernel log message.
569 * USBDeviceReEnumerate() could be used as a workaround.
570 */
571 dfuh->kr = (*(dfuh->dev))->USBDeviceReEnumerate(dfuh->dev, 0);
572#endif
573 dfu_iokit_chkrc(dfuh, "Could not reset USB device");
574 return dfuh->res;
575}
576
577static void dfu_iokit_close(struct dfuDev *dfuh)
578{
579 if (dfuh->dev) {
580 (*(dfuh->dev))->USBDeviceClose(dfuh->dev);
581 (*(dfuh->dev))->Release(dfuh->dev);
582 dfuh->dev = NULL;
583 }
584}
585
586static dfuAPIResult dfu_iokit_open(struct dfuDev *dfuh, int *pid_list)
587{
588 kern_return_t kr;
589 CFMutableDictionaryRef usb_matching_dict = 0;
590 io_object_t usbDevice;
591 io_iterator_t usb_iterator = IO_OBJECT_NULL;
592 IOCFPlugInInterface **plugInInterface = NULL;
593 IOUSBDeviceInterface **dev = NULL;
594 HRESULT result;
595 SInt32 score;
596 UInt16 vendor;
597 UInt16 product;
598 UInt16 release;
599
600 dfuh->dev = NULL;
601 dfuh->found_pid = 0;
602 dfuh->res = DFUAPISuccess;
603
604 usb_matching_dict = IOServiceMatching(kIOUSBDeviceClassName);
605 dfuh->kr = IOServiceGetMatchingServices(
606 kIOMasterPortDefault, usb_matching_dict, &usb_iterator);
607 if (!dfu_iokit_chkrc(dfuh, "Could not get matching services"))
608 goto error;
609
610 while ((usbDevice = IOIteratorNext(usb_iterator)))
611 {
612 /* Create an intermediate plug-in */
613 kr = IOCreatePlugInInterfaceForService(usbDevice,
614 kIOUSBDeviceUserClientTypeID,
615 kIOCFPlugInInterfaceID,
616 &plugInInterface,
617 &score);
618 IOObjectRelease(usbDevice);
619
620 if ((kIOReturnSuccess != kr) || !plugInInterface)
621 continue; /* Unable to create a plugin */
622
623 /* Now create the device interface */
624 result = (*plugInInterface)->QueryInterface(plugInInterface,
625 CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID),
626 (LPVOID*)&dev);
627 (*plugInInterface)->Release(plugInInterface);
628
629 if (result || !dev)
630 continue; /* Couldn't create a device interface */
631
632 kr = (*dev)->GetDeviceVendor(dev, &vendor);
633 kr = (*dev)->GetDeviceProduct(dev, &product);
634 kr = (*dev)->GetDeviceReleaseNumber(dev, &release);
635
636 if (!dfu_check_id(vendor, product, pid_list)) {
637 (*dev)->Release(dev);
638 continue;
639 }
640
641 /* Device found, open it */
642 dfuh->kr = (*dev)->USBDeviceOpen(dev);
643 if (!dfu_iokit_chkrc(dfuh, "Could not open USB device")) {
644 (*dev)->Release(dev);
645 goto error;
646 }
647
648 /* ok */
649 dfuh->found_pid = product;
650 dfuh->dev = dev;
651 snprintf(dfuh->descr, sizeof(dfuh->descr),
652 "[%04x:%04x] release: %d", vendor, product, release);
653 break;
654 }
655
656bye:
657 if (usb_iterator != IO_OBJECT_NULL)
658 IOObjectRelease(usb_iterator);
659 return dfuh->res;
660
661error:
662 goto bye;
663}
664#endif /* __APPLE__ */
665
666/* list of suported APIs */
667static struct dfuAPI api_list[] =
668{
669#ifdef WIN32
670 { "winapi",
671 dfu_winapi_open,
672 dfu_winapi_request,
673 dfu_winapi_reset,
674 dfu_winapi_close },
675#endif
676#ifdef USE_LIBUSBAPI
677 { "libusb",
678 dfu_libusb_open,
679 dfu_libusb_request,
680 dfu_libusb_reset,
681 dfu_libusb_close },
682#endif
683#ifdef __APPLE__
684 { "IOKit",
685 dfu_iokit_open,
686 dfu_iokit_request,
687 dfu_iokit_reset,
688 dfu_iokit_close },
689#endif
690};
691#define N_DFU_APIS (sizeof(api_list)/sizeof(struct dfuAPI))
692
693
694/*
695 * DFU API common functions
696 */
697static int DEBUG_DFUREQ = 0;
698
699static dfuAPIResult dfuapi_request(struct dfuDev *dfuh,
700 struct usbControlSetup *cs, void *data)
701{
702 if (!DEBUG_DFUREQ)
703 return dfuh->api->dfureq_fn(dfuh, cs, data);
704
705 /* DEBUG */
706
707 /* previous state */
708 unsigned char ste = 0;
709 struct usbControlSetup css = { 0xA1, DFU_GETSTATE, 0, 0, sizeof(ste) };
710 if (dfuh->api->dfureq_fn(dfuh, &css, &ste) != DFUAPISuccess) {
711 snprintf(dfuh->err + strlen(dfuh->err), sizeof(dfuh->err) -
712 strlen(dfuh->err), " [DEBUG_DFUREQ ERROR: state=%d]", ste);
713 goto error;
714 }
715
716 dfuh->api->dfureq_fn(dfuh, cs, data);
717 fprintf(stderr, "[DEBUG]: REQ: ste=%d, cs=%2x/%d/%d/%d/%d -> %s",
718 ste, cs->bmRequestType, cs->bRequest, cs->wValue,
719 cs->wIndex, cs->wLength,
720 (dfuh->res == DFUAPISuccess) ? "ok" : "ERROR");
721 if (cs->bRequest == DFU_GETSTATE)
722 fprintf(stderr, " (state=%d)", *((unsigned char*)(data)));
723 if (cs->bRequest == DFU_GETSTATUS) {
724 struct usbStatusData *sd = (struct usbStatusData*)data;
725 fprintf(stderr, " (status=%d, polltmo=%d, state=%d)", sd->bStatus,
726 (sd->bwPollTimeout2 << 16) | (sd->bwPollTimeout1 << 8) |
727 (sd->bwPollTimeout0), sd->bState);
728 }
729 fputc('\n', stderr);
730 fflush(stderr);
731
732bye:
733 return dfuh->res;
734error:
735 goto bye;
736}
737
738static dfuAPIResult dfuapi_req_getstatus(struct dfuDev *dfuh,
739 DFUStatus *status, int *poll_tmo /*ms*/,
740 DFUState *state)
741{
742 struct usbStatusData sd = { 0, 0, 0, 0, 0, 0 };
743 struct usbControlSetup cs = { 0xA1, DFU_GETSTATUS, 0, 0, sizeof(sd) };
744 dfuapi_request(dfuh, &cs, &sd);
745 if (status) *status = sd.bStatus;
746 if (state) *state = sd.bState;
747 if (poll_tmo) *poll_tmo = (sd.bwPollTimeout2 << 16) |
748 (sd.bwPollTimeout1 << 8) | (sd.bwPollTimeout0);
749 return dfuh->res;
750}
751
752static dfuAPIResult dfuapi_req_getstate(struct dfuDev *dfuh, DFUState *state)
753{
754 unsigned char sts = 0;
755 struct usbControlSetup cs = { 0xA1, DFU_GETSTATE, 0, 0, sizeof(sts) };
756 dfuapi_request(dfuh, &cs, &sts);
757 if (state) *state = sts;
758 return dfuh->res;
759}
760
761static dfuAPIResult dfuapi_req_dnload(struct dfuDev* dfuh, uint16_t blknum,
762 uint16_t len, unsigned char *data)
763{
764 struct usbControlSetup cs = { 0x21, DFU_DNLOAD, blknum, 0, len };
765 return dfuapi_request(dfuh, &cs, data);
766}
767
768/* not used */
769#if 0
770static dfuAPIResult dfuapi_req_upload(struct dfuDev* dfuh,
771 uint16_t blknum, uint16_t len, unsigned char *data)
772{
773 struct usbControlSetup cs = { 0xA1, DFU_UPLOAD, blknum, 0, len };
774 return dfuapi_request(dfuh, &cs, data);
775}
776
777static dfuAPIResult dfuapi_req_clrstatus(struct dfuDev* dfuh)
778{
779 struct usbControlSetup cs = { 0x21, DFU_CLRSTATUS, 0, 0, 0 };
780 return dfuapi_request(dfuh, &cs, NULL);
781}
782
783static dfuAPIResult dfuapi_req_abort(struct dfuDev* dfuh)
784{
785 struct usbControlSetup cs = { 0x21, DFU_ABORT, 0, 0, 0 };
786 return dfuapi_request(dfuh, &cs, NULL);
787}
788
789/* not implemented on DFU8702 */
790static dfuAPIResult dfuapi_req_detach(struct dfuDev* dfuh, int tmo)
791{
792 struct usbControlSetup cs = { 0x21, DFU_DETACH, tmo, 0, 0 };
793 return dfuapi_request(dfuh, &cs, NULL);
794}
795#endif
796
797static dfuAPIResult dfuapi_reset(struct dfuDev *dfuh)
798{
799 return dfuh->api->reset_fn(dfuh);
800}
801
802static dfuAPIResult dfuapi_send_packet(struct dfuDev* dfuh, uint16_t blknum,
803 uint16_t len, unsigned char *data, DFUStatus *status,
804 int *poll_tmo, DFUState *state, DFUState *pre_state)
805{
806 if (dfuapi_req_dnload(dfuh, blknum, len, data) != DFUAPISuccess)
807 goto error;
808
809 /* device is in dfuDLSYNC state, waiting for a GETSTATUS request
810 * to enter the next state, if she respond with dfuDLBUSY then
811 * we must wait to resend the GETSTATUS request */
812
813 if (dfuapi_req_getstatus(dfuh, status, poll_tmo, state) != DFUAPISuccess)
814 goto error;
815
816 if (*state == dfuDNBUSY) {
817 if (*poll_tmo)
818 sleep_ms(*poll_tmo);
819 if (pre_state)
820 if (dfuapi_req_getstate(dfuh, pre_state) != DFUAPISuccess)
821 goto error;
822 if (dfuapi_req_getstatus(dfuh, status, poll_tmo, state) != DFUAPISuccess)
823 goto error;
824 }
825
826bye:
827 return dfuh->res;
828error:
829 goto bye;
830}
831
832static void dfuapi_set_err(struct dfuDev *dfuh, char *str)
833{
834 dfuh->res = DFUAPIFail;
835 strncpy(dfuh->err, str, sizeof(dfuh->err));
836}
837
838static dfuAPIResult dfuapi_open(struct dfuDev *dfuh, int pid)
839{
840 int pid_l[N_KNOWN_PIDS+1] = { 0 };
841 struct dfuAPI *api;
842 unsigned i, p;
843
844 /* fill pid list */
845 if (pid)
846 pid_l[0] = pid;
847 else
848 for (p = 0; p < N_KNOWN_PIDS; p++)
849 pid_l[p] = known_pids[p].pid;
850
851 for (i = 0; i < N_DFU_APIS; i++)
852 {
853 api = &api_list[i];
854 if (api->open_fn(dfuh, pid_l) != DFUAPISuccess)
855 goto error;
856 if (dfuh->found_pid) {
857 /* ok */
858 dfuh->api = api;
859 printf("[INFO] %s: found %s\n", api->name, dfuh->descr);
860 for (p = 0; p < N_KNOWN_PIDS; p++) {
861 if (known_pids[p].pid == dfuh->found_pid) {
862 printf("[INFO] iPod %s, mode: %s\n", known_pids[p].desc,
863 known_pids[p].mode ? "WTF" : "DFU");
864 break;
865 }
866 }
867 fflush(stdout);
868 goto bye;
869 }
870 printf("[INFO] %s: no DFU devices found\n", api->name);
871 fflush(stdout);
872 }
873
874 /* error */
875 dfuapi_set_err(dfuh, "DFU device not found");
876
877bye:
878 return dfuh->res;
879error:
880 goto bye;
881}
882
883static void dfuapi_destroy(struct dfuDev *dfuh)
884{
885 if (dfuh) {
886 if (dfuh->api)
887 dfuh->api->close_fn(dfuh);
888 free(dfuh);
889 }
890}
891
892static struct dfuDev *dfuapi_create(void)
893{
894 return calloc(sizeof(struct dfuDev), 1);
895}
896
897
898/*
899 * app level functions
900 */
901static int ipoddfu_download_file(struct dfuDev* dfuh,
902 unsigned char *data, unsigned long size)
903{
904 unsigned int blknum, len, remaining;
905 int poll_tmo;
906 DFUStatus status;
907 DFUState state;
908
909 if (dfuapi_req_getstate(dfuh, &state) != DFUAPISuccess)
910 goto error;
911
912 if (state != dfuIDLE) {
913 dfuapi_set_err(dfuh, "Could not start DFU download: not idle");
914 goto error;
915 }
916
917 blknum = 0;
918 remaining = size;
919 while (remaining)
920 {
921 len = (remaining < DFU_PKT_SZ) ? remaining : DFU_PKT_SZ;
922
923 if (dfuapi_send_packet(dfuh, blknum, len, data + blknum*DFU_PKT_SZ,
924 &status, &poll_tmo, &state, NULL) != DFUAPISuccess)
925 goto error;
926
927 if (state != dfuDNLOAD_IDLE) {
928 dfuapi_set_err(dfuh, "DFU download aborted: unexpected state");
929 goto error;
930 }
931
932 remaining -= len;
933 blknum++;
934 }
935
936 /* send ZLP */
937 DFUState pre_state = appIDLE; /* dummy state */
938 if (dfuapi_send_packet(dfuh, blknum, 0, NULL,
939 &status, &poll_tmo, &state, &pre_state) != DFUAPISuccess) {
940 if (pre_state == dfuMANIFEST_SYNC)
941 goto ok; /* pwnaged .dfu file */
942 goto error;
943 }
944
945 if (state != dfuMANIFEST) {
946 if (status == errFIRMWARE)
947 dfuapi_set_err(dfuh, "DFU download failed: corrupt firmware");
948 else
949 dfuapi_set_err(dfuh, "DFU download failed: unexpected state");
950 goto error;
951 }
952
953 /* wait for manifest stage */
954 if (poll_tmo)
955 sleep_ms(poll_tmo);
956
957 if (dfuapi_req_getstatus(dfuh, &status, NULL, &state) != DFUAPISuccess)
958 goto ok; /* 1223 .dfu file */
959
960 /* XXX: next code never tested */
961
962 if (state != dfuMANIFEST_WAIT_RESET) {
963 if (status == errVERIFY)
964 dfuapi_set_err(dfuh, "DFU manifest failed: wrong FW verification");
965 else
966 dfuapi_set_err(dfuh, "DFU manifest failed: unexpected state");
967 goto error;
968 }
969
970 if (dfuapi_reset(dfuh) != DFUAPISuccess)
971 goto error;
972
973ok:
974 return 1;
975error:
976 return 0;
977}
978
979/* exported functions */
980int ipoddfu_send(int pid, unsigned char *data, int size,
981 char* errstr, int errstrsize)
982{
983 struct dfuDev *dfuh;
984 unsigned char *buf;
985 uint32_t checksum;
986 int ret = 1; /* ok */
987
988 dfuh = dfuapi_create();
989
990 buf = malloc(size+4);
991 if (!buf) {
992 dfuapi_set_err(dfuh, "Could not allocate memory for DFU buffer");
993 goto error;
994 }
995
996 if (memcmp(data, IM3_IDENT, 4)) {
997 dfuapi_set_err(dfuh, "Bad DFU image data");
998 goto error;
999 }
1000
1001 crc32_init();
1002 checksum = crc32(data, size, 0);
1003 memcpy(buf, data, size);
1004 put_uint32le(buf+size, ~checksum);
1005
1006 if (dfuapi_open(dfuh, pid) != DFUAPISuccess)
1007 goto error;
1008
1009 if (!ipoddfu_download_file(dfuh, buf, size+4))
1010 goto error;
1011
1012bye:
1013 if (buf) free(buf);
1014 dfuapi_destroy(dfuh);
1015 return ret;
1016
1017error:
1018 ret = 0;
1019 if (errstr)
1020 snprintf(errstr, errstrsize, "[ERR] %s", dfuh->err);
1021 goto bye;
1022}
1023
1024/* search for the DFU device and gets its DFUState */
1025int ipoddfu_scan(int pid, int *state, int reset,
1026 char* errstr, int errstrsize)
1027{
1028 struct dfuDev *dfuh;
1029 int ret = 1; /* ok */
1030
1031 dfuh = dfuapi_create();
1032
1033 if (dfuapi_open(dfuh, pid) != DFUAPISuccess)
1034 goto error;
1035
1036 if (reset)
1037 if (dfuapi_reset(dfuh) != DFUAPISuccess)
1038 goto error;
1039
1040 if (state) {
1041 DFUState sts;
1042 if (dfuapi_req_getstate(dfuh, &sts) != DFUAPISuccess)
1043 goto error;
1044 *state = (int)sts;
1045 }
1046
1047bye:
1048 dfuapi_destroy(dfuh);
1049 return ret;
1050
1051error:
1052 ret = 0;
1053 if (errstr)
1054 snprintf(errstr, errstrsize, "[ERR] %s", dfuh->err);
1055 goto bye;
1056}
1057
1058void ipoddfu_debug(int debug)
1059{
1060 DEBUG_DFUREQ = debug;
1061}
diff --git a/utils/mks5lboot/main.c b/utils/mks5lboot/main.c
new file mode 100644
index 0000000000..31e16eca82
--- /dev/null
+++ b/utils/mks5lboot/main.c
@@ -0,0 +1,296 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2015 by Cástor Muñoz
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 <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <unistd.h>
26#include <fcntl.h>
27#include <sys/types.h>
28#include <sys/stat.h>
29
30#include "mks5lboot.h"
31
32/* Win32 compatibility */
33#ifndef O_BINARY
34#define O_BINARY 0
35#endif
36
37#ifdef WIN32
38#include <windows.h>
39#define sleep_ms(ms) Sleep(ms)
40#else
41#include <time.h>
42static void sleep_ms(unsigned int ms)
43{
44 struct timespec req;
45 req.tv_sec = ms / 1000;
46 req.tv_nsec = (ms % 1000) * 1000000;
47 nanosleep(&req, NULL);
48}
49#endif
50
51#define DEFAULT_LOOP_PERIOD 1 /* seconds */
52
53#define _ERR(format, ...) \
54 do { \
55 snprintf(errstr, errstrsize, "[ERR] "format, __VA_ARGS__); \
56 goto error; \
57 } while(0)
58
59static int write_file(char *outfile, unsigned char* buf,
60 int bufsize, char* errstr, int errstrsize)
61{
62 int fd = open(outfile, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, 0666);
63 if (fd < 0)
64 _ERR("Could not open %s for writing", outfile);
65
66 if (write(fd, buf, bufsize) != bufsize)
67 _ERR("Could not write file %s", outfile);
68
69 return 1;
70
71error:
72 return 0;
73}
74
75static unsigned char *read_file(char *infile, int *bufsize,
76 char* errstr, int errstrsize)
77{
78 unsigned char *buf;
79 int fd;
80 struct stat s;
81
82 fd = open(infile, O_RDONLY|O_BINARY);
83 if (fd < 0)
84 _ERR("Could not open %s for reading", infile);
85
86 if (fstat(fd, &s) < 0)
87 _ERR("Checking size of input file %s", infile);
88
89 *bufsize = s.st_size;
90
91 buf = malloc(*bufsize);
92 if (buf == NULL)
93 _ERR("Could not allocate memory for %s", infile);
94
95 if (read(fd, buf, *bufsize) != *bufsize)
96 _ERR("Could not read file %s", infile);
97
98 return buf;
99
100error:
101 return NULL;
102}
103
104static void usage(void)
105{
106 fprintf(stderr,
107 "Usage:\n"
108 " mks5lboot --bl-inst <bootloader.ipod> [-p <pid>] [--single]\n"
109 " --bl-uninst <platform> [-p <pid>]\n"
110 " --dfuscan [--loop [<sec>]] [-p <pid>]\n"
111 " --dfusend <infile.dfu> [-p <pid>]\n"
112 " --dfureset [--loop [<sec>]] [-p <pid>]\n"
113 " --mkdfu-inst <bootloader.ipod> <outfile.dfu> [--single]\n"
114 " --mkdfu-uninst <platform> <outfile.dfu>\n"
115 " --mkdfu-raw <filename.bin> <outfile.dfu>\n"
116 "\n"
117 "Commands:\n"
118 " --bl-inst Install file <bootloader.ipod> into an iPod device\n"
119 " (same as --mkdfu-inst and --dfusend).\n"
120 " --bl-uninst Remove a bootloader from an iPod device (same as\n"
121 " --mkdfu-uninst and --dfusend).\n"
122 "\n"
123 " --dfuscan scan for DFU USB devices and outputs the status.\n"
124 " --dfusend send DFU image <infile.dfu> to the device.\n"
125 " --dfureset reset DFU USB device bus.\n"
126 "\n"
127 " --mkdfu-inst Build a DFU image containing an installer for\n"
128 " <bootloader.ipod>, save it as <outfile.dfu>.\n"
129 " --mkdfu-uninst Build a DFU image containing an uninstaler for\n"
130 " <platform> devices, save it as <outfile.dfu>.\n"
131 " --mkdfu-raw Build a DFU image containing raw executable\n"
132 " code, save it ass <outfile.dfu>. <infile.bin>\n"
133 " is the code you want to run, it is loaded at\n"
134 " address 0x%08x and executed.\n"
135 "\n"
136 " <bootloader.ipod> is the rockbox bootloader that you want to\n"
137 " install (previously scrambled with tools/scramble utility).\n"
138 "\n"
139 " <platform> is the name of the platform (type of device) for\n"
140 " which the DFU uninstaller will be built. Currently supported\n"
141 " platform names are:\n"
142 " ipod6g: iPod Classic 6G\n"
143 "\n"
144 "Options:\n"
145 " -p, --pid <pid> Use a specific <pid> (Product Id) USB device,\n"
146 " if this option is ommited then it uses the\n"
147 " first USB DFU device found.\n"
148 " -l, --loop <sec> Run the command every <sec> seconds, default\n"
149 " period (<sec> ommited) is %d seconds.\n"
150 " -S, --single Be careful using this option. The bootloader\n"
151 " is installed for single boot, the original\n"
152 " Apple NOR boot is destroyed (if it exists),\n"
153 " and only Rockbox can be used.\n"
154 , DFU_LOADADDR + BIN_OFFSET
155 , DEFAULT_LOOP_PERIOD);
156
157 exit(1);
158}
159
160int main(int argc, char* argv[])
161{
162 char *dfuoutfile = NULL;
163 char *dfuinfile = NULL;
164 char *dfu_arg = NULL;
165 int dfu_type = DFU_NONE;
166 int n_cmds = 0;
167 int scan = 0;
168 int pid = 0;
169 int reset = 0;
170 int loop = 0;
171 int single = 0;
172 char errstr[200];
173 unsigned char *dfubuf;
174 int dfusize;
175
176 fprintf(stderr,
177#if defined(WIN32) && defined(USE_LIBUSBAPI)
178 "mks5lboot Version " VERSION " (libusb)\n"
179#else
180 "mks5lboot Version " VERSION "\n"
181#endif
182 "This is free software; see the source for copying conditions. There is NO\n"
183 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
184 "\n");
185 fflush(stderr);
186
187 while (--argc)
188 {
189 argv++;
190 if (!memcmp(*argv, "--bl", 4)) {
191 if (!strcmp(*argv+4, "-inst")) dfu_type = DFU_INST;
192 else if (!strcmp(*argv+4, "-uninst")) dfu_type = DFU_UNINST;
193 else usage();
194 if (!--argc) usage();
195 dfu_arg = *++argv;
196 n_cmds++;
197 }
198 else if (!memcmp(*argv, "--mkdfu", 7)) {
199 if (!strcmp(*argv+7, "-inst")) dfu_type = DFU_INST;
200 else if (!strcmp(*argv+7, "-uninst")) dfu_type = DFU_UNINST;
201 else if (!strcmp(*argv+7, "-raw")) dfu_type = DFU_RAW;
202 else usage();
203 if (!--argc) usage();
204 dfu_arg = *++argv;
205 if (!--argc) usage();
206 dfuoutfile = *++argv;
207 n_cmds++;
208 }
209 else if (!strcmp(*argv, "--dfusend")) {
210 if (!--argc) usage();
211 dfuinfile = *++argv;
212 n_cmds++;
213 }
214 else if (!strcmp(*argv, "--dfuscan")) {
215 scan = 1;
216 n_cmds++;
217 }
218 else if (!strcmp(*argv, "--dfureset")) {
219 scan = 1;
220 reset = 1;
221 n_cmds++;
222 }
223 else if (!strcmp(*argv, "--pid") || !strcmp(*argv, "-p")) {
224 if (!--argc) usage();
225 if (sscanf(*++argv, "%x", &pid) != 1) usage();
226 }
227 else if (!strcmp(*argv, "--loop") || !strcmp (*argv, "-l")) {
228 if (!(argc-1) || *(argv+1)[0] == '-') {
229 loop = DEFAULT_LOOP_PERIOD;
230 }
231 else {
232 if ((sscanf(*++argv, "%d", &loop) != 1) || !loop) usage();
233 argc--;
234 }
235 }
236 else if (!strcmp(*argv, "--single") || !strcmp(*argv, "-S")) {
237 single = 1;
238 }
239 else if (!strcmp(*argv, "--debug")) {
240 ipoddfu_debug(1);
241 }
242 else
243 usage();
244 }
245
246 if (n_cmds != 1)
247 usage();
248
249 if ((dfu_type == DFU_INST) && single)
250 dfu_type = DFU_INST_SINGLE;
251
252 if (scan) {
253 int cnt = 0;
254 while (1) {
255 int state, res;
256 if (loop) printf("[%d] ", cnt);
257 else printf("[INFO] ");
258 printf("DFU %s:\n", reset ? "reset":"scan");
259 res = ipoddfu_scan(pid, &state, reset, errstr, sizeof(errstr));
260 if (res == 0)
261 printf("%s\n", errstr);
262 else
263 printf("[INFO] DFU device state: %d\n", state);
264 if (!loop)
265 exit(!res);
266 fflush(stdout);
267 sleep_ms(loop*1000);
268 cnt += loop;
269 }
270 }
271
272 if (dfuinfile)
273 dfubuf = read_file(dfuinfile, &dfusize, errstr, sizeof(errstr));
274 else
275 dfubuf = mkdfu(dfu_type, dfu_arg, &dfusize, errstr, sizeof(errstr));
276
277 if (!dfubuf)
278 goto error;
279
280 if (dfuoutfile) {
281 if (write_file(dfuoutfile, dfubuf, dfusize, errstr, sizeof(errstr))) {
282 printf("[INFO] Created file %s (%d bytes)\n", dfuoutfile, dfusize);
283 exit(0);
284 }
285 }
286 else {
287 if (ipoddfu_send(pid, dfubuf, dfusize, errstr, sizeof(errstr))) {
288 printf("[INFO] DFU image sent successfully (%d bytes)\n", dfusize);
289 exit(0);
290 }
291 }
292
293error:
294 printf("%s\n", errstr);
295 exit(1);
296}
diff --git a/utils/mks5lboot/mkdfu.c b/utils/mks5lboot/mkdfu.c
new file mode 100644
index 0000000000..bb1929bffd
--- /dev/null
+++ b/utils/mks5lboot/mkdfu.c
@@ -0,0 +1,318 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2015 by Cástor Muñoz
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#include <stdio.h>
22#include <stdlib.h>
23#include <stdint.h>
24#include <stdbool.h>
25
26#include <sys/types.h>
27#include <sys/stat.h>
28#include <fcntl.h>
29#include <unistd.h>
30#include <string.h>
31
32#include "mks5lboot.h"
33
34/* Header for ARM code binaries */
35#include "dualboot.h"
36
37/* Win32 compatibility */
38#ifndef O_BINARY
39#define O_BINARY 0
40#endif
41
42/*
43 * This code is based on emCORE, adds a couple of improvements thanks to
44 * some extra features in Apple's ROM:
45 * - Generic Im3Info header valid for all payloads. It is done by moving
46 * the certificate to a fixed position (before data), and using a 'magic'
47 * value (0x300) for signature offset.
48 * - Some integer overflows in ROM make it possible to use the free space
49 * available in Im3Hdr, resulting a maximum payload size of:
50 * 128 KiB - 0x50 bytes (IM3INFO_SZ) - 700 bytes (CERT_SIZE).
51 */
52
53const struct ipod_models ipod_identity[] =
54{
55 [MODEL_IPOD6G] = {
56 "Classic 6G", "ipod6g", "ip6g", 71,
57 dualboot_install_ipod6g, sizeof(dualboot_install_ipod6g),
58 dualboot_uninstall_ipod6g, sizeof(dualboot_uninstall_ipod6g) },
59};
60
61struct Im3Info s5l8702hdr =
62{
63 .ident = IM3_IDENT,
64 .version = IM3_VERSION,
65 .enc_type = 3,
66 .u.enc34 = {
67 .sign_off = "\x00\x03\x00\x00",
68 .cert_off = "\x50\xF8\xFF\xFF", /* -0x800 + CERT_OFFSET */
69 .cert_sz = "\xBA\x02\x00\x00", /* CERT_SIZE */
70 },
71 .info_sign = "\xC2\x54\x51\x31\xDC\xC0\x84\xA4"
72 "\x7F\xD1\x45\x08\xE8\xFF\xE8\x1D",
73};
74
75unsigned char s5l8702pwnage[/*CERT_SIZE*/] =
76{
77 "\x30\x82\x00\x7A\x30\x66\x02\x00\x30\x0D\x06\x09\x2A\x86\x48\x86"
78 "\xF7\x0D\x01\x01\x05\x05\x00\x30\x0B\x31\x09\x30\x07\x06\x03\x55"
79 "\x04\x03\x13\x00\x30\x1E\x17\x0D\x00\x00\x00\x00\x00\x00\x00\x00"
80 "\x00\x00\x00\x00\x00\x17\x0D\x00\x00\x00\x00\x00\x00\x00\x00\x00"
81 "\x00\x00\x00\x00\x30\x0B\x31\x09\x30\x07\x06\x03\x55\x04\x03\x13"
82 "\x00\x30\x19\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01"
83 "\x05\x00\x03\x08\x00\x30\x05\x02\x01\x00\x02\x00\x30\x0D\x06\x09"
84 "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05\x05\x00\x03\x01\x00\x30\x82"
85 "\x00\x7A\x30\x66\x02\x00\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D"
86 "\x01\x01\x05\x05\x00\x30\x0B\x31\x09\x30\x07\x06\x03\x55\x04\x03"
87 "\x13\x00\x30\x1E\x17\x0D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
88 "\x00\x00\x00\x17\x0D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
89 "\x00\x00\x30\x0B\x31\x09\x30\x07\x06\x03\x55\x04\x03\x13\x00\x30"
90 "\x19\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00"
91 "\x03\x08\x00\x30\x05\x02\x01\x00\x02\x00\x30\x0D\x06\x09\x2A\x86"
92 "\x48\x86\xF7\x0D\x01\x01\x05\x05\x00\x03\x01\x00\x30\x82\x01\xBA"
93 "\x30\x50\x02\x00\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01"
94 "\x05\x05\x00\x30\x00\x30\x1E\x17\x0D\x00\x00\x00\x00\x00\x00\x00"
95 "\x00\x00\x00\x00\x00\x00\x17\x0D\x00\x00\x00\x00\x00\x00\x00\x00"
96 "\x00\x00\x00\x00\x00\x30\x00\x30\x19\x30\x0D\x06\x09\x2A\x86\x48"
97 "\x86\xF7\x0D\x01\x01\x01\x05\x00\x03\x08\x00\x30\x05\x02\x01\x00"
98 "\x02\x00\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05\x05"
99 "\x00\x03\x82\x01\x55"
100};
101
102static uint32_t get_uint32le(unsigned char* p)
103{
104 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
105}
106
107static uint32_t get_uint32be(unsigned char* p)
108{
109 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
110}
111
112static void put_uint32le(unsigned char* p, uint32_t x)
113{
114 p[0] = x & 0xff;
115 p[1] = (x >> 8) & 0xff;
116 p[2] = (x >> 16) & 0xff;
117 p[3] = (x >> 24) & 0xff;
118}
119
120#define _ERR(format, ...) \
121 do { \
122 snprintf(errstr, errstrsize, "[ERR] "format, __VA_ARGS__); \
123 goto error; \
124 } while(0)
125
126static unsigned char *load_file(char *filename, int *bufsize,
127 const struct ipod_models** model,
128 char* errstr, int errstrsize)
129{
130 int fd, i;
131 struct stat s;
132 unsigned char header[8];
133 unsigned char *buf = NULL;
134 bool is_rbbl = (model);
135
136 fd = open(filename, O_RDONLY|O_BINARY);
137 if (fd < 0)
138 _ERR("Could not open %s for reading", filename);
139
140 if (fstat(fd, &s) < 0)
141 _ERR("Checking filesize of input file %s", filename);
142 *bufsize = s.st_size;
143
144 if (is_rbbl) {
145 /* Read Rockbox header */
146 if (read(fd, header, sizeof(header)) != sizeof(header))
147 _ERR("Could not read file %s", filename);
148 *bufsize -= sizeof(header);
149
150 for (i = 0; i < NUM_MODELS; i++)
151 if (memcmp(ipod_identity[i].rb_model_name, header + 4, 4) == 0)
152 break;
153
154 if (i == NUM_MODELS)
155 _ERR("Model name \"%4.4s\" unknown. "
156 "Is this really a rockbox bootloader?", header + 4);
157
158 *model = &ipod_identity[i];
159 }
160
161 buf = malloc(*bufsize);
162 if (buf == NULL)
163 _ERR("Could not allocate memory for %s", filename);
164
165 if (read(fd, buf, *bufsize) != *bufsize)
166 _ERR("Could not read file %s", filename);
167
168 if (is_rbbl) {
169 /* Check checksum */
170 uint32_t sum = (*model)->rb_model_num;
171 for (i = 0; i < *bufsize; i++) {
172 /* add 8 unsigned bits but keep a 32 bit sum */
173 sum += buf[i];
174 }
175 if (sum != get_uint32be(header))
176 _ERR("Checksum mismatch in %s", filename);
177 }
178
179 close(fd);
180 return buf;
181
182error:
183 if (fd >= 0)
184 close(fd);
185 if (buf)
186 free(buf);
187 return NULL;
188}
189
190unsigned char *mkdfu(int dfu_type, char *dfu_arg, int* dfu_size,
191 char* errstr, int errstrsize)
192{
193 const struct ipod_models *model = NULL;
194 unsigned char *dfu_buf = NULL;
195 unsigned char *f_buf;
196 int f_size;
197 uint32_t padded_bl_size;
198 uint32_t cert_off, cert_sz;
199 off_t cur_off;
200 char *dfu_desc;
201 int i;
202
203 switch (dfu_type)
204 {
205 case DFU_INST:
206 case DFU_INST_SINGLE:
207 f_buf = load_file(dfu_arg, &f_size, &model, errstr, errstrsize);
208 if (f_buf == NULL)
209 goto error;
210 /* IM3 data size should be padded to 16 */
211 padded_bl_size = ((f_size + 0xf) & ~0xf);
212 *dfu_size = BIN_OFFSET + (model->dualboot_install_size +
213 (IM3HDR_SZ - (int)IM3INFO_SZ) + (int)padded_bl_size);
214 dfu_desc = (dfu_type == DFU_INST_SINGLE) ? "BL installer (single)"
215 : "BL installer";
216 break;
217
218 case DFU_UNINST:
219 for (i = 0; i < NUM_MODELS; i++) {
220 if (!strcmp(ipod_identity[i].platform_name, dfu_arg)) {
221 model = &ipod_identity[i];
222 break;
223 }
224 }
225 if (!model)
226 _ERR("Platform name \"%s\" unknown", dfu_arg);
227
228 *dfu_size = BIN_OFFSET + model->dualboot_uninstall_size;
229 dfu_desc = "BL uninstaller";
230 break;
231
232 case DFU_RAW:
233 default:
234 f_buf = load_file(dfu_arg, &f_size, NULL, errstr, errstrsize);
235 if (f_buf == NULL)
236 goto error;
237 /* IM3 data size should be padded to 16 */
238 *dfu_size = BIN_OFFSET + ((f_size + 0xf) & ~0xf);
239 dfu_desc = "raw binary";
240 break;
241 }
242
243 printf("[INFO] Building DFU:\n");
244 printf("[INFO] type: %s\n", dfu_desc);
245 if ((dfu_type == DFU_INST) || (dfu_type == DFU_INST_SINGLE))
246 printf("[INFO] BL size: %d\n", f_size);
247 if (dfu_type == DFU_RAW)
248 printf("[INFO] BIN size: %d\n", f_size);
249 printf("[INFO] DFU size: %d\n", *dfu_size);
250 if (model) {
251 printf("[INFO] model name: %s\n", model->model_name);
252 printf("[INFO] platform: %s\n", model->platform_name);
253 printf("[INFO] RB name: %s\n", model->rb_model_name);
254 printf("[INFO] RB num: %d\n", model->rb_model_num);
255 }
256
257 if (*dfu_size > DFU_MAXSIZE)
258 _ERR("DFU image (%d bytes) too big", *dfu_size);
259
260 dfu_buf = calloc(*dfu_size, 1);
261 if (!dfu_buf)
262 _ERR("Could not allocate %d bytes for DFU image", *dfu_size);
263
264 cert_off = get_uint32le(s5l8702hdr.u.enc34.cert_off);
265 cert_sz = get_uint32le(s5l8702hdr.u.enc34.cert_sz);
266
267 memcpy(dfu_buf, &s5l8702hdr, sizeof(s5l8702hdr));
268
269 cur_off = IM3HDR_SZ + cert_off;
270
271 memcpy(dfu_buf + cur_off, s5l8702pwnage, sizeof(s5l8702pwnage));
272
273 /* set entry point */
274 cur_off += cert_sz - 4;
275 put_uint32le(dfu_buf + cur_off, DFU_LOADADDR + BIN_OFFSET);
276
277 cur_off = BIN_OFFSET;
278
279 switch (dfu_type)
280 {
281 case DFU_INST:
282 case DFU_INST_SINGLE:
283 /* copy the dualboot installer binary */
284 memcpy(dfu_buf + cur_off, model->dualboot_install,
285 model->dualboot_install_size);
286 /* point to the start of the included IM3 header info */
287 cur_off += model->dualboot_install_size - IM3INFO_SZ;
288 /* set bootloader data size */
289 struct Im3Info *bl_info = (struct Im3Info*)(dfu_buf + cur_off);
290 put_uint32le(bl_info->data_sz, padded_bl_size);
291 /* use info_sign to pass params to the dualboot installer */
292 if (dfu_type == DFU_INST_SINGLE)
293 bl_info->info_sign[0] = 0x1;
294 /* add bootloader binary */
295 cur_off += IM3HDR_SZ;
296 memcpy(dfu_buf + cur_off, f_buf, f_size);
297 break;
298
299 case DFU_UNINST:
300 /* copy the dualboot uninstaller binary */
301 memcpy(dfu_buf + cur_off, model->dualboot_uninstall,
302 model->dualboot_uninstall_size);
303 break;
304
305 case DFU_RAW:
306 default:
307 /* add raw binary */
308 memcpy(dfu_buf + cur_off, f_buf, f_size);
309 break;
310 }
311
312 return dfu_buf;
313
314error:
315 if (dfu_buf)
316 free(dfu_buf);
317 return NULL;
318}
diff --git a/utils/mks5lboot/mks5lboot.h b/utils/mks5lboot/mks5lboot.h
new file mode 100644
index 0000000000..084bec61f9
--- /dev/null
+++ b/utils/mks5lboot/mks5lboot.h
@@ -0,0 +1,129 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2015 by Cástor Muñoz
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#ifndef __MK6GBOOT_H__
22#define __MK6GBOOT_H__
23
24/* useful for dualboot.lds */
25#define DFU_LOADADDR 0x22000000
26#define DFU_MAXSIZE 0x20000 /* maximum .dfu file size */
27
28#define CERT_OFFSET 0x50 /* IM3INFO_SZ */
29#define CERT_SIZE 698
30#define BIN_OFFSET (CERT_OFFSET + ((CERT_SIZE + 0x3) & ~ 0x3))
31#define MAX_PAYLOAD (DFU_MAXSIZE - BIN_OFFSET)
32
33#ifndef ASM
34#include <stddef.h>
35#include <stdint.h>
36
37#ifdef __cplusplus
38extern "C" {
39#endif
40
41#define IM3_IDENT "8702"
42#define IM3_VERSION "1.0"
43#define IM3HDR_SZ 0x800
44#define IM3INFO_SZ (sizeof(struct Im3Info))
45#define IM3INFOSIGN_SZ (offsetof(struct Im3Info, info_sign))
46
47#define SIGN_SZ 16
48
49struct Im3Info
50{
51 uint8_t ident[4];
52 uint8_t version[3];
53 uint8_t enc_type;
54 uint8_t entry[4]; /* LE */
55 uint8_t data_sz[4]; /* LE */
56 union {
57 struct {
58 uint8_t data_sign[SIGN_SZ];
59 uint8_t _reserved[32];
60 } enc12;
61 struct {
62 uint8_t sign_off[4]; /* LE */
63 uint8_t cert_off[4]; /* LE */
64 uint8_t cert_sz[4]; /* LE */
65 uint8_t _reserved[36];
66 } enc34;
67 } u;
68 uint8_t info_sign[SIGN_SZ];
69} __attribute__ ((packed));
70
71struct Im3Hdr
72{
73 struct Im3Info info;
74 uint8_t _zero[IM3HDR_SZ - sizeof(struct Im3Info)];
75} __attribute__ ((packed));
76
77
78/* Supported models */
79enum {
80 MODEL_UNKNOWN = -1,
81 MODEL_IPOD6G = 0,
82 /* new models go here */
83
84 NUM_MODELS
85};
86
87struct ipod_models {
88 /* Descriptive name of this model */
89 const char* model_name;
90 /* for bootloader uninstallers */
91 const char* platform_name;
92 /* Model name used in the Rockbox header in ".ipod" files - these match the
93 -add parameter to the "scramble" tool */
94 const char* rb_model_name;
95 /* Model number used to initialise the checksum in the Rockbox header in
96 ".ipod" files - these are the same as MODEL_NUMBER in config-target.h */
97 const int rb_model_num;
98 /* Dualboot functions for this model */
99 const unsigned char* dualboot_install;
100 int dualboot_install_size;
101 const unsigned char* dualboot_uninstall;
102 int dualboot_uninstall_size;
103};
104extern const struct ipod_models ipod_identity[];
105
106
107enum {
108 DFU_NONE = -1,
109 DFU_INST, /* RB installer */
110 DFU_INST_SINGLE, /* RB installer (single) */
111 DFU_UNINST, /* RB uninstaller */
112 DFU_RAW /* raw binary */
113};
114
115unsigned char *mkdfu(int dfu_type, char *dfu_arg, int* dfu_size,
116 char* errstr, int errstrsize);
117
118int ipoddfu_send(int pid, unsigned char *buf, int size,
119 char* errstr, int errstrsize);
120int ipoddfu_scan(int pid, int *state, int reset,
121 char* errstr, int errstrsize);
122void ipoddfu_debug(int debug);
123
124#ifdef __cplusplus
125};
126#endif
127#endif /* ASM */
128
129#endif /* __MK6GBOOT_H__ */