summaryrefslogtreecommitdiffstats
path: root/rbutil
diff options
context:
space:
mode:
authorCástor Muñoz <cmvidal@gmail.com>2016-02-04 23:05:17 +0100
committerCástor Muñoz <cmvidal@gmail.com>2017-04-14 00:03:42 +0200
commit346423c040fe4ac31dae7c1afcb1d853cc80635c (patch)
treebd8dd4c55f083a1162f7019188977213a20dc41c /rbutil
parenteefc7c73e2495decdc6f242515696fe0e3f85609 (diff)
downloadrockbox-346423c040fe4ac31dae7c1afcb1d853cc80635c.tar.gz
rockbox-346423c040fe4ac31dae7c1afcb1d853cc80635c.tar.bz2
rockbox-346423c040fe4ac31dae7c1afcb1d853cc80635c.zip
mks5lboot v1.0 - dualboot installer for s5l8702 targetsmks5lboot_1.0
A tool to install/uninstall a bootloader into a s5l8702 based device: - iPod Classic 6G - iPod Nano 3G (TODO) See mks5lboot/README for detailed info. Change-Id: I451d2aaff34509ebd356e4660647e5222c5d3409
Diffstat (limited to 'rbutil')
-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 @@
+buildposix/
+mks5lboot
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 @@
+# __________ __ ___.
+# Open \______ \ ____ ____ | | _\_ |__ _______ ___
+# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+# \/ \/ \/ \/ \/
+CFLAGS += -Wall -Wextra
+
+OUTPUT = mks5lboot
+
+# inputs for lib
+LIBSOURCES := dualboot.c mkdfu.c ipoddfu.c
+# inputs for binary only
+SOURCES := $(LIBSOURCES) main.c
+# dependencies for binary
+EXTRADEPS :=
+
+ifeq ($(findstring MINGW,$(shell uname)),MINGW)
+LDOPTS += -lsetupapi
+# optional libusb support on Windows
+ifdef DISABLE_LIBUSBAPI
+CFLAGS += -DNO_LIBUSBAPI
+else
+LDOPTS += -Wl,-Bstatic -lusb-1.0
+endif
+else
+# Linux, OS X
+LDOPTS += -lusb-1.0
+endif
+
+include ../libtools.make
+
+# explicit dependencies on dualboot.{c,h} and mks5lboot.h
+$(OBJDIR)mks5lboot.o: dualboot.h dualboot.c mks5lboot.h
+$(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 @@
+mks5lboot
+---------
+
+A tool to install/uninstall a dual bootloader into a s5l8702 based
+device:
+
+ - iPod Classic 6G
+ - iPod Nano 3G (TODO)
+
+
+Usage
+-----
+
+ mks5lboot --bl-inst <bootloader.ipod> [-p <pid>] [--single]
+ --bl-uninst <platform> [-p <pid>]
+ --dfuscan [--loop [<sec>]] [-p <pid>]
+ --dfusend <infile.dfu> [-p <pid>]
+ --dfureset [--loop [<sec>]] [-p <pid>]
+ --mkdfu-inst <bootloader.ipod> <outfile.dfu> [--single]
+ --mkdfu-uninst <platform> <outfile.dfu>
+ --mkdfu-raw <filename.bin> <outfile.dfu>
+
+Commands:
+ --bl-inst Install file <bootloader.ipod> into an iPod device
+ (same as --mkdfu-inst and --dfusend).
+ --bl-uninst Remove a bootloader from an iPod device (same as
+ --mkdfu-uninst and --dfusend).
+
+ --dfuscan scan for DFU USB devices and outputs the status.
+ --dfusend send DFU image <infile.dfu> to the device.
+ --dfureset reset DFU USB device bus.
+
+ --mkdfu-inst Build a DFU image containing an installer for
+ <bootloader.ipod>, save it as <outfile.dfu>.
+ --mkdfu-uninst Build a DFU image containing an uninstaler for
+ <platform> devices, save it as <outfile.dfu>.
+ --mkdfu-raw Build a DFU image containing raw executable
+ code, save it as <outfile.dfu>. <infile.bin>
+ is the code you want to run, it is loaded at
+ address 0x2200030c and executed.
+
+ <bootloader.ipod> is the rockbox bootloader that you want to
+ install (previously scrambled with tools/scramble utility).
+
+ <platform> is the name of the platform (type of device) for
+ which the DFU uninstaller will be built. Currently supported
+ platform names are:
+ ipod6g: iPod Classic 6G
+
+Options:
+ -p, --pid <pid> Use a specific <pid> (Product Id) USB device,
+ if this option is ommited then it uses the
+ first USB DFU device found.
+ -l, --loop <sec> Run the command every <sec> seconds, default
+ period (<sec> ommited) is 1 seconds.
+ -S, --single Be careful using this option. The bootloader
+ is installed for single boot, the original
+ Apple NOR boot is destroyed (if it exists),
+ and only Rockbox can be used.
+
+
+Dual bootloader installation
+----------------------------
+
+Prerequisites:
+
+ - An iPod Classic 6th with Apple firmware installed and running, current
+ supported FW versions for existing models:
+
+ Classic 6th 80/160 Late 2007 (1G): 1.1.2
+ Classic 6th 120 Late 2008 (2G): 2.0.1
+ Classic 6th 160 Late 2009 (3G): 2.0.4
+ Classic 6th 160 Late 2012 (4G): 2.0.5
+
+ - If your iPod is formated using Apple partitions you must convert this
+ ipod to FAT32 format (aka a "winpod"), see http://www.rockbox.org/
+ wiki/IpodConversionToFAT32
+
+ - It is recommended to install the RB firmware before installing the dual
+ bootloader for the first time. Install Rockbox using RockboxUtility or
+ download the latest daily build and uncompress it into the root folder
+ of the iPod.
+
+ Windows only:
+
+ - If iTunes is installed:
+ . Configure iTunes: Summary -> Options -> check "Enable disk use".
+
+ - If iTunes is not installed:
+ . You need a DFU USB driver for your device. To check if there is a
+ valid USB driver installed, put your device on DFU mode and choose
+ one of either:
+ a) Use Windows Device Manager to verify if you USB DFU device is
+ present.
+ b) Use mks5lboot tool running "mks5lboot --dfuscan", common output:
+ . When the DFU device is found and a valid driver is installed:
+ [INFO] DFU device state: 2
+ . When the device is found but there is no driver installed:
+ [ERR] Could not open USB device: LIBUSB_ERROR_NOT_SUPPORTED
+ . Then the device is found but driver is not valid (probably a
+ libusb-win32 driver is installed):
+ [ERR] Could not set USB configuration: LIBUSB_ERROR_NOT_FOUND
+ . If there is no valid DFU driver installed, try one of these:
+ a) Use Zadig (http://zadig.akeo.ie/) to build and install a WinUSB
+ (libusb.info) or libusbK driver for your device. Note that
+ libusb-win32 (libusb0) drivers are not valid for mks5lboot.
+ b) Use Apple Mobile Device USB driver (included with iTunes).
+
+Command line install:
+
+ - If you are using iTunes on Windows, close iTunes and kill (or pause)
+ iTunesHelper.exe before entering DFU mode.
+
+ - Put you device on DFU mode by pressing and holding SELECT+MENU buttons
+ for about 12 seconds.
+
+ You can notice when the device enters DFU mode running the next command
+ to scan the USB bus every second (press Ctrl-C to abort the scan):
+ mks5lboot --dfuscan --loop
+
+ - To install or update a bootloader, build the DFU installer and send it
+ to the device:
+ mks5lboot --bl-inst /path/to/bootloader-ipod6g.ipod
+
+ When the DFU imagen is loaded and executed, the device emits an 'alive'
+ tone (2000Hz/100ms). When the bootloader is successfully installed then
+ a dual tone beep sounds (1000Hz/100ms+2000Hz/150ms) and the device
+ reboots. If something went bad then 330Hz/500ms tone is emited and the
+ device reboots. When three 330Hz tones sounds, it means that the NOR
+ got corrupted and the device must be restored using iTunes (should not
+ happen).
+
+ - To remove a previously installed bootloader, build the DFU uninstaler
+ and send it to the device:
+ mks5lboot --bl-uninst ipod6g
+
+ If USB access is denied, try to run the mks5lboot tool using a privileged
+ user (i.e. Administrator or root).
+
+
+Dual-Boot
+---------
+
+The purpose of this program is to provide dual-boot between the original
+firmware and the new (rockbox) firmware.
+
+The button press check is done ~800 ms. after power-up or reboot, then:
+
+ SELECT + MENU: resets the device after ~5 seconds, then if SELECT+MENU
+ remains pressed the device enters DFU mode after an
+ additional period of ~8 seconds.
+ SELECT + LEFT: enter OF diagnostics (after ~7 seconds).
+ SELECT + PLAY: enter OF diskmode (after ~7 seconds).
+ SELECT + RIGHT: enter bootloader USB mode.
+ MENU: enter OF
+ Hold Switch locked: enter OF (see below for details).
+ Any other combination: launch Rockbox.
+
+Switch current firmware:
+
+ Tries to behave like ipod Video, see http://download.rockbox.org/manual/
+ rockbox-ipodvideo/rockbox-buildch3.html#x5-290003.1.3
+
+ Apple is the current FW:
+ - Stop playback and wait a few seconds for hard disk spin-down.
+ - Press and hold SELECT+MENU, after ~5 seconds the player hard resets,
+ release the buttons when the screen goes black.
+
+ Rockbox is the current FW:
+ - Shut down the device using "Long Play" key press.
+ - Once the device is powered off, there are three ways to enter OF:
+ 1) Press and hold MENU button for at least ~800 ms.
+ 2) Turn on the Hold switch immediately after turning the player on,
+ it must be done before "Loading Rockbox..." message appears (~3
+ seconds from power-on). Be careful, if the hold switch is locked
+ when Rockbox starts then your RB settings will be cleared!
+ 3) You can also load the original firmware by shutting down the
+ device, then clicking the Hold switch on and connecting the iPod
+ to your computer.
+
+
+Single-Boot
+-----------
+
+Use --single option if the Apple firmware is not installed on your iPod
+and/or you want to force the installation of the bootloader to use Rockbox
+as unique firmware. The single-boot installer writes the bootloader on the
+NOR with no previous check, the original Apple NOR boot is destroyed if it
+exists.
+
+To build the DFU single-boot installer and send it to the device:
+ mks5lboot --bl-inst --single /path/to/bootloader-ipod6g.ipod
+
+
+Compilation
+-----------
+
+Needs libusb > 1.0 installed, tested on:
+
+Linux: gcc-4.9.2 + libusb-1.0.19
+Windows XP: mingw32-gcc-4.8.1 + libusbx-1.0.15
+OS X 10.11: clang-7.3.0 + libusb-1.0.20
+
+
+Hacking
+-------
+
+See comments in mkdfu.c, ipoddfu.c, dualboot.c and bootloader/ipod6g.c for
+more 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 @@
+/* Generated by bin2c */
+
+#include "dualboot.h"
+
+unsigned char dualboot_install_ipod6g[5396] = {
+ 0xd7, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x24, 0xd0, 0x9f, 0xe5, 0xdb, 0x00, 0xa0, 0xe3,
+ 0x00, 0xf0, 0x21, 0xe1, 0x18, 0xd0, 0x9f, 0xe5, 0xd3, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1,
+ 0x10, 0xd0, 0x9f, 0xe5, 0x05, 0x08, 0xa0, 0xe3, 0x78, 0x00, 0x80, 0xe3, 0x10, 0x0f, 0x01, 0xee,
+ 0x1d, 0x00, 0x00, 0xeb, 0x0c, 0x03, 0x00, 0x22, 0x0c, 0x03, 0x00, 0x22, 0x7f, 0x40, 0x2d, 0xe9,
+ 0x5c, 0x10, 0x9f, 0xe5, 0x10, 0x20, 0xa0, 0xe3, 0x0d, 0x00, 0xa0, 0xe1, 0xea, 0x04, 0x00, 0xeb,
+ 0x00, 0x00, 0xa0, 0xe3, 0x02, 0x10, 0xa0, 0xe3, 0x0d, 0x20, 0xa0, 0xe1, 0x10, 0x30, 0xa0, 0xe3,
+ 0x8d, 0x04, 0x00, 0xeb, 0x3c, 0x60, 0x9f, 0xe5, 0x0d, 0x40, 0xa0, 0xe1, 0x00, 0x50, 0xa0, 0xe3,
+ 0x06, 0x10, 0xa0, 0xe1, 0x0d, 0x00, 0xa0, 0xe1, 0x10, 0x20, 0xa0, 0xe3, 0x77, 0x00, 0x00, 0xeb,
+ 0x10, 0x60, 0x86, 0xe2, 0x00, 0x00, 0x50, 0xe3, 0x02, 0x00, 0x00, 0x0a, 0x01, 0x50, 0x85, 0xe2,
+ 0x04, 0x00, 0x55, 0xe3, 0xf5, 0xff, 0xff, 0x1a, 0x05, 0x00, 0xa0, 0xe1, 0x10, 0xd0, 0x8d, 0xe2,
+ 0x70, 0x80, 0xbd, 0xe8, 0x10, 0x00, 0x02, 0x22, 0x54, 0x17, 0x00, 0x22, 0x70, 0x40, 0x2d, 0xe9,
+ 0xae, 0x00, 0x00, 0xeb, 0x7c, 0x41, 0x9f, 0xe5, 0x7c, 0x01, 0x9f, 0xe5, 0xa3, 0x04, 0x00, 0xeb,
+ 0x00, 0x00, 0xa0, 0xe3, 0x04, 0x10, 0xa0, 0xe3, 0xc4, 0x00, 0x00, 0xeb, 0x0e, 0x30, 0xd4, 0xe5,
+ 0x0d, 0x00, 0xd4, 0xe5, 0x0c, 0x10, 0xd4, 0xe5, 0x0f, 0x20, 0xd4, 0xe5, 0x03, 0x38, 0xa0, 0xe1,
+ 0x00, 0x34, 0x83, 0xe1, 0x01, 0x30, 0x83, 0xe1, 0x02, 0x2c, 0x83, 0xe1, 0x40, 0x50, 0xd4, 0xe5,
+ 0x02, 0x00, 0xa0, 0xe3, 0x02, 0x1b, 0x84, 0xe2, 0x10, 0x30, 0x84, 0xe2, 0xee, 0x01, 0x00, 0xeb,
+ 0x40, 0x20, 0xa0, 0xe3, 0x02, 0x00, 0xa0, 0xe3, 0x04, 0x10, 0xa0, 0xe1, 0x02, 0x30, 0x84, 0xe0,
+ 0xe9, 0x01, 0x00, 0xeb, 0x00, 0x00, 0x55, 0xe3, 0x08, 0x00, 0x00, 0x0a, 0x04, 0x10, 0xa0, 0xe1,
+ 0x02, 0x09, 0xa0, 0xe3, 0x62, 0x03, 0x00, 0xeb, 0x10, 0x31, 0x9f, 0xe5, 0x10, 0x21, 0x9f, 0xe5,
+ 0x00, 0x00, 0x50, 0xe3, 0x02, 0x00, 0xa0, 0x11, 0x03, 0x00, 0xa0, 0x01, 0x33, 0x00, 0x00, 0xea,
+ 0x02, 0x09, 0xa0, 0xe3, 0xfc, 0x10, 0x9f, 0xe5, 0xfc, 0x20, 0x9f, 0xe5, 0x77, 0x03, 0x00, 0xeb,
+ 0x00, 0x00, 0x50, 0xe3, 0x2c, 0x00, 0x00, 0x1a, 0xb7, 0xff, 0xff, 0xeb, 0x04, 0x00, 0x50, 0xe3,
+ 0x0a, 0x00, 0x00, 0x1a, 0xdc, 0x00, 0x9f, 0xe5, 0xc5, 0x01, 0x00, 0xeb, 0xd4, 0x10, 0x9f, 0xe5,
+ 0xd4, 0x20, 0x9f, 0xe5, 0x02, 0x09, 0x80, 0xe2, 0x6c, 0x03, 0x00, 0xeb, 0x00, 0x00, 0x50, 0xe3,
+ 0x21, 0x00, 0x00, 0x1a, 0xac, 0xff, 0xff, 0xeb, 0x04, 0x00, 0x50, 0xe3, 0x1e, 0x00, 0x00, 0x0a,
+ 0xa0, 0x00, 0x9f, 0xe5, 0xba, 0x01, 0x00, 0xeb, 0x00, 0x40, 0xa0, 0xe1, 0x23, 0x03, 0x00, 0xeb,
+ 0x04, 0x00, 0x50, 0xe1, 0xa4, 0x00, 0x9f, 0x35, 0x18, 0x00, 0x00, 0x3a, 0x02, 0x09, 0x84, 0xe2,
+ 0x90, 0x10, 0x9f, 0xe5, 0x3e, 0x03, 0x00, 0xeb, 0x00, 0x00, 0x50, 0xe3, 0x05, 0x00, 0x00, 0x0a,
+ 0x02, 0x09, 0xa0, 0xe3, 0x6c, 0x10, 0x9f, 0xe5, 0x39, 0x03, 0x00, 0xeb, 0x00, 0x00, 0x50, 0xe3,
+ 0x6c, 0x00, 0x9f, 0x15, 0x0d, 0x00, 0x00, 0x1a, 0x6c, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0xa0, 0xe3,
+ 0x60, 0x10, 0x9f, 0xe5, 0xc8, 0x01, 0x00, 0xeb, 0x02, 0x09, 0xa0, 0xe3, 0x54, 0x10, 0x9f, 0xe5,
+ 0x2f, 0x03, 0x00, 0xeb, 0x58, 0x30, 0x9f, 0xe5, 0x0c, 0x20, 0x83, 0xe2, 0x00, 0x00, 0x50, 0xe3,
+ 0x03, 0x00, 0xa0, 0x01, 0x02, 0x00, 0xa0, 0x11, 0x00, 0x00, 0x00, 0xea, 0x2c, 0x00, 0x9f, 0xe5,
+ 0x40, 0x20, 0x9f, 0xe5, 0x40, 0x30, 0x9f, 0xe5, 0xb4, 0x10, 0x92, 0xe5, 0x03, 0x00, 0x51, 0xe1,
+ 0xfc, 0xff, 0xff, 0x9a, 0x49, 0x04, 0x00, 0xeb, 0x01, 0x26, 0xa0, 0xe3, 0xf2, 0x35, 0xa0, 0xe3,
+ 0x00, 0x20, 0x83, 0xe5, 0xfe, 0xff, 0xff, 0xea, 0xd0, 0x17, 0x00, 0x22, 0x94, 0x17, 0x00, 0x22,
+ 0x4c, 0x17, 0x00, 0x22, 0x9c, 0x17, 0x00, 0x22, 0x00, 0x00, 0x02, 0x22, 0x00, 0x08, 0x02, 0x22,
+ 0x46, 0x17, 0x00, 0x22, 0x40, 0x17, 0x00, 0x22, 0x00, 0x00, 0x70, 0x3c, 0x7f, 0x84, 0x1e, 0x00,
+ 0x10, 0x40, 0x2d, 0xe9, 0x00, 0x30, 0xa0, 0xe3, 0x07, 0x00, 0x00, 0xea, 0x03, 0x40, 0xd0, 0xe7,
+ 0x03, 0xc0, 0xd1, 0xe7, 0x01, 0x20, 0x42, 0xe2, 0x0c, 0x00, 0x54, 0xe1, 0x01, 0x30, 0x83, 0xe2,
+ 0x01, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x6c, 0xe0, 0x10, 0x80, 0xbd, 0xe8, 0x00, 0x00, 0x52, 0xe3,
+ 0xf5, 0xff, 0xff, 0x1a, 0x02, 0x00, 0xa0, 0xe1, 0x10, 0x80, 0xbd, 0xe8, 0x1f, 0x30, 0x00, 0xe2,
+ 0x01, 0x20, 0xa0, 0xe3, 0xc0, 0x02, 0xa0, 0xe1, 0x00, 0x00, 0x51, 0xe3, 0x12, 0x33, 0xa0, 0xe1,
+ 0x02, 0x20, 0x00, 0xe0, 0x08, 0x00, 0x00, 0x0a, 0x3c, 0x10, 0x9f, 0xe5, 0x3c, 0x00, 0x9f, 0xe5,
+ 0x00, 0x00, 0x52, 0xe3, 0x00, 0x20, 0xa0, 0x11, 0x01, 0x20, 0xa0, 0x01, 0x00, 0x10, 0x92, 0xe5,
+ 0x03, 0x30, 0xc1, 0xe1, 0x00, 0x30, 0x82, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x18, 0x10, 0x9f, 0xe5,
+ 0x18, 0x00, 0x9f, 0xe5, 0x00, 0x00, 0x52, 0xe3, 0x01, 0x00, 0xa0, 0x01, 0x00, 0x20, 0x90, 0xe5,
+ 0x03, 0x30, 0x82, 0xe1, 0x00, 0x30, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x48, 0x00, 0x50, 0x3c,
+ 0x4c, 0x00, 0x50, 0x3c, 0x70, 0x40, 0x2d, 0xe9, 0x10, 0x50, 0x9d, 0xe5, 0x01, 0x30, 0x43, 0xe2,
+ 0x01, 0x50, 0x45, 0xe2, 0x03, 0x60, 0x02, 0xe2, 0x0f, 0x30, 0x03, 0xe2, 0x05, 0x52, 0xa0, 0xe1,
+ 0x03, 0xc0, 0xc0, 0xe3, 0xff, 0x50, 0x05, 0xe2, 0x06, 0x36, 0x83, 0xe1, 0x00, 0x40, 0x9c, 0xe5,
+ 0x05, 0x30, 0x83, 0xe1, 0x30, 0x50, 0x9f, 0xe5, 0x02, 0x20, 0x00, 0xe2, 0x82, 0x21, 0xa0, 0xe1,
+ 0x00, 0x00, 0x51, 0xe3, 0x02, 0x19, 0xa0, 0x03, 0x00, 0x10, 0xa0, 0x13, 0x35, 0x42, 0x04, 0xe0,
+ 0x01, 0x30, 0x83, 0xe1, 0x13, 0x22, 0x84, 0xe1, 0x00, 0x20, 0x8c, 0xe5, 0xb0, 0x20, 0xd0, 0xe1,
+ 0x03, 0x00, 0x52, 0xe1, 0xfc, 0xff, 0xff, 0x1a, 0x70, 0x80, 0xbd, 0xe8, 0x00, 0x00, 0xff, 0xff,
+ 0x5c, 0xc0, 0x9f, 0xe5, 0x13, 0x40, 0x2d, 0xe9, 0x44, 0xe0, 0x9c, 0xe5, 0x01, 0x40, 0xa0, 0xe3,
+ 0x01, 0xec, 0xce, 0xe3, 0x00, 0x20, 0xa0, 0xe3, 0x04, 0x30, 0xa0, 0xe1, 0x44, 0xe0, 0x8c, 0xe5,
+ 0x40, 0x00, 0x9f, 0xe5, 0x04, 0x10, 0xa0, 0xe1, 0x00, 0x40, 0x8d, 0xe5, 0xd8, 0xff, 0xff, 0xeb,
+ 0x04, 0x10, 0xa0, 0xe1, 0x25, 0x00, 0xa0, 0xe3, 0xbb, 0xff, 0xff, 0xeb, 0x28, 0x30, 0x9f, 0xe5,
+ 0x11, 0x2d, 0xa0, 0xe3, 0xa0, 0x20, 0x83, 0xe5, 0x0b, 0x20, 0xa0, 0xe3, 0xb0, 0x20, 0x83, 0xe5,
+ 0x00, 0x20, 0xe0, 0xe3, 0xa8, 0x20, 0x83, 0xe5, 0x04, 0x20, 0x82, 0xe2, 0xa4, 0x20, 0x83, 0xe5,
+ 0x1c, 0x80, 0xbd, 0xe8, 0x00, 0x00, 0x50, 0x3c, 0x12, 0x00, 0x50, 0x3c, 0x00, 0x00, 0x70, 0x3c,
+ 0x04, 0x30, 0x9f, 0xe5, 0x00, 0x11, 0x83, 0xe7, 0x1e, 0xff, 0x2f, 0xe1, 0xac, 0x17, 0x00, 0x22,
+ 0x80, 0x20, 0x9f, 0xe5, 0x00, 0x00, 0x51, 0xe3, 0x7c, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x11,
+ 0x01, 0x00, 0x50, 0xe3, 0x0a, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x50, 0xe3, 0x0f, 0x00, 0x00, 0x0a,
+ 0x00, 0x00, 0x50, 0xe3, 0x1e, 0xff, 0x2f, 0x11, 0x60, 0x10, 0x9f, 0xe5, 0x00, 0x20, 0x91, 0xe5,
+ 0x22, 0x28, 0xa0, 0xe1, 0x02, 0x28, 0xa0, 0xe1, 0x02, 0x30, 0x83, 0xe1, 0x00, 0x30, 0x81, 0xe5,
+ 0x1e, 0xff, 0x2f, 0xe1, 0x44, 0x10, 0x9f, 0xe5, 0xc0, 0x20, 0x91, 0xe5, 0x02, 0x28, 0xa0, 0xe1,
+ 0x22, 0x28, 0xa0, 0xe1, 0x03, 0x38, 0x82, 0xe1, 0xc0, 0x30, 0x81, 0xe5, 0x1e, 0xff, 0x2f, 0xe1,
+ 0x28, 0x00, 0x9f, 0xe5, 0xc0, 0x21, 0x90, 0xe5, 0xff, 0x24, 0xc2, 0xe3, 0x03, 0x2c, 0x82, 0xe1,
+ 0xc0, 0x21, 0x80, 0xe5, 0xe0, 0x21, 0x90, 0xe5, 0xff, 0x20, 0xc2, 0xe3, 0x23, 0x34, 0x82, 0xe1,
+ 0xe0, 0x31, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x22, 0x22, 0x00, 0x00, 0xef, 0xee, 0x00, 0x00,
+ 0x00, 0x00, 0xf0, 0x3c, 0x01, 0x00, 0x50, 0xe3, 0x01, 0x10, 0x21, 0xe2, 0x06, 0x00, 0x00, 0x0a,
+ 0x02, 0x00, 0x50, 0xe3, 0x06, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x50, 0xe3, 0x24, 0x30, 0x9f, 0x05,
+ 0x0e, 0x10, 0x81, 0x03, 0x00, 0x12, 0x83, 0x05, 0x1e, 0xff, 0x2f, 0xe1, 0x18, 0x30, 0x9f, 0xe5,
+ 0x00, 0x00, 0x00, 0xea, 0x14, 0x30, 0x9f, 0xe5, 0x08, 0x20, 0x9f, 0xe5, 0x03, 0x30, 0x81, 0xe1,
+ 0x00, 0x32, 0x82, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0xf0, 0x3c, 0x0e, 0x04, 0x06, 0x00,
+ 0x0e, 0x06, 0x0e, 0x00, 0x02, 0x00, 0x50, 0xe3, 0x10, 0x40, 0x2d, 0xe9, 0xbc, 0x30, 0x9f, 0x05,
+ 0x03, 0x00, 0x00, 0x0a, 0xb8, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3, 0xb4, 0x30, 0x9f, 0xe5,
+ 0x02, 0x30, 0xa0, 0x01, 0xb0, 0x40, 0x9f, 0xe5, 0xb0, 0xc0, 0x9f, 0xe5, 0x01, 0x20, 0xa0, 0xe3,
+ 0x00, 0x20, 0x83, 0xe5, 0x02, 0x00, 0x50, 0xe3, 0xa4, 0x30, 0x9f, 0x05, 0x02, 0x00, 0x00, 0x0a,
+ 0x01, 0x00, 0x50, 0xe3, 0x04, 0x30, 0xa0, 0x01, 0x0c, 0x30, 0xa0, 0x11, 0x00, 0x30, 0x93, 0xe5,
+ 0x1f, 0x3e, 0x03, 0xe2, 0x01, 0x0c, 0x53, 0xe3, 0xf5, 0xff, 0xff, 0x0a, 0x02, 0x00, 0x50, 0xe3,
+ 0x80, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0x7c, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3,
+ 0x78, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0x5c, 0xc0, 0x9f, 0xe5, 0x5c, 0x20, 0x9f, 0xe5,
+ 0x00, 0x10, 0x83, 0xe5, 0x02, 0x00, 0x50, 0xe3, 0x54, 0x30, 0x9f, 0x05, 0x02, 0x00, 0x00, 0x0a,
+ 0x01, 0x00, 0x50, 0xe3, 0x0c, 0x30, 0xa0, 0x01, 0x02, 0x30, 0xa0, 0x11, 0x00, 0x30, 0x93, 0xe5,
+ 0x3e, 0x0c, 0x13, 0xe3, 0xf6, 0xff, 0xff, 0x0a, 0x02, 0x00, 0x50, 0xe3, 0x40, 0x00, 0x9f, 0x05,
+ 0x04, 0x00, 0x00, 0x0a, 0x3c, 0x30, 0x9f, 0xe5, 0x3c, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3,
+ 0x02, 0x00, 0xa0, 0x01, 0x03, 0x00, 0xa0, 0x11, 0x00, 0x00, 0x90, 0xe5, 0x10, 0x80, 0xbd, 0xe8,
+ 0x34, 0x00, 0x20, 0x3d, 0x34, 0x00, 0xe0, 0x3c, 0x34, 0x00, 0x30, 0x3c, 0x08, 0x00, 0xe0, 0x3c,
+ 0x08, 0x00, 0x30, 0x3c, 0x08, 0x00, 0x20, 0x3d, 0x10, 0x00, 0x20, 0x3d, 0x10, 0x00, 0xe0, 0x3c,
+ 0x10, 0x00, 0x30, 0x3c, 0x20, 0x00, 0x20, 0x3d, 0x20, 0x00, 0x30, 0x3c, 0x20, 0x00, 0xe0, 0x3c,
+ 0x02, 0x00, 0x50, 0xe3, 0xf0, 0x40, 0x2d, 0xe9, 0xd8, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a,
+ 0xd4, 0xc0, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3, 0xd0, 0x30, 0x9f, 0xe5, 0x0c, 0x30, 0xa0, 0x01,
+ 0x02, 0x00, 0x50, 0xe3, 0x00, 0x10, 0x83, 0xe5, 0xc4, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a,
+ 0xc0, 0xc0, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3, 0xbc, 0x30, 0x9f, 0xe5, 0x0c, 0x30, 0xa0, 0x01,
+ 0x00, 0x40, 0x93, 0xe5, 0x00, 0xc0, 0xa0, 0xe3, 0x01, 0x40, 0x84, 0xe3, 0x00, 0x40, 0x83, 0xe5,
+ 0xa8, 0x70, 0x9f, 0xe5, 0xa8, 0x60, 0x9f, 0xe5, 0xa8, 0x50, 0x9f, 0xe5, 0xa8, 0x40, 0x9f, 0xe5,
+ 0x12, 0x00, 0x00, 0xea, 0x02, 0x00, 0x50, 0xe3, 0xa0, 0x30, 0x9f, 0x05, 0x02, 0x00, 0x00, 0x0a,
+ 0x01, 0x00, 0x50, 0xe3, 0x07, 0x30, 0xa0, 0x01, 0x06, 0x30, 0xa0, 0x11, 0x00, 0x30, 0x93, 0xe5,
+ 0x3e, 0x0c, 0x13, 0xe3, 0xf6, 0xff, 0xff, 0x0a, 0x02, 0x00, 0x50, 0xe3, 0x80, 0x30, 0x9f, 0x05,
+ 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x05, 0x30, 0xa0, 0x01, 0x04, 0x30, 0xa0, 0x11,
+ 0x00, 0x30, 0x93, 0xe5, 0x01, 0x10, 0x41, 0xe2, 0x0c, 0x30, 0xc2, 0xe7, 0x01, 0xc0, 0x8c, 0xe2,
+ 0x00, 0x00, 0x51, 0xe3, 0xea, 0xff, 0xff, 0x1a, 0x02, 0x00, 0x50, 0xe3, 0x30, 0x00, 0x9f, 0x05,
+ 0x04, 0x00, 0x00, 0x0a, 0x2c, 0x30, 0x9f, 0xe5, 0x2c, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3,
+ 0x02, 0x00, 0xa0, 0x11, 0x03, 0x00, 0xa0, 0x01, 0x00, 0x30, 0x90, 0xe5, 0x01, 0x30, 0xc3, 0xe3,
+ 0x00, 0x30, 0x80, 0xe5, 0xf0, 0x80, 0xbd, 0xe8, 0x34, 0x00, 0x20, 0x3d, 0x34, 0x00, 0xe0, 0x3c,
+ 0x34, 0x00, 0x30, 0x3c, 0x04, 0x00, 0x20, 0x3d, 0x04, 0x00, 0xe0, 0x3c, 0x04, 0x00, 0x30, 0x3c,
+ 0x08, 0x00, 0xe0, 0x3c, 0x08, 0x00, 0x30, 0x3c, 0x20, 0x00, 0xe0, 0x3c, 0x20, 0x00, 0x30, 0x3c,
+ 0x08, 0x00, 0x20, 0x3d, 0x20, 0x00, 0x20, 0x3d, 0x02, 0x00, 0x50, 0xe3, 0x2e, 0x00, 0x80, 0x02,
+ 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x2b, 0x00, 0xa0, 0x03, 0x22, 0x00, 0xa0, 0x13,
+ 0x00, 0x10, 0xa0, 0xe3, 0xe4, 0xfe, 0xff, 0xea, 0x02, 0x00, 0x50, 0xe3, 0x10, 0x40, 0x2d, 0xe9,
+ 0x00, 0x40, 0xa0, 0xe1, 0x30, 0x00, 0xa0, 0x03, 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x54, 0xe3,
+ 0x2b, 0x00, 0xa0, 0x03, 0x22, 0x00, 0xa0, 0x13, 0x01, 0x10, 0xa0, 0xe3, 0xda, 0xfe, 0xff, 0xeb,
+ 0x02, 0x00, 0x54, 0xe3, 0x04, 0x31, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0x00, 0x21, 0x9f, 0xe5,
+ 0x01, 0x00, 0x54, 0xe3, 0xfc, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0x02, 0x00, 0x54, 0xe3,
+ 0x0f, 0x20, 0xa0, 0xe3, 0x00, 0x20, 0x83, 0xe5, 0xec, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a,
+ 0xe8, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3, 0xe4, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01,
+ 0x00, 0x20, 0x93, 0xe5, 0x02, 0x00, 0x54, 0xe3, 0x0c, 0x20, 0x82, 0xe3, 0x00, 0x20, 0x83, 0xe5,
+ 0xd0, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0xcc, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3,
+ 0xc8, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0xc4, 0x20, 0x9f, 0xe5, 0x02, 0x00, 0x54, 0xe3,
+ 0x04, 0x21, 0x92, 0xe7, 0x00, 0x20, 0x83, 0xe5, 0xb8, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a,
+ 0xb4, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3, 0xb0, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01,
+ 0x02, 0x00, 0x54, 0xe3, 0x06, 0x20, 0xa0, 0xe3, 0x00, 0x20, 0x83, 0xe5, 0xa0, 0x30, 0x9f, 0x05,
+ 0x03, 0x00, 0x00, 0x0a, 0x9c, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3, 0x98, 0x30, 0x9f, 0xe5,
+ 0x02, 0x30, 0xa0, 0x01, 0x94, 0x20, 0x9f, 0xe5, 0x02, 0x00, 0x54, 0xe3, 0x00, 0x20, 0x83, 0xe5,
+ 0x54, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0x50, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3,
+ 0x4c, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0x00, 0x20, 0x93, 0xe5, 0x02, 0x00, 0x54, 0xe3,
+ 0x0c, 0x20, 0x82, 0xe3, 0x00, 0x20, 0x83, 0xe5, 0x2c, 0x40, 0x9f, 0x05, 0x04, 0x00, 0x00, 0x0a,
+ 0x2c, 0x30, 0x9f, 0xe5, 0x24, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3, 0x02, 0x40, 0xa0, 0x01,
+ 0x03, 0x40, 0xa0, 0x11, 0x01, 0x30, 0xa0, 0xe3, 0x00, 0x30, 0x84, 0xe5, 0x10, 0x80, 0xbd, 0xe8,
+ 0x08, 0x00, 0x20, 0x3d, 0x08, 0x00, 0xe0, 0x3c, 0x08, 0x00, 0x30, 0x3c, 0x00, 0x00, 0x20, 0x3d,
+ 0x00, 0x00, 0xe0, 0x3c, 0x00, 0x00, 0x30, 0x3c, 0x30, 0x00, 0x20, 0x3d, 0x30, 0x00, 0xe0, 0x3c,
+ 0x30, 0x00, 0x30, 0x3c, 0xac, 0x17, 0x00, 0x22, 0x0c, 0x00, 0x20, 0x3d, 0x0c, 0x00, 0xe0, 0x3c,
+ 0x0c, 0x00, 0x30, 0x3c, 0x04, 0x00, 0x20, 0x3d, 0x04, 0x00, 0xe0, 0x3c, 0x04, 0x00, 0x30, 0x3c,
+ 0x18, 0x06, 0x01, 0x00, 0x0c, 0x30, 0x80, 0xe2, 0x02, 0xc0, 0xd3, 0xe5, 0x01, 0x10, 0xd3, 0xe5,
+ 0x0c, 0x20, 0xd0, 0xe5, 0x03, 0x30, 0xd3, 0xe5, 0x0c, 0x08, 0xa0, 0xe1, 0x01, 0x04, 0x80, 0xe1,
+ 0x02, 0x00, 0x80, 0xe1, 0x03, 0x0c, 0x80, 0xe1, 0x5f, 0x0d, 0x80, 0xe2, 0x3f, 0x00, 0x80, 0xe2,
+ 0xff, 0x0e, 0xc0, 0xe3, 0x0f, 0x00, 0xc0, 0xe3, 0x1e, 0xff, 0x2f, 0xe1, 0x70, 0x40, 0x2d, 0xe9,
+ 0x18, 0xd0, 0x4d, 0xe2, 0x04, 0x40, 0x8d, 0xe2, 0x03, 0x50, 0xa0, 0xe1, 0x00, 0x60, 0xa0, 0xe1,
+ 0x01, 0x00, 0xa0, 0xe1, 0x02, 0x10, 0xa0, 0xe1, 0x04, 0x20, 0xa0, 0xe1, 0xf5, 0x01, 0x00, 0xeb,
+ 0x04, 0x10, 0xa0, 0xe1, 0x05, 0x00, 0xa0, 0xe1, 0x10, 0x20, 0xa0, 0xe3, 0xc2, 0x02, 0x00, 0xeb,
+ 0x06, 0x10, 0xa0, 0xe1, 0x05, 0x20, 0xa0, 0xe1, 0x01, 0x00, 0xa0, 0xe3, 0x10, 0x30, 0xa0, 0xe3,
+ 0x65, 0x02, 0x00, 0xeb, 0x18, 0xd0, 0x8d, 0xe2, 0x70, 0x80, 0xbd, 0xe8, 0x01, 0x00, 0x50, 0xe3,
+ 0xf0, 0x47, 0x2d, 0xe9, 0x0c, 0x50, 0xd1, 0xe5, 0x0c, 0x30, 0x81, 0xe2, 0x00, 0x40, 0xa0, 0xe1,
+ 0x01, 0x00, 0xa0, 0x03, 0x02, 0x00, 0xa0, 0x13, 0x03, 0x80, 0xd3, 0xe5, 0x02, 0x70, 0xd3, 0xe5,
+ 0x01, 0x60, 0xd3, 0xe5, 0x02, 0xa0, 0xa0, 0xe1, 0x07, 0x00, 0xc1, 0xe5, 0x40, 0x30, 0x81, 0xe2,
+ 0x02, 0x00, 0xa0, 0xe3, 0x40, 0x20, 0xa0, 0xe3, 0xdb, 0xff, 0xff, 0xeb, 0x07, 0x78, 0xa0, 0xe1,
+ 0x06, 0x64, 0x87, 0xe1, 0x05, 0x50, 0x86, 0xe1, 0x08, 0x3c, 0x85, 0xe1, 0x04, 0x00, 0xa0, 0xe1,
+ 0x0a, 0x20, 0xa0, 0xe1, 0x02, 0x10, 0xa0, 0xe3, 0xf0, 0x47, 0xbd, 0xe8, 0x4a, 0x02, 0x00, 0xea,
+ 0x10, 0x40, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
+ 0xbf, 0xfe, 0xff, 0xeb, 0x05, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0xd0, 0xfe, 0xff, 0xeb,
+ 0xff, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0xcd, 0xfe, 0xff, 0xeb, 0x00, 0x10, 0xa0, 0xe3,
+ 0x01, 0x30, 0x10, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x00, 0x00, 0x0a, 0xb4, 0xfe, 0xff, 0xeb,
+ 0xf0, 0xff, 0xff, 0xea, 0x04, 0x00, 0xa0, 0xe1, 0x03, 0x10, 0xa0, 0xe1, 0x10, 0x40, 0xbd, 0xe8,
+ 0xaf, 0xfe, 0xff, 0xea, 0x70, 0x40, 0x2d, 0xe9, 0x00, 0x50, 0x51, 0xe2, 0x00, 0x40, 0xa0, 0xe1,
+ 0x07, 0x00, 0x00, 0x1a, 0x01, 0x10, 0x81, 0xe2, 0xa9, 0xfe, 0xff, 0xeb, 0x04, 0x10, 0xa0, 0xe3,
+ 0x04, 0x00, 0xa0, 0xe1, 0xba, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x05, 0x10, 0xa0, 0xe1,
+ 0xa3, 0xfe, 0xff, 0xeb, 0x01, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0xa0, 0xfe, 0xff, 0xeb,
+ 0x50, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0xb1, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
+ 0x00, 0x10, 0xa0, 0xe3, 0x9a, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
+ 0x97, 0xfe, 0xff, 0xeb, 0x01, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0xa8, 0xfe, 0xff, 0xeb,
+ 0x00, 0x00, 0x55, 0xe3, 0x1c, 0x10, 0xa0, 0x03, 0x00, 0x10, 0xa0, 0x13, 0x04, 0x00, 0xa0, 0xe1,
+ 0xa3, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0x8c, 0xfe, 0xff, 0xeb,
+ 0x00, 0x00, 0x55, 0xe3, 0x70, 0x80, 0xbd, 0x08, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
+ 0x87, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x06, 0x10, 0xa0, 0xe3, 0x98, 0xfe, 0xff, 0xeb,
+ 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0x70, 0x40, 0xbd, 0xe8, 0x80, 0xfe, 0xff, 0xea,
+ 0x70, 0x40, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x01, 0x50, 0xa0, 0xe1, 0x1d, 0xff, 0xff, 0xeb,
+ 0x04, 0x00, 0xa0, 0xe1, 0xb5, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
+ 0xc7, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0x74, 0xfe, 0xff, 0xeb,
+ 0x04, 0x00, 0xa0, 0xe1, 0x20, 0x10, 0xa0, 0xe3, 0x85, 0xfe, 0xff, 0xeb, 0x25, 0x18, 0xa0, 0xe1,
+ 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x81, 0xfe, 0xff, 0xeb, 0x25, 0x14, 0xa0, 0xe1,
+ 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x7d, 0xfe, 0xff, 0xeb, 0xff, 0x10, 0x05, 0xe2,
+ 0x04, 0x00, 0xa0, 0xe1, 0x7a, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3,
+ 0x63, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0xb0, 0xff, 0xff, 0xeb,
+ 0x04, 0x00, 0xa0, 0xe1, 0x70, 0x40, 0xbd, 0xe8, 0xf6, 0xfe, 0xff, 0xea, 0xf0, 0x45, 0x2d, 0xe9,
+ 0x00, 0x40, 0xa0, 0xe1, 0x24, 0xd0, 0x4d, 0xe2, 0x02, 0x50, 0xa0, 0xe1, 0x03, 0x70, 0xa0, 0xe1,
+ 0x01, 0x60, 0xa0, 0xe1, 0xf7, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x8f, 0xff, 0xff, 0xeb,
+ 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0x51, 0xfe, 0xff, 0xeb, 0x03, 0x10, 0xa0, 0xe3,
+ 0x04, 0x00, 0xa0, 0xe1, 0x62, 0xfe, 0xff, 0xeb, 0x26, 0x18, 0xa0, 0xe1, 0xff, 0x10, 0x01, 0xe2,
+ 0x04, 0x00, 0xa0, 0xe1, 0x5e, 0xfe, 0xff, 0xeb, 0x26, 0x14, 0xa0, 0xe1, 0xff, 0x10, 0x01, 0xe2,
+ 0x04, 0x00, 0xa0, 0xe1, 0x5a, 0xfe, 0xff, 0xeb, 0xff, 0x10, 0x06, 0xe2, 0x04, 0x00, 0xa0, 0xe1,
+ 0x57, 0xfe, 0xff, 0xeb, 0x00, 0x60, 0xa0, 0xe3, 0x0d, 0x80, 0xa0, 0xe1, 0x15, 0x00, 0x00, 0xea,
+ 0x20, 0x00, 0x57, 0xe3, 0x07, 0xa0, 0xa0, 0xb1, 0x20, 0xa0, 0xa0, 0xa3, 0x04, 0x00, 0xa0, 0xe1,
+ 0x0a, 0x10, 0xa0, 0xe1, 0x0d, 0x20, 0xa0, 0xe1, 0x8c, 0xfe, 0xff, 0xeb, 0x05, 0x00, 0xa0, 0xe1,
+ 0x0d, 0x10, 0xa0, 0xe1, 0x0a, 0x20, 0xa0, 0xe1, 0xac, 0xfd, 0xff, 0xeb, 0x00, 0x30, 0xa0, 0xe3,
+ 0x00, 0x00, 0x50, 0xe3, 0x01, 0x60, 0x86, 0x13, 0x03, 0x20, 0xd8, 0xe7, 0x02, 0x30, 0x83, 0xe2,
+ 0xff, 0x00, 0x52, 0xe3, 0x02, 0x60, 0x86, 0x13, 0x0a, 0x00, 0x53, 0xe1, 0xf9, 0xff, 0xff, 0xba,
+ 0x20, 0x50, 0x85, 0xe2, 0x20, 0x70, 0x47, 0xe2, 0x00, 0x00, 0x57, 0xe3, 0xe7, 0xff, 0xff, 0xca,
+ 0x00, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0x25, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
+ 0xbc, 0xfe, 0xff, 0xeb, 0x06, 0x00, 0xa0, 0xe1, 0x24, 0xd0, 0x8d, 0xe2, 0xf0, 0x85, 0xbd, 0xe8,
+ 0xf0, 0x4f, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x14, 0xd0, 0x4d, 0xe2, 0x01, 0x50, 0xa0, 0xe1,
+ 0x02, 0x70, 0xa0, 0xe1, 0x03, 0x80, 0xa0, 0xe1, 0x53, 0x00, 0x00, 0xea, 0x05, 0x6a, 0xa0, 0xe1,
+ 0x26, 0x6a, 0xa0, 0xe1, 0x01, 0x6a, 0x66, 0xe2, 0x08, 0x00, 0x56, 0xe1, 0x08, 0x60, 0xa0, 0xa1,
+ 0x04, 0x00, 0xa0, 0xe1, 0x05, 0x10, 0xa0, 0xe1, 0x07, 0x20, 0xa0, 0xe1, 0x06, 0x30, 0xa0, 0xe1,
+ 0xb1, 0xff, 0xff, 0xeb, 0x01, 0x00, 0x10, 0xe3, 0x44, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x10, 0xe3,
+ 0x03, 0x00, 0x00, 0x0a, 0xff, 0x1e, 0xc5, 0xe3, 0x0f, 0x10, 0xc1, 0xe3, 0x04, 0x00, 0xa0, 0xe1,
+ 0x86, 0xff, 0xff, 0xeb, 0x00, 0x30, 0xa0, 0xe3, 0x03, 0x20, 0xd7, 0xe7, 0x07, 0x90, 0xa0, 0xe1,
+ 0xff, 0x00, 0x52, 0xe3, 0x01, 0x30, 0x83, 0xe2, 0x02, 0x00, 0x00, 0x1a, 0x06, 0x00, 0x53, 0xe1,
+ 0xf8, 0xff, 0xff, 0xba, 0x35, 0x00, 0x00, 0xea, 0x04, 0x00, 0xa0, 0xe1, 0x9d, 0xfe, 0xff, 0xeb,
+ 0x04, 0x00, 0xa0, 0xe1, 0x35, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
+ 0x47, 0xff, 0xff, 0xeb, 0x25, 0x34, 0xa0, 0xe1, 0xff, 0x30, 0x03, 0xe2, 0x25, 0x28, 0xa0, 0xe1,
+ 0xff, 0x20, 0x02, 0xe2, 0x08, 0x30, 0x8d, 0xe5, 0x06, 0xa0, 0xa0, 0xe1, 0xff, 0x30, 0x05, 0xe2,
+ 0x01, 0xb0, 0xa0, 0xe3, 0x04, 0x20, 0x8d, 0xe5, 0x0c, 0x30, 0x8d, 0xe5, 0x04, 0x00, 0xa0, 0xe1,
+ 0x01, 0x10, 0xa0, 0xe3, 0xea, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0xad, 0x10, 0xa0, 0xe3,
+ 0xfb, 0xfd, 0xff, 0xeb, 0x00, 0x00, 0x5b, 0xe3, 0x00, 0xb0, 0xa0, 0xe3, 0x08, 0x00, 0x00, 0x0a,
+ 0x04, 0x10, 0x9d, 0xe5, 0x04, 0x00, 0xa0, 0xe1, 0xf5, 0xfd, 0xff, 0xeb, 0x08, 0x10, 0x9d, 0xe5,
+ 0x04, 0x00, 0xa0, 0xe1, 0xf2, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x0c, 0x10, 0x9d, 0xe5,
+ 0xef, 0xfd, 0xff, 0xeb, 0x00, 0x10, 0xd9, 0xe5, 0x04, 0x00, 0xa0, 0xe1, 0xec, 0xfd, 0xff, 0xeb,
+ 0x01, 0x10, 0xd9, 0xe5, 0x04, 0x00, 0xa0, 0xe1, 0xe9, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
+ 0x00, 0x10, 0xa0, 0xe3, 0xd2, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x0b, 0xff, 0xff, 0xeb,
+ 0x02, 0xa0, 0x5a, 0xe2, 0x02, 0x90, 0x89, 0xe2, 0xdf, 0xff, 0xff, 0x1a, 0x04, 0x00, 0xa0, 0xe1,
+ 0x0a, 0x10, 0xa0, 0xe1, 0x1a, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x61, 0xfe, 0xff, 0xeb,
+ 0x08, 0x80, 0x66, 0xe0, 0x06, 0x70, 0x87, 0xe0, 0x06, 0x50, 0x85, 0xe0, 0x00, 0x00, 0x58, 0xe3,
+ 0xa9, 0xff, 0xff, 0xca, 0x14, 0xd0, 0x8d, 0xe2, 0xf0, 0x8f, 0xbd, 0xe8, 0xf0, 0x41, 0x2d, 0xe9,
+ 0x00, 0x40, 0xa0, 0xe1, 0x03, 0x50, 0xa0, 0xe1, 0x02, 0x70, 0xa0, 0xe1, 0x01, 0x60, 0xa0, 0xe1,
+ 0x5c, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0xf4, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
+ 0x01, 0x10, 0xa0, 0xe3, 0xb6, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x03, 0x10, 0xa0, 0xe3,
+ 0xc7, 0xfd, 0xff, 0xeb, 0x26, 0x18, 0xa0, 0xe1, 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1,
+ 0xc3, 0xfd, 0xff, 0xeb, 0x26, 0x14, 0xa0, 0xe1, 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1,
+ 0xbf, 0xfd, 0xff, 0xeb, 0xff, 0x10, 0x06, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0xbc, 0xfd, 0xff, 0xeb,
+ 0x04, 0x00, 0xa0, 0xe1, 0x07, 0x10, 0xa0, 0xe1, 0x05, 0x20, 0xa0, 0xe1, 0xf7, 0xfd, 0xff, 0xeb,
+ 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0xa1, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
+ 0xf0, 0x41, 0xbd, 0xe8, 0x37, 0xfe, 0xff, 0xea, 0x00, 0x10, 0xa0, 0xe3, 0x77, 0xfd, 0xff, 0xea,
+ 0x10, 0x40, 0x2d, 0xe9, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x40, 0xa0, 0xe1, 0x73, 0xfd, 0xff, 0xeb,
+ 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0x10, 0x40, 0xbd, 0xe8, 0x94, 0xfd, 0xff, 0xea,
+ 0xf0, 0x40, 0x2d, 0xe9, 0x6c, 0x40, 0x9f, 0xe5, 0x2c, 0xd0, 0x4d, 0xe2, 0x00, 0x00, 0xa0, 0xe3,
+ 0xf2, 0xff, 0xff, 0xeb, 0x60, 0x70, 0x9f, 0xe5, 0x04, 0x50, 0xa0, 0xe1, 0x0d, 0x60, 0xa0, 0xe1,
+ 0x04, 0x10, 0xa0, 0xe1, 0x28, 0x20, 0xa0, 0xe3, 0x0d, 0x30, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3,
+ 0xc5, 0xff, 0xff, 0xeb, 0x0d, 0x00, 0xa0, 0xe1, 0x40, 0x10, 0x9f, 0xe5, 0x04, 0x20, 0xa0, 0xe3,
+ 0xfa, 0xfc, 0xff, 0xeb, 0x28, 0x40, 0x84, 0xe2, 0x00, 0x00, 0x50, 0xe3, 0x04, 0x00, 0x00, 0x1a,
+ 0x0c, 0x30, 0x9d, 0xe5, 0x03, 0x00, 0x55, 0xe1, 0x03, 0x50, 0xa0, 0x21, 0x07, 0x00, 0x54, 0xe1,
+ 0xee, 0xff, 0xff, 0x1a, 0x00, 0x00, 0xa0, 0xe3, 0xda, 0xff, 0xff, 0xeb, 0x0a, 0x09, 0x45, 0xe2,
+ 0x2c, 0xd0, 0x8d, 0xe2, 0xf0, 0x80, 0xbd, 0xe8, 0x00, 0xfe, 0x0f, 0x00, 0xe0, 0xff, 0x0f, 0x00,
+ 0xb8, 0x17, 0x00, 0x22, 0x0c, 0x30, 0x81, 0xe2, 0x70, 0x40, 0x2d, 0xe9, 0x02, 0x50, 0xd3, 0xe5,
+ 0x01, 0x40, 0xa0, 0xe1, 0x01, 0x10, 0xd3, 0xe5, 0x0c, 0x20, 0xd4, 0xe5, 0x03, 0x30, 0xd3, 0xe5,
+ 0x05, 0x58, 0xa0, 0xe1, 0x01, 0x54, 0x85, 0xe1, 0x02, 0x50, 0x85, 0xe1, 0x03, 0x5c, 0x85, 0xe1,
+ 0x00, 0x60, 0xa0, 0xe1, 0x02, 0x5b, 0x85, 0xe2, 0x00, 0x00, 0xa0, 0xe3, 0xc7, 0xff, 0xff, 0xeb,
+ 0x06, 0x10, 0xa0, 0xe1, 0x04, 0x20, 0xa0, 0xe1, 0x05, 0x30, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3,
+ 0x3e, 0xff, 0xff, 0xeb, 0x04, 0x20, 0xa0, 0xe1, 0x06, 0x10, 0xa0, 0xe1, 0x05, 0x30, 0xa0, 0xe1,
+ 0x00, 0x00, 0xa0, 0xe3, 0xfc, 0xfe, 0xff, 0xeb, 0x00, 0x40, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3,
+ 0xb8, 0xff, 0xff, 0xeb, 0x01, 0x00, 0x24, 0xe2, 0x01, 0x00, 0x00, 0xe2, 0x70, 0x80, 0xbd, 0xe8,
+ 0xf0, 0x45, 0x2d, 0xe9, 0x01, 0x40, 0xa0, 0xe1, 0x14, 0xd0, 0x4d, 0xe2, 0x00, 0x80, 0xa0, 0xe1,
+ 0x00, 0x00, 0xa0, 0xe3, 0x02, 0x60, 0xa0, 0xe1, 0xb0, 0xff, 0xff, 0xeb, 0x08, 0x10, 0xa0, 0xe1,
+ 0x02, 0x2b, 0xa0, 0xe3, 0x04, 0x30, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3, 0x86, 0xff, 0xff, 0xeb,
+ 0x00, 0x00, 0xa0, 0xe3, 0xa7, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x40, 0x11, 0x9f, 0xe5,
+ 0x04, 0x20, 0xa0, 0xe3, 0xb9, 0xfc, 0xff, 0xeb, 0x00, 0x00, 0x50, 0xe3, 0x00, 0x00, 0xe0, 0x13,
+ 0x49, 0x00, 0x00, 0x1a, 0x04, 0x10, 0xa0, 0xe1, 0x40, 0x20, 0xa0, 0xe3, 0x0d, 0x30, 0xa0, 0xe1,
+ 0x02, 0x00, 0xa0, 0xe3, 0x48, 0xfe, 0xff, 0xeb, 0x0d, 0x00, 0xa0, 0xe1, 0x40, 0x10, 0x84, 0xe2,
+ 0x10, 0x20, 0xa0, 0xe3, 0xad, 0xfc, 0xff, 0xeb, 0x0d, 0x50, 0xa0, 0xe1, 0x00, 0x70, 0x50, 0xe2,
+ 0x01, 0x00, 0xe0, 0x13, 0x3c, 0x00, 0x00, 0x1a, 0x0c, 0x30, 0x84, 0xe2, 0x02, 0x50, 0xd3, 0xe5,
+ 0x01, 0x10, 0xd3, 0xe5, 0x0c, 0x20, 0xd4, 0xe5, 0x05, 0x58, 0xa0, 0xe1, 0x03, 0x30, 0xd3, 0xe5,
+ 0x01, 0x54, 0x85, 0xe1, 0x02, 0x50, 0x85, 0xe1, 0x03, 0x5c, 0x85, 0xe1, 0x7e, 0x0b, 0x55, 0xe3,
+ 0x2e, 0x00, 0x00, 0x8a, 0x08, 0x30, 0x84, 0xe2, 0x02, 0xc0, 0xd3, 0xe5, 0x01, 0xa0, 0xd3, 0xe5,
+ 0x08, 0x10, 0xd4, 0xe5, 0x03, 0x20, 0xd3, 0xe5, 0x0c, 0xc8, 0xa0, 0xe1, 0x0a, 0x34, 0x8c, 0xe1,
+ 0x01, 0x30, 0x83, 0xe1, 0x02, 0x3c, 0x83, 0xe1, 0x05, 0x00, 0x53, 0xe1, 0x23, 0x00, 0x00, 0x8a,
+ 0x07, 0x30, 0xd4, 0xe5, 0x01, 0x30, 0x43, 0xe2, 0x01, 0x00, 0x53, 0xe3, 0x03, 0x00, 0xe0, 0x83,
+ 0x21, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x56, 0xe3, 0x1e, 0x00, 0x00, 0x0a, 0x77, 0xff, 0xff, 0xeb,
+ 0x06, 0x30, 0xa0, 0xe1, 0x07, 0x00, 0xa0, 0xe1, 0x02, 0x1b, 0x88, 0xe2, 0x05, 0x20, 0xa0, 0xe1,
+ 0x4d, 0xff, 0xff, 0xeb, 0x07, 0x00, 0xa0, 0xe1, 0x6e, 0xff, 0xff, 0xeb, 0x07, 0x30, 0xd4, 0xe5,
+ 0x01, 0x00, 0x53, 0xe3, 0x03, 0x00, 0x00, 0x1a, 0x07, 0x00, 0xa0, 0xe1, 0x04, 0x10, 0xa0, 0xe1,
+ 0x06, 0x20, 0xa0, 0xe1, 0x28, 0xfe, 0xff, 0xeb, 0x06, 0x10, 0xa0, 0xe1, 0x05, 0x20, 0xa0, 0xe1,
+ 0x0d, 0x30, 0xa0, 0xe1, 0x02, 0x00, 0xa0, 0xe3, 0x0f, 0xfe, 0xff, 0xeb, 0x0d, 0x00, 0xa0, 0xe1,
+ 0x10, 0x10, 0x84, 0xe2, 0x10, 0x20, 0xa0, 0xe3, 0x74, 0xfc, 0xff, 0xeb, 0x0d, 0x70, 0xa0, 0xe1,
+ 0x00, 0x00, 0x50, 0xe3, 0x04, 0x00, 0xe0, 0x13, 0x02, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x00, 0xea,
+ 0x02, 0x00, 0xe0, 0xe3, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0xa0, 0xe3, 0x14, 0xd0, 0x8d, 0xe2,
+ 0xf0, 0x85, 0xbd, 0xe8, 0xbd, 0x17, 0x00, 0x22, 0xf0, 0x4f, 0x2d, 0xe9, 0x00, 0x50, 0xa0, 0xe1,
+ 0x54, 0xd0, 0x4d, 0xe2, 0x01, 0x40, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3, 0x01, 0x10, 0xa0, 0xe3,
+ 0x02, 0x60, 0xa0, 0xe1, 0x70, 0xfc, 0xff, 0xeb, 0x0e, 0x23, 0xa0, 0xe3, 0x01, 0x10, 0xa0, 0xe3,
+ 0x02, 0xc0, 0xa0, 0xe1, 0x10, 0x30, 0x8d, 0xe2, 0x04, 0x10, 0x82, 0xe5, 0x00, 0x00, 0x9c, 0xe5,
+ 0x0e, 0x23, 0xa0, 0xe3, 0x01, 0x00, 0x10, 0xe2, 0xfb, 0xff, 0xff, 0x1a, 0x40, 0xc0, 0x64, 0xe2,
+ 0xa4, 0x72, 0xa0, 0xe1, 0x84, 0xe1, 0xa0, 0xe1, 0x7c, 0x81, 0x9f, 0xe5, 0xa4, 0xaa, 0xa0, 0xe1,
+ 0xa4, 0x96, 0xa0, 0xe1, 0xff, 0x70, 0x07, 0xe2, 0xff, 0xe0, 0x0e, 0xe2, 0x0c, 0xc0, 0x65, 0xe0,
+ 0xff, 0x90, 0x09, 0xe2, 0x04, 0x70, 0x8d, 0xe5, 0x00, 0xe0, 0x8d, 0xe5, 0x0c, 0xc0, 0x8d, 0xe5,
+ 0x02, 0x10, 0xa0, 0xe1, 0xff, 0xa0, 0x0a, 0xe2, 0x00, 0x70, 0xa0, 0xe1, 0xa4, 0x4e, 0xa0, 0xe1,
+ 0x10, 0xc0, 0x8d, 0xe2, 0x02, 0xe0, 0xa0, 0xe1, 0x04, 0x00, 0x82, 0xe5, 0x08, 0x90, 0x8d, 0xe5,
+ 0x00, 0x00, 0x82, 0xe5, 0x0c, 0x20, 0x9d, 0xe5, 0x02, 0x00, 0x85, 0xe0, 0x00, 0x00, 0x50, 0xe3,
+ 0x25, 0x00, 0x00, 0xda, 0x00, 0x20, 0xa0, 0xe3, 0x02, 0x70, 0x8c, 0xe7, 0x04, 0x20, 0x82, 0xe2,
+ 0x40, 0x00, 0x52, 0xe3, 0xfb, 0xff, 0xff, 0x1a, 0x40, 0x00, 0x50, 0xe3, 0x07, 0x20, 0xa0, 0xd1,
+ 0x40, 0x90, 0x60, 0xd2, 0x03, 0x00, 0x00, 0xda, 0x09, 0x00, 0x00, 0xea, 0x02, 0xb0, 0xd5, 0xe7,
+ 0x02, 0xb0, 0xcc, 0xe7, 0x01, 0x20, 0x82, 0xe2, 0x09, 0x00, 0x52, 0xe1, 0xfa, 0xff, 0xff, 0xba,
+ 0x07, 0x00, 0x50, 0xe3, 0x7f, 0x20, 0xe0, 0xe3, 0x09, 0x20, 0xc3, 0xe7, 0x00, 0x00, 0xa0, 0xd3,
+ 0x08, 0x00, 0x00, 0xda, 0x3b, 0x40, 0xc3, 0xe5, 0x3c, 0xa0, 0xc3, 0xe5, 0x08, 0x20, 0x9d, 0xe5,
+ 0x01, 0x00, 0xa0, 0xe3, 0x3d, 0x20, 0xc3, 0xe5, 0x04, 0x20, 0x9d, 0xe5, 0x3e, 0x20, 0xc3, 0xe5,
+ 0x00, 0x20, 0x9d, 0xe5, 0x3f, 0x20, 0xc3, 0xe5, 0xb0, 0x20, 0x9f, 0xe5, 0x02, 0x90, 0x8c, 0xe0,
+ 0x32, 0x93, 0x89, 0xe2, 0x40, 0x90, 0x49, 0xe2, 0x00, 0x90, 0x99, 0xe5, 0x04, 0x90, 0x82, 0xe4,
+ 0x08, 0x00, 0x52, 0xe1, 0xf8, 0xff, 0xff, 0x1a, 0x09, 0x00, 0x00, 0xea, 0x8c, 0x20, 0x9f, 0xe5,
+ 0x02, 0x00, 0x85, 0xe0, 0x32, 0x03, 0x80, 0xe2, 0x40, 0x00, 0x40, 0xe2, 0x00, 0x00, 0x90, 0xe5,
+ 0x04, 0x00, 0x82, 0xe4, 0x08, 0x00, 0x52, 0xe1, 0xf8, 0xff, 0xff, 0x1a, 0x40, 0x50, 0x85, 0xe2,
+ 0x00, 0x00, 0xa0, 0xe3, 0x00, 0x20, 0x91, 0xe5, 0x02, 0x20, 0x82, 0xe3, 0x00, 0x20, 0x81, 0xe5,
+ 0x00, 0x20, 0x91, 0xe5, 0x01, 0x00, 0x12, 0xe3, 0xfc, 0xff, 0xff, 0x1a, 0x00, 0x20, 0x9e, 0xe5,
+ 0x00, 0x00, 0x50, 0xe3, 0x08, 0x20, 0x82, 0xe3, 0x00, 0x20, 0x8e, 0xe5, 0xc0, 0xff, 0xff, 0x0a,
+ 0x3c, 0x30, 0x9f, 0xe5, 0x3c, 0x10, 0x9f, 0xe5, 0x03, 0x20, 0xa0, 0xe1, 0x06, 0x00, 0x92, 0xe6,
+ 0x04, 0x30, 0x83, 0xe2, 0x32, 0x23, 0x82, 0xe2, 0x20, 0x20, 0x42, 0xe2, 0x01, 0x00, 0x53, 0xe1,
+ 0x00, 0x00, 0x82, 0xe5, 0xf7, 0xff, 0xff, 0x1a, 0x00, 0x00, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe1,
+ 0x05, 0xfc, 0xff, 0xeb, 0x54, 0xd0, 0x8d, 0xe2, 0xf0, 0x8f, 0xbd, 0xe8, 0x80, 0x00, 0x00, 0x38,
+ 0x40, 0x00, 0x00, 0x38, 0x20, 0x00, 0x00, 0x38, 0x34, 0x00, 0x00, 0x38, 0xf0, 0x47, 0x2d, 0xe9,
+ 0x00, 0x40, 0xa0, 0xe1, 0x01, 0x50, 0xa0, 0xe1, 0x0a, 0x00, 0xa0, 0xe3, 0x01, 0x10, 0xa0, 0xe3,
+ 0xe3, 0x85, 0xa0, 0xe3, 0x03, 0x60, 0xa0, 0xe1, 0x02, 0x70, 0xa0, 0xe1, 0x01, 0xa0, 0xa0, 0xe3,
+ 0xf5, 0xfb, 0xff, 0xeb, 0x00, 0x30, 0xa0, 0xe3, 0x74, 0x30, 0x88, 0xe5, 0x78, 0x30, 0x88, 0xe5,
+ 0x7c, 0x30, 0x88, 0xe5, 0x80, 0x30, 0x88, 0xe5, 0x08, 0xa0, 0x88, 0xe5, 0x08, 0x30, 0x88, 0xe5,
+ 0x00, 0xa0, 0x88, 0xe5, 0x10, 0x30, 0x88, 0xe5, 0x6c, 0x50, 0x88, 0xe5, 0x6c, 0x20, 0x98, 0xe5,
+ 0x0a, 0x00, 0x54, 0xe1, 0x09, 0x40, 0xa0, 0x03, 0x08, 0x40, 0xa0, 0x13, 0x02, 0x20, 0xe0, 0xe1,
+ 0x88, 0x20, 0x88, 0xe5, 0x8c, 0x30, 0x88, 0xe5, 0x14, 0x40, 0x88, 0xe5, 0x18, 0x60, 0x88, 0xe5,
+ 0x20, 0x70, 0x88, 0xe5, 0x24, 0x60, 0x88, 0xe5, 0x28, 0x70, 0x88, 0xe5, 0x2c, 0x60, 0x88, 0xe5,
+ 0x30, 0x70, 0x88, 0xe5, 0x34, 0x60, 0x88, 0xe5, 0x3c, 0x00, 0x00, 0xeb, 0x08, 0x30, 0xa0, 0xe1,
+ 0x04, 0xa0, 0x88, 0xe5, 0x0c, 0x20, 0x93, 0xe5, 0x0f, 0x00, 0x12, 0xe3, 0xfc, 0xff, 0xff, 0x0a,
+ 0x0a, 0x00, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0xf0, 0x47, 0xbd, 0xe8, 0xd2, 0xfb, 0xff, 0xea,
+ 0x98, 0x30, 0x9f, 0xe5, 0xf0, 0x45, 0x2d, 0xe9, 0x94, 0xc0, 0x9f, 0xe5, 0xfa, 0x4f, 0xa0, 0xe3,
+ 0x03, 0x60, 0xa0, 0xe1, 0x8c, 0x50, 0x9f, 0xe5, 0x1c, 0x00, 0x00, 0xea, 0xb4, 0x10, 0x93, 0xe5,
+ 0xb2, 0x80, 0xd0, 0xe1, 0xa2, 0xa0, 0xa0, 0xe1, 0x94, 0x18, 0x27, 0xe0, 0x00, 0x20, 0xa0, 0xe3,
+ 0x09, 0x00, 0x00, 0xea, 0x01, 0x20, 0x22, 0xe2, 0x06, 0x1c, 0x82, 0xe3, 0x0e, 0x10, 0x81, 0xe3,
+ 0x00, 0x12, 0x8c, 0xe5, 0xb4, 0x10, 0x93, 0xe5, 0x01, 0x10, 0x8a, 0xe0, 0xb4, 0x80, 0x93, 0xe5,
+ 0x08, 0x80, 0x61, 0xe0, 0x00, 0x00, 0x58, 0xe3, 0xfb, 0xff, 0xff, 0xba, 0xb4, 0x10, 0x93, 0xe5,
+ 0x01, 0x10, 0x67, 0xe0, 0x00, 0x00, 0x51, 0xe3, 0xf1, 0xff, 0xff, 0xba, 0x00, 0x52, 0x8c, 0xe5,
+ 0xb4, 0x70, 0xd0, 0xe1, 0xb4, 0x10, 0x96, 0xe5, 0x94, 0x17, 0x22, 0xe0, 0xb4, 0x10, 0x93, 0xe5,
+ 0x01, 0x10, 0x62, 0xe0, 0x00, 0x00, 0x51, 0xe3, 0xfb, 0xff, 0xff, 0xba, 0x06, 0x00, 0x80, 0xe2,
+ 0xb0, 0x20, 0xd0, 0xe1, 0x00, 0x00, 0x52, 0xe3, 0xdf, 0xff, 0xff, 0x1a, 0xf0, 0x85, 0xbd, 0xe8,
+ 0x00, 0x00, 0x70, 0x3c, 0x00, 0x00, 0xf0, 0x3c, 0x0e, 0x06, 0x00, 0x00, 0x00, 0x30, 0xa0, 0xe3,
+ 0x02, 0x00, 0x00, 0xea, 0x03, 0xc0, 0xd1, 0xe7, 0x03, 0xc0, 0xc0, 0xe7, 0x01, 0x30, 0x83, 0xe2,
+ 0x00, 0x00, 0x52, 0xe3, 0x01, 0x20, 0x42, 0xe2, 0xf9, 0xff, 0xff, 0x1a, 0x1e, 0xff, 0x2f, 0xe1,
+ 0x7e, 0xff, 0x17, 0xee, 0xfd, 0xff, 0xff, 0x1a, 0x00, 0x10, 0xa0, 0xe3, 0x9a, 0x1f, 0x07, 0xee,
+ 0x1e, 0xff, 0x2f, 0xe1, 0xb8, 0x0b, 0xf4, 0x01, 0xf4, 0x01, 0xb8, 0x0b, 0xf4, 0x01, 0xf4, 0x01,
+ 0xb8, 0x0b, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x76, 0xdc, 0x1d, 0x32, 0xb2, 0x46,
+ 0xa6, 0xc9, 0x7d, 0x5a, 0x61, 0xd3, 0x49, 0x4c, 0x1e, 0xf0, 0xd9, 0xde, 0xc2, 0x7e, 0xec, 0x02,
+ 0x7c, 0x15, 0x76, 0xbb, 0x5c, 0x4f, 0x2d, 0x95, 0x06, 0x85, 0xdf, 0x28, 0xe4, 0xd7, 0xf4, 0x82,
+ 0xc0, 0x73, 0xb0, 0x53, 0x26, 0xfc, 0xb0, 0xfe, 0x60, 0x80, 0x7d, 0x33, 0xa8, 0xde, 0xf8, 0x49,
+ 0xbb, 0xbe, 0x01, 0x45, 0xff, 0x62, 0x40, 0x19, 0xf4, 0x01, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xe8, 0x03, 0x64, 0x00, 0x00, 0x00, 0xf4, 0x01, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x68, 0x73, 0x6c, 0x66,
+ 0x00, 0x38, 0x37, 0x30, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x38, 0x37, 0x30, 0x32, 0x31, 0x2e, 0x30, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+};
+unsigned char dualboot_uninstall_ipod6g[5076] = {
+ 0xd7, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x24, 0xd0, 0x9f, 0xe5, 0xdb, 0x00, 0xa0, 0xe3,
+ 0x00, 0xf0, 0x21, 0xe1, 0x18, 0xd0, 0x9f, 0xe5, 0xd3, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1,
+ 0x10, 0xd0, 0x9f, 0xe5, 0x05, 0x08, 0xa0, 0xe3, 0x78, 0x00, 0x80, 0xe3, 0x10, 0x0f, 0x01, 0xee,
+ 0x1d, 0x00, 0x00, 0xeb, 0x0c, 0x03, 0x00, 0x22, 0x0c, 0x03, 0x00, 0x22, 0x7f, 0x40, 0x2d, 0xe9,
+ 0x5c, 0x10, 0x9f, 0xe5, 0x10, 0x20, 0xa0, 0xe3, 0x0d, 0x00, 0xa0, 0xe1, 0xaf, 0x04, 0x00, 0xeb,
+ 0x00, 0x00, 0xa0, 0xe3, 0x02, 0x10, 0xa0, 0xe3, 0x0d, 0x20, 0xa0, 0xe1, 0x10, 0x30, 0xa0, 0xe3,
+ 0x52, 0x04, 0x00, 0xeb, 0x3c, 0x60, 0x9f, 0xe5, 0x0d, 0x40, 0xa0, 0xe1, 0x00, 0x50, 0xa0, 0xe3,
+ 0x06, 0x10, 0xa0, 0xe1, 0x0d, 0x00, 0xa0, 0xe1, 0x10, 0x20, 0xa0, 0xe3, 0x50, 0x00, 0x00, 0xeb,
+ 0x10, 0x60, 0x86, 0xe2, 0x00, 0x00, 0x50, 0xe3, 0x02, 0x00, 0x00, 0x0a, 0x01, 0x50, 0x85, 0xe2,
+ 0x04, 0x00, 0x55, 0xe3, 0xf5, 0xff, 0xff, 0x1a, 0x05, 0x00, 0xa0, 0xe1, 0x10, 0xd0, 0x8d, 0xe2,
+ 0x70, 0x80, 0xbd, 0xe8, 0x10, 0x00, 0x02, 0x22, 0x68, 0x16, 0x00, 0x22, 0x70, 0x40, 0x2d, 0xe9,
+ 0x87, 0x00, 0x00, 0xeb, 0xe8, 0x00, 0x9f, 0xe5, 0x69, 0x04, 0x00, 0xeb, 0x00, 0x00, 0xa0, 0xe3,
+ 0x04, 0x10, 0xa0, 0xe3, 0x9e, 0x00, 0x00, 0xeb, 0x02, 0x09, 0xa0, 0xe3, 0xd4, 0x10, 0x9f, 0xe5,
+ 0x00, 0x20, 0xa0, 0xe3, 0x5a, 0x03, 0x00, 0xeb, 0x00, 0x00, 0x50, 0xe3, 0x25, 0x00, 0x00, 0x1a,
+ 0xd5, 0xff, 0xff, 0xeb, 0x04, 0x00, 0x50, 0xe3, 0x20, 0x00, 0x00, 0x1a, 0xb4, 0x00, 0x9f, 0xe5,
+ 0xbc, 0x01, 0x00, 0xeb, 0xac, 0x10, 0x9f, 0xe5, 0xac, 0x20, 0x9f, 0xe5, 0x00, 0x50, 0xa0, 0xe1,
+ 0x02, 0x09, 0x80, 0xe2, 0x4e, 0x03, 0x00, 0xeb, 0x00, 0x40, 0x50, 0xe2, 0x19, 0x00, 0x00, 0x1a,
+ 0xc9, 0xff, 0xff, 0xeb, 0x04, 0x00, 0x50, 0xe3, 0x16, 0x00, 0x00, 0x0a, 0x01, 0x00, 0xa0, 0xe3,
+ 0x80, 0x10, 0x9f, 0xe5, 0x80, 0x20, 0x9f, 0xe5, 0xd0, 0x01, 0x00, 0xeb, 0x02, 0x09, 0xa0, 0xe3,
+ 0x70, 0x10, 0x9f, 0xe5, 0x23, 0x03, 0x00, 0xeb, 0x00, 0x00, 0x50, 0xe3, 0x6c, 0x00, 0x9f, 0x05,
+ 0x0d, 0x00, 0x00, 0x0a, 0x04, 0x00, 0xa0, 0xe1, 0x16, 0x03, 0x00, 0xeb, 0x54, 0x00, 0x9f, 0xe5,
+ 0xa4, 0x01, 0x00, 0xeb, 0x25, 0x26, 0xa0, 0xe1, 0x02, 0x19, 0x80, 0xe2, 0x21, 0x16, 0xa0, 0xe1,
+ 0x04, 0x00, 0xa0, 0xe1, 0x41, 0x02, 0x00, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x0b, 0x03, 0x00, 0xeb,
+ 0x3c, 0x00, 0x9f, 0xe5, 0x00, 0x00, 0x00, 0xea, 0x38, 0x00, 0x9f, 0xe5, 0x38, 0x20, 0x9f, 0xe5,
+ 0x38, 0x30, 0x9f, 0xe5, 0xb4, 0x10, 0x92, 0xe5, 0x03, 0x00, 0x51, 0xe1, 0xfc, 0xff, 0xff, 0x9a,
+ 0x33, 0x04, 0x00, 0xeb, 0x01, 0x26, 0xa0, 0xe3, 0xf2, 0x35, 0xa0, 0xe3, 0x00, 0x20, 0x83, 0xe5,
+ 0xfe, 0xff, 0xff, 0xea, 0xa8, 0x16, 0x00, 0x22, 0x00, 0x00, 0x02, 0x22, 0x00, 0x08, 0x02, 0x22,
+ 0x54, 0x16, 0x00, 0x22, 0xb0, 0x16, 0x00, 0x22, 0x60, 0x16, 0x00, 0x22, 0x00, 0x00, 0x70, 0x3c,
+ 0x7f, 0x84, 0x1e, 0x00, 0x10, 0x40, 0x2d, 0xe9, 0x00, 0x30, 0xa0, 0xe3, 0x07, 0x00, 0x00, 0xea,
+ 0x03, 0x40, 0xd0, 0xe7, 0x03, 0xc0, 0xd1, 0xe7, 0x01, 0x20, 0x42, 0xe2, 0x0c, 0x00, 0x54, 0xe1,
+ 0x01, 0x30, 0x83, 0xe2, 0x01, 0x00, 0x00, 0x0a, 0x04, 0x00, 0x6c, 0xe0, 0x10, 0x80, 0xbd, 0xe8,
+ 0x00, 0x00, 0x52, 0xe3, 0xf5, 0xff, 0xff, 0x1a, 0x02, 0x00, 0xa0, 0xe1, 0x10, 0x80, 0xbd, 0xe8,
+ 0x1f, 0x30, 0x00, 0xe2, 0x01, 0x20, 0xa0, 0xe3, 0xc0, 0x02, 0xa0, 0xe1, 0x00, 0x00, 0x51, 0xe3,
+ 0x12, 0x33, 0xa0, 0xe1, 0x02, 0x20, 0x00, 0xe0, 0x08, 0x00, 0x00, 0x0a, 0x3c, 0x10, 0x9f, 0xe5,
+ 0x3c, 0x00, 0x9f, 0xe5, 0x00, 0x00, 0x52, 0xe3, 0x00, 0x20, 0xa0, 0x11, 0x01, 0x20, 0xa0, 0x01,
+ 0x00, 0x10, 0x92, 0xe5, 0x03, 0x30, 0xc1, 0xe1, 0x00, 0x30, 0x82, 0xe5, 0x1e, 0xff, 0x2f, 0xe1,
+ 0x18, 0x10, 0x9f, 0xe5, 0x18, 0x00, 0x9f, 0xe5, 0x00, 0x00, 0x52, 0xe3, 0x01, 0x00, 0xa0, 0x01,
+ 0x00, 0x20, 0x90, 0xe5, 0x03, 0x30, 0x82, 0xe1, 0x00, 0x30, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1,
+ 0x48, 0x00, 0x50, 0x3c, 0x4c, 0x00, 0x50, 0x3c, 0x70, 0x40, 0x2d, 0xe9, 0x10, 0x50, 0x9d, 0xe5,
+ 0x01, 0x30, 0x43, 0xe2, 0x01, 0x50, 0x45, 0xe2, 0x03, 0x60, 0x02, 0xe2, 0x0f, 0x30, 0x03, 0xe2,
+ 0x05, 0x52, 0xa0, 0xe1, 0x03, 0xc0, 0xc0, 0xe3, 0xff, 0x50, 0x05, 0xe2, 0x06, 0x36, 0x83, 0xe1,
+ 0x00, 0x40, 0x9c, 0xe5, 0x05, 0x30, 0x83, 0xe1, 0x30, 0x50, 0x9f, 0xe5, 0x02, 0x20, 0x00, 0xe2,
+ 0x82, 0x21, 0xa0, 0xe1, 0x00, 0x00, 0x51, 0xe3, 0x02, 0x19, 0xa0, 0x03, 0x00, 0x10, 0xa0, 0x13,
+ 0x35, 0x42, 0x04, 0xe0, 0x01, 0x30, 0x83, 0xe1, 0x13, 0x22, 0x84, 0xe1, 0x00, 0x20, 0x8c, 0xe5,
+ 0xb0, 0x20, 0xd0, 0xe1, 0x03, 0x00, 0x52, 0xe1, 0xfc, 0xff, 0xff, 0x1a, 0x70, 0x80, 0xbd, 0xe8,
+ 0x00, 0x00, 0xff, 0xff, 0x5c, 0xc0, 0x9f, 0xe5, 0x13, 0x40, 0x2d, 0xe9, 0x44, 0xe0, 0x9c, 0xe5,
+ 0x01, 0x40, 0xa0, 0xe3, 0x01, 0xec, 0xce, 0xe3, 0x00, 0x20, 0xa0, 0xe3, 0x04, 0x30, 0xa0, 0xe1,
+ 0x44, 0xe0, 0x8c, 0xe5, 0x40, 0x00, 0x9f, 0xe5, 0x04, 0x10, 0xa0, 0xe1, 0x00, 0x40, 0x8d, 0xe5,
+ 0xd8, 0xff, 0xff, 0xeb, 0x04, 0x10, 0xa0, 0xe1, 0x25, 0x00, 0xa0, 0xe3, 0xbb, 0xff, 0xff, 0xeb,
+ 0x28, 0x30, 0x9f, 0xe5, 0x11, 0x2d, 0xa0, 0xe3, 0xa0, 0x20, 0x83, 0xe5, 0x0b, 0x20, 0xa0, 0xe3,
+ 0xb0, 0x20, 0x83, 0xe5, 0x00, 0x20, 0xe0, 0xe3, 0xa8, 0x20, 0x83, 0xe5, 0x04, 0x20, 0x82, 0xe2,
+ 0xa4, 0x20, 0x83, 0xe5, 0x1c, 0x80, 0xbd, 0xe8, 0x00, 0x00, 0x50, 0x3c, 0x12, 0x00, 0x50, 0x3c,
+ 0x00, 0x00, 0x70, 0x3c, 0x04, 0x30, 0x9f, 0xe5, 0x00, 0x11, 0x83, 0xe7, 0x1e, 0xff, 0x2f, 0xe1,
+ 0xc0, 0x16, 0x00, 0x22, 0x80, 0x20, 0x9f, 0xe5, 0x00, 0x00, 0x51, 0xe3, 0x7c, 0x30, 0x9f, 0xe5,
+ 0x02, 0x30, 0xa0, 0x11, 0x01, 0x00, 0x50, 0xe3, 0x0a, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x50, 0xe3,
+ 0x0f, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x50, 0xe3, 0x1e, 0xff, 0x2f, 0x11, 0x60, 0x10, 0x9f, 0xe5,
+ 0x00, 0x20, 0x91, 0xe5, 0x22, 0x28, 0xa0, 0xe1, 0x02, 0x28, 0xa0, 0xe1, 0x02, 0x30, 0x83, 0xe1,
+ 0x00, 0x30, 0x81, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x44, 0x10, 0x9f, 0xe5, 0xc0, 0x20, 0x91, 0xe5,
+ 0x02, 0x28, 0xa0, 0xe1, 0x22, 0x28, 0xa0, 0xe1, 0x03, 0x38, 0x82, 0xe1, 0xc0, 0x30, 0x81, 0xe5,
+ 0x1e, 0xff, 0x2f, 0xe1, 0x28, 0x00, 0x9f, 0xe5, 0xc0, 0x21, 0x90, 0xe5, 0xff, 0x24, 0xc2, 0xe3,
+ 0x03, 0x2c, 0x82, 0xe1, 0xc0, 0x21, 0x80, 0xe5, 0xe0, 0x21, 0x90, 0xe5, 0xff, 0x20, 0xc2, 0xe3,
+ 0x23, 0x34, 0x82, 0xe1, 0xe0, 0x31, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x22, 0x22, 0x00, 0x00,
+ 0xef, 0xee, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3c, 0x01, 0x00, 0x50, 0xe3, 0x01, 0x10, 0x21, 0xe2,
+ 0x06, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x50, 0xe3, 0x06, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x50, 0xe3,
+ 0x24, 0x30, 0x9f, 0x05, 0x0e, 0x10, 0x81, 0x03, 0x00, 0x12, 0x83, 0x05, 0x1e, 0xff, 0x2f, 0xe1,
+ 0x18, 0x30, 0x9f, 0xe5, 0x00, 0x00, 0x00, 0xea, 0x14, 0x30, 0x9f, 0xe5, 0x08, 0x20, 0x9f, 0xe5,
+ 0x03, 0x30, 0x81, 0xe1, 0x00, 0x32, 0x82, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0xf0, 0x3c,
+ 0x0e, 0x04, 0x06, 0x00, 0x0e, 0x06, 0x0e, 0x00, 0x02, 0x00, 0x50, 0xe3, 0x10, 0x40, 0x2d, 0xe9,
+ 0xbc, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0xb8, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3,
+ 0xb4, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0xb0, 0x40, 0x9f, 0xe5, 0xb0, 0xc0, 0x9f, 0xe5,
+ 0x01, 0x20, 0xa0, 0xe3, 0x00, 0x20, 0x83, 0xe5, 0x02, 0x00, 0x50, 0xe3, 0xa4, 0x30, 0x9f, 0x05,
+ 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x04, 0x30, 0xa0, 0x01, 0x0c, 0x30, 0xa0, 0x11,
+ 0x00, 0x30, 0x93, 0xe5, 0x1f, 0x3e, 0x03, 0xe2, 0x01, 0x0c, 0x53, 0xe3, 0xf5, 0xff, 0xff, 0x0a,
+ 0x02, 0x00, 0x50, 0xe3, 0x80, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0x7c, 0x20, 0x9f, 0xe5,
+ 0x01, 0x00, 0x50, 0xe3, 0x78, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0x5c, 0xc0, 0x9f, 0xe5,
+ 0x5c, 0x20, 0x9f, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x02, 0x00, 0x50, 0xe3, 0x54, 0x30, 0x9f, 0x05,
+ 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x0c, 0x30, 0xa0, 0x01, 0x02, 0x30, 0xa0, 0x11,
+ 0x00, 0x30, 0x93, 0xe5, 0x3e, 0x0c, 0x13, 0xe3, 0xf6, 0xff, 0xff, 0x0a, 0x02, 0x00, 0x50, 0xe3,
+ 0x40, 0x00, 0x9f, 0x05, 0x04, 0x00, 0x00, 0x0a, 0x3c, 0x30, 0x9f, 0xe5, 0x3c, 0x20, 0x9f, 0xe5,
+ 0x01, 0x00, 0x50, 0xe3, 0x02, 0x00, 0xa0, 0x01, 0x03, 0x00, 0xa0, 0x11, 0x00, 0x00, 0x90, 0xe5,
+ 0x10, 0x80, 0xbd, 0xe8, 0x34, 0x00, 0x20, 0x3d, 0x34, 0x00, 0xe0, 0x3c, 0x34, 0x00, 0x30, 0x3c,
+ 0x08, 0x00, 0xe0, 0x3c, 0x08, 0x00, 0x30, 0x3c, 0x08, 0x00, 0x20, 0x3d, 0x10, 0x00, 0x20, 0x3d,
+ 0x10, 0x00, 0xe0, 0x3c, 0x10, 0x00, 0x30, 0x3c, 0x20, 0x00, 0x20, 0x3d, 0x20, 0x00, 0x30, 0x3c,
+ 0x20, 0x00, 0xe0, 0x3c, 0x02, 0x00, 0x50, 0xe3, 0xf0, 0x40, 0x2d, 0xe9, 0xd8, 0x30, 0x9f, 0x05,
+ 0x03, 0x00, 0x00, 0x0a, 0xd4, 0xc0, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3, 0xd0, 0x30, 0x9f, 0xe5,
+ 0x0c, 0x30, 0xa0, 0x01, 0x02, 0x00, 0x50, 0xe3, 0x00, 0x10, 0x83, 0xe5, 0xc4, 0x30, 0x9f, 0x05,
+ 0x03, 0x00, 0x00, 0x0a, 0xc0, 0xc0, 0x9f, 0xe5, 0x01, 0x00, 0x50, 0xe3, 0xbc, 0x30, 0x9f, 0xe5,
+ 0x0c, 0x30, 0xa0, 0x01, 0x00, 0x40, 0x93, 0xe5, 0x00, 0xc0, 0xa0, 0xe3, 0x01, 0x40, 0x84, 0xe3,
+ 0x00, 0x40, 0x83, 0xe5, 0xa8, 0x70, 0x9f, 0xe5, 0xa8, 0x60, 0x9f, 0xe5, 0xa8, 0x50, 0x9f, 0xe5,
+ 0xa8, 0x40, 0x9f, 0xe5, 0x12, 0x00, 0x00, 0xea, 0x02, 0x00, 0x50, 0xe3, 0xa0, 0x30, 0x9f, 0x05,
+ 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x07, 0x30, 0xa0, 0x01, 0x06, 0x30, 0xa0, 0x11,
+ 0x00, 0x30, 0x93, 0xe5, 0x3e, 0x0c, 0x13, 0xe3, 0xf6, 0xff, 0xff, 0x0a, 0x02, 0x00, 0x50, 0xe3,
+ 0x80, 0x30, 0x9f, 0x05, 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x05, 0x30, 0xa0, 0x01,
+ 0x04, 0x30, 0xa0, 0x11, 0x00, 0x30, 0x93, 0xe5, 0x01, 0x10, 0x41, 0xe2, 0x0c, 0x30, 0xc2, 0xe7,
+ 0x01, 0xc0, 0x8c, 0xe2, 0x00, 0x00, 0x51, 0xe3, 0xea, 0xff, 0xff, 0x1a, 0x02, 0x00, 0x50, 0xe3,
+ 0x30, 0x00, 0x9f, 0x05, 0x04, 0x00, 0x00, 0x0a, 0x2c, 0x30, 0x9f, 0xe5, 0x2c, 0x20, 0x9f, 0xe5,
+ 0x01, 0x00, 0x50, 0xe3, 0x02, 0x00, 0xa0, 0x11, 0x03, 0x00, 0xa0, 0x01, 0x00, 0x30, 0x90, 0xe5,
+ 0x01, 0x30, 0xc3, 0xe3, 0x00, 0x30, 0x80, 0xe5, 0xf0, 0x80, 0xbd, 0xe8, 0x34, 0x00, 0x20, 0x3d,
+ 0x34, 0x00, 0xe0, 0x3c, 0x34, 0x00, 0x30, 0x3c, 0x04, 0x00, 0x20, 0x3d, 0x04, 0x00, 0xe0, 0x3c,
+ 0x04, 0x00, 0x30, 0x3c, 0x08, 0x00, 0xe0, 0x3c, 0x08, 0x00, 0x30, 0x3c, 0x20, 0x00, 0xe0, 0x3c,
+ 0x20, 0x00, 0x30, 0x3c, 0x08, 0x00, 0x20, 0x3d, 0x20, 0x00, 0x20, 0x3d, 0x02, 0x00, 0x50, 0xe3,
+ 0x2e, 0x00, 0x80, 0x02, 0x02, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe3, 0x2b, 0x00, 0xa0, 0x03,
+ 0x22, 0x00, 0xa0, 0x13, 0x00, 0x10, 0xa0, 0xe3, 0xe4, 0xfe, 0xff, 0xea, 0x02, 0x00, 0x50, 0xe3,
+ 0x10, 0x40, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x30, 0x00, 0xa0, 0x03, 0x02, 0x00, 0x00, 0x0a,
+ 0x01, 0x00, 0x54, 0xe3, 0x2b, 0x00, 0xa0, 0x03, 0x22, 0x00, 0xa0, 0x13, 0x01, 0x10, 0xa0, 0xe3,
+ 0xda, 0xfe, 0xff, 0xeb, 0x02, 0x00, 0x54, 0xe3, 0x04, 0x31, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a,
+ 0x00, 0x21, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3, 0xfc, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01,
+ 0x02, 0x00, 0x54, 0xe3, 0x0f, 0x20, 0xa0, 0xe3, 0x00, 0x20, 0x83, 0xe5, 0xec, 0x30, 0x9f, 0x05,
+ 0x03, 0x00, 0x00, 0x0a, 0xe8, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3, 0xe4, 0x30, 0x9f, 0xe5,
+ 0x02, 0x30, 0xa0, 0x01, 0x00, 0x20, 0x93, 0xe5, 0x02, 0x00, 0x54, 0xe3, 0x0c, 0x20, 0x82, 0xe3,
+ 0x00, 0x20, 0x83, 0xe5, 0xd0, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0xcc, 0x20, 0x9f, 0xe5,
+ 0x01, 0x00, 0x54, 0xe3, 0xc8, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0xc4, 0x20, 0x9f, 0xe5,
+ 0x02, 0x00, 0x54, 0xe3, 0x04, 0x21, 0x92, 0xe7, 0x00, 0x20, 0x83, 0xe5, 0xb8, 0x30, 0x9f, 0x05,
+ 0x03, 0x00, 0x00, 0x0a, 0xb4, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3, 0xb0, 0x30, 0x9f, 0xe5,
+ 0x02, 0x30, 0xa0, 0x01, 0x02, 0x00, 0x54, 0xe3, 0x06, 0x20, 0xa0, 0xe3, 0x00, 0x20, 0x83, 0xe5,
+ 0xa0, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0x9c, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3,
+ 0x98, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0x94, 0x20, 0x9f, 0xe5, 0x02, 0x00, 0x54, 0xe3,
+ 0x00, 0x20, 0x83, 0xe5, 0x54, 0x30, 0x9f, 0x05, 0x03, 0x00, 0x00, 0x0a, 0x50, 0x20, 0x9f, 0xe5,
+ 0x01, 0x00, 0x54, 0xe3, 0x4c, 0x30, 0x9f, 0xe5, 0x02, 0x30, 0xa0, 0x01, 0x00, 0x20, 0x93, 0xe5,
+ 0x02, 0x00, 0x54, 0xe3, 0x0c, 0x20, 0x82, 0xe3, 0x00, 0x20, 0x83, 0xe5, 0x2c, 0x40, 0x9f, 0x05,
+ 0x04, 0x00, 0x00, 0x0a, 0x2c, 0x30, 0x9f, 0xe5, 0x24, 0x20, 0x9f, 0xe5, 0x01, 0x00, 0x54, 0xe3,
+ 0x02, 0x40, 0xa0, 0x01, 0x03, 0x40, 0xa0, 0x11, 0x01, 0x30, 0xa0, 0xe3, 0x00, 0x30, 0x84, 0xe5,
+ 0x10, 0x80, 0xbd, 0xe8, 0x08, 0x00, 0x20, 0x3d, 0x08, 0x00, 0xe0, 0x3c, 0x08, 0x00, 0x30, 0x3c,
+ 0x00, 0x00, 0x20, 0x3d, 0x00, 0x00, 0xe0, 0x3c, 0x00, 0x00, 0x30, 0x3c, 0x30, 0x00, 0x20, 0x3d,
+ 0x30, 0x00, 0xe0, 0x3c, 0x30, 0x00, 0x30, 0x3c, 0xc0, 0x16, 0x00, 0x22, 0x0c, 0x00, 0x20, 0x3d,
+ 0x0c, 0x00, 0xe0, 0x3c, 0x0c, 0x00, 0x30, 0x3c, 0x04, 0x00, 0x20, 0x3d, 0x04, 0x00, 0xe0, 0x3c,
+ 0x04, 0x00, 0x30, 0x3c, 0x18, 0x06, 0x01, 0x00, 0x0c, 0x30, 0x80, 0xe2, 0x02, 0xc0, 0xd3, 0xe5,
+ 0x01, 0x10, 0xd3, 0xe5, 0x0c, 0x20, 0xd0, 0xe5, 0x03, 0x30, 0xd3, 0xe5, 0x0c, 0x08, 0xa0, 0xe1,
+ 0x01, 0x04, 0x80, 0xe1, 0x02, 0x00, 0x80, 0xe1, 0x03, 0x0c, 0x80, 0xe1, 0x5f, 0x0d, 0x80, 0xe2,
+ 0x3f, 0x00, 0x80, 0xe2, 0xff, 0x0e, 0xc0, 0xe3, 0x0f, 0x00, 0xc0, 0xe3, 0x1e, 0xff, 0x2f, 0xe1,
+ 0x70, 0x40, 0x2d, 0xe9, 0x18, 0xd0, 0x4d, 0xe2, 0x04, 0x40, 0x8d, 0xe2, 0x03, 0x50, 0xa0, 0xe1,
+ 0x00, 0x60, 0xa0, 0xe1, 0x01, 0x00, 0xa0, 0xe1, 0x02, 0x10, 0xa0, 0xe1, 0x04, 0x20, 0xa0, 0xe1,
+ 0xe1, 0x01, 0x00, 0xeb, 0x04, 0x10, 0xa0, 0xe1, 0x05, 0x00, 0xa0, 0xe1, 0x10, 0x20, 0xa0, 0xe3,
+ 0xae, 0x02, 0x00, 0xeb, 0x06, 0x10, 0xa0, 0xe1, 0x05, 0x20, 0xa0, 0xe1, 0x01, 0x00, 0xa0, 0xe3,
+ 0x10, 0x30, 0xa0, 0xe3, 0x51, 0x02, 0x00, 0xeb, 0x18, 0xd0, 0x8d, 0xe2, 0x70, 0x80, 0xbd, 0xe8,
+ 0x01, 0x00, 0x50, 0xe3, 0xf0, 0x47, 0x2d, 0xe9, 0x0c, 0x50, 0xd1, 0xe5, 0x0c, 0x30, 0x81, 0xe2,
+ 0x00, 0x40, 0xa0, 0xe1, 0x01, 0x00, 0xa0, 0x03, 0x02, 0x00, 0xa0, 0x13, 0x03, 0x80, 0xd3, 0xe5,
+ 0x02, 0x70, 0xd3, 0xe5, 0x01, 0x60, 0xd3, 0xe5, 0x02, 0xa0, 0xa0, 0xe1, 0x07, 0x00, 0xc1, 0xe5,
+ 0x40, 0x30, 0x81, 0xe2, 0x02, 0x00, 0xa0, 0xe3, 0x40, 0x20, 0xa0, 0xe3, 0xdb, 0xff, 0xff, 0xeb,
+ 0x07, 0x78, 0xa0, 0xe1, 0x06, 0x64, 0x87, 0xe1, 0x05, 0x50, 0x86, 0xe1, 0x08, 0x3c, 0x85, 0xe1,
+ 0x04, 0x00, 0xa0, 0xe1, 0x0a, 0x20, 0xa0, 0xe1, 0x02, 0x10, 0xa0, 0xe3, 0xf0, 0x47, 0xbd, 0xe8,
+ 0x36, 0x02, 0x00, 0xea, 0x10, 0x40, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x04, 0x00, 0xa0, 0xe1,
+ 0x01, 0x10, 0xa0, 0xe3, 0xbf, 0xfe, 0xff, 0xeb, 0x05, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1,
+ 0xd0, 0xfe, 0xff, 0xeb, 0xff, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0xcd, 0xfe, 0xff, 0xeb,
+ 0x00, 0x10, 0xa0, 0xe3, 0x01, 0x30, 0x10, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x00, 0x00, 0x0a,
+ 0xb4, 0xfe, 0xff, 0xeb, 0xf0, 0xff, 0xff, 0xea, 0x04, 0x00, 0xa0, 0xe1, 0x03, 0x10, 0xa0, 0xe1,
+ 0x10, 0x40, 0xbd, 0xe8, 0xaf, 0xfe, 0xff, 0xea, 0x70, 0x40, 0x2d, 0xe9, 0x00, 0x50, 0x51, 0xe2,
+ 0x00, 0x40, 0xa0, 0xe1, 0x07, 0x00, 0x00, 0x1a, 0x01, 0x10, 0x81, 0xe2, 0xa9, 0xfe, 0xff, 0xeb,
+ 0x04, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0xba, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
+ 0x05, 0x10, 0xa0, 0xe1, 0xa3, 0xfe, 0xff, 0xeb, 0x01, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1,
+ 0xa0, 0xfe, 0xff, 0xeb, 0x50, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0xb1, 0xfe, 0xff, 0xeb,
+ 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0x9a, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
+ 0x01, 0x10, 0xa0, 0xe3, 0x97, 0xfe, 0xff, 0xeb, 0x01, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1,
+ 0xa8, 0xfe, 0xff, 0xeb, 0x00, 0x00, 0x55, 0xe3, 0x1c, 0x10, 0xa0, 0x03, 0x00, 0x10, 0xa0, 0x13,
+ 0x04, 0x00, 0xa0, 0xe1, 0xa3, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3,
+ 0x8c, 0xfe, 0xff, 0xeb, 0x00, 0x00, 0x55, 0xe3, 0x70, 0x80, 0xbd, 0x08, 0x04, 0x00, 0xa0, 0xe1,
+ 0x01, 0x10, 0xa0, 0xe3, 0x87, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x06, 0x10, 0xa0, 0xe3,
+ 0x98, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0x70, 0x40, 0xbd, 0xe8,
+ 0x80, 0xfe, 0xff, 0xea, 0x70, 0x40, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x01, 0x50, 0xa0, 0xe1,
+ 0x1d, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0xb5, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
+ 0x01, 0x10, 0xa0, 0xe3, 0xc7, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
+ 0x74, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x20, 0x10, 0xa0, 0xe3, 0x85, 0xfe, 0xff, 0xeb,
+ 0x25, 0x18, 0xa0, 0xe1, 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x81, 0xfe, 0xff, 0xeb,
+ 0x25, 0x14, 0xa0, 0xe1, 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x7d, 0xfe, 0xff, 0xeb,
+ 0xff, 0x10, 0x05, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x7a, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
+ 0x00, 0x10, 0xa0, 0xe3, 0x63, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3,
+ 0xb0, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x70, 0x40, 0xbd, 0xe8, 0xf6, 0xfe, 0xff, 0xea,
+ 0x70, 0x40, 0x2d, 0xe9, 0x00, 0x50, 0xa0, 0xe1, 0x01, 0x46, 0xa0, 0xe1, 0x02, 0x60, 0xa0, 0xe1,
+ 0x00, 0x00, 0x00, 0xea, 0xd6, 0xff, 0xff, 0xeb, 0x00, 0x00, 0x56, 0xe3, 0x04, 0x10, 0xa0, 0xe1,
+ 0x05, 0x00, 0xa0, 0xe1, 0x01, 0x4a, 0x84, 0xe2, 0x01, 0x60, 0x46, 0xe2, 0xf8, 0xff, 0xff, 0x1a,
+ 0x70, 0x80, 0xbd, 0xe8, 0xf0, 0x45, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x24, 0xd0, 0x4d, 0xe2,
+ 0x02, 0x50, 0xa0, 0xe1, 0x03, 0x70, 0xa0, 0xe1, 0x01, 0x60, 0xa0, 0xe1, 0xea, 0xfe, 0xff, 0xeb,
+ 0x04, 0x00, 0xa0, 0xe1, 0x82, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
+ 0x44, 0xfe, 0xff, 0xeb, 0x03, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0x55, 0xfe, 0xff, 0xeb,
+ 0x26, 0x18, 0xa0, 0xe1, 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x51, 0xfe, 0xff, 0xeb,
+ 0x26, 0x14, 0xa0, 0xe1, 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x4d, 0xfe, 0xff, 0xeb,
+ 0xff, 0x10, 0x06, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0x4a, 0xfe, 0xff, 0xeb, 0x00, 0x60, 0xa0, 0xe3,
+ 0x0d, 0x80, 0xa0, 0xe1, 0x15, 0x00, 0x00, 0xea, 0x20, 0x00, 0x57, 0xe3, 0x07, 0xa0, 0xa0, 0xb1,
+ 0x20, 0xa0, 0xa0, 0xa3, 0x04, 0x00, 0xa0, 0xe1, 0x0a, 0x10, 0xa0, 0xe1, 0x0d, 0x20, 0xa0, 0xe1,
+ 0x7f, 0xfe, 0xff, 0xeb, 0x05, 0x00, 0xa0, 0xe1, 0x0d, 0x10, 0xa0, 0xe1, 0x0a, 0x20, 0xa0, 0xe1,
+ 0x9f, 0xfd, 0xff, 0xeb, 0x00, 0x30, 0xa0, 0xe3, 0x00, 0x00, 0x50, 0xe3, 0x01, 0x60, 0x86, 0x13,
+ 0x03, 0x20, 0xd8, 0xe7, 0x02, 0x30, 0x83, 0xe2, 0xff, 0x00, 0x52, 0xe3, 0x02, 0x60, 0x86, 0x13,
+ 0x0a, 0x00, 0x53, 0xe1, 0xf9, 0xff, 0xff, 0xba, 0x20, 0x50, 0x85, 0xe2, 0x20, 0x70, 0x47, 0xe2,
+ 0x00, 0x00, 0x57, 0xe3, 0xe7, 0xff, 0xff, 0xca, 0x00, 0x10, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1,
+ 0x18, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0xaf, 0xfe, 0xff, 0xeb, 0x06, 0x00, 0xa0, 0xe1,
+ 0x24, 0xd0, 0x8d, 0xe2, 0xf0, 0x85, 0xbd, 0xe8, 0xf0, 0x4f, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1,
+ 0x14, 0xd0, 0x4d, 0xe2, 0x01, 0x50, 0xa0, 0xe1, 0x02, 0x70, 0xa0, 0xe1, 0x03, 0x80, 0xa0, 0xe1,
+ 0x53, 0x00, 0x00, 0xea, 0x05, 0x6a, 0xa0, 0xe1, 0x26, 0x6a, 0xa0, 0xe1, 0x01, 0x6a, 0x66, 0xe2,
+ 0x08, 0x00, 0x56, 0xe1, 0x08, 0x60, 0xa0, 0xa1, 0x04, 0x00, 0xa0, 0xe1, 0x05, 0x10, 0xa0, 0xe1,
+ 0x07, 0x20, 0xa0, 0xe1, 0x06, 0x30, 0xa0, 0xe1, 0xb1, 0xff, 0xff, 0xeb, 0x01, 0x00, 0x10, 0xe3,
+ 0x44, 0x00, 0x00, 0x0a, 0x02, 0x00, 0x10, 0xe3, 0x03, 0x00, 0x00, 0x0a, 0xff, 0x1e, 0xc5, 0xe3,
+ 0x0f, 0x10, 0xc1, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0x79, 0xff, 0xff, 0xeb, 0x00, 0x30, 0xa0, 0xe3,
+ 0x03, 0x20, 0xd7, 0xe7, 0x07, 0x90, 0xa0, 0xe1, 0xff, 0x00, 0x52, 0xe3, 0x01, 0x30, 0x83, 0xe2,
+ 0x02, 0x00, 0x00, 0x1a, 0x06, 0x00, 0x53, 0xe1, 0xf8, 0xff, 0xff, 0xba, 0x35, 0x00, 0x00, 0xea,
+ 0x04, 0x00, 0xa0, 0xe1, 0x90, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x28, 0xff, 0xff, 0xeb,
+ 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0x3a, 0xff, 0xff, 0xeb, 0x25, 0x34, 0xa0, 0xe1,
+ 0xff, 0x30, 0x03, 0xe2, 0x25, 0x28, 0xa0, 0xe1, 0xff, 0x20, 0x02, 0xe2, 0x08, 0x30, 0x8d, 0xe5,
+ 0x06, 0xa0, 0xa0, 0xe1, 0xff, 0x30, 0x05, 0xe2, 0x01, 0xb0, 0xa0, 0xe3, 0x04, 0x20, 0x8d, 0xe5,
+ 0x0c, 0x30, 0x8d, 0xe5, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0xdd, 0xfd, 0xff, 0xeb,
+ 0x04, 0x00, 0xa0, 0xe1, 0xad, 0x10, 0xa0, 0xe3, 0xee, 0xfd, 0xff, 0xeb, 0x00, 0x00, 0x5b, 0xe3,
+ 0x00, 0xb0, 0xa0, 0xe3, 0x08, 0x00, 0x00, 0x0a, 0x04, 0x10, 0x9d, 0xe5, 0x04, 0x00, 0xa0, 0xe1,
+ 0xe8, 0xfd, 0xff, 0xeb, 0x08, 0x10, 0x9d, 0xe5, 0x04, 0x00, 0xa0, 0xe1, 0xe5, 0xfd, 0xff, 0xeb,
+ 0x04, 0x00, 0xa0, 0xe1, 0x0c, 0x10, 0x9d, 0xe5, 0xe2, 0xfd, 0xff, 0xeb, 0x00, 0x10, 0xd9, 0xe5,
+ 0x04, 0x00, 0xa0, 0xe1, 0xdf, 0xfd, 0xff, 0xeb, 0x01, 0x10, 0xd9, 0xe5, 0x04, 0x00, 0xa0, 0xe1,
+ 0xdc, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0xc5, 0xfd, 0xff, 0xeb,
+ 0x04, 0x00, 0xa0, 0xe1, 0xfe, 0xfe, 0xff, 0xeb, 0x02, 0xa0, 0x5a, 0xe2, 0x02, 0x90, 0x89, 0xe2,
+ 0xdf, 0xff, 0xff, 0x1a, 0x04, 0x00, 0xa0, 0xe1, 0x0a, 0x10, 0xa0, 0xe1, 0x0d, 0xff, 0xff, 0xeb,
+ 0x04, 0x00, 0xa0, 0xe1, 0x54, 0xfe, 0xff, 0xeb, 0x08, 0x80, 0x66, 0xe0, 0x06, 0x70, 0x87, 0xe0,
+ 0x06, 0x50, 0x85, 0xe0, 0x00, 0x00, 0x58, 0xe3, 0xa9, 0xff, 0xff, 0xca, 0x14, 0xd0, 0x8d, 0xe2,
+ 0xf0, 0x8f, 0xbd, 0xe8, 0xf0, 0x41, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x03, 0x50, 0xa0, 0xe1,
+ 0x02, 0x70, 0xa0, 0xe1, 0x01, 0x60, 0xa0, 0xe1, 0x4f, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
+ 0xe7, 0xfe, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0xa9, 0xfd, 0xff, 0xeb,
+ 0x04, 0x00, 0xa0, 0xe1, 0x03, 0x10, 0xa0, 0xe3, 0xba, 0xfd, 0xff, 0xeb, 0x26, 0x18, 0xa0, 0xe1,
+ 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0xb6, 0xfd, 0xff, 0xeb, 0x26, 0x14, 0xa0, 0xe1,
+ 0xff, 0x10, 0x01, 0xe2, 0x04, 0x00, 0xa0, 0xe1, 0xb2, 0xfd, 0xff, 0xeb, 0xff, 0x10, 0x06, 0xe2,
+ 0x04, 0x00, 0xa0, 0xe1, 0xaf, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x07, 0x10, 0xa0, 0xe1,
+ 0x05, 0x20, 0xa0, 0xe1, 0xea, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3,
+ 0x94, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0xf0, 0x41, 0xbd, 0xe8, 0x2a, 0xfe, 0xff, 0xea,
+ 0x00, 0x10, 0xa0, 0xe3, 0x6a, 0xfd, 0xff, 0xea, 0x10, 0x40, 0x2d, 0xe9, 0x01, 0x10, 0xa0, 0xe3,
+ 0x00, 0x40, 0xa0, 0xe1, 0x66, 0xfd, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3,
+ 0x10, 0x40, 0xbd, 0xe8, 0x87, 0xfd, 0xff, 0xea, 0x0c, 0x30, 0x81, 0xe2, 0x70, 0x40, 0x2d, 0xe9,
+ 0x02, 0x50, 0xd3, 0xe5, 0x01, 0x40, 0xa0, 0xe1, 0x01, 0x10, 0xd3, 0xe5, 0x0c, 0x20, 0xd4, 0xe5,
+ 0x03, 0x30, 0xd3, 0xe5, 0x05, 0x58, 0xa0, 0xe1, 0x01, 0x54, 0x85, 0xe1, 0x02, 0x50, 0x85, 0xe1,
+ 0x03, 0x5c, 0x85, 0xe1, 0x00, 0x60, 0xa0, 0xe1, 0x02, 0x5b, 0x85, 0xe2, 0x00, 0x00, 0xa0, 0xe3,
+ 0xe8, 0xff, 0xff, 0xeb, 0x06, 0x10, 0xa0, 0xe1, 0x04, 0x20, 0xa0, 0xe1, 0x05, 0x30, 0xa0, 0xe1,
+ 0x00, 0x00, 0xa0, 0xe3, 0x5f, 0xff, 0xff, 0xeb, 0x04, 0x20, 0xa0, 0xe1, 0x06, 0x10, 0xa0, 0xe1,
+ 0x05, 0x30, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3, 0x1d, 0xff, 0xff, 0xeb, 0x00, 0x40, 0xa0, 0xe1,
+ 0x00, 0x00, 0xa0, 0xe3, 0xd9, 0xff, 0xff, 0xeb, 0x01, 0x00, 0x24, 0xe2, 0x01, 0x00, 0x00, 0xe2,
+ 0x70, 0x80, 0xbd, 0xe8, 0xf0, 0x45, 0x2d, 0xe9, 0x01, 0x40, 0xa0, 0xe1, 0x14, 0xd0, 0x4d, 0xe2,
+ 0x00, 0x80, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3, 0x02, 0x60, 0xa0, 0xe1, 0xd1, 0xff, 0xff, 0xeb,
+ 0x08, 0x10, 0xa0, 0xe1, 0x02, 0x2b, 0xa0, 0xe3, 0x04, 0x30, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3,
+ 0xa7, 0xff, 0xff, 0xeb, 0x00, 0x00, 0xa0, 0xe3, 0xc8, 0xff, 0xff, 0xeb, 0x04, 0x00, 0xa0, 0xe1,
+ 0x40, 0x11, 0x9f, 0xe5, 0x04, 0x20, 0xa0, 0xe3, 0xcd, 0xfc, 0xff, 0xeb, 0x00, 0x00, 0x50, 0xe3,
+ 0x00, 0x00, 0xe0, 0x13, 0x49, 0x00, 0x00, 0x1a, 0x04, 0x10, 0xa0, 0xe1, 0x40, 0x20, 0xa0, 0xe3,
+ 0x0d, 0x30, 0xa0, 0xe1, 0x02, 0x00, 0xa0, 0xe3, 0x5c, 0xfe, 0xff, 0xeb, 0x0d, 0x00, 0xa0, 0xe1,
+ 0x40, 0x10, 0x84, 0xe2, 0x10, 0x20, 0xa0, 0xe3, 0xc1, 0xfc, 0xff, 0xeb, 0x0d, 0x50, 0xa0, 0xe1,
+ 0x00, 0x70, 0x50, 0xe2, 0x01, 0x00, 0xe0, 0x13, 0x3c, 0x00, 0x00, 0x1a, 0x0c, 0x30, 0x84, 0xe2,
+ 0x02, 0x50, 0xd3, 0xe5, 0x01, 0x10, 0xd3, 0xe5, 0x0c, 0x20, 0xd4, 0xe5, 0x05, 0x58, 0xa0, 0xe1,
+ 0x03, 0x30, 0xd3, 0xe5, 0x01, 0x54, 0x85, 0xe1, 0x02, 0x50, 0x85, 0xe1, 0x03, 0x5c, 0x85, 0xe1,
+ 0x7e, 0x0b, 0x55, 0xe3, 0x2e, 0x00, 0x00, 0x8a, 0x08, 0x30, 0x84, 0xe2, 0x02, 0xc0, 0xd3, 0xe5,
+ 0x01, 0xa0, 0xd3, 0xe5, 0x08, 0x10, 0xd4, 0xe5, 0x03, 0x20, 0xd3, 0xe5, 0x0c, 0xc8, 0xa0, 0xe1,
+ 0x0a, 0x34, 0x8c, 0xe1, 0x01, 0x30, 0x83, 0xe1, 0x02, 0x3c, 0x83, 0xe1, 0x05, 0x00, 0x53, 0xe1,
+ 0x23, 0x00, 0x00, 0x8a, 0x07, 0x30, 0xd4, 0xe5, 0x01, 0x30, 0x43, 0xe2, 0x01, 0x00, 0x53, 0xe3,
+ 0x03, 0x00, 0xe0, 0x83, 0x21, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x56, 0xe3, 0x1e, 0x00, 0x00, 0x0a,
+ 0x98, 0xff, 0xff, 0xeb, 0x06, 0x30, 0xa0, 0xe1, 0x07, 0x00, 0xa0, 0xe1, 0x02, 0x1b, 0x88, 0xe2,
+ 0x05, 0x20, 0xa0, 0xe1, 0x6e, 0xff, 0xff, 0xeb, 0x07, 0x00, 0xa0, 0xe1, 0x8f, 0xff, 0xff, 0xeb,
+ 0x07, 0x30, 0xd4, 0xe5, 0x01, 0x00, 0x53, 0xe3, 0x03, 0x00, 0x00, 0x1a, 0x07, 0x00, 0xa0, 0xe1,
+ 0x04, 0x10, 0xa0, 0xe1, 0x06, 0x20, 0xa0, 0xe1, 0x3c, 0xfe, 0xff, 0xeb, 0x06, 0x10, 0xa0, 0xe1,
+ 0x05, 0x20, 0xa0, 0xe1, 0x0d, 0x30, 0xa0, 0xe1, 0x02, 0x00, 0xa0, 0xe3, 0x23, 0xfe, 0xff, 0xeb,
+ 0x0d, 0x00, 0xa0, 0xe1, 0x10, 0x10, 0x84, 0xe2, 0x10, 0x20, 0xa0, 0xe3, 0x88, 0xfc, 0xff, 0xeb,
+ 0x0d, 0x70, 0xa0, 0xe1, 0x00, 0x00, 0x50, 0xe3, 0x04, 0x00, 0xe0, 0x13, 0x02, 0x00, 0x00, 0x0a,
+ 0x02, 0x00, 0x00, 0xea, 0x02, 0x00, 0xe0, 0xe3, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0xa0, 0xe3,
+ 0x14, 0xd0, 0x8d, 0xe2, 0xf0, 0x85, 0xbd, 0xe8, 0xd1, 0x16, 0x00, 0x22, 0xf0, 0x4f, 0x2d, 0xe9,
+ 0x00, 0x50, 0xa0, 0xe1, 0x54, 0xd0, 0x4d, 0xe2, 0x01, 0x40, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3,
+ 0x01, 0x10, 0xa0, 0xe3, 0x02, 0x60, 0xa0, 0xe1, 0x84, 0xfc, 0xff, 0xeb, 0x0e, 0x23, 0xa0, 0xe3,
+ 0x01, 0x10, 0xa0, 0xe3, 0x02, 0xc0, 0xa0, 0xe1, 0x10, 0x30, 0x8d, 0xe2, 0x04, 0x10, 0x82, 0xe5,
+ 0x00, 0x00, 0x9c, 0xe5, 0x0e, 0x23, 0xa0, 0xe3, 0x01, 0x00, 0x10, 0xe2, 0xfb, 0xff, 0xff, 0x1a,
+ 0x40, 0xc0, 0x64, 0xe2, 0xa4, 0x72, 0xa0, 0xe1, 0x84, 0xe1, 0xa0, 0xe1, 0x7c, 0x81, 0x9f, 0xe5,
+ 0xa4, 0xaa, 0xa0, 0xe1, 0xa4, 0x96, 0xa0, 0xe1, 0xff, 0x70, 0x07, 0xe2, 0xff, 0xe0, 0x0e, 0xe2,
+ 0x0c, 0xc0, 0x65, 0xe0, 0xff, 0x90, 0x09, 0xe2, 0x04, 0x70, 0x8d, 0xe5, 0x00, 0xe0, 0x8d, 0xe5,
+ 0x0c, 0xc0, 0x8d, 0xe5, 0x02, 0x10, 0xa0, 0xe1, 0xff, 0xa0, 0x0a, 0xe2, 0x00, 0x70, 0xa0, 0xe1,
+ 0xa4, 0x4e, 0xa0, 0xe1, 0x10, 0xc0, 0x8d, 0xe2, 0x02, 0xe0, 0xa0, 0xe1, 0x04, 0x00, 0x82, 0xe5,
+ 0x08, 0x90, 0x8d, 0xe5, 0x00, 0x00, 0x82, 0xe5, 0x0c, 0x20, 0x9d, 0xe5, 0x02, 0x00, 0x85, 0xe0,
+ 0x00, 0x00, 0x50, 0xe3, 0x25, 0x00, 0x00, 0xda, 0x00, 0x20, 0xa0, 0xe3, 0x02, 0x70, 0x8c, 0xe7,
+ 0x04, 0x20, 0x82, 0xe2, 0x40, 0x00, 0x52, 0xe3, 0xfb, 0xff, 0xff, 0x1a, 0x40, 0x00, 0x50, 0xe3,
+ 0x07, 0x20, 0xa0, 0xd1, 0x40, 0x90, 0x60, 0xd2, 0x03, 0x00, 0x00, 0xda, 0x09, 0x00, 0x00, 0xea,
+ 0x02, 0xb0, 0xd5, 0xe7, 0x02, 0xb0, 0xcc, 0xe7, 0x01, 0x20, 0x82, 0xe2, 0x09, 0x00, 0x52, 0xe1,
+ 0xfa, 0xff, 0xff, 0xba, 0x07, 0x00, 0x50, 0xe3, 0x7f, 0x20, 0xe0, 0xe3, 0x09, 0x20, 0xc3, 0xe7,
+ 0x00, 0x00, 0xa0, 0xd3, 0x08, 0x00, 0x00, 0xda, 0x3b, 0x40, 0xc3, 0xe5, 0x3c, 0xa0, 0xc3, 0xe5,
+ 0x08, 0x20, 0x9d, 0xe5, 0x01, 0x00, 0xa0, 0xe3, 0x3d, 0x20, 0xc3, 0xe5, 0x04, 0x20, 0x9d, 0xe5,
+ 0x3e, 0x20, 0xc3, 0xe5, 0x00, 0x20, 0x9d, 0xe5, 0x3f, 0x20, 0xc3, 0xe5, 0xb0, 0x20, 0x9f, 0xe5,
+ 0x02, 0x90, 0x8c, 0xe0, 0x32, 0x93, 0x89, 0xe2, 0x40, 0x90, 0x49, 0xe2, 0x00, 0x90, 0x99, 0xe5,
+ 0x04, 0x90, 0x82, 0xe4, 0x08, 0x00, 0x52, 0xe1, 0xf8, 0xff, 0xff, 0x1a, 0x09, 0x00, 0x00, 0xea,
+ 0x8c, 0x20, 0x9f, 0xe5, 0x02, 0x00, 0x85, 0xe0, 0x32, 0x03, 0x80, 0xe2, 0x40, 0x00, 0x40, 0xe2,
+ 0x00, 0x00, 0x90, 0xe5, 0x04, 0x00, 0x82, 0xe4, 0x08, 0x00, 0x52, 0xe1, 0xf8, 0xff, 0xff, 0x1a,
+ 0x40, 0x50, 0x85, 0xe2, 0x00, 0x00, 0xa0, 0xe3, 0x00, 0x20, 0x91, 0xe5, 0x02, 0x20, 0x82, 0xe3,
+ 0x00, 0x20, 0x81, 0xe5, 0x00, 0x20, 0x91, 0xe5, 0x01, 0x00, 0x12, 0xe3, 0xfc, 0xff, 0xff, 0x1a,
+ 0x00, 0x20, 0x9e, 0xe5, 0x00, 0x00, 0x50, 0xe3, 0x08, 0x20, 0x82, 0xe3, 0x00, 0x20, 0x8e, 0xe5,
+ 0xc0, 0xff, 0xff, 0x0a, 0x3c, 0x30, 0x9f, 0xe5, 0x3c, 0x10, 0x9f, 0xe5, 0x03, 0x20, 0xa0, 0xe1,
+ 0x06, 0x00, 0x92, 0xe6, 0x04, 0x30, 0x83, 0xe2, 0x32, 0x23, 0x82, 0xe2, 0x20, 0x20, 0x42, 0xe2,
+ 0x01, 0x00, 0x53, 0xe1, 0x00, 0x00, 0x82, 0xe5, 0xf7, 0xff, 0xff, 0x1a, 0x00, 0x00, 0xa0, 0xe3,
+ 0x00, 0x10, 0xa0, 0xe1, 0x19, 0xfc, 0xff, 0xeb, 0x54, 0xd0, 0x8d, 0xe2, 0xf0, 0x8f, 0xbd, 0xe8,
+ 0x80, 0x00, 0x00, 0x38, 0x40, 0x00, 0x00, 0x38, 0x20, 0x00, 0x00, 0x38, 0x34, 0x00, 0x00, 0x38,
+ 0xf0, 0x47, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x01, 0x50, 0xa0, 0xe1, 0x0a, 0x00, 0xa0, 0xe3,
+ 0x01, 0x10, 0xa0, 0xe3, 0xe3, 0x85, 0xa0, 0xe3, 0x03, 0x60, 0xa0, 0xe1, 0x02, 0x70, 0xa0, 0xe1,
+ 0x01, 0xa0, 0xa0, 0xe3, 0x09, 0xfc, 0xff, 0xeb, 0x00, 0x30, 0xa0, 0xe3, 0x74, 0x30, 0x88, 0xe5,
+ 0x78, 0x30, 0x88, 0xe5, 0x7c, 0x30, 0x88, 0xe5, 0x80, 0x30, 0x88, 0xe5, 0x08, 0xa0, 0x88, 0xe5,
+ 0x08, 0x30, 0x88, 0xe5, 0x00, 0xa0, 0x88, 0xe5, 0x10, 0x30, 0x88, 0xe5, 0x6c, 0x50, 0x88, 0xe5,
+ 0x6c, 0x20, 0x98, 0xe5, 0x0a, 0x00, 0x54, 0xe1, 0x09, 0x40, 0xa0, 0x03, 0x08, 0x40, 0xa0, 0x13,
+ 0x02, 0x20, 0xe0, 0xe1, 0x88, 0x20, 0x88, 0xe5, 0x8c, 0x30, 0x88, 0xe5, 0x14, 0x40, 0x88, 0xe5,
+ 0x18, 0x60, 0x88, 0xe5, 0x20, 0x70, 0x88, 0xe5, 0x24, 0x60, 0x88, 0xe5, 0x28, 0x70, 0x88, 0xe5,
+ 0x2c, 0x60, 0x88, 0xe5, 0x30, 0x70, 0x88, 0xe5, 0x34, 0x60, 0x88, 0xe5, 0x3c, 0x00, 0x00, 0xeb,
+ 0x08, 0x30, 0xa0, 0xe1, 0x04, 0xa0, 0x88, 0xe5, 0x0c, 0x20, 0x93, 0xe5, 0x0f, 0x00, 0x12, 0xe3,
+ 0xfc, 0xff, 0xff, 0x0a, 0x0a, 0x00, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0xf0, 0x47, 0xbd, 0xe8,
+ 0xe6, 0xfb, 0xff, 0xea, 0x98, 0x30, 0x9f, 0xe5, 0xf0, 0x45, 0x2d, 0xe9, 0x94, 0xc0, 0x9f, 0xe5,
+ 0xfa, 0x4f, 0xa0, 0xe3, 0x03, 0x60, 0xa0, 0xe1, 0x8c, 0x50, 0x9f, 0xe5, 0x1c, 0x00, 0x00, 0xea,
+ 0xb4, 0x10, 0x93, 0xe5, 0xb2, 0x80, 0xd0, 0xe1, 0xa2, 0xa0, 0xa0, 0xe1, 0x94, 0x18, 0x27, 0xe0,
+ 0x00, 0x20, 0xa0, 0xe3, 0x09, 0x00, 0x00, 0xea, 0x01, 0x20, 0x22, 0xe2, 0x06, 0x1c, 0x82, 0xe3,
+ 0x0e, 0x10, 0x81, 0xe3, 0x00, 0x12, 0x8c, 0xe5, 0xb4, 0x10, 0x93, 0xe5, 0x01, 0x10, 0x8a, 0xe0,
+ 0xb4, 0x80, 0x93, 0xe5, 0x08, 0x80, 0x61, 0xe0, 0x00, 0x00, 0x58, 0xe3, 0xfb, 0xff, 0xff, 0xba,
+ 0xb4, 0x10, 0x93, 0xe5, 0x01, 0x10, 0x67, 0xe0, 0x00, 0x00, 0x51, 0xe3, 0xf1, 0xff, 0xff, 0xba,
+ 0x00, 0x52, 0x8c, 0xe5, 0xb4, 0x70, 0xd0, 0xe1, 0xb4, 0x10, 0x96, 0xe5, 0x94, 0x17, 0x22, 0xe0,
+ 0xb4, 0x10, 0x93, 0xe5, 0x01, 0x10, 0x62, 0xe0, 0x00, 0x00, 0x51, 0xe3, 0xfb, 0xff, 0xff, 0xba,
+ 0x06, 0x00, 0x80, 0xe2, 0xb0, 0x20, 0xd0, 0xe1, 0x00, 0x00, 0x52, 0xe3, 0xdf, 0xff, 0xff, 0x1a,
+ 0xf0, 0x85, 0xbd, 0xe8, 0x00, 0x00, 0x70, 0x3c, 0x00, 0x00, 0xf0, 0x3c, 0x0e, 0x06, 0x00, 0x00,
+ 0x00, 0x30, 0xa0, 0xe3, 0x02, 0x00, 0x00, 0xea, 0x03, 0xc0, 0xd1, 0xe7, 0x03, 0xc0, 0xc0, 0xe7,
+ 0x01, 0x30, 0x83, 0xe2, 0x00, 0x00, 0x52, 0xe3, 0x01, 0x20, 0x42, 0xe2, 0xf9, 0xff, 0xff, 0x1a,
+ 0x1e, 0xff, 0x2f, 0xe1, 0x7e, 0xff, 0x17, 0xee, 0xfd, 0xff, 0xff, 0x1a, 0x00, 0x10, 0xa0, 0xe3,
+ 0x9a, 0x1f, 0x07, 0xee, 0x1e, 0xff, 0x2f, 0xe1, 0xb8, 0x0b, 0xf4, 0x01, 0xf4, 0x01, 0xb8, 0x0b,
+ 0xf4, 0x01, 0xf4, 0x01, 0xb8, 0x0b, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x76, 0xdc,
+ 0x1d, 0x32, 0xb2, 0x46, 0xa6, 0xc9, 0x7d, 0x5a, 0x61, 0xd3, 0x49, 0x4c, 0x1e, 0xf0, 0xd9, 0xde,
+ 0xc2, 0x7e, 0xec, 0x02, 0x7c, 0x15, 0x76, 0xbb, 0x5c, 0x4f, 0x2d, 0x95, 0x06, 0x85, 0xdf, 0x28,
+ 0xe4, 0xd7, 0xf4, 0x82, 0xc0, 0x73, 0xb0, 0x53, 0x26, 0xfc, 0xb0, 0xfe, 0x60, 0x80, 0x7d, 0x33,
+ 0xa8, 0xde, 0xf8, 0x49, 0xbb, 0xbe, 0x01, 0x45, 0xff, 0x62, 0x40, 0x19, 0xf4, 0x01, 0x64, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xe8, 0x03, 0x64, 0x00, 0x00, 0x00, 0xf4, 0x01, 0x96, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x68, 0x73, 0x6c, 0x66, 0x00, 0x38, 0x37, 0x30, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+};
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 @@
+/* Generated by bin2c */
+
+extern unsigned char dualboot_install_ipod6g[5396];
+extern 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 @@
+build/
+*.arm-bin
+bin2c
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 @@
+# __________ __ ___.
+# Open \______ \ ____ ____ | | _\_ |__ _______ ___
+# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+# \/ \/ \/ \/ \/
+# $Id$
+#
+ifndef V
+SILENT = @
+endif
+
+CC = gcc
+LD = ld
+OC = objcopy
+CROSS ?= arm-elf-eabi-
+
+ROOTDIR = ../../..
+FIRMDIR = $(ROOTDIR)/firmware
+FWARM = $(FIRMDIR)/target/arm
+FW8702 = $(FWARM)/s5l8702
+BUILDDIR = build/
+LINKFILE = dualboot.lds
+
+# Edit the following variables when adding a new target.
+# mks5lboot.c also needs to be edited to refer to these
+# To add a new target x you need to:
+# 1) add x to the list in TARGETS
+# 2) create a variable named OPT_x of the form:
+# OPT_x=target specific defines
+TARGETS = ipod6g
+OPT_ipod6g = -DIPOD_6G -DMEMORYSIZE=64
+
+LOADERS = install uninstall
+OPT_install =
+OPT_uninstall = -DDUALBOOT_UNINSTALL
+
+# target/loader specific options
+$(foreach l, $(LOADERS),$(foreach t, $(TARGETS),\
+ $(eval OPT_$(l)_$(t) = $(OPT_$(l)) $(OPT_$(t)))))
+
+DEFINES = -DBOOTLOADER
+
+SOURCES = init.S dualboot.c
+SOURCES += $(ROOTDIR)/lib/arm_support/support-arm.S
+SOURCES += $(wildcard $(FIRMDIR)/asm/mem*.c $(FIRMDIR)/libc/mem*.c)
+SOURCES += $(addprefix $(FWARM)/, mmu-arm.S)
+SOURCES += $(addprefix $(FW8702)/, clocking-s5l8702.c spi-s5l8702.c nor-s5l8702.c crypto-s5l8702.c)
+# target/loader specific sources
+SRCTARGET = piezo-.c
+$(foreach l, $(LOADERS), $(foreach t, $(TARGETS),\
+ $(eval SRC_$(l)_$(t) = $(addprefix $(FW8702)/$(t)/, $(subst -.,-$(subst ipod,,$(t)).,$(SRCTARGET))))))
+
+INCLUDES += -I. -I.. -I$(FIRMDIR) -I$(FWARM) -I$(FW8702)
+INCLUDES += $(addprefix -I$(FIRMDIR)/, export include libc/include kernel/include)
+# target/loader specific includes
+$(foreach l,$(LOADERS),$(foreach t,$(TARGETS),$(eval INC_$(l)_$(t) = -I$(FW8702)/$(t))))
+
+CFLAGS = $(INCLUDES) -mcpu=arm926ej-s -std=gnu99 -nostdlib -ffreestanding -Os -W -Wall\
+ -Wundef -Wstrict-prototypes -ffunction-sections -fdata-sections -Wl,--gc-sections $(DEFINES)
+
+# Build filenames prefix
+PFX = dualboot_
+
+BOOTBINS = $(foreach l, $(LOADERS),$(foreach t, $(TARGETS),$(PFX)$(l)_$(t).arm-bin))
+
+OUTPUTDUALBOOT = ../dualboot.h ../dualboot.c
+OUTPUTDEBUG = $(BOOTBINS:%.arm-bin=$(BUILDDIR)%.arm-elf) $(BOOTBINS:%.arm-bin=$(BUILDDIR)%.lds)
+
+
+all: $(BUILDDIR) $(OUTPUTDUALBOOT)
+
+$(BUILDDIR)$(PFX)%.lds: $(LINKFILE)
+ @echo Creating $@
+ $(SILENT)$(CROSS)$(CC) $(INC_$*) $(CFLAGS) $(OPT_$*) -E -x c - < $< | sed '/#/d' > $@
+
+$(BUILDDIR)$(PFX)%.arm-elf: $(BUILDDIR)$(PFX)%.lds $(SOURCES)
+ @echo CC -T $(notdir $^ $(SRC_$*))
+ $(SILENT)$(CROSS)$(CC) $(INC_$*) $(CFLAGS) $(OPT_$*) -o $@ -T$^ $(SRC_$*)
+
+$(PFX)%.arm-bin: $(BUILDDIR)$(PFX)%.arm-elf
+ @echo OC $<
+ $(SILENT)$(CROSS)$(OC) -O binary $< $@
+
+bin2c: bin2c.c
+ $(CC) -o $@ $<
+
+$(OUTPUTDUALBOOT): bin2c $(BOOTBINS)
+ ./bin2c ../dualboot $(BOOTBINS)
+
+$(BUILDDIR):
+ mkdir -p $@
+
+clean:
+ rm -rf bin2c $(BOOTBINS) $(BUILDDIR)
+
+.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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:$
+ *
+ * Copyright (C) 2012 by Andrew Ryabinin
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef __BUILD_AUTOCONF_H
+#define __BUILD_AUTOCONF_H
+
+/* lower case names match the what's exported in the Makefile
+ * upper case name looks nicer in the code */
+
+#define arch_none 0
+#define ARCH_NONE 0
+
+#define arch_sh 1
+#define ARCH_SH 1
+
+#define arch_m68k 2
+#define ARCH_M68K 2
+
+#define arch_arm 3
+#define ARCH_ARM 3
+
+#define arch_mips 4
+#define ARCH_MIPS 4
+
+#define arch_x86 5
+#define ARCH_X86 5
+
+#define arch_amd64 6
+#define ARCH_AMD64 6
+
+/* Define target machine architecture */
+#define ARCH arch_arm
+/* Optionally define architecture version */
+#define ARCH_VERSION 5
+
+/* Define endianess for the target or simulator platform */
+#define ROCKBOX_LITTLE_ENDIAN 1
+
+/* Define this if you build rockbox to support the logf logging and display */
+#undef ROCKBOX_HAS_LOGF
+
+/* Define this if you want logf to output to the serial port */
+#undef LOGF_SERIAL
+
+/* Define this to record a chart with timings for the stages of boot */
+#undef DO_BOOTCHART
+
+/* the threading backend we use */
+#define ASSEMBLER_THREADS
+
+/* root of Rockbox */
+#define ROCKBOX_DIR "/.rockbox"
+#define ROCKBOX_SHARE_PATH ""
+#define ROCKBOX_BINARY_PATH ""
+#define ROCKBOX_LIBRARY_PATH ""
+
+#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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2007 Dave Chapman
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <libgen.h>
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+static off_t filesize(int fd)
+{
+ struct stat buf;
+
+ fstat(fd,&buf);
+ return buf.st_size;
+}
+
+static void write_cfile(const unsigned char* buf, off_t len, FILE* fp, const char *name)
+{
+ int i;
+
+ fprintf(fp,"unsigned char %s[%ld] = {",name,len);
+
+ for (i=0;i<len;i++) {
+ if ((i % 16) == 0) {
+ fprintf(fp,"\n ");
+ }
+ if (i == (len-1)) {
+ fprintf(fp,"0x%02x",buf[i]);
+ } else if ((i % 16) == 15) {
+ fprintf(fp,"0x%02x,",buf[i]);
+ } else {
+ fprintf(fp,"0x%02x, ",buf[i]);
+ }
+ }
+ fprintf(fp,"\n};\n");
+}
+
+int main (int argc, char* argv[])
+{
+ char* cname;
+ int i;
+ FILE *cfile, *hfile;
+ char cfilename[256], hfilename[256];
+
+ if (argc < 3) {
+ fprintf(stderr,"Usage: bin2c cname file1 [file2 [file3 ...]]\n");
+ return 1;
+ }
+
+ cname=argv[1];
+
+ snprintf(cfilename,256,"%s.c",cname);
+ cfile = fopen(cfilename,"w+");
+ if (cfile == NULL) {
+ fprintf(stderr,"Couldn't open %s\n",cfilename);
+ return 2;
+ }
+
+ snprintf(hfilename,256,"%s.h",cname);
+ hfile = fopen(hfilename,"w+");
+ if (hfile == NULL) {
+ fprintf(stderr,"Couldn't open %s\n",hfilename);
+ fclose(cfile);
+ return 3;
+ }
+
+ fprintf(cfile,"/* Generated by bin2c */\n\n");
+ fprintf(cfile,"#include \"%s\"\n\n", basename(hfilename));
+ fprintf(hfile,"/* Generated by bin2c */\n\n");
+
+ for(i=0; i < argc - 2; i++) {
+ unsigned char* buf;
+ off_t len;
+ off_t orig_len;
+ char *ext;
+ char *array = argv[2+i];
+
+ int fd = open(array,O_RDONLY|O_BINARY);
+ if (fd < 0) {
+ fprintf(stderr,"Can not open %s\n",argv[2+i]);
+ fclose(cfile);
+ fclose(hfile);
+ return 4;
+ }
+
+ orig_len = filesize(fd);
+ /* pad to 32bit */
+ len = (orig_len + 3) & ~3;
+
+ buf = malloc(len);
+ if (read(fd,buf,orig_len) < orig_len) {
+ fprintf(stderr,"Short read, aborting\n");
+ return 5;
+ }
+
+ /* pad to 32bit with zeros */
+ if (len > orig_len)
+ memset(buf+orig_len, 0, len-orig_len);
+
+ /* remove file extension */
+ ext = strchr (array, '.');
+ if (ext != NULL)
+ *ext = '\0';
+ write_cfile (buf, len, cfile, array);
+ fprintf(hfile,"extern unsigned char %s[%ld];\n",array,len);
+
+ close(fd);
+ }
+
+ fclose(cfile);
+ fclose(hfile);
+
+ return 0;
+}
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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2015 by Cástor Muñoz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include <stdint.h>
+#include <string.h>
+
+#include "config.h"
+#include "system.h"
+#include "button.h"
+
+#include "s5l8702.h"
+#include "clocking-s5l8702.h"
+#include "spi-s5l8702.h"
+#include "nor-target.h"
+#include "piezo.h"
+
+/* How it works:
+ *
+ * - dualboot-installer: installs or updates a RB bootloader, the bootloader
+ * to install/update is already included into dualboot-installer.dfu file,
+ * once it is executed by the iPod device:
+ *
+ * 1) locates an original NORBOOT (ONB): first it looks at offset=32KB, if
+ * a NORBOOT is found but it is not an ONB then it is supposed it is a
+ * RB bootloader (that should be updated), then the ONB is loaded from
+ * offset=32KB+old_BLSIZE).
+ * 2) write ONB at 32KB+new_BLSIZE, if it fails then:
+ * 2a) try to restore ONB to its 'pristine' place (offset=32KB), if it
+ * also fails then the NOR got corrupted (ONB probably destroyed)
+ * and iTunes should be used to restore the iPod.
+ * 3) write new (included) RB bootloader at offset=32KB, it it fails then
+ * goto 2a)
+ *
+ * - dualboot-uninstaller: uninstall RB bootloader from NOR, leaving it at
+ * it's previous (pristine) state.
+ *
+ * See bootloader/ipod6g.c for notes on how the RB bootloader works.
+ *
+ *
+ * Pristine NOR Rockboxed NOR
+ * 1MB ______________
+ * | |
+ * | flsh DIR |
+ * 1MB-0x200 |______________|
+ * | |
+ * | File 1 |
+ * |..............|
+ * | |
+ * . .
+ * . .
+ * . .
+ * | |
+ * |..............|
+ * | | . .
+ * | File N | . .
+ * |______________| |______________|
+ * | | | |
+ * | | | |
+ * | | | Unused |
+ * | | | |
+ * | Unused | 160KB+BLSZ |______________|
+ * | | | |
+ * | | | Original |
+ * | | | NOR boot |
+ * 160KB |______________| | (decrypted) |
+ * | | | |
+ * | | 32KB+BLSZ |______________|
+ * | Original | | |
+ * | NOR boot | | Decrypted |
+ * | (encrypted) | | Rockbox |
+ * | | | Bootloader |
+ * 32KB |______________| 32KB |______________|
+ * | | | |
+ * | | . .
+ * | | . .
+ * |______________|
+ * | |
+ * | SysCfg |
+ * 0 |______________|
+ *
+ */
+
+#define OF_LOADADDR IRAM1_ORIG
+
+/* tone sequences: period (uS), duration (ms), silence (ms) */
+static uint16_t alive[] = { 500,100,0, 0 };
+static uint16_t happy[] = { 1000,100,0, 500,150,0, 0 };
+static uint16_t fatal[] = { 3000,500,500, 3000,500,500, 3000,500,0, 0 };
+#define sad2 (&fatal[3])
+#define sad (&fatal[6])
+
+/* iPod Classic: decrypted hashes for known OFs */
+static unsigned char of_sha[][SIGN_SZ] = {
+ "\x66\x66\x76\xDC\x1D\x32\xB2\x46\xA6\xC9\x7D\x5A\x61\xD3\x49\x4C", /* v1.1.2 */
+ "\x1E\xF0\xD9\xDE\xC2\x7E\xEC\x02\x7C\x15\x76\xBB\x5C\x4F\x2D\x95", /* v2.0.1 */
+ "\x06\x85\xDF\x28\xE4\xD7\xF4\x82\xC0\x73\xB0\x53\x26\xFC\xB0\xFE", /* v2.0.4 */
+ "\x60\x80\x7D\x33\xA8\xDE\xF8\x49\xBB\xBE\x01\x45\xFF\x62\x40\x19" /* v2.0.5 */
+};
+#define N_OF (int)(sizeof(of_sha)/SIGN_SZ)
+
+/* we can assume that unknown FW is a RB bootloader */
+#define FW_RB N_OF
+
+static int identify_fw(struct Im3Info *hinfo)
+{
+ unsigned char hash[SIGN_SZ];
+ int of;
+
+ /* decrypt hash to identify OF */
+ memcpy(hash, hinfo->u.enc12.data_sign, SIGN_SZ);
+ hwkeyaes(HWKEYAES_DECRYPT, HWKEYAES_UKEY, hash, SIGN_SZ);
+
+ for (of = 0; of < N_OF; of++)
+ if (memcmp(hash, of_sha[of], SIGN_SZ) == 0)
+ break;
+
+ return of;
+}
+
+#ifdef DUALBOOT_UNINSTALL
+/* Uninstall RB bootloader */
+void main(void)
+{
+ struct Im3Info *hinfo;
+ void *fw_addr;
+ uint16_t *status;
+ unsigned bl_nor_sz;
+
+ usec_timer_init();
+ piezo_seq(alive);
+ spi_clkdiv(SPI_PORT, 4); /* SPI clock = 27/5 MHz. */
+
+ hinfo = (struct Im3Info*)OF_LOADADDR;
+ fw_addr = (void*)hinfo + IM3HDR_SZ;
+
+ if (im3_read(NORBOOT_OFF, hinfo, NULL) != 0) {
+ status = sad;
+ goto bye; /* no FW found */
+ }
+
+ if (identify_fw(hinfo) != FW_RB) {
+ status = happy;
+ goto bye; /* RB bootloader not installed, nothing to do */
+ }
+
+ /* if found FW is a RB bootloader, OF should start just behind it */
+ bl_nor_sz = im3_nor_sz(hinfo);
+ if ((im3_read(NORBOOT_OFF + bl_nor_sz, hinfo, fw_addr) != 0)
+ || (identify_fw(hinfo) == FW_RB)) {
+ status = sad;
+ goto bye; /* OF not found */
+ }
+
+ /* decrypted OF correctly loaded, encrypt it before restoration */
+ im3_crypt(HWKEYAES_ENCRYPT, hinfo, fw_addr);
+
+ /* restore OF to it's original place */
+ if (!im3_write(NORBOOT_OFF, hinfo)) {
+ status = fatal;
+ goto bye; /* corrupted NOR, use iTunes to restore */
+ }
+
+ /* erase freed NOR blocks */
+ bootflash_init(SPI_PORT);
+ bootflash_erase_blocks(SPI_PORT,
+ (NORBOOT_OFF + im3_nor_sz(hinfo)) >> 12, bl_nor_sz >> 12);
+ bootflash_close(SPI_PORT);
+
+ status = happy;
+
+bye:
+ /* minimum time between the initial and the final beeps */
+ while (USEC_TIMER < 2000000);
+ piezo_seq(status);
+ WDTCON = 0x100000; /* WDT reset */
+ while (1);
+}
+
+#else
+/* Install RB bootloader */
+struct Im3Info bl_hinfo __attribute__((section(".im3info.data"))) =
+{
+ .ident = IM3_IDENT,
+ .version = IM3_VERSION,
+ .enc_type = 2,
+};
+
+static uint32_t get_uint32le(unsigned char *p)
+{
+ return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+}
+
+void main(void)
+{
+ uint16_t *status = happy;
+ int single_boot;
+ struct Im3Info *hinfo;
+ void *fw_addr;
+ unsigned bl_nor_sz;
+
+ usec_timer_init();
+ piezo_seq(alive);
+ spi_clkdiv(SPI_PORT, 4); /* SPI clock = 27/5 MHz. */
+
+ /* check for single boot installation, is is configured when
+ mks5lboot.exe builds the .dfu image */
+ single_boot = bl_hinfo.info_sign[0];
+
+ /* sign RB bootloader (data and header), but don't encrypt it,
+ use current decrypted image for faster load */
+ im3_sign(HWKEYAES_UKEY, (void*)&bl_hinfo + IM3HDR_SZ,
+ get_uint32le(bl_hinfo.data_sz), bl_hinfo.u.enc12.data_sign);
+ im3_sign(HWKEYAES_UKEY, &bl_hinfo, IM3INFOSIGN_SZ, bl_hinfo.info_sign);
+
+ if (single_boot) {
+ if (!im3_write(NORBOOT_OFF, &bl_hinfo))
+ status = sad;
+ goto bye;
+ }
+
+ hinfo = (struct Im3Info*)OF_LOADADDR;
+ fw_addr = (void*)hinfo + IM3HDR_SZ;
+
+ if (im3_read(NORBOOT_OFF, hinfo, fw_addr) != 0) {
+ status = sad;
+ goto bye; /* no FW found */
+ }
+
+ if (identify_fw(hinfo) == FW_RB) {
+ /* FW found, but not OF, assume it is a RB bootloader,
+ already decrypted OF should be located just behind */
+ int nor_offset = NORBOOT_OFF + im3_nor_sz(hinfo);
+ if ((im3_read(nor_offset, hinfo, fw_addr) != 0)
+ || (identify_fw(hinfo) == FW_RB)) {
+ status = sad;
+ goto bye; /* OF not found, use iTunes to restore */
+ }
+ }
+
+ bl_nor_sz = im3_nor_sz(&bl_hinfo);
+ /* safety check - verify we are not going to overwrite useful data */
+ if (flsh_get_unused() < bl_nor_sz) {
+ status = sad2;
+ goto bye; /* no space if flash, use iTunes to restore */
+ }
+
+ /* write decrypted OF and RB bootloader, if any of these fails we
+ will try to retore OF to its original place */
+ if (!im3_write(NORBOOT_OFF + bl_nor_sz, hinfo)
+ || !im3_write(NORBOOT_OFF, &bl_hinfo)) {
+ im3_crypt(HWKEYAES_ENCRYPT, hinfo, fw_addr);
+ if (!im3_write(NORBOOT_OFF, hinfo)) {
+ /* corrupted NOR, use iTunes to restore */
+ status = fatal;
+ }
+ else {
+ /* RB bootloader not succesfully intalled, but device
+ was restored and should be working as before */
+ status = sad;
+ }
+ }
+
+bye:
+ /* minimum time between the initial and the final beeps */
+ while (USEC_TIMER < 2000000);
+ piezo_seq(status);
+ WDTCON = 0x100000; /* WDT reset */
+ while (1);
+}
+#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 @@
+#define ASM
+#include "config.h"
+#include "cpu.h"
+#include "mks5lboot.h"
+
+ENTRY(_start)
+OUTPUT_FORMAT(elf32-littlearm)
+OUTPUT_ARCH(arm)
+
+#define BIN_ORIG DFU_LOADADDR + BIN_OFFSET
+#define BIN_SIZE MAX_PAYLOAD
+
+MEMORY
+{
+ IRAM : ORIGIN = BIN_ORIG, LENGTH = BIN_SIZE
+}
+
+SECTIONS
+{
+ .text : {
+ *(.init.text*)
+ *(.text*)
+ *(.icode*)
+ . = ALIGN(4);
+ } > IRAM
+
+ /* include initialized BSS (if any) into DFU image */
+ .bss : {
+ *(.bss*)
+ *(.ibss*)
+ *(COMMON)
+ . = ALIGN(4);
+ } > IRAM
+
+#if 1
+ /* reuse pwnage as stack, 0x30c bytes available */
+ _exception_stack = BIN_ORIG;
+ _supervisor_stack = _exception_stack;
+#else
+ /* include stack into DFU image */
+ .stack : {
+ . += 0x400;
+ _supervisor_stack = .;
+ . += 0x200;
+ _exception_stack = .;
+ } > IRAM
+#endif
+
+ .data : {
+ *(.data*)
+ *(.rodata*)
+ *(.idata*)
+ *(.irodata*)
+ /* place bootloader IM3 header at the end, mkdfu
+ will concatenate the bootloader binary here */
+ . = ALIGN(16);
+ *(.im3info.data*)
+ } > IRAM
+}
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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:
+ *
+ * Copyright © 2009 Michael Sparmann
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+ .section .init.text, "ax", %progbits
+ .global _start
+
+_start:
+ mov r0, #0xD7
+ msr CPSR_c, r0 @ Abort mode, IRQs/FIQs disabled
+ ldr sp, =_exception_stack
+
+ mov r0, #0xDB
+ msr CPSR_c, r0 @ Undefined Instruction mode, IRQs/FIQs disabled
+ ldr sp, =_exception_stack
+
+ mov r0, #0xD3
+ msr CPSR_c, r0 @ Supervisor mode, IRQs/FIQs disabled
+ ldr sp, =_supervisor_stack
+
+ MOV R0, #0x00050000
+ ORR R0, #0x00000078
+ MCR p15, 0, R0, c1, c0, 0 @ Get rid of some CPU "features" likely to cause trouble
+
+ bl main
+ .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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2015 by Cástor Muñoz
+ *
+ * based on:
+ * ipoddfu_c by user890104
+ * xpwn/pwnmetheus2
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef NO_LIBUSBAPI
+#define USE_LIBUSBAPI
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <time.h>
+#ifdef WIN32
+#include <windows.h>
+#include <setupapi.h>
+#include <stdbool.h>
+#endif
+
+#ifdef USE_LIBUSBAPI
+#include <libusb-1.0/libusb.h>
+#endif
+
+#include "mks5lboot.h"
+
+
+static void sleep_ms(unsigned int ms)
+{
+ struct timespec req;
+ req.tv_sec = ms / 1000;
+ req.tv_nsec = (ms % 1000) * 1000000;
+ nanosleep(&req, NULL);
+}
+
+/*
+ * CRC32 functions
+ * Based on public domain implementation by Finn Yannick Jacobs.
+ */
+
+/* Written and copyright 1999 by Finn Yannick Jacobs
+ * No rights were reserved to this, so feel free to
+ * manipulate or do with it, what you want or desire :)
+ */
+
+#define CRC32_DEFAULT_SEED 0xffffffff
+
+/* crc32table[] built by crc32_init() */
+static unsigned long crc32table[256];
+
+/* Calculate crc32. Little endian.
+ * Standard seed is 0xffffffff or 0.
+ * Some implementations xor result with 0xffffffff after calculation.
+ */
+static uint32_t crc32(void *data, unsigned int len, uint32_t seed)
+{
+ uint8_t *d = data;
+
+ while (len--)
+ {
+ seed = ((seed >> 8) & 0x00FFFFFF) ^ crc32table [(seed ^ *d++) & 0xFF];
+ }
+
+ return seed;
+}
+
+/* Calculate crc32table */
+static void crc32_init()
+{
+ uint32_t poly = 0xEDB88320L;
+ uint32_t crc;
+ int i, j;
+
+ for (i = 0; i < 256; ++i)
+ {
+ crc = i;
+
+ for (j = 8; j > 0; --j)
+ {
+ crc = (crc >> 1) ^ ((crc & 1) ? poly : 0);
+ }
+
+ crc32table[i] = crc;
+ }
+}
+
+
+/*
+ * DFU
+ */
+
+/* must be pow2 <= wTransferSize (2048) */
+#define DFU_PKT_SZ 2048
+
+#define APPLE_VID 0x05AC
+
+static int KNOWN_PIDS[] =
+{
+ /* DFU */
+ 0x1220, /* Nano 2G */
+ 0x1223, /* Nano 3G and Classic 1G/2G/3G/4G */
+ 0x1224, /* Shuffle 3G */
+ 0x1225, /* Nano 4G */
+ 0x1231, /* Nano 5G */
+ 0x1232, /* Nano 6G */
+ 0x1233, /* Shuffle 4G */
+ 0x1234, /* Nano 7G */
+ /* WTF */
+ 0x1240, /* Nano 2G */
+ 0x1241, /* Classic 1G */
+ 0x1242, /* Nano 3G */
+ 0x1243, /* Nano 4G */
+ 0x1245, /* Classic 2G */
+ 0x1246, /* Nano 5G */
+ 0x1247, /* Classic 3G */
+ 0x1248, /* Nano 6G */
+ 0x1249, /* Nano 7G */
+ 0x124a, /* Nano 7G */
+ 0x1250, /* Classic 4G */
+ 0
+};
+
+struct usbControlSetup {
+ uint8_t bmRequestType;
+ uint8_t bRequest;
+ uint16_t wValue;
+ uint16_t wIndex;
+ uint16_t wLength;
+} __attribute__ ((packed));
+#define USB_CS_SZ (sizeof(struct usbControlSetup))
+
+struct usbStatusData {
+ uint8_t bStatus;
+ uint8_t bwPollTimeout0;
+ uint8_t bwPollTimeout1;
+ uint8_t bwPollTimeout2;
+ uint8_t bState;
+ uint8_t iString;
+} __attribute__ ((packed));
+
+/* DFU 1.1 specs */
+typedef enum DFUState {
+ appIDLE = 0,
+ appDETACH = 1,
+ dfuIDLE = 2,
+ dfuDNLOAD_SYNC = 3,
+ dfuDNBUSY = 4,
+ dfuDNLOAD_IDLE = 5,
+ dfuMANIFEST_SYNC = 6,
+ dfuMANIFEST = 7,
+ dfuMANIFEST_WAIT_RESET = 8,
+ dfuUPLOAD_IDLE = 9,
+ dfuERROR = 10
+} DFUState;
+
+typedef enum DFUStatus {
+ errNONE = 0,
+ errTARGET = 1,
+ errFILE = 2,
+ errWRITE = 3,
+ errERASE = 4,
+ errCHECK_ERASED = 5,
+ errPROG = 6,
+ errVERIFY = 7,
+ errADDRESS = 8,
+ errNOTDONE = 9,
+ errFIRMWARE = 10,
+ errVENDOR = 11,
+ errUSBR = 12,
+ errPOR = 13,
+ errUNKNOWN = 14,
+ errSTALLEDPKT = 15
+} DFUStatus;
+
+typedef enum DFURequest {
+ DFU_DETACH = 0,
+ DFU_DNLOAD = 1,
+ DFU_UPLOAD = 2,
+ DFU_GETSTATUS = 3,
+ DFU_CLRSTATUS = 4,
+ DFU_GETSTATE = 5,
+ DFU_ABORT = 6
+} DFURequest;
+
+struct dfuDev {
+ struct dfuAPI *api;
+ int found_pid;
+ int detached;
+ char descr[256];
+ int res; /* API result: 1->ok, 0->failure */
+ char err[256];
+ /* API private */
+#ifdef WIN32
+ HANDLE fh;
+ HANDLE ph;
+ DWORD ec; /* winapi error code */
+#endif
+#ifdef USE_LIBUSBAPI
+ libusb_context* ctx;
+ libusb_device_handle* devh;
+ int rc; /* libusb return code */
+#endif
+};
+
+struct dfuAPI {
+ char *name;
+ int (*open_fn)(struct dfuDev*, int*);
+ int (*dfureq_fn)(struct dfuDev*, struct usbControlSetup*, void*);
+ int (*reset_fn)(struct dfuDev*);
+ void (*close_fn)(struct dfuDev*);
+};
+
+
+/*
+ * low-level (API specific) functions
+ */
+static int dfu_check_id(int vid, int pid, int *pid_list)
+{
+ int *p;
+ if (vid != APPLE_VID)
+ return 0;
+ for (p = pid_list; *p; p++)
+ if (*p == pid)
+ return 1;
+ return 0;
+}
+
+/* adds extra DFU request error info */
+static void dfu_add_reqerrstr(struct dfuDev *dfuh, struct usbControlSetup *cs)
+{
+ snprintf(dfuh->err + strlen(dfuh->err),
+ sizeof(dfuh->err) - strlen(dfuh->err), " (cs=%02x/%d/%d/%d/%d)",
+ cs->bmRequestType, cs->bRequest, cs->wValue, cs->wIndex, cs->wLength);
+}
+
+#ifdef WIN32
+static int dfu_winapi_chkrc(struct dfuDev *dfuh, char *str, bool success)
+{
+ dfuh->res = (int)success;
+ if (!success) {
+ dfuh->ec = GetLastError();
+ snprintf(dfuh->err, sizeof(dfuh->err), "%s error %ld", str, dfuh->ec);
+ }
+ return dfuh->res;
+}
+
+static int dfu_winapi_request(struct dfuDev *dfuh,
+ struct usbControlSetup* cs, void* data)
+{
+ unsigned char buf[USB_CS_SZ + DFU_PKT_SZ];
+ DWORD rdwr;
+ bool rc;
+
+ memcpy(buf, cs, USB_CS_SZ);
+
+ if (cs->bmRequestType & 0x80)
+ {
+ rc = ReadFile(dfuh->ph, buf, USB_CS_SZ + cs->wLength, &rdwr, NULL);
+ memcpy(data, buf+USB_CS_SZ, cs->wLength);
+ dfu_winapi_chkrc(dfuh, "DFU request failed: ReadFile()", rc);
+ }
+ else
+ {
+ memcpy(buf+USB_CS_SZ, data, cs->wLength);
+ rc = WriteFile(dfuh->ph, buf, USB_CS_SZ + cs->wLength, &rdwr, NULL);
+ dfu_winapi_chkrc(dfuh, "DFU request failed: WriteFile()", rc);
+ }
+
+ if (!dfuh->res)
+ dfu_add_reqerrstr(dfuh, cs);
+ return dfuh->res;
+}
+
+static int dfu_winapi_reset(struct dfuDev *dfuh)
+{
+ DWORD bytesReturned;
+ bool rc = DeviceIoControl(dfuh->fh, 0x22000c,
+ NULL, 0, NULL, 0, &bytesReturned, NULL);
+ return dfu_winapi_chkrc(dfuh,
+ "Could not reset USB device: DeviceIoControl()", rc);
+}
+
+static void dfu_winapi_close(struct dfuDev *dfuh)
+{
+ if (dfuh->fh != INVALID_HANDLE_VALUE) {
+ CloseHandle(dfuh->fh);
+ dfuh->fh = INVALID_HANDLE_VALUE;
+ }
+ if (dfuh->ph != INVALID_HANDLE_VALUE) {
+ CloseHandle(dfuh->ph);
+ dfuh->ph = INVALID_HANDLE_VALUE;
+ }
+}
+
+static const GUID GUID_AAPLDFU =
+ { 0xB8085869L, 0xFEB9, 0x404B, {0x8C, 0xB1, 0x1E, 0x5C, 0x14, 0xFA, 0x8C, 0x54}};
+
+static int dfu_winapi_open(struct dfuDev *dfuh, int *pid_list)
+{
+ const GUID *guid = &GUID_AAPLDFU;
+ HDEVINFO devinfo = NULL;
+ SP_DEVICE_INTERFACE_DETAIL_DATA_A* details = NULL;
+ SP_DEVICE_INTERFACE_DATA iface;
+ char *path = NULL;
+ DWORD i, size;
+ bool rc;
+
+ dfuh->fh =
+ dfuh->ph = INVALID_HANDLE_VALUE;
+ dfuh->found_pid = 0;
+ dfuh->res = 1; /* ok */
+ dfuh->ec = 0;
+
+ /* Get DFU path */
+ devinfo = SetupDiGetClassDevsA(guid, NULL, NULL,
+ DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
+ if (!dfu_winapi_chkrc(dfuh, "SetupDiGetClassDevsA()",
+ (devinfo != INVALID_HANDLE_VALUE)))
+ goto error;
+
+ iface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
+
+ for (i = 0; SetupDiEnumDeviceInterfaces(devinfo, NULL, guid, i, &iface); i++)
+ {
+ int vid, pid;
+
+ SetupDiGetDeviceInterfaceDetailA(devinfo, &iface, NULL, 0, &size, NULL);
+
+ if (details) free(details);
+ details = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc(size);
+ details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
+ rc = SetupDiGetDeviceInterfaceDetailA(devinfo, &iface, details, size, NULL, NULL);
+ if (!dfu_winapi_chkrc(dfuh, "SetupDiGetDeviceInterfaceDetailA()", rc))
+ goto error;
+
+ CharUpperA(details->DevicePath);
+ if (sscanf(details->DevicePath, "%*4cUSB#VID_%04x&PID_%04x%*s", &vid, &pid) != 2)
+ continue;
+ if (!dfu_check_id(vid, pid, pid_list))
+ continue;
+
+ if (path) free(path);
+ path = malloc(size - sizeof(DWORD) + 16);
+ memcpy(path, details->DevicePath, size - sizeof(DWORD));
+
+ dfuh->fh = CreateFileA(path, GENERIC_READ|GENERIC_WRITE,
+ FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
+ if (!dfu_winapi_chkrc(dfuh, "CreateFileA(fh)", (dfuh->fh != INVALID_HANDLE_VALUE)))
+ goto error;
+
+ strcat(path, "\\PIPE0");
+ dfuh->ph = CreateFileA(path, GENERIC_READ|GENERIC_WRITE,
+ FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
+ if (!dfu_winapi_chkrc(dfuh, "CreateFileA(ph)", (dfuh->ph != INVALID_HANDLE_VALUE)))
+ goto error;
+
+ /* ok */
+ snprintf(dfuh->descr, sizeof(dfuh->descr), "%s", details->DevicePath);
+ dfuh->found_pid = pid;
+ goto bye;
+ }
+
+ if (!dfu_winapi_chkrc(dfuh, "SetupDiEnumDeviceInterfaces()",
+ (GetLastError() == ERROR_NO_MORE_ITEMS)))
+ goto error;
+
+ /* no devices found */
+
+bye:
+ if (path) free(path);
+ if (details) free(details);
+ if (devinfo) SetupDiDestroyDeviceInfoList(devinfo);
+ return dfuh->res;
+
+error:
+ dfu_winapi_close(dfuh);
+ goto bye;
+}
+#endif /* WIN32 */
+
+#ifdef USE_LIBUSBAPI
+static int dfu_libusb_chkrc(struct dfuDev *dfuh, char *str)
+{
+ dfuh->res = (dfuh->rc < LIBUSB_SUCCESS) ? 0 : 1;
+ if (dfuh->res == 0)
+ snprintf(dfuh->err, sizeof(dfuh->err),
+ "%s: %s", str, libusb_error_name(dfuh->rc));
+ return dfuh->res;
+}
+
+static int dfu_libusb_request(struct dfuDev *dfuh,
+ struct usbControlSetup *cs, void *data)
+{
+ dfuh->rc = libusb_control_transfer(dfuh->devh, cs->bmRequestType,
+ cs->bRequest, cs->wValue, cs->wIndex, data, cs->wLength, 500);
+ if (!dfu_libusb_chkrc(dfuh, "DFU request failed"))
+ dfu_add_reqerrstr(dfuh, cs);
+ return dfuh->res;
+}
+
+static int dfu_libusb_reset(struct dfuDev *dfuh)
+{
+ dfuh->rc = libusb_reset_device(dfuh->devh);
+ return dfu_libusb_chkrc(dfuh, "Could not reset USB device");
+}
+
+static void dfu_libusb_close(struct dfuDev *dfuh)
+{
+ if (dfuh->devh) {
+ libusb_release_interface(dfuh->devh, 0);
+ if (dfuh->detached)
+ libusb_attach_kernel_driver(dfuh->devh, 0);
+ libusb_close(dfuh->devh);
+ dfuh->devh = NULL;
+ }
+ if (dfuh->ctx) {
+ libusb_exit(dfuh->ctx);
+ dfuh->ctx = NULL;
+ }
+}
+
+static int dfu_libusb_open(struct dfuDev *dfuh, int *pid_list)
+{
+ struct libusb_device_descriptor desc;
+ libusb_device **devs = NULL, *dev;
+ int n_devs, i;
+
+ dfuh->devh = NULL;
+ dfuh->found_pid = 0;
+ dfuh->detached = 0;
+ dfuh->res = 1; /* ok */
+
+ dfuh->rc = libusb_init(&(dfuh->ctx));
+ if (!dfu_libusb_chkrc(dfuh, "Could not init USB library")) {
+ dfuh->ctx = NULL; /* invalidate ctx (if any) */
+ goto error;
+ }
+
+ n_devs =
+ dfuh->rc = libusb_get_device_list(dfuh->ctx, &devs);
+ if (!dfu_libusb_chkrc(dfuh, "Could not get USB device list"))
+ goto error;
+
+ for (i = 0; i < n_devs; ++i)
+ {
+ dev = devs[i];
+
+ /* Note: since libusb-1.0.16 (LIBUSB_API_VERSION >= 0x01000102)
+ this function always succeeds. */
+ if (libusb_get_device_descriptor(dev, &desc) != LIBUSB_SUCCESS)
+ continue; /* Unable to get device descriptor */
+
+ if (!dfu_check_id(desc.idVendor, desc.idProduct, pid_list))
+ continue;
+
+ dfuh->rc = libusb_open(dev, &(dfuh->devh));
+ if (!dfu_libusb_chkrc(dfuh, "Could not open USB device"))
+ goto error;
+
+ dfuh->rc = libusb_set_configuration(dfuh->devh, 1);
+ if (!dfu_libusb_chkrc(dfuh, "Could not set USB configuration"))
+ goto error;
+
+ dfuh->rc = libusb_kernel_driver_active(dfuh->devh, 0);
+ if (dfuh->rc != LIBUSB_ERROR_NOT_SUPPORTED) {
+ if (!dfu_libusb_chkrc(dfuh, "Could not get USB driver status"))
+ goto error;
+ if (dfuh->rc == 1) {
+ dfuh->rc = libusb_detach_kernel_driver(dfuh->devh, 0);
+ if (!dfu_libusb_chkrc(dfuh, "Could not detach USB driver"))
+ goto error;
+ dfuh->detached = 1;
+ }
+ }
+
+ dfuh->rc = libusb_claim_interface(dfuh->devh, 0);
+ if (!dfu_libusb_chkrc(dfuh, "Could not claim USB interface"))
+ goto error;
+
+ /* ok */
+ snprintf(dfuh->descr, sizeof(dfuh->descr),
+ "[%04x:%04x] at bus %d, device %d, USB ver. %04x",
+ desc.idVendor, desc.idProduct, libusb_get_bus_number(dev),
+ libusb_get_device_address(dev), desc.bcdUSB);
+ dfuh->found_pid = desc.idProduct;
+ break;
+ }
+
+bye:
+ if (devs)
+ libusb_free_device_list(devs, 1);
+ if (!dfuh->found_pid)
+ dfu_libusb_close(dfuh);
+ return dfuh->res;
+
+error:
+ goto bye;
+}
+#endif /* USE_LIBUSBAPI */
+
+/* list of suported APIs:
+ * Windows: winapi and libusb (optional)
+ * Linux and OSX: libusb
+ */
+static struct dfuAPI api_list[] =
+{
+#ifdef WIN32
+ { "winapi",
+ dfu_winapi_open,
+ dfu_winapi_request,
+ dfu_winapi_reset,
+ dfu_winapi_close },
+#endif
+#ifdef USE_LIBUSBAPI
+ { "libusb",
+ dfu_libusb_open,
+ dfu_libusb_request,
+ dfu_libusb_reset,
+ dfu_libusb_close },
+#endif
+#ifdef __APPLE__
+ /* TODO: implement API for OS X < 10.6 ??? */
+#endif
+};
+#define DFU_N_APIS (sizeof(api_list)/sizeof(struct dfuAPI))
+
+/*
+ * mid-layer (common) functions
+ */
+static void dfu_set_errstr(struct dfuDev *dfuh, char *str)
+{
+ strncpy(dfuh->err, str, sizeof(dfuh->err));
+}
+
+static int DEBUG_DFUREQ = 0;
+
+static int dfu_request(struct dfuDev *dfuh,
+ struct usbControlSetup *cs, void *data)
+{
+ if (!DEBUG_DFUREQ)
+ return dfuh->api->dfureq_fn(dfuh, cs, data);
+
+ /* DEBUG */
+
+ /* previous state */
+ unsigned char ste = 0;
+ struct usbControlSetup css = { 0xA1, DFU_GETSTATE, 0, 0, sizeof(ste) };
+ if (!dfuh->api->dfureq_fn(dfuh, &css, &ste)) {
+ snprintf(dfuh->err + strlen(dfuh->err), sizeof(dfuh->err) -
+ strlen(dfuh->err), " [DEBUG_DFUREQ ERROR: state=%d]", ste);
+ return 0;
+ }
+
+ int ret = dfuh->api->dfureq_fn(dfuh, cs, data);
+ fprintf(stderr, "[DEBUG]: REQ: ste=%d, cs=%2x/%d/%d/%d/%d -> %s",
+ ste, cs->bmRequestType, cs->bRequest, cs->wValue,
+ cs->wIndex, cs->wLength, ret ? "ok" : "ERROR");
+ if (cs->bRequest == DFU_GETSTATE)
+ fprintf(stderr, " (state=%d)", *((unsigned char*)(data)));
+ if (cs->bRequest == DFU_GETSTATUS) {
+ struct usbStatusData *sd = (struct usbStatusData*)data;
+ fprintf(stderr, " (status=%d, polltmo=%d, state=%d)", sd->bStatus,
+ (sd->bwPollTimeout2 << 16) | (sd->bwPollTimeout1 << 8) |
+ (sd->bwPollTimeout0), sd->bState);
+ }
+ fputc('\n', stderr);
+ fflush(stderr);
+ return ret;
+}
+
+static int dfureq_getstatus(struct dfuDev *dfuh, int *status,
+ int *poll_tmo /*ms*/, int *state)
+{
+ struct usbStatusData sd = { 0, 0, 0, 0, 0, 0 };
+ struct usbControlSetup cs = { 0xA1, DFU_GETSTATUS, 0, 0, sizeof(sd) };
+ int ret = dfu_request(dfuh, &cs, &sd);
+ if (status) *status = sd.bStatus;
+ if (state) *state = sd.bState;
+ if (poll_tmo) *poll_tmo = (sd.bwPollTimeout2 << 16) |
+ (sd.bwPollTimeout1 << 8) | (sd.bwPollTimeout0);
+ return ret;
+}
+
+static int dfureq_getstate(struct dfuDev *dfuh, int *state)
+{
+ if (!state)
+ return 1; /* nothing to do */
+ unsigned char sts = 0;
+ struct usbControlSetup cs = { 0xA1, DFU_GETSTATE, 0, 0, sizeof(sts) };
+ int ret = dfu_request(dfuh, &cs, &sts);
+ *state = sts;
+ return ret;
+}
+
+static int dfureq_dnload(struct dfuDev* dfuh, uint16_t blknum,
+ uint16_t len, unsigned char *data)
+{
+ struct usbControlSetup cs = { 0x21, DFU_DNLOAD, blknum, 0, len };
+ return dfu_request(dfuh, &cs, data);
+}
+
+/* not used */
+#if 0
+static int dfureq_upload(struct dfuDev* dfuh,
+ uint16_t blknum, uint16_t len, unsigned char *data)
+{
+ struct usbControlSetup cs = { 0xA1, DFU_UPLOAD, blknum, 0, len };
+ return dfu_request(dfuh, &cs, data);
+}
+
+static int dfureq_clrstatus(struct dfuDev* dfuh)
+{
+ struct usbControlSetup cs = { 0x21, DFU_CLRSTATUS, 0, 0, 0 };
+ return dfu_request(dfuh, &cs, NULL);
+}
+
+static int dfureq_abort(struct dfuDev* dfuh)
+{
+ struct usbControlSetup cs = { 0x21, DFU_ABORT, 0, 0, 0 };
+ return dfu_request(dfuh, &cs, NULL);
+}
+
+/* not implemented on DFU8702 */
+static int dfureq_detach(struct dfuDev* dfuh, int tmo)
+{
+ struct usbControlSetup cs = { 0x21, DFU_DETACH, tmo, 0, 0 };
+ return dfu_request(dfuh, &cs, NULL);
+}
+#endif
+
+static int dfu_send_packet(struct dfuDev* dfuh, uint16_t blknum,
+ uint16_t len, unsigned char *data, int *status,
+ int *poll_tmo, int *state, int *pre_state)
+{
+ if (!dfureq_dnload(dfuh, blknum, len, data))
+ return 0;
+
+ /* device is in dfuDLSYNC state, waiting for a GETSTATUS request
+ to enter the next state, if she respond with dfuDLBUSY then
+ we must wait to resend the GETSTATUS request */
+
+ if (!dfureq_getstatus(dfuh, status, poll_tmo, state))
+ return 0;
+
+ if (*state == dfuDNBUSY) {
+ if (*poll_tmo)
+ sleep_ms(*poll_tmo);
+ if (!dfureq_getstate(dfuh, pre_state))
+ return 0;
+ if (!dfureq_getstatus(dfuh, status, poll_tmo, state))
+ return 0;
+ }
+
+ return 1;
+}
+
+static int dfu_download_file(struct dfuDev* dfuh,
+ unsigned char *data, unsigned long size)
+{
+ unsigned int blknum, len, remaining;
+ int status, poll_tmo, state;
+
+ if (!dfureq_getstate(dfuh, &state))
+ goto error;
+
+ if (state != dfuIDLE) {
+ dfu_set_errstr(dfuh, "Could not start DFU download: not idle");
+ goto error;
+ }
+
+ blknum = 0;
+ remaining = size;
+ while (remaining)
+ {
+ len = (remaining < DFU_PKT_SZ) ? remaining : DFU_PKT_SZ;
+
+ if (!dfu_send_packet(dfuh, blknum, len, data +
+ blknum*DFU_PKT_SZ, &status, &poll_tmo, &state, NULL))
+ goto error;
+
+ if (state != dfuDNLOAD_IDLE) {
+ dfu_set_errstr(dfuh, "DFU download aborted: unexpected state");
+ goto error;
+ }
+
+ remaining -= len;
+ blknum++;
+ }
+
+ /* send ZLP */
+ int pre_state = 0;
+ if (!dfu_send_packet(dfuh, blknum, 0, NULL,
+ &status, &poll_tmo, &state, &pre_state)) {
+ if (pre_state == dfuMANIFEST_SYNC)
+ goto ok; /* pwnaged .dfu file */
+ goto error;
+ }
+
+ if (state != dfuMANIFEST) {
+ if (status == errFIRMWARE)
+ dfu_set_errstr(dfuh, "DFU download failed: corrupt firmware");
+ else
+ dfu_set_errstr(dfuh, "DFU download failed: unexpected state");
+ goto error;
+ }
+
+ /* wait for manifest stage */
+ if (poll_tmo)
+ sleep_ms(poll_tmo);
+
+ if (!dfureq_getstatus(dfuh, &status, NULL, &state))
+ goto ok; /* 1223 .dfu file */
+
+
+ /* TODO: next code never tested */
+
+ if (state != dfuMANIFEST_WAIT_RESET) {
+ if (status == errVERIFY)
+ dfu_set_errstr(dfuh, "DFU manifest failed: wrong FW verification");
+ else
+ dfu_set_errstr(dfuh, "DFU manifest failed: unexpected state");
+ goto error;
+ }
+
+ if (!dfuh->api->reset_fn(dfuh))
+ goto error;
+
+ok:
+ return 1;
+error:
+ return 0;
+}
+
+static int dfu_open(struct dfuDev *dfuh, int pid)
+{
+ int pid_l[2] = {0};
+ struct dfuAPI *api;
+ unsigned i;
+
+ pid_l[0] = pid;
+
+ for (i = 0; i < DFU_N_APIS; i++)
+ {
+ api = &api_list[i];
+ if (!(api->open_fn(dfuh, pid ? pid_l : KNOWN_PIDS)))
+ return 0; /* error */
+ if (dfuh->found_pid) {
+ dfuh->api = api;
+ printf("[INFO] %s: found %s\n", api->name, dfuh->descr);
+ fflush(stdout);
+ return 1; /* ok */
+ }
+ printf("[INFO] %s: no DFU devices found\n", api->name);
+ fflush(stdout);
+ }
+
+ dfu_set_errstr(dfuh, "DFU device not found");
+ return 0;
+}
+
+static void dfu_destroy(struct dfuDev *dfuh)
+{
+ if (dfuh) {
+ if (dfuh->api)
+ dfuh->api->close_fn(dfuh);
+ free(dfuh);
+ }
+}
+
+static struct dfuDev *dfu_create()
+{
+ return calloc(sizeof(struct dfuDev), 1);
+}
+
+/*
+ * exported functions
+ */
+int ipoddfu_send(int pid, unsigned char *data, int size,
+ char* errstr, int errstrsize)
+{
+ struct dfuDev *dfuh;
+ unsigned char *buf;
+ unsigned int checksum;
+ int ret = 1; /* ok */
+
+ dfuh = dfu_create();
+
+ buf = malloc(size+4);
+ if (!buf) {
+ dfu_set_errstr(dfuh, "Could not allocate memory for DFU buffer");
+ goto error;
+ }
+
+ if (memcmp(data, IM3_IDENT, 4)) {
+ dfu_set_errstr(dfuh, "Bad DFU image data");
+ goto error;
+ }
+
+ /* FIXME: big endian */
+ crc32_init();
+ checksum = crc32(data, size, CRC32_DEFAULT_SEED);
+ memcpy(buf, data, size);
+ memcpy(buf+size, &checksum, 4);
+
+ if (!dfu_open(dfuh, pid))
+ goto error;
+
+ if (!dfu_download_file(dfuh, buf, size+4))
+ goto error;
+
+bye:
+ if (buf) free(buf);
+ dfu_destroy(dfuh);
+ return ret;
+
+error:
+ ret = 0;
+ if (errstr)
+ snprintf(errstr, errstrsize, "[ERR] %s", dfuh->err);
+ goto bye;
+}
+
+/* search for the DFU device and gets its DFUState */
+int ipoddfu_scan(int pid, int *state, int reset,
+ char* errstr, int errstrsize)
+{
+ struct dfuDev *dfuh;
+ int ret = 1; /* ok */
+
+ dfuh = dfu_create();
+
+ if (!dfu_open(dfuh, pid))
+ goto error;
+
+ if (reset)
+ if (!dfuh->api->reset_fn(dfuh))
+ goto error;
+
+ if (!dfureq_getstate(dfuh, state))
+ goto error;
+
+bye:
+ dfu_destroy(dfuh);
+ return ret;
+
+error:
+ ret = 0;
+ if (errstr)
+ snprintf(errstr, errstrsize, "[ERR] %s", dfuh->err);
+ goto bye;
+}
+
+void ipoddfu_debug(int debug)
+{
+ DEBUG_DFUREQ = debug;
+}
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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:$
+ *
+ * Copyright (C) 2015 by Cástor Muñoz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "mks5lboot.h"
+
+/* Win32 compatibility */
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#define DEFAULT_LOOP_PERIOD 1 /* seconds */
+
+#define ERROR(format, ...) \
+ do { \
+ snprintf(errstr, errstrsize, "[ERR] "format, __VA_ARGS__); \
+ goto error; \
+ } while(0)
+
+static int write_file(char *outfile, unsigned char* buf,
+ int bufsize, char* errstr, int errstrsize)
+{
+ int fd = open(outfile, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, 0666);
+ if (fd < 0)
+ ERROR("Could not open %s for writing", outfile);
+
+ if (write(fd, buf, bufsize) != bufsize)
+ ERROR("Could not write file %s", outfile);
+
+ return 1;
+
+error:
+ return 0;
+}
+
+static unsigned char *read_file(char *infile, int *bufsize,
+ char* errstr, int errstrsize)
+{
+ unsigned char *buf;
+ int fd;
+ struct stat s;
+
+ fd = open(infile, O_RDONLY|O_BINARY);
+ if (fd < 0)
+ ERROR("Could not open %s for reading", infile);
+
+ if (fstat(fd, &s) < 0)
+ ERROR("Checking size of input file %s", infile);
+
+ *bufsize = s.st_size;
+
+ buf = malloc(*bufsize);
+ if (buf == NULL)
+ ERROR("Could not allocate memory for %s", infile);
+
+ if (read(fd, buf, *bufsize) != *bufsize)
+ ERROR("Could not read file %s", infile);
+
+ return buf;
+
+error:
+ return NULL;
+}
+
+static void sleep_ms(unsigned int ms)
+{
+ struct timespec req;
+ req.tv_sec = ms / 1000;
+ req.tv_nsec = (ms % 1000) * 1000000;
+ nanosleep(&req, NULL);
+}
+
+static void usage(void)
+{
+ fprintf(stderr,
+ "Usage:\n"
+ " mks5lboot --bl-inst <bootloader.ipod> [-p <pid>] [--single]\n"
+ " --bl-uninst <platform> [-p <pid>]\n"
+ " --dfuscan [--loop [<sec>]] [-p <pid>]\n"
+ " --dfusend <infile.dfu> [-p <pid>]\n"
+ " --dfureset [--loop [<sec>]] [-p <pid>]\n"
+ " --mkdfu-inst <bootloader.ipod> <outfile.dfu> [--single]\n"
+ " --mkdfu-uninst <platform> <outfile.dfu>\n"
+ " --mkdfu-raw <filename.bin> <outfile.dfu>\n"
+ "\n"
+ "Commands:\n"
+ " --bl-inst Install file <bootloader.ipod> into an iPod device\n"
+ " (same as --mkdfu-inst and --dfusend).\n"
+ " --bl-uninst Remove a bootloader from an iPod device (same as\n"
+ " --mkdfu-uninst and --dfusend).\n"
+ "\n"
+ " --dfuscan scan for DFU USB devices and outputs the status.\n"
+ " --dfusend send DFU image <infile.dfu> to the device.\n"
+ " --dfureset reset DFU USB device bus.\n"
+ "\n"
+ " --mkdfu-inst Build a DFU image containing an installer for\n"
+ " <bootloader.ipod>, save it as <outfile.dfu>.\n"
+ " --mkdfu-uninst Build a DFU image containing an uninstaler for\n"
+ " <platform> devices, save it as <outfile.dfu>.\n"
+ " --mkdfu-raw Build a DFU image containing raw executable\n"
+ " code, save it ass <outfile.dfu>. <infile.bin>\n"
+ " is the code you want to run, it is loaded at\n"
+ " address 0x%08x and executed.\n"
+ "\n"
+ " <bootloader.ipod> is the rockbox bootloader that you want to\n"
+ " install (previously scrambled with tools/scramble utility).\n"
+ "\n"
+ " <platform> is the name of the platform (type of device) for\n"
+ " which the DFU uninstaller will be built. Currently supported\n"
+ " platform names are:\n"
+ " ipod6g: iPod Classic 6G\n"
+ "\n"
+ "Options:\n"
+ " -p, --pid <pid> Use a specific <pid> (Product Id) USB device,\n"
+ " if this option is ommited then it uses the\n"
+ " first USB DFU device found.\n"
+ " -l, --loop <sec> Run the command every <sec> seconds, default\n"
+ " period (<sec> ommited) is %d seconds.\n"
+ " -S, --single Be careful using this option. The bootloader\n"
+ " is installed for single boot, the original\n"
+ " Apple NOR boot is destroyed (if it exists),\n"
+ " and only Rockbox can be used.\n"
+ , DFU_LOADADDR + BIN_OFFSET
+ , DEFAULT_LOOP_PERIOD);
+
+ exit(1);
+}
+
+int main(int argc, char* argv[])
+{
+ char *dfuoutfile = NULL;
+ char *dfuinfile = NULL;
+ char *dfu_arg = NULL;
+ int dfu_type = DFU_NONE;
+ int n_cmds = 0;
+ int scan = 0;
+ int pid = 0;
+ int reset = 0;
+ int loop = 0;
+ int single = 0;
+ char errstr[200];
+ unsigned char *dfubuf;
+ int dfusize;
+
+ fprintf(stderr,
+ "mks5lboot Version " VERSION "\n"
+ "This is free software; see the source for copying conditions. There is NO\n"
+ "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+ "\n");
+ fflush(stderr);
+
+ while (--argc)
+ {
+ argv++;
+ if (!memcmp(*argv, "--bl", 4)) {
+ if (!strcmp(*argv+4, "-inst")) dfu_type = DFU_INST;
+ else if (!strcmp(*argv+4, "-uninst")) dfu_type = DFU_UNINST;
+ else usage();
+ if (!--argc) usage();
+ dfu_arg = *++argv;
+ n_cmds++;
+ }
+ else if (!memcmp(*argv, "--mkdfu", 7)) {
+ if (!strcmp(*argv+7, "-inst")) dfu_type = DFU_INST;
+ else if (!strcmp(*argv+7, "-uninst")) dfu_type = DFU_UNINST;
+ else if (!strcmp(*argv+7, "-raw")) dfu_type = DFU_RAW;
+ else usage();
+ if (!--argc) usage();
+ dfu_arg = *++argv;
+ if (!--argc) usage();
+ dfuoutfile = *++argv;
+ n_cmds++;
+ }
+ else if (!strcmp(*argv, "--dfusend")) {
+ if (!--argc) usage();
+ dfuinfile = *++argv;
+ n_cmds++;
+ }
+ else if (!strcmp(*argv, "--dfuscan")) {
+ scan = 1;
+ n_cmds++;
+ }
+ else if (!strcmp(*argv, "--dfureset")) {
+ scan = 1;
+ reset = 1;
+ n_cmds++;
+ }
+ else if (!strcmp(*argv, "--pid") || !strcmp(*argv, "-p")) {
+ if (!--argc) usage();
+ if (sscanf(*++argv, "%x", &pid) != 1) usage();
+ }
+ else if (!strcmp(*argv, "--loop") || !strcmp (*argv, "-l")) {
+ if (!(argc-1) || *(argv+1)[0] == '-') {
+ loop = DEFAULT_LOOP_PERIOD;
+ }
+ else {
+ if ((sscanf(*++argv, "%d", &loop) != 1) || !loop) usage();
+ argc--;
+ }
+ }
+ else if (!strcmp(*argv, "--single") || !strcmp(*argv, "-S")) {
+ single = 1;
+ }
+ else if (!strcmp(*argv, "--debug")) {
+ ipoddfu_debug(1);
+ }
+ else
+ usage();
+ }
+
+ if (n_cmds != 1)
+ usage();
+
+ if ((dfu_type == DFU_INST) && single)
+ dfu_type = DFU_INST_SINGLE;
+
+ if (scan) {
+ int cnt = 0;
+ while (1) {
+ int state, res;
+ if (loop) printf("[%d] ", cnt);
+ else printf("[INFO] ");
+ printf("DFU %s:\n", reset ? "reset":"scan");
+ res = ipoddfu_scan(pid, &state, reset, errstr, sizeof(errstr));
+ if (res == 0)
+ printf("%s\n", errstr);
+ else
+ printf("[INFO] DFU device state: %d\n", state);
+ if (!loop)
+ exit(!res);
+ fflush(stdout);
+ sleep_ms(loop*1000);
+ cnt += loop;
+ }
+ }
+
+ if (dfuinfile)
+ dfubuf = read_file(dfuinfile, &dfusize, errstr, sizeof(errstr));
+ else
+ dfubuf = mkdfu(dfu_type, dfu_arg, &dfusize, errstr, sizeof(errstr));
+
+ if (!dfubuf)
+ goto error;
+
+ if (dfuoutfile) {
+ if (write_file(dfuoutfile, dfubuf, dfusize, errstr, sizeof(errstr))) {
+ printf("[INFO] Created file %s (%d bytes)\n", dfuoutfile, dfusize);
+ exit(0);
+ }
+ }
+ else {
+ if (ipoddfu_send(pid, dfubuf, dfusize, errstr, sizeof(errstr))) {
+ printf("[INFO] DFU image sent successfully (%d bytes)\n", dfusize);
+ exit(0);
+ }
+ }
+
+error:
+ printf("%s\n", errstr);
+ exit(1);
+}
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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2015 by Cástor Muñoz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "mks5lboot.h"
+
+/* Header for ARM code binaries */
+#include "dualboot.h"
+
+/* Win32 compatibility */
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+/*
+ * This code is based on emCORE, adds a couple of improvements thanks to
+ * some extra features in Apple's ROM:
+ * - Generic Im3Info header valid for all payloads. It is done by moving
+ * the certificate to a fixed position (before data), and using a 'magic'
+ * value (0x300) for signature offset.
+ * - Some integer overflows in ROM make it possible to use the free space
+ * available in Im3Hdr, resulting a maximum payload size of:
+ * 128 KiB - 0x50 bytes (IM3INFO_SZ) - 700 bytes (CERT_SIZE).
+ */
+
+const struct ipod_models ipod_identity[] =
+{
+ [MODEL_IPOD6G] = {
+ "Classic 6G", "ipod6g", "ip6g", 71,
+ dualboot_install_ipod6g, sizeof(dualboot_install_ipod6g),
+ dualboot_uninstall_ipod6g, sizeof(dualboot_uninstall_ipod6g) },
+};
+
+struct Im3Info s5l8702hdr =
+{
+ .ident = IM3_IDENT,
+ .version = IM3_VERSION,
+ .enc_type = 3,
+ .u.enc34 = {
+ .sign_off = "\x00\x03\x00\x00",
+ .cert_off = "\x50\xF8\xFF\xFF", /* -0x800 + CERT_OFFSET */
+ .cert_sz = "\xBA\x02\x00\x00", /* CERT_SIZE */
+ },
+ .info_sign = "\xC2\x54\x51\x31\xDC\xC0\x84\xA4"
+ "\x7F\xD1\x45\x08\xE8\xFF\xE8\x1D",
+};
+
+unsigned char s5l8702pwnage[/*CERT_SIZE*/] =
+{
+ "\x30\x82\x00\x7A\x30\x66\x02\x00\x30\x0D\x06\x09\x2A\x86\x48\x86"
+ "\xF7\x0D\x01\x01\x05\x05\x00\x30\x0B\x31\x09\x30\x07\x06\x03\x55"
+ "\x04\x03\x13\x00\x30\x1E\x17\x0D\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x17\x0D\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x30\x0B\x31\x09\x30\x07\x06\x03\x55\x04\x03\x13"
+ "\x00\x30\x19\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01"
+ "\x05\x00\x03\x08\x00\x30\x05\x02\x01\x00\x02\x00\x30\x0D\x06\x09"
+ "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05\x05\x00\x03\x01\x00\x30\x82"
+ "\x00\x7A\x30\x66\x02\x00\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D"
+ "\x01\x01\x05\x05\x00\x30\x0B\x31\x09\x30\x07\x06\x03\x55\x04\x03"
+ "\x13\x00\x30\x1E\x17\x0D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x17\x0D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x30\x0B\x31\x09\x30\x07\x06\x03\x55\x04\x03\x13\x00\x30"
+ "\x19\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00"
+ "\x03\x08\x00\x30\x05\x02\x01\x00\x02\x00\x30\x0D\x06\x09\x2A\x86"
+ "\x48\x86\xF7\x0D\x01\x01\x05\x05\x00\x03\x01\x00\x30\x82\x01\xBA"
+ "\x30\x50\x02\x00\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01"
+ "\x05\x05\x00\x30\x00\x30\x1E\x17\x0D\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x17\x0D\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x30\x00\x30\x19\x30\x0D\x06\x09\x2A\x86\x48"
+ "\x86\xF7\x0D\x01\x01\x01\x05\x00\x03\x08\x00\x30\x05\x02\x01\x00"
+ "\x02\x00\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05\x05"
+ "\x00\x03\x82\x01\x55"
+};
+
+static uint32_t get_uint32le(unsigned char* p)
+{
+ return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+}
+
+static uint32_t get_uint32be(unsigned char* p)
+{
+ return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+}
+
+static void put_uint32le(unsigned char* p, uint32_t x)
+{
+ p[0] = x & 0xff;
+ p[1] = (x >> 8) & 0xff;
+ p[2] = (x >> 16) & 0xff;
+ p[3] = (x >> 24) & 0xff;
+}
+
+#define ERROR(format, ...) \
+ do { \
+ snprintf(errstr, errstrsize, "[ERR] "format, __VA_ARGS__); \
+ goto error; \
+ } while(0)
+
+static unsigned char *load_file(char *filename, int *bufsize,
+ const struct ipod_models** model,
+ char* errstr, int errstrsize)
+{
+ int fd, i;
+ struct stat s;
+ unsigned char header[8];
+ unsigned char *buf = NULL;
+ bool is_rbbl = (model);
+
+ fd = open(filename, O_RDONLY|O_BINARY);
+ if (fd < 0)
+ ERROR("Could not open %s for reading", filename);
+
+ if (fstat(fd, &s) < 0)
+ ERROR("Checking filesize of input file %s", filename);
+ *bufsize = s.st_size;
+
+ if (is_rbbl) {
+ /* Read Rockbox header */
+ if (read(fd, header, sizeof(header)) != sizeof(header))
+ ERROR("Could not read file %s", filename);
+ *bufsize -= sizeof(header);
+
+ for (i = 0; i < NUM_MODELS; i++)
+ if (memcmp(ipod_identity[i].rb_model_name, header + 4, 4) == 0)
+ break;
+
+ if (i == NUM_MODELS)
+ ERROR("Model name \"%4.4s\" unknown. "
+ "Is this really a rockbox bootloader?", header + 4);
+
+ *model = &ipod_identity[i];
+ }
+
+ buf = malloc(*bufsize);
+ if (buf == NULL)
+ ERROR("Could not allocate memory for %s", filename);
+
+ if (read(fd, buf, *bufsize) != *bufsize)
+ ERROR("Could not read file %s", filename);
+
+ if (is_rbbl) {
+ /* Check checksum */
+ uint32_t sum = (*model)->rb_model_num;
+ for (i = 0; i < *bufsize; i++) {
+ /* add 8 unsigned bits but keep a 32 bit sum */
+ sum += buf[i];
+ }
+ if (sum != get_uint32be(header))
+ ERROR("Checksum mismatch in %s", filename);
+ }
+
+ close(fd);
+ return buf;
+
+error:
+ if (fd >= 0)
+ close(fd);
+ if (buf)
+ free(buf);
+ return NULL;
+}
+
+unsigned char *mkdfu(int dfu_type, char *dfu_arg, int* dfu_size,
+ char* errstr, int errstrsize)
+{
+ const struct ipod_models *model = NULL;
+ unsigned char *dfu_buf = NULL;
+ unsigned char *f_buf;
+ int f_size;
+ uint32_t padded_bl_size;
+ uint32_t cert_off, cert_sz;
+ off_t cur_off;
+ char *dfu_desc;
+ int i;
+
+ switch (dfu_type)
+ {
+ case DFU_INST:
+ case DFU_INST_SINGLE:
+ f_buf = load_file(dfu_arg, &f_size, &model, errstr, errstrsize);
+ if (f_buf == NULL)
+ goto error;
+ /* IM3 data size should be padded to 16 */
+ padded_bl_size = ((f_size + 0xf) & ~0xf);
+ *dfu_size = BIN_OFFSET + (model->dualboot_install_size +
+ (IM3HDR_SZ - (int)IM3INFO_SZ) + (int)padded_bl_size);
+ dfu_desc = (dfu_type == DFU_INST_SINGLE) ? "BL installer (single)"
+ : "BL installer";
+ break;
+
+ case DFU_UNINST:
+ for (i = 0; i < NUM_MODELS; i++) {
+ if (!strcmp(ipod_identity[i].platform_name, dfu_arg)) {
+ model = &ipod_identity[i];
+ break;
+ }
+ }
+ if (!model)
+ ERROR("Platform name \"%s\" unknown", dfu_arg);
+
+ *dfu_size = BIN_OFFSET + model->dualboot_uninstall_size;
+ dfu_desc = "BL uninstaller";
+ break;
+
+ case DFU_RAW:
+ default:
+ f_buf = load_file(dfu_arg, &f_size, NULL, errstr, errstrsize);
+ if (f_buf == NULL)
+ goto error;
+ /* IM3 data size should be padded to 16 */
+ *dfu_size = BIN_OFFSET + ((f_size + 0xf) & ~0xf);
+ dfu_desc = "raw binary";
+ break;
+ }
+
+ printf("[INFO] Building DFU:\n");
+ printf("[INFO] type: %s\n", dfu_desc);
+ if ((dfu_type == DFU_INST) || (dfu_type == DFU_INST_SINGLE))
+ printf("[INFO] BL size: %d\n", f_size);
+ if (dfu_type == DFU_RAW)
+ printf("[INFO] BIN size: %d\n", f_size);
+ printf("[INFO] DFU size: %d\n", *dfu_size);
+ if (model) {
+ printf("[INFO] model name: %s\n", model->model_name);
+ printf("[INFO] platform: %s\n", model->platform_name);
+ printf("[INFO] RB name: %s\n", model->rb_model_name);
+ printf("[INFO] RB num: %d\n", model->rb_model_num);
+ }
+
+ if (*dfu_size > DFU_MAXSIZE)
+ ERROR("DFU image (%d bytes) too big", *dfu_size);
+
+ dfu_buf = calloc(*dfu_size, 1);
+ if (!dfu_buf)
+ ERROR("Could not allocate %d bytes for DFU image", *dfu_size);
+
+ cert_off = get_uint32le(s5l8702hdr.u.enc34.cert_off);
+ cert_sz = get_uint32le(s5l8702hdr.u.enc34.cert_sz);
+
+ memcpy(dfu_buf, &s5l8702hdr, sizeof(s5l8702hdr));
+
+ cur_off = IM3HDR_SZ + cert_off;
+
+ memcpy(dfu_buf + cur_off, s5l8702pwnage, sizeof(s5l8702pwnage));
+
+ /* set entry point */
+ cur_off += cert_sz - 4;
+ put_uint32le(dfu_buf + cur_off, DFU_LOADADDR + BIN_OFFSET);
+
+ cur_off = BIN_OFFSET;
+
+ switch (dfu_type)
+ {
+ case DFU_INST:
+ case DFU_INST_SINGLE:
+ /* copy the dualboot installer binary */
+ memcpy(dfu_buf + cur_off, model->dualboot_install,
+ model->dualboot_install_size);
+ /* point to the start of the included IM3 header info */
+ cur_off += model->dualboot_install_size - IM3INFO_SZ;
+ /* set bootloader data size */
+ struct Im3Info *bl_info = (struct Im3Info*)(dfu_buf + cur_off);
+ put_uint32le(bl_info->data_sz, padded_bl_size);
+ /* use info_sign to pass params to the dualboot installer */
+ if (dfu_type == DFU_INST_SINGLE)
+ bl_info->info_sign[0] = 0x1;
+ /* add bootloader binary */
+ cur_off += IM3HDR_SZ;
+ memcpy(dfu_buf + cur_off, f_buf, f_size);
+ break;
+
+ case DFU_UNINST:
+ /* copy the dualboot uninstaller binary */
+ memcpy(dfu_buf + cur_off, model->dualboot_uninstall,
+ model->dualboot_uninstall_size);
+ break;
+
+ case DFU_RAW:
+ default:
+ /* add raw binary */
+ memcpy(dfu_buf + cur_off, f_buf, f_size);
+ break;
+ }
+
+ return dfu_buf;
+
+error:
+ if (dfu_buf)
+ free(dfu_buf);
+ return NULL;
+}
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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:$
+ *
+ * Copyright (C) 2015 by Cástor Muñoz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef __MK6GBOOT_H__
+#define __MK6GBOOT_H__
+
+/* useful for dualboot.lds */
+#define DFU_LOADADDR 0x22000000
+#define DFU_MAXSIZE 0x20000 /* maximum .dfu file size */
+
+#define CERT_OFFSET 0x50 /* IM3INFO_SZ */
+#define CERT_SIZE 698
+#define BIN_OFFSET (CERT_OFFSET + ((CERT_SIZE + 0x3) & ~ 0x3))
+#define MAX_PAYLOAD (DFU_MAXSIZE - BIN_OFFSET)
+
+#ifndef ASM
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define IM3_IDENT "8702"
+#define IM3_VERSION "1.0"
+#define IM3HDR_SZ 0x800
+#define IM3INFO_SZ (sizeof(struct Im3Info))
+#define IM3INFOSIGN_SZ (offsetof(struct Im3Info, info_sign))
+
+#define SIGN_SZ 16
+
+struct Im3Info
+{
+ uint8_t ident[4];
+ uint8_t version[3];
+ uint8_t enc_type;
+ uint8_t entry[4]; /* LE */
+ uint8_t data_sz[4]; /* LE */
+ union {
+ struct {
+ uint8_t data_sign[SIGN_SZ];
+ uint8_t _reserved[32];
+ } enc12;
+ struct {
+ uint8_t sign_off[4]; /* LE */
+ uint8_t cert_off[4]; /* LE */
+ uint8_t cert_sz[4]; /* LE */
+ uint8_t _reserved[36];
+ } enc34;
+ } u;
+ uint8_t info_sign[SIGN_SZ];
+} __attribute__ ((packed));
+
+struct Im3Hdr
+{
+ struct Im3Info info;
+ uint8_t _zero[IM3HDR_SZ - sizeof(struct Im3Info)];
+} __attribute__ ((packed));
+
+
+/* Supported models */
+enum {
+ MODEL_UNKNOWN = -1,
+ MODEL_IPOD6G = 0,
+ /* new models go here */
+
+ NUM_MODELS
+};
+
+struct ipod_models {
+ /* Descriptive name of this model */
+ const char* model_name;
+ /* for bootloader uninstallers */
+ const char* platform_name;
+ /* Model name used in the Rockbox header in ".ipod" files - these match the
+ -add parameter to the "scramble" tool */
+ const char* rb_model_name;
+ /* Model number used to initialise the checksum in the Rockbox header in
+ ".ipod" files - these are the same as MODEL_NUMBER in config-target.h */
+ const int rb_model_num;
+ /* Dualboot functions for this model */
+ const unsigned char* dualboot_install;
+ int dualboot_install_size;
+ const unsigned char* dualboot_uninstall;
+ int dualboot_uninstall_size;
+};
+extern const struct ipod_models ipod_identity[];
+
+
+enum {
+ DFU_NONE = -1,
+ DFU_INST, /* RB installer */
+ DFU_INST_SINGLE, /* RB installer (single) */
+ DFU_UNINST, /* RB uninstaller */
+ DFU_RAW /* raw binary */
+};
+
+unsigned char *mkdfu(int dfu_type, char *dfu_arg, int* dfu_size,
+ char* errstr, int errstrsize);
+
+int ipoddfu_send(int pid, unsigned char *buf, int size,
+ char* errstr, int errstrsize);
+int ipoddfu_scan(int pid, int *state, int reset,
+ char* errstr, int errstrsize);
+void ipoddfu_debug(int debug);
+
+#ifdef __cplusplus
+};
+#endif
+#endif /* ASM */
+
+#endif /* __MK6GBOOT_H__ */