summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCástor Muñoz <cmvidal@gmail.com>2017-05-04 10:52:03 +0200
committerCástor Muñoz <cmvidal@gmail.com>2017-06-19 02:00:30 +0200
commitfbbba9292b07d91916d330b31e7f8644d65ff91a (patch)
tree191d6ad03986d3e469a1dc32c11f2d423601dec7
parentcf168d4636b81e414f11ef2c69b1430302d33c3b (diff)
mks5lboot: updates
- fix Makefile to allow cross compilation - Windows: use Sleep() instead of nanosleep() - Windows: libusb now is optional - OS X: use IOKit instead of libusb - small rework on the DFU API Change-Id: Ia4b07012c098ad608594e15f6effe9c9d2164b9b
-rw-r--r--rbutil/mks5lboot/.gitignore3
-rw-r--r--rbutil/mks5lboot/Makefile20
-rw-r--r--rbutil/mks5lboot/README49
-rw-r--r--rbutil/mks5lboot/ipoddfu.c624
-rw-r--r--rbutil/mks5lboot/main.c41
-rw-r--r--rbutil/mks5lboot/mkdfu.c22
6 files changed, 492 insertions, 267 deletions
diff --git a/rbutil/mks5lboot/.gitignore b/rbutil/mks5lboot/.gitignore
index 9078451a7a..9b9b1de6ab 100644
--- a/rbutil/mks5lboot/.gitignore
+++ b/rbutil/mks5lboot/.gitignore
@@ -1,2 +1,5 @@
buildposix/
+buildmingw/
+builddarwin/
mks5lboot
+mks5lboot.exe
diff --git a/rbutil/mks5lboot/Makefile b/rbutil/mks5lboot/Makefile
index ba118eefd0..72ea521d5f 100644
--- a/rbutil/mks5lboot/Makefile
+++ b/rbutil/mks5lboot/Makefile
@@ -4,6 +4,7 @@
# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
# \/ \/ \/ \/ \/
+CC := gcc
CFLAGS += -Wall -Wextra
OUTPUT = mks5lboot
@@ -15,18 +16,25 @@ SOURCES := $(LIBSOURCES) main.c
# dependencies for binary
EXTRADEPS :=
-ifeq ($(findstring MINGW,$(shell uname)),MINGW)
+CPPDEFINES := $(shell echo foo | $(CROSS)$(CC) -dM -E -)
+
+ifeq ($(findstring WIN32,$(CPPDEFINES)),WIN32)
LDOPTS += -lsetupapi
-# optional libusb support on Windows
-ifdef DISABLE_LIBUSBAPI
-CFLAGS += -DNO_LIBUSBAPI
-else
+# optional libusb support (needed for WinUSB and libusbK drivers)
+ifeq ($(findstring MINGW,$(CPPDEFINES)),MINGW)
+ifeq ($(USE_LIBUSBAPI),1)
+CFLAGS += -DUSE_LIBUSBAPI
LDOPTS += -Wl,-Bstatic -lusb-1.0
endif
+endif
else
-# Linux, OS X
+ifeq ($(findstring APPLE,$(CPPDEFINES)),APPLE)
+LDOPTS += -L/usr/local/lib -framework IOKit -framework CoreFoundation
+else # Linux
+CFLAGS += -DUSE_LIBUSBAPI
LDOPTS += -lusb-1.0
endif
+endif
include ../libtools.make
diff --git a/rbutil/mks5lboot/README b/rbutil/mks5lboot/README
index c2df299867..c424f7e617 100644
--- a/rbutil/mks5lboot/README
+++ b/rbutil/mks5lboot/README
@@ -5,7 +5,7 @@ A tool to install/uninstall a dual bootloader into a s5l8702 based
device:
- iPod Classic 6G
- - iPod Nano 3G (TODO)
+ - iPod Nano 3G (WIP)
Usage
@@ -97,32 +97,40 @@ Prerequisites:
[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
+ . When 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).
+ b) Use Apple Mobile Device USB driver (included with iTunes). To
+ install this driver without iTunes see https://www.freemyipod.org
+ /wiki/EmCORE_Installation/iPodClassic/InstalliTunesDrivers
Command line install:
- If you are using iTunes on Windows, close iTunes and kill (or pause)
iTunesHelper.exe before entering DFU mode.
+ - If you are using iTunes on Mac, quit iTunes and kill (or pause) the
+ iTunesHelper process before entering DFU mode.
+ You can use "ps x | grep iTunesHelper" to locate the process <PID>,
+ use "kill -STOP <PID>" to suspend the process and "kill -CONT <PID>"
+ to resume it once the bootloader is installed.
+
- 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
+ ./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
+ ./mks5lboot --bl-inst path/to/bootloader-ipod6g.ipod
- When the DFU imagen is loaded and executed, the device emits an 'alive'
+ When the DFU image 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
@@ -132,10 +140,15 @@ Command line install:
- To remove a previously installed bootloader, build the DFU uninstaler
and send it to the device:
- mks5lboot --bl-uninst ipod6g
+ ./mks5lboot --bl-uninst ipod6g
+
+ Notes:
+
+ - If USB access is denied, try to run the mks5lboot tool using a privileged
+ user (i.e. Administrator or root).
+
+ - On Windows, use 'mks5lboot' or 'mks5lboot.exe' instead of './mks5lboot'.
- If USB access is denied, try to run the mks5lboot tool using a privileged
- user (i.e. Administrator or root).
Dual-Boot
@@ -192,14 +205,20 @@ To build the DFU single-boot installer and send it to the device:
mks5lboot --bl-inst --single /path/to/bootloader-ipod6g.ipod
-Compilation
------------
+Build
+-----
+
+To build type 'make'.
+
+Linux needs libusb >= 1.0, use your package manager to install libusb.
-Needs libusb > 1.0 installed, tested on:
+For Windows, to build with libusb support type 'make USE_LIBUSBAPI=1'.
-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
+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
+ MXE: i686-w64-mingw32.static-gcc 5.4.0 + libusb-1.0.21
Hacking
diff --git a/rbutil/mks5lboot/ipoddfu.c b/rbutil/mks5lboot/ipoddfu.c
index 6d303d6603..5e2914af4b 100644
--- a/rbutil/mks5lboot/ipoddfu.c
+++ b/rbutil/mks5lboot/ipoddfu.c
@@ -22,28 +22,32 @@
* KIND, either express or implied.
*
****************************************************************************/
-#ifndef NO_LIBUSBAPI
-#define USE_LIBUSBAPI
-#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <stdbool.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
+#ifdef __APPLE__
+#include <CoreFoundation/CoreFoundation.h>
+#include <IOKit/IOCFPlugIn.h>
+#include <IOKit/usb/IOUSBLib.h>
+#endif
#include "mks5lboot.h"
+#ifdef WIN32
+#define sleep_ms(ms) Sleep(ms)
+#else
+#include <time.h>
static void sleep_ms(unsigned int ms)
{
struct timespec req;
@@ -51,36 +55,36 @@ static void sleep_ms(unsigned int ms)
req.tv_nsec = (ms % 1000) * 1000000;
nanosleep(&req, NULL);
}
+#endif
+
+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;
+}
/*
* CRC32 functions
* Based on public domain implementation by Finn Yannick Jacobs.
- */
-
-/* Written and copyright 1999 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];
+static uint32_t 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)
+/* Calculate crc32 */
+static uint32_t crc32(void *data, unsigned int len, uint32_t previousCrc32)
{
- uint8_t *d = data;
-
+ uint32_t crc = ~previousCrc32;
+ unsigned char *d = (unsigned char*) data;
while (len--)
- {
- seed = ((seed >> 8) & 0x00FFFFFF) ^ crc32table [(seed ^ *d++) & 0xFF];
- }
-
- return seed;
+ crc = (crc >> 8) ^ crc32table[(crc & 0xFF) ^ *d++];
+ return ~crc;
}
/* Calculate crc32table */
@@ -89,55 +93,49 @@ 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)
- {
+ for (j = 0; j < 8; ++j)
crc = (crc >> 1) ^ ((crc & 1) ? poly : 0);
- }
-
crc32table[i] = crc;
}
}
-
-/*
- * DFU
- */
-
-/* must be pow2 <= wTransferSize (2048) */
-#define DFU_PKT_SZ 2048
-
+/* USB */
#define APPLE_VID 0x05AC
-static int KNOWN_PIDS[] =
+struct pid_info {
+ int pid;
+ int mode; /* 0->DFU, 1->WTF */
+ char *desc;
+};
+
+struct pid_info 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 */
+ { 0x1220, 0, "Nano 2G" },
+ { 0x1223, 0, "Nano 3G / Classic" },
+ { 0x1224, 0, "Shuffle 3G" },
+ { 0x1225, 0, "Nano 4G" },
+ { 0x1231, 0, "Nano 5G" },
+ { 0x1232, 0, "Nano 6G" },
+ { 0x1233, 0, "Shuffle 4G" },
+ { 0x1234, 0, "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
+ { 0x1240, 1, "Nano 2G" },
+ { 0x1241, 1, "Classic 1G" },
+ { 0x1242, 1, "Nano 3G" },
+ { 0x1243, 1, "Nano 4G" },
+ { 0x1245, 1, "Classic 2G" },
+ { 0x1246, 1, "Nano 5G" },
+ { 0x1247, 1, "Classic 3G" },
+ { 0x1248, 1, "Nano 6G" },
+ { 0x1249, 1, "Nano 7G" },
+ { 0x124a, 1, "Nano 7G" },
+ { 0x1250, 1, "Classic 4G" },
};
+#define N_KNOWN_PIDS (sizeof(known_pids)/sizeof(struct pid_info))
struct usbControlSetup {
uint8_t bmRequestType;
@@ -157,8 +155,14 @@ struct usbStatusData {
uint8_t iString;
} __attribute__ ((packed));
+
+/*
+ * DFU API
+ */
+#define DFU_PKT_SZ 2048 /* must be pow2 <= wTransferSize (2048) */
+
/* DFU 1.1 specs */
-typedef enum DFUState {
+typedef enum {
appIDLE = 0,
appDETACH = 1,
dfuIDLE = 2,
@@ -172,7 +176,7 @@ typedef enum DFUState {
dfuERROR = 10
} DFUState;
-typedef enum DFUStatus {
+typedef enum {
errNONE = 0,
errTARGET = 1,
errFILE = 2,
@@ -191,7 +195,7 @@ typedef enum DFUStatus {
errSTALLEDPKT = 15
} DFUStatus;
-typedef enum DFURequest {
+typedef enum {
DFU_DETACH = 0,
DFU_DNLOAD = 1,
DFU_UPLOAD = 2,
@@ -201,12 +205,17 @@ typedef enum DFURequest {
DFU_ABORT = 6
} DFURequest;
+typedef enum {
+ DFUAPIFail = 0,
+ DFUAPISuccess,
+} dfuAPIResult;
+
struct dfuDev {
struct dfuAPI *api;
int found_pid;
int detached;
char descr[256];
- int res; /* API result: 1->ok, 0->failure */
+ dfuAPIResult res;
char err[256];
/* API private */
#ifdef WIN32
@@ -219,21 +228,25 @@ struct dfuDev {
libusb_device_handle* devh;
int rc; /* libusb return code */
#endif
+#ifdef __APPLE__
+ IOUSBDeviceInterface** dev;
+ kern_return_t kr;
+#endif
};
struct dfuAPI {
char *name;
- int (*open_fn)(struct dfuDev*, int*);
- int (*dfureq_fn)(struct dfuDev*, struct usbControlSetup*, void*);
- int (*reset_fn)(struct dfuDev*);
+ dfuAPIResult (*open_fn)(struct dfuDev*, int*);
+ dfuAPIResult (*dfureq_fn)(struct dfuDev*, struct usbControlSetup*, void*);
+ dfuAPIResult (*reset_fn)(struct dfuDev*);
void (*close_fn)(struct dfuDev*);
};
/*
- * low-level (API specific) functions
+ * DFU API low-level (specific) functions
*/
-static int dfu_check_id(int vid, int pid, int *pid_list)
+static bool dfu_check_id(int vid, int pid, int *pid_list)
{
int *p;
if (vid != APPLE_VID)
@@ -253,17 +266,17 @@ static void dfu_add_reqerrstr(struct dfuDev *dfuh, struct usbControlSetup *cs)
}
#ifdef WIN32
-static int dfu_winapi_chkrc(struct dfuDev *dfuh, char *str, bool success)
+static bool dfu_winapi_chkrc(struct dfuDev *dfuh, char *str, bool success)
{
- dfuh->res = (int)success;
+ dfuh->res = (success) ? DFUAPISuccess : DFUAPIFail;
if (!success) {
dfuh->ec = GetLastError();
snprintf(dfuh->err, sizeof(dfuh->err), "%s error %ld", str, dfuh->ec);
}
- return dfuh->res;
+ return success;
}
-static int dfu_winapi_request(struct dfuDev *dfuh,
+static dfuAPIResult dfu_winapi_request(struct dfuDev *dfuh,
struct usbControlSetup* cs, void* data)
{
unsigned char buf[USB_CS_SZ + DFU_PKT_SZ];
@@ -284,19 +297,20 @@ static int dfu_winapi_request(struct dfuDev *dfuh,
rc = WriteFile(dfuh->ph, buf, USB_CS_SZ + cs->wLength, &rdwr, NULL);
dfu_winapi_chkrc(dfuh, "DFU request failed: WriteFile()", rc);
}
-
- if (!dfuh->res)
+ if (!rc)
dfu_add_reqerrstr(dfuh, cs);
+
return dfuh->res;
}
-static int dfu_winapi_reset(struct dfuDev *dfuh)
+static dfuAPIResult 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,
+ bool rc = DeviceIoControl(dfuh->fh,
+ 0x22000c, NULL, 0, NULL, 0, &bytesReturned, NULL);
+ dfu_winapi_chkrc(dfuh,
"Could not reset USB device: DeviceIoControl()", rc);
+ return dfuh->res;
}
static void dfu_winapi_close(struct dfuDev *dfuh)
@@ -314,7 +328,7 @@ static void dfu_winapi_close(struct dfuDev *dfuh)
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)
+static dfuAPIResult dfu_winapi_open(struct dfuDev *dfuh, int *pid_list)
{
const GUID *guid = &GUID_AAPLDFU;
HDEVINFO devinfo = NULL;
@@ -327,7 +341,7 @@ static int dfu_winapi_open(struct dfuDev *dfuh, int *pid_list)
dfuh->fh =
dfuh->ph = INVALID_HANDLE_VALUE;
dfuh->found_pid = 0;
- dfuh->res = 1; /* ok */
+ dfuh->res = DFUAPISuccess;
dfuh->ec = 0;
/* Get DFU path */
@@ -398,16 +412,16 @@ error:
#endif /* WIN32 */
#ifdef USE_LIBUSBAPI
-static int dfu_libusb_chkrc(struct dfuDev *dfuh, char *str)
+static bool dfu_libusb_chkrc(struct dfuDev *dfuh, char *str)
{
- dfuh->res = (dfuh->rc < LIBUSB_SUCCESS) ? 0 : 1;
- if (dfuh->res == 0)
+ dfuh->res = (dfuh->rc < LIBUSB_SUCCESS) ? DFUAPIFail : DFUAPISuccess;
+ if (dfuh->res == DFUAPIFail)
snprintf(dfuh->err, sizeof(dfuh->err),
"%s: %s", str, libusb_error_name(dfuh->rc));
- return dfuh->res;
+ return (dfuh->res == DFUAPISuccess);
}
-static int dfu_libusb_request(struct dfuDev *dfuh,
+static dfuAPIResult dfu_libusb_request(struct dfuDev *dfuh,
struct usbControlSetup *cs, void *data)
{
dfuh->rc = libusb_control_transfer(dfuh->devh, cs->bmRequestType,
@@ -417,10 +431,11 @@ static int dfu_libusb_request(struct dfuDev *dfuh,
return dfuh->res;
}
-static int dfu_libusb_reset(struct dfuDev *dfuh)
+static dfuAPIResult dfu_libusb_reset(struct dfuDev *dfuh)
{
dfuh->rc = libusb_reset_device(dfuh->devh);
- return dfu_libusb_chkrc(dfuh, "Could not reset USB device");
+ dfu_libusb_chkrc(dfuh, "Could not reset USB device");
+ return dfuh->res;
}
static void dfu_libusb_close(struct dfuDev *dfuh)
@@ -438,7 +453,7 @@ static void dfu_libusb_close(struct dfuDev *dfuh)
}
}
-static int dfu_libusb_open(struct dfuDev *dfuh, int *pid_list)
+static dfuAPIResult dfu_libusb_open(struct dfuDev *dfuh, int *pid_list)
{
struct libusb_device_descriptor desc;
libusb_device **devs = NULL, *dev;
@@ -447,7 +462,7 @@ static int dfu_libusb_open(struct dfuDev *dfuh, int *pid_list)
dfuh->devh = NULL;
dfuh->found_pid = 0;
dfuh->detached = 0;
- dfuh->res = 1; /* ok */
+ dfuh->res = DFUAPISuccess;
dfuh->rc = libusb_init(&(dfuh->ctx));
if (!dfu_libusb_chkrc(dfuh, "Could not init USB library")) {
@@ -517,10 +532,138 @@ error:
}
#endif /* USE_LIBUSBAPI */
-/* list of suported APIs:
- * Windows: winapi and libusb (optional)
- * Linux and OSX: libusb
- */
+#ifdef __APPLE__
+static bool dfu_iokit_chkrc(struct dfuDev *dfuh, char *str)
+{
+ dfuh->res = (dfuh->kr == kIOReturnSuccess) ? DFUAPISuccess : DFUAPIFail;
+ if (dfuh->res == DFUAPIFail)
+ snprintf(dfuh->err, sizeof(dfuh->err),
+ "%s: error %08x", str, dfuh->kr);
+ return (dfuh->res == DFUAPISuccess);
+}
+
+static dfuAPIResult dfu_iokit_request(struct dfuDev *dfuh,
+ struct usbControlSetup *cs, void *data)
+{
+ IOUSBDevRequest req;
+ req.bmRequestType = cs->bmRequestType;
+ req.bRequest = cs->bRequest;
+ req.wValue = cs->wValue;
+ req.wIndex = cs->wIndex;
+ req.wLength = cs->wLength;
+ req.pData = data;
+
+ dfuh->kr = (*(dfuh->dev))->DeviceRequest(dfuh->dev, &req);
+ if (!dfu_iokit_chkrc(dfuh, "DFU request failed"))
+ dfu_add_reqerrstr(dfuh, cs);
+
+ return dfuh->res;
+}
+
+static dfuAPIResult dfu_iokit_reset(struct dfuDev *dfuh)
+{
+ dfuh->kr = (*(dfuh->dev))->ResetDevice(dfuh->dev);
+#if 0
+ /* On 10.11+ ResetDevice() returns no error but does not perform
+ * any reset, just a kernel log message.
+ * USBDeviceReEnumerate() could be used as a workaround.
+ */
+ dfuh->kr = (*(dfuh->dev))->USBDeviceReEnumerate(dfuh->dev, 0);
+#endif
+ dfu_iokit_chkrc(dfuh, "Could not reset USB device");
+ return dfuh->res;
+}
+
+static void dfu_iokit_close(struct dfuDev *dfuh)
+{
+ if (dfuh->dev) {
+ (*(dfuh->dev))->USBDeviceClose(dfuh->dev);
+ (*(dfuh->dev))->Release(dfuh->dev);
+ dfuh->dev = NULL;
+ }
+}
+
+static dfuAPIResult dfu_iokit_open(struct dfuDev *dfuh, int *pid_list)
+{
+ kern_return_t kr;
+ CFMutableDictionaryRef usb_matching_dict = 0;
+ io_object_t usbDevice;
+ io_iterator_t usb_iterator = IO_OBJECT_NULL;
+ IOCFPlugInInterface **plugInInterface = NULL;
+ IOUSBDeviceInterface **dev = NULL;
+ HRESULT result;
+ SInt32 score;
+ UInt16 vendor;
+ UInt16 product;
+ UInt16 release;
+
+ dfuh->dev = NULL;
+ dfuh->found_pid = 0;
+ dfuh->res = DFUAPISuccess;
+
+ usb_matching_dict = IOServiceMatching(kIOUSBDeviceClassName);
+ dfuh->kr = IOServiceGetMatchingServices(
+ kIOMasterPortDefault, usb_matching_dict, &usb_iterator);
+ if (!dfu_iokit_chkrc(dfuh, "Could not get matching services"))
+ goto error;
+
+ while ((usbDevice = IOIteratorNext(usb_iterator)))
+ {
+ /* Create an intermediate plug-in */
+ kr = IOCreatePlugInInterfaceForService(usbDevice,
+ kIOUSBDeviceUserClientTypeID,
+ kIOCFPlugInInterfaceID,
+ &plugInInterface,
+ &score);
+ IOObjectRelease(usbDevice);
+
+ if ((kIOReturnSuccess != kr) || !plugInInterface)
+ continue; /* Unable to create a plugin */
+
+ /* Now create the device interface */
+ result = (*plugInInterface)->QueryInterface(plugInInterface,
+ CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID),
+ (LPVOID*)&dev);
+ (*plugInInterface)->Release(plugInInterface);
+
+ if (result || !dev)
+ continue; /* Couldn't create a device interface */
+
+ kr = (*dev)->GetDeviceVendor(dev, &vendor);
+ kr = (*dev)->GetDeviceProduct(dev, &product);
+ kr = (*dev)->GetDeviceReleaseNumber(dev, &release);
+
+ if (!dfu_check_id(vendor, product, pid_list)) {
+ (*dev)->Release(dev);
+ continue;
+ }
+
+ /* Device found, open it */
+ dfuh->kr = (*dev)->USBDeviceOpen(dev);
+ if (!dfu_iokit_chkrc(dfuh, "Could not open USB device")) {
+ (*dev)->Release(dev);
+ goto error;
+ }
+
+ /* ok */
+ dfuh->found_pid = product;
+ dfuh->dev = dev;
+ snprintf(dfuh->descr, sizeof(dfuh->descr),
+ "[%04x:%04x] release: %d", vendor, product, release);
+ break;
+ }
+
+bye:
+ if (usb_iterator != IO_OBJECT_NULL)
+ IOObjectRelease(usb_iterator);
+ return dfuh->res;
+
+error:
+ goto bye;
+}
+#endif /* __APPLE__ */
+
+/* list of suported APIs */
static struct dfuAPI api_list[] =
{
#ifdef WIN32
@@ -538,22 +681,22 @@ static struct dfuAPI api_list[] =
dfu_libusb_close },
#endif
#ifdef __APPLE__
- /* TODO: implement API for OS X < 10.6 ??? */
+ { "IOKit",
+ dfu_iokit_open,
+ dfu_iokit_request,
+ dfu_iokit_reset,
+ dfu_iokit_close },
#endif
};
-#define DFU_N_APIS (sizeof(api_list)/sizeof(struct dfuAPI))
+#define N_DFU_APIS (sizeof(api_list)/sizeof(struct dfuAPI))
+
/*
- * mid-layer (common) functions
+ * DFU API 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,
+static dfuAPIResult dfuapi_request(struct dfuDev *dfuh,
struct usbControlSetup *cs, void *data)
{
if (!DEBUG_DFUREQ)
@@ -564,16 +707,17 @@ static int dfu_request(struct dfuDev *dfuh,
/* previous state */
unsigned char ste = 0;
struct usbControlSetup css = { 0xA1, DFU_GETSTATE, 0, 0, sizeof(ste) };
- if (!dfuh->api->dfureq_fn(dfuh, &css, &ste)) {
+ if (dfuh->api->dfureq_fn(dfuh, &css, &ste) != DFUAPISuccess) {
snprintf(dfuh->err + strlen(dfuh->err), sizeof(dfuh->err) -
strlen(dfuh->err), " [DEBUG_DFUREQ ERROR: state=%d]", ste);
- return 0;
+ goto error;
}
- int ret = dfuh->api->dfureq_fn(dfuh, cs, data);
+ 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");
+ cs->wIndex, cs->wLength,
+ (dfuh->res == DFUAPISuccess) ? "ok" : "ERROR");
if (cs->bRequest == DFU_GETSTATE)
fprintf(stderr, " (state=%d)", *((unsigned char*)(data)));
if (cs->bRequest == DFU_GETSTATUS) {
@@ -584,106 +728,189 @@ static int dfu_request(struct dfuDev *dfuh,
}
fputc('\n', stderr);
fflush(stderr);
- return ret;
+
+bye:
+ return dfuh->res;
+error:
+ goto bye;
}
-static int dfureq_getstatus(struct dfuDev *dfuh, int *status,
- int *poll_tmo /*ms*/, int *state)
+static dfuAPIResult dfuapi_req_getstatus(struct dfuDev *dfuh,
+ DFUStatus *status, int *poll_tmo /*ms*/,
+ DFUState *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);
+ dfuapi_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;
+ return dfuh->res;
}
-static int dfureq_getstate(struct dfuDev *dfuh, int *state)
+static dfuAPIResult dfuapi_req_getstate(struct dfuDev *dfuh, DFUState *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;
+ dfuapi_request(dfuh, &cs, &sts);
+ if (state) *state = sts;
+ return dfuh->res;
}
-static int dfureq_dnload(struct dfuDev* dfuh, uint16_t blknum,
+static dfuAPIResult dfuapi_req_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);
+ return dfuapi_request(dfuh, &cs, data);
}
/* not used */
#if 0
-static int dfureq_upload(struct dfuDev* dfuh,
+static dfuAPIResult dfuapi_req_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);
+ return dfuapi_request(dfuh, &cs, data);
}
-static int dfureq_clrstatus(struct dfuDev* dfuh)
+static dfuAPIResult dfuapi_req_clrstatus(struct dfuDev* dfuh)
{
struct usbControlSetup cs = { 0x21, DFU_CLRSTATUS, 0, 0, 0 };
- return dfu_request(dfuh, &cs, NULL);
+ return dfuapi_request(dfuh, &cs, NULL);
}
-static int dfureq_abort(struct dfuDev* dfuh)
+static dfuAPIResult dfuapi_req_abort(struct dfuDev* dfuh)
{
struct usbControlSetup cs = { 0x21, DFU_ABORT, 0, 0, 0 };
- return dfu_request(dfuh, &cs, NULL);
+ return dfuapi_request(dfuh, &cs, NULL);
}
/* not implemented on DFU8702 */
-static int dfureq_detach(struct dfuDev* dfuh, int tmo)
+static dfuAPIResult dfuapi_req_detach(struct dfuDev* dfuh, int tmo)
{
struct usbControlSetup cs = { 0x21, DFU_DETACH, tmo, 0, 0 };
- return dfu_request(dfuh, &cs, NULL);
+ return dfuapi_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)
+static dfuAPIResult dfuapi_reset(struct dfuDev *dfuh)
{
- if (!dfureq_dnload(dfuh, blknum, len, data))
- return 0;
+ return dfuh->api->reset_fn(dfuh);
+}
+
+static dfuAPIResult dfuapi_send_packet(struct dfuDev* dfuh, uint16_t blknum,
+ uint16_t len, unsigned char *data, DFUStatus *status,
+ int *poll_tmo, DFUState *state, DFUState *pre_state)
+{
+ if (dfuapi_req_dnload(dfuh, blknum, len, data) != DFUAPISuccess)
+ goto error;
/* 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 */
+ * 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 (dfuapi_req_getstatus(dfuh, status, poll_tmo, state) != DFUAPISuccess)
+ goto error;
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;
+ if (pre_state)
+ if (dfuapi_req_getstate(dfuh, pre_state) != DFUAPISuccess)
+ goto error;
+ if (dfuapi_req_getstatus(dfuh, status, poll_tmo, state) != DFUAPISuccess)
+ goto error;
}
- return 1;
+bye:
+ return dfuh->res;
+error:
+ goto bye;
+}
+
+static void dfuapi_set_err(struct dfuDev *dfuh, char *str)
+{
+ dfuh->res = DFUAPIFail;
+ strncpy(dfuh->err, str, sizeof(dfuh->err));
+}
+
+static dfuAPIResult dfuapi_open(struct dfuDev *dfuh, int pid)
+{
+ int pid_l[N_KNOWN_PIDS+1] = { 0 };
+ struct dfuAPI *api;
+ unsigned i, p;
+
+ /* fill pid list */
+ if (pid)
+ pid_l[0] = pid;
+ else
+ for (p = 0; p < N_KNOWN_PIDS; p++)
+ pid_l[p] = known_pids[p].pid;
+
+ for (i = 0; i < N_DFU_APIS; i++)
+ {
+ api = &api_list[i];
+ if (api->open_fn(dfuh, pid_l) != DFUAPISuccess)
+ goto error;
+ if (dfuh->found_pid) {
+ /* ok */
+ dfuh->api = api;
+ printf("[INFO] %s: found %s\n", api->name, dfuh->descr);
+ for (p = 0; p < N_KNOWN_PIDS; p++) {
+ if (known_pids[p].pid == dfuh->found_pid) {
+ printf("[INFO] iPod %s, mode: %s\n", known_pids[p].desc,
+ known_pids[p].mode ? "WTF" : "DFU");
+ break;
+ }
+ }
+ fflush(stdout);
+ goto bye;
+ }
+ printf("[INFO] %s: no DFU devices found\n", api->name);
+ fflush(stdout);
+ }
+
+ /* error */
+ dfuapi_set_err(dfuh, "DFU device not found");
+
+bye:
+ return dfuh->res;
+error:
+ goto bye;
}
-static int dfu_download_file(struct dfuDev* dfuh,
+static void dfuapi_destroy(struct dfuDev *dfuh)
+{
+ if (dfuh) {
+ if (dfuh->api)
+ dfuh->api->close_fn(dfuh);
+ free(dfuh);
+ }
+}
+
+static struct dfuDev *dfuapi_create(void)
+{
+ return calloc(sizeof(struct dfuDev), 1);
+}
+
+
+/*
+ * app level functions
+ */
+static int ipoddfu_download_file(struct dfuDev* dfuh,
unsigned char *data, unsigned long size)
{
unsigned int blknum, len, remaining;
- int status, poll_tmo, state;
+ int poll_tmo;
+ DFUStatus status;
+ DFUState state;
- if (!dfureq_getstate(dfuh, &state))
+ if (dfuapi_req_getstate(dfuh, &state) != DFUAPISuccess)
goto error;
if (state != dfuIDLE) {
- dfu_set_errstr(dfuh, "Could not start DFU download: not idle");
+ dfuapi_set_err(dfuh, "Could not start DFU download: not idle");
goto error;
}
@@ -693,12 +920,12 @@ static int dfu_download_file(struct dfuDev* dfuh,
{
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))
+ if (dfuapi_send_packet(dfuh, blknum, len, data + blknum*DFU_PKT_SZ,
+ &status, &poll_tmo, &state, NULL) != DFUAPISuccess)
goto error;
if (state != dfuDNLOAD_IDLE) {
- dfu_set_errstr(dfuh, "DFU download aborted: unexpected state");
+ dfuapi_set_err(dfuh, "DFU download aborted: unexpected state");
goto error;
}
@@ -707,9 +934,9 @@ static int dfu_download_file(struct dfuDev* dfuh,
}
/* send ZLP */
- int pre_state = 0;
- if (!dfu_send_packet(dfuh, blknum, 0, NULL,
- &status, &poll_tmo, &state, &pre_state)) {
+ DFUState pre_state = appIDLE; /* dummy state */
+ if (dfuapi_send_packet(dfuh, blknum, 0, NULL,
+ &status, &poll_tmo, &state, &pre_state) != DFUAPISuccess) {
if (pre_state == dfuMANIFEST_SYNC)
goto ok; /* pwnaged .dfu file */
goto error;
@@ -717,9 +944,9 @@ static int dfu_download_file(struct dfuDev* dfuh,
if (state != dfuMANIFEST) {
if (status == errFIRMWARE)
- dfu_set_errstr(dfuh, "DFU download failed: corrupt firmware");
+ dfuapi_set_err(dfuh, "DFU download failed: corrupt firmware");
else
- dfu_set_errstr(dfuh, "DFU download failed: unexpected state");
+ dfuapi_set_err(dfuh, "DFU download failed: unexpected state");
goto error;
}
@@ -727,21 +954,20 @@ static int dfu_download_file(struct dfuDev* dfuh,
if (poll_tmo)
sleep_ms(poll_tmo);
- if (!dfureq_getstatus(dfuh, &status, NULL, &state))
+ if (dfuapi_req_getstatus(dfuh, &status, NULL, &state) != DFUAPISuccess)
goto ok; /* 1223 .dfu file */
-
- /* TODO: next code never tested */
+ /* XXX: next code never tested */
if (state != dfuMANIFEST_WAIT_RESET) {
if (status == errVERIFY)
- dfu_set_errstr(dfuh, "DFU manifest failed: wrong FW verification");
+ dfuapi_set_err(dfuh, "DFU manifest failed: wrong FW verification");
else
- dfu_set_errstr(dfuh, "DFU manifest failed: unexpected state");
+ dfuapi_set_err(dfuh, "DFU manifest failed: unexpected state");
goto error;
}
- if (!dfuh->api->reset_fn(dfuh))
+ if (dfuapi_reset(dfuh) != DFUAPISuccess)
goto error;
ok:
@@ -750,86 +976,42 @@ 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
- */
+/* 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;
+ uint32_t checksum;
int ret = 1; /* ok */
- dfuh = dfu_create();
+ dfuh = dfuapi_create();
buf = malloc(size+4);
if (!buf) {
- dfu_set_errstr(dfuh, "Could not allocate memory for DFU buffer");
+ dfuapi_set_err(dfuh, "Could not allocate memory for DFU buffer");
goto error;
}
if (memcmp(data, IM3_IDENT, 4)) {
- dfu_set_errstr(dfuh, "Bad DFU image data");
+ dfuapi_set_err(dfuh, "Bad DFU image data");
goto error;
}
- /* FIXME: big endian */
crc32_init();
- checksum = crc32(data, size, CRC32_DEFAULT_SEED);
+ checksum = crc32(data, size, 0);
memcpy(buf, data, size);
- memcpy(buf+size, &checksum, 4);
+ put_uint32le(buf+size, ~checksum);
- if (!dfu_open(dfuh, pid))
+ if (dfuapi_open(dfuh, pid) != DFUAPISuccess)
goto error;
- if (!dfu_download_file(dfuh, buf, size+4))
+ if (!ipoddfu_download_file(dfuh, buf, size+4))
goto error;
bye:
if (buf) free(buf);
- dfu_destroy(dfuh);
+ dfuapi_destroy(dfuh);
return ret;
error:
@@ -846,20 +1028,24 @@ int ipoddfu_scan(int pid, int *state, int reset,
struct dfuDev *dfuh;
int ret = 1; /* ok */
- dfuh = dfu_create();
+ dfuh = dfuapi_create();
- if (!dfu_open(dfuh, pid))
+ if (dfuapi_open(dfuh, pid) != DFUAPISuccess)
goto error;
if (reset)
- if (!dfuh->api->reset_fn(dfuh))
+ if (dfuapi_reset(dfuh) != DFUAPISuccess)
goto error;
- if (!dfureq_getstate(dfuh, state))
- goto error;
+ if (state) {
+ DFUState sts;
+ if (dfuapi_req_getstate(dfuh, &sts) != DFUAPISuccess)
+ goto error;
+ *state = (int)sts;
+ }
bye:
- dfu_destroy(dfuh);
+ dfuapi_destroy(dfuh);
return ret;
error:
diff --git a/rbutil/mks5lboot/main.c b/rbutil/mks5lboot/main.c
index 98c85b9bb7..31e16eca82 100644
--- a/rbutil/mks5lboot/main.c
+++ b/rbutil/mks5lboot/main.c
@@ -24,7 +24,6 @@
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
-#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -35,9 +34,23 @@
#define O_BINARY 0
#endif
+#ifdef WIN32
+#include <windows.h>
+#define sleep_ms(ms) Sleep(ms)
+#else
+#include <time.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);
+}
+#endif
+
#define DEFAULT_LOOP_PERIOD 1 /* seconds */
-#define ERROR(format, ...) \
+#define _ERR(format, ...) \
do { \
snprintf(errstr, errstrsize, "[ERR] "format, __VA_ARGS__); \
goto error; \
@@ -48,10 +61,10 @@ static int write_file(char *outfile, unsigned char* buf,
{
int fd = open(outfile, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, 0666);
if (fd < 0)
- ERROR("Could not open %s for writing", outfile);
+ _ERR("Could not open %s for writing", outfile);
if (write(fd, buf, bufsize) != bufsize)
- ERROR("Could not write file %s", outfile);
+ _ERR("Could not write file %s", outfile);
return 1;
@@ -68,19 +81,19 @@ static unsigned char *read_file(char *infile, int *bufsize,
fd = open(infile, O_RDONLY|O_BINARY);
if (fd < 0)
- ERROR("Could not open %s for reading", infile);
+ _ERR("Could not open %s for reading", infile);
if (fstat(fd, &s) < 0)
- ERROR("Checking size of input file %s", infile);
+ _ERR("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);
+ _ERR("Could not allocate memory for %s", infile);
if (read(fd, buf, *bufsize) != *bufsize)
- ERROR("Could not read file %s", infile);
+ _ERR("Could not read file %s", infile);
return buf;
@@ -88,14 +101,6 @@ 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,
@@ -169,7 +174,11 @@ int main(int argc, char* argv[])
int dfusize;
fprintf(stderr,
+#if defined(WIN32) && defined(USE_LIBUSBAPI)
+ "mks5lboot Version " VERSION " (libusb)\n"
+#else
"mks5lboot Version " VERSION "\n"
+#endif
"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");
diff --git a/rbutil/mks5lboot/mkdfu.c b/rbutil/mks5lboot/mkdfu.c
index 6ac0daf1ac..bb1929bffd 100644
--- a/rbutil/mks5lboot/mkdfu.c
+++ b/rbutil/mks5lboot/mkdfu.c
@@ -117,7 +117,7 @@ static void put_uint32le(unsigned char* p, uint32_t x)
p[3] = (x >> 24) & 0xff;
}
-#define ERROR(format, ...) \
+#define _ERR(format, ...) \
do { \
snprintf(errstr, errstrsize, "[ERR] "format, __VA_ARGS__); \
goto error; \
@@ -135,16 +135,16 @@ static unsigned char *load_file(char *filename, int *bufsize,
fd = open(filename, O_RDONLY|O_BINARY);
if (fd < 0)
- ERROR("Could not open %s for reading", filename);
+ _ERR("Could not open %s for reading", filename);
if (fstat(fd, &s) < 0)
- ERROR("Checking filesize of input file %s", filename);
+ _ERR("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);
+ _ERR("Could not read file %s", filename);
*bufsize -= sizeof(header);
for (i = 0; i < NUM_MODELS; i++)
@@ -152,7 +152,7 @@ static unsigned char *load_file(char *filename, int *bufsize,
break;
if (i == NUM_MODELS)
- ERROR("Model name \"%4.4s\" unknown. "
+ _ERR("Model name \"%4.4s\" unknown. "
"Is this really a rockbox bootloader?", header + 4);
*model = &ipod_identity[i];
@@ -160,10 +160,10 @@ static unsigned char *load_file(char *filename, int *bufsize,
buf = malloc(*bufsize);
if (buf == NULL)
- ERROR("Could not allocate memory for %s", filename);
+ _ERR("Could not allocate memory for %s", filename);
if (read(fd, buf, *bufsize) != *bufsize)
- ERROR("Could not read file %s", filename);
+ _ERR("Could not read file %s", filename);
if (is_rbbl) {
/* Check checksum */
@@ -173,7 +173,7 @@ static unsigned char *load_file(char *filename, int *bufsize,
sum += buf[i];
}
if (sum != get_uint32be(header))
- ERROR("Checksum mismatch in %s", filename);
+ _ERR("Checksum mismatch in %s", filename);
}
close(fd);
@@ -223,7 +223,7 @@ unsigned char *mkdfu(int dfu_type, char *dfu_arg, int* dfu_size,
}
}
if (!model)
- ERROR("Platform name \"%s\" unknown", dfu_arg);
+ _ERR("Platform name \"%s\" unknown", dfu_arg);
*dfu_size = BIN_OFFSET + model->dualboot_uninstall_size;
dfu_desc = "BL uninstaller";
@@ -255,11 +255,11 @@ unsigned char *mkdfu(int dfu_type, char *dfu_arg, int* dfu_size,
}
if (*dfu_size > DFU_MAXSIZE)
- ERROR("DFU image (%d bytes) too big", *dfu_size);
+ _ERR("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);
+ _ERR("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);