8 Commits
31 changed files with 737 additions and 1483 deletions

No files matched your search

+2 -7
View File
@@ -2,10 +2,6 @@ sudo: false
language: c
arch:
- AMD64
- ppc64le
compiler:
- gcc
- clang
@@ -13,15 +9,14 @@ compiler:
addons: &addons
apt:
packages:
- libusb-1.0-0-dev
- pkg-config
- libusb-dev
matrix:
include:
- compiler: gcc
if: (branch = master) AND (type != pull_request)
env:
- secure: "f+qBVyDcDe/9IUmWcqlhL81s4QdY/eHeJW81Zfkfulu0Iai20Ro/lnj0PxVHeSo12cldUTG0XhY1GURYLe2RNdtB2ooe3d9JGn9uFrkyDNhmHcOuJQKY/g2XQ0gJQ9tpWkZhSzENl2C9H/uz87oGqSqwlCLdwixekk8vrmH5kpnNXtbgfK3EKWbhGN0Zub70+qeLa7jTShMN3HgJbrkDYgxUPMofqOCHp8W1xPIvUjNS4yQtN/Ahl6g7z79xopgCvGI91ZkAigSHJGBeHoq3rxG+ecoK+AprhiXuIZ8tD8bHv5IpKEi6mFGf4Fo0mQw+1b8g0HLBwWoiR5Yz7fv6fRgDhuK2AqZZmK8J6q13Lxl/DZS93hTeSJPk9FBEvJsPRwDUgy0P6HObmmEnmclERd9aqcK4RxrQkTjWK+rhHtoRg1kB2QiLz0dNpXQ/CTImv5jooYibo2TCyH6nBcEKzIxSQABvorEwpn7rx7UqL+rFqCQgLrqcRgCna615XpxpS+/W8VeScp2y1MzClwuudBaOiEAK5b6xa6HWk7RDQPkUAYmsnlFZ3zDbTiMzpKRYp/I2N6CPD50PX8lRJpxDSn6qL0HC0qCaYZqlKA+kKxl+OWbtUWM9mE9MJE3V8RRQO8g5p1mJ8NpjdOx7wwYk09BIp6YYPLXLj32hKn4kfXo="
- secure: "JdUp+xFykPZoYA4aRfmYk2CtilLapniQllWPKo2dDdJd1vzdawfTvVxIAKjy7ac9RKwZzg3Chq3RsMEXPv8BtaLbssw266C7RDLMgjacl1eFLcmGRj/Gkk9peDSZ6vVdGEcA2j+6KDSfpCa/XjFjvOufZOgKw6m+3+d0A4G45SI="
addons:
<<: *addons
coverity_scan:
+3 -9
View File
@@ -1,15 +1,9 @@
Installation instructions:
==========================
To build the flasher you will need gcc, make and libusb-1.0 (version 1.0.16
or newer). Compiler and linker flags for libusb-1.0 are detected by pkg-config;
without it set LIBUSB_CFLAGS and LIBUSB_LIBS manually (see config.mk), e.g.:
$ make LIBUSB_CFLAGS=-I/opt/homebrew/opt/libusb/include/libusb-1.0 \
LIBUSB_LIBS="-L/opt/homebrew/opt/libusb/lib -lusb-1.0"
For crosscompiling to arm you can use scratchbox. But you will probably need
the libusb-1.0.so of the scratchbox environment to the device.
To build the flasher you will need gcc, make and libusb. For crosscompiling
to arm you can use scratchbox. But you will probably need the libusb.so of
the scratchbox environment to the device.
Just type:
+13 -13
View File
@@ -10,24 +10,24 @@
_/ ___|_.|__|
'`
0xFFFF is the Open Free Fiasco Firmware Flasher for Maemo devices. It supports
generating and unpacking FIASCO images. It is useful for editing Maemo firmware
packages before flashing. It supports flashing via USB any image type to a
Maemo device and also \"cold\" flashing which means flashing dead device with
erased bootloader. There is support for booting kernel via USB without flashing
to NAND and also changing configuration of Maemo device (enable/disable R&D
mode, changing HW revision strings, ...).
0xFFFF is Open Free Fiasco Firmware Flasher for Maemo devices. It support
generating and unpacking FIASCO images on local computer. Useful for editing
Maemo firmware package for future flash. It support via USB flashing any image
type to Maemo device and also \"cold\" flashing which means flashing dead device
with erased bootloader. There is support for booting kernel via USB without
flashing to NAND and also changing configuration of Maemo device (enable/disable
R&D mode, changing HW revision strings, ...).
0xFFFF is an alternative tool to proprietary Nokia flasher-3.5 and fiasco-gen.
0xFFFF generates compatible FIASCO images and also accepts FIASCO images
generated by Nokia fiasco-gen.
0xFFFF is alternative tool to proprietary Nokia flasher-3.5 and fiasco-gen.
0xFFFF generate compatible FIASCO images and also accept FIASCO images generated
by Nokia fiasco-gen.
Use it with CARE. This is an experimental tool and it can brick your device.
It's not supposed to be stable, so Nokia will probably release incompatible
It's not supposed to be stable, so nokia will probably release incompatible
bootloaders to break this tool. USE IT AT YOUR OWN RISK.
PLEASE. Read all the documentation inside doc/* carefully before building or
using the flasher to avoid questions, problems or so.
PLEASE. Read carefully all the documentation inside doc/* for more information
before building or using the flasher to avoid questions, problems or so.
https://github.com/pali/0xFFFF
+2
View File
@@ -5,6 +5,7 @@ cold-flash:
* Detect device from asic id
disk:
* Support for flashing mmc images
* Badblock checking
fiasco:
@@ -14,6 +15,7 @@ image:
* Support for Harmattan images
local:
* Support for flashing (on device)
* Write versions
* Badblock checking
+1 -6
View File
@@ -1,11 +1,6 @@
VERSION = 0.10
VERSION = 0.8
PREFIX = /usr/local
# NetBSD stuff
#CPPFLAGS += -I/usr/pkg/include
#LDFLAGS += -L/usr/pkg/lib -Wl,-R/usr/pkg/lib
# libusb-1.0 flags are detected by pkg-config, set them manually without it
# (e.g. macOS with Homebrew libusb on Apple Silicon)
#LIBUSB_CFLAGS = -I/opt/homebrew/opt/libusb/include/libusb-1.0
#LIBUSB_LIBS = -L/opt/homebrew/opt/libusb/lib -lusb-1.0
+27
View File
@@ -0,0 +1,27 @@
0xffff (0.8-1) fremantle; urgency=low
* New upstream version
-- Pali Rohár <pali.rohar@gmail.com> Sun, 08 Jul 2018 12:43:42 +0200
0xffff (0.7-1) fremantle; urgency=low
* New upstream version
-- Pali Rohár <pali.rohar@gmail.com> Sun, 25 Dec 2016 11:47:44 +0100
0xffff (0.6.1-1) experimental; urgency=medium
* New upstream release
- Contains a few security related fixes (memory corruptions & leaks)
- Support for -t (filter by type) for -e (dump images)
- reattach kernel driver
- minor fixes
-- Sebastian Reichel <sre@debian.org> Thu, 11 Dec 2014 21:52:53 +0100
0xffff (0.6-1) unstable; urgency=low
* This is new rewritten version of original 0xFFFF 0.5 tool
-- Pali Rohár <pali.rohar@gmail.com> Sun, 07 Apr 2013 15:01:50 +0200
+1
View File
@@ -0,0 +1 @@
7
+89
View File
@@ -0,0 +1,89 @@
Source: 0xffff
Section: user/system
Priority: extra
Maintainer: Pali Rohár <pali.rohar@gmail.com>
Standards-Version: 3.9.8
Build-Depends: debhelper (>= 7),
libusb-dev
Homepage: https://github.com/pali/0xFFFF
Vcs-Git: https://github.com/pali/0xFFFF.git
Vcs-Browser: https://github.com/pali/0xFFFF/tree/maemo
Package: 0xffff
Architecture: any
Depends: ${misc:Depends}, ${shlibs:Depends}, mtd-utils
Description: Open Free Fiasco Firmware Flasher
The ‘Open Free Fiasco Firmware Flasher’ aka 0xFFFF utility implements
a free userspace handler for the NOLO bootloader and extended features
for flashing, dumping and getting information for the Nokia Internet
Tablets. Thus it's a free alternative to Nokia's closed source flashing
utility called flasher.
.
Supported operations currently include, but are not limited to:
* generating and unpacking FIASCO images on local device
* editing Maemo firmware packages
* flashing any kind image type to Maemo devices via USB
* "cold" flashing for devices with bricked bootloaders
* direct kernel boot without flashing it to NAND
* changing configuration of Maemo device (R&D flags, HW revision strings, ...)
.
Supported are the Nokia 770, N800, N810, N810w, N900, N950 and N9.
XSBC-Maemo-Display-Name: 0xFFFF
XB-Maemo-Icon-26:
iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAGXRFWHRTb2Z0
d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAACYtJREFUeNrUWkurZUcVXvXY
59zbtyXpICEiaFrJQFDo6CDOHAi2UQdOFBw4CAqCDhU0DuIPEBtCRupIBxk4
MBMHgpIMnChE1OAD2uADEkFpUM9z710vv7Wq6ty6u09f0+nb3Tcb6u7Hqb33
96361qq1al/1vscfp+Ac3fjH6+S9v3owP/iYMfqyMaabz2ax62wwtnPDOPgY
ok8pxpQoKKW9UhRC8IFI+UQ4ds7HFKLW1mujffDexRi9MXiGMQG34uborbEO
515pckopZ7RxuN8RyflgtBrxfKeNGlNMY0ppxItGUnowSm3Rr7ezubfdnCwe
SuMw2EsPPvi9x957+SlrNAXvCCTIWkMKvQP6JEYdorQoG6gkUIpo+SgkStyV
SQb0RwOolACOQdBIlAaQ7XGtT4q2lGhDDCjRGsZYg8Qa71sR75WSPe5Z411o
doPfN1rrDs/q8MaVVt5Z5T1dnM++8sEPXHnqXzduxOuv/iVutlsGKeCxJbyE
jxN2uJc3FfkcJzHviBlG5sq/kUq8D4qvyzWKpQ/fzn94H/Mzub88L0hfJc/w
OPc8Ijh3is8xUhqIMZr+woULscMwRmjCwoDdY+959xcXiwX9/KVfRAyV0gYD
xTBVeY2mjJuvAR3+aMrgjPRQKtVzrRSDwE1Kl1uEuBADKCX34g5VzKLk/ihk
lQBl8CKt3IQA5MMEICttPIY5XDw6glSVspv15tGLRxcu/+rl3/D4q9lsJtjl
1WyTA7TxBKRYfjZEO2IMTufRosxdVcoCPvEIQTaBrYlLjuWFH0Z0Y433LC3Y
occ5a3ybz7EvmjdaD9IfvudG57d6G4E12fmse+d6tT76z38XcC6TwcOdEtvj
EGL7jif/fU3x1yaDmWejNuCpEI4ilZT3AFPAwifgA9gPuGMIFAESfqDUBpw2
inWuVNY+6z4l7NkX1ApWgI/QlvuD/qDZoWMEeRskaODBlmJ4oB9HGoYxycCy
1R9OavYtT92nweIRotnn4ZkvBhqfRvc/oM8MUJIQqC00zeemWL/FutRnq8Jp
uam0BtA1yC5x8xLHS7xa9sREEjsy+ogTg4CiASQGpZVDjBMJcTDEEajEeDSM
DjxCHm/s5s96mn0W0ekF3PZ2eSR1n0qk3+/U5koXaQU9G6q6nwCXcMgWF/CF
QAVfQHGESSsmQHTcUiYi0QfH6K8YfF8iGEASnBjagPGgp4SoTdra7tAhEnFc
ZIdVhxD3h3GI1/afgcV/B/pfsnG4plP8pU7q0s76twTPsbyAL3quwKUJUIBa
4HiBvrLHNd6DFI9MqpbvAWsANifPR2iGUnA6JDiwRAcLz547FwQThihxpE5/
Bol3YSS+G0g/iuuPQLxftUHEb9HRngDvmv0O/EQ2FfyqtTg3oBGrcyvgNzje
8nMYKT8XGANvmGhzGG68DzIKc4fJNAmDHC+Gr1kKf1Q0/0Kk7qOJDl/y+vAn
mDyfwOj5E1av4MVJG/CnAW8tn7XfWL6A7xvwwO134GmycUye8+y6+9FCG7/V
kbW+eRJzxcsYlb+q1H0yqQs/852+Ehm2b2QzNpavkmkJTMHv9F4IrCqBBvzY
gOe5aS94IYDOMw7R0oH/HqRkPhJJfyiS+yl+/j3i2FXr+meQ+7wN/J5MWlKE
4xFgy/eNbE61fNF7Bc9EBDzA7sDnWRfx3rlTwYu9Met2nNmIvj1m0YeSPXzR
6fRPIHiii3LrDO49pzyNDSecdtij+XUhsdqneb7GwIvmN9wYPPb8nLHMwCyZ
WHCdull0xghIHgPBk0l/V3H8tlHzrwd9dN1ZhmA/Hg/0OyD26xTdj2Eplo1T
rNFW8xm8Bngrx8tCYNGCLwR2Dgvw/RQ8W/6NgBcCmH2ZgJd8RkmESeM3kW+8
orS9GpX9RNTxFRXG57RzP9Tr9Lra6IcxIg8kg/s4XYXXgHqNSivI6QZAqx34
VRvjJ5bvS7gdVc6Dbgt8HgEE1JRvyK2kYP55ONDzOsyv+QN3zazia5KbsIV6
+zn/UPflcKmZiVPJg8i9oF8dv2H/pDqRUXXYKhukxVFi/EQ2bwq8EAB4Sfkl
rc0kJLNRs2zR8Rm7gKs6nDN4KS7cD8xr/kf6b6mJOJK3ECzb078xV6xvBb5G
GgbPDssZprxn5Een2wIvBJgxW6CkxabMEqk4aYBrSk7DecjOWVe0TQu1Po44
kAVxZEFMZ+mYYwKtbJhkBY/mKni2fDoxPd0mAS73mqSspgmZgJYYz+YZdpGG
HVW3sT6tbxE6V8XyN4Fnh71T8DmMah13TpzTYt0QqOBrmGzj/KbG8X2hskab
Ap5lw5rnRGbkephLzjsFn30AD2IHypUThJJ9IRTnOmn5mg4XSxfwiwJ20ZCR
jHKqebZ8BQ/Nx9MmqDdMQAoOPLg+rJRSgXaVEg3T3KZoejVNhat8JrKpSRk7
rMxObPmzAL8jUPKZpgTMs+wey68ay7fpwLLR/qa1fMlr7gr4EwSK5WNOV2VE
hgJ6O3HQ3ew6Ab8rRKrm26SMl18APp0l+ErAFZ2rov3YyGczyWv2WX65J5c/
kVEiIYu3SofvmECxds/1sKQGx/l967DLKfg9hQjLpm9yeV/Ah7sFvh2BPvuv
LJz4Rj7VYZdTy59SRY37qii6S5tNOaPcFgkxCY5KbMl1ydX3hsry+02yKRnl
/y1Ezm4EkqzZMAj2Xl0WWLcFaAt+57CTdJjJD/cDfK0HhryEsdvGMiInnHYP
+Dq79jU1aMBHukebLbPkuoTRVB24AbwsSx7rPYVIXzPKJh1OdA83Wxx4nYNQ
DqGs7zJhtaFyva+KmoCPdI83duKq91iW0nn9vs0qV00hcqsSMNxry7cFzaaA
5HqA1/T71KyiVctPqig3qV/vC/hcD2QJLWsWWvKfOgKbAn5qeV+qqPhmqqiz
deJs8WVd6yyzabU6E7jJ8qUQSfcbfIlCPOuqKiH+gtKu72wby0sJWAqRcwH+
mECCD+yqMLVbpGoKEUmHzxv4UlIalEZhjVosmKT5i2OtA1rLn2kVdbYE+IOS
0uyknEp7HfUYVeQlQ65fRTZ3oxA5w2xUeaNpw18tEf99UFHWf/iLSLH8uQVf
RyBARltrDaaEEPhbbI408jURmh/TeQWf10ZtF9iRu86mAAImSi4WeLklr5ad
X/BCoOsMf/cdZ11HKJ/4HwdiMHyg0/2cYW8nG+X1IDefzxUI8P9ySP2KITj3
4PMnpqT4ozZrP3bWxq7rUlmle0tsVv6xgWkg/Bg7IxPr/2K8Nbb/CTAAF12f
5l7y6xMAAAAASUVORK5CYII=
+31
View File
@@ -0,0 +1,31 @@
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Source: https://github.com/pali/0xFFFF
Files: *
Copyright: 2007-2012 pancake <pancake@youterm.com>
2011 Michael Buesch <mb@bu3sch.de>
2011-2013 Pali Rohár <pali.rohar@gmail.com>
License: GPL-3+
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 3 of the License, or (at your option) any later
version.
.
On Debian systems, the complete text of the GPL-3 can be found in
/usr/share/common-licenses/GPL-3.
Files: debian/*
Copyright: Sebastian Reichel <sre@debian.org>
License: ISC
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
Vendored
+3
View File
@@ -0,0 +1,3 @@
doc/
TODO
README
Vendored Executable
+7
View File
@@ -0,0 +1,7 @@
#!/usr/bin/make -f
%:
dh $@
override_dh_auto_install:
dh_auto_install -- PREFIX=/usr
+1
View File
@@ -0,0 +1 @@
3.0 (quilt)
+4
View File
@@ -0,0 +1,4 @@
version=3
opts=filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/0xFFFF-$1\.tar\.gz/,pgpsigurlmangle=s/$/.asc/ \
https://github.com/pali/0xFFFF/releases .*/0xffff_(\d\S+)\.orig\.tar\.gz
+3 -2
View File
@@ -30,10 +30,11 @@ Technical details:
For dumping mtd partition is used tool nanddump. Here is example how to dump
kernel image without padding to file zImage:
$ nanddump --omitoob -s 0x00000800 -l 0x001FF800 -f zImage /dev/mtd2
$ nanddump -o -b -s 0x00000800 -l 0x001FF800 -f zImage /dev/mtd2
Params means:
--omitoob - "Omit oob data"
-o - "Omit oob data"
-b - "Omit bad blocks"
-s - "Start address"
-l - "Length"
-f - "Output file"
-3
View File
@@ -38,6 +38,3 @@ $ 0xFFFF -M <file> -u
Generate new FIASCO image image.fiasco from files xloader.bin, nolo.bin, zImage, rootfs and append device&version information (xloader for RX-51 hw revision: 2101 and 2102, version 1.0)
$ 0xFFFF -m RX-51:2101,2102:1.0:xloader:xloader.bin -m RX-51:2101,2102:1.0:secondary:nolo.bin -m 2.6.28:kernel:zImage -m rootfs -g image.fiasco
Generate new FIASCO mmc image mmc_image.fiasco from layout file layout.txt and two partition files mydocs_fat32.bin (with name mydocs) and home.tar (without name) for device RX-51 with image version 1.0
$ 0xFFFF -m RX-51:1.0:mmc:mydocs_fat32.bin@mydocs#home.tar%layout.txt -g mmc_image.fiasco
+16 -66
View File
@@ -38,74 +38,24 @@ IMAGE
1 byte = 0x54 -- signature
1 byte -- number of subsection blocks
block {
1 byte -- type of subsection block
0x2E - file data
0x2F - partition info
0x31 - version
0x32 - device & hw revisions (size of device is 16, hw revision 8)
0x33 - layout
0x34 - image data part block (one block for one data part)
1 byte -- length of subsection block
N bytes -- subsection block data
}
1 byte -- checksum of subsection data without signature (0xFF - xorpair)
N bytes -- image data
FILE DATA BLOCK
1 byte -- asic index (always APE - 0x01)
1 byte -- device type (always NAND - 0x01)
1 byte -- device index (always 0x00)
(start of data block)
1 byte -- type of subsection block (data - always 0x2e)
1 byte -- length of subsection block (data - always 25)
3 bytes -- unknown (always 0x01 0x01 0x00)
2 bytes -- checksum for the image contents (xorpair) (big endian)
12 bytes -- image name type (first byte is FF if is the last image)
4 bytes -- length of image data (big endian)
4 bytes -- load address of image data (big endian, unused always zero)
PARTITION INFO BLOCK
1 byte -- asic index (always APE - 0x01)
1 byte -- device type (always NAND - 0x01)
1 byte -- device index (always 0x00)
4 bytes -- partition version (always 0x00 0x00 0x00 0x00)
4 bytes -- spare (always 0xFF 0xFF 0xFF 0xFF)
4 bytes -- number of partition blocks (big endian)
4 bytes -- unknown (always 0x00 0x00 0x00 0x00)
(end of data block)
block {
1 byte -- partition type (0x03 - kernel, 0x04 - initfs, 0x05 - rootfs)
1 byte -- partition attribute (0x01 - read/write, 0x02 - read-only)
4 bytes -- partition size (big endian, 0 - remaining space)
1 byte -- type of subsection block
'1' - version
'2' - device & hw revisions (size of device is 16, hw revision 8)
'3' - layout
'4' - unknown
'/' - unknown
1 byte -- length of subsection block
N bytes -- subsection block data
}
IMAGE DATA PART BLOCK
4 bytes -- unknown (always 0x00 0x00 0x00 0x00)
4 bytes -- offset (big endian)
4 bytes -- unknown (always 0x00 0x00 0x00 0x00)
4 bytes -- size (big endian)
N bytes -- partition name (prefix) in layout (may be omitted)
LAYOUT DATA BLOCK
N bytes of text data, e.g.:
mmc {
name = "internal";
partition {
fs_type = "vfat";
prefix = "mydocs";
no_create = true;
}
partition {
size = 2048;
fs_type = "ext3";
prefix = "home";
}
partition {
size = 768;
fs_type = "swap";
}
}
1 byte -- unknown (0x00 is accepted, maybe end of subsections?)
N bytes -- image data
+2 -6
View File
@@ -9,13 +9,9 @@ CC ?= cc
CROSS_CC ?= $(CROSS_COMPILE)$(CC)
HOST_CC ?= $(HOST_COMPILE)$(CC)
PKG_CONFIG ?= pkg-config
LIBUSB_CFLAGS ?= $(shell $(PKG_CONFIG) --cflags libusb-1.0 2>/dev/null)
LIBUSB_LIBS ?= $(shell $(PKG_CONFIG) --libs libusb-1.0 2>/dev/null || echo -lusb-1.0)
CPPFLAGS += -DVERSION=\"$(VERSION)\" -DBUILD_DATE="\"$(BUILD_DATE)\"" -D_POSIX_C_SOURCE=200809L -D_FILE_OFFSET_BITS=64
CFLAGS += -W -Wall -O2 -pedantic -std=c99
LIBS += $(LIBUSB_LIBS)
LIBS += -lusb -ldl
DEPENDS = Makefile ../config.mk
@@ -43,7 +39,7 @@ libusb-sniff-64.so: libusb-sniff.c $(DEPENDS)
$(CC) $(CFLAGS) $(LDFLAGS) -fPIC $< -ldl -shared -m64 -o $@
%.o: %.c $(DEPENDS)
$(CROSS_CC) $(CFLAGS) $(CPPFLAGS) $(LIBUSB_CFLAGS) -c -o $@ $<
$(CROSS_CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
install: $(BIN) $(BIN).1
$(INSTALL) -D -m 755 $(BIN) $(DESTDIR)$(PREFIX)/bin/$(BIN)
+22 -22
View File
@@ -167,12 +167,12 @@ struct xloader_msg xloader_msg_create(uint32_t type, struct image * image) {
}
static int read_asic(libusb_device_handle * udev, uint8_t * asic_buffer, int size, int asic_size) {
static int read_asic(usb_dev_handle * udev, uint8_t * asic_buffer, int size, int asic_size) {
int ret;
printf("Waiting for ASIC ID...\n");
ret = usb_bulk_recv(udev, USB_READ_EP, asic_buffer, size, READ_TIMEOUT);
ret = usb_bulk_read(udev, USB_READ_EP, (char *)asic_buffer, size, READ_TIMEOUT);
if ( ret != asic_size )
ERROR_RETURN("Invalid size of ASIC ID", -1);
@@ -180,25 +180,25 @@ static int read_asic(libusb_device_handle * udev, uint8_t * asic_buffer, int siz
}
static int send_2nd(libusb_device_handle * udev, struct image * image) {
static int send_2nd(usb_dev_handle * udev, struct image * image) {
uint8_t buffer[1024];
uint32_t need, sent;
int ret;
printf("Sending OMAP peripheral boot message...\n");
ret = usb_bulk_send(udev, USB_WRITE_EP, &omap_peripheral_msg, sizeof(omap_peripheral_msg), WRITE_TIMEOUT);
ret = usb_bulk_write(udev, USB_WRITE_EP, (char *)&omap_peripheral_msg, sizeof(omap_peripheral_msg), WRITE_TIMEOUT);
if ( ret != sizeof(omap_peripheral_msg) )
ERROR_RETURN("Sending OMAP peripheral boot message failed", -1);
MSLEEP(5);
SLEEP(5000);
printf("Sending 2nd X-Loader image size...\n");
ret = usb_bulk_send(udev, USB_WRITE_EP, &image->size, 4, WRITE_TIMEOUT);
ret = usb_bulk_write(udev, USB_WRITE_EP, (char *)&image->size, 4, WRITE_TIMEOUT);
if ( ret != 4 )
ERROR_RETURN("Sending 2nd X-Loader image size failed", -1);
MSLEEP(5);
SLEEP(5000);
printf("Sending 2nd X-Loader image...\n");
printf_progressbar(0, image->size);
@@ -211,18 +211,18 @@ static int send_2nd(libusb_device_handle * udev, struct image * image) {
ret = image_read(image, buffer, need);
if ( ret == 0 )
break;
if ( usb_bulk_send(udev, USB_WRITE_EP, buffer, ret, WRITE_TIMEOUT) != ret )
if ( usb_bulk_write(udev, USB_WRITE_EP, (char *)buffer, ret, WRITE_TIMEOUT) != ret )
PRINTF_ERROR_RETURN("Sending 2nd X-Loader image failed", -1);
sent += ret;
printf_progressbar(sent, image->size);
}
MSLEEP(50);
SLEEP(50000);
return 0;
}
static int send_secondary(libusb_device_handle * udev, struct image * image) {
static int send_secondary(usb_dev_handle * udev, struct image * image) {
struct xloader_msg init_msg;
uint8_t buffer[1024];
@@ -232,13 +232,13 @@ static int send_secondary(libusb_device_handle * udev, struct image * image) {
init_msg = xloader_msg_create(XLOADER_MSG_TYPE_SEND, image);
printf("Sending X-Loader init message...\n");
ret = usb_bulk_send(udev, USB_WRITE_EP, &init_msg, sizeof(init_msg), WRITE_TIMEOUT);
ret = usb_bulk_write(udev, USB_WRITE_EP, (char *)&init_msg, sizeof(init_msg), WRITE_TIMEOUT);
if ( ret != sizeof(init_msg) )
ERROR_RETURN("Sending X-Loader init message failed", -1);
printf("Waiting for X-Loader response...\n");
MSLEEP(5);
ret = usb_bulk_recv(udev, USB_READ_EP, &buffer, 4, READ_TIMEOUT); /* 4 bytes - dummy value */
SLEEP(5000);
ret = usb_bulk_read(udev, USB_READ_EP, (char *)&buffer, 4, READ_TIMEOUT); /* 4 bytes - dummy value */
if ( ret != 4 )
ERROR_RETURN("No response", -1);
@@ -253,15 +253,15 @@ static int send_secondary(libusb_device_handle * udev, struct image * image) {
ret = image_read(image, buffer, need);
if ( ret == 0 )
break;
if ( usb_bulk_send(udev, USB_WRITE_EP, buffer, ret, WRITE_TIMEOUT) != ret )
if ( usb_bulk_write(udev, USB_WRITE_EP, (char *)buffer, ret, WRITE_TIMEOUT) != ret )
PRINTF_ERROR_RETURN("Sending Secondary image failed", -1);
sent += ret;
printf_progressbar(sent, image->size);
}
printf("Waiting for X-Loader response...\n");
MSLEEP(5);
ret = usb_bulk_recv(udev, USB_READ_EP, &buffer, 4, READ_TIMEOUT); /* 4 bytes - dummy value */
SLEEP(5000);
ret = usb_bulk_read(udev, USB_READ_EP, (char *)&buffer, 4, READ_TIMEOUT); /* 4 bytes - dummy value */
if ( ret != 4 )
ERROR_RETURN("No response", -1);
@@ -269,7 +269,7 @@ static int send_secondary(libusb_device_handle * udev, struct image * image) {
}
static int ping_timeout(libusb_device_handle * udev) {
static int ping_timeout(usb_dev_handle * udev) {
int ret;
int pong = 0;
@@ -281,7 +281,7 @@ static int ping_timeout(libusb_device_handle * udev) {
int try_read = 4;
printf("Sending X-Loader ping message\n");
ret = usb_bulk_send(udev, USB_WRITE_EP, &ping_msg, sizeof(ping_msg), WRITE_TIMEOUT);
ret = usb_bulk_write(udev, USB_WRITE_EP, (char *)&ping_msg, sizeof(ping_msg), WRITE_TIMEOUT);
if ( ret != sizeof(ping_msg) )
ERROR_RETURN("Sending X-Loader ping message failed", -1);
@@ -289,14 +289,14 @@ static int ping_timeout(libusb_device_handle * udev) {
while ( try_read > 0 ) {
uint32_t ping_read;
ret = usb_bulk_recv(udev, USB_READ_EP, &ping_read, sizeof(ping_read), READ_TIMEOUT);
ret = usb_bulk_read(udev, USB_READ_EP, (char *)&ping_read, sizeof(ping_read), READ_TIMEOUT);
if ( ret == sizeof(ping_read) ) {
printf("Got it\n");
pong = 1;
break;
}
MSLEEP(5);
SLEEP(5000);
--try_read;
}
@@ -409,11 +409,11 @@ int leave_cold_flash(struct usb_device_info * dev) {
int ret;
printf("Sending OMAP memory boot message...\n");
ret = usb_bulk_send(dev->udev, USB_WRITE_EP, &omap_memory_msg, sizeof(omap_memory_msg), WRITE_TIMEOUT);
ret = usb_bulk_write(dev->udev, USB_WRITE_EP, (char *)&omap_memory_msg, sizeof(omap_memory_msg), WRITE_TIMEOUT);
if ( ret != sizeof(omap_memory_msg) )
ERROR_RETURN("Sending OMAP memory boot message failed", -1);
MSLEEP(250);
SLEEP(1000000);
return 0;
}
+6 -8
View File
@@ -184,11 +184,9 @@ char ** device_list_alloc_to_bufs(const struct device_list * device_list) {
continue;
}
if ( device_first->hwrevs ) {
for ( i = 0; device_first->hwrevs[i] != -1; ++i )
if ( device_first->hwrevs[i] >= 0 && device_first->hwrevs[i] <= 9999 )
++local;
}
for ( i = 0; device_first->hwrevs[i] != -1; ++i )
if ( device_first->hwrevs[i] >= 0 && device_first->hwrevs[i] <= 9999 )
++local;
size += (1+16+(MAX_HWREVS+1)*8)*(local/MAX_HWREVS+1);
count += local/MAX_HWREVS;
@@ -217,7 +215,7 @@ char ** device_list_alloc_to_bufs(const struct device_list * device_list) {
continue;
}
do {
while ( device_first->hwrevs[i+1] != -1 ) {
uint8_t len = 0;
ret[j] = ++last_ptr;
@@ -230,7 +228,7 @@ char ** device_list_alloc_to_bufs(const struct device_list * device_list) {
for ( k = 0; k < MAX_HWREVS; ++k ) {
if ( ! device_first->hwrevs || device_first->hwrevs[i+1] == -1 )
if ( device_first->hwrevs[i+1] == -1 )
break;
++i;
@@ -248,7 +246,7 @@ char ** device_list_alloc_to_bufs(const struct device_list * device_list) {
++j;
} while ( device_first->hwrevs && device_first->hwrevs[i+1] != -1 );
}
device_first = device_first->next;
+42 -106
View File
@@ -118,7 +118,7 @@ int disk_open_dev(int maj, int min, int partition, int readonly) {
blkdev[len] = 0;
fd = open(blkdev, ((simulate || readonly) ? O_RDONLY : O_RDWR) | O_EXCL | O_NONBLOCK);
fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL | O_NONBLOCK);
if ( fd < 0 ) {
ERROR_INFO("Cannot open block device %s", blkdev);
return -1;
@@ -144,13 +144,13 @@ int disk_open_dev(int maj, int min, int partition, int readonly) {
ERROR("Block device name is too long");
return -1;
}
fd = open(blkdev, ((simulate || readonly) ? O_RDONLY : O_RDWR) | O_EXCL);
fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL);
if ( fd < 0 && errno == ENOENT ) {
if ( snprintf(blkdev+len, sizeof(blkdev)-len, "%d", partition) >= (int)(sizeof(blkdev)-len) ) {
ERROR("Block device name is too long");
return -1;
}
fd = open(blkdev, ((simulate || readonly) ? O_RDONLY : O_RDWR) | O_EXCL);
fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL);
}
if ( fd < 0 && errno == ENOENT ) {
blkdev[len] = 0;
@@ -201,7 +201,7 @@ int disk_open_dev(int maj, int min, int partition, int readonly) {
int disk_dump_dev(int fd, const char * file) {
int fd2 = -1;
int fd2;
int ret;
char * path;
uint64_t blksize;
@@ -253,15 +253,11 @@ int disk_dump_dev(int fd, const char * file) {
return -1;
}
if ( ! simulate ) {
fd2 = creat(file, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if ( fd2 < 0 ) {
ERROR_INFO("Cannot create file %s", file);
return -1;
}
fd2 = creat(file, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if ( fd2 < 0 ) {
ERROR_INFO("Cannot create file %s", file);
return -1;
}
sent = 0;
@@ -274,91 +270,26 @@ int disk_dump_dev(int fd, const char * file) {
size = read(fd, global_buf, need);
if ( size == 0 )
break;
if ( size < 0 ) {
PRINTF_ERROR("Reading from block device failed");
if ( ! simulate )
close(fd2);
if ( write(fd2, global_buf, size) != size ) {
PRINTF_ERROR("Dumping image failed");
close(fd2);
return -1;
}
if ( ! simulate ) {
if ( write(fd2, global_buf, size) != size ) {
PRINTF_ERROR("Dumping image failed");
close(fd2);
return -1;
}
}
sent += size;
printf_progressbar(sent, blksize);
}
if ( ! simulate )
close(fd2);
close(fd2);
return 0;
}
int disk_flash_dev(int fd, struct image * image) {
int disk_flash_dev(int fd, const char * file) {
uint64_t blksize;
size_t need, sent;
ssize_t size;
if ( image->type != IMAGE_MMC )
ERROR_RETURN("Only mmc images are supported", -1);
printf("Writing image to block device...\n");
#ifdef __linux__
if ( ioctl(fd, BLKGETSIZE64, &blksize) != 0 ) {
ERROR_INFO("Cannot get size of block device");
return -1;
}
#else
blksize = lseek(fd, 0, SEEK_END);
if ( (off_t)blksize == (off_t)-1 ) {
ERROR_INFO("Cannot get size of block device");
return -1;
}
if ( lseek(fd, 0, SEEK_SET) == (off_t)-1 ) {
ERROR_INFO("Cannot seek to begin of block device");
return -1;
}
#endif
if ( blksize == 0 )
ERROR_RETURN("Block device has zero size", -1);
if ( image->size > blksize )
ERROR_RETURN("Image is too big", -1);
sent = 0;
printf_progressbar(0, image->size);
while ( sent < image->size ) {
need = image->size - sent;
if ( need > sizeof(global_buf) )
need = sizeof(global_buf);
size = image_read(image, global_buf, need);
if ( size == 0 ) {
PRINTF_ERROR("Failed to read image");
return -1;
}
if ( ! simulate ) {
if ( write(fd, global_buf, size) != size ) {
PRINTF_ERROR("Writing image failed");
return -1;
}
}
sent += size;
printf_progressbar(sent, image->size);
}
return 0;
ERROR("Not implemented yet");
(void)fd;
(void)file;
return -1;
}
@@ -385,9 +316,13 @@ int disk_init(struct usb_device_info * dev) {
unsigned int devnum;
unsigned int busnum;
libusb_device * device;
struct usb_device * device;
device = libusb_get_device(dev->udev);
device = usb_device(dev->udev);
if ( ! device || ! device->bus ) {
ERROR_INFO("Cannot read usb devnum and busnum");
return -1;
}
dir = opendir("/sys/dev/block/");
if ( ! dir ) {
@@ -428,11 +363,16 @@ int disk_init(struct usb_device_info * dev) {
fclose(f);
if ( (unsigned int)libusb_get_device_address(device) != devnum )
if ( device->devnum != devnum )
continue;
if ( (unsigned int)libusb_get_bus_number(device) != busnum )
continue;
if ( device->bus->location ) {
if ( device->bus->location != busnum )
continue;
} else if ( device->bus->dirname[0] ) {
if ( atoi(device->bus->dirname) != (int)busnum )
continue;
}
if ( sscanf(dirent->d_name, "%d:%d", &maj2, &min2) != 2 ) {
maj2 = -1;
@@ -467,14 +407,16 @@ int disk_init(struct usb_device_info * dev) {
maj2 = tmp;
}
/* RX-51, RM-680 and RM-696 export MyDocs in first usb device and just first partion, so host system see whole device without MBR table */
if ( dev->device == DEVICE_RX_51 || dev->device == DEVICE_RM_680 || dev->device == DEVICE_RM_696 )
fd = disk_open_dev(maj1, min1, -1, simulate ? 1 : 0);
/* TODO: change 1 to 0 when disk_flash_dev will be implemented */
/* RX-51 and RM-680 export MyDocs in first usb device and just first partion, so host system see whole device without MBR table */
if ( dev->device == DEVICE_RX_51 || dev->device == DEVICE_RM_680 )
fd = disk_open_dev(maj1, min1, -1, 1);
/* Other devices can export SD card as first partition and export whole mmc device, so host system will see MBR table */
else if ( maj2 != -1 && min2 != -1 )
fd = disk_open_dev(maj2, min2, 1, simulate ? 1 : 0);
fd = disk_open_dev(maj2, min2, 1, 1);
else
fd = disk_open_dev(maj1, min1, 1, simulate ? 1 : 0);
fd = disk_open_dev(maj1, min1, 1, 1);
if ( fd < 0 )
return -1;
@@ -507,16 +449,10 @@ enum device disk_get_device(struct usb_device_info * dev) {
int disk_flash_image(struct usb_device_info * dev, struct image * image) {
int ret;
printf("Flash image:\n");
image_print_info(image);
ret = disk_flash_dev(dev->data, image);
if ( ret == 0 )
printf("Done\n");
return ret;
ERROR("Not implemented yet");
(void)dev;
(void)image;
return -1;
}
+1 -1
View File
@@ -30,7 +30,7 @@ enum device disk_get_device(struct usb_device_info * dev);
int disk_open_dev(int maj, int min, int partition, int readonly);
int disk_dump_dev(int fd, const char * file);
int disk_flash_dev(int fd, struct image * image);
int disk_flash_dev(int fd, const char * file);
int disk_flash_image(struct usb_device_info * dev, struct image * image);
int disk_dump_image(struct usb_device_info * dev, enum image_type image, const char * file);
+77 -270
View File
@@ -34,11 +34,10 @@
#include "image.h"
#include "fiasco.h"
#define CHECKSUM(checksum, buf, size) do { size_t _i; for ( _i = 0; _i < size; _i++ ) checksum += ((unsigned char *)buf)[_i]; } while (0)
#define FIASCO_READ_ERROR(fiasco, ...) do { ERROR_INFO(__VA_ARGS__); fiasco_free(fiasco); return NULL; } while (0)
#define FIASCO_WRITE_ERROR(file, fd, ...) do { ERROR_INFO_STR(file, __VA_ARGS__); if ( fd >= 0 ) close(fd); return -1; } while (0)
#define READ_OR_FAIL(fiasco, buf, size) do { if ( read(fiasco->fd, buf, size) != size ) { FIASCO_READ_ERROR(fiasco, "Cannot read %d bytes", size); } } while (0)
#define READ_OR_RETURN(fiasco, checksum, buf, size) do { if ( read(fiasco->fd, buf, size) != size ) return fiasco; CHECKSUM(checksum, buf, size); } while (0)
#define READ_OR_RETURN(fiasco, buf, size) do { if ( read(fiasco->fd, buf, size) != size ) return fiasco; } while (0)
#define WRITE_OR_FAIL_FREE(file, fd, buf, size, var) do { if ( ! simulate ) { if ( write(fd, buf, size) != (ssize_t)size ) { free(var); FIASCO_WRITE_ERROR(file, fd, "Cannot write %d bytes", size); } } } while (0)
#define WRITE_OR_FAIL(file, fd, buf, size) WRITE_OR_FAIL_FREE(file, fd, buf, size, NULL)
@@ -66,16 +65,9 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
char hwrevs[1024];
char version[257];
char layout[257];
uint8_t asicidx;
uint8_t devicetype;
uint8_t deviceidx;
uint8_t checksum;
uint32_t address;
uint16_t hash;
off_t offset;
struct image * image;
struct image_part * image_part;
struct image_part * image_parts;
char hwrev[9];
unsigned char buf[512];
@@ -112,11 +104,11 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
READ_OR_FAIL(fiasco, buf, length8);
if ( byte == 0xe8 ) {
memset(fiasco->name, 0, sizeof(fiasco->name));
memcpy(fiasco->name, buf, length8);
strncpy(fiasco->name, (char *)buf, length8);
VERBOSE("Fiasco name: %s\n", fiasco->name);
} else if ( byte == 0x31 ) {
memset(fiasco->swver, 0, sizeof(fiasco->swver));
memcpy(fiasco->swver, buf, length8);
strncpy(fiasco->swver, (char *)buf, length8);
VERBOSE("SW version: %s\n", fiasco->swver);
} else {
VERBOSE("Unknown header %#x\n", byte);
@@ -128,41 +120,23 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
while ( 1 ) {
/* If end of file, return fiasco image */
checksum = 0x00;
READ_OR_RETURN(fiasco, checksum, buf, 1);
READ_OR_RETURN(fiasco, buf, 7);
/* Header of next image (0x54) */
if ( buf[0] != 0x54 ) {
/* Header of next image */
if ( ! ( buf[0] == 0x54 && buf[2] == 0x2E && buf[3] == 0x19 && buf[4] == 0x01 && buf[5] == 0x01 && buf[6] == 0x00 ) ) {
ERROR("Invalid next image header");
return fiasco;
}
checksum = 0x00;
count8 = buf[1];
if ( count8 > 0 )
--count8;
READ_OR_RETURN(fiasco, checksum, &count8, 1);
if ( count8 == 0 ) {
ERROR("No section in image header");
return fiasco;
}
READ_OR_RETURN(fiasco, checksum, buf, 2);
/* File data section (0x2E) with length of 25 bytes */
if ( buf[0] != 0x2E || buf[1] != 25 ) {
ERROR("First section in image header is not file data with length of 25 bytes");
return fiasco;
}
READ_OR_RETURN(fiasco, checksum, &asicidx, 1);
READ_OR_RETURN(fiasco, checksum, &devicetype, 1);
READ_OR_RETURN(fiasco, checksum, &deviceidx, 1);
READ_OR_RETURN(fiasco, checksum, &hash, 2);
READ_OR_RETURN(fiasco, &hash, 2);
hash = ntohs(hash);
memset(type, 0, sizeof(type));
READ_OR_RETURN(fiasco, checksum, type, 12);
READ_OR_RETURN(fiasco, type, 12);
byte = type[0];
if ( byte == 0xFF )
@@ -170,35 +144,26 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
VERBOSE(" %s\n", type);
READ_OR_RETURN(fiasco, checksum, &length, 4);
READ_OR_RETURN(fiasco, &length, 4);
length = ntohl(length);
/* load address (unused) */
READ_OR_RETURN(fiasco, checksum, &address, 4);
/* end of file data section */
--count8;
/* unknown */
READ_OR_RETURN(fiasco, buf, 4);
VERBOSE(" size: %d bytes\n", length);
VERBOSE(" address: 0x%04x\n", address);
VERBOSE(" hash: 0x%04x\n", hash);
VERBOSE(" asic idx: %d\n", asicidx);
VERBOSE(" device type: %d\n", devicetype);
VERBOSE(" device idx: %d\n", deviceidx);
VERBOSE(" hash: %#04x\n", hash);
VERBOSE(" subsections: %d\n", count8);
memset(device, 0, sizeof(device));
memset(hwrevs, 0, sizeof(hwrevs));
memset(version, 0, sizeof(version));
memset(layout, 0, sizeof(layout));
image_part = NULL;
image_parts = NULL;
while ( count8 > 0 ) {
READ_OR_RETURN(fiasco, checksum, &byte, 1);
READ_OR_RETURN(fiasco, checksum, &length8, 1);
READ_OR_RETURN(fiasco, checksum, buf, length8);
READ_OR_RETURN(fiasco, &byte, 1);
READ_OR_RETURN(fiasco, &length8, 1);
READ_OR_RETURN(fiasco, buf, length8);
VERBOSE(" subinfo\n");
VERBOSE(" length: %d\n", length8);
@@ -206,14 +171,14 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
if ( byte == '1' ) {
memset(version, 0, sizeof(version));
memcpy(version, buf, length8);
strncpy(version, (char *)buf, length8);
VERBOSE("version string\n");
VERBOSE(" version: %s\n", version);
} else if ( byte == '2' ) {
int tmp = length8;
if ( tmp > 16 ) tmp = 16;
memset(device, 0, sizeof(device));
memcpy(device, buf, tmp);
strncpy(device, (char *)buf, tmp);
VERBOSE("hw revision\n");
VERBOSE(" device: %s\n", device);
pbuf = buf + strlen(device) + 1;
@@ -224,7 +189,7 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
tmp = buf + length8 - pbuf;
if ( tmp > 8 ) tmp = 8;
memset(hwrev, 0, sizeof(hwrev));
memcpy(hwrev, pbuf, tmp);
strncpy(hwrev, (char *)pbuf, tmp);
if ( ! hwrevs[0] )
strcpy(hwrevs, hwrev);
else {
@@ -240,90 +205,17 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
}
} else if ( byte == '3' ) {
memset(layout, 0, sizeof(layout));
memcpy(layout, buf, length8);
strncpy(layout, (char *)buf, length8);
VERBOSE("layout\n");
} else if ( byte == '4' ) {
VERBOSE("data part\n");
if ( length8 < 16 ) {
VERBOSE(" (damaged)\n");
} else {
if ( image_parts ) {
image_part->next = calloc(1, sizeof(struct image_part));
if ( ! image_part->next )
FIASCO_READ_ERROR(fiasco, "Cannot allocate image");
image_part = image_part->next;
} else {
image_parts = calloc(1, sizeof(struct image_part));
if ( ! image_parts )
FIASCO_READ_ERROR(fiasco, "Cannot allocate image");
image_part = image_parts;
}
image_part->offset = ntohl(*(uint32_t *)&buf[4]);
image_part->size = ntohl(*(uint32_t *)&buf[12]);
if ( length8 > 16 ) {
image_part->name = calloc(1, length8-16+1);
if ( image_part->name )
memcpy(image_part->name, &buf[16], length8-16);
}
VERBOSE(" unknown: 0x%02x 0x%02x 0x%02x 0x%02x\n", buf[0], buf[1], buf[2], buf[3]);
VERBOSE(" offset: %u bytes\n", image_part->offset);
VERBOSE(" unknown: 0x%02x 0x%02x 0x%02x 0x%02x\n", buf[8], buf[9], buf[10], buf[11]);
VERBOSE(" size: %u bytes\n", image_part->size);
if ( image_part->name )
VERBOSE(" partition name: %s\n", image_part->name);
}
} else if ( byte == 0x2F ) {
VERBOSE("partition info\n");
if ( length8 < 15 ) {
VERBOSE(" (damaged)\n");
} else {
unsigned int i;
unsigned int part_type;
unsigned int part_attr;
unsigned int part_size;
unsigned int num_parts = ((unsigned)buf[11] << 24) | ((unsigned)buf[12] << 16) | ((unsigned)buf[13] << 8) | ((unsigned)buf[14] << 0);
VERBOSE(" asic idx: %d\n", buf[0]);
VERBOSE(" device type: %d\n", buf[1]);
VERBOSE(" device idx: %d\n", buf[2]);
VERBOSE(" version: 0x%02x%02x%02x%02x\n", buf[3], buf[4], buf[5], buf[6]);
VERBOSE(" spare: 0x%02x%02x%02x%02x\n", buf[7], buf[8], buf[9], buf[10]);
VERBOSE(" partitions: %d\n", num_parts);
for ( i = 0; i < num_parts; i++ ) {
VERBOSE(" partition\n");
if ( 20 + i*6 >= length8 ) {
VERBOSE(" (damaged)\n");
continue;
}
part_type = buf[15 + i*6];
part_attr = buf[16 + i*6];
part_size = ((unsigned)buf[17 + i*6] << 24) | ((unsigned)buf[18 + i*6] << 16) | ((unsigned)buf[19 + i*6] << 8) | ((unsigned)buf[20 + i*6] << 0);
VERBOSE(" type: 0x%02x (%s)\n", part_type, part_type == 0x03 ? "kernel" : part_type == 0x04 ? "initfs" : part_type == 0x05 ? "rootfs" : "unknown");
VERBOSE(" attribute: 0x%02x (%s)\n", part_attr, part_attr == 0x1 ? "read/write" : part_attr == 0x2 ? "read-only" : "unknown");
if ( part_size == 0 )
VERBOSE(" size: remaining space\n");
else
VERBOSE(" size: %u bytes\n", part_size);
}
}
} else {
int i;
VERBOSE("unknown (%#x)\n", byte);
VERBOSE(" hexdump:");
for ( i = 0; i < length8; i++ ) VERBOSE(" 0x%02x", buf[i]);
VERBOSE("\n");
VERBOSE("unknown ('%c':%#x)\n", byte, byte);
}
--count8;
}
/* checksum */
READ_OR_RETURN(fiasco, checksum, buf, 1);
VERBOSE(" subinfo checksum: 0x%02x\n", buf[0]);
if ( ! noverify && buf[0] != 0x00 && checksum != 0xFF ) {
ERROR("Image header subinfo checksum mishmash (counted 0x%02x, got 0x%02x)", (0xFF - checksum + buf[0]) & 0xFF, buf[0]);
return fiasco;
}
/* unknown */
READ_OR_RETURN(fiasco, buf, 1);
offset = lseek(fiasco->fd, 0, SEEK_CUR);
if ( offset == (off_t)-1 )
@@ -334,7 +226,7 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
VERBOSE(" hwrevs: %s\n", hwrevs);
VERBOSE(" data at: %#08x\n", (unsigned int)offset);
image = image_alloc_from_shared_fd(fiasco->fd, length, offset, hash, type, device, hwrevs, version, layout, image_parts);
image = image_alloc_from_shared_fd(fiasco->fd, length, offset, hash, type, device, hwrevs, version, layout);
if ( ! image )
FIASCO_READ_ERROR(fiasco, "Cannot allocate image");
@@ -382,12 +274,10 @@ int fiasco_write_to_file(struct fiasco * fiasco, const char * file) {
uint32_t length;
uint16_t hash;
uint8_t length8;
uint8_t checksum;
char ** device_hwrevs_bufs;
const char * str;
const char * type;
struct image_list * image_list;
struct image_part * image_part;
struct image * image;
unsigned char buf[4096];
@@ -485,46 +375,32 @@ int fiasco_write_to_file(struct fiasco * fiasco, const char * file) {
/* signature */
WRITE_OR_FAIL_FREE(file, fd, "T", 1, device_hwrevs_bufs);
checksum = 0x00;
/* number of subsections */
length8 = device_count+1;
if ( image->version )
++length8;
if ( image->layout )
++length8;
if ( image->parts ) {
for ( image_part = image->parts; image_part; image_part = image_part->next )
++length8;
} else {
++length;
}
WRITE_OR_FAIL_FREE(file, fd, &length8, 1, device_hwrevs_bufs);
CHECKSUM(checksum, &length8, 1);
/* file data: asic index: APE (0x01), device type: NAND (0x01), device index: 0 */
/* unknown */
WRITE_OR_FAIL_FREE(file, fd, "\x2e\x19\x01\x01\x00", 5, device_hwrevs_bufs);
CHECKSUM(checksum, "\x2e\x19\x01\x01\x00", 5);
/* checksum */
hash = htons(image->hash);
WRITE_OR_FAIL_FREE(file, fd, &hash, 2, device_hwrevs_bufs);
CHECKSUM(checksum, &hash, 2);
/* image type name */
memset(buf, 0, 12);
strncpy((char *)buf, type, 12);
WRITE_OR_FAIL_FREE(file, fd, buf, 12, device_hwrevs_bufs);
CHECKSUM(checksum, buf, 12);
/* image size */
size = htonl(image->size);
WRITE_OR_FAIL_FREE(file, fd, &size, 4, device_hwrevs_bufs);
CHECKSUM(checksum, &size, 4);
/* image load address (unused always zero) */
/* unknown */
WRITE_OR_FAIL_FREE(file, fd, "\x00\x00\x00\x00", 4, device_hwrevs_bufs);
CHECKSUM(checksum, "\x00\x00\x00\x00", 4);
/* append version subsection */
if ( image->version ) {
@@ -532,9 +408,6 @@ int fiasco_write_to_file(struct fiasco * fiasco, const char * file) {
length8 = strlen(image->version)+1; /* +1 for NULL term */
WRITE_OR_FAIL_FREE(file, fd, &length8, 1, device_hwrevs_bufs);
WRITE_OR_FAIL_FREE(file, fd, image->version, length8, device_hwrevs_bufs);
CHECKSUM(checksum, "1", 1);
CHECKSUM(checksum, &length8, 1);
CHECKSUM(checksum, image->version, length8);
}
/* append device & hwrevs subsection */
@@ -543,9 +416,6 @@ int fiasco_write_to_file(struct fiasco * fiasco, const char * file) {
length8 = ((uint8_t *)(device_hwrevs_bufs[i]))[0];
WRITE_OR_FAIL_FREE(file, fd, &length8, 1, device_hwrevs_bufs);
WRITE_OR_FAIL_FREE(file, fd, device_hwrevs_bufs[i]+1, length8, device_hwrevs_bufs);
CHECKSUM(checksum, "2", 1);
CHECKSUM(checksum, &length8, 1);
CHECKSUM(checksum, device_hwrevs_bufs[i]+1, length8);
}
free(device_hwrevs_bufs);
@@ -555,47 +425,10 @@ int fiasco_write_to_file(struct fiasco * fiasco, const char * file) {
length8 = strlen(image->layout);
WRITE_OR_FAIL(file, fd, &length8, 1);
WRITE_OR_FAIL(file, fd, image->layout, length8);
CHECKSUM(checksum, "3", 1);
CHECKSUM(checksum, &length8, 1);
CHECKSUM(checksum, image->layout, length8);
}
if ( image->parts ) {
/* for each image part append subsection */
for ( image_part = image->parts; image_part; image_part = image_part->next ) {
WRITE_OR_FAIL(file, fd, "4", 1); /* 4 - image data part */
CHECKSUM(checksum, "4", 1);
length = 16 + (image_part->name ? strlen(image_part->name) : 0);
length8 = length <= UINT8_MAX ? length : UINT8_MAX;
WRITE_OR_FAIL(file, fd, &length8, 1);
CHECKSUM(checksum, &length8, 1);
WRITE_OR_FAIL(file, fd, "\x00\x00\x00\x00", 4); /* unknown */
CHECKSUM(checksum, "\x00\x00\x00\x00", 4);
size = htonl(image_part->offset);
WRITE_OR_FAIL(file, fd, &size, 4);
CHECKSUM(checksum, &size, 4);
WRITE_OR_FAIL(file, fd, "\x00\x00\x00\x00", 4); /* unknown */
CHECKSUM(checksum, "\x00\x00\x00\x00", 4);
size = htonl(image_part->size);
WRITE_OR_FAIL(file, fd, &size, 4);
CHECKSUM(checksum, &size, 4);
if ( image_part->name ) {
WRITE_OR_FAIL(file, fd, image_part->name, length8-16);
CHECKSUM(checksum, image_part->name, (size_t)length8-16);
}
}
} else {
/* append one image data part subsection */;
WRITE_OR_FAIL(file, fd, "4\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 14);
CHECKSUM(checksum, "4\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 14);
size = htonl(image->size);
WRITE_OR_FAIL(file, fd, &size, 4);
CHECKSUM(checksum, &size, 4);
}
/* checksum of header */
checksum = 0xFF - checksum;
WRITE_OR_FAIL(file, fd, &checksum, 1);
/* dummy byte - end of all subsections */
WRITE_OR_FAIL(file, fd, "\x00", 1);
printf("Writing image data...\n");
@@ -628,10 +461,8 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) {
char * name;
char * layout_name;
struct image * image;
struct image_part * image_part;
struct image_list * image_list;
uint32_t offset, size, need, total_size, written;
int part_num;
uint32_t size;
char cwd[256];
unsigned char buf[4096];
@@ -658,30 +489,68 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) {
while ( image_list ) {
fd = -1;
name = NULL;
layout_name = NULL;
image = image_list->image;
name = image_name_alloc_from_values(image);
if ( ! name )
return -1;
printf("\n");
printf("Unpacking image...\n");
image_print_info(image);
if ( image->layout ) {
name = image_name_alloc_from_values(image, -1);
if ( ! name )
ALLOC_ERROR_RETURN(-1);
layout_name = calloc(1, strlen(name) + sizeof("_layout.txt")-1 + 1);
layout_name = calloc(1, strlen(name) + sizeof(".layout")-1 + 1);
if ( ! layout_name ) {
free(name);
ALLOC_ERROR_RETURN(-1);
}
sprintf(layout_name, "%s_layout.txt", name);
free(name);
sprintf(layout_name, "%s.layout", name);
printf(" Layout file: %s\n", layout_name);
}
printf(" Output file: %s\n", name);
if ( ! simulate ) {
fd = open(name, O_RDWR|O_CREAT|O_TRUNC, 0644);
if ( fd < 0 ) {
ERROR_INFO("Cannot create output file %s", name);
free(name);
free(layout_name);
return -1;
}
}
image_seek(image, 0);
while ( 1 ) {
size = image_read(image, buf, sizeof(buf));
if ( size == 0 )
break;
if ( ! simulate ) {
if ( write(fd, buf, size) != (ssize_t)size ) {
ERROR_INFO_STR(name, "Cannot write %d bytes", size);
close(fd);
free(name);
free(layout_name);
return -1;
}
}
}
free(name);
if ( ! simulate )
close(fd);
if ( image->layout ) {
if ( ! simulate ) {
fd = open(layout_name, O_RDWR|O_CREAT|O_TRUNC, 0644);
if ( fd < 0 ) {
@@ -702,73 +571,11 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) {
free(layout_name);
if ( ! simulate ) {
if ( ! simulate )
close(fd);
fd = -1;
}
}
part_num = 0;
image_part = image->parts;
do {
offset = image_part ? image_part->offset : 0;
total_size = image_part ? image_part->size : image->size;
name = image_name_alloc_from_values(image, image_part ? part_num : -1);
if ( ! name )
ALLOC_ERROR_RETURN(-1);
if ( image_part && ( part_num > 0 || image_part->next ) )
printf(" Output file part %d: %s\n", part_num+1, name);
else
printf(" Output file: %s\n", name);
if ( ! simulate ) {
fd = open(name, O_RDWR|O_CREAT|O_TRUNC, 0644);
if ( fd < 0 ) {
ERROR_INFO("Cannot create output file %s", name);
free(name);
return -1;
}
}
written = 0;
image_seek(image, offset);
while ( written < total_size ) {
need = total_size - written;
if ( need > sizeof(buf) )
need = sizeof(buf);
size = image_read(image, buf, need);
if ( size == 0 )
break;
if ( ! simulate ) {
if ( write(fd, buf, size) != (ssize_t)size ) {
ERROR_INFO_STR(name, "Cannot write %d bytes", size);
close(fd);
free(name);
return -1;
}
}
written += size;
}
free(name);
if ( ! simulate ) {
close(fd);
fd = -1;
}
if ( image_part ) {
image_part = image_part->next;
part_num++;
}
} while ( image_part );
image_list = image_list->next;
}
+1 -1
View File
@@ -22,7 +22,7 @@ extern int verbose;
#define ALLOC_ERROR() do { ERROR("Cannot allocate memory"); } while (0)
#define ALLOC_ERROR_RETURN(...) do { ALLOC_ERROR(); return __VA_ARGS__; } while (0)
#define MSLEEP(msec) do { nanosleep(&(struct timespec){ (msec / 1000), (1000L * 1000L * (msec % 1000)) }, NULL); } while (0)
#define SLEEP(usec) do { struct timespec _t = { 0, (usec) }; nanosleep(&_t, NULL); } while (0)
static inline void * MEMMEM(void *haystack, size_t haystacklen, const void *needle, size_t needlelen) {
for ( size_t i = 0; i < haystacklen; ++i ) {
+105 -268
View File
@@ -30,6 +30,9 @@
#include "device.h"
#include "image.h"
#define IMAGE_STORE_CUR(image) do { if ( image->is_shared_fd ) { image->cur = lseek(image->fd, 0, SEEK_CUR) - image->offset; if ( image->cur > image->size ) image->cur = image->size; } } while (0)
#define IMAGE_RESTORE_CUR(image) do { if ( image->is_shared_fd ) { if ( image->cur <= image->size ) lseek(image->fd, image->offset + image->cur, SEEK_SET); else lseek(image->fd, image->offset + image->size, SEEK_SET); } } while (0)
/* format: type-device:hwrevs_version */
static void image_missing_values_from_name(struct image * image, const char * name) {
@@ -97,7 +100,7 @@ static void image_missing_values_from_name(struct image * image, const char * na
}
/* format: type-device:hwrevs_version */
char * image_name_alloc_from_values(struct image * image, int part_num) {
char * image_name_alloc_from_values(struct image * image) {
char * name;
char * ptr;
@@ -105,8 +108,6 @@ char * image_name_alloc_from_values(struct image * image, int part_num) {
size_t length;
const char * type;
const char * device;
struct image_part * part;
int i;
type = image_type_to_string(image->type);
@@ -123,14 +124,6 @@ char * image_name_alloc_from_values(struct image * image, int part_num) {
else
hwrevs = NULL;
part = image->parts;
if ( part && ( !part->next || part_num < 0 ) )
part = NULL;
for ( i = 0; i < part_num && part; i++ )
part = part->next;
length = 1 + strlen(type);
if ( device )
@@ -139,10 +132,6 @@ char * image_name_alloc_from_values(struct image * image, int part_num) {
length += 1 + strlen(hwrevs);
if ( image->version )
length += 1 + strlen(image->version);
if ( part )
length += 4 + 3; /* 3 <= strlen(part_num) */
if ( part && part->name )
length += 1 + strlen(part->name);
name = calloc(1, length);
if ( ! name ) {
@@ -160,19 +149,13 @@ char * image_name_alloc_from_values(struct image * image, int part_num) {
if ( image->version )
ptr += sprintf(ptr, "_%s", image->version);
if ( part ) {
ptr += sprintf(ptr, "_part%d", part_num+1);
if ( part->name )
ptr += sprintf(ptr, "_%s", part->name);
}
free(hwrevs);
return name;
}
static int image_append(struct image * image, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts) {
static int image_append(struct image * image, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout) {
enum image_type detected_type;
@@ -227,42 +210,26 @@ static int image_append(struct image * image, const char * type, const char * de
else
image->layout = NULL;
image->parts = parts;
return 0;
}
static void image_align(struct image * image) {
struct image_fd * image_fd = image->fds;
size_t align, aligned_size;
uint32_t total_size;
size_t align;
if ( image->type == IMAGE_MMC )
align = 8;
else
align = 7;
if ( image_fd && ! image_fd->next && image->size == image_fd->size && ( image->size & ( ( 1ULL << align ) - 1 ) ) == 0 )
if ( ( image->size & ( ( 1ULL << align ) - 1 ) ) == 0 )
return;
total_size = 0;
align = ((image->size >> align) + 1) << align;
while ( image_fd ) {
if ( ( image_fd->size & ( ( 1ULL << align ) - 1 ) ) != 0 ) {
aligned_size = ((image_fd->size >> align) + 1) << align;
image_fd->align = aligned_size - image_fd->size;
image_fd->size = aligned_size;
}
total_size += image_fd->size;
image_fd = image_fd->next;
}
image->size = total_size;
image->align = align - image->size;
image->size = align;
image->hash = image_hash_from_data(image);
@@ -277,100 +244,58 @@ static struct image * image_alloc(void) {
}
struct image * image_alloc_from_file(const char * file, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts) {
struct image * image_alloc_from_file(const char * file, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout) {
return image_alloc_from_files(&file, 1, type, device, hwrevs, version, layout, parts);
int fd;
}
struct image * image_alloc_from_files(const char ** files, int count, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts) {
struct image * image;
int i;
int * fds = calloc(count, sizeof(int));
if ( ! fds )
ALLOC_ERROR_RETURN(NULL);
for ( i = 0; i < count; ++i ) {
fds[i] = open(files[i], O_RDONLY);
if ( fds[i] < 0 ) {
ERROR_INFO("Cannot open image file %s", files[i]);
free(fds);
return NULL;
}
}
image = image_alloc_from_fds(fds, files, count, type, device, hwrevs, version, layout, parts);
free(fds);
return image;
}
struct image * image_alloc_from_fd(int fd, const char * orig_filename, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts) {
return image_alloc_from_fds(&fd, &orig_filename, 1, type, device, hwrevs, version, layout, parts);
}
struct image * image_alloc_from_fds(int * fds, const char ** orig_filenames, int count, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts) {
int i;
struct image * image = image_alloc();
if ( ! image ) {
for ( i = 0; i < count; ++i )
close(fds[i]);
fd = open(file, O_RDONLY);
if ( fd < 0 ) {
ERROR_INFO("Cannot open image file %s", file);
return NULL;
}
for ( i = 0; i < count; ++i ) {
return image_alloc_from_fd(fd, file, type, device, hwrevs, version, layout);
off_t offset;
struct image_fd * image_fds = image->fds;
struct image_fd * image_fd = calloc(1, sizeof(struct image_fd));
if ( ! image_fd ) {
image_free(image);
return NULL;
}
}
if ( ! image_fds ) {
image->fds = image_fd;
} else {
while ( image_fds->next )
image_fds = image_fds->next;
image_fds->next = image_fd;
}
image_fd->is_shared_fd = 0;
image_fd->fd = fds[i];
offset = lseek(image_fd->fd, 0, SEEK_END);
if ( offset == (off_t)-1 ) {
ERROR_INFO("Cannot seek to end of file %s", orig_filenames[i]);
image_free(image);
return NULL;
}
image_fd->size = offset;
image_fd->offset = 0;
image_fd->is_shared_fd = 0;
image_fd->shared_cur = 0;
image_fd->orig_filename = strdup(orig_filenames[i]);
image->size += image_fd->size;
if ( lseek(image_fd->fd, 0, SEEK_SET) == (off_t)-1 ) {
ERROR_INFO("Cannot seek to begin of file %s", orig_filenames[i]);
image_free(image);
return NULL;
}
struct image * image_alloc_from_fd(int fd, const char * orig_filename, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout) {
off_t offset;
struct image * image = image_alloc();
if ( ! image ) {
close(fd);
return NULL;
}
if ( image_append(image, type, device, hwrevs, version, layout, parts) < 0 )
image->is_shared_fd = 0;
image->fd = fd;
offset = lseek(image->fd, 0, SEEK_END);
if ( offset == (off_t)-1 ) {
ERROR_INFO("Cannot seek to end of file %s", orig_filename);
close(image->fd);
free(image);
return NULL;
}
image->size = offset;
image->offset = 0;
image->cur = 0;
image->orig_filename = strdup(orig_filename);
if ( lseek(image->fd, 0, SEEK_SET) == (off_t)-1 ) {
ERROR_INFO("Cannot seek to begin of file %s", orig_filename);
close(image->fd);
free(image->orig_filename);
free(image);
return NULL;
}
if ( image_append(image, type, device, hwrevs, version, layout) < 0 )
return NULL;
if ( ( ! type || ! type[0] ) && ( ! device || ! device[0] ) && ( ! hwrevs || ! hwrevs[0] ) && ( ! version || ! version[0] ) )
image_missing_values_from_name(image, count > 0 ? orig_filenames[0] : NULL);
image_missing_values_from_name(image, orig_filename);
image_align(image);
@@ -378,25 +303,19 @@ struct image * image_alloc_from_fds(int * fds, const char ** orig_filenames, int
}
struct image * image_alloc_from_shared_fd(int fd, size_t size, size_t offset, uint16_t hash, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts) {
struct image * image_alloc_from_shared_fd(int fd, size_t size, size_t offset, uint16_t hash, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout) {
struct image * image = image_alloc();
struct image_fd * image_fd = calloc(1, sizeof(struct image_fd));
if ( ! image || ! image_fd ) {
free(image);
free(image_fd);
if ( ! image )
return NULL;
}
image_fd->is_shared_fd = 1;
image_fd->fd = fd;
image_fd->size = size;
image_fd->offset = offset;
image_fd->shared_cur = 0;
image->fds = image_fd;
image->size = image_fd->size;
image->is_shared_fd = 1;
image->fd = fd;
image->size = size;
image->offset = offset;
image->cur = 0;
if ( image_append(image, type, device, hwrevs, version, layout, parts) < 0 )
if ( image_append(image, type, device, hwrevs, version, layout) < 0 )
return NULL;
if ( ! noverify && image->hash != hash ) {
@@ -416,13 +335,9 @@ void image_free(struct image * image) {
if ( ! image )
return;
while ( image->fds ) {
struct image_fd * next = image->fds->next;
if ( ! image->fds->is_shared_fd )
close(image->fds->fd);
free(image->fds->orig_filename);
free(image->fds);
image->fds = next;
if ( ! image->is_shared_fd ) {
close(image->fd);
image->fd = -1;
}
while ( image->devices ) {
@@ -432,15 +347,9 @@ void image_free(struct image * image) {
image->devices = next;
}
while ( image->parts ) {
struct image_part * next = image->parts->next;
free(image->parts->name);
free(image->parts);
image->parts = next;
}
free(image->version);
free(image->layout);
free(image->orig_filename);
free(image);
@@ -449,122 +358,74 @@ void image_free(struct image * image) {
void image_seek(struct image * image, size_t whence) {
off_t offset;
size_t start = 0;
struct image_fd * image_fd = image->fds;
image->cur = whence;
if ( whence > image->size ) {
ERROR("Seek in image failed: Position end of the image");
if ( whence > image->size )
return;
}
while ( image_fd ) {
if ( ( whence >= start && whence < start + image_fd->size ) || ! image_fd->next )
break;
start += image_fd->size;
image_fd = image_fd->next;
}
if ( whence - start >= image_fd->size - image_fd->align ) {
offset = lseek(image_fd->fd, image_fd->size - image_fd->align, SEEK_SET);
if ( whence >= image->size - image->align ) {
offset = lseek(image->fd, image->size - image->align - 1, SEEK_SET);
image->acur = whence - ( image->size - image->align );
} else {
offset = lseek(image_fd->fd, image_fd->offset + whence - start, SEEK_SET);
offset = lseek(image->fd, image->offset + whence, SEEK_SET);
image->acur = 0;
}
if ( offset == (off_t)-1 )
ERROR_INFO("Seek in file %s failed", (image_fd->orig_filename ? image_fd->orig_filename : "(unknown)"));
else if ( image_fd->is_shared_fd )
image_fd->shared_cur = offset;
ERROR_INFO("Seek in file %s failed", (image->orig_filename ? image->orig_filename : "(unknown)"));
IMAGE_STORE_CUR(image);
}
size_t image_read(struct image * image, void * buf, size_t count) {
size_t cur;
ssize_t ret;
off_t offset;
size_t new_count = 0;
size_t ret_count = 0;
size_t start = 0;
struct image_fd * image_fd = image->fds;
while ( image_fd ) {
if ( ( image->cur >= start && image->cur < start + image_fd->size ) || ! image_fd->next )
break;
start += image_fd->size;
image_fd = image_fd->next;
}
IMAGE_RESTORE_CUR(image);
if ( image_fd->is_shared_fd ) {
if ( lseek(image_fd->fd, image_fd->shared_cur, SEEK_SET) != image_fd->shared_cur ) {
ERROR_INFO("Cannot restore offset of file %s", (image_fd->orig_filename ? image_fd->orig_filename : "(unknown)"));
if ( ! image->is_shared_fd || image->cur < image->size - image->align ) {
if ( image->is_shared_fd && image->cur + count > image->size - image->align )
new_count = image->size - image->align - image->cur;
else
new_count = count;
ret = read(image->fd, buf, new_count);
if ( ret > 0 )
ret_count += ret;
IMAGE_STORE_CUR(image);
if ( ret < 0 )
return 0;
}
}
while ( count > 0 ) {
if ( ret_count == count )
return ret_count;
if ( image->cur < start + image_fd->size - image_fd->align ) {
offset = lseek(image->fd, 0, SEEK_CUR);
if ( offset == (off_t)-1 ) {
ERROR_INFO("Cannot get offset of file %s", (image->orig_filename ? image->orig_filename : "(unknown)"));
return 0;
}
if ( image->cur + count > start + image_fd->size - image_fd->align )
new_count = start + image_fd->size - image_fd->align - image->cur;
else
new_count = count;
cur = offset - image->offset;
ret = read(image_fd->fd, buf, new_count);
if ( ret <= 0 )
break;
if ( image->align && cur == image->size - image->align && image->acur < image->align ) {
count -= ret;
buf = (unsigned char *)buf + ret;
ret_count += ret;
image->cur += ret;
if ( image->acur + count - ret_count > image->align )
new_count = image->align - image->acur;
else
new_count = count - ret_count;
if ( image_fd->is_shared_fd )
image_fd->shared_cur += ret;
if ( (size_t)ret != new_count )
continue;
}
if ( image_fd->align > 0 && count > 0 && image->cur < start + image_fd->size ) {
if ( count > image_fd->align )
new_count = image_fd->align;
else
new_count = count;
if ( image->cur + new_count > start + image_fd->size )
new_count = start + image_fd->size - image->cur;
memset(buf, 0xFF, new_count);
ret = new_count;
count -= ret;
buf = (unsigned char *)buf + ret;
ret_count += ret;
image->cur += ret;
}
if ( image->cur == start + image_fd->size ) {
start += image_fd->size;
image_fd = image_fd->next;
if ( ! image_fd )
break;
offset = lseek(image_fd->fd, image_fd->offset, SEEK_SET);
if ( offset == (off_t)-1 ) {
ERROR_INFO("Seek in file %s failed", (image_fd->orig_filename ? image_fd->orig_filename : "(unknown)"));
break;
} else if ( image_fd->is_shared_fd ) {
image_fd->shared_cur = offset;
}
}
memset((unsigned char *)buf+ret_count, 0xFF, new_count);
ret_count += new_count;
image->acur += new_count;
}
@@ -655,9 +516,6 @@ static const char * image_types[] = {
[IMAGE_CMT_2ND] = "cmt-2nd",
[IMAGE_CMT_ALGO] = "cmt-algo",
[IMAGE_CMT_MCUSW] = "cmt-mcusw",
[IMAGE_1ST] = "1st",
[IMAGE_CERT_SW] = "cert-sw",
[IMAGE_APE_ALGO] = "ape-algo",
};
enum image_type image_type_from_data(struct image * image) {
@@ -748,18 +606,11 @@ int image_hwrev_is_valid(struct image * image, int16_t hwrev) {
void image_print_info(struct image * image) {
int i = 0;
const char * str;
struct image_fd * image_fd = image->fds;
struct image_part * part = image->parts;
struct device_list * device = image->devices;
if ( image->fds && image->fds->orig_filename ) {
if ( image->fds->next )
printf("Multifile image:\n");
else
printf("File: %s\n", image->fds->orig_filename);
}
if ( image->orig_filename )
printf("File: %s\n", image->orig_filename);
str = image_type_to_string(image->type);
printf(" Image type: %s\n", str ? str : "unknown");
@@ -771,20 +622,6 @@ void image_print_info(struct image * image) {
if ( image->layout )
printf(" Image layout: included\n");
while ( part ) {
if ( image->fds && image->fds->orig_filename && image->fds->next )
printf("File: %s\n", (image_fd && image_fd->orig_filename) ? image_fd->orig_filename : "(unknown)");
printf(" Image part %d name: %s\n", i, part->name ? part->name : "(empty)");
printf(" Image part %d size: %d bytes\n", i, part->size);
part = part->next;
image_fd = image_fd ? image_fd->next : NULL;
++i;
}
while ( device ) {
char * str2 = NULL;
+11 -29
View File
@@ -37,30 +37,9 @@ enum image_type {
IMAGE_CMT_2ND,
IMAGE_CMT_ALGO,
IMAGE_CMT_MCUSW,
IMAGE_1ST,
IMAGE_CERT_SW,
IMAGE_APE_ALGO,
IMAGE_COUNT,
};
struct image_part {
struct image_part * next;
uint32_t offset;
uint32_t size;
char * name;
};
struct image_fd {
struct image_fd * next;
int fd;
int is_shared_fd;
off_t shared_cur;
uint32_t size;
uint32_t align;
size_t offset;
char * orig_filename;
};
struct image {
enum image_type type;
struct device_list * devices;
@@ -68,9 +47,14 @@ struct image {
char * layout;
uint16_t hash;
uint32_t size;
struct image_part * parts;
struct image_fd * fds;
int fd;
int is_shared_fd;
uint32_t align;
size_t offset;
size_t cur;
size_t acur;
char * orig_filename;
};
struct image_list {
@@ -79,11 +63,9 @@ struct image_list {
struct image_list * next;
};
struct image * image_alloc_from_file(const char * file, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts);
struct image * image_alloc_from_files(const char ** files, int count, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts);
struct image * image_alloc_from_fd(int fd, const char * orig_filename, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts);
struct image * image_alloc_from_fds(int * fds, const char ** orig_filenames, int count, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts);
struct image * image_alloc_from_shared_fd(int fd, size_t size, size_t offset, uint16_t hash, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts);
struct image * image_alloc_from_file(const char * file, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout);
struct image * image_alloc_from_fd(int fd, const char * orig_filename, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout);
struct image * image_alloc_from_shared_fd(int fd, size_t size, size_t offset, uint16_t hash, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout);
void image_free(struct image * image);
void image_seek(struct image * image, size_t whence);
size_t image_read(struct image * image, void * buf, size_t count);
@@ -94,7 +76,7 @@ void image_list_unlink(struct image_list * list);
uint16_t image_hash_from_data(struct image * image);
enum image_type image_type_from_data(struct image * image);
char * image_name_alloc_from_values(struct image * image, int part_num);
char * image_name_alloc_from_values(struct image * image);
enum image_type image_type_from_string(const char * type);
const char * image_type_to_string(enum image_type type);
int image_hwrev_is_valid(struct image * image, int16_t hwrev);
+65 -275
View File
@@ -19,7 +19,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/statvfs.h>
#include <sys/types.h>
@@ -199,6 +198,14 @@ enum device local_get_device(void) {
}
int local_flash_image(struct image * image) {
ERROR("Not implemented yet");
(void)image;
return -1;
}
static int local_nanddump(const char * file, int mtd, int offset, int length) {
struct statvfs buf;
@@ -220,18 +227,15 @@ static int local_nanddump(const char * file, int mtd, int offset, int length) {
return 1;
}
size = snprintf(NULL, 0, "nanddump --omitoob -s %d -l %d -f %s /dev/mtd%d", offset, length, file, mtd);
size = snprintf(NULL, 0, "nanddump -o -b -s %d -l %d -f %s /dev/mtd%dro", offset, length, file, mtd);
command = malloc(size+1);
if ( ! command )
return 1;
snprintf(command, size+1, "nanddump --omitoob -s %d -l %d -f %s /dev/mtd%d", offset, length, file, mtd);
snprintf(command, size+1, "nanddump -o -b -s %d -l %d -f %s /dev/mtd%dro", offset, length, file, mtd);
if ( ! simulate )
ret = system(command);
else
ret = 0;
ret = system(command);
free(command);
@@ -239,77 +243,52 @@ static int local_nanddump(const char * file, int mtd, int offset, int length) {
}
static FILE * local_nandwrite(int mtd, int offset) {
char * command;
FILE * stream;
size_t size;
size = snprintf(NULL, 0, "nandwrite -a -s %d -p /dev/mtd%d -", offset, mtd);
command = malloc(size+1);
if ( ! command )
return NULL;
snprintf(command, size+1, "nandwrite -a -s %d -p /dev/mtd%d -", offset, mtd);
if ( ! simulate )
stream = popen(command, "w");
else
stream = NULL;
free(command);
return stream;
}
struct nandpart_args {
unsigned int mtd;
unsigned int offset;
unsigned int length;
unsigned int header;
struct nanddump_args {
int valid;
int mtd;
int offset;
int length;
};
static struct nandpart_args nandpart_rx51[] = {
[IMAGE_XLOADER] = { 0, 0x00000000, 0x00004000, 0x00000000 },
[IMAGE_SECONDARY] = { 0, 0x00004000, 0x0001C000, 0x00000000 },
[IMAGE_KERNEL] = { 3, 0x00000000, 0x00200000, 0x00000800 },
[IMAGE_INITFS] = { 4, 0x00000000, 0x00200000, 0x00000000 },
[IMAGE_ROOTFS] = { 5, 0x00000000, 0x0fb40000, 0x00000000 },
static struct nanddump_args nanddump_rx51[] = {
[IMAGE_XLOADER] = { 1, 0, 0x00000000, 0x00004000 },
[IMAGE_SECONDARY] = { 1, 0, 0x00004000, 0x0001C000 },
[IMAGE_KERNEL] = { 1, 3, 0x00000800, 0x001FF800 },
[IMAGE_INITFS] = { 1, 4, 0x00000000, 0x00200000 },
[IMAGE_ROOTFS] = { 1, 5, 0x00000000, 0x0fb40000 },
};
/* FIXME: Is this table correct? */
static struct nandpart_args nandpart_rx4x[] = {
[IMAGE_XLOADER] = { 0, 0x00000200, 0x00003E00, 0x00000000 },
[IMAGE_SECONDARY] = { 0, 0x00004000, 0x0001C000, 0x00000000 },
[IMAGE_KERNEL] = { 2, 0x00000000, 0x00220000, 0x00000800 },
[IMAGE_INITFS] = { 3, 0x00000000, 0x00400000, 0x00000000 },
[IMAGE_ROOTFS] = { 4, 0x00000000, 0x0f960000, 0x00000000 },
static struct nanddump_args nanddump_rx4x[] = {
[IMAGE_XLOADER] = { 1, 0, 0x00000200, 0x00003E00 },
[IMAGE_SECONDARY] = { 1, 0, 0x00004000, 0x0001C000 },
[IMAGE_KERNEL] = { 1, 2, 0x00000800, 0x0021F800 },
[IMAGE_INITFS] = { 1, 3, 0x00000000, 0x00400000 },
[IMAGE_ROOTFS] = { 1, 4, 0x00000000, 0x0f960000 },
};
/* FIXME: Is this table correct? */
static struct nandpart_args nandpart_old[] = {
[IMAGE_XLOADER] = { 0, 0x00000200, 0x00003E00, 0x00000000 },
[IMAGE_SECONDARY] = { 0, 0x00004000, 0x0001C000, 0x00000000 },
[IMAGE_KERNEL] = { 2, 0x00000000, 0x00200000, 0x00000800 },
[IMAGE_INITFS] = { 3, 0x00000000, 0x00200000, 0x00000000 },
[IMAGE_ROOTFS] = { 4, 0x00000000, 0x0fb80000, 0x00000000 },
static struct nanddump_args nanddump_old[] = {
[IMAGE_XLOADER] = { 1, 0, 0x00000200, 0x00003E00 },
[IMAGE_SECONDARY] = { 1, 0, 0x00004000, 0x0001C000 },
[IMAGE_KERNEL] = { 1, 2, 0x00000800, 0x001FF800 },
[IMAGE_INITFS] = { 1, 3, 0x00000000, 0x00200000 },
[IMAGE_ROOTFS] = { 1, 4, 0x00000000, 0x0fb80000 },
};
struct nand_device {
struct nanddump_device {
size_t count;
struct nandpart_args * args;
struct nanddump_args * args;
};
#define NAND_DEVICE(device, array) [device] = { .count = sizeof(array)/sizeof(array[0]), .args = array }
#define NANDDUMP(device, array) [device] = { .count = sizeof(array)/sizeof(array[0]), .args = array }
static struct nand_device nand_device[] = {
NAND_DEVICE(DEVICE_SU_18, nandpart_old),
NAND_DEVICE(DEVICE_RX_34, nandpart_old),
NAND_DEVICE(DEVICE_RX_44, nandpart_rx4x),
NAND_DEVICE(DEVICE_RX_48, nandpart_rx4x),
NAND_DEVICE(DEVICE_RX_51, nandpart_rx51),
static struct nanddump_device nanddump[] = {
NANDDUMP(DEVICE_SU_18, nanddump_old),
NANDDUMP(DEVICE_RX_34, nanddump_old),
NANDDUMP(DEVICE_RX_44, nanddump_rx4x),
NANDDUMP(DEVICE_RX_48, nanddump_rx4x),
NANDDUMP(DEVICE_RX_51, nanddump_rx51),
};
#undef NANDDUMP
@@ -401,13 +380,10 @@ static void local_find_internal_mydocs(int * maj, int * min) {
int local_dump_image(enum image_type image, const char * file) {
unsigned char buf[20];
int ret = -1;
int fd = -1;
int header = 0;
unsigned char * addr = NULL;
off_t nlen = (off_t)-1;
off_t len;
off_t nlen, len;
int align;
int maj, min;
@@ -439,49 +415,17 @@ int local_dump_image(enum image_type image, const char * file) {
} else {
if ( device >= sizeof(nand_device)/sizeof(nand_device[0]) ) {
if ( device >= sizeof(nanddump)/sizeof(nanddump[0]) ) {
ERROR("Unsupported device");
goto clean;
}
if ( image >= nand_device[device].count ) {
if ( image >= nanddump[device].count ) {
ERROR("Unsupported image type: %s", image_type_to_string(image));
goto clean;
}
header = nand_device[device].args[image].header;
if ( header > 0 ) {
ret = local_nanddump(file, nand_device[device].args[image].mtd, nand_device[device].args[image].offset, header);
if ( ret != 0 ) {
if ( ! simulate )
unlink(file);
ret = -1;
goto clean;
}
if ( ! simulate ) {
fd = open(file, O_RDONLY);
if ( fd >= 0 ) {
if ( read(fd, buf, 20) == 20 ) {
if ( memcmp(buf, "NOLO!img\x02\x00\x00\x00\x00\x00\x00\x00", 16) == 0 )
nlen = ((unsigned int)buf[16] << 0) | ((unsigned int)buf[17] << 8) | ((unsigned int)buf[18] << 16) | ((unsigned int)buf[19] << 24);
else if ( memcmp(buf, "NOLO img", 8) == 0 )
nlen = ((unsigned int)buf[8] << 0) | ((unsigned int)buf[9] << 8) | ((unsigned int)buf[10] << 16) | ((unsigned int)buf[11] << 24);
}
close(fd);
fd = -1;
}
unlink(file);
}
}
ret = local_nanddump(file, nand_device[device].args[image].mtd, nand_device[device].args[image].offset + header, nand_device[device].args[image].length - header);
ret = local_nanddump(file, nanddump[device].args[image].mtd, nanddump[device].args[image].offset, nanddump[device].args[image].length);
}
@@ -490,9 +434,6 @@ int local_dump_image(enum image_type image, const char * file) {
goto clean;
}
if ( simulate )
goto clean;
fd = open(file, O_RDWR);
if ( fd < 0 )
goto clean;
@@ -501,35 +442,31 @@ int local_dump_image(enum image_type image, const char * file) {
if ( len == (off_t)-1 || len == 0 )
goto clean;
if ( header <= 0 || nlen == (off_t)-1 ) {
addr = (unsigned char *)mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
addr = (unsigned char *)mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
if ( addr == MAP_FAILED )
addr = NULL;
if ( addr == MAP_FAILED )
addr = NULL;
if ( ! addr )
goto clean;
if ( ! addr )
goto clean;
for ( nlen = len; nlen > 0; --nlen )
if ( addr[nlen-1] != 0xFF )
break;
for ( nlen = len; nlen > 0; --nlen )
if ( addr[nlen-1] != 0xFF )
break;
for ( ; nlen > 0; --nlen )
if ( addr[nlen-1] != 0x00 )
break;
for ( ; nlen > 0; --nlen )
if ( addr[nlen-1] != 0x00 )
break;
if ( image == IMAGE_MMC )
align = 8;
else
align = 7;
if ( image == IMAGE_MMC )
align = 8;
else
align = 7;
if ( ( nlen & ( ( 1ULL << align ) - 1 ) ) != 0 )
nlen = ((nlen >> align) + 1) << align;
if ( ( nlen & ( ( 1ULL << align ) - 1 ) ) != 0 )
nlen = ((nlen >> align) + 1) << align;
}
if ( header <= 0 && nlen == 0 ) {
if ( nlen == 0 ) {
printf("File %s is empty, removing it...\n", file);
unlink(file);
} else if ( nlen != len ) {
@@ -550,153 +487,6 @@ clean:
}
int local_flash_image(struct image * image) {
unsigned char buf[0x20000];
unsigned int remaining, size;
void (*sighandler)(int);
int min, maj, fd;
FILE * stream;
int ret;
printf("Flash image:\n");
image_print_info(image);
if ( image->type == IMAGE_MMC ) {
maj = -1;
min = -1;
local_find_internal_mydocs(&maj, &min);
if ( maj == -1 || min == -1 )
ERROR_RETURN("Cannot find MyDocs mmc device: Slot 'internal' was not found", -1);
VERBOSE("Detected internal MyDocs mmc device: major=%d minor=%d\n", maj, min);
fd = disk_open_dev(maj, min, 1, simulate ? 1 : 0);
if ( fd < 0 )
ERROR_RETURN("Cannot open MyDocs mmc device in /dev/", -1);
ret = disk_flash_dev(fd, image);
close(fd);
} else {
if ( device >= sizeof(nand_device)/sizeof(nand_device[0]) )
ERROR_RETURN("Unsupported device", -1);
if ( image->type >= nand_device[device].count ) {
ERROR("Unsupported image type: %s", image_type_to_string(image->type));
return -1;
}
if ( image->size > nand_device[device].args[image->type].length - nand_device[device].args[image->type].header )
ERROR_RETURN("Image is too big", -1);
printf("Using nandwrite for flashing %s image...\n", image_type_to_string(image->type));
stream = local_nandwrite(nand_device[device].args[image->type].mtd, nand_device[device].args[image->type].offset);
if ( ! simulate && ! stream )
ERROR_RETURN("Cannot start nandwrite process", -1);
ret = 0;
sighandler = signal(SIGPIPE, SIG_IGN);
/* Write NOLO!img or NOLO img header with size */
if ( nand_device[device].args[image->type].header > 0 ) {
if ( device == DEVICE_RX_51 ) {
memcpy(buf, "NOLO!img\x02\x00\x00\x00\x00\x00\x00\x00", 16);
buf[16] = (image->size >> 0) & 0xFF;
buf[17] = (image->size >> 8) & 0xFF;
buf[18] = (image->size >> 16) & 0xFF;
buf[19] = (image->size >> 24) & 0xFF;
size = 20;
} else {
memcpy(buf, "NOLO img", 8);
buf[ 8] = (image->size >> 0) & 0xFF;
buf[ 9] = (image->size >> 8) & 0xFF;
buf[10] = (image->size >> 16) & 0xFF;
buf[11] = (image->size >> 24) & 0xFF;
size = 12;
}
if ( ! simulate ) {
if ( fwrite(buf, size, 1, stream) != 1 ) {
ret = -1;
goto clean;
}
}
memset(buf, 0, sizeof(buf));
remaining = nand_device[device].args[image->type].header - size;
while ( remaining > 0 ) {
size = remaining < sizeof(buf) ? remaining : sizeof(buf);
if ( ! simulate ) {
if ( fwrite(buf, size, 1, stream) != 1 ) {
ret = -1;
goto clean;
}
}
remaining -= size;
}
}
/* Write image data */
image_seek(image, 0);
remaining = image->size;
while ( remaining > 0 ) {
size = remaining < sizeof(buf) ? remaining : sizeof(buf);
size = image_read(image, buf, size);
if ( size == 0 ) {
ERROR("Failed to read image");
ret = -1;
goto clean;
}
if ( ! simulate ) {
if ( fwrite(buf, size, 1, stream) != 1 ) {
ret = -1;
goto clean;
}
}
remaining -= size;
}
/* Write filler zeros to clear previous data */
memset(buf, 0, sizeof(buf));
remaining = nand_device[device].args[image->type].length - (image->size + nand_device[device].args[image->type].header);
while ( remaining > 0 ) {
size = remaining < sizeof(buf) ? remaining : sizeof(buf);
if ( ! simulate ) {
if ( fwrite(buf, size, 1, stream) != 1 ) {
ret = -1;
goto clean;
}
}
remaining -= size;
}
clean:
if ( ! simulate ) {
if ( ret == 0 )
ret = pclose(stream);
else
pclose(stream);
}
signal(SIGPIPE, sighandler);
if ( ret != 0 )
ERROR("Flashing failed");
}
if ( ret == 0 )
printf("Done\n");
return ret;
}
int local_check_badblocks(const char * device) {
ERROR("Not implemented yet");
+20 -133
View File
@@ -77,14 +77,12 @@ static void show_usage(void) {
"Input image specification:\n"
" -M file specify fiasco image\n"
" -m arg specify normal image\n"
" arg is [[[dev:[hw:]]ver:]type:]file[@name][#file2[@name2]...][%%lay]\n"
" arg is [[[dev:[hw:]]ver:]type:]file[%%lay]\n"
" dev is device name string (default: empty)\n"
" hw are comma separated list of HW revisions (default: empty)\n"
" ver is image version string (default: empty)\n"
" type is image type (default: autodetect)\n"
" file is image file name\n"
" fileN is file name of the Nth image part\n"
" nameN is name of the Nth image part (default: none)\n"
" lay is layout file name (default: none)\n"
"\n"
@@ -145,34 +143,25 @@ int simulate;
int noverify;
int verbose;
/* arg = [[[dev:[hw:]]ver:]type:]file[@name][#file2[@name2][#file3[@name3]...]][%lay] */
/* arg = [[[dev:[hw:]]ver:]type:]file[%%lay] */
static void parse_image_arg(char * arg, struct image_list ** image_first) {
struct stat st;
struct image * image;
struct image_fd * image_fd;
struct image_part * image_part;
struct image_part * image_parts;
char * file;
const char ** files;
char * type;
char * device;
char * hwrevs;
char * version;
char * layout;
char * part_files;
char * layout_file;
char * name;
char * ptr;
uint32_t offset;
int count;
int fd;
/* First check if arg is file, then try to parse arg format */
fd = open(arg, O_RDONLY);
if ( fd >= 0 ) {
if ( fstat(fd, &st) == 0 && !S_ISDIR(st.st_mode) ) {
image = image_alloc_from_fd(fd, arg, NULL, NULL, NULL, NULL, NULL, NULL);
image = image_alloc_from_fd(fd, arg, NULL, NULL, NULL, NULL, NULL);
if ( ! image ) {
ERROR("Cannot load image file %s", arg);
exit(1);
@@ -186,12 +175,7 @@ static void parse_image_arg(char * arg, struct image_list ** image_first) {
exit(1);
}
part_files = strchr(arg, '#');
if ( part_files )
*(part_files++) = 0;
layout_file = part_files ? part_files : arg;
layout_file = strchr(layout_file, '%');
layout_file = strchr(arg, '%');
if ( layout_file )
*(layout_file++) = 0;
@@ -253,85 +237,16 @@ static void parse_image_arg(char * arg, struct image_list ** image_first) {
close(fd);
}
count = 0;
ptr = part_files;
while ( ptr ) {
count++;
ptr = strchr(ptr, '#');
if ( ptr )
ptr++;
}
image = image_alloc_from_file(file, type, device, hwrevs, version, layout);
files = calloc(count+1, sizeof(*files));
if ( ! files ) {
ALLOC_ERROR();
exit(1);
}
name = strchr(file, '@');
if ( name ) {
*name = 0;
name++;
}
if ( count > 0 || name ) {
image_part = calloc(1, sizeof(*image_part));
if ( ! image_part ) {
ALLOC_ERROR();
exit(1);
}
image_part->name = name ? strdup(name) : NULL;
image_parts = image_part;
} else {
image_part = NULL;
image_parts = NULL;
}
count = 0;
files[count++] = file;
while ( part_files ) {
ptr = strchr(part_files, '#');
if ( ptr ) {
*ptr = 0;
ptr++;
}
name = strchr(part_files, '@');
if ( name ) {
*name = 0;
name++;
}
image_part->next = calloc(1, sizeof(*image_part));
if ( ! image_part->next ) {
ALLOC_ERROR();
exit(1);
}
image_part = image_part->next;
image_part->name = name ? strdup(name) : NULL;
files[count++] = part_files;
part_files = ptr;
}
image = image_alloc_from_files(files, count, type, device, hwrevs, version, layout, image_parts);
free(files);
free(layout);
if ( layout )
free(layout);
if ( ! image ) {
ERROR("Cannot load image file %s", file);
exit(1);
}
image_part = image_parts;
image_fd = image->fds;
offset = 0;
while ( image_part && image_fd ) {
image_part->offset = offset;
image_part->size = image_fd->size;
offset += image_part->size;
image_part = image_part->next;
image_fd = image_fd->next;
}
image_list_add(image_first, image);
}
@@ -506,13 +421,9 @@ int main(int argc, char **argv) {
enum device detected_device = DEVICE_UNKNOWN;
int16_t detected_hwrev = -1;
struct stat st;
int i;
char buf[512];
char * ptr = NULL;
char * ptr1 = NULL;
char * ptr2 = NULL;
char * tmp = NULL;
char nolo_ver[512];
@@ -912,7 +823,7 @@ int main(int argc, char **argv) {
while ( image_ptr ) {
struct image_list * next = image_ptr->next;
if ( image_ptr->image->type == IMAGE_UNKNOWN ) {
WARNING("Removing unknown image (specified by %s %s)", (image_ptr->image->fds && image_ptr->image->fds->orig_filename) ? "file" : "fiasco", (image_ptr->image->fds && image_ptr->image->fds->orig_filename) ? image_ptr->image->fds->orig_filename : "image");
WARNING("Removing unknown image (specified by %s %s)", image_ptr->image->orig_filename ? "file" : "fiasco", image_ptr->image->orig_filename ? image_ptr->image->orig_filename : "image");
if ( image_ptr == image_first )
image_first = next;
if ( fiasco_in && image_ptr == fiasco_in->first )
@@ -1123,9 +1034,9 @@ int main(int argc, char **argv) {
/* filter images by device & hwrev */
if ( detected_device )
filter_images_by_device(dev->detected_device, &image_first);
if ( detected_hwrev > 0 )
if ( detected_hwrev )
filter_images_by_hwrev(dev->detected_hwrev, &image_first);
if ( fiasco_in && ( detected_device || detected_hwrev > 0 ) )
if ( fiasco_in && ( detected_device || detected_hwrev ) )
fiasco_in->first = image_first;
/* set kernel and initfs images for loading */
@@ -1183,7 +1094,7 @@ int main(int argc, char **argv) {
if ( dev_load ) {
if ( image_kernel ) {
ret = dev_load_image(dev, image_kernel->image);
if ( ret == -EAGAIN )
if ( ret < 0 )
goto again;
if ( image_kernel == image_first )
@@ -1197,7 +1108,7 @@ int main(int argc, char **argv) {
if ( image_initfs ) {
ret = dev_load_image(dev, image_initfs->image);
if ( ret == -EAGAIN )
if ( ret < 0 )
goto again;
if ( image_initfs == image_first )
@@ -1216,7 +1127,7 @@ int main(int argc, char **argv) {
while ( image_ptr ) {
struct image_list * next = image_ptr->next;
ret = dev_flash_image(dev, image_ptr->image);
if ( ret == -EAGAIN )
if ( ret < 0 )
goto again;
if ( image_ptr == image_first )
@@ -1348,12 +1259,11 @@ int main(int argc, char **argv) {
for ( i = 0; i < IMAGE_COUNT; ++i ) {
if ( ! image_tmp_name(i) || ( stat(image_tmp_name(i), &st) < 0 && errno == ENOENT ) )
if ( ! image_tmp_name(i) )
continue;
buf[0] = 0;
if ( dev->detected_hwrev > 0 )
snprintf(buf, sizeof(buf), "%hd", dev->detected_hwrev);
snprintf(buf, sizeof(buf), "%hd", dev->detected_hwrev);
switch ( i ) {
case IMAGE_2ND:
@@ -1383,9 +1293,7 @@ int main(int argc, char **argv) {
break;
}
/* TODO: add support for dumping mmc layout and also other mmc partitions as image data parts */
image_dump = image_alloc_from_file(image_tmp_name(i), image_type_to_string(i), device_to_string(dev->detected_device), buf, ptr, NULL, NULL);
image_dump = image_alloc_from_file(image_tmp_name(i), image_type_to_string(i), device_to_string(dev->detected_device), buf, ptr, NULL);
if ( ! image_dump )
continue;
@@ -1456,20 +1364,7 @@ int main(int argc, char **argv) {
}
buf[0] = 0;
snprintf(buf, sizeof(buf), "%s", image_type_to_string(i));
ptr1 = buf + strlen(buf);
if ( dev->detected_device ) {
snprintf(ptr1, sizeof(buf)-(ptr1-buf), "-%s", device_to_string(dev->detected_device));
ptr1 += strlen(ptr1);
}
if ( dev->detected_hwrev > 0 )
snprintf(ptr1, sizeof(buf)-(ptr1-buf), ":%hd", dev->detected_hwrev);
ptr2 = ptr1 + strlen(ptr1);
if ( ptr && ptr[0] )
snprintf(ptr2, sizeof(buf)-(ptr2-buf), "_%s", ptr);
snprintf(buf, sizeof(buf), "%s-%s:%hd_%s", image_type_to_string(i), device_to_string(dev->detected_device), dev->detected_hwrev, ptr);
rename_ret = rename(image_tmp_name(i), buf);
rename_errno = errno;
@@ -1484,21 +1379,13 @@ int main(int argc, char **argv) {
errno = rename_errno;
ERROR_INFO("Renaming failed");
*ptr2 = 0;
buf[0] = 0;
snprintf(buf, sizeof(buf), "%s-%s_%s", image_type_to_string(i), device_to_string(dev->detected_device), ptr);
printf("Trying to rename %s image file to %s...\n", image_type_to_string(i), buf);
if ( rename(image_tmp_name(i), buf) < 0 ) {
if ( rename(image_tmp_name(i), buf) < 0 )
ERROR_INFO("Renaming failed");
*ptr1 = 0;
printf("Trying to rename %s image file to %s...\n", image_type_to_string(i), buf);
if ( rename(image_tmp_name(i), buf) < 0 )
ERROR_INFO("Renaming failed");
}
}
}
+11 -23
View File
@@ -48,7 +48,7 @@ struct mkii_message {
} __attribute__((__packed__));
static int mkii_send_receive(libusb_device_handle * udev, uint8_t type, struct mkii_message * in_msg, size_t data_size, struct mkii_message * out_msg, size_t out_size) {
static int mkii_send_receive(usb_dev_handle * udev, uint8_t type, struct mkii_message * in_msg, size_t data_size, struct mkii_message * out_msg, size_t out_size) {
int ret;
static uint8_t number = 0;
@@ -59,13 +59,13 @@ static int mkii_send_receive(libusb_device_handle * udev, uint8_t type, struct m
in_msg->num = number++;
in_msg->type = type;
ret = usb_bulk_send(udev, USB_WRITE_EP, in_msg, data_size + sizeof(*in_msg), 5000);
ret = usb_bulk_write(udev, USB_WRITE_EP, (char *)in_msg, data_size + sizeof(*in_msg), 5000);
if ( ret < 0 )
return ret;
if ( (size_t)ret != data_size + sizeof(*in_msg) )
return -1;
ret = usb_bulk_recv(udev, USB_READ_EP, out_msg, out_size, 5000);
ret = usb_bulk_read(udev, USB_READ_EP, (char *)out_msg, out_size, 5000);
if ( ret < 0 )
return ret;
@@ -89,7 +89,6 @@ int mkii_init(struct usb_device_info * dev) {
char buf[2048];
struct mkii_message * msg;
struct libusb_config_descriptor * config;
enum device device;
int ret;
char * newptr;
@@ -160,10 +159,8 @@ int mkii_init(struct usb_device_info * dev) {
printf("\n");
memset(buf, 0, sizeof(buf));
if ( libusb_get_config_descriptor(libusb_get_device(dev->udev), 0, &config) == 0 ) {
libusb_get_string_descriptor_ascii(dev->udev, config->iConfiguration, (unsigned char *)buf, sizeof(buf));
libusb_free_config_descriptor(config);
}
if ( usb_device(dev->udev)->descriptor.bNumConfigurations >= 1 )
usb_get_string_simple(dev->udev, usb_device(dev->udev)->config[0].iConfiguration, buf, sizeof(buf));
if ( strncmp(buf, "Firmware Upgrade Configuration", sizeof("Firmware Upgrade Configuration")) == 0 )
dev->data |= MKII_UPDATE_MODE;
@@ -216,18 +213,14 @@ int mkii_flash_image(struct usb_device_info * dev, struct image * image) {
msg1 = (struct mkii_message *)buf1;
ptr = msg->data;
/* File data header */
memcpy(ptr, "\x2E", 1);
ptr += 1;
/* Signature */
memcpy(ptr, "\x2E\x19\x01\x01", 4);
ptr += 4;
/* Length of file data */
memcpy(ptr, "\x19", 1);
/* Space */
memcpy(ptr, "\x00", 1);
ptr += 1;
/* File data (ignored): asic index: APE (0x01), device type: NAND (0x01), device index: 0 */
memcpy(ptr, "\x01\x01\x00", 3);
ptr += 3;
/* Hash */
hash = htons(image->hash);
memcpy(ptr, &hash, 2);
@@ -246,7 +239,7 @@ int mkii_flash_image(struct usb_device_info * dev, struct image * image) {
memcpy(ptr, &size, 4);
ptr += 4;
/* Load address (ignored) */
/* Space */
memcpy(ptr, "\x00\x00\x00\x00", 4);
ptr += 4;
@@ -368,11 +361,6 @@ int mkii_reboot_device(struct usb_device_info * dev, int update) {
if ( ret != 1 || msg->data[0] != 0 )
ERROR_RETURN("Cannot send reboot command", -1);
if (dev->data & MKII_UPDATE_MODE)
MSLEEP(100);
else
MSLEEP(3000);
return 0;
}
+31 -35
View File
@@ -88,7 +88,7 @@ static void nolo_error_log(struct usb_device_info * dev, int only_clear) {
memset(buf, 0, sizeof(buf));
ret = libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_ERROR_LOG, 0, 0, (unsigned char *)buf, sizeof(buf), 2000);
ret = usb_control_msg(dev->udev, NOLO_QUERY, NOLO_ERROR_LOG, 0, 0, buf, sizeof(buf), 2000);
if ( ret < 0 )
break;
@@ -118,7 +118,7 @@ static int nolo_identify_string(struct usb_device_info * dev, const char * str,
memset(buf, 0, sizeof(buf));
ret = libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_IDENTIFY, 0, 0, (unsigned char *)buf, sizeof(buf), 2000);
ret = usb_control_msg(dev->udev, NOLO_QUERY, NOLO_IDENTIFY, 0, 0, (char *)buf, sizeof(buf), 2000);
if ( ret < 0 )
NOLO_ERROR_RETURN("NOLO_IDENTIFY failed", -1);
@@ -148,10 +148,10 @@ static int nolo_set_string(struct usb_device_info * dev, char * str, char * arg)
if ( simulate )
return 0;
if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_STRING, 0, 0, (unsigned char *)str, strlen(str), 2000) < 0 )
if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_STRING, 0, 0, str, strlen(str), 2000) < 0 )
NOLO_ERROR_RETURN("NOLO_STRING failed", -1);
if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_SET_STRING, 0, 0, (unsigned char *)arg, strlen(arg), 2000) < 0 )
if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_SET_STRING, 0, 0, arg, strlen(arg), 2000) < 0 )
NOLO_ERROR_RETURN("NOLO_SET_STRING failed", -1);
return 0;
@@ -162,10 +162,10 @@ static int nolo_get_string(struct usb_device_info * dev, char * str, char * out,
int ret = 0;
if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_STRING, 0, 0, (unsigned char *)str, strlen(str), 2000) < 0 )
if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_STRING, 0, 0, str, strlen(str), 2000) < 0 )
return -1;
if ( ( ret = libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_GET_STRING, 0, 0, (unsigned char *)out, size-1, 2000) ) < 0 )
if ( ( ret = usb_control_msg(dev->udev, NOLO_QUERY, NOLO_GET_STRING, 0, 0, out, size-1, 2000) ) < 0 )
return -1;
if ( (size_t)ret > size-1 )
@@ -209,7 +209,7 @@ int nolo_init(struct usb_device_info * dev) {
printf("Initializing NOLO...\n");
while ( val != 0 )
if ( libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_STATUS, 0, 0, (unsigned char *)&val, 4, 2000) < 0 )
if ( usb_control_msg(dev->udev, NOLO_QUERY, NOLO_STATUS, 0, 0, (char *)&val, 4, 2000) == -1 )
NOLO_ERROR_RETURN("NOLO_STATUS failed", -1);
/* clear error log */
@@ -269,18 +269,14 @@ static int nolo_send_image(struct usb_device_info * dev, struct image * image, i
ptr = buf;
/* File data header */
memcpy(ptr, "\x2E", 1);
ptr += 1;
/* Signature */
memcpy(ptr, "\x2E\x19\x01\x01", 4);
ptr += 4;
/* Length of file data */
memcpy(ptr, "\x19", 1);
/* Space */
memcpy(ptr, "\x00", 1);
ptr += 1;
/* File data (ignored by NOLO): asic index: APE (0x01), device type: NAND (0x01), device index: 0 */
memcpy(ptr, "\x01\x01\x00", 3);
ptr += 3;
/* Hash */
hash = htons(image->hash);
memcpy(ptr, &hash, 2);
@@ -299,7 +295,7 @@ static int nolo_send_image(struct usb_device_info * dev, struct image * image, i
memcpy(ptr, &size, 4);
ptr += 4;
/* Load address (ignored by NOLO) */
/* Space */
memcpy(ptr, "\x00\x00\x00\x00", 4);
ptr += 4;
@@ -372,7 +368,7 @@ static int nolo_send_image(struct usb_device_info * dev, struct image * image, i
printf("Sending image header...\n");
if ( ! simulate ) {
if ( libusb_control_transfer(dev->udev, NOLO_WRITE, request, 0, 0, (unsigned char *)buf, ptr-buf, 2000) < 0 )
if ( usb_control_msg(dev->udev, NOLO_WRITE, request, 0, 0, buf, ptr-buf, 2000) < 0 )
NOLO_ERROR_RETURN("Sending image header failed", -1);
}
@@ -391,7 +387,7 @@ static int nolo_send_image(struct usb_device_info * dev, struct image * image, i
if ( ret == 0 )
break;
if ( ! simulate ) {
if ( usb_bulk_send(dev->udev, USB_WRITE_DATA_EP, buf, ret, 5000) != ret ) {
if ( usb_bulk_write(dev->udev, USB_WRITE_DATA_EP, buf, ret, 5000) != ret ) {
PRINTF_END();
NOLO_ERROR_RETURN("Sending image failed", -1);
}
@@ -403,7 +399,7 @@ static int nolo_send_image(struct usb_device_info * dev, struct image * image, i
if ( flash ) {
printf("Finishing flashing...\n");
if ( ! simulate ) {
if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_SEND_FLASH_FINISH, 0, 0, NULL, 0, 30000) < 0 )
if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_SEND_FLASH_FINISH, 0, 0, NULL, 0, 30000) < 0 )
NOLO_ERROR_RETURN("Finishing failed", -1);
}
}
@@ -460,7 +456,7 @@ int nolo_flash_image(struct usb_device_info * dev, struct image * image) {
printf("Flashing image...\n");
if ( ! simulate ) {
if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_FLASH_IMAGE, 0, index, NULL, 0, 10000) )
if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_FLASH_IMAGE, 0, index, NULL, 0, 10000) )
NOLO_ERROR_RETURN("Flashing failed", -1);
}
@@ -545,7 +541,7 @@ int nolo_flash_image(struct usb_device_info * dev, struct image * image) {
}
MSLEEP(50);
SLEEP(0xc350); // 0.5s
}
@@ -581,7 +577,7 @@ int nolo_boot_device(struct usb_device_info * dev, const char * cmdline) {
cmdline = NULL;
}
if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_BOOT, mode, 0, (unsigned char *)cmdline, size, 2000) < 0 )
if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_BOOT, mode, 0, (char *)cmdline, size, 2000) < 0 )
NOLO_ERROR_RETURN("Booting failed", -1);
return 0;
@@ -591,7 +587,7 @@ int nolo_boot_device(struct usb_device_info * dev, const char * cmdline) {
int nolo_reboot_device(struct usb_device_info * dev) {
printf("Rebooting device...\n");
if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_REBOOT, 0, 0, NULL, 0, 2000) < 0 )
if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_REBOOT, 0, 0, NULL, 0, 2000) < 0 )
NOLO_ERROR_RETURN("NOLO_REBOOT failed", -1);
return 0;
@@ -600,7 +596,7 @@ int nolo_reboot_device(struct usb_device_info * dev) {
int nolo_get_root_device(struct usb_device_info * dev) {
uint8_t device = 0;
if ( libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_GET, 0, NOLO_ROOT_DEVICE, (unsigned char *)&device, 1, 2000) < 0 )
if ( usb_control_msg(dev->udev, NOLO_QUERY, NOLO_GET, 0, NOLO_ROOT_DEVICE, (char *)&device, 1, 2000) < 0 )
NOLO_ERROR_RETURN("Cannot get root device", -1);
return device;
@@ -611,7 +607,7 @@ int nolo_set_root_device(struct usb_device_info * dev, int device) {
printf("Setting root device to %d...\n", device);
if ( simulate )
return 0;
if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_SET, device, NOLO_ROOT_DEVICE, NULL, 0, 2000) < 0 )
if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_SET, device, NOLO_ROOT_DEVICE, NULL, 0, 2000) < 0 )
NOLO_ERROR_RETURN("Cannot set root device", -1);
return 0;
@@ -620,7 +616,7 @@ int nolo_set_root_device(struct usb_device_info * dev, int device) {
int nolo_get_usb_host_mode(struct usb_device_info * dev) {
uint32_t enabled = 0;
if ( libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_GET, 0, NOLO_USB_HOST_MODE, (unsigned char *)&enabled, 4, 2000) < 0 )
if ( usb_control_msg(dev->udev, NOLO_QUERY, NOLO_GET, 0, NOLO_USB_HOST_MODE, (void *)&enabled, 4, 2000) < 0 )
NOLO_ERROR_RETURN("Cannot get USB host mode status", -1);
return enabled ? 1 : 0;
@@ -631,7 +627,7 @@ int nolo_set_usb_host_mode(struct usb_device_info * dev, int enable) {
printf("%s USB host mode...\n", enable ? "Enabling" : "Disabling");
if ( simulate )
return 0;
if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_SET, enable, NOLO_USB_HOST_MODE, NULL, 0, 2000) < 0 )
if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_SET, enable, NOLO_USB_HOST_MODE, NULL, 0, 2000) < 0 )
NOLO_ERROR_RETURN("Cannot change USB host mode status", -1);
return 0;
@@ -640,7 +636,7 @@ int nolo_set_usb_host_mode(struct usb_device_info * dev, int enable) {
int nolo_get_rd_mode(struct usb_device_info * dev) {
uint8_t enabled = 0;
if ( libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_GET, 0, NOLO_RD_MODE, (unsigned char *)&enabled, 1, 2000) < 0 )
if ( usb_control_msg(dev->udev, NOLO_QUERY, NOLO_GET, 0, NOLO_RD_MODE, (char *)&enabled, 1, 2000) < 0 )
NOLO_ERROR_RETURN("Cannot get R&D mode status", -1);
return enabled ? 1 : 0;
@@ -651,7 +647,7 @@ int nolo_set_rd_mode(struct usb_device_info * dev, int enable) {
printf("%s R&D mode...\n", enable ? "Enabling" : "Disabling");
if ( simulate )
return 0;
if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_SET, enable, NOLO_RD_MODE, NULL, 0, 2000) < 0 )
if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_SET, enable, NOLO_RD_MODE, NULL, 0, 2000) < 0 )
NOLO_ERROR_RETURN("Cannot change R&D mode status", -1);
return 0;
@@ -664,7 +660,7 @@ int nolo_get_rd_flags(struct usb_device_info * dev, char * flags, size_t size) {
uint16_t add_flags = 0;
char * ptr = flags;
if ( libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_GET, 0, NOLO_ADD_RD_FLAGS, (unsigned char *)&add_flags, 2, 2000) < 0 )
if ( usb_control_msg(dev->udev, NOLO_QUERY, NOLO_GET, 0, NOLO_ADD_RD_FLAGS, (char *)&add_flags, 2, 2000) < 0 )
NOLO_ERROR_RETURN("Cannot get R&D flags", -1);
if ( add_flags & NOLO_RD_FLAG_NO_OMAP_WD )
@@ -764,10 +760,10 @@ int nolo_set_rd_flags(struct usb_device_info * dev, const char * flags) {
if ( simulate )
return 0;
if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_SET, add_flags, NOLO_ADD_RD_FLAGS, NULL, 0, 2000) < 0 )
if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_SET, add_flags, NOLO_ADD_RD_FLAGS, NULL, 0, 2000) < 0 )
NOLO_ERROR_RETURN("Cannot add R&D flags", -1);
if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_SET, del_flags, NOLO_DEL_RD_FLAGS, NULL, 0, 2000) < 0 )
if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_SET, del_flags, NOLO_DEL_RD_FLAGS, NULL, 0, 2000) < 0 )
NOLO_ERROR_RETURN("Cannot del R&D flags", -1);
return 0;
@@ -827,7 +823,7 @@ int nolo_get_nolo_ver(struct usb_device_info * dev, char * ver, size_t size) {
uint32_t version = 0;
if ( libusb_control_transfer(dev->udev, NOLO_QUERY, NOLO_GET_NOLO_VERSION, 0, 0, (unsigned char *)&version, 4, 2000) < 0 )
if ( usb_control_msg(dev->udev, NOLO_QUERY, NOLO_GET_NOLO_VERSION, 0, 0, (char *)&version, 4, 2000) < 0 )
NOLO_ERROR_RETURN("Cannot get NOLO version", -1);
if ( (version & 255) > 1 )
@@ -886,7 +882,7 @@ int nolo_set_sw_ver(struct usb_device_info * dev, const char * ver) {
memcpy(ptr, ver, len);
ptr += len;
if ( libusb_control_transfer(dev->udev, NOLO_WRITE, NOLO_SET_SW_RELEASE, 0, 0, (unsigned char *)buf, ptr-buf, 2000) < 0 )
if ( usb_control_msg(dev->udev, NOLO_WRITE, NOLO_SET_SW_RELEASE, 0, 0, buf, ptr-buf, 2000) < 0 )
NOLO_ERROR_RETURN("NOLO_SET_SW_RELEASE failed", -1);
return 0;
+129 -191
View File
@@ -17,6 +17,11 @@
*/
/* Enable RTLD_DEFAULT for glibc */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
@@ -24,6 +29,7 @@
#include <errno.h>
#include <ctype.h>
#include <signal.h>
#include <dlfcn.h>
#include "global.h"
#include "device.h"
@@ -33,26 +39,23 @@
#include "cold-flash.h"
#include "mkii.h"
#define USB_ERROR(str, err) do { PRINTF_END(); ERROR("%s: %s", str, libusb_strerror(err)); } while (0)
static libusb_context * usb_ctx;
#ifdef __linux__
#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
#include <sys/ioctl.h>
#endif
#endif
static struct usb_flash_device usb_devices[] = {
/* vend prod i a protocol devices */
{ 0x0421, 0x0096, -1, -1, FLASH_DISK, { DEVICE_RX_44, 0 } },
{ 0x0421, 0x0105, 2, 1, FLASH_NOLO, { DEVICE_SU_18, DEVICE_RX_34, DEVICE_RX_44, DEVICE_RX_48, DEVICE_RX_51, DEVICE_RM_680, DEVICE_RM_696, 0 } },
{ 0x0421, 0x0106, 0, 0, FLASH_COLD, { DEVICE_RX_51, DEVICE_RM_680, DEVICE_RM_696, 0 } },
{ 0x0421, 0x0189, -1, -1, FLASH_DISK, { DEVICE_RX_48, 0 } },
{ 0x0421, 0x01c7, -1, -1, FLASH_DISK, { DEVICE_RX_51, 0 } },
{ 0x0421, 0x01c8, 1, 1, FLASH_MKII, { DEVICE_RX_51, DEVICE_RM_680, 0 } },
{ 0x0421, 0x01c8, 1, 0, FLASH_UNKN, { DEVICE_RX_51, 0 } }, /* U-Boot mode (TTY via USB) */
{ 0x0421, 0x03d1, -1, -1, FLASH_DISK, { DEVICE_RM_680, 0 } },
{ 0x0421, 0x03d2, 1, 1, FLASH_MKII, { DEVICE_RM_680, 0 } },
{ 0x0421, 0x0431, -1, -1, FLASH_DISK, { DEVICE_SU_18, DEVICE_RX_34, 0 } },
{ 0x0421, 0x04c3, -1, -1, FLASH_DISK, { DEVICE_RX_34, 0 } },
{ 0x0421, 0x0518, -1, -1, FLASH_DISK, { DEVICE_RM_696, 0 } },
{ 0x0421, 0x0519, -1, -1, FLASH_UNKN, { DEVICE_RM_696, 0 } }, /* RNDIS/Ethernet mode */
{ 0x0421, 0x051a, 2, 1, FLASH_UNKN, { DEVICE_RM_696, 0 } }, /* Sync mode (ADL protocol) */
{ 0x0421, 0x0096, -1, -1, -1, FLASH_DISK, { DEVICE_RX_44, 0 } },
{ 0x0421, 0x0105, 2, 1, -1, FLASH_NOLO, { DEVICE_SU_18, DEVICE_RX_34, DEVICE_RX_44, DEVICE_RX_48, DEVICE_RX_51, DEVICE_RM_680, DEVICE_RM_696, 0 } },
{ 0x0421, 0x0106, 0, -1, -1, FLASH_COLD, { DEVICE_RX_51, DEVICE_RM_680, DEVICE_RM_696, 0 } },
{ 0x0421, 0x0189, -1, -1, -1, FLASH_DISK, { DEVICE_RX_48, 0 } },
{ 0x0421, 0x01c7, -1, -1, -1, FLASH_DISK, { DEVICE_RX_51, 0 } },
{ 0x0421, 0x01c8, 1, 1, -1, FLASH_MKII, { DEVICE_RX_51, DEVICE_RM_680, 0 } },
{ 0x0421, 0x03d1, -1, -1, -1, FLASH_DISK, { DEVICE_RM_680, 0 } },
{ 0x0421, 0x0431, -1, -1, -1, FLASH_DISK, { DEVICE_SU_18, DEVICE_RX_34, 0 } },
{ 0x0421, 0x04c3, -1, -1, -1, FLASH_DISK, { DEVICE_RX_34, 0 } },
{ 0x0421, 0x3f00, 2, 1, -1, FLASH_NOLO, { DEVICE_RX_34, 0 } },
};
static const char * usb_flash_protocols[] = {
@@ -84,20 +87,31 @@ static void usb_flash_device_info_print(const struct usb_flash_device * dev) {
}
static void usb_reattach_kernel_driver(libusb_device_handle * udev, int interface, int detached) {
static void usb_reattach_kernel_driver(usb_dev_handle * udev, int interface) {
#ifdef __linux__
#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
struct {
int ifno;
int ioctl_code;
void * data;
} command = {
.ifno = interface,
.ioctl_code = _IO('U', 23),
.data = NULL,
};
if ( interface < 0 )
return;
libusb_release_interface(udev, interface);
/* Reattach only driver detached by us, on macOS reattaching re-enumerates (resets) device */
if ( detached )
libusb_attach_kernel_driver(udev, interface);
usb_release_interface(udev, interface);
ioctl(*((int *)udev), _IOWR('U', 18, command), &command);
#endif
#endif
}
static void usb_descriptor_info_print(libusb_device_handle * udev, const struct libusb_device_descriptor * desc, char * product, size_t size) {
static void usb_descriptor_info_print(usb_dev_handle * udev, struct usb_device * dev, char * product, size_t size) {
char buf[1024];
char buf2[1024];
@@ -106,7 +120,7 @@ static void usb_descriptor_info_print(libusb_device_handle * udev, const struct
int i;
memset(buf, 0, sizeof(buf));
libusb_get_string_descriptor_ascii(udev, desc->iProduct, (unsigned char *)buf, sizeof(buf));
usb_get_string_simple(udev, dev->descriptor.iProduct, buf, sizeof(buf));
PRINTF_LINE("USB device product string: %s", buf[0] ? buf : "(not detected)");
PRINTF_END();
@@ -115,12 +129,12 @@ static void usb_descriptor_info_print(libusb_device_handle * udev, const struct
memset(buf, 0, sizeof(buf));
memset(buf2, 0, sizeof(buf2));
ret = libusb_get_string_descriptor_ascii(udev, desc->iSerialNumber, (unsigned char *)buf, sizeof(buf));
ret = usb_get_string_simple(udev, dev->descriptor.iSerialNumber, buf, sizeof(buf));
if ( ! isalnum(buf[0]) )
buf[0] = 0;
for ( i = 0; i < ret; i+=2 ) {
sscanf(buf+i, "%2x", &x);
if ( x > 31 && x < 127 )
if ( x > 32 && x < 128 )
buf2[i/2] = x;
else {
buf2[0] = 0;
@@ -134,51 +148,15 @@ static void usb_descriptor_info_print(libusb_device_handle * udev, const struct
}
static int usb_device_has_interface(libusb_device * dev, int interface, int alternate) {
static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) {
struct libusb_config_descriptor * config;
int ret = 1;
if ( interface == -1 )
return 1;
if ( libusb_get_config_descriptor(dev, 0, &config) < 0 )
return 0;
if ( interface >= config->bNumInterfaces )
ret = 0;
else if ( alternate != -1 && alternate >= config->interface[interface].num_altsetting )
ret = 0;
libusb_free_config_descriptor(config);
return ret;
}
static struct usb_device_info * usb_device_is_valid(libusb_device * dev) {
size_t i;
int err;
int detached = 0;
int i;
char product[1024];
struct libusb_device_descriptor desc;
struct usb_device_info * ret = NULL;
if ( libusb_get_device_descriptor(dev, &desc) < 0 )
return NULL;
for ( i = 0; usb_devices[i].vendor; ++i ) {
for ( i = 0; i < sizeof(usb_devices)/sizeof(usb_devices[0]); ++i ) {
if ( desc.idVendor == usb_devices[i].vendor && desc.idProduct == usb_devices[i].product ) {
if ( usb_devices[i].protocol == FLASH_UNKN )
continue;
if ( desc.bNumConfigurations < 1 )
continue;
if ( ! usb_device_has_interface(dev, usb_devices[i].interface, usb_devices[i].alternate) )
continue;
if ( dev->descriptor.idVendor == usb_devices[i].vendor && dev->descriptor.idProduct == usb_devices[i].product ) {
printf("\b\b ");
PRINTF_END();
@@ -187,37 +165,28 @@ static struct usb_device_info * usb_device_is_valid(libusb_device * dev) {
PRINTF_END();
PRINTF_LINE("Opening USB...");
libusb_device_handle * udev;
err = libusb_open(dev, &udev);
if ( err < 0 ) {
USB_ERROR("libusb_open failed", err);
usb_dev_handle * udev = usb_open(dev);
if ( ! udev ) {
PRINTF_ERROR("usb_open failed");
fprintf(stderr, "\n");
return NULL;
}
memset(product, 0, sizeof(product));
usb_descriptor_info_print(udev, &desc, product, sizeof(product));
usb_descriptor_info_print(udev, dev, product, sizeof(product));
if ( usb_devices[i].interface >= 0 ) {
if ( libusb_kernel_driver_active(udev, usb_devices[i].interface) == 1 ) {
PRINTF_LINE("Detaching kernel from USB interface...");
err = libusb_detach_kernel_driver(udev, usb_devices[i].interface);
if ( err == 0 )
detached = 1;
else {
PRINTF_END();
WARNING("Cannot detach kernel driver: %s", libusb_strerror(err));
}
}
#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
PRINTF_LINE("Detaching kernel from USB interface...");
usb_detach_kernel_driver_np(udev, usb_devices[i].interface);
#endif
PRINTF_LINE("Claiming USB interface...");
err = libusb_claim_interface(udev, usb_devices[i].interface);
if ( err < 0 ) {
USB_ERROR("libusb_claim_interface failed", err);
if ( usb_claim_interface(udev, usb_devices[i].interface) < 0 ) {
PRINTF_ERROR("usb_claim_interface failed");
fprintf(stderr, "\n");
usb_reattach_kernel_driver(udev, usb_devices[i].interface, detached);
libusb_close(udev);
usb_reattach_kernel_driver(udev, usb_devices[i].interface);
usb_close(udev);
return NULL;
}
@@ -225,12 +194,22 @@ static struct usb_device_info * usb_device_is_valid(libusb_device * dev) {
if ( usb_devices[i].alternate >= 0 ) {
PRINTF_LINE("Setting alternate USB interface...");
err = libusb_set_interface_alt_setting(udev, usb_devices[i].interface, usb_devices[i].alternate);
if ( err < 0 ) {
USB_ERROR("libusb_set_interface_alt_setting failed", err);
if ( usb_set_altinterface(udev, usb_devices[i].alternate) < 0 ) {
PRINTF_ERROR("usb_claim_interface failed");
fprintf(stderr, "\n");
usb_reattach_kernel_driver(udev, usb_devices[i].interface, detached);
libusb_close(udev);
usb_reattach_kernel_driver(udev, usb_devices[i].interface);
usb_close(udev);
return NULL;
}
}
if ( usb_devices[i].configuration >= 0 ) {
PRINTF_LINE("Setting USB configuration...");
if ( usb_set_configuration(udev, usb_devices[i].configuration) < 0 ) {
PRINTF_ERROR("usb_set_configuration failed");
fprintf(stderr, "\n");
usb_reattach_kernel_driver(udev, usb_devices[i].interface);
usb_close(udev);
return NULL;
}
}
@@ -238,8 +217,8 @@ static struct usb_device_info * usb_device_is_valid(libusb_device * dev) {
ret = calloc(1, sizeof(struct usb_device_info));
if ( ! ret ) {
ALLOC_ERROR();
usb_reattach_kernel_driver(udev, usb_devices[i].interface, detached);
libusb_close(udev);
usb_reattach_kernel_driver(udev, usb_devices[i].interface);
usb_close(udev);
return NULL;
}
@@ -251,13 +230,13 @@ static struct usb_device_info * usb_device_is_valid(libusb_device * dev) {
ret->device = DEVICE_RX_44;
else if ( strcmp(product, "Nokia N810 Internet Tablet WiMAX Edition") == 0 || strcmp(product, "Nokia-RX48 (Update mode)") == 0 )
ret->device = DEVICE_RX_48;
else if ( strcmp(product, "N900 (Storage Mode)") == 0 || strcmp(product, "Nokia N900 (Update mode)") == 0 || strcmp(product, "N900 (PC-Suite Mode)") == 0 || strcmp(product, "N900 (U-Boot)") == 0 )
else if ( strcmp(product, "N900 (Storage Mode)") == 0 || strcmp(product, "Nokia N900 (Update mode)") == 0 || strcmp(product, "N900 (PC-Suite Mode)") == 0 )
ret->device = DEVICE_RX_51;
else if ( strcmp(product, "Nokia N950") == 0 || strcmp(product, "N950 (Update mode)") == 0 )
else if ( strcmp(product, "Nokia N950") == 0 || strcmp(product, "Sync Mode") == 0 || strcmp(product, "N950 (Update mode)") == 0 )
ret->device = DEVICE_RM_680;
else if ( strcmp(product, "Nokia N9") == 0 || strcmp(product, "N9 (Update mode)") == 0 || strcmp(product, "Nokia N9 RNDIS/Ethernet") == 0 )
else if ( strcmp(product, "N9 (Update mode)") == 0 || strcmp(product, "Nxy (Update mode)") == 0 )
ret->device = DEVICE_RM_696;
else if ( strcmp(product, "Nokia USB ROM") == 0 || strcmp(product, "Sync Mode") == 0 || strcmp(product, "Nxy (Update mode)") == 0 )
else if ( strcmp(product, "Nokia USB ROM") == 0 )
ret->device = DEVICE_ANY;
else
ret->device = DEVICE_UNKNOWN;
@@ -271,8 +250,8 @@ static struct usb_device_info * usb_device_is_valid(libusb_device * dev) {
if ( ! noverify && ret->device == DEVICE_UNKNOWN ) {
ERROR("Device detection failed");
fprintf(stderr, "\n");
usb_reattach_kernel_driver(udev, usb_devices[i].interface, detached);
libusb_close(udev);
usb_reattach_kernel_driver(udev, usb_devices[i].interface);
usb_close(udev);
free(ret);
return NULL;
}
@@ -285,8 +264,8 @@ static struct usb_device_info * usb_device_is_valid(libusb_device * dev) {
if ( ! *device ) {
ERROR("Device mishmash");
fprintf(stderr, "\n");
usb_reattach_kernel_driver(udev, usb_devices[i].interface, detached);
libusb_close(udev);
usb_reattach_kernel_driver(udev, usb_devices[i].interface);
usb_close(udev);
free(ret);
return NULL;
}
@@ -295,7 +274,6 @@ static struct usb_device_info * usb_device_is_valid(libusb_device * dev) {
ret->hwrev = -1;
ret->flash_device = &usb_devices[i];
ret->udev = udev;
ret->detached = detached;
break;
}
}
@@ -304,6 +282,28 @@ static struct usb_device_info * usb_device_is_valid(libusb_device * dev) {
}
static struct usb_device_info * usb_search_device(struct usb_device * dev, int level) {
int i;
struct usb_device_info * ret = NULL;
if ( ! dev )
return NULL;
ret = usb_device_is_valid(dev);
if ( ret )
return ret;
for ( i = 0; i < dev->num_children; i++ ) {
ret = usb_search_device(dev->children[i], level + 1);
if ( ret )
break;
}
return ret;
}
static volatile sig_atomic_t signal_quit;
static void signal_handler(int signum) {
@@ -313,33 +313,19 @@ static void signal_handler(int signum) {
}
static void usb_exit(void) {
libusb_exit(usb_ctx);
usb_ctx = NULL;
}
struct usb_device_info * usb_open_and_wait_for_device(void) {
libusb_device ** devs;
ssize_t count;
ssize_t j;
struct usb_bus * bus;
struct usb_device_info * ret = NULL;
int i = 0;
int err;
void (*prev)(int);
static char progress[] = {'/','-','\\', '|'};
/* Context is kept until exit, so device list stays up to date between waits */
if ( ! usb_ctx ) {
err = libusb_init(&usb_ctx);
if ( err < 0 ) {
USB_ERROR("libusb_init failed", err);
return NULL;
}
atexit(usb_exit);
}
if ( dlsym(RTLD_DEFAULT, "libusb_init") )
ERROR_RETURN("You are trying to use broken libusb-1.0 library (either directly or via wrapper) which has slow listing of usb devices. It cannot be used for flashing or cold-flashing. Please use libusb 0.1.", NULL);
usb_init();
usb_find_busses();
PRINTF_BACK();
printf("\n");
@@ -352,25 +338,30 @@ struct usb_device_info * usb_open_and_wait_for_device(void) {
PRINTF_LINE("Waiting for USB device... %c", progress[++i%sizeof(progress)]);
count = libusb_get_device_list(usb_ctx, &devs);
if ( count < 0 ) {
USB_ERROR("libusb_get_device_list failed", (int)count);
break;
}
usb_find_devices();
for ( bus = usb_get_busses(); bus; bus = bus->next ) {
if ( bus->root_dev )
ret = usb_search_device(bus->root_dev, 0);
else {
struct usb_device *dev;
for ( dev = bus->devices; dev; dev = dev->next ) {
ret = usb_search_device(dev, 0);
if ( ret )
break;
}
}
for ( j = 0; j < count; ++j ) {
ret = usb_device_is_valid(devs[j]);
if ( ret )
break;
}
/* Opened device handle holds its own reference */
libusb_free_device_list(devs, 1);
}
if ( ret )
break;
MSLEEP(50);
SLEEP(0xc350); // 0.5s
}
@@ -390,65 +381,12 @@ struct usb_device_info * usb_open_and_wait_for_device(void) {
void usb_close_device(struct usb_device_info * dev) {
if ( dev->flash_device->protocol != FLASH_COLD )
usb_reattach_kernel_driver(dev->udev, dev->flash_device->interface, dev->detached);
libusb_close(dev->udev);
usb_reattach_kernel_driver(dev->udev, dev->flash_device->interface);
usb_close(dev->udev);
free(dev);
}
/* Translate libusb error, so error messages which print errno stay meaningful */
static int usb_error_to_errno(int err) {
switch ( err ) {
case LIBUSB_ERROR_INVALID_PARAM: return EINVAL;
case LIBUSB_ERROR_ACCESS: return EACCES;
case LIBUSB_ERROR_NO_DEVICE: return ENODEV;
case LIBUSB_ERROR_NOT_FOUND: return ENOENT;
case LIBUSB_ERROR_BUSY: return EBUSY;
case LIBUSB_ERROR_TIMEOUT: return ETIMEDOUT;
case LIBUSB_ERROR_OVERFLOW: return EOVERFLOW;
case LIBUSB_ERROR_PIPE: return EPIPE;
case LIBUSB_ERROR_INTERRUPTED: return EINTR;
case LIBUSB_ERROR_NO_MEM: return ENOMEM;
case LIBUSB_ERROR_NOT_SUPPORTED: return ENOTSUP;
default: return EIO;
}
}
/* Returns number of transferred bytes or negative libusb error code */
static int usb_bulk_transfer(libusb_device_handle * udev, unsigned char endpoint, unsigned char * data, int size, unsigned int timeout) {
int transferred = 0;
int ret;
ret = libusb_bulk_transfer(udev, endpoint, data, size, &transferred, timeout);
if ( ret == 0 )
return transferred;
errno = usb_error_to_errno(ret);
/* Timed out transfer which moved some data is reported as short transfer, callers check its size */
if ( ret == LIBUSB_ERROR_TIMEOUT && transferred > 0 )
return transferred;
return ret;
}
int usb_bulk_send(libusb_device_handle * udev, unsigned char endpoint, const void * data, int size, unsigned int timeout) {
/* libusb does not modify buffer of OUT transfer */
return usb_bulk_transfer(udev, endpoint, (unsigned char *)data, size, timeout);
}
int usb_bulk_recv(libusb_device_handle * udev, unsigned char endpoint, void * data, int size, unsigned int timeout) {
return usb_bulk_transfer(udev, endpoint, data, size, timeout);
}
void usb_switch_to_nolo(struct usb_device_info * dev) {
printf("\nSwitching to NOLO mode...\n");
+11 -9
View File
@@ -22,11 +22,16 @@
#include <stdint.h>
#include <libusb.h>
/* u_int*_t types are not defined without _GNU_SOURCE but usb.h needs them */
#define u_int8_t uint8_t
#define u_int16_t uint16_t
#define u_int32_t uint32_t
#define USB_READ_EP (LIBUSB_ENDPOINT_IN | 0x1)
#define USB_WRITE_EP (LIBUSB_ENDPOINT_OUT | 0x1)
#define USB_WRITE_DATA_EP (LIBUSB_ENDPOINT_OUT | 0x2)
#include <usb.h>
#define USB_READ_EP (USB_ENDPOINT_IN | 0x1)
#define USB_WRITE_EP (USB_ENDPOINT_OUT | 0x1)
#define USB_WRITE_DATA_EP (USB_ENDPOINT_OUT | 0x2)
#include "device.h"
@@ -44,6 +49,7 @@ struct usb_flash_device {
uint16_t product;
int interface;
int alternate;
int configuration;
enum usb_flash_protocol protocol;
enum device devices[DEVICE_COUNT];
};
@@ -52,8 +58,7 @@ struct usb_device_info {
enum device device;
int16_t hwrev;
const struct usb_flash_device * flash_device;
libusb_device_handle * udev;
int detached;
usb_dev_handle * udev;
int data;
};
@@ -61,9 +66,6 @@ const char * usb_flash_protocol_to_string(enum usb_flash_protocol protocol);
struct usb_device_info * usb_open_and_wait_for_device(void);
void usb_close_device(struct usb_device_info * dev);
int usb_bulk_send(libusb_device_handle * udev, unsigned char endpoint, const void * data, int size, unsigned int timeout);
int usb_bulk_recv(libusb_device_handle * udev, unsigned char endpoint, void * data, int size, unsigned int timeout);
void usb_switch_to_nolo(struct usb_device_info * dev);
void usb_switch_to_cold(struct usb_device_info * dev);
void usb_switch_to_update(struct usb_device_info * dev);