1 Commits
Author SHA1 Message Date
pancake a215967e38 Import version 0.3 from tarball 0xFFFF-0.3.tar.gz 2007-10-20 02:32:24 +02:00
46 changed files with 856 additions and 3947 deletions

No files matched your search

-9
View File
@@ -1,9 +0,0 @@
[Desktop Entry]
Encoding=UTF-8
Name=0xFFFF
Comment=Free flasher for the Nokia internet tablets
Exec=gnome-terminal -e goxf
Icon=gnome-terminal.png
Terminal=false
Type=Application
Categories=GTK;Application;Utility;
+5 -20
View File
@@ -1,17 +1,11 @@
include config.mk
PREFIX?=/usr/local PREFIX?=/usr/local
DESTDIR?=
all: logot frontend all: logot
cd src && ${MAKE} all cd src && ${MAKE} all
frontend:
-cd src/gui && ${MAKE} all
static: logot static: logot
cd libusb && ${MAKE} all cd libusb && ${MAKE} all
cd src && ${MAKE} static cd src && ${MAKE} static
cd logotool && ${MAKE} static
allusb: logot allusb: logot
cd libusb && ${MAKE} all cd libusb && ${MAKE} all
@@ -22,21 +16,12 @@ logot:
clean: clean:
cd src && ${MAKE} clean cd src && ${MAKE} clean
cd libusb && ${MAKE} clean
cd logotool && ${MAKE} clean cd logotool && ${MAKE} clean
install: install:
mkdir -p ${DESTDIR}${PREFIX}/bin cp src/0xFFFF ${PREFIX}/bin
mkdir -p ${DESTDIR}${PREFIX}/share/applications/ cp logotool/logotool ${PREFIX}/bin
cp src/0xFFFF ${DESTDIR}${PREFIX}/bin
-cp src/gui/goxf ${DESTDIR}${PREFIX}/bin
cp logotool/logotool ${DESTDIR}${PREFIX}/bin
cp 0xFFFF.desktop ${DESTDIR}${PREFIX}/share/applications/
mkdir -p ${DESTDIR}${PREFIX}/share/man/man1
cp man/*.1 ${DESTDIR}${PREFIX}/share/man/man1
deinstall: deinstall:
rm -f ${DESTDIR}${PREFIX}/bin/0xFFFF rm -f ${PREFIX}/bin/0xFFFF
rm -f ${DESTDIR}${PREFIX}/bin/logotool rm -f ${PREFIX}/bin/logotool
rm -f ${DESTDIR}${PREFIX}/bin/goxf
rm ${DESTDIR}${PREFIX}/share/applications/0xFFFF.desktop
+2 -9
View File
@@ -27,15 +27,8 @@ Feel free to join to the mailing list and visit the homepage for more info:
0xffff@lists.nopcode.org 0xffff@lists.nopcode.org
http://www.nopcode.org/0xFFFF http://www.nopcode.org/0xFFFF
-----------8<---------------------------------------------------------------
Build:
$ make
To install: (by default is /usr/local)
$ make install PREFIX=/usr DESTDIR=/
Have phun! Have phun!
--pancake --pancake
-9
View File
@@ -1,9 +0,0 @@
VERSION=0.5
PREFIX=/usr/local
# NetBSD stuff
CFLAGS+=-I/usr/pkg/include -g -O2
LDFLAGS+=-L/usr/pkg/lib -Wl,-R/usr/pkg/lib
HAVE_USB=1
HAVE_GUI=1
+2 -2
View File
@@ -40,14 +40,14 @@ and sometimes (in the early days often) replacing proprietary software.
The non-free bits in the core infrastructure of the IT OS 2007 are a road block The non-free bits in the core infrastructure of the IT OS 2007 are a road block
for efforts to create free operating systems/distributions besides IT OS on the for efforts to create free operating systems/distributions besides IT OS on the
770/N800. N770/N800.
The reason for why it is helpful to have other operating system/distribution on The reason for why it is helpful to have other operating system/distribution on
the N800 is simple: There are hundreds of GNU/Linux distributions out there. the N800 is simple: There are hundreds of GNU/Linux distributions out there.
Each one exists because there is a userbase that exactly likes their flavor of Each one exists because there is a userbase that exactly likes their flavor of
GNU/Linux. GNU/Linux.
For the 770/N800 Internet Tablets there exists only one such distribution: The For the N770/N800 Internet Tablets there exists only one such distribution: The
Internet Tablet OS. With the sheer amount of GNU/Linux distributions for Internet Tablet OS. With the sheer amount of GNU/Linux distributions for
desktops/workstations/servers/routers/PDAs on the one hand and the single OS desktops/workstations/servers/routers/PDAs on the one hand and the single OS
solution for the Internet Tablets on the other I doubt that it can handle all solution for the Internet Tablets on the other I doubt that it can handle all
+59 -29
View File
@@ -1,49 +1,79 @@
<h2>FAQ</h2> <b>FAQ</b>
<b>*) How can I set my Internet Tablet into RD mode with 0xFFFF?</b> This file tries to collect a bunch of common questions/answers about flashing
Just type '0xFFFF -r 1' as root <b>*) Why implement a free software flasher?</b>
The Nokia Internet Tablets are based on Free Software (software libre), but
not everything included *is* free software, for instance, the firmware flasher
tool.
The 0xFFFF project aims to feed the minds of those who really want to
understand how these gadgets work internally, free the knowledge to
avoid the restrictions and fill the lack of information on the most
important part of the system.
That's it, now you can build and run this flasher on *BSD, w32, MacOSX on ARM,
powerpc, x86, mips, etc...
<b>*) How can I unpack a FIASCO firmware? <b>*) Can I brick my device?</b>
Just type '0xFFFF -r 1' as root Of course! You're free to do what you want with your device :)
Seriously. Flashing a device is not a safe thing, so I give no warranty
of what will happen to your device when using this tool.
BTW, after a huge number of tests I can say that these devices are hard
to brick, but if you are scared about bricking your device you should
use the flasher provided by Nokia, it's better for your heart's health.
<b>*) How can I unpack a FIASCO firmware?</b> <b>*) What can I do with 0xFFFF?</b>
Just type '0xFFFF -u FiascoFirmware.bin -e /tmp' as root Actually 0xFFFF allows you to:
- flash separated pieces of the firmware.
- retrieve information about the device
- reboot de mother board
- extract the current firmware pieces from the device (reverse flash)
- set the USB host/slave mode
- set the R&R mode
- identify firmware pieces
<b>*) How can I flash a new rootfs? <b>*) What is NOLO?</b>
Unpack the pieces from the fiasco firmware (the one distributed by Nokia for example) and then type: NOLO is the 'server-side' part of the flasher from Nokia. NOLO means
NOkia LOader and it's composed by two pieces of the firmware that are
flashed together.
# 0xFFFF -R -p rootfs.jffs On the n800 firmwares, these two pieces are distributed in a single
file, but when flashing a n770, NOLO requires to provide the xloader
(without commiting) and then the secondary piece.
This piece of software is closed source and is the responsable of
handling the requests from the client-side flasher. It provides a
query-like interface via usb control messages for doing different
actions on the device.
<b>*) How can I flash a full FIASCO image?</b> <b>*) How can I identify my device?</b>
It is not recommended to use, it needs more testing, and is more secure to unpack them first manually Theorically n770 and n800 have different USB device ID, but this is not
and flash the pieces manually with multiple '-p' flags. If you are brave try: true at all. The first series of the n800 comes with the same usb-id
than n770. That's weird!
# 0xFFFF -F FiascoFirmware.fiasco So, the only way to identify the device is by asking nolo for the version
information of different pieces of the firmware. This can be faked, because
you can flash n770 stuff on n800 and viceversa, but it's not recommended
because it wouldn't work :)
<h2>Advanced commands</h2> <b>*) Can I unpack fiasco blobs?</b>
<b>*) How to extract the firmware pieces from a running device?</b> Actually the fiasco format is not yet supported and not planned in
short term. There is no real need for supporting a proprietary
format image containing a proprietary system.
It is possible to dump the firmware pieces from the internal MTD to reconstruct a FIASCO image. We can just use tarballs containing the desired pieces.
To do this recompile the flasher for ARM and run this command in the device:
# mkdir /media/mmc1/backup
# 0xFFFF -e /media/mmc1/backup
<b>*) Dumping configuration region</b>
There's a hidden mtd partition containing undocumented configuration information. This one can be
dumped from the device using the following command:
# 0xFFFF -x
-80
View File
@@ -1,80 +0,0 @@
<b>FAQ</b>
This file tries to collect a bunch of common questions/answers about flashing
<b>*) Why implement a free software flasher?</b>
The Nokia Internet Tablets are based on Free Software (software libre), but
not everything included *is* free software, for instance, the firmware flasher
tool.
The 0xFFFF project aims to feed the minds of those who really want to
understand how these gadgets work internally, free the knowledge to
avoid the restrictions and fill the lack of information on the most
important part of the system.
That's it, now you can build and run this flasher on *BSD, w32, MacOSX on ARM,
powerpc, x86, mips, etc...
<b>*) Can I brick my device?</b>
Of course! You're free to do what you want with your device :)
Seriously. Flashing a device is not a safe thing, so I give no warranty
of what will happen to your device when using this tool.
BTW, after a huge number of tests I can say that these devices are hard
to brick, but if you are scared about bricking your device you should
use the flasher provided by Nokia, it's better for your heart's health.
<b>*) What can I do with 0xFFFF?</b>
Actually 0xFFFF allows you to:
- flash separated pieces of the firmware.
- retrieve information about the device
- reboot de mother board
- extract the current firmware pieces from the device (reverse flash)
- set the USB host/slave mode
- set the R&R mode
- identify firmware pieces
<b>*) What is NOLO?</b>
NOLO is the 'server-side' part of the flasher from Nokia. NOLO means
NOkia LOader and it's composed by two pieces of the firmware that are
flashed together.
On the n800 firmwares, these two pieces are distributed in a single
file, but when flashing a 770, NOLO requires to provide the xloader
(without commiting) and then the secondary piece.
This piece of software is closed source and is the responsable of
handling the requests from the client-side flasher. It provides a
query-like interface via usb control messages for doing different
actions on the device.
<b>*) How can I identify my device?</b>
Theorically 770 and n800 have different USB device ID, but this is not
true at all. The first series of the n800 comes with the same usb-id
than 770. That's weird!
So, the only way to identify the device is by asking nolo for the version
information of different pieces of the firmware. This can be faked, because
you can flash 770 stuff on n800 and viceversa, but it's not recommended
because it wouldn't work :)
<b>*) Can I unpack fiasco blobs?</b>
Actually the fiasco format is not yet supported and not planned in
short term. There is no real need for supporting a proprietary
format image containing a proprietary system.
We can just use tarballs containing the desired pieces.
+14 -33
View File
@@ -1,6 +1,3 @@
Copyright (C) 2007-2011 pancake <pancake@youterm.com>
Copyright (C) 2011-2012 Pali Rohár <pali.rohar@gmail.com>
SPECS FOR TEH FIASCO FIRMWARE FILE FORMAT ffff! SPECS FOR TEH FIASCO FIRMWARE FILE FORMAT ffff!
----------------------------------------------- -----------------------------------------------
@@ -11,39 +8,23 @@ SPECS FOR TEH FIASCO FIRMWARE FILE FORMAT ffff!
FILE HEADER FILE HEADER
1 byte = 0xb4 -- signature 1 byte = 0xb4 -- signature
4 bytes -- FW header length (big endian) 4 bytes -- firmware name length (big endian)
6 bytes -- versioning info ( byte 4 is format version )
N-6 bytes -- firmware name (zero fill)
FW HEADER PIECE HEADER
4 bytes -- number of FW header blocks (big endian) 1 byte = 0x54 -- piece signature
6 bytes -- unknown
2 bytes -- checksum for the piece contents (xorpair)
12 bytes -- piece name (first byte is FF if is the last)
4 bytes -- piece size (big endian)
4 bytes -- unknown
block { block {
1 byte -- type of block 1 byte -- if (value '1'-'9') { ..there's a comment.. }
0xE8 - Fiasco name 1 byte -- length of comment
0x31 - FW name N bytes -- comment
1 byte -- length of block data
N bytes -- block data
} }
N bytes -- piece data
IMAGE
1 byte = 0x54 -- signature
1 byte -- number of subsection blocks + 1
5 bytes -- unknown (always 0x2e 0x19 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 -- unknown (always 0x00 0x00 0x00 0x00)
block {
1 byte -- type of subsection block
'1' - version
'2' - device & hw revisions (separated by char 0x00, max size of device is 16, hw revision 8)
'3' - layout
'4' - unknown
'/' - unknown
1 byte -- length of subsection block
N bytes -- subsection block data
}
1 byte -- unknown (maybe end of subsections?)
N bytes -- image data
+1 -1
View File
@@ -21,4 +21,4 @@ have flashed properly every piece inside the device, but keep in mind
that it is dangerous and you can brick your device. that it is dangerous and you can brick your device.
But feel free to send feedback to provide a full support for local But feel free to send feedback to provide a full support for local
flashing on 770 and n800. flashing on n770 and n800.
+1 -1
View File
@@ -37,7 +37,7 @@ Pieces can be automatically identified by using the '-I' flag:
You can dump these pieces from the internal memory of the internet You can dump these pieces from the internal memory of the internet
tablet by using the mtd-utils over /dev/mtd* or just running: tablet by using the mtd-utils over /dev/mtd* or just running:
770$ 0xFFFF -e /media/mmc1 n770$ 0xFFFF -e /media/mmc1
There is another way for dumping pieces with extra parameters and options, There is another way for dumping pieces with extra parameters and options,
read doc/dumping for more information. read doc/dumping for more information.
+1 -1
View File
@@ -1,7 +1,7 @@
<b>Usage guide</b> <b>Usage guide</b>
0xFFFF is a free software implementation of the flasher for the Nokia Internet 0xFFFF is a free software implementation of the flasher for the Nokia Internet
Tablets (770 and n800). Tablets (n770 and n800).
<pre> <pre>
- flash separated pieces of the firmware. - flash separated pieces of the firmware.
- retrieve information about the device - retrieve information about the device
+53
View File
@@ -0,0 +1,53 @@
- preferences
* choose flasher type.
by default 0xFFFF is used
*
piece [file]
|
+-- radio
|
+-- nbh
info
|
+-- -i
reboot
|
+-- ???
----------
piece [file]
|
+-- xloader
|
+-- secondary
|
+-- kernel
|
+-- initfs
|
+-- rootfs
|
+-- autodetected
info
|
+-- -i
usb-host-mode
|
+-- -U [0|1]
rd-mode
|
+-- -r 0|1
reboot
|
+-- -R
+8
View File
@@ -0,0 +1,8 @@
OBJ=main.o
BIN=goxf
CFLAGS=`pkg-config libgladeui-1.0 libglade-2.0 --cflags`
LDFLAGS=`pkg-config libgladeui-1.0 libglade-2.0 --libs`
all: ${OBJ}
${CC} ${LDFLAGS} ${OBJ} -o ${BIN}
+223
View File
@@ -0,0 +1,223 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--*- mode: xml -*-->
<glade-interface>
<widget class="GtkWindow" id="main_window">
<property name="border_width">5</property>
<property name="title" translatable="yes" context="yes">g0xFFFF</property>
<property name="default_width">501</property>
<property name="default_height">329</property>
<property name="icon_name">gtk-connect</property>
<signal name="destroy_event" handler="gtk_main_quit" object="0"/>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="spacing">3</property>
<child>
<widget class="GtkHButtonBox" id="hbuttonbox2">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_START</property>
<child>
<widget class="GtkComboBox" id="combobox2">
<property name="visible">True</property>
<property name="active">0</property>
<property name="items" translatable="yes" context="yes">n770/n800
HERMflasher</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="gochange">
<property name="width_request">32</property>
<property name="visible">True</property>
<property name="has_default">True</property>
<property name="label" translatable="yes" context="yes">&gt;</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<child>
<widget class="GtkTreeView" id="treeview1">
<property name="visible">True</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkVBox" id="vbox2">
<property name="visible">True</property>
<property name="border_width">3</property>
<property name="spacing">2</property>
<child>
<widget class="GtkFileChooserButton" id="filechooserbutton2">
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkComboBox" id="combo1">
<property name="row_span_column">0</property>
<property name="column_span_column">0</property>
<property name="active">0</property>
<property name="tearoff_title">patata</property>
<property name="items" translatable="yes" context="yes">rootfs
initfs
kernel
secondary
xloader</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox4">
<property name="visible">True</property>
<child>
<widget class="GtkButton" id="button2">
<property name="visible">True</property>
<property name="label" context="yes">Remove</property>
</widget>
</child>
<child>
<widget class="GtkButton" id="add">
<property name="visible">True</property>
<property name="label" context="yes">Add</property>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="checkbutton2">
<property name="visible">True</property>
<property name="label" translatable="yes" context="yes">USB host mode</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">3</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="checkbutton3">
<property name="visible">True</property>
<property name="label" translatable="yes" context="yes">R&amp;D mode</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">4</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="reboot">
<property name="visible">True</property>
<property name="label" translatable="yes" context="yes">Reboot</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">5</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">3</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox3">
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
<widget class="GtkProgressBar" id="progressbar1">
<property name="visible">True</property>
<property name="show_text">True</property>
</widget>
</child>
<child>
<widget class="GtkHBox" id="hbox5">
<property name="visible">True</property>
<child>
<widget class="GtkButton" id="info">
<property name="visible">True</property>
<property name="label" translatable="yes" context="yes">gtk-dialog-info</property>
<property name="use_stock">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="but_commit">
<property name="visible">True</property>
<property name="label" translatable="yes" context="yes">gtk-execute</property>
<property name="use_stock">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">GTK_PACK_END</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>
+49
View File
@@ -0,0 +1,49 @@
/*
* 0xFFFF - Open Free Fiasco Firmware Flasher
* Copyright (C) 2007 pancake <pancake@youterm.com>
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <glade/glade.h>
#include <gtk/gtk.h>
#define U(x) printf("%d\n",x); fflush(stdout);
int main(int argc, char **argv)
{
GtkWidget *w;
GladeXML *xml;
gtk_init(&argc, &argv);
xml = glade_xml_new("g0xFFFF.glade", "main_window", "");
//xml = glade_xml_new("test.glade", "window1", NULL);
if(!xml) {
g_warning("We could not load the interface!");
return 1;
}
glade_xml_signal_autoconnect(xml);
w = glade_xml_get_widget(xml, "main_window");
gtk_signal_connect(GTK_OBJECT(w), "destroy",
GTK_SIGNAL_FUNC(gtk_main_quit),NULL);
gtk_widget_show_all(w);
gtk_object_unref(GTK_OBJECT(xml));
gtk_main();
return 0;
}
+2 -8
View File
@@ -1,14 +1,8 @@
OBJ=logotool.o compress.o uncompress.o rgb2yuv.o OBJ=logotool.o compress.o uncompress.o rgb2yuv.o
#CFLAGS=-Wall -g CFLAGS=-Wall -g
BIN=logotool
all: ${BIN} all: ${OBJ}
${BIN}: ${OBJ}
${CC} ${OBJ} -o logotool ${CC} ${OBJ} -o logotool
static: ${BIN}
${CC} -static ${OBJ} -o logotool
clean: clean:
rm -f ${OBJ} logotool rm -f ${OBJ} logotool
+2 -2
View File
@@ -71,7 +71,7 @@ int uncompress_image(char *srcf, char *dstf)
src = malloc ( fsize ); src = malloc ( fsize );
dst = malloc ( width*height*2 ); dst = malloc ( width*height*2 );
deof = dst+width*height*2; deof = dst+width*height*2;
if (src == (void *)-1 || dst == (void *)-1 ) { if ((int)src == -1 || (int)dst == -1 ) {
printf("Cannot malloc\n"); printf("Cannot malloc\n");
return 1; return 1;
} }
@@ -105,7 +105,7 @@ int uncompress_image(char *srcf, char *dstf)
} }
} }
} }
fprintf(stderr, "Output Size: %lld\n",(long long int)(dst2-dst)); fprintf(stderr, "Output Size: %d\n",dst2-dst);
if ((dst2-dst)!=(width*height*2)) if ((dst2-dst)!=(width*height*2))
fprintf(stderr, "failed?\n"); fprintf(stderr, "failed?\n");
-99
View File
@@ -1,99 +0,0 @@
.TH 0xFFFF 1 "November 18, 2010"
.\" Please adjust this date whenever revising the manpage.
.SH NAME
0xFFFF \- Open Free Fiasco Firmware Flasher
.SH SYNOPSIS
.B 0xFFFF
.RB [OPTION]...
.SH DESCRIPTION
The 'Open Free Fiasco Firmware Flasher' aka 0xFFFF utility implements
a free (GPL3) userspace handler for the NOLO bootloader and related
utilities for the Nokia Internet Tablets like flashing, setting device
options, packing/unpacking FIASCO firmware format and more.
.SH OPTIONS
.TP
.BI -b [args]
boots the kernel with arguments
.TP
.BI -c
console prompt mode
.TP
.BI -d [vid:pid]
injects a usb device into the supported list
.TP
.BI -D [0|1|2]
sets the root device to flash (0), mmc (1) or usb (2)
.TP
.BI -f <flags>
set the given RD flags (see '-f help')
.TP
.BI -i
show device information (let standby mode)
.TP
.BI -l
list supported usb device ids
.TP
.BI -p [[p%]file]
piece-of-firmware % file-where-this-piece-is
.TP
.BI -r [0|1]
disable/enable R&D mode
.TP
.BI -R
reboot the omap board
.TP
.BI -U [0|1]
disable/enable the usb host mode
.TP
.BI -Q
enter shared queues server mode (for gui or remote)
.TP
.BI -s [serial]
serial port console (minicom like terminal)
.TP
.BI -h
show help message
.TP
.BI -S [subversion]
unpacks/flash pieces matching this sub-version information
.TP
.BI -n
do not flash or write to disk (simulation)
.TP
.BI -C [/dev/mtd]
check bad blocks on mtd
.TP
.BI -e [path]
dump/extract pieces to path
.TP
.BI -F [fiasco]
flash a fiasco firmware image
.TP
.BI -H [file]
calculate hash for file
.TP
.BI -I [piece]
identify a firmware piece
.TP
.BI -P [new-fiasco]
creates a new fiasco package, pieces as arguments
.TP
.BI -u [fiasco]
unpack target fiasco image
.TP
.BI -v
be verbose and noisy
.TP
.BI -V
show version information and exit.
.TP
.BI -x
extract configuration entries from /dev/mtd1
.SH AUTHOR
0xFFFF was written by pancake.
.PP
This manual page was written by Sebastian Reichel <elektranox@gmail.com>,
for the Debian project (but may be used by others).
-20
View File
@@ -1,20 +0,0 @@
.TH GOXF 1 "November 18, 2010"
.\" Please adjust this date whenever revising the manpage.
.SH NAME
goxf \- 0xFFFF GUI
.SH SYNOPSIS
.B goxf
.RB [FILE]
.SH DESCRIPTION
This utility is a graphical interface to 0xFFFF. It is used to
communicate with the NOLO bootloader of Nokia's internet tablets
(770, N800, N810, N900).
.SH OPTIONS
goxf takes no options.
.SH SEE ALSO
.B 0xFFFF(1)
.SH AUTHOR
goxf was written by pancake.
.PP
This manual page was written by Sebastian Reichel <elektranox@gmail.com>,
for the Debian project (but may be used by others).
-41
View File
@@ -1,41 +0,0 @@
.TH LOGOTOOL 1 "November 18, 2010"
.\" Please adjust this date whenever revising the manpage.
.SH NAME
logotool \- FIASCO logo file tool
.SH SYNOPSIS
.B logotool
.RB [OPTION]...
.SH DESCRIPTION
Tool to compress, uncompress or watch FIASCO logo files.
.SH OPTIONS
.TP
.BI -u img
uncompress image to img.rgb
.TP
.BI -c img
compres a 24 bit rgb raw image to a 16(565) one
.TP
.BI -m img
show image using mplayer (dumps to <img>.yuv)
.TP
.BI -v img
view uncompressed image using the 'display' command from ImageMagick (in monochrome)
.TP
.BI -w
specify width (required for -v and -c)
.TP
.BI -a
force RGBA instead of RGB when compressing (use with -c)
.TP
.BI -h
specify height (required for -v and -c)
.TP
.BI -V
show version information and exit.
.SH SEE ALSO
.B 0xFFFF(1)
.SH AUTHOR
logotool was written by pancake and esteve.
.PP
This manual page was written by Sebastian Reichel <elektranox@gmail.com>,
for the Debian project (but may be used by others).
+5 -14
View File
@@ -1,22 +1,13 @@
include ../config.mk VERSION=0.3
OBJ=main.o fiasco.o hexdump.o dump.o flash.o serial.o qmode.o OBJ=main.o fiasco.o hexdump.o dump.o flash.o serial.o
OBJ+=hash.o fpid.o query.o pieces.o utils.o devices.o console.o OBJ+=hash.o fpid.o query.o pieces.o utils.o devices.o console.o
OBJ+=squeue/squeue.o
BIN=0xFFFF BIN=0xFFFF
#LIBS=`${HAVE_USB} && echo -- '-lusb'` CFLAGS+=-DVERSION=\"${VERSION}\" -Wall -g -I .
LIBS=`if [ "${HAVE_USB}" = 1 ]; then echo '-lusb'; fi`
CFLAGS+=-DVERSION=\"${VERSION}\" -Wall -I .
CFLAGS+=-pedantic -std=c99 -DHAVE_USB=${HAVE_USB} -Wno-unused-result
USBOBJ=../libusb/error.o ../libusb/usb.o ../libusb/descriptors.o USBOBJ=../libusb/error.o ../libusb/usb.o ../libusb/descriptors.o
USBOBJ+=../libusb/linux.o ## XXX not portable USBOBJ+=../libusb/linux.o ## XXX not portable
CFLAGS+=-I../libusb all: ${OBJ}
LDFLAGS+=-L../libusb ${CC} ${LDFLAGS} -o ${BIN} ${OBJ} -lusb
all: ${BIN}
${BIN}: ${OBJ}
${CC} ${LDFLAGS} -o ${BIN} ${OBJ} ${LIBS}
allusb: ${OBJ} allusb: ${OBJ}
${CC} ${LDFLAGS} -o ${BIN} ${OBJ} ${USBOBJ} ${CC} ${LDFLAGS} -o ${BIN} ${OBJ} ${USBOBJ}
+8 -19
View File
@@ -1,6 +1,6 @@
/* /*
* 0xFFFF - Open Free Fiasco Firmware Flasher * 0xFFFF - Open Free Fiasco Firmware Flasher
* Copyright (C) 2007, 2008 pancake <pancake@youterm.com> * Copyright (C) 2007 pancake <pancake@youterm.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -16,7 +16,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#if HAVE_USB
#include "main.h" #include "main.h"
#include "query.h" #include "query.h"
#include <stdio.h> #include <stdio.h>
@@ -46,13 +45,7 @@ void cmd_help(char *line)
void cmd_info(char *line) void cmd_info(char *line)
{ {
char *p, str[128]; get_hw_revision(); // get hardware revision:
get_sw_version();
get_hw_revision(str, 128); // get hardware revision:
p = strstr(str, "hw_rev:");
if (p) // TODO: delimit string by comma
printf("SubVersionString autodetected: '%s'\n", p+7);
else printf("SubVersionString autodetected: (error)\n");
get_root_device(); // only for flashing get_root_device(); // only for flashing
get_usb_mode(); get_usb_mode();
get_rd_mode(); get_rd_mode();
@@ -67,17 +60,14 @@ void cmd_nanddump(char *line)
char out[128]; char out[128];
int ignbb; int ignbb;
int ignoob = -1; int ignoob = -1;
sscanf(line, "%127s 0x%x 0x%x %127s %d %d", &dev, &from, &length, &out, &ignbb, &ignoob);
sscanf(line, "%127s 0x%x 0x%x %127s %d %d",
(char *)&dev, (unsigned int*)&from, (unsigned int *)&length,
(char *)&out, (int*)&ignbb, (int *)&ignoob);
if (ignoob == -1) { if (ignoob == -1) {
eprintf("Invalid arguments.\n"); printf("Invalid arguments.\n");
eprintf("nanddump [dev] [start] [len] [out] [ignore-badblocks] [ignore-oob]\n"); printf("nanddump [dev] [start] [len] [out] [ignore-badblocks] [ignore-oob]\n");
eprintf(" f.ex: nanddump /dev/mtd0 0x0 0x4000 xloader.bin 1 1\n"); printf(" f.ex: nanddump /dev/mtd0 0x0 0x4000 xloader.bin 1 1\n");
} else } else {
nanddump(dev, from, length, out, ignbb, ignoob); nanddump(dev, from, length, out, ignbb, ignoob);
}
} }
void cmd_dump(char *line) void cmd_dump(char *line)
@@ -171,4 +161,3 @@ int console_prompt()
return 0; return 0;
} }
#endif
+35 -43
View File
@@ -1,7 +1,6 @@
/* /*
* 0xFFFF - Open Free Fiasco Firmware Flasher * 0xFFFF - Open Free Fiasco Firmware Flasher
* Copyright (C) 2007-2009 pancake <pancake@nopcode.org> * Copyright (C) 2007 pancake <pancake@youterm.com>
* Copyright (C) 2012 Pali Rohár <pali.rohar@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -17,7 +16,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#if HAVE_USB
#include "main.h" #include "main.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -30,31 +28,18 @@
* *
* The following table shows this info: * The following table shows this info:
* *
* omap-rom nolo flash-mode mass-stor pc-suite * boot os
* 770 0421:0105 0421:0431 * n770 0421:0105 0421:0431
* n800 0421:04c3 0421:0431 * n800 0421:0431
* n810 0421:0105
* n900 0421:0106 0421:0105 0421:01c8 0421:01c7 0421:01c8
*
* mode images protocol
* omap-rom 2nd, secondary OMAP messages + Nokia X-Loader protocol
* nolo all except mmc NOLO
* flash-mode mmc MK II
* mass-storage sd, first emmc Standard USB Mass Storage
* pc-suite mmc MK II
* *
*/ */
struct devices supported_devices[SUPPORTED_DEVICES] = { struct devices supported_devices[SUPPORTED_DEVICES] = {
{ "FFFF", 0x0000, 0x0000, FLASH_NORMAL }, // dummy { "FFFF", 0x000, 0x0000, 0x0000 }, // dummy
{ "unkn", 0x0421, 0x3f00, FLASH_NORMAL }, // probably a development board { "unkn", 0x421, 0x3f00, 0x0000 }, // probably a development board
{ "n800", 0x0421, 0x04c3, FLASH_NORMAL }, // n800 { "n770", 0x421, 0x0105, 0x0001 }, // my n770
{ "770/n810/n900", 0x0421, 0x0105, FLASH_NORMAL }, // 770, n810, n900 { "n800", 0x421, 0x04c3, 0x0001 }, // a n800
{ "n900", 0x0421, 0x0106, FLASH_COLD }, // n900 cold flashing { 0 },
{ "n900", 0x0421, 0x01c8, FLASH_MKII }, // n900 mmc flashing { 0 }
{ "770/n800", 0x0421, 0x0431, FLASH_DISK }, // 770, n800 usb mass storage
{ "n900", 0x0421, 0x01c7, FLASH_DISK }, // n900 usb mass storage
{ NULL },
{ NULL }
}; };
/** Returns 0 when no device was found and a positive /** Returns 0 when no device was found and a positive
@@ -71,7 +56,7 @@ int is_valid_device(struct usb_device_descriptor *udd)
for(i=1 ; ptr.vendor_id; ptr = supported_devices[++i]) for(i=1 ; ptr.vendor_id; ptr = supported_devices[++i])
if ((udd->idVendor == ptr.vendor_id) if ((udd->idVendor == ptr.vendor_id)
&& (udd->idProduct == ptr.product_id)) { && (udd->idProduct == ptr.product_id)) {
D printf("found %s\n", supported_devices[i].name); D printf("found %s\n", supported_devices[i]);
return i; return i;
} }
@@ -87,7 +72,7 @@ void list_valid_devices()
int i; int i;
struct devices ptr = supported_devices[1]; struct devices ptr = supported_devices[1];
for(i=1; ptr.name; ptr = supported_devices[++i]) for(i=1; ptr.vendor_id; ptr = supported_devices[++i])
printf("%04x:%04x %s\n", ptr.vendor_id, ptr.product_id, ptr.name); printf("%04x:%04x %s\n", ptr.vendor_id, ptr.product_id, ptr.name);
} }
@@ -96,31 +81,38 @@ void list_valid_devices()
* structures for the specified device. * structures for the specified device.
* Otherwise returns false (0) * Otherwise returns false (0)
*/ */
int usb_device_found(struct usb_device_descriptor *udd, struct devices *it_device) int usb_device_found(struct usb_device_descriptor *udd, struct devices *it_device)
{ {
int dev_index = 0;
struct usb_bus *bus; struct usb_bus *bus;
if ((usb_find_busses()<0) || (usb_find_devices()==-1)) { int dev_index = 0;
fprintf(stderr, "\nerror: no usb bus or device found.\n");
if (usb_find_busses() < 0) {
fprintf(stderr, "\nerror: no usb busses found.\n");
exit(1); exit(1);
} else { } else {
for (bus = usb_busses; bus; bus = bus->next) { switch(usb_find_devices()) {
struct usb_device *dev = bus->devices; case -1:
D printf("bus: \n"); fprintf(stderr, "\nerror: no devices found.\n");
for (; dev; dev = dev->next) { exit(1);
*udd = dev->descriptor; default:
D printf(" dev (%s) - ", dev->filename); for (bus = usb_busses; bus; bus = bus->next) {
D printf("vendor: %04x product: %04x\n", udd->idVendor, udd->idProduct); struct usb_device *dev = bus->devices;
D printf("bus: \n");
for (; dev; dev = dev->next) {
*udd = dev->descriptor;
D printf(" dev (%s) - ", dev->filename);
D printf("vendor: %04x product: %04x\n", udd->idVendor, udd->idProduct);
if ((dev_index = is_valid_device(udd))) { if ((dev_index = is_valid_device(udd))) {
device = dev; device = dev;
printf("%s found!\n", dev->filename); *it_device = supported_devices[dev_index];
*it_device = supported_devices[dev_index]; return 1;
return 1; }
} }
} }
} }
} }
return 0; return 0;
} }
#endif
+21 -81
View File
@@ -1,6 +1,6 @@
/* /*
* 0xFFFF - Open Free Fiasco Firmware Flasher * 0xFFFF - Open Free Fiasco Firmware Flasher
* Copyright (C) 2007-2009 pancake <pancake@nopcode.org> * Copyright (C) 2007 pancake <pancake@youterm.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -18,6 +18,7 @@
#include "main.h" #include "main.h"
#include "hexdump.h" #include "hexdump.h"
#include <usb.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -37,7 +38,7 @@ int rf_extract(char *dev, off_t from, off_t to, char *file)
FILE *fd = fopen(file, "wb+"); FILE *fd = fopen(file, "wb+");
if (from>to) { if (from>to) {
printf("Bad range %lld - %lld for %s\n", (long long int)from, (long long int)to, file); printf("Bad range %lld - %lld for %s\n", from, to, file);
goto __rf_extract_exit; goto __rf_extract_exit;
} }
if (fs == NULL) { perror(dev); goto __rf_extract_exit; } if (fs == NULL) { perror(dev); goto __rf_extract_exit; }
@@ -56,7 +57,7 @@ int rf_extract(char *dev, off_t from, off_t to, char *file)
} }
printf("\r%s: %lld bytes dumped from %s\n", printf("\r%s: %lld bytes dumped from %s\n",
file, (long long int)(to-from), dev); file, to-from, dev);
__rf_extract_exit: __rf_extract_exit:
if (fs) fclose(fs); if (fs) fclose(fs);
@@ -80,11 +81,8 @@ __rf_extract_exit:
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
//#include <asm/types.h> #include <asm/types.h>
#include <mtd/mtd-user.h> #include <mtd/mtd-user.h>
#ifndef loff_t
#define loff_t off_t
#endif
#define M_RDONLY 0x00000001 #define M_RDONLY 0x00000001
#define M_RDRW 0x00000002 #define M_RDRW 0x00000002
@@ -141,8 +139,8 @@ int mtd_close(int fd, struct nand_oobinfo *old_oobinfo, int oobinfochanged)
// configuration for nanddump // // configuration for nanddump //
//int noecc = 0; // don't error correct //int noecc = 0; // don't error correct
static int omitoob = 1; // omit oob data int omitoob = 1; // omit oob data
static int omitbad = 1; int omitbad = 1;
// configuration for nanddump // // configuration for nanddump //
#define CONFIGURE_FLAGS(x) \ #define CONFIGURE_FLAGS(x) \
@@ -161,7 +159,6 @@ int check_badblocks(char *mtddev)
unsigned char oobbuf[64]; unsigned char oobbuf[64];
struct nand_oobinfo old_oobinfo; struct nand_oobinfo old_oobinfo;
struct mtd_oob_buf oob = {0, 16, oobbuf}; struct mtd_oob_buf oob = {0, 16, oobbuf};
/* XXX stat1 is never initialized !!! */
struct mtd_ecc_stats stat1, stat2; struct mtd_ecc_stats stat1, stat2;
mtd_info_t meminfo; mtd_info_t meminfo;
@@ -177,6 +174,7 @@ int check_badblocks(char *mtddev)
fprintf(stderr, "Size %u, flags %u, type 0x%x\n", fprintf(stderr, "Size %u, flags %u, type 0x%x\n",
meminfo.size, meminfo.flags, (int)meminfo.type); meminfo.size, meminfo.flags, (int)meminfo.type);
oob.length = meminfo.oobsize; oob.length = meminfo.oobsize;
for(i = 0; i < meminfo.size; i+= meminfo.writesize) { for(i = 0; i < meminfo.size; i+= meminfo.writesize) {
@@ -204,9 +202,8 @@ int check_badblocks(char *mtddev)
} }
/* ECC stats available ? */ /* ECC stats available ? */
memset (&stat1, 0, sizeof (stat1));
if (eccstats) { if (eccstats) {
if (ioctl (fd, ECCGETSTATS, &stat2)) { if (ioctl(fd, ECCGETSTATS, &stat2)) {
perror("ioctl(ECCGETSTATS)"); perror("ioctl(ECCGETSTATS)");
goto closeall; goto closeall;
} }
@@ -245,9 +242,7 @@ closeall:
return 1; return 1;
} }
// XXX warning ioob is not used int nanddump(char *mtddev, unsigned long start_addr, unsigned long length, char *dumpfile, int isbl)
// isbl is used to skip bad blocks ?
int nanddump(char *mtddev, unsigned long start_addr, unsigned long length, char *dumpfile, int isbl, int ioob)
{ {
unsigned char readbuf[2048]; unsigned char readbuf[2048];
int oobinfochanged = 0 ; int oobinfochanged = 0 ;
@@ -384,7 +379,6 @@ int nanddump(char *mtddev, unsigned long start_addr, unsigned long length, char
/* Write out page data */ /* Write out page data */
//if (pretty_print) dump_bytes(readbuf, bs); //if (pretty_print) dump_bytes(readbuf, bs);
write(ofd, readbuf, bs);
progressbar(ofs, end_addr); progressbar(ofs, end_addr);
// OOB STUFF // // OOB STUFF //
@@ -455,35 +449,22 @@ __done:
return 1; return 1;
} }
static int is_n900() int is_n800()
{
int n900 = 0;
unsigned char buf[4];
FILE *fd = fopen("/dev/mtd2", "rb");
if (!fd) {
fprintf(stderr, "Cannot open /dev/mtd2.\n");
exit(1);
}
fread(buf, 4, 1, fd);
if (!memcmp("\xff\xff\xff\xff", buf, 4))
n900 = 1;
fclose(fd);
return n900;
}
static int is_n800()
{ {
int n800 = 0; int n800 = 0;
unsigned char buf[4]; unsigned char buf[4];
FILE *fd = fopen("/dev/mtd0", "rb"); FILE *fd = fopen("/dev/mtd0", "rb");
if (!fd) { if (!fd) {
fprintf(stderr, "Cannot open /dev/mtd0.\n"); fprintf(stderr, "Cannot open /dev/mtd0.\n");
exit(1); exit(1);
} }
fread(buf, 4, 1, fd); fread(buf, 4, 1,fd);
if (!memcmp("\xff\xff\xff\xff", buf, 4)) if (!memcmp("\xff\xff\xff\xff", buf, 4))
n800 = 1; n800 = 1;
fclose(fd); fclose(fd);
return n800; return n800;
} }
@@ -554,69 +535,28 @@ int dump_config()
return 0; return 0;
} }
int reverse_extract_pieces_n900(char *dir)
{
char reply;
chdir(dir);
printf("Device detected: n900\n");
// Some of the values here are probably not correct
// I need a firmware to identify if the sizes of the pieces are ok
nanddump("/dev/mtd0", 0, 0, "xloader.bin", 1, 0); // fix size?
nanddump("/dev/mtd1", 0, 0, "config.bin", 1, 0);
nanddump("/dev/mtd3", 0, 0, "nolo.bin", 0, 0);
printf("\n\nExtract rootfs? (y/N): "); fflush(stdout);
read(0, &reply, 1);
if (reply=='y'||reply=='Y') {
//rf_extract("/dev/mtd4", 0x000000, 0x6000000, "rootfs.jffs2");
nanddump("/dev/mtd5", 0x000000, 0, "rootfs.jffs2", 0,0);
} else printf("*** Ignoring rootfs\n");
printf("\n\nStrip dumped files? (y/N): "); fflush(stdout);
read(0, &reply, 1);
if (reply=='y'||reply=='Y') {
rf_strip("xloader.bin");
rf_strip("config.bin");
rf_strip("nolo.bin");
} else printf("*** Ignoring strip\n");
printf("\nIdentifying extracted files...\n");
printf("%s: xloader\n", fpid_file("xloader.bin"));
printf("%s: config.bin\n", fpid_file("config.bin"));
printf("%s: nolo.bin\n", fpid_file("nolo.bin"));
printf("%s: rootfs.jffs2\n", fpid_file("rootfs.jffs2"));
return 1;
}
int reverse_extract_pieces(char *dir) int reverse_extract_pieces(char *dir)
{ {
char reply; char reply;
if (is_n900())
return reverse_extract_pieces_n900(dir);
printf("Device detected: 770/n800/n900\n");
chdir(dir); chdir(dir);
// TODO: get values from /proc/mtd ??? // TODO: get values from /proc/mtd ???
//rf_extract("/dev/mtd0", is_n800()?0x200:0, 0x003600, "xloader.bin"); //rf_extract("/dev/mtd0", is_n800()?0x200:0, 0x003600, "xloader.bin");
nanddump("/dev/mtd0", is_n800()?0x200:0, 0x4000, "xloader.bin", 1,0); // 0x3600 size? nanddump("/dev/mtd0", is_n800()?0x200:0, 0x4000, "xloader.bin", 1); // 0x3600 size?
//rf_extract("/dev/mtd0", 0x004000, 0x01ffff, "secondary.bin"); //rf_extract("/dev/mtd0", 0x004000, 0x01ffff, "secondary.bin");
nanddump("/dev/mtd0", 0x004000, 0, "secondary.bin", 1,0); nanddump("/dev/mtd0", 0x004000, 0, "secondary.bin", 1);
nanddump("/dev/mtd1", 0, 0, "config.bin", 0,0); nanddump("/dev/mtd1", 0, 0, "config.bin", 0);
//rf_extract("/dev/mtd2", 0x000800, 0x200000, "zImage"); //rf_extract("/dev/mtd2", 0x000800, 0x200000, "zImage");
nanddump("/dev/mtd2", 0x000800, 0, "zImage", 0,0); nanddump("/dev/mtd2", 0x000800, 0, "zImage", 0);
//rf_extract("/dev/mtd3", 0x000000, 0x1D00000, "initfs.jffs2"); //rf_extract("/dev/mtd3", 0x000000, 0x1D00000, "initfs.jffs2");
nanddump("/dev/mtd3", 0x000000, 0, "initfs.jffs2", 0,0); nanddump("/dev/mtd3", 0x000000, 0, "initfs.jffs2", 0);
printf("\n\nExtract rootfs? (y/N): "); fflush(stdout); printf("\n\nExtract rootfs? (y/N): "); fflush(stdout);
read(0, &reply, 1); read(0, &reply, 1);
if (reply=='y'||reply=='Y') { if (reply=='y'||reply=='Y') {
//rf_extract("/dev/mtd4", 0x000000, 0x6000000, "rootfs.jffs2"); //rf_extract("/dev/mtd4", 0x000000, 0x6000000, "rootfs.jffs2");
nanddump("/dev/mtd4", 0x000000, 0, "rootfs.jffs2", 0,0); nanddump("/dev/mtd4", 0x000000, 0, "rootfs.jffs2", 0);
} else printf("*** Ignoring rootfs\n"); } else printf("*** Ignoring rootfs\n");
printf("\n\nStrip dumped files? (y/N): "); fflush(stdout); printf("\n\nStrip dumped files? (y/N): "); fflush(stdout);
+132 -487
View File
@@ -1,7 +1,6 @@
/* /*
* 0xFFFF - Open Free Fiasco Firmware Flasher * 0xFFFF - Open Free Fiasco Firmware Flasher
* Copyright (C) 2007-2011 pancake <pancake@youterm.com> * Copyright (C) 2007 pancake <pancake@youterm.com>
* Copyright (C) 2011-2012 Pali Rohár <pali.rohar@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -28,24 +27,16 @@
#include "main.h" #include "main.h"
#include "hash.h" #include "hash.h"
char *strdup(const char *s); void (*fiasco_callback)(struct header_t *header) = NULL;
int (*fiasco_callback)(struct header_t *header) = NULL; int openfiasco(char *name)
int openfiasco(const char *name, const char *type, const char *device, const char *hwrev, const char *version, int v)
{ {
struct header_t header; struct header_t header;
unsigned char buf[256]; unsigned char buf[128];
unsigned char data[256]; unsigned char data[128];
unsigned char *pdata, *pdataend; unsigned int namelen;
unsigned int headerlen; off_t off;
unsigned int blockcount;
off_t off, here;
int subsections;
int match;
int i; int i;
memset(&header, 0, sizeof(header));
header.fd = open(name, O_RDONLY); header.fd = open(name, O_RDONLY);
if (header.fd == -1) { if (header.fd == -1) {
@@ -54,73 +45,36 @@ int openfiasco(const char *name, const char *type, const char *device, const cha
} }
/* read header */ /* read header */
if (read(header.fd, buf, 5) != 5) { read(header.fd, buf, 5);
printf("Invalid read of 5 bytes\n");
return close(header.fd);
}
if (buf[0] != 0xb4) { if (buf[0] != 0xb4) {
printf("Invalid header\n"); printf("Invalid header\n");
return close(header.fd); return close(header.fd);
} }
memcpy(&namelen,buf+1,4);
memcpy(&headerlen,buf+1,4); namelen = ntohl(namelen);
headerlen = ntohl(headerlen); if (namelen>128) {
if (headerlen>128) {
printf("Stupid length at header. Is this a joke?\n"); printf("Stupid length at header. Is this a joke?\n");
return close(header.fd); return close(header.fd);
} }
memset(buf,'\0', 128); memset(buf,'\0', 128);
if (read(header.fd, buf, headerlen) != headerlen) { read(header.fd, buf, namelen);
printf("Invalid read of %d bytes\n", headerlen);
return close(header.fd);
}
memcpy(&blockcount,buf,4); printf("Fiasco version: %2d\n", buf[3]);
blockcount = ntohl(blockcount); strcpy(header.fwname, buf+6);
if (blockcount==0) { for(i=6;i<namelen;i+=strlen(buf+i)+1)
printf("Error: No block in header\n"); printf("Name: %s\n", buf+i);
return close(header.fd);
}
if (v) printf("Number of blocks: %d\n", blockcount);
pdata = buf+4;
while (pdata < buf+headerlen-4) {
if (pdata[0] == 0xe8) {
if (v) printf("Header: %s\n", pdata+2);
} else if (pdata[0] == 0x31) {
i = pdata[1];
if (i >= sizeof(header.swver)) i = sizeof(header.swver)-1;
memset(header.swver, 0, sizeof(header.swver));
strncpy(header.swver, (char *)pdata+2, i);
if (v) printf("SW version: %s\n", header.swver);
} else {
if (v) printf("Unknown header 0x%x, length %d, data %s\n", pdata[0], pdata[1], pdata+2);
}
pdata += (int)pdata[1]+2;
}
/* walk the tree */ /* walk the tree */
while(1) { while(1) {
here = lseek(header.fd, 0, SEEK_CUR); if (read(header.fd, buf, 9)<9)
i = 0;
while(1) {
if (read(header.fd, buf, 7)<7) {
printf("Next valid header not found\n");
return close(header.fd);
}
if (buf[0] == 0x54 && buf[2] == 0x2E && buf[3] == 0x19 && buf[4] == 0x01 && buf[5] == 0x01 && buf[6] == 0x00)
break;
lseek(header.fd, -6, SEEK_CUR);
++i;
}
if (i && v) printf("Skipping %d padding bytes\n", i);
subsections = buf[1]-1;
if (read(header.fd, buf+7, 2)<2)
break; break;
if (buf[0] != 0x54) { // 'T'
printf("unexpected header at 0x%x, found %02x %02x %02x\n",
((int)lseek(header.fd, 0, SEEK_CUR))-9,
buf[0], buf[1], buf[2]);
break;
}
header.hash = buf[7]<<8|buf[8]; header.hash = buf[7]<<8|buf[8];
/* piece name */ /* piece name */
@@ -131,270 +85,98 @@ int openfiasco(const char *name, const char *type, const char *device, const cha
if (data[0] == 0xff) { if (data[0] == 0xff) {
printf(" [eof]\n"); printf(" [eof]\n");
break; break;
} else if (v) printf(" %s\n", data); } else printf(" %s\n", data);
memset(header.type, 0, sizeof(header.type)); strcpy(header.name, data);
strncpy(header.type, (char *)data, sizeof(header.type)-1);
if (v) {
printf(" header: ");
for (i=0; i<7;++i) printf(" 0x%.2X", (unsigned int)buf[i]);
printf("\n");
}
if (read(header.fd, buf, 9)<9) if (read(header.fd, buf, 9)<9)
return close(header.fd); break;
memcpy(&header.size, buf,4); memcpy(&header.size, buf,4);
header.size = ntohl(header.size); header.size = ntohl(header.size);
if (v) { printf(" size: %d bytes\n", header.size);
printf(" offset: 0x%08x\n", (unsigned int)here); printf(" hash: %04x\n", header.hash);
printf(" size: %d bytes\n", header.size); //printf("BYTE: %02x %02x %02x %02x %02x\n",
printf(" hash: %04x\n", header.hash); // buf[4], buf[5], buf[6], buf[7], buf[8]);
printf(" subsections: %d\n", subsections); /* XXX this is not ok */
} //printf("BUF8: %02x\n", buf[8]);
while (buf[8] && buf[8]>'0' && buf[8] < '9') {
memset(header.device, 0, sizeof(header.device));
memset(header.hwrevs, 0, sizeof(header.hwrevs));
memset(header.version, 0, sizeof(header.version));
if (header.layout) {
free(header.layout);
header.layout = NULL;
}
while (subsections > 0) {
if (read(header.fd, data, 1)<1) if (read(header.fd, data, 1)<1)
return close(header.fd); break;
i = data[0]; i = data[0];
if (read(header.fd, data, i)<i) if (read(header.fd, data, i)<i)
return close(header.fd); break;
{ if (data[0])
if (v) { printf(" version: %s\n", data);
printf(" subinfo\n"); strcpy(header.version, data);
printf(" type: ");
if (buf[8] == '1') printf("version string");
else if (buf[8] == '2') printf("hw revision");
else if (buf[8] == '3') printf("layout");
else printf("unknown (%c:0x%x)", buf[8], buf[8]);
printf("\n");
printf(" length: %d\n", i);
}
pdata = data;
pdataend = data+i;
while(pdata<pdataend) {
char buf2[9];
if (buf[8] == '2' && pdata != data) {
memset(buf2, 0, 9);
strncpy(buf2, (char *)pdata, 8);
}
if (v) {
printf(" ");
if (buf[8] == '1') printf("version");
else if (buf[8] == '2' && pdata == data) printf("device");
else if (buf[8] == '2' && pdata != data) printf("hw revision");
else if (buf[8] == '3') printf("layout");
else printf("data");
if (buf[8] == '2' && pdata != data)
printf(": %s\n", buf2);
else if (buf[8] == '3')
printf(": (not printing)\n");
else if (buf[8] == '1' || buf[8] == '2')
printf(": %s\n", pdata);
else {
char *buf3 = malloc(i+1);
memcpy(buf3, pdata, i);
buf3[i] = 0;
printf(": (raw) %s\n", buf3);
free(buf3);
}
}
if (buf[8] == '1') {
strncpy(header.version, (char *)pdata, sizeof(header.version)-1);
} else if (buf[8] == '2' && pdata == data) {
strncpy(header.device, (char *)pdata, sizeof(header.device)-1);
} else if (buf[8] == '2' && pdata != data) {
if (header.hwrevs[0] == 0)
strncpy(header.hwrevs, buf2, sizeof(header.hwrevs)-1);
else {
strcat(header.hwrevs, ",");
strcat(header.hwrevs, buf2);
}
} else if (buf[8] == '3') {
if (header.layout) free(header.layout);
header.layout = malloc(strlen((char*)pdata)+1);
if (header.layout) strcpy(header.layout, (char *)pdata);
}
if (buf[8] == '2' && pdata != data && strlen((char *)pdata) > 8)
pdata += 8;
else
pdata += strlen((char*)pdata)+1;
for(;*pdata=='\0' && pdata<pdataend; pdata++);
}
}
if (read(header.fd, buf+8, 1)<1) if (read(header.fd, buf+8, 1)<1)
return close(header.fd); break;
--subsections;
} }
header.name = malloc(strlen(header.type)+strlen(header.device)+strlen(header.hwrevs)+strlen(header.version)+4);
if (!header.name) {
printf("malloc error\n");
exit(1);
}
strcpy(header.name, header.type);
if (header.device[0]) {
strcat(header.name, "-");
strcat(header.name, header.device);
}
if (header.hwrevs[0]) {
strcat(header.name, "-");
strcat(header.name, header.hwrevs);
}
if (header.version[0]) {
strcat(header.name, "-");
strcat(header.name, header.version);
}
off = lseek(header.fd, 0, SEEK_CUR);
if (v) {
printf(" version: %s\n", header.version);
printf(" device: %s\n", header.device);
printf(" hwrevs: %s\n", header.hwrevs);
printf(" name: %s\n", header.name);
printf(" body-at: 0x%08x\n", (unsigned int)off);
}
match = 1;
if (match && type && strcmp(header.type, type) != 0)
match = 0;
if (match && device && strcmp(header.device, device) != 0)
match = 0;
if (match && version && strcmp(header.version, version) != 0)
match = 0;
if (match && hwrev) {
char *tmp1 = malloc(strlen(header.hwrevs)+3);
char *tmp2 = malloc(strlen(hwrev)+3);
if (!tmp1 || !tmp2) {
printf("malloc error\n");
return close(header.fd);
}
sprintf(tmp1, ",%s,", header.hwrevs);
sprintf(tmp2, ",%s,", hwrev);
if (!strstr(tmp1, tmp2))
match = 0;
free(tmp1);
free(tmp2);
}
/* callback */ /* callback */
if (match) { off = lseek(header.fd, 0, SEEK_CUR);
printf("==> %s\n", header.name); if (fiasco_callback != NULL) {
if (fiasco_callback != NULL) { fiasco_callback(&header);
fiasco_callback(&header); free(header.data);
if (header.layout) { continue;
free(header.layout);
header.layout = NULL;
}
free(header.name);
free(header.data);
continue;
} else {
// ??huh
}
} else {
printf("ignored %s\n", header.name);
} }
// XXX dup // XXX dup
lseek(header.fd, off, SEEK_SET); lseek(header.fd, off, SEEK_SET);
lseek(header.fd, header.size, SEEK_CUR); lseek(header.fd, header.size, SEEK_CUR);
if (header.layout) {
free(header.layout);
header.layout = NULL;
}
free(header.name);
} }
return close(header.fd); return 0;
} }
void fiasco_data_read(struct header_t *header) void fiasco_data_read(struct header_t *header)
{ {
header->data = (unsigned char *)malloc(header->size); header->data = (char *)malloc(header->size);
if (header->data == NULL) { if (header->data == NULL) {
printf("Cannot alloc %d bytes\n", header->size); printf("Cannot alloc %d bytes\n", header->size);
return; return;
} }
if (read (header->fd, header->data, header->size) != header->size) { read(header->fd, header->data, header->size);
printf("Cannot read %d bytes\n", header->size);
return;
}
} }
/* fiasco writer */ /* fiasco writer */
int fiasco_new(const char *filename, const char *swver) int fiasco_new(const char *filename, const char *name)
{ {
int fd; int fd;
unsigned int len; //int len = htonl(strlen(name)+1+6+14);
unsigned char len8;
const char *str = "OSSO UART+USB";
if (swver && strlen(swver)+1 > UINT8_MAX) { fd = open(filename, O_RDWR|O_CREAT, 0644);
printf("SW version is too long\n");
return -1;
}
fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0644);
if (fd == -1) if (fd == -1)
return -1; return -1;
#if 1
printf("Writing header\n"); write(fd, "\xb4\x00\x00\x00\x14\x00\x00\x00\x01\xe8\x0e", 11);
write(fd, "OSSO UART+USB", 14);
write(fd, "\xb4", 1); //signature #else
/* 2nd format doesnt works. atm stay with old one */
len = 4; write(fd, "\xb4", 1);
len += strlen(str) + 3;
if (swver)
len += strlen(swver) + 3;
len = htonl(len);
write(fd, &len, 4); write(fd, &len, 4);
/* version header */
if (swver) write(fd, "\x00\x00\x00\x02\xe8\x0e", 6);
len = htonl(2); /* firmware type */
else write(fd, "OSSO UART+USB", 14);
len = htonl(1); /* firmware name */
write(fd, &len, 4); write(fd, name, strlen(name));
write(fd, "", 1);
// header #endif
len = strlen(str)+1;
len8 = len;
write(fd, "\xe8", 1);
write(fd, &len8, 1);
write(fd, str, len);
// sw version
if (swver) {
printf("Writing SW version: %s\n", swver);
len = strlen(swver)+1;
len8 = len;
write(fd, "\x31", 1);
write(fd, &len8, 1);
write(fd, swver, len);
};
return fd; return fd;
} }
int fiasco_add(int fd, const char *name, const char *file, const char *layout, const char *device, const char *hwrevs, const char *version) int fiasco_add_eof(int fd)
{
#if 0
unsigned char buf[120];
if (fd == -1)
return -1;
memset(buf,'\xff', 120);
write(fd, buf, 120);
#endif
return 0;
}
int fiasco_add(int fd, const char *name, const char *file, const char *version)
{ {
int i;
int gd,ret; int gd,ret;
int size;
int align;
unsigned int sz; unsigned int sz;
unsigned char len; unsigned char len;
unsigned short hash; unsigned short hash;
@@ -410,40 +192,17 @@ int fiasco_add(int fd, const char *name, const char *file, const char *layout, c
if (gd == -1) if (gd == -1)
return -1; return -1;
sz = lseek(gd, 0, SEEK_END); sz = htonl((unsigned int) lseek(gd, 0, SEEK_END));
if (name) {
if (strcmp(name, "mmc") == 0) // align mmc
sz = ((sz >> 8) + 1) << 8;
else if (strcmp(name, "kernel") == 0) // align kernel
sz = ((sz >> 7) + 1) << 7;
}
printf(" size: %d\n", sz);
sz = htonl((unsigned int) sz);
lseek(gd, 0, SEEK_SET); lseek(gd, 0, SEEK_SET);
// 4 bytes big endian
write(fd, "T", 1); //write(fd, "T\x02\x2e\x19\x01\x01\x00", 7); // header?
write(fd, "T\x01\x2e\x19\x01\x01\x00", 7); // header (old piece format)
/* number of subsections */
len = 1;
if (version)
++len;
if (device)
++len;
if (layout)
++len;
write(fd, &len, 1);
write(fd, "\x2e\x19\x01\x01\x00", 5);
/* checksum */ /* checksum */
hash = do_hash_file(file, name); hash = do_hash_file(file);
ptr[0]^=ptr[1]; ptr[1]=ptr[0]^ptr[1]; ptr[0]^=ptr[1]; ptr[0]^=ptr[1]; ptr[1]=ptr[0]^ptr[1]; ptr[0]^=ptr[1];
write(fd, &hash, 2); write(fd, &hash, 2);
printf(" hash: %04x\n", hash); printf("hash: %04x\n", hash);
/* image type name */
memset(bname, '\0', 13); memset(bname, '\0', 13);
if (name == NULL) if (name == NULL)
name = fpid_file(file); name = fpid_file(file);
@@ -453,104 +212,24 @@ int fiasco_add(int fd, const char *name, const char *file, const char *layout, c
strncpy(bname, name, 12); strncpy(bname, name, 12);
write(fd, bname, 12); write(fd, bname, 12);
write(fd, &sz, 4);
write(fd, "\x00\x00\x00\x00", 4);
/* append version subsection */ write(fd, &sz, 4);
if (version) { if (version) {
write(fd, "1", 1); /* 1 - version */ /* append metadata */
len = strlen(version)+1; write(fd, "\x00\x00\x00\x00\x31", 5);
len = strlen(version);
write(fd, &len, 1); write(fd, &len, 1);
write(fd, version, len); write(fd, version, len);
write(fd, "\x00\x9b", 2);
} else {
write(fd, "\x00\x00\x00\x00\x9b", 5);
} }
/* append device & hwrevs subsection */
if (device) {
const char *ptr = hwrevs;
const char *oldptr = hwrevs;
write(fd, "2", 1); /* 2 - device & hwrevs */
len = 16;
if (hwrevs) {
i = 1;
while ((ptr = strchr(ptr, ','))) { i++; ptr++; }
if ((int)len + i*8 > 255) {
printf("Device string and HW revisions are too long\n");
return -1;
}
len += i*8;
}
write(fd, &len, 1);
len = strlen(device);
if (len > 15) len = 15;
write(fd, device, len);
for (i=0; i<16-len; ++i)
write(fd, "\x00", 1);
if (hwrevs) {
ptr = hwrevs;
oldptr = hwrevs;
while ((ptr = strchr(ptr, ','))) {
len = ptr-oldptr;
if (len > 8) len = 8;
write(fd, oldptr, len);
for (i=0; i<8-len; ++i)
write(fd, "\x00", 1);
++ptr;
oldptr = ptr;
}
len = strlen(oldptr);
if (len > 8) len = 8;
write(fd, oldptr, len);
for (i=0; i<8-len; ++i)
write(fd, "\x00", 1);
}
}
/* append layout subsection */
if (layout) {
int lfd = open(layout, O_RDONLY);
if (lfd >= 0) {
len = read(lfd, buf, sizeof(buf));
if (len > 0) {
write(fd, "3", 1); /* 3 - layout */
write(fd, &len, 1);
write(fd, buf, len);
}
close(lfd);
} else {
printf("Cannot open layout file %s\n", layout);
return -1;
}
}
/* dummy byte - end of all subsections */
write(fd, "\x00", 1);
size = 0;
while(1) { while(1) {
ret = read(gd, buf, 4096); ret = read(gd, buf, 4096);
size += ret;
if (ret<1) if (ret<1)
break; break;
if (write(fd, buf, ret) != ret) { write(fd, buf, ret);
fprintf (stderr, "Cannot write %d bytes\n", ret);
return -1;
}
}
/* align mmc and kernel (fill with 0xff) */
align = 0;
if (name) {
if (strcmp(name, "mmc") == 0)
align = ((size >> 8) + 1) << 8;
else if (strcmp(name, "kernel") == 0)
align = ((size >> 7) + 1) << 7;
}
if (align) {
while (size < align) {
write(fd, "\xff", 1);
++size;
}
} }
return 0; return 0;
@@ -558,91 +237,57 @@ int fiasco_add(int fd, const char *name, const char *file, const char *layout, c
int fiasco_pack(int optind, char *argv[]) int fiasco_pack(int optind, char *argv[])
{ {
char *file = argv[optind]; const char *file = argv[optind];
int fd, ret, i;
char *ptr;
char *arg;
char *type; char *type;
char *device; int fd, ret;
char *hwrevs;
char *version;
char *layout;
char *swver = NULL; fd = fiasco_new(file, file); // TODO use a format here
i = optind;
while((arg=argv[++i])) {
if (strncmp(arg, "version:", strlen("version:"))==0) {
swver = arg+strlen("version:");
break;
}
}
printf("Package: %s\n", file);
fd = fiasco_new(file, swver);
if (fd == -1) if (fd == -1)
return 1; return 1;
while((arg=argv[++optind])) { printf("Package: %s\n", file);
while((file=argv[++optind])) {
if (strncmp(arg, "version:", strlen("version:"))==0) type = (char *)fpid_file(file);
continue; printf("Adding %s: %s..\n", type, file);
ret = fiasco_add(fd, type, file, NULL);
// format: [[[[dev:[hw:]]ver:]type:]file[%layout]
ptr = strdup(arg);
layout = strchr(ptr, '%');
if (layout) {
*(layout++) = 0;
}
type = NULL;
device = NULL;
hwrevs = NULL;
version = NULL;
file = strrchr(ptr, ':');
if (file) {
*(file++) = 0;
type = strrchr(ptr, ':');
if (type) {
*(type++) = 0;
version = strrchr(ptr, ':');
if (version) {
*(version++) = 0;
hwrevs = strchr(ptr, ':');
if (hwrevs)
*(hwrevs++) = 0;
device = ptr;
} else {
version = ptr;
}
} else {
type = ptr;
}
} else {
file = ptr;
}
if (!type)
type = (char *)fpid_file(file);
printf("Adding file: %s\n", file);
printf(" type: %s\n", type);
if (device) printf(" device: %s\n", device);
if (hwrevs) printf(" hw revisions: %s\n", hwrevs);
if (version) printf(" version: %s\n", version);
if (layout) printf(" layout file: %s\n", layout);
ret = fiasco_add(fd, type, file, layout, device, hwrevs, version);
free(ptr);
if (ret<0) { if (ret<0) {
printf("Error\n"); printf("Error\n");
close(fd); close(fd);
return 1; return 1;
} }
} }
fiasco_add_eof(fd);
printf("Done!\n"); printf("Done!\n");
close(fd); close(fd);
return 0; return 0;
} }
/* local code */
#if 0
void my_callback(int fd, struct header_t *header)
{
fiasco_data_read(header);
//read(fd, buf, header->size);
printf("Dumping %s\n", header->name);
printf("DATA: %02x\n", header->data[0]);
fiasco_data_free(header);
}
int main(int argc, char **argv)
{
if (argc!=2) {
printf("Usage: unfiasco [file]\n");
return 1;
}
/*
fd = fiasco_new("myfiasco", "pancake-edition");
fiasco_add(fd, "kernel", "zImage", "2.6.22");
close(fd);
*/
// fiasco_callback = &my_callback;
return openfiasco(argv[1]);
}
#endif
+3 -21
View File
@@ -16,10 +16,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#if HAVE_USB
#include "main.h" #include "main.h"
#include "hash.h" #include "hash.h"
#include "hexdump.h" #include "hexdump.h"
#include <usb.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
@@ -74,7 +74,7 @@ void check_nolo_order()
check_nolo_order_failed(); check_nolo_order_failed();
} }
void flash_image(const char *filename, const char *piece, const char *device, const char *hwrevs, const char *version) void flash_image(char *filename, char *piece, char *version)
{ {
FILE *fd; FILE *fd;
int vlen = 0; int vlen = 0;
@@ -84,24 +84,7 @@ void flash_image(const char *filename, const char *piece, const char *device, co
unsigned long long size, off; unsigned long long size, off;
unsigned char bsize[4], tmp; unsigned char bsize[4], tmp;
unsigned char nolofiller[128]; unsigned char nolofiller[128];
ushort hash = do_hash_file(filename, piece); ushort hash = do_hash_file(filename);
if (piece == NULL) {
//exit(1);
piece = fpid_file(filename);
if (piece == NULL) {
printf("Unknown piece type\n");
return;
}
printf("Piece type: %s\n", piece);
}
if (piece != NULL) {
if (!strcmp(piece, "fiasco")) {
fiasco_flash(filename);
return;
}
}
if (version) if (version)
vlen = strlen(version)+1; vlen = strlen(version)+1;
@@ -212,4 +195,3 @@ void flash_image(const char *filename, const char *piece, const char *device, co
} }
printf("Flash done succesfully.\n"); printf("Flash done succesfully.\n");
} }
#endif
+4 -39
View File
@@ -1,7 +1,6 @@
/* /*
* 0xFFFF - Open Free Fiasco Firmware Flasher * 0xFFFF - Open Free Fiasco Firmware Flasher
* Copyright (C) 2007 pancake <pancake@youterm.com> * Copyright (C) 2007 pancake <pancake@youterm.com>
* Copyright (C) 2012 Pali Rohár <pali.rohar@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -21,38 +20,12 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
/* global structs */
char *pieces[] = {
"xloader", // xloader.bin
"2nd", // 2nd.bin
"secondary", // secondary.bin
"kernel", // zImage
"initfs", // initfs
"rootfs", // rootfs
"omap-nand", // 8kB of food for the nand
"mmc", // raw eMMC image
"cmt-2nd", // cmt-2nd
"cmt-algo", // cmt-algo
"cmt-mcusw", // cmt-mcusw
"fiasco", // FIASCO IMAGE
NULL
};
long fpid_size(const char *filename)
{
long sz;
FILE *fd = fopen(filename, "r");
fseek(fd, 0, SEEK_END);
sz = ftell(fd);
fclose(fd);
return sz;
}
const char *fpid_file(const char *filename) const char *fpid_file(const char *filename)
{ {
FILE *fd; FILE *fd;
char buf[512]; char buf[512];
unsigned char *b = (unsigned char *)&buf; unsigned char *b = (unsigned char *)&buf;
char *piece = NULL;
long size; long size;
// 2nd : +0x34 = 2NDAPE // 2nd : +0x34 = 2NDAPE
@@ -72,9 +45,6 @@ const char *fpid_file(const char *filename)
size = ftell(fd); size = ftell(fd);
fclose(fd); fclose(fd);
if (!memcmp(b, "\xb4", 1))
return pieces[PIECE_FIASCO];
else
if (!memcmp(b+0x34, "2NDAPE", 6)) if (!memcmp(b+0x34, "2NDAPE", 6))
return pieces[PIECE_2ND]; return pieces[PIECE_2ND];
else else
@@ -84,15 +54,10 @@ const char *fpid_file(const char *filename)
if (!memcmp(b+0x14, "X-LOADER", 8)) if (!memcmp(b+0x14, "X-LOADER", 8))
return pieces[PIECE_XLOADER]; return pieces[PIECE_XLOADER];
else else
if (!memcmp(b+0x0c, "NOLOXldr", 8)) if (!memcmp(b+0x0c, "NOLOXldr", 8)) // TODO: this is xloader800, not valid on 770?
return pieces[PIECE_XLOADER]; return pieces[PIECE_XLOADER];
else else
if (!memcmp(b+4,"NOLOXldr",8)) if (!memcmp(b+0x00, "\x00\x00\xa0\xe1\x00\x00\xa0\xe1", 8))
// TODO: this is xloader800, not valid on 770?
return pieces[PIECE_2ND];
else
if (!memcmp(b+0x00, "\x00\x00\xa0\xe1\x00\x00\xa0\xe1", 8)
|| (!memcmp(b, "\x21\x01\x01", 3)))
return pieces[PIECE_KERNEL]; return pieces[PIECE_KERNEL];
else else
// JFFS2 MAGIC // JFFS2 MAGIC
@@ -103,5 +68,5 @@ const char *fpid_file(const char *filename)
return pieces[PIECE_ROOTFS]; return pieces[PIECE_ROOTFS];
} }
return NULL; return piece;
} }
-21
View File
@@ -1,21 +0,0 @@
include ../../config.mk
ifeq (${HAVE_GUI},1)
all: goxf
goxf:
${CC} -I../squeue ../squeue/squeue.c ../fpid.c gui.c `pkg-config --cflags --libs gtk+-2.0` -o goxf
c:
gtkamlc --save-temps --Xcc=-I../squeue ../squeue/squeue.c ../fpid.c ../squeue/squeue.vapi gui.gtkon extras.vapi --pkg gtk+-2.0 -o goxf
test:
valac --save-temps --Xcc=-I.. squeue.vapi test.vala ../squeue.c -o v
valac --save-temps --Xcc=-I.. squeue.vapi client.vala ../squeue.c -o c
else
all:
@true
endif
clean:
rm -f goxf *.o *.c
-10
View File
@@ -1,10 +0,0 @@
namespace Extras {
public class External {
[CCode (cname = "system")]
public static int system(string cmd);
[CCode (cname = "fpid_file")]
public static string fpid_file(string file);
[CCode (cname = "fpid_size")]
public static long fpid_size(string file);
}
}
-1163
View File
File diff suppressed because it is too large. Load diff
-356
View File
@@ -1,356 +0,0 @@
<!--
Frontend for the 0xFFFF flasher in gtkaml
author: pancake <youterm.com>
-->
<Window xmlns="Gtk"
xmlns:GLib="GLib"
xmlns:Extras="Extras"
xmlns:SQueues="SQueues"
xmlns:class="http://gtkaml.org/0.2"
class:name="MainWindow"
title="0xFFFF GUI">
<!-- delete-event="{OnWindow1DeleteEvent}" -->
<VBox>
<MenuBar expand="false">
<MenuItem label="_File" with-mnemonic="true">
<submenu>
<Menu>
<ImageMenuItem stock-id="gtk-new" activate="{OnFileNewEvent}"/>
<ImageMenuItem stock-id="gtk-open" activate="{OnFileOpenEvent}"/>
<SeparatorMenuItem />
<ImageMenuItem stock-id="gtk-quit" activate="{OnQuitEvent}"/>
</Menu>
</submenu>
</MenuItem>
<!-- Help menu -->
<MenuItem label="_Target" with-mnemonic="true">
<submenu>
<Menu>
<ImageMenuItem stock-id="gtk-connect" activate="{OnConnect}"/>
<ImageMenuItem stock-id="gtk-stop" activate="{OnStop}"/>
<ImageMenuItem stock-id="gtk-info" activate="{OnGetInformation}"/>
<ImageMenuItem label="Reset" activate="{OnReset}"/>
</Menu>
</submenu>
</MenuItem>
<!-- Help menu -->
<MenuItem label="_Help" with-mnemonic="true">
<submenu>
<Menu>
<ImageMenuItem stock-id="gtk-about" activate="{OnMenuHelpAboutActivatedEvent}"/>
</Menu>
</submenu>
</MenuItem>
</MenuBar>
<HBox border-width="5">
<VBox border-width="3" spacing="3">
<ScrolledWindow can-focus="true" hscrollbar-policy="{PolicyType.AUTOMATIC}" vscrollbar-policy="{PolicyType.AUTOMATIC}">
<TreeView class:private="tv">
</TreeView>
</ScrolledWindow>
</VBox>
<VBox expand="false" border-width="3" spacing="3">
<Button label="gtk-connect" use-stock="true" expand="false" clicked="{OnConnect}"/>
<Button label="gtk-stop" use-stock="true" expand="false" clicked="{OnStop}"/>
<Button label="gtk-info" use-stock="true" expand="false" clicked="{OnGetInformation}"/>
<Label label="" />
<!-- <Button label="Options" use-stock="false" expand="false"/>
<Button label="Fiasco!" use-stock="false" expand="false"/>
<Button label="Unpack!" use-stock="false" expand="false"/> -->
<Button label="gtk-add" use-stock="true" expand="false" clicked="{OnFileOpenEvent}" />
<Button label="gtk-remove" use-stock="true" expand="false" clicked="{list_del}"/>
<Label label="" />
<Button label="gtk-media-record" use-stock="true" expand="false" clicked="{OnFileFlashEvent}"/>
</VBox>
</HBox>
<ProgressBar class:private="pb" expand="false" />
<!-- <Statusbar expand="false"/> -->
</VBox>
<AboutDialog class:standalone="true" class:private="aboutdialog1" delete-event="{aboutdialog1.hide_on_delete}"
border-width="5" title="About 0xFFFF gui" resizable="false" modal="true"
window-position="{WindowPosition.CENTER_ON_PARENT}" has-separator="false"
program-name="0xFFFF" version="0.5" copyright="Copyright (c) 2007-2009 pancake"
comments="The Free Nokia Internet Tablet flasher"
website="http://www.nopcode.org/0xFFFF/"
authors='{new string[] {"pancake (pancake@youterm.com)", null}}'>
</AboutDialog>
<![CDATA[
private void doCloseApplication ()
{
Gtk.main_quit ();
}
private void OnReset()
{
q->push("reset:device", 1);
}
private void OnFileFlashEvent()
{
ListStore ls = (ListStore)tv.get_model();
weak string str;
TreeIter iter;
int n = ls.iter_n_children(null);
if (n >0) {
if (showYesNo("Do you want to flash these files?")) {
ls.get_iter_first(out iter);
do {
ls.get(iter, 2, out str, -1);
//stdout.printf("polla:%s\n", str);
q->push2("flash", str, 1);
} while(ls.iter_next(ref iter));
}
} else {
showMessage("No files selected", MessageType.ERROR);
}
}
private void OnFileOpenEvent ()
{
FileChooserDialog fc = new FileChooserDialog("Select file to open",
this, FileChooserAction.OPEN,
"gtk-cancel", ResponseType.CANCEL,
"gtk-open", ResponseType.ACCEPT);
int resp = fc.run ();
fc.hide ();
if (resp == ResponseType.ACCEPT) {
string file = fc.get_filename();
string *type = External.fpid_file(file);
string size = "%ld".printf(External.fpid_size(file));
if (type == null) {
showMessage("Invalid file type", MessageType.ERROR);
} else {
add_file(type, size, file);
}
}
fc.destroy ();
}
public bool loadFile( string filename )
{
int err = 0;
try {
string contents; size_t length;
FileUtils.get_contents (filename, out contents, out length);
//textview1.buffer.set_text (contents, length);
} catch(Error e) {
showError ("Unexpected error while loading the file, please contact the author with the following information:\n\n" + e.message);
err++;
}
return err == 0;
}
public bool showYesNo(string s)
{
MessageDialog md = new MessageDialog (this,
DialogFlags.DESTROY_WITH_PARENT,
MessageType.QUESTION, ButtonsType.YES_NO, s);
int ret = md.run ();
md.destroy ();
return ret==ResponseType.YES;
}
public void showMessage(string s, MessageType mt)
{
MessageDialog md = new MessageDialog (this,
DialogFlags.DESTROY_WITH_PARENT,
mt, ButtonsType.CLOSE, s);
md.run ();
md.destroy ();
}
private void OnMenuHelpAboutActivatedEvent ()
{
aboutdialog1.transient_for = this;
aboutdialog1.run ();
}
public void showError (string s)
{
MessageDialog md = new MessageDialog (this,
DialogFlags.DESTROY_WITH_PARENT,
MessageType.ERROR,
ButtonsType.CLOSE,
s);
md.run ();
md.destroy ();
}
private void OnFileNewEvent ()
{
list_clear();
// TODO: clear file list
}
private void OnQuitEvent ()
{
doCloseApplication();
// TODO: send message to gracefully kill 0xFFFF
// TODO: handle ^C when flashing
}
public void list_clear()
{
((ListStore)tv.model).clear();
}
public void list_del()
{
TreeIter iter;
TreeModel model;
TreeSelection sel = tv.get_selection();
if (sel.count_selected_rows() == 1) {
sel.get_selected(out model, out iter);
((ListStore)tv.model).remove(iter);
}
}
public void add_file(string type, string size, string file)
{
ListStore listmodel = (ListStore)tv.get_model();
Gtk.TreeIter iter;
listmodel.append (out iter);
listmodel.set (iter, 0, type, 1, size, 2, file, -1);
}
public static void setup_treeview (Gtk.TreeView view)
{
/* use liststore to hold accountname, accounttype, balance and color attribute */
/* for more info how gtkTreeview works take a look in the GTK API */
var listmodel = new Gtk.ListStore(4, typeof(string), typeof(string), typeof(string), typeof(string));
view.set_model(listmodel);
view.insert_column_with_attributes (-1, "Type", new Gtk.CellRendererText(), "text", 0, null);
view.insert_column_with_attributes (-1, "Size", new Gtk.CellRendererText(), "text", 1, null);
var cell = new Gtk.CellRendererText ();
cell.set ("foreground_set", true, null);
view.insert_column_with_attributes (-1, "Name", cell, "text", 2, "foreground", 3, null);
// Gtk.TreeIter iter;
// listmodel.append (out iter);
// listmodel.set (iter, 0, "initfs", 1, "3M", 2, "initfs.jffs", -1);
//listmodel.set (iter, 0, "initfs", 1, "3M", 2, "initfs.jffs", 3, "green", -1);
// listmodel.append (out iter);
// listmodel.set (iter, 0, "rootfs", 1, "52M", 2, "rootfs.jffs", -1);
}
public static bool readFunc()
{
weak string msg = p->get(0);
if (msg != null && msg[0]!='\0') {
stdout.printf("[<] msg received: %s\n", msg);
string[] foo = msg.split(":",2);
if (foo[1] != null) {
switch(foo[0]) {
case "bar":
viewer.pb.fraction = foo[1].to_int() / 100;
viewer.pb.text = foo[1]+"%";
break;
case "error":
viewer.showMessage(foo[1], MessageType.ERROR);
break;
case "info":
viewer.showMessage(foo[1], MessageType.INFO);
break;
default:
stderr.printf("[E] Unknown message type\n");
break;
}
//viewer.showMessage(msg, MessageType.INFO);
}
p->pop();
}
return true;
}
static SQueue *q = null;
static SQueue *p = null;
private void OnGetInformation()
{
msg("info:device");
}
private void OnConnect()
{
//msg("connect:device");
OnStop();
External.system("sudo 0xFFFF -Q &");
p->close();
q->close();
p = q = null;
}
private void OnStop()
{
External.system("sudo pkill 0xFFFF");
}
private bool chk_queues()
{
if (p == null)
p = SQueue.open("/tmp/0xFFFF.1", SQueueMode.OPEN);
if (q == null)
q = SQueue.open("/tmp/0xFFFF.2", SQueueMode.OPEN);
if (p == null || q == null) {
showMessage("Cannot connect to queues", MessageType.ERROR);
return false;
}
return true;
}
public void msg(string str)
{
if (!chk_queues())
return;
if (q->push(str, 0)<1) {
stderr.printf("Oops on push\n");
q->free();
q = null;
p->free();
p = null;
}
}
static MainWindow viewer;
static int main (string[] args)
{
Gtk.init (ref args);
viewer = new MainWindow();
if (args.length > 1)
viewer.loadFile (args[1]);
viewer.resize(600,400);
viewer.set_position(WindowPosition.CENTER);
viewer.delete_event += (x,y) => { Gtk.main_quit(); };
setup_treeview(viewer.tv);
viewer.show_all ();
// viewer.showMessage("This software is beta and does not guaranties correct functionality", MessageType.WARNING);
Timeout.add(200, (SourceFunc)(readFunc));
Gtk.main ();
return 0;
}
]]>
</Window>
-321
View File
@@ -1,321 +0,0 @@
/*
| Frontend for the 0xFFFF flasher in gtkaml
| author: pancake <youterm.com>
*/
Window using="Gtk" gtkon:version=0.4
using:Extras="Extras"
using:SQueues="SQueues"
name="MainWindow"
title="0xFFFF GUI"
{
/* delete-event="{OnWindow1DeleteEvent}" */
VBox {
MenuBar !expand {
MenuItem label="_File" with-mnemonic {
submenu {
Menu {
ImageMenuItem stock-id="gtk-new" activate=OnFileNewEvent;
ImageMenuItem stock-id="gtk-open" activate=OnFileOpenEvent;
SeparatorMenuItem;
ImageMenuItem stock-id="gtk-quit" activate=OnQuitEvent;
}
}
}
MenuItem label="_Target" with-mnemonic {
submenu {
Menu {
ImageMenuItem stock-id="gtk-connect" activate=OnConnect;
ImageMenuItem stock-id="gtk-stop" activate=OnStop;
ImageMenuItem stock-id="gtk-info" activate=OnGetInformation;
ImageMenuItem label="Reset" activate=OnReset;
}
}
}
MenuItem label="_Help" with-mnemonic {
submenu {
Menu {
ImageMenuItem stock-id="gtk-about" activate=OnMenuHelpAboutActivatedEvent;
}
}
}
}
HBox border-width="5" {
VBox border-width="3" spacing="3" {
ScrolledWindow can-focus="true" hscrollbar-policy="{PolicyType.AUTOMATIC}" vscrollbar-policy="{PolicyType.AUTOMATIC}" {
TreeView $.tv;
}
}
VBox !expand border-width="3" spacing="3" {
Button label="gtk-connect" use-stock !expand clicked=OnConnect;
Button label="gtk-stop" use-stock !expand clicked=OnStop;
Button label="gtk-info" use-stock !expand clicked=OnGetInformation;
Label label="";
/*
<!-- <Button label="Options" use-stock="false" expand="false"/>
<Button label="Fiasco!" use-stock="false" expand="false"/>
<Button label="Unpack!" use-stock="false" expand/> -->
*/
Button label="gtk-add" use-stock="true" !expand clicked=OnFileOpenEvent;
Button label="gtk-remove" use-stock="true" expand="false" clicked=list_del;
Label label="";
Button label="gtk-media-record" use-stock="true" expand="false" clicked=OnFileFlashEvent;
}
}
ProgressBar $.pb !expand;
//<!-- <Statusbar expand="false"/> -->
}
AboutDialog gtkaml:standalone $.aboutdialog1 delete-event=aboutdialog1.hide_on_delete
border-width="5" title="About 0xFFFF gui" resizable="false" modal="true"
window-position="{WindowPosition.CENTER_ON_PARENT}" has-separator="false"
program-name="0xFFFF" version="0.5" copyright="Copyright (c) 2007-2009 pancake"
comments="The Free Nokia Internet Tablet flasher"
website="http://www.nopcode.org/0xFFFF/"
authors='{new string[] {"pancake (pancake@youterm.com)", null}}';
-{
private void doCloseApplication () {
Gtk.main_quit ();
}
private void OnReset() {
q->push("reset:device", 1);
}
private void OnFileFlashEvent() {
ListStore ls = (ListStore)tv.get_model();
weak string str;
TreeIter iter;
int n = ls.iter_n_children(null);
if (n >0) {
if (showYesNo("Do you want to flash these files?")) {
ls.get_iter_first(out iter);
do {
ls.get(iter, 2, out str, -1);
//stdout.printf("polla:%s\n", str);
q->push2("flash", str, 1);
} while(ls.iter_next(ref iter));
}
} else showMessage("No files selected", MessageType.ERROR);
}
private void OnFileOpenEvent () {
FileChooserDialog fc = new FileChooserDialog("Select file to open",
this, FileChooserAction.OPEN,
"gtk-cancel", ResponseType.CANCEL,
"gtk-open", ResponseType.ACCEPT);
int resp = fc.run ();
fc.hide ();
if (resp == ResponseType.ACCEPT) {
string file = fc.get_filename();
string *type = External.fpid_file(file);
string size = "%ld".printf(External.fpid_size(file));
if (type == null)
showMessage("Invalid file type", MessageType.ERROR);
else add_file(type, size, file);
}
fc.destroy ();
}
public bool loadFile( string filename ) {
int err = 0;
try {
string contents; size_t length;
FileUtils.get_contents (filename, out contents, out length);
//textview1.buffer.set_text (contents, length);
} catch(Error e) {
showError ("Unexpected error while loading the file, please contact the author with the following information:\n\n" + e.message);
err++;
}
return err == 0;
}
public bool showYesNo(string s) {
MessageDialog md = new MessageDialog (this,
DialogFlags.DESTROY_WITH_PARENT,
MessageType.QUESTION, ButtonsType.YES_NO, s);
int ret = md.run ();
md.destroy ();
return ret==ResponseType.YES;
}
public void showMessage(string s, MessageType mt) {
MessageDialog md = new MessageDialog (this,
DialogFlags.DESTROY_WITH_PARENT,
mt, ButtonsType.CLOSE, s);
md.run ();
md.destroy ();
}
private void OnMenuHelpAboutActivatedEvent () {
aboutdialog1.transient_for = this;
aboutdialog1.response.connect ((x)=> { aboutdialog1.hide (); });
aboutdialog1.run ();
}
public void showError (string s) {
MessageDialog md = new MessageDialog (this,
DialogFlags.DESTROY_WITH_PARENT,
MessageType.ERROR,
ButtonsType.CLOSE,
s);
md.run ();
md.destroy ();
}
private void OnFileNewEvent () {
list_clear();
// TODO: clear file list
}
private void OnQuitEvent () {
doCloseApplication();
// TODO: send message to gracefully kill 0xFFFF
// TODO: handle ^C when flashing
}
public void list_clear() {
((ListStore)tv.model).clear();
}
public void list_del() {
TreeIter iter;
TreeModel model;
TreeSelection sel = tv.get_selection();
if (sel.count_selected_rows() == 1) {
sel.get_selected(out model, out iter);
((ListStore)tv.model).remove(iter);
}
}
public void add_file(string type, string size, string file) {
ListStore listmodel = (ListStore)tv.get_model();
Gtk.TreeIter iter;
listmodel.append (out iter);
listmodel.set (iter, 0, type, 1, size, 2, file, -1);
}
public static void setup_treeview (Gtk.TreeView view) {
/* use liststore to hold accountname, accounttype, balance and color attribute */
/* for more info how gtkTreeview works take a look in the GTK API */
var listmodel = new Gtk.ListStore(4, typeof(string), typeof(string), typeof(string), typeof(string));
view.set_model(listmodel);
view.insert_column_with_attributes (-1, "Type", new Gtk.CellRendererText(), "text", 0, null);
view.insert_column_with_attributes (-1, "Size", new Gtk.CellRendererText(), "text", 1, null);
var cell = new Gtk.CellRendererText ();
cell.set ("foreground_set", true, null);
view.insert_column_with_attributes (-1, "Name", cell, "text", 2, "foreground", 3, null);
// Gtk.TreeIter iter;
// listmodel.append (out iter);
// listmodel.set (iter, 0, "initfs", 1, "3M", 2, "initfs.jffs", -1);
//listmodel.set (iter, 0, "initfs", 1, "3M", 2, "initfs.jffs", 3, "green", -1);
// listmodel.append (out iter);
// listmodel.set (iter, 0, "rootfs", 1, "52M", 2, "rootfs.jffs", -1);
}
public static bool readFunc() {
weak string msg = p->get(0);
if (msg != null && msg[0]!='\0') {
stdout.printf("[<] msg received: %s\n", msg);
string[] foo = msg.split(":",2);
if (foo[1] != null) {
switch(foo[0]) {
case "bar":
viewer.pb.fraction = foo[1].to_int() / 100;
viewer.pb.text = foo[1]+"%";
break;
case "error":
viewer.showMessage(foo[1], MessageType.ERROR);
break;
case "info":
viewer.showMessage(foo[1], MessageType.INFO);
break;
default:
stderr.printf("[E] Unknown message type\n");
break;
}
//viewer.showMessage(msg, MessageType.INFO);
}
p->pop();
}
return true;
}
static SQueue *q = null;
static SQueue *p = null;
private void OnGetInformation() {
msg("info:device");
}
private void OnConnect() {
//msg("connect:device");
OnStop();
External.system("sudo 0xFFFF -Q &");
p->close();
q->close();
p = q = null;
}
private void OnStop() {
External.system("sudo pkill 0xFFFF");
}
private bool chk_queues() {
if (p == null)
p = SQueue.open("/tmp/0xFFFF.1", SQueueMode.OPEN);
if (q == null)
q = SQueue.open("/tmp/0xFFFF.2", SQueueMode.OPEN);
if (p == null || q == null) {
showMessage("Cannot connect to queues", MessageType.ERROR);
return false;
}
return true;
}
public void msg(string str) {
if (!chk_queues())
return;
if (q->push(str, 0)<1) {
stderr.printf("Oops on push\n");
q->free();
q = null;
p->free();
p = null;
}
}
static MainWindow viewer;
static int main (string[] args) {
Gtk.init (ref args);
viewer = new MainWindow();
if (args.length > 1)
viewer.loadFile (args[1]);
viewer.resize(600,400);
viewer.set_position(WindowPosition.CENTER);
viewer.delete_event.connect ((x,y) => { Gtk.main_quit(); return false; });
setup_treeview(viewer.tv);
viewer.show_all ();
// viewer.showMessage("This software is beta and does not guaranties correct functionality", MessageType.WARNING);
Timeout.add(200, (SourceFunc)(readFunc));
Gtk.main ();
return 0;
}
}-
}
+3 -25
View File
@@ -1,6 +1,6 @@
/* /*
* 0xFFFF - Open Free Fiasco Firmware Flasher * 0xFFFF - Open Free Fiasco Firmware Flasher
* Copyright (C) 2007-2009 pancake <pancake@youterm.com> * Copyright (C) 2007 pancake <pancake@youterm.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -17,7 +17,6 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include "hash.h" #include "hash.h"
usho do_hash(usho *b, int len) usho do_hash(usho *b, int len)
@@ -28,13 +27,11 @@ usho do_hash(usho *b, int len)
return result; return result;
} }
usho do_hash_file(const char *filename, const char *type) usho do_hash_file(char *filename)
{ {
unsigned char buf[BSIZE]; unsigned char buf[BSIZE];
FILE *fd = fopen(filename, "r"); FILE *fd = fopen(filename, "r");
usho hash = 0; usho hash = 0;
int align = 0;
int size;
int ret; int ret;
if (fd == NULL) { if (fd == NULL) {
@@ -42,33 +39,14 @@ usho do_hash_file(const char *filename, const char *type)
return -1; return -1;
} }
do { do { ret = fread(&buf, 1, BSIZE, fd);
ret = fread(&buf, 1, BSIZE, fd);
if (ret == -1) if (ret == -1)
return 0; return 0;
hash ^= do_hash((usho *)&buf, ret); hash ^= do_hash((usho *)&buf, ret);
} while(ret); } while(ret);
size = ftell(fd);
fclose(fd); fclose(fd);
/* mmc and kernel image must be aligned */
if (type) {
if (strcmp(type, "mmc") == 0)
align = ((size >> 8) + 1) << 8;
else if (strcmp(type, "kernel") == 0)
align = ((size >> 7) + 1) << 7;
}
if (align) {
printf("align from %d to %d\n", size, align);
buf[0] = 0xff;
while (size < align) {
hash ^= do_hash((usho *)&buf, 1);
++size;
}
}
return hash; return hash;
} }
+1 -1
View File
@@ -5,6 +5,6 @@
#define BSIZE 0x20000 #define BSIZE 0x20000
usho do_hash(usho *b, int len); usho do_hash(usho *b, int len);
usho do_hash_file(const char *filename, const char *type); usho do_hash_file(char *filename);
#endif #endif
+153 -289
View File
@@ -1,6 +1,6 @@
/* /*
* 0xFFFF - Open Free Fiasco Firmware Flasher * 0xFFFF - Open Free Fiasco Firmware Flasher
* Copyright (C) 2007, 2008 pancake <pancake@youterm.com> * Copyright (C) 2007 pancake <pancake@youterm.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -24,40 +24,47 @@
#include <getopt.h> #include <getopt.h>
/* global pr0n */ /* global pr0n */
#if HAVE_USB
#include <usb.h>
struct usb_device *device = NULL; struct usb_device *device = NULL;
struct usb_dev_handle *dev = NULL; struct usb_dev_handle *dev = NULL;
#endif
char *fiasco_image = NULL; char *fiasco_image = NULL;
char *boot_cmdline = NULL; char *boot_cmdline = NULL;
char *reverseto = NULL; char *reverseto = NULL;
char *subverstr = NULL;
int rd_mode = -1; int rd_mode = -1;
int rd_flags = -1; int rd_flags = -1;
int usb_mode = -1; int usb_mode = -1;
int root_device = -1; int root_device = -1;
int verbose = 0; int verbose = 0;
int identify = 0; int identify = 0;
int moboreboot = 0; int reboot = 0;
int unpack = 0; int unpack = 0;
int qmode = 0;
int info = 0; int info = 0;
int nomode = 0;
/* global structs */
char *pieces[] = {
"xloader", // xloader.bin
"2nd", // 2nd
"secondary", // secondary.bin
"kernel", // zImage
"initfs", // jffs'd initfs
"rootfs", // 80mB of blob
"omap-nand", // 8kB of food for the nand
NULL
};
char *modes[]={ char *modes[]={
"host", "host",
"peripheral", "peripheral",
NULL NULL
}; };
char *root_devices[] = { char *root_devices[] = {
"flash", "flash",
"mmc", "mmc",
"usb", "usb",
NULL NULL
}; };
void show_title() void show_title()
{ {
printf("0xFFFF v%s // The Free Fiasco Firmware Flasher\n", VERSION); printf("0xFFFF v%s // The Free Fiasco Firmware Flasher\n", VERSION);
@@ -67,48 +74,30 @@ void show_usage()
{ {
int i; int i;
show_title(); show_title();
printf(" -b [arg] boots the kernel with arguments\n");
#if HAVE_USB printf(" -c console prompt mode\n");
printf ("Over USB:\n" printf(" -C [/dev/mtd] check bad blocks on mtd\n");
" -b [arg] boots the kernel with arguments\n" printf(" -d [vid:pid] injects a usb device into the supported list\n");
" -c console prompt mode\n" printf(" -D [0|1|2] sets the root device to flash (0), mmc (1) or usb (2)\n");
" -d [vid:pid] injects a usb device into the supported list\n" printf(" -e [path] dump and extract pieces to path\n");
" -D [0|1|2] sets the root device to flash (0), mmc (1) or usb (2)\n" printf(" -f <flags> set the given RD flags (see '-f help')\n");
" -f <flags> set the given RD flags (see '-f help')\n" printf(" -F [fiasco] flash a fiasco firmware image\n");
" -i show device information (let standby mode)\n" printf(" -h show this help message\n");
" -l list supported usb device ids\n" printf(" -H [file] calculate hash for file\n");
" -p format piece-of-firmware\n" printf(" -i show device information (let standby mode)\n");
" piece format: [[[[dev:[hw:]]ver:]type:]file[%%layout]\n" printf(" -I [piece] identify a firmware piece\n");
" hw is device HW revision\n" printf(" -l, -L list supported usb device ids\n");
" dev is device name string\n" printf(" -p [[p%%]file] piece-of-firmware %% file-where-this-piece-is\n");
" ver is image version string\n" printf(" -P [new-fiasco] creates a new fiasco package, pieces as arguments\n");
" type is image type\n" printf(" -r [0|1] disable/enable R&D mode\n");
" file is image file name\n" printf(" -R reboot the omap board\n");
" layout is file name for layout file\n" printf(" -s [serial] serial port console (minicom like terminal)\n");
" -r [0|1] disable/enable R&D mode\n" printf(" -u [fiasco] unpack target fiasco image\n");
" -R reboot the omap board\n" printf(" -U [0|1] disable/enable the usb host mode\n");
" -U [0|1] disable/enable the usb host mode\n"); printf(" -v be verbose and noisy\n");
#endif printf(" -V show 0xFFFF version information\n");
#if HAVE_SQUEUE printf(" -x extract configuration entries from /dev/mtd1\n");
printf(" -Q enter shared queues server mode (for gui or remote)\n"); printf("Pieces are: ");
#endif
printf ("Local stuff:\n"
" -s [serial] serial port console (minicom like terminal)\n"
" -h show this help message\n"
" -S [subversion] unpacks/flash pieces matching this sub-version information\n"
" -n do not flash or write to disk (simulation)\n"
" -C [/dev/mtd] check bad blocks on mtd\n"
" -e [path] dump/extract pieces to path\n"
" -F [fiasco] flash a fiasco firmware image\n"
" -H [file] calculate hash for file\n"
" -I [piece] identify a firmware piece\n"
" -P [new-fiasco] creates a new fiasco package, pieces as arguments\n"
" optional argument 'version:<version>'\n"
" -u [fiasco] unpack target fiasco image\n"
" -v be verbose and noisy\n"
" -V show 0xFFFF version information\n"
" -x extract configuration entries from /dev/mtd1\n"
"Pieces are: ");
for(i=0;pieces[i];i++) printf("%s ", pieces[i]); printf("\n"); for(i=0;pieces[i];i++) printf("%s ", pieces[i]); printf("\n");
// serial port support is not yet done (cold flash is for flashing the 8kB nand) // serial port support is not yet done (cold flash is for flashing the 8kB nand)
// TODO: commandline shell prompt for nolo comm // TODO: commandline shell prompt for nolo comm
@@ -116,182 +105,98 @@ void show_usage()
exit(0); exit(0);
} }
int unpack_callback(struct header_t *header)
void unpack_callback(struct header_t *header)
{ {
FILE *fd; FILE *fd = fopen(header->name, "wb");
fiasco_data_read(header);
if (subverstr) {
if (strchr(header->name, ',') != NULL) {
if (!strstr(header->name, subverstr)) {
printf("Skipping '%s' does not matches -S subversion\n",
header->name);
return 1;
}
}
}
if (nomode)
return 1;
printf("Unpacking file: %s\n", header->name);
printf(" type: %s\n", header->type);
if (header->device[0]) printf(" device: %s\n", header->device);
if (header->hwrevs[0]) printf(" hw revisions: %s\n", header->hwrevs);
if (header->version[0]) printf(" version: %s\n", header->version);
if (header->layout) printf(" layout file: %s\n", header->layout);
printf(" size: %d\n", header->size);
printf(" hash: %04x\n", header->hash);
fd = fopen(header->name, "wb");
if (fd == NULL) { if (fd == NULL) {
printf("Cannot open file.\n"); printf("Cannot open file.\n");
return 1; return;
} }
if (fwrite(header->data, header->size, 1, fd) != 1) fiasco_data_read(header);
printf("Writing failed\n"); fwrite(header->data, header->size, 1, fd);
fclose(fd); fclose(fd);
return 0;
}
int flash_callback(struct header_t *header)
{
int ret;
char *type;
ret = unpack_callback(header);
if (ret) {
printf("ignored\n");
return 1;
}
type = header->type;
if (!type[0])
type = (char *)fpid_file(header->name);
printf("\nFlashing %s (%s)\n", header->name, type);
flash_image(header->name, type, header->device, header->hwrevs, header->version);
return 0;
} }
void unpack_fiasco_image(char *file) void unpack_fiasco_image(char *file)
{ {
printf("Dumping firmware pieces to disk.\n"); printf("Dumping firmware pieces to disk.\n");
fiasco_callback = &unpack_callback; fiasco_callback = &unpack_callback;
openfiasco(file, NULL, NULL, NULL, NULL, 0); openfiasco( file );
} }
int fiasco_flash(const char *file) int fiasco_flash(char *file)
{ {
char *p; /* TODO */
char version[64]; fiasco_callback = NULL;
openfiasco( file );
if (connect_via_usb()) { printf("\nTODO: Implement the fiasco flashing here.\n");
fprintf(stderr, "Cannot connect to device. It is possibly not in boot stage.\n");
return 0;
}
// if (info)
cmd_info("");
check_nolo_order();
get_nolo_version();
get_sw_version();
get_hw_revision(version, 44);
if (subverstr == NULL) {
p = strstr(version, "hw_rev:");
if (p) {
subverstr = strdup(p+7);
// TODO: delimit string by comma
printf("SubVersionString autodetected: '%s'\n", subverstr);
}
}
printf("\n");
fiasco_callback = &flash_callback;
openfiasco(file, "xloader", NULL, NULL, NULL, 0);
openfiasco(file, "secondary", NULL, NULL, NULL, 0);
openfiasco(file, "kernel", NULL, NULL, NULL, 0);
openfiasco(file, "initfs", NULL, NULL, NULL, 0);
openfiasco(file, "rootfs", NULL, NULL, NULL, 0);
return 0;
} }
#if HAVE_USB
int connect_via_usb() int connect_via_usb()
{ {
static char pbc[]={'/','-','\\', '|'}; struct usb_device_descriptor udd;
struct usb_device_descriptor udd; struct devices it_device;
struct devices it_device;
int c = 0; int c = 0;
static char pbc[]={'/','-','\\', '|'};
// usb_set_debug(5); // usb_set_debug(5);
usb_init(); usb_init();
/* Tries to get access to the Internet Tablet and retries /* Tries to get access to the Internet Tablet and retries
* if any of the neccessary steps fail. * if any of the neccessary steps fail.
* *
* Note: While a proper device may be found on the bus it may * Note: While a proper device may be found on the bus it may
* not be in the right state to be accessed (e.g. the Nokia is * not be in the right state to be accessed (e.g. the Nokia is
* not in the boot stage any more). * not in the boot stage any more).
*/ */
while(!dev) { while(!dev) {
usleep(0xc350); // 0.5s usleep(0xc350); // 0.5s
if(!usb_device_found(&udd, &it_device)) { if(!usb_device_found(&udd, &it_device)) {
printf("\rWaiting for device... %c", pbc[++c%4]); printf("\rWaiting for device... %c", pbc[++c%4]);
fflush(stdout); fflush(stdout);
continue; continue;
} }
/* open device */ /* open device */
if(!(dev = usb_open(device))) { if(!(dev = usb_open(device))) {
perror("usb_open"); perror("usb_open");
return 1; return 1;
} }
#if 1 if ( usb_claim_interface(dev, 2) < 0) { // 2 or 0
{ D perror("usb_claim_interface");
char name[32];
name[0] = '\0';
usb_get_driver_np(dev, 2, name, sizeof(name));
printf ("Driver: %s\n", name);
usb_detach_kernel_driver_np(dev, 2);
}
#endif
if (usb_claim_interface(dev, 2) < 0) {
//device->config->interface->altsetting->bInterfaceNumber) < 0) { // 2 or 0
perror("usb_claim_interface");
// Something is broken if closing fails. // Something is broken if closing fails.
if(usb_close(dev)) { if(usb_close(dev)) {
perror("usb_close"); perror("usb_close");
return 1; return 1;
} }
dev = NULL;
// Try again later.?
exit(1);
}
if (usb_set_altinterface(dev, 1) <0) { //device->config->interface->altsetting->bAlternateSetting) < 0) { dev = NULL;
perror("usb_set_altinterface");
// Something is broken if closing fails. // Try again later.
if(usb_close(dev)) { continue;
perror("usb_close"); }
return 1;
}
dev = NULL; if (usb_set_altinterface(dev, 1) < 0) {
// Try again later. D perror("usb_set_altinterface");
continue;
}
break;
}
printf("found %s (%04x:%04x)\n", it_device.name, // Something is broken if closing fails.
if(usb_close(dev)) {
perror("usb_close");
return 1;
}
dev = NULL;
// Try again later.
continue;
}
}
printf("found %s (%04x:%04x)\n", it_device.name,
it_device.vendor_id, it_device.product_id); it_device.vendor_id, it_device.product_id);
/* go go go! */ /* go go go! */
@@ -301,98 +206,78 @@ usb_detach_kernel_driver_np(dev, 2);
return 0; return 0;
} }
#endif
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int c; int c;
const char *type;
while((c = getopt(argc, argv, "QC:cp:PvVhRu:ib:U:r:e:ld:I:D:f:F:s:xH:S:n")) != -1) { while((c = getopt(argc, argv, "C:cp:PvVhRu:ib:U:r:e:Lld:I:D:f:F:s:xH:")) != -1) {
switch(c) { switch(c) {
case 'H': case 'H':
printf("xorpair: %04x\n", do_hash_file(optarg, NULL)); printf("xorpair: %04x\n", do_hash_file(optarg));
return 0; return 0;
case 'x': case 'x':
return dump_config(); return dump_config();
#if HAVE_USB
case 'c': case 'c':
return console_prompt(); return console_prompt();
case 'b':
boot_cmdline = optarg;
break;
case 'S':
subverstr = optarg;
break;
case 'n':
nomode = 1;
break;
case 'U':
usb_mode = atoi(optarg);
break;
case 'F': case 'F':
fiasco_image = optarg; return fiasco_flash(optarg);
break;
case 'd': case 'd':
sscanf(optarg, "%04hx:%04hx", sscanf(optarg, "%04hx:%04hx",
&supported_devices[SUPPORTED_DEVICES-2].vendor_id, &supported_devices[SUPPORTED_DEVICES-2].vendor_id,
&supported_devices[SUPPORTED_DEVICES-2].product_id); &supported_devices[SUPPORTED_DEVICES-2].product_id);
supported_devices[SUPPORTED_DEVICES-2].name = strdup("user"); supported_devices[SUPPORTED_DEVICES-2].name = strdup("user");
break; break;
case 'D': case 'D':
root_device = atoi(optarg); root_device = atoi(optarg);
break; break;
case 'f':
if (!strcmp(optarg,"help")) {
printf("* Flags are composed of:\n");
printf(" 0x02 - disable OMAP watchdog (possibly)\n");
printf(" 0x04 - disable RETU watchdog (possibly)\n");
printf(" 0x08 - disable lifeguard reset\n");
printf(" 0x10 - enable serial console\n");
printf(" 0x20 - disable USB timeout\n");
exit(1);
}
rd_flags = (unsigned short) strtoul(optarg, NULL, 16);
break;
case 'r':
rd_mode = atoi(optarg);
break;
case 'l':
list_valid_devices();
return 0;
case 'p':
add_piece(optarg);
break;
case 'i':
info = 1;
break;
case 'R':
moboreboot = 1;
break;
#endif
case 'e': case 'e':
reverseto = optarg; reverseto = optarg;
break; break;
case 's': case 's':
return console(optarg); return console(optarg);
case 'f':
if (!strcmp(optarg,"help")) {
printf("* Flags are composed of:\n");
printf(" 0x02 - disable OMAP watchdog (possibly)\n");
printf(" 0x04 - disable RETU watchdog (possibly)\n");
printf(" 0x08 - disable lifeguard reset\n");
printf(" 0x10 - enable serial console\n");
printf(" 0x20 - disable USB timeout\n");
exit(1);
}
rd_flags = (unsigned short) strtoul(optarg, NULL, 16);
case 'U':
usb_mode = atoi(optarg);
break;
case 'r':
rd_mode = atoi(optarg);
break;
case 'b':
boot_cmdline = optarg;
break;
case 'u': case 'u':
fiasco_image = optarg; fiasco_image = optarg;
unpack = 1; unpack = 1;
break; break;
case 'Q': case 'p':
qmode = 1; add_piece(optarg);
break; break;
case 'P': case 'P':
return fiasco_pack(optind, argv); return fiasco_pack(optind, argv);
case 'L':
case 'l':
list_valid_devices();
return 0;
case 'I': case 'I':
type = fpid_file(optarg); printf("%s: %s\n", fpid_file(optarg), optarg);
printf("%s: %s\n", type, optarg);
if (type && strcmp(type, "fiasco") == 0)
openfiasco(optarg, NULL, NULL, NULL, NULL, 1);
identify = 1; identify = 1;
break; break;
case 'C': case 'C':
return check_badblocks(optarg); return check_badblocks(optarg);
case 'i':
info = 1;
break;
case 'v': case 'v':
verbose = 1; verbose = 1;
break; break;
@@ -402,45 +287,34 @@ int main(int argc, char **argv)
case 'V': case 'V':
printf("%s\n", VERSION); printf("%s\n", VERSION);
return 0; return 0;
case 'R':
reboot = 1;
break;
} }
} }
if (qmode)
return queue_mode();
if (!unpack && fiasco_image)
return fiasco_flash(fiasco_image);
if (identify) if (identify)
return 0; return 0;
// flags ok? // flags ok?
if ( (fiasco_image == NULL) if ( (fiasco_image == NULL)
&& (boot_cmdline == NULL) && (boot_cmdline == NULL)
&& (reverseto == NULL) && (reverseto == NULL)
&& (pcs_n == 0) && (pcs_n == 0)
&& (rd_flags == -1) && (rd_flags == -1)
&& (rd_mode == -1) && (rd_mode == -1)
&& (info == 0) && (info == 0)
&& (moboreboot == 0) && (reboot == 0)
&& (usb_mode == -1) && (usb_mode == -1)
&& (root_device == -1)) && (root_device == -1))
{ {
printf("0xFFFF [-chiLRvVx] [-C mtd-dev] [-d vid:pid] [-D 0|1|2] [-e path] [-f flags]\n");
printf("# The Free Fiasco Firmware Flasher v"VERSION"\n" printf(" [-F fiasco] [-H hash-file] [-I piece] [-p [piece%%]file]] [-r 0|1]\n");
"0xFFFF [-chinlQRvVx] [-C mtd-dev] [-d vid:pid] [-D 0|1|2] [-e path] [-f flags]\n" printf(" [-s serial-dev] [-u fiasco-image] [-U 0|1] | [-P new-fiasco] [piece1] [2] ..\n");
" [-F fiasco] [-H hash-file] [-I piece] [-p [piece%%]file]] [-r 0|1] [-S subver]\n"
" [-s serial-dev] [-u fiasco-image] [-U 0|1] | [-P new-fiasco] [piece1] [2] ..\n");
return 1; return 1;
} }
if (unpack) { if (unpack) {
if (reverseto) {
if (chdir(reverseto) < 0) {
printf("Error: Cannot change directory to %s\n", reverseto);
return 1;
}
}
unpack_fiasco_image(fiasco_image); unpack_fiasco_image(fiasco_image);
return 0; return 0;
} }
@@ -450,41 +324,32 @@ int main(int argc, char **argv)
return 0; return 0;
} }
#if HAVE_USB if (connect_via_usb()) {
if (connect_via_usb()) { fprintf(stderr, "Cannot connect to device. It is possibly not in boot stage.\n");
fprintf(stderr, "Cannot connect to device. It is possibly not in boot stage.\n"); return 0;
return 0; }
}
// if (info) // if (info)
cmd_info(""); cmd_info("");
if (pcs_n) { if (pcs_n) {
char version[64]; int c;
check_nolo_order(); check_nolo_order();
get_sw_version(); get_sw_version();
get_hw_revision(version, 44);
if (subverstr == NULL) {
char *p = strstr(version, "hw_rev:");
if (p) {
subverstr = strdup(p+7);
// TODO: delimit string by comma
printf("SubVersionString autodetected: '%s'\n", subverstr);
}
}
get_nolo_version(); get_nolo_version();
for(c=0;c<pcs_n;c++) { for(c=0;c<pcs_n;c++) {
printf("Flashing %s (%s)\n", pcs[c].type, pcs[c].name); printf("Flashing %s (%s)\n", pcs[c].type, pcs[c].name);
flash_image(pcs[c].name, pcs[c].type, pcs[c].device, pcs[c].hwrevs, pcs[c].version); flash_image(pcs[c].name, pcs[c].type, pcs[c].vers);
} }
} }
if (rd_mode != -1) if (rd_mode != -1)
set_rd_mode(rd_mode); set_rd_mode(rd_mode);
if (rd_flags != -1) if (rd_flags != -1)
set_rd_flags(rd_flags); set_rd_flags(rd_flags);
if (root_device != -1) if (root_device != -1)
set_root_device(root_device); set_root_device(root_device);
@@ -495,9 +360,8 @@ int main(int argc, char **argv)
if (boot_cmdline) if (boot_cmdline)
boot_board(boot_cmdline); boot_board(boot_cmdline);
if (moboreboot) if (reboot)
reboot_board(); reboot_board();
#endif
return 0; return 0;
} }
+22 -58
View File
@@ -2,38 +2,24 @@
#ifndef _INCLUDE_MAIN_H_ #ifndef _INCLUDE_MAIN_H_
#define _INCLUDE_MAIN_H_ #define _INCLUDE_MAIN_H_
#include "hash.h"
#include "nolo.h"
#include "os.h"
extern char strbuf[1024];
#define _FILE_OFFSET_BITS 64 #define _FILE_OFFSET_BITS 64
#define _GNU_SOURCE #define _GNU_SOURCE
// Forward declaration for use in function arguments. // Forward declaration for use in function arguments.
struct devices; struct devices;
int queue_mode();
int reverse_extract_pieces(char *dir); int reverse_extract_pieces(char *dir);
void flash_image(const char *filename, const char *piece, const char *device, const char *hwrevs, const char *version); void flash_image(char *filename, char *piece, char *version);
int fiasco_read_image(char *file); int fiasco_read_image(char *file);
void check_nolo_order(); void check_nolo_order();
extern struct usb_dev_handle *dev; extern struct usb_dev_handle *dev;
unsigned long get_file_size(const char *file); unsigned long get_file_size(char *file);
void progressbar(unsigned long long part, unsigned long long total); void progressbar(unsigned long long part, unsigned long long total);
const char *fpid_file(const char *filename); const char *fpid_file(const char *filename);
int add_piece(char *piece); int add_piece(char *piece);
void eprintf(const char *format, ...);
#include <limits.h>
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
#if HAVE_USB
#include <usb.h> #include <usb.h>
int fiasco_flash(const char *file);
extern struct usb_device *device; extern struct usb_device *device;
extern struct usb_dev_handle *dev; extern struct usb_dev_handle *dev;
int is_valid_device(struct usb_device_descriptor *udd); int is_valid_device(struct usb_device_descriptor *udd);
@@ -41,8 +27,6 @@ void list_valid_devices();
int usb_device_found(struct usb_device_descriptor *udd, struct devices *it_device); int usb_device_found(struct usb_device_descriptor *udd, struct devices *it_device);
int console(const char *device); int console(const char *device);
int connect_via_usb(); int connect_via_usb();
#endif
int console_prompt(); int console_prompt();
// //
@@ -56,29 +40,24 @@ extern int verbose;
#define CMD_WRITE 64 #define CMD_WRITE 64
#define CMD_QUERY 192 #define CMD_QUERY 192
#define NOLO_GET_STATUS 1
#define NOLO_GET_BOARD_ID 2
#define NOLO_GET_VERSION 3
struct piece_t { struct piece_t {
char *name; char *name;
char *type; char *type;
char *device; char *vers;
char *hwrevs;
char *version;
};
enum flash_mode {
FLASH_COLD,
FLASH_NORMAL,
FLASH_MKII,
FLASH_DISK,
}; };
struct devices { struct devices {
char *name; char *name;
unsigned short vendor_id; unsigned short vendor_id;
unsigned short product_id; unsigned short product_id;
enum flash_mode mode; unsigned short flags;
}; };
#define SUPPORTED_DEVICES 10 #define SUPPORTED_DEVICES 6
extern struct devices supported_devices[SUPPORTED_DEVICES]; extern struct devices supported_devices[SUPPORTED_DEVICES];
extern int pcs_n; extern int pcs_n;
@@ -92,45 +71,30 @@ enum {
PIECE_INITFS, PIECE_INITFS,
PIECE_ROOTFS, PIECE_ROOTFS,
PIECE_OMAPNAND, PIECE_OMAPNAND,
PIECE_MMC,
PIECE_CMT_2ND,
PIECE_CMT_ALGO,
PIECE_CMT_MCUSW,
PIECE_FIASCO,
PIECE_LAST PIECE_LAST
}; };
struct header_t {
int fd;
char swver[128];
char type[128];
char device[16];
char hwrevs[128];
char version[128];
unsigned short hash;
unsigned int size;
unsigned char *data;
char *name;
char *layout;
};
extern char *pieces[]; extern char *pieces[];
extern char *modes[]; extern char *modes[];
extern char *root_devices[]; extern char *root_devices[];
// fiasco // fiasco
int openfiasco(const char *name, const char *type, const char *device, const char *hwrev, const char *version, int v); int openfiasco(char *name);
int fiasco_new(const char *filename, const char *name); int fiasco_new(const char *filename, const char *name);
void fiasco_data_read(struct header_t *header); void fiasco_data_read(struct header_t *header);
extern int (*fiasco_callback)(struct header_t *header); int fiasco_add_eof(int fd);
int fiasco_add(int fd, const char *name, const char *file, const char *layout, const char *device, const char *hwrevs, const char *version); extern void (*fiasco_callback)(struct header_t *header);
int fiasco_add(int fd, const char *name, const char *file, const char *version);
int fiasco_pack(int optind, char *argv[]); int fiasco_pack(int optind, char *argv[]);
int nanddump(char *mtddev, unsigned long start_addr, unsigned long length, char *dumpfile, int isbl, int ioob); struct header_t {
int fd;
char fwname[128];
char name[128];
char version[128];
unsigned short hash;
unsigned int size;
unsigned char *data;
};
//
int reboot_board();
int get_rd_flags();
int get_usb_mode();
int get_nolo_version();
#endif #endif
-7
View File
@@ -1,7 +0,0 @@
#define NOLO_GET_STATUS 1
#define NOLO_GET_BOARD_ID 2
#define NOLO_GET_VERSION 3
#define NOLO_GET_HWVERSION 4
#define NOLO_SET_RDFLAGS 16
#define NOLO_GET_RDFLAGS 17
-19
View File
@@ -1,19 +0,0 @@
#ifndef _OS_H_
#define _OS_H_
#if __linux__ || __NetBSD__ || __FreBSD__ || __OpenBSD__ || __Darwin__ || __MacOSX__
#define HAVE_SQUEUE 1
#else
#define HAVE_SQUEUE 0
#endif
#if HAVE_SQUEUE
#include "squeue/squeue.h"
extern int qmode;
extern struct squeue_t *p;
#endif
#endif
+3 -7
View File
@@ -52,12 +52,10 @@ int add_piece(char *piece)
pcs[pcs_n].name = strdup(file); pcs[pcs_n].name = strdup(file);
pcs[pcs_n].type = strdup(piece); pcs[pcs_n].type = strdup(piece);
pcs[pcs_n].device = NULL; pcs[pcs_n].vers = NULL; // TODO version string not yet supported
pcs[pcs_n].hwrevs = NULL;
pcs[pcs_n].version = NULL; // TODO version string not yet supported
} else { } else {
/*/ autodetect piece type */ /*/ autodetect piece type */
pcs[pcs_n].type = (char *)fpid_file(piece); pcs[pcs_n].type = fpid_file(piece);
if (pcs[pcs_n].type == NULL) { if (pcs[pcs_n].type == NULL) {
printf("Use -p [piece]:[file]\n"); printf("Use -p [piece]:[file]\n");
printf("Pieces: "); printf("Pieces: ");
@@ -68,9 +66,7 @@ int add_piece(char *piece)
} else { } else {
pcs[pcs_n].name = strdup(piece); pcs[pcs_n].name = strdup(piece);
pcs[pcs_n].type = strdup(pcs[pcs_n].type); pcs[pcs_n].type = strdup(pcs[pcs_n].type);
pcs[pcs_n].device = NULL; pcs[pcs_n].vers = NULL;
pcs[pcs_n].hwrevs = NULL;
pcs[pcs_n].version = NULL;
} }
} }
-146
View File
@@ -1,146 +0,0 @@
/*
* 0xFFFF - Open Free Fiasco Firmware Flasher
* Copyright (C) 2008 pancake <pancake@youterm.com>
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "main.h"
#include "os.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#if HAVE_SQUEUE
struct squeue_t *q;
struct squeue_t *p;
int fork_enabled = 0;
int dofork()
{
if (fork_enabled)
return fork();
return 0;
}
void process_message(char *msg)
{
char *str;
char *arg;
int c=1;
if (msg == NULL)
return;
printf("[x] (%s)\n", msg);
str = strdup(msg);
arg = strchr(str, ':');
if (c!=0) {
arg[0]='\0';
arg = arg +1;
if (!strcmp(str, "flash")) {
const char *type = fpid_file(arg);
if (type == NULL) {
squeue_push2(p, "error", "Unknown piece format", 1);
} else flash_image(arg, type, NULL, NULL, NULL);
} else
if (!strcmp(str, "reset")) {
if (reboot_board() == 0) {
squeue_push2(p,"info", "Device reboots", 1);
} else squeue_push2(p,"error", "Cannot reboot device", 1);
} else
if (!strcmp(str, "info")) {
get_rd_flags();
squeue_push2(p, "info", strbuf, 1);
get_nolo_version();
squeue_push2(p, "info", strbuf, 1);
get_usb_mode();
squeue_push2(p, "info", strbuf, 1);
} else
squeue_push2(p, "error", "invalid command", 0);
} else {
squeue_push2(p, "error", "invalid command format", 0);
}
free(str);
}
static void cc()
{
squeue_close(p);
squeue_close(q);
printf("pipes closed\n");
squeue_release("/tmp/0xFFFF.1");
squeue_release("/tmp/0xFFFF.2");
exit(1);
}
int queue_mode()
{
int pid = 0;
char *msg;
signal(SIGINT, cc);
pid = dofork();
if (pid) {
wait(&pid);
return 0;
} else {
p = squeue_open("/tmp/0xFFFF.1", Q_CREAT);
q = squeue_open("/tmp/0xFFFF.2", Q_CREAT);
if (p == NULL || q == NULL) {
fprintf(stderr, "Cannot open queue files\n");
return 0;
}
chmod("/tmp/0xFFFF.1", 0666);
chmod("/tmp/0xFFFF.2", 0666);
pid = dofork();
if (pid) {
printf( "Entering into shared queue server mode.\n"
"Type $ kill -9 %d # to stop\n"
"NOTE: Manually remove the /tmp/.0xFFFF.* files to solve perm problems\n", pid);
} else {
do {
#if HAVE_USB
if (connect_via_usb()) {
fprintf(stderr, "Cannot connect to device. It is possibly not in boot stage.\n");
squeue_push2(p, "error", "Cannot connect to the device", 1);
return 0;
}
#endif
printf("Waiting for a client in shared queues..\n");
setsid();
while(1) {
msg = squeue_get(q, 1);
if (msg) {
process_message(msg);
squeue_pop(q);
}
}
printf("Connection restarted\n");
} while (1);
}
}
return 0;
}
#else
int queue_mode()
{
/* dummy */
fprintf(stderr, "No HAVE_SQUEUE support\n");
}
#endif
+32 -56
View File
@@ -1,6 +1,6 @@
/* /*
* 0xFFFF - Open Free Fiasco Firmware Flasher * 0xFFFF - Open Free Fiasco Firmware Flasher
* Copyright (C) 2007-2009 pancake <@youterm.com> * Copyright (C) 2007 pancake <pancake@youterm.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -16,16 +16,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#if HAVE_USB
#include "main.h" #include "main.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <usb.h> #include <usb.h>
char strbuf[1024];
/* wait for status = 0 */ /* wait for status = 0 */
int get_status() int get_status()
{ {
@@ -46,7 +42,8 @@ int get_status()
*/ */
int set_usb_mode(unsigned int mode) int set_usb_mode(unsigned int mode)
{ {
if (mode > 1) { if (mode > 1)
{
printf("Invalid USB mode specified '%d'.\n", mode); printf("Invalid USB mode specified '%d'.\n", mode);
return -1; return -1;
} }
@@ -77,8 +74,7 @@ int get_usb_mode()
return -1; return -1;
} }
sprintf(strbuf, "Device's USB mode is '%s'\n", (mode) ? "host" : "client"); printf("Device's USB mode is '%s'\n", (mode) ? "host" : "client");
printf("%s", strbuf);
return 0; return 0;
} }
@@ -120,7 +116,7 @@ int set_rd_mode(unsigned short mode)
if (((short)mode)==-1) if (((short)mode)==-1)
return 1; return 1;
if (usb_control_msg(dev, CMD_WRITE, NOLO_SET_RDFLAGS, mode, 0, 0, 0, 2000) == -1) { if (usb_control_msg(dev, CMD_WRITE, 16, mode, 0, 0, 0, 2000) == -1) {
fprintf(stderr, "Cannot set R&D flags.\n"); fprintf(stderr, "Cannot set R&D flags.\n");
return 1; return 1;
} }
@@ -133,28 +129,26 @@ int set_rd_mode(unsigned short mode)
/* /*
* query root device * query root device
*/ */
int get_hw_revision(char *str, int len) int get_hw_revision()
{ {
unsigned char string[512]; unsigned char string[512];
char tmpstr[64]; int i = 0;
int i = 0, j=0, mod=0;
if (str == NULL) if (usb_control_msg(dev, CMD_QUERY, 4, 0, 0, (char *)string, 512, 2000) == -1) {
str = tmpstr;
memset(string,'\0',512);
if (usb_control_msg(dev, CMD_QUERY, NOLO_GET_HWVERSION, 0, 0, (char *)string, 512, 2000) == -1) {
fprintf(stderr, "Cannot query hw revision.\n"); fprintf(stderr, "Cannot query hw revision.\n");
return -1; return -1;
} }
for(i=0;i<44&&i<len;i++) { // XXX ?? printf("HW revision string: '");
if (string[i]>19) { for(i=0;i<44;i++) { // XXX ??
if (i>0 && string[i-1]<19) if (string[i]==0) {
str[j++] = (++mod%2)?':':','; printf(" ");
str[j++] = string[i]; } else {
if (string[i]>19)
printf("%c", string[i]);
} }
} }
printf("HW revision string: '%s'\n", str); printf("'\n");
return 0; return 0;
} }
@@ -163,12 +157,11 @@ int get_rd_mode()
{ {
char isrd = 1; char isrd = 1;
strbuf[0]='\0'; if (usb_control_msg(dev, CMD_QUERY, 17, 0, 0, (char *)&isrd, 1, 2000) == -1) {
if (usb_control_msg(dev, CMD_QUERY, NOLO_GET_RDFLAGS, 0, 0, (char *)&isrd, 1, 2000) == -1) {
fprintf(stderr, "Cannot query rd mode.\n"); fprintf(stderr, "Cannot query rd mode.\n");
return -1; return -1;
} }
sprintf(strbuf, "RD mode is: %s\n", isrd?"on":"off"); printf("RD mode is: %s\n", isrd?"on":"off");
return isrd; return isrd;
} }
@@ -177,14 +170,13 @@ int get_root_device()
{ {
unsigned char opcode; unsigned char opcode;
if (usb_control_msg(dev, CMD_QUERY, NOLO_GET_RDFLAGS, 0, 1, (char *)&opcode, 1, 2000) < 0) { if (usb_control_msg(dev, CMD_QUERY, 17, 0, 1, (char *)&opcode, 1, 2000) < 0) {
fprintf(stderr, "Cannot query root device\n"); fprintf(stderr, "Cannot query root device\n");
return -1; return -1;
} }
if (opcode>2) { // use sizeof || enum if (opcode>2) { // use sizeof || enum
fprintf(stderr, "Invalid root device received from the device '%d'.\n", opcode); printf("Invalid root device received from the device '%d'.\n", opcode);
return -1;
} }
printf("Root device is: %s\n", root_devices[opcode]); printf("Root device is: %s\n", root_devices[opcode]);
@@ -205,7 +197,7 @@ int set_root_device(unsigned short root_device)
return -1; return -1;
} }
if (usb_control_msg(dev, CMD_WRITE, NOLO_SET_RDFLAGS, root_device, 1, 0, 0, 2000) == -1) { if (usb_control_msg(dev, CMD_WRITE, 16, root_device, 1, 0, 0, 2000) == -1) {
fprintf(stderr, "Cannot set root device\n"); fprintf(stderr, "Cannot set root device\n");
return -1; return -1;
} }
@@ -289,25 +281,17 @@ int get_rd_flags()
{ {
unsigned short flags = 0; unsigned short flags = 0;
if (usb_control_msg (dev, CMD_QUERY, NOLO_GET_RDFLAGS, 0, 3, (void *) &flags,sizeof(flags), 2000) == -1) { if (usb_control_msg(dev, CMD_QUERY, 17, 0, 3, (void *) &flags, sizeof(flags), 2000) == -1) {
fprintf(stderr, "Cannot get rd flags\n"); fprintf(stderr, "Cannot get rd flags\n");
sprintf(strbuf, "error: Cannot read rd flags\n");
return -1; return -1;
} }
sprintf (strbuf, printf("Current rd flag setting:\n");
"Current rd flag setting:\n" printf("disable OMAP watchdog : %s\n", (flags & 0x02) ? "set" : "not set");
"disable OMAP watchdog : %s\n" printf("disable RETU watchdog : %s\n", (flags & 0x04) ? "set" : "not set");
"disable RETU watchdog : %s\n" printf("disable lifeguard reset: %s\n", (flags & 0x08) ? "set" : "not set");
"disable lifeguard reset: %s\n" printf("enable serial console : %s\n", (flags & 0x10) ? "set" : "not set");
"enable serial console : %s\n" printf("disable USB timeout : %s\n", (flags & 0x20) ? "set" : "not set");
"disable USB timeout : %s\n"
, (flags & 0x02) ? "set" : "not set"
, (flags & 0x04) ? "set" : "not set"
, (flags & 0x08) ? "set" : "not set"
, (flags & 0x10) ? "set" : "not set"
, (flags & 0x20) ? "set" : "not set");
puts (strbuf);
return 0; return 0;
} }
@@ -317,14 +301,12 @@ int get_nolo_version()
unsigned int version; // ensure uint is at least 32 bits unsigned int version; // ensure uint is at least 32 bits
//if (usb_control_msg(dev, CMD_QUERY, 3, 0, 1, (char *)&version, 4 , 2000) < 0) { //if (usb_control_msg(dev, CMD_QUERY, 3, 0, 1, (char *)&version, 4 , 2000) < 0) {
if (usb_control_msg(dev, CMD_QUERY, NOLO_GET_VERSION, 0, 0, (char *)&version, 4 , 2000) < 0) { if (usb_control_msg(dev, CMD_QUERY, 3, 0, 0, (char *)&version, 4 , 2000) < 0) {
fprintf(stderr, "Cannot query nolo version. Old bootloader version?\n"); fprintf(stderr, "Cannot query nolo version. Old bootloader version?\n");
sprintf(strbuf, "error: Cannot query nolo version. Old bootloader?"); exit(1);
return -1;
} }
sprintf(strbuf, printf("NOLO Version %d.%d.%d\n",
"NOLO Version %d.%d.%d\n",
version >> 20 & 15, version >> 20 & 15,
version >> 16 & 15, version >> 16 & 15,
version >> 8 & 255); version >> 8 & 255);
@@ -346,18 +328,12 @@ int get_sw_version()
fprintf(stderr, "error: cannot write query 18\n"); fprintf(stderr, "error: cannot write query 18\n");
return 0; return 0;
} }
bytes[0]='\0';
ret = usb_control_msg(dev, CMD_QUERY, 20, 0, 0, (char *)&bytes, 512, 2000); ret = usb_control_msg(dev, CMD_QUERY, 20, 0, 0, (char *)&bytes, 512, 2000);
if (ret<0) { if (ret<0) {
fprintf(stderr, "error: b0rken swversion read!\n"); fprintf(stderr, "error: b0rken swversion read!\n");
return 0; return 0;
} }
if (bytes[0]) { printf("SWVERSION GOT: %s\n", bytes); //???+strlen(bytes)+1));
sprintf(strbuf, "Software Version: %s\n", bytes);
printf("Software Version: %s\n", bytes); //???+strlen(bytes)+1));
} else printf("No software version detected\n");
return 1; return 1;
} }
#endif
+1 -1
View File
@@ -16,7 +16,7 @@ int set_rd_mode(unsigned short mode);
int get_rd_flags(); int get_rd_flags();
int set_rd_flags(unsigned short flags); int set_rd_flags(unsigned short flags);
int get_hw_revision(char *str, int len); int get_hw_revision();
int get_root_device(); int get_root_device();
int set_root_device(unsigned short); int set_root_device(unsigned short);
-294
View File
@@ -1,294 +0,0 @@
#include "squeue.h"
#define _XOPEN_SOURCE 500 /* Or: #define _BSD_SOURCE */
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <signal.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#define POOL_SIZE ITEM_MAX*ITEM_SIZE
#define ITEM_SIZE 512
#define ITEM_MAX 10
int squeue_release(const char *file)
{
int shmid;
key_t k = ftok(file, 0xa3);
if (k == -1) {
perror("ftok");
return -1;
}
shmid = shmget(k, POOL_SIZE, 0666);
if (shmid == -1)
return -1; // not released
return shmctl(shmid, IPC_RMID,NULL);
}
extern int errno;
struct squeue_t *squeue_open(const char *file, int mode)
{
struct squeue_t *q;
char *pool;
int shmid;
key_t k;
k = ftok(file, 0x34);
if (k == -1) {
perror("ftok");
squeue_release(file);
close(creat(file, 0666));
chmod(file, 0666);
k = ftok(file, 0xa3);
if (k == -1) {
perror("ftok");
return NULL;
}
}
_retry:
shmid = shmget(k, POOL_SIZE, 0666|(mode==Q_CREAT)?IPC_CREAT:0);
if (shmid == -1) {
perror("shmget1");
shmid = shmget(k, POOL_SIZE, 0666|((mode==Q_CREAT)?IPC_CREAT:0));
if (shmid == -1) {
perror("shmget2");
if (errno == EEXIST)
shmid = shmget(k, POOL_SIZE, 0666 |IPC_CREAT);
if (shmid == -1) {
if (mode == Q_WAIT) {
usleep(100);
goto _retry;
}
perror("shmget");
return NULL;
}
}
}
if (mode == Q_WAIT)
mode = Q_OPEN;
/* fix perms */
if (mode == Q_CREAT) {
struct shmid_ds sd;
shmctl(shmid, IPC_STAT, &sd);
sd.shm_perm.uid = 1000;
sd.shm_perm.gid = 1000;
sd.shm_perm.mode = sd.shm_perm.mode|0666;
shmctl(shmid, IPC_SET, &sd);
}
pool = shmat(shmid, NULL, 0);
if (pool == (void *)-1) {
perror("shmat");
return NULL;
}
if (mode == Q_CREAT)
memset(pool, '\0', POOL_SIZE);
q = (struct squeue_t *)malloc(sizeof(struct squeue_t));
memset(q, '\0', sizeof(struct squeue_t));
q->shmid = shmid;
q->pool = pool;
q->mode = mode;
return q;
}
void squeue_free(struct squeue_t *q)
{
free(q);
}
int squeue_close(struct squeue_t *q)
{
char *pool;
if (q==NULL)
return -1;
pool = q->pool;
shmctl(q->shmid, IPC_RMID, NULL);
free(q);
return shmdt(pool);
}
int squeue_push(struct squeue_t *q, const char *str, int lock)
{
int i;
if (q==NULL)
return -1;
// if (q->mode == Q_CREAT) {
// printf("squeue_push: cannot push from the creator\n");
// return -1;
// }
if (str==NULL||strlen(str)>ITEM_SIZE)
return -1;
do {
if (q->squeue_idx >= ITEM_MAX) {
while (q->pool[0]!='\0') {
q->squeue_locks++;
if (!lock) {
printf("buffer is full\n");
return -1;
}
usleep(100);
}
q->squeue_idx = 0;
}
for(i=q->squeue_idx*ITEM_SIZE;i<POOL_SIZE;i+=ITEM_SIZE) {
if (q->pool[i]=='\0') {
strcpy(q->pool+i, str);
q->squeue_idx++;
return 1;
}
}
q->squeue_locks++;
} while (lock);
q->squeue_lost++;
return 0;
}
int squeue_push2(struct squeue_t *q, const char *head, const char *str, int lock)
{
int ret;
char *buf = malloc(strlen(head) + strlen(str) + 2);
strcpy(buf, head);
strcat(buf, ":");
strcat(buf, str);
ret = squeue_push(q, buf, lock);
free(buf);
return ret;
}
int squeue_pop(struct squeue_t *q)
{
int i;
int two = 1;
if (q==NULL)
return -1;
// if (q->mode == Q_OPEN) { // cannot pop when not owner of squeue
// fprintf(stderr, "squeue_pop: cannot pop when you are not owner.\n");
// return -1;
// }
for(two=1;two--;q->head_idx = 0)
for(i=q->head_idx*ITEM_SIZE;i<POOL_SIZE;i+=ITEM_SIZE) {
if (q->pool[i]!='\0') {
q->pool[i]='\0';
q->head_idx++;
q->squeue_pops++;
return 1;
}
}
q->squeue_oops++;
fprintf(stderr, "WARNING: race condition detected in squeue.\n");
return 0;
}
char *squeue_get(struct squeue_t *q, int lock)
{
int i=0;
int two = 1;
if(q==NULL)
return NULL;
// if (q->mode == Q_OPEN) { // cannot pop when not owner of squeue
// fprintf(stderr, "squeue_get: cannot pop when you are not owner.\n");
// return NULL;
// }
do {
for(two=1;two--;q->head_idx = 0) {
for(i=q->head_idx*ITEM_SIZE;i<POOL_SIZE;i+=ITEM_SIZE)
if (q->pool[i]!='\0')
return q->pool+i;
}
if (lock)
usleep(100);
} while (lock);
return NULL;
}
void squeue_stats(struct squeue_t *q)
{
if(q==NULL)
return;
printf("Queue locks: %d\n", q->squeue_locks);
printf("Queue lost: %d\n", q->squeue_lost);
printf("Queue oops: %d\n", q->squeue_oops);
printf("Queue pops: %d\n", q->squeue_pops);
}
#if _MAIN_
struct squeue_t *q;
int sigc()
{
squeue_stats(q);
exit(1);
}
int main()
{
char buf[102];
int i;
int pid;
signal(SIGINT, sigc);
squeue_release("/dev/null");
pid = fork();
if (pid) {
q = squeue_open("/dev/null", Q_CREAT);
if (q == NULL) {
perror("oops");
kill(pid, SIGINT);
return;
}
squeue_push(q, "Hello World", 0);
squeue_push(q, "jeje msg 2", 0);
while(1) {
char *uh = squeue_get(q,1);
if (uh) {
printf("get: (%s)\n", uh);
squeue_pop(q);
}
usleep(100);
}
squeue_close(q);
} else {
q = squeue_open("/dev/null", Q_WAIT);
if (q == NULL) {
perror("oops");
return;
}
for(i=0;i<128;i++) {
sprintf(buf, "puta%d", i);
squeue_push(q, buf, 1);
usleep(100);
}
squeue_stats(q);
printf("cya\n");
squeue_close(q);
}
return 0;
}
#endif
-28
View File
@@ -1,28 +0,0 @@
struct squeue_t {
int shmid;
int mode;
char *pool;
/* pointers */
int head_idx;
int squeue_idx;
/* counters */
int squeue_locks;
int squeue_lost;
int squeue_oops;
int squeue_pops;
};
#define Q_OPEN 0
#define Q_CREAT 1
#define Q_WAIT 2
int squeue_release(const char *file);
struct squeue_t *squeue_open(const char *file, int init);
int squeue_close(struct squeue_t *q);
void squeue_free(struct squeue_t *q);
int squeue_push(struct squeue_t *q, const char *str, int lock);
int squeue_push2(struct squeue_t *q, const char *head, const char *str, int lock);
int squeue_pop(struct squeue_t *q);
char *squeue_get(struct squeue_t *q, int lock);
void squeue_stats(struct squeue_t *q);
-45
View File
@@ -1,45 +0,0 @@
using GLib;
[CCode (lower_case_cprefix = "squeue_", cheader_filename = "squeue.h")]
namespace SQueues {
[CCode (cname = "struct squeue_t", free_function = "squeue_free")]
public struct SQueue {
int shmid;
int mode;
char *pool;
/* pointers */
int head_idx;
int queue_idx;
/* counters */
int locks;
int lost;
int oops;
int pops;
[CCode (cname = "squeue_open")]
public static SQueue* open(string file, int mode);
[CCode (cname = "squeue_push")]
public int push(string msg, int l);
[CCode (cname = "squeue_push2")]
public int push2(string cmd, string msg, int l);
[CCode (cname = "squeue_get")]
public unowned string get(int l);
[CCode (cname = "squeue_pop")]
public int pop();
[CCode (cname = "squeue_stats")]
public int stats();
[CCode (cname = "squeue_close")]
public int close();
[CCode (cname = "squeue_free")]
public int free();
[CCode (cname = "squeue_release")]
public static int release(string file);
}
[CCode (cprefix = "Q_", cheader_fileneme = "squeue.h")]
public enum SQueueMode {
OPEN = 0,
CREAT = 1,
WAIT = 2
}
}
+11 -32
View File
@@ -17,12 +17,12 @@
*/ */
#include "main.h" #include "main.h"
#include <usb.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
unsigned long get_file_size(const char *file) unsigned long get_file_size(char *file)
{ {
FILE *fd = fopen(file, "r"); FILE *fd = fopen(file, "r");
unsigned long len = 0; unsigned long len = 0;
@@ -42,35 +42,14 @@ void progressbar(unsigned long long part, unsigned long long total)
int pc; int pc;
int tmp, cols = 80; int tmp, cols = 80;
/* percentage calculation */
pc = (int)(part*100/total); pc = (int)(part*100/total);
(pc<0)?pc=0:(pc>100)?pc=100:0; (pc<0)?pc=0:(pc>100)?pc=100:0;
printf("\e[K %3d%% [", pc);
#if HAVE_SQUEUE if (columns)
if (qmode) { cols = atoi(columns);
char msg[128]; cols-=15;
sprintf(msg, "%d%%", pc); for(tmp=cols*pc/100;tmp;tmp--) printf("#");
squeue_push2(p, "bar", msg, 0); for(tmp=cols-(cols*pc/100);tmp;tmp--) printf("-");
} else { printf("]\r");
#endif fflush(stdout);
printf("\x1b[K %3d%% [", pc);
if (columns)
cols = atoi(columns);
cols-=15;
for(tmp=cols*pc/100;tmp;tmp--) printf("#");
for(tmp=cols-(cols*pc/100);tmp;tmp--) printf("-");
printf("]\r");
fflush(stdout);
#if HAVE_SQUEUE
}
#endif
}
void eprintf(const char *format, ...)
{
va_list ap;
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
//fflush(stderr); // XXX CRASH?!? stdin here?!?!?
} }