summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rbutil/mks5lboot/.gitignore2
-rw-r--r--rbutil/mks5lboot/Makefile35
-rw-r--r--rbutil/mks5lboot/README209
-rw-r--r--rbutil/mks5lboot/dualboot.c664
-rw-r--r--rbutil/mks5lboot/dualboot.h4
-rw-r--r--rbutil/mks5lboot/dualboot/.gitignore3
-rw-r--r--rbutil/mks5lboot/dualboot/Makefile97
-rw-r--r--rbutil/mks5lboot/dualboot/autoconf.h74
-rw-r--r--rbutil/mks5lboot/dualboot/bin2c.c140
-rw-r--r--rbutil/mks5lboot/dualboot/dualboot.c287
-rw-r--r--rbutil/mks5lboot/dualboot/dualboot.lds59
-rw-r--r--rbutil/mks5lboot/dualboot/init.S43
-rw-r--r--rbutil/mks5lboot/ipoddfu.c875
-rw-r--r--rbutil/mks5lboot/main.c287
-rw-r--r--rbutil/mks5lboot/mkdfu.c318
-rw-r--r--rbutil/mks5lboot/mks5lboot.h129
16 files changed, 3226 insertions, 0 deletions
diff --git a/rbutil/mks5lboot/.gitignore b/rbutil/mks5lboot/.gitignore
new file mode 100644
index 0000000000..9078451a7a
--- /dev/null
+++ b/rbutil/mks5lboot/.gitignore
@@ -0,0 +1,2 @@
1buildposix/
2mks5lboot
diff --git a/rbutil/mks5lboot/Makefile b/rbutil/mks5lboot/Makefile
new file mode 100644
index 0000000000..ba118eefd0
--- /dev/null
+++ b/rbutil/mks5lboot/Makefile
@@ -0,0 +1,35 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7CFLAGS += -Wall -Wextra
8
9OUTPUT = mks5lboot
10
11# inputs for lib
12LIBSOURCES := dualboot.c mkdfu.c ipoddfu.c
13# inputs for binary only
14SOURCES := $(LIBSOURCES) main.c
15# dependencies for binary
16EXTRADEPS :=
17
18ifeq ($(findstring MINGW,$(shell uname)),MINGW)
19LDOPTS += -lsetupapi
20# optional libusb support on Windows
21ifdef DISABLE_LIBUSBAPI
22CFLAGS += -DNO_LIBUSBAPI
23else
24LDOPTS += -Wl,-Bstatic -lusb-1.0
25endif
26else
27# Linux, OS X
28LDOPTS += -lusb-1.0
29endif
30
31include ../libtools.make
32
33# explicit dependencies on dualboot.{c,h} and mks5lboot.h
34$(OBJDIR)mks5lboot.o: dualboot.h dualboot.c mks5lboot.h
35$(OBJDIR)main.o: dualboot.h dualboot.c main.c mks5lboot.h
diff --git a/rbutil/mks5lboot/README b/rbutil/mks5lboot/README
new file mode 100644
index 0000000000..c2df299867
--- /dev/null
+++ b/rbutil/mks5lboot/README
@@ -0,0 +1,209 @@
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 (TODO)
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 . Then 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).
108
109Command line install:
110
111 - If you are using iTunes on Windows, close iTunes and kill (or pause)
112 iTunesHelper.exe before entering DFU mode.
113
114 - Put you device on DFU mode by pressing and holding SELECT+MENU buttons
115 for about 12 seconds.
116
117 You can notice when the device enters DFU mode running the next command
118 to scan the USB bus every second (press Ctrl-C to abort the scan):
119 mks5lboot --dfuscan --loop
120
121 - To install or update a bootloader, build the DFU installer and send it
122 to the device:
123 mks5lboot --bl-inst /path/to/bootloader-ipod6g.ipod
124
125 When the DFU imagen is loaded and executed, the device emits an 'alive'
126 tone (2000Hz/100ms). When the bootloader is successfully installed then
127 a dual tone beep sounds (1000Hz/100ms+2000Hz/150ms) and the device
128 reboots. If something went bad then 330Hz/500ms tone is emited and the
129 device reboots. When three 330Hz tones sounds, it means that the NOR
130 got corrupted and the device must be restored using iTunes (should not
131 happen).
132
133 - To remove a previously installed bootloader, build the DFU uninstaler
134 and send it to the device:
135 mks5lboot --bl-uninst ipod6g
136
137 If USB access is denied, try to run the mks5lboot tool using a privileged
138 user (i.e. Administrator or root).
139
140
141Dual-Boot
142---------
143
144The purpose of this program is to provide dual-boot between the original
145firmware and the new (rockbox) firmware.
146
147The button press check is done ~800 ms. after power-up or reboot, then:
148
149 SELECT + MENU: resets the device after ~5 seconds, then if SELECT+MENU
150 remains pressed the device enters DFU mode after an
151 additional period of ~8 seconds.
152 SELECT + LEFT: enter OF diagnostics (after ~7 seconds).
153 SELECT + PLAY: enter OF diskmode (after ~7 seconds).
154 SELECT + RIGHT: enter bootloader USB mode.
155 MENU: enter OF
156 Hold Switch locked: enter OF (see below for details).
157 Any other combination: launch Rockbox.
158
159Switch current firmware:
160
161 Tries to behave like ipod Video, see http://download.rockbox.org/manual/
162 rockbox-ipodvideo/rockbox-buildch3.html#x5-290003.1.3
163
164 Apple is the current FW:
165 - Stop playback and wait a few seconds for hard disk spin-down.
166 - Press and hold SELECT+MENU, after ~5 seconds the player hard resets,
167 release the buttons when the screen goes black.
168
169 Rockbox is the current FW:
170 - Shut down the device using "Long Play" key press.
171 - Once the device is powered off, there are three ways to enter OF:
172 1) Press and hold MENU button for at least ~800 ms.
173 2) Turn on the Hold switch immediately after turning the player on,
174 it must be done before "Loading Rockbox..." message appears (~3
175 seconds from power-on). Be careful, if the hold switch is locked
176 when Rockbox starts then your RB settings will be cleared!
177 3) You can also load the original firmware by shutting down the
178 device, then clicking the Hold switch on and connecting the iPod
179 to your computer.
180
181
182Single-Boot
183-----------
184
185Use --single option if the Apple firmware is not installed on your iPod
186and/or you want to force the installation of the bootloader to use Rockbox
187as unique firmware. The single-boot installer writes the bootloader on the
188NOR with no previous check, the original Apple NOR boot is destroyed if it
189exists.
190
191To build the DFU single-boot installer and send it to the device:
192 mks5lboot --bl-inst --single /path/to/bootloader-ipod6g.ipod
193
194
195Compilation
196-----------
197
198Needs libusb > 1.0 installed, tested on:
199
200Linux: gcc-4.9.2 + libusb-1.0.19
201Windows XP: mingw32-gcc-4.8.1 + libusbx-1.0.15
202OS X 10.11: clang-7.3.0 + libusb-1.0.20
203
204
205Hacking
206-------
207
208See comments in mkdfu.c, ipoddfu.c, dualboot.c and bootloader/ipod6g.c for
209more information.
diff --git a/rbutil/mks5lboot/dualboot.c b/rbutil/mks5lboot/dualboot.c
new file mode 100644
index 0000000000..4c1608fc41
--- /dev/null
+++ b/rbutil/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/rbutil/mks5lboot/dualboot.h b/rbutil/mks5lboot/dualboot.h
new file mode 100644
index 0000000000..c8952a4c07
--- /dev/null
+++ b/rbutil/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/rbutil/mks5lboot/dualboot/.gitignore b/rbutil/mks5lboot/dualboot/.gitignore
new file mode 100644
index 0000000000..34c53b3c82
--- /dev/null
+++ b/rbutil/mks5lboot/dualboot/.gitignore
@@ -0,0 +1,3 @@
1build/
2*.arm-bin
3bin2c
diff --git a/rbutil/mks5lboot/dualboot/Makefile b/rbutil/mks5lboot/dualboot/Makefile
new file mode 100644
index 0000000000..51ce816ca0
--- /dev/null
+++ b/rbutil/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/rbutil/mks5lboot/dualboot/autoconf.h b/rbutil/mks5lboot/dualboot/autoconf.h
new file mode 100644
index 0000000000..cd5b3f9aeb
--- /dev/null
+++ b/rbutil/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/rbutil/mks5lboot/dualboot/bin2c.c b/rbutil/mks5lboot/dualboot/bin2c.c
new file mode 100644
index 0000000000..4d74a19696
--- /dev/null
+++ b/rbutil/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/rbutil/mks5lboot/dualboot/dualboot.c b/rbutil/mks5lboot/dualboot/dualboot.c
new file mode 100644
index 0000000000..b8167ec124
--- /dev/null
+++ b/rbutil/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/rbutil/mks5lboot/dualboot/dualboot.lds b/rbutil/mks5lboot/dualboot/dualboot.lds
new file mode 100644
index 0000000000..cb92e2a286
--- /dev/null
+++ b/rbutil/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/rbutil/mks5lboot/dualboot/init.S b/rbutil/mks5lboot/dualboot/init.S
new file mode 100644
index 0000000000..bd049515f4
--- /dev/null
+++ b/rbutil/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/rbutil/mks5lboot/ipoddfu.c b/rbutil/mks5lboot/ipoddfu.c
new file mode 100644
index 0000000000..6d303d6603
--- /dev/null
+++ b/rbutil/mks5lboot/ipoddfu.c
@@ -0,0 +1,875 @@
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#ifndef NO_LIBUSBAPI
26#define USE_LIBUSBAPI
27#endif
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <unistd.h>
32#include <string.h>
33#include <time.h>
34#ifdef WIN32
35#include <windows.h>
36#include <setupapi.h>
37#include <stdbool.h>
38#endif
39
40#ifdef USE_LIBUSBAPI
41#include <libusb-1.0/libusb.h>
42#endif
43
44#include "mks5lboot.h"
45
46
47static void sleep_ms(unsigned int ms)
48{
49 struct timespec req;
50 req.tv_sec = ms / 1000;
51 req.tv_nsec = (ms % 1000) * 1000000;
52 nanosleep(&req, NULL);
53}
54
55/*
56 * CRC32 functions
57 * Based on public domain implementation by Finn Yannick Jacobs.
58 */
59
60/* Written and copyright 1999 by Finn Yannick Jacobs
61 * No rights were reserved to this, so feel free to
62 * manipulate or do with it, what you want or desire :)
63 */
64
65#define CRC32_DEFAULT_SEED 0xffffffff
66
67/* crc32table[] built by crc32_init() */
68static unsigned long crc32table[256];
69
70/* Calculate crc32. Little endian.
71 * Standard seed is 0xffffffff or 0.
72 * Some implementations xor result with 0xffffffff after calculation.
73 */
74static uint32_t crc32(void *data, unsigned int len, uint32_t seed)
75{
76 uint8_t *d = data;
77
78 while (len--)
79 {
80 seed = ((seed >> 8) & 0x00FFFFFF) ^ crc32table [(seed ^ *d++) & 0xFF];
81 }
82
83 return seed;
84}
85
86/* Calculate crc32table */
87static void crc32_init()
88{
89 uint32_t poly = 0xEDB88320L;
90 uint32_t crc;
91 int i, j;
92
93 for (i = 0; i < 256; ++i)
94 {
95 crc = i;
96
97 for (j = 8; j > 0; --j)
98 {
99 crc = (crc >> 1) ^ ((crc & 1) ? poly : 0);
100 }
101
102 crc32table[i] = crc;
103 }
104}
105
106
107/*
108 * DFU
109 */
110
111/* must be pow2 <= wTransferSize (2048) */
112#define DFU_PKT_SZ 2048
113
114#define APPLE_VID 0x05AC
115
116static int KNOWN_PIDS[] =
117{
118 /* DFU */
119 0x1220, /* Nano 2G */
120 0x1223, /* Nano 3G and Classic 1G/2G/3G/4G */
121 0x1224, /* Shuffle 3G */
122 0x1225, /* Nano 4G */
123 0x1231, /* Nano 5G */
124 0x1232, /* Nano 6G */
125 0x1233, /* Shuffle 4G */
126 0x1234, /* Nano 7G */
127 /* WTF */
128 0x1240, /* Nano 2G */
129 0x1241, /* Classic 1G */
130 0x1242, /* Nano 3G */
131 0x1243, /* Nano 4G */
132 0x1245, /* Classic 2G */
133 0x1246, /* Nano 5G */
134 0x1247, /* Classic 3G */
135 0x1248, /* Nano 6G */
136 0x1249, /* Nano 7G */
137 0x124a, /* Nano 7G */
138 0x1250, /* Classic 4G */
139 0
140};
141
142struct usbControlSetup {
143 uint8_t bmRequestType;
144 uint8_t bRequest;
145 uint16_t wValue;
146 uint16_t wIndex;
147 uint16_t wLength;
148} __attribute__ ((packed));
149#define USB_CS_SZ (sizeof(struct usbControlSetup))
150
151struct usbStatusData {
152 uint8_t bStatus;
153 uint8_t bwPollTimeout0;
154 uint8_t bwPollTimeout1;
155 uint8_t bwPollTimeout2;
156 uint8_t bState;
157 uint8_t iString;
158} __attribute__ ((packed));
159
160/* DFU 1.1 specs */
161typedef enum DFUState {
162 appIDLE = 0,
163 appDETACH = 1,
164 dfuIDLE = 2,
165 dfuDNLOAD_SYNC = 3,
166 dfuDNBUSY = 4,
167 dfuDNLOAD_IDLE = 5,
168 dfuMANIFEST_SYNC = 6,
169 dfuMANIFEST = 7,
170 dfuMANIFEST_WAIT_RESET = 8,
171 dfuUPLOAD_IDLE = 9,
172 dfuERROR = 10
173} DFUState;
174
175typedef enum DFUStatus {
176 errNONE = 0,
177 errTARGET = 1,
178 errFILE = 2,
179 errWRITE = 3,
180 errERASE = 4,
181 errCHECK_ERASED = 5,
182 errPROG = 6,
183 errVERIFY = 7,
184 errADDRESS = 8,
185 errNOTDONE = 9,
186 errFIRMWARE = 10,
187 errVENDOR = 11,
188 errUSBR = 12,
189 errPOR = 13,
190 errUNKNOWN = 14,
191 errSTALLEDPKT = 15
192} DFUStatus;
193
194typedef enum DFURequest {
195 DFU_DETACH = 0,
196 DFU_DNLOAD = 1,
197 DFU_UPLOAD = 2,
198 DFU_GETSTATUS = 3,
199 DFU_CLRSTATUS = 4,
200 DFU_GETSTATE = 5,
201 DFU_ABORT = 6
202} DFURequest;
203
204struct dfuDev {
205 struct dfuAPI *api;
206 int found_pid;
207 int detached;
208 char descr[256];
209 int res; /* API result: 1->ok, 0->failure */
210 char err[256];
211 /* API private */
212#ifdef WIN32
213 HANDLE fh;
214 HANDLE ph;
215 DWORD ec; /* winapi error code */
216#endif
217#ifdef USE_LIBUSBAPI
218 libusb_context* ctx;
219 libusb_device_handle* devh;
220 int rc; /* libusb return code */
221#endif
222};
223
224struct dfuAPI {
225 char *name;
226 int (*open_fn)(struct dfuDev*, int*);
227 int (*dfureq_fn)(struct dfuDev*, struct usbControlSetup*, void*);
228 int (*reset_fn)(struct dfuDev*);
229 void (*close_fn)(struct dfuDev*);
230};
231
232
233/*
234 * low-level (API specific) functions
235 */
236static int dfu_check_id(int vid, int pid, int *pid_list)
237{
238 int *p;
239 if (vid != APPLE_VID)
240 return 0;
241 for (p = pid_list; *p; p++)
242 if (*p == pid)
243 return 1;
244 return 0;
245}
246
247/* adds extra DFU request error info */
248static void dfu_add_reqerrstr(struct dfuDev *dfuh, struct usbControlSetup *cs)
249{
250 snprintf(dfuh->err + strlen(dfuh->err),
251 sizeof(dfuh->err) - strlen(dfuh->err), " (cs=%02x/%d/%d/%d/%d)",
252 cs->bmRequestType, cs->bRequest, cs->wValue, cs->wIndex, cs->wLength);
253}
254
255#ifdef WIN32
256static int dfu_winapi_chkrc(struct dfuDev *dfuh, char *str, bool success)
257{
258 dfuh->res = (int)success;
259 if (!success) {
260 dfuh->ec = GetLastError();
261 snprintf(dfuh->err, sizeof(dfuh->err), "%s error %ld", str, dfuh->ec);
262 }
263 return dfuh->res;
264}
265
266static int dfu_winapi_request(struct dfuDev *dfuh,
267 struct usbControlSetup* cs, void* data)
268{
269 unsigned char buf[USB_CS_SZ + DFU_PKT_SZ];
270 DWORD rdwr;
271 bool rc;
272
273 memcpy(buf, cs, USB_CS_SZ);
274
275 if (cs->bmRequestType & 0x80)
276 {
277 rc = ReadFile(dfuh->ph, buf, USB_CS_SZ + cs->wLength, &rdwr, NULL);
278 memcpy(data, buf+USB_CS_SZ, cs->wLength);
279 dfu_winapi_chkrc(dfuh, "DFU request failed: ReadFile()", rc);
280 }
281 else
282 {
283 memcpy(buf+USB_CS_SZ, data, cs->wLength);
284 rc = WriteFile(dfuh->ph, buf, USB_CS_SZ + cs->wLength, &rdwr, NULL);
285 dfu_winapi_chkrc(dfuh, "DFU request failed: WriteFile()", rc);
286 }
287
288 if (!dfuh->res)
289 dfu_add_reqerrstr(dfuh, cs);
290 return dfuh->res;
291}
292
293static int dfu_winapi_reset(struct dfuDev *dfuh)
294{
295 DWORD bytesReturned;
296 bool rc = DeviceIoControl(dfuh->fh, 0x22000c,
297 NULL, 0, NULL, 0, &bytesReturned, NULL);
298 return dfu_winapi_chkrc(dfuh,
299 "Could not reset USB device: DeviceIoControl()", rc);
300}
301
302static void dfu_winapi_close(struct dfuDev *dfuh)
303{
304 if (dfuh->fh != INVALID_HANDLE_VALUE) {
305 CloseHandle(dfuh->fh);
306 dfuh->fh = INVALID_HANDLE_VALUE;
307 }
308 if (dfuh->ph != INVALID_HANDLE_VALUE) {
309 CloseHandle(dfuh->ph);
310 dfuh->ph = INVALID_HANDLE_VALUE;
311 }
312}
313
314static const GUID GUID_AAPLDFU =
315 { 0xB8085869L, 0xFEB9, 0x404B, {0x8C, 0xB1, 0x1E, 0x5C, 0x14, 0xFA, 0x8C, 0x54}};
316
317static int dfu_winapi_open(struct dfuDev *dfuh, int *pid_list)
318{
319 const GUID *guid = &GUID_AAPLDFU;
320 HDEVINFO devinfo = NULL;
321 SP_DEVICE_INTERFACE_DETAIL_DATA_A* details = NULL;
322 SP_DEVICE_INTERFACE_DATA iface;
323 char *path = NULL;
324 DWORD i, size;
325 bool rc;
326
327 dfuh->fh =
328 dfuh->ph = INVALID_HANDLE_VALUE;
329 dfuh->found_pid = 0;
330 dfuh->res = 1; /* ok */
331 dfuh->ec = 0;
332
333 /* Get DFU path */
334 devinfo = SetupDiGetClassDevsA(guid, NULL, NULL,
335 DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
336 if (!dfu_winapi_chkrc(dfuh, "SetupDiGetClassDevsA()",
337 (devinfo != INVALID_HANDLE_VALUE)))
338 goto error;
339
340 iface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
341
342 for (i = 0; SetupDiEnumDeviceInterfaces(devinfo, NULL, guid, i, &iface); i++)
343 {
344 int vid, pid;
345
346 SetupDiGetDeviceInterfaceDetailA(devinfo, &iface, NULL, 0, &size, NULL);
347
348 if (details) free(details);
349 details = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc(size);
350 details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
351 rc = SetupDiGetDeviceInterfaceDetailA(devinfo, &iface, details, size, NULL, NULL);
352 if (!dfu_winapi_chkrc(dfuh, "SetupDiGetDeviceInterfaceDetailA()", rc))
353 goto error;
354
355 CharUpperA(details->DevicePath);
356 if (sscanf(details->DevicePath, "%*4cUSB#VID_%04x&PID_%04x%*s", &vid, &pid) != 2)
357 continue;
358 if (!dfu_check_id(vid, pid, pid_list))
359 continue;
360
361 if (path) free(path);
362 path = malloc(size - sizeof(DWORD) + 16);
363 memcpy(path, details->DevicePath, size - sizeof(DWORD));
364
365 dfuh->fh = CreateFileA(path, GENERIC_READ|GENERIC_WRITE,
366 FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
367 if (!dfu_winapi_chkrc(dfuh, "CreateFileA(fh)", (dfuh->fh != INVALID_HANDLE_VALUE)))
368 goto error;
369
370 strcat(path, "\\PIPE0");
371 dfuh->ph = CreateFileA(path, GENERIC_READ|GENERIC_WRITE,
372 FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
373 if (!dfu_winapi_chkrc(dfuh, "CreateFileA(ph)", (dfuh->ph != INVALID_HANDLE_VALUE)))
374 goto error;
375
376 /* ok */
377 snprintf(dfuh->descr, sizeof(dfuh->descr), "%s", details->DevicePath);
378 dfuh->found_pid = pid;
379 goto bye;
380 }
381
382 if (!dfu_winapi_chkrc(dfuh, "SetupDiEnumDeviceInterfaces()",
383 (GetLastError() == ERROR_NO_MORE_ITEMS)))
384 goto error;
385
386 /* no devices found */
387
388bye:
389 if (path) free(path);
390 if (details) free(details);
391 if (devinfo) SetupDiDestroyDeviceInfoList(devinfo);
392 return dfuh->res;
393
394error:
395 dfu_winapi_close(dfuh);
396 goto bye;
397}
398#endif /* WIN32 */
399
400#ifdef USE_LIBUSBAPI
401static int dfu_libusb_chkrc(struct dfuDev *dfuh, char *str)
402{
403 dfuh->res = (dfuh->rc < LIBUSB_SUCCESS) ? 0 : 1;
404 if (dfuh->res == 0)
405 snprintf(dfuh->err, sizeof(dfuh->err),
406 "%s: %s", str, libusb_error_name(dfuh->rc));
407 return dfuh->res;
408}
409
410static int dfu_libusb_request(struct dfuDev *dfuh,
411 struct usbControlSetup *cs, void *data)
412{
413 dfuh->rc = libusb_control_transfer(dfuh->devh, cs->bmRequestType,
414 cs->bRequest, cs->wValue, cs->wIndex, data, cs->wLength, 500);
415 if (!dfu_libusb_chkrc(dfuh, "DFU request failed"))
416 dfu_add_reqerrstr(dfuh, cs);
417 return dfuh->res;
418}
419
420static int dfu_libusb_reset(struct dfuDev *dfuh)
421{
422 dfuh->rc = libusb_reset_device(dfuh->devh);
423 return dfu_libusb_chkrc(dfuh, "Could not reset USB device");
424}
425
426static void dfu_libusb_close(struct dfuDev *dfuh)
427{
428 if (dfuh->devh) {
429 libusb_release_interface(dfuh->devh, 0);
430 if (dfuh->detached)
431 libusb_attach_kernel_driver(dfuh->devh, 0);
432 libusb_close(dfuh->devh);
433 dfuh->devh = NULL;
434 }
435 if (dfuh->ctx) {
436 libusb_exit(dfuh->ctx);
437 dfuh->ctx = NULL;
438 }
439}
440
441static int dfu_libusb_open(struct dfuDev *dfuh, int *pid_list)
442{
443 struct libusb_device_descriptor desc;
444 libusb_device **devs = NULL, *dev;
445 int n_devs, i;
446
447 dfuh->devh = NULL;
448 dfuh->found_pid = 0;
449 dfuh->detached = 0;
450 dfuh->res = 1; /* ok */
451
452 dfuh->rc = libusb_init(&(dfuh->ctx));
453 if (!dfu_libusb_chkrc(dfuh, "Could not init USB library")) {
454 dfuh->ctx = NULL; /* invalidate ctx (if any) */
455 goto error;
456 }
457
458 n_devs =
459 dfuh->rc = libusb_get_device_list(dfuh->ctx, &devs);
460 if (!dfu_libusb_chkrc(dfuh, "Could not get USB device list"))
461 goto error;
462
463 for (i = 0; i < n_devs; ++i)
464 {
465 dev = devs[i];
466
467 /* Note: since libusb-1.0.16 (LIBUSB_API_VERSION >= 0x01000102)
468 this function always succeeds. */
469 if (libusb_get_device_descriptor(dev, &desc) != LIBUSB_SUCCESS)
470 continue; /* Unable to get device descriptor */
471
472 if (!dfu_check_id(desc.idVendor, desc.idProduct, pid_list))
473 continue;
474
475 dfuh->rc = libusb_open(dev, &(dfuh->devh));
476 if (!dfu_libusb_chkrc(dfuh, "Could not open USB device"))
477 goto error;
478
479 dfuh->rc = libusb_set_configuration(dfuh->devh, 1);
480 if (!dfu_libusb_chkrc(dfuh, "Could not set USB configuration"))
481 goto error;
482
483 dfuh->rc = libusb_kernel_driver_active(dfuh->devh, 0);
484 if (dfuh->rc != LIBUSB_ERROR_NOT_SUPPORTED) {
485 if (!dfu_libusb_chkrc(dfuh, "Could not get USB driver status"))
486 goto error;
487 if (dfuh->rc == 1) {
488 dfuh->rc = libusb_detach_kernel_driver(dfuh->devh, 0);
489 if (!dfu_libusb_chkrc(dfuh, "Could not detach USB driver"))
490 goto error;
491 dfuh->detached = 1;
492 }
493 }
494
495 dfuh->rc = libusb_claim_interface(dfuh->devh, 0);
496 if (!dfu_libusb_chkrc(dfuh, "Could not claim USB interface"))
497 goto error;
498
499 /* ok */
500 snprintf(dfuh->descr, sizeof(dfuh->descr),
501 "[%04x:%04x] at bus %d, device %d, USB ver. %04x",
502 desc.idVendor, desc.idProduct, libusb_get_bus_number(dev),
503 libusb_get_device_address(dev), desc.bcdUSB);
504 dfuh->found_pid = desc.idProduct;
505 break;
506 }
507
508bye:
509 if (devs)
510 libusb_free_device_list(devs, 1);
511 if (!dfuh->found_pid)
512 dfu_libusb_close(dfuh);
513 return dfuh->res;
514
515error:
516 goto bye;
517}
518#endif /* USE_LIBUSBAPI */
519
520/* list of suported APIs:
521 * Windows: winapi and libusb (optional)
522 * Linux and OSX: libusb
523 */
524static struct dfuAPI api_list[] =
525{
526#ifdef WIN32
527 { "winapi",
528 dfu_winapi_open,
529 dfu_winapi_request,
530 dfu_winapi_reset,
531 dfu_winapi_close },
532#endif
533#ifdef USE_LIBUSBAPI
534 { "libusb",
535 dfu_libusb_open,
536 dfu_libusb_request,
537 dfu_libusb_reset,
538 dfu_libusb_close },
539#endif
540#ifdef __APPLE__
541 /* TODO: implement API for OS X < 10.6 ??? */
542#endif
543};
544#define DFU_N_APIS (sizeof(api_list)/sizeof(struct dfuAPI))
545
546/*
547 * mid-layer (common) functions
548 */
549static void dfu_set_errstr(struct dfuDev *dfuh, char *str)
550{
551 strncpy(dfuh->err, str, sizeof(dfuh->err));
552}
553
554static int DEBUG_DFUREQ = 0;
555
556static int dfu_request(struct dfuDev *dfuh,
557 struct usbControlSetup *cs, void *data)
558{
559 if (!DEBUG_DFUREQ)
560 return dfuh->api->dfureq_fn(dfuh, cs, data);
561
562 /* DEBUG */
563
564 /* previous state */
565 unsigned char ste = 0;
566 struct usbControlSetup css = { 0xA1, DFU_GETSTATE, 0, 0, sizeof(ste) };
567 if (!dfuh->api->dfureq_fn(dfuh, &css, &ste)) {
568 snprintf(dfuh->err + strlen(dfuh->err), sizeof(dfuh->err) -
569 strlen(dfuh->err), " [DEBUG_DFUREQ ERROR: state=%d]", ste);
570 return 0;
571 }
572
573 int ret = dfuh->api->dfureq_fn(dfuh, cs, data);
574 fprintf(stderr, "[DEBUG]: REQ: ste=%d, cs=%2x/%d/%d/%d/%d -> %s",
575 ste, cs->bmRequestType, cs->bRequest, cs->wValue,
576 cs->wIndex, cs->wLength, ret ? "ok" : "ERROR");
577 if (cs->bRequest == DFU_GETSTATE)
578 fprintf(stderr, " (state=%d)", *((unsigned char*)(data)));
579 if (cs->bRequest == DFU_GETSTATUS) {
580 struct usbStatusData *sd = (struct usbStatusData*)data;
581 fprintf(stderr, " (status=%d, polltmo=%d, state=%d)", sd->bStatus,
582 (sd->bwPollTimeout2 << 16) | (sd->bwPollTimeout1 << 8) |
583 (sd->bwPollTimeout0), sd->bState);
584 }
585 fputc('\n', stderr);
586 fflush(stderr);
587 return ret;
588}
589
590static int dfureq_getstatus(struct dfuDev *dfuh, int *status,
591 int *poll_tmo /*ms*/, int *state)
592{
593 struct usbStatusData sd = { 0, 0, 0, 0, 0, 0 };
594 struct usbControlSetup cs = { 0xA1, DFU_GETSTATUS, 0, 0, sizeof(sd) };
595 int ret = dfu_request(dfuh, &cs, &sd);
596 if (status) *status = sd.bStatus;
597 if (state) *state = sd.bState;
598 if (poll_tmo) *poll_tmo = (sd.bwPollTimeout2 << 16) |
599 (sd.bwPollTimeout1 << 8) | (sd.bwPollTimeout0);
600 return ret;
601}
602
603static int dfureq_getstate(struct dfuDev *dfuh, int *state)
604{
605 if (!state)
606 return 1; /* nothing to do */
607 unsigned char sts = 0;
608 struct usbControlSetup cs = { 0xA1, DFU_GETSTATE, 0, 0, sizeof(sts) };
609 int ret = dfu_request(dfuh, &cs, &sts);
610 *state = sts;
611 return ret;
612}
613
614static int dfureq_dnload(struct dfuDev* dfuh, uint16_t blknum,
615 uint16_t len, unsigned char *data)
616{
617 struct usbControlSetup cs = { 0x21, DFU_DNLOAD, blknum, 0, len };
618 return dfu_request(dfuh, &cs, data);
619}
620
621/* not used */
622#if 0
623static int dfureq_upload(struct dfuDev* dfuh,
624 uint16_t blknum, uint16_t len, unsigned char *data)
625{
626 struct usbControlSetup cs = { 0xA1, DFU_UPLOAD, blknum, 0, len };
627 return dfu_request(dfuh, &cs, data);
628}
629
630static int dfureq_clrstatus(struct dfuDev* dfuh)
631{
632 struct usbControlSetup cs = { 0x21, DFU_CLRSTATUS, 0, 0, 0 };
633 return dfu_request(dfuh, &cs, NULL);
634}
635
636static int dfureq_abort(struct dfuDev* dfuh)
637{
638 struct usbControlSetup cs = { 0x21, DFU_ABORT, 0, 0, 0 };
639 return dfu_request(dfuh, &cs, NULL);
640}
641
642/* not implemented on DFU8702 */
643static int dfureq_detach(struct dfuDev* dfuh, int tmo)
644{
645 struct usbControlSetup cs = { 0x21, DFU_DETACH, tmo, 0, 0 };
646 return dfu_request(dfuh, &cs, NULL);
647}
648#endif
649
650static int dfu_send_packet(struct dfuDev* dfuh, uint16_t blknum,
651 uint16_t len, unsigned char *data, int *status,
652 int *poll_tmo, int *state, int *pre_state)
653{
654 if (!dfureq_dnload(dfuh, blknum, len, data))
655 return 0;
656
657 /* device is in dfuDLSYNC state, waiting for a GETSTATUS request
658 to enter the next state, if she respond with dfuDLBUSY then
659 we must wait to resend the GETSTATUS request */
660
661 if (!dfureq_getstatus(dfuh, status, poll_tmo, state))
662 return 0;
663
664 if (*state == dfuDNBUSY) {
665 if (*poll_tmo)
666 sleep_ms(*poll_tmo);
667 if (!dfureq_getstate(dfuh, pre_state))
668 return 0;
669 if (!dfureq_getstatus(dfuh, status, poll_tmo, state))
670 return 0;
671 }
672
673 return 1;
674}
675
676static int dfu_download_file(struct dfuDev* dfuh,
677 unsigned char *data, unsigned long size)
678{
679 unsigned int blknum, len, remaining;
680 int status, poll_tmo, state;
681
682 if (!dfureq_getstate(dfuh, &state))
683 goto error;
684
685 if (state != dfuIDLE) {
686 dfu_set_errstr(dfuh, "Could not start DFU download: not idle");
687 goto error;
688 }
689
690 blknum = 0;
691 remaining = size;
692 while (remaining)
693 {
694 len = (remaining < DFU_PKT_SZ) ? remaining : DFU_PKT_SZ;
695
696 if (!dfu_send_packet(dfuh, blknum, len, data +
697 blknum*DFU_PKT_SZ, &status, &poll_tmo, &state, NULL))
698 goto error;
699
700 if (state != dfuDNLOAD_IDLE) {
701 dfu_set_errstr(dfuh, "DFU download aborted: unexpected state");
702 goto error;
703 }
704
705 remaining -= len;
706 blknum++;
707 }
708
709 /* send ZLP */
710 int pre_state = 0;
711 if (!dfu_send_packet(dfuh, blknum, 0, NULL,
712 &status, &poll_tmo, &state, &pre_state)) {
713 if (pre_state == dfuMANIFEST_SYNC)
714 goto ok; /* pwnaged .dfu file */
715 goto error;
716 }
717
718 if (state != dfuMANIFEST) {
719 if (status == errFIRMWARE)
720 dfu_set_errstr(dfuh, "DFU download failed: corrupt firmware");
721 else
722 dfu_set_errstr(dfuh, "DFU download failed: unexpected state");
723 goto error;
724 }
725
726 /* wait for manifest stage */
727 if (poll_tmo)
728 sleep_ms(poll_tmo);
729
730 if (!dfureq_getstatus(dfuh, &status, NULL, &state))
731 goto ok; /* 1223 .dfu file */
732
733
734 /* TODO: next code never tested */
735
736 if (state != dfuMANIFEST_WAIT_RESET) {
737 if (status == errVERIFY)
738 dfu_set_errstr(dfuh, "DFU manifest failed: wrong FW verification");
739 else
740 dfu_set_errstr(dfuh, "DFU manifest failed: unexpected state");
741 goto error;
742 }
743
744 if (!dfuh->api->reset_fn(dfuh))
745 goto error;
746
747ok:
748 return 1;
749error:
750 return 0;
751}
752
753static int dfu_open(struct dfuDev *dfuh, int pid)
754{
755 int pid_l[2] = {0};
756 struct dfuAPI *api;
757 unsigned i;
758
759 pid_l[0] = pid;
760
761 for (i = 0; i < DFU_N_APIS; i++)
762 {
763 api = &api_list[i];
764 if (!(api->open_fn(dfuh, pid ? pid_l : KNOWN_PIDS)))
765 return 0; /* error */
766 if (dfuh->found_pid) {
767 dfuh->api = api;
768 printf("[INFO] %s: found %s\n", api->name, dfuh->descr);
769 fflush(stdout);
770 return 1; /* ok */
771 }
772 printf("[INFO] %s: no DFU devices found\n", api->name);
773 fflush(stdout);
774 }
775
776 dfu_set_errstr(dfuh, "DFU device not found");
777 return 0;
778}
779
780static void dfu_destroy(struct dfuDev *dfuh)
781{
782 if (dfuh) {
783 if (dfuh->api)
784 dfuh->api->close_fn(dfuh);
785 free(dfuh);
786 }
787}
788
789static struct dfuDev *dfu_create()
790{
791 return calloc(sizeof(struct dfuDev), 1);
792}
793
794/*
795 * exported functions
796 */
797int ipoddfu_send(int pid, unsigned char *data, int size,
798 char* errstr, int errstrsize)
799{
800 struct dfuDev *dfuh;
801 unsigned char *buf;
802 unsigned int checksum;
803 int ret = 1; /* ok */
804
805 dfuh = dfu_create();
806
807 buf = malloc(size+4);
808 if (!buf) {
809 dfu_set_errstr(dfuh, "Could not allocate memory for DFU buffer");
810 goto error;
811 }
812
813 if (memcmp(data, IM3_IDENT, 4)) {
814 dfu_set_errstr(dfuh, "Bad DFU image data");
815 goto error;
816 }
817
818 /* FIXME: big endian */
819 crc32_init();
820 checksum = crc32(data, size, CRC32_DEFAULT_SEED);
821 memcpy(buf, data, size);
822 memcpy(buf+size, &checksum, 4);
823
824 if (!dfu_open(dfuh, pid))
825 goto error;
826
827 if (!dfu_download_file(dfuh, buf, size+4))
828 goto error;
829
830bye:
831 if (buf) free(buf);
832 dfu_destroy(dfuh);
833 return ret;
834
835error:
836 ret = 0;
837 if (errstr)
838 snprintf(errstr, errstrsize, "[ERR] %s", dfuh->err);
839 goto bye;
840}
841
842/* search for the DFU device and gets its DFUState */
843int ipoddfu_scan(int pid, int *state, int reset,
844 char* errstr, int errstrsize)
845{
846 struct dfuDev *dfuh;
847 int ret = 1; /* ok */
848
849 dfuh = dfu_create();
850
851 if (!dfu_open(dfuh, pid))
852 goto error;
853
854 if (reset)
855 if (!dfuh->api->reset_fn(dfuh))
856 goto error;
857
858 if (!dfureq_getstate(dfuh, state))
859 goto error;
860
861bye:
862 dfu_destroy(dfuh);
863 return ret;
864
865error:
866 ret = 0;
867 if (errstr)
868 snprintf(errstr, errstrsize, "[ERR] %s", dfuh->err);
869 goto bye;
870}
871
872void ipoddfu_debug(int debug)
873{
874 DEBUG_DFUREQ = debug;
875}
diff --git a/rbutil/mks5lboot/main.c b/rbutil/mks5lboot/main.c
new file mode 100644
index 0000000000..98c85b9bb7
--- /dev/null
+++ b/rbutil/mks5lboot/main.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
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <unistd.h>
26#include <fcntl.h>
27#include <time.h>
28#include <sys/types.h>
29#include <sys/stat.h>
30
31#include "mks5lboot.h"
32
33/* Win32 compatibility */
34#ifndef O_BINARY
35#define O_BINARY 0
36#endif
37
38#define DEFAULT_LOOP_PERIOD 1 /* seconds */
39
40#define ERROR(format, ...) \
41 do { \
42 snprintf(errstr, errstrsize, "[ERR] "format, __VA_ARGS__); \
43 goto error; \
44 } while(0)
45
46static int write_file(char *outfile, unsigned char* buf,
47 int bufsize, char* errstr, int errstrsize)
48{
49 int fd = open(outfile, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, 0666);
50 if (fd < 0)
51 ERROR("Could not open %s for writing", outfile);
52
53 if (write(fd, buf, bufsize) != bufsize)
54 ERROR("Could not write file %s", outfile);
55
56 return 1;
57
58error:
59 return 0;
60}
61
62static unsigned char *read_file(char *infile, int *bufsize,
63 char* errstr, int errstrsize)
64{
65 unsigned char *buf;
66 int fd;
67 struct stat s;
68
69 fd = open(infile, O_RDONLY|O_BINARY);
70 if (fd < 0)
71 ERROR("Could not open %s for reading", infile);
72
73 if (fstat(fd, &s) < 0)
74 ERROR("Checking size of input file %s", infile);
75
76 *bufsize = s.st_size;
77
78 buf = malloc(*bufsize);
79 if (buf == NULL)
80 ERROR("Could not allocate memory for %s", infile);
81
82 if (read(fd, buf, *bufsize) != *bufsize)
83 ERROR("Could not read file %s", infile);
84
85 return buf;
86
87error:
88 return NULL;
89}
90
91static void sleep_ms(unsigned int ms)
92{
93 struct timespec req;
94 req.tv_sec = ms / 1000;
95 req.tv_nsec = (ms % 1000) * 1000000;
96 nanosleep(&req, NULL);
97}
98
99static void usage(void)
100{
101 fprintf(stderr,
102 "Usage:\n"
103 " mks5lboot --bl-inst <bootloader.ipod> [-p <pid>] [--single]\n"
104 " --bl-uninst <platform> [-p <pid>]\n"
105 " --dfuscan [--loop [<sec>]] [-p <pid>]\n"
106 " --dfusend <infile.dfu> [-p <pid>]\n"
107 " --dfureset [--loop [<sec>]] [-p <pid>]\n"
108 " --mkdfu-inst <bootloader.ipod> <outfile.dfu> [--single]\n"
109 " --mkdfu-uninst <platform> <outfile.dfu>\n"
110 " --mkdfu-raw <filename.bin> <outfile.dfu>\n"
111 "\n"
112 "Commands:\n"
113 " --bl-inst Install file <bootloader.ipod> into an iPod device\n"
114 " (same as --mkdfu-inst and --dfusend).\n"
115 " --bl-uninst Remove a bootloader from an iPod device (same as\n"
116 " --mkdfu-uninst and --dfusend).\n"
117 "\n"
118 " --dfuscan scan for DFU USB devices and outputs the status.\n"
119 " --dfusend send DFU image <infile.dfu> to the device.\n"
120 " --dfureset reset DFU USB device bus.\n"
121 "\n"
122 " --mkdfu-inst Build a DFU image containing an installer for\n"
123 " <bootloader.ipod>, save it as <outfile.dfu>.\n"
124 " --mkdfu-uninst Build a DFU image containing an uninstaler for\n"
125 " <platform> devices, save it as <outfile.dfu>.\n"
126 " --mkdfu-raw Build a DFU image containing raw executable\n"
127 " code, save it ass <outfile.dfu>. <infile.bin>\n"
128 " is the code you want to run, it is loaded at\n"
129 " address 0x%08x and executed.\n"
130 "\n"
131 " <bootloader.ipod> is the rockbox bootloader that you want to\n"
132 " install (previously scrambled with tools/scramble utility).\n"
133 "\n"
134 " <platform> is the name of the platform (type of device) for\n"
135 " which the DFU uninstaller will be built. Currently supported\n"
136 " platform names are:\n"
137 " ipod6g: iPod Classic 6G\n"
138 "\n"
139 "Options:\n"
140 " -p, --pid <pid> Use a specific <pid> (Product Id) USB device,\n"
141 " if this option is ommited then it uses the\n"
142 " first USB DFU device found.\n"
143 " -l, --loop <sec> Run the command every <sec> seconds, default\n"
144 " period (<sec> ommited) is %d seconds.\n"
145 " -S, --single Be careful using this option. The bootloader\n"
146 " is installed for single boot, the original\n"
147 " Apple NOR boot is destroyed (if it exists),\n"
148 " and only Rockbox can be used.\n"
149 , DFU_LOADADDR + BIN_OFFSET
150 , DEFAULT_LOOP_PERIOD);
151
152 exit(1);
153}
154
155int main(int argc, char* argv[])
156{
157 char *dfuoutfile = NULL;
158 char *dfuinfile = NULL;
159 char *dfu_arg = NULL;
160 int dfu_type = DFU_NONE;
161 int n_cmds = 0;
162 int scan = 0;
163 int pid = 0;
164 int reset = 0;
165 int loop = 0;
166 int single = 0;
167 char errstr[200];
168 unsigned char *dfubuf;
169 int dfusize;
170
171 fprintf(stderr,
172 "mks5lboot Version " VERSION "\n"
173 "This is free software; see the source for copying conditions. There is NO\n"
174 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
175 "\n");
176 fflush(stderr);
177
178 while (--argc)
179 {
180 argv++;
181 if (!memcmp(*argv, "--bl", 4)) {
182 if (!strcmp(*argv+4, "-inst")) dfu_type = DFU_INST;
183 else if (!strcmp(*argv+4, "-uninst")) dfu_type = DFU_UNINST;
184 else usage();
185 if (!--argc) usage();
186 dfu_arg = *++argv;
187 n_cmds++;
188 }
189 else if (!memcmp(*argv, "--mkdfu", 7)) {
190 if (!strcmp(*argv+7, "-inst")) dfu_type = DFU_INST;
191 else if (!strcmp(*argv+7, "-uninst")) dfu_type = DFU_UNINST;
192 else if (!strcmp(*argv+7, "-raw")) dfu_type = DFU_RAW;
193 else usage();
194 if (!--argc) usage();
195 dfu_arg = *++argv;
196 if (!--argc) usage();
197 dfuoutfile = *++argv;
198 n_cmds++;
199 }
200 else if (!strcmp(*argv, "--dfusend")) {
201 if (!--argc) usage();
202 dfuinfile = *++argv;
203 n_cmds++;
204 }
205 else if (!strcmp(*argv, "--dfuscan")) {
206 scan = 1;
207 n_cmds++;
208 }
209 else if (!strcmp(*argv, "--dfureset")) {
210 scan = 1;
211 reset = 1;
212 n_cmds++;
213 }
214 else if (!strcmp(*argv, "--pid") || !strcmp(*argv, "-p")) {
215 if (!--argc) usage();
216 if (sscanf(*++argv, "%x", &pid) != 1) usage();
217 }
218 else if (!strcmp(*argv, "--loop") || !strcmp (*argv, "-l")) {
219 if (!(argc-1) || *(argv+1)[0] == '-') {
220 loop = DEFAULT_LOOP_PERIOD;
221 }
222 else {
223 if ((sscanf(*++argv, "%d", &loop) != 1) || !loop) usage();
224 argc--;
225 }
226 }
227 else if (!strcmp(*argv, "--single") || !strcmp(*argv, "-S")) {
228 single = 1;
229 }
230 else if (!strcmp(*argv, "--debug")) {
231 ipoddfu_debug(1);
232 }
233 else
234 usage();
235 }
236
237 if (n_cmds != 1)
238 usage();
239
240 if ((dfu_type == DFU_INST) && single)
241 dfu_type = DFU_INST_SINGLE;
242
243 if (scan) {
244 int cnt = 0;
245 while (1) {
246 int state, res;
247 if (loop) printf("[%d] ", cnt);
248 else printf("[INFO] ");
249 printf("DFU %s:\n", reset ? "reset":"scan");
250 res = ipoddfu_scan(pid, &state, reset, errstr, sizeof(errstr));
251 if (res == 0)
252 printf("%s\n", errstr);
253 else
254 printf("[INFO] DFU device state: %d\n", state);
255 if (!loop)
256 exit(!res);
257 fflush(stdout);
258 sleep_ms(loop*1000);
259 cnt += loop;
260 }
261 }
262
263 if (dfuinfile)
264 dfubuf = read_file(dfuinfile, &dfusize, errstr, sizeof(errstr));
265 else
266 dfubuf = mkdfu(dfu_type, dfu_arg, &dfusize, errstr, sizeof(errstr));
267
268 if (!dfubuf)
269 goto error;
270
271 if (dfuoutfile) {
272 if (write_file(dfuoutfile, dfubuf, dfusize, errstr, sizeof(errstr))) {
273 printf("[INFO] Created file %s (%d bytes)\n", dfuoutfile, dfusize);
274 exit(0);
275 }
276 }
277 else {
278 if (ipoddfu_send(pid, dfubuf, dfusize, errstr, sizeof(errstr))) {
279 printf("[INFO] DFU image sent successfully (%d bytes)\n", dfusize);
280 exit(0);
281 }
282 }
283
284error:
285 printf("%s\n", errstr);
286 exit(1);
287}
diff --git a/rbutil/mks5lboot/mkdfu.c b/rbutil/mks5lboot/mkdfu.c
new file mode 100644
index 0000000000..6ac0daf1ac
--- /dev/null
+++ b/rbutil/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 ERROR(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 ERROR("Could not open %s for reading", filename);
139
140 if (fstat(fd, &s) < 0)
141 ERROR("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 ERROR("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 ERROR("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 ERROR("Could not allocate memory for %s", filename);
164
165 if (read(fd, buf, *bufsize) != *bufsize)
166 ERROR("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 ERROR("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 ERROR("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 ERROR("DFU image (%d bytes) too big", *dfu_size);
259
260 dfu_buf = calloc(*dfu_size, 1);
261 if (!dfu_buf)
262 ERROR("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/rbutil/mks5lboot/mks5lboot.h b/rbutil/mks5lboot/mks5lboot.h
new file mode 100644
index 0000000000..084bec61f9
--- /dev/null
+++ b/rbutil/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__ */