7 Commits
Author SHA1 Message Date
pancake 3a1053b29e * Oops missing up
* Added fixups for make install/deinstall
* HAVE_GUI is now enabled by default
* New 'stop' button for goxf GUI
* Fix lil bug in squeue.c
* Initial .desktop icon for freedesktop environments (GNOME)
2008-12-14 03:05:19 +01:00
pancake fc3a613276 * Minor stetical fixups
* Cut 0.4 release :)
2008-12-14 01:40:49 +01:00
pancake 5a96158322 * Implement and test direct file FIASCO flash - openfiasco receives options for grepping for pieces and be verbose - fixed flashing order using grep options xloader, secondary, kernel, initfs, rootfs - Tested and working - Added parser for the hw revision string
* Autodetect device hw revision and setup the subversion string
  on the fly.
2008-12-08 18:13:36 +01:00
pancake 3d427bfd77 * Added -n flag to do not write to disk or flash (simulation)
* Added -S flag to specify subversion id manually while flashing or dumping
* Fixed support for the last fiasco image
  - Skip paddings
  - More verbose output while parsing FIASCO headers
* Initial implementation of the full direct FIASCO flasher
  - No need to dump manually before flashing
* Some warnings and code cleanup
* Fix building issue
* Add HAVE_GUI directive in config.mk
* Up to version 0.4
2008-12-08 00:21:05 +01:00
pancake edac98d26e * Shift doc/faq to doc/faq2
* Add 'doc/faq' with most used commands
* -e can be used with -u to specify the path to extract the files
* Remove gui directory
  - GUI source is in src/gui
  - Incrusted inside the build and install targets
    (ignores build and install errors)
2008-03-07 00:20:45 +01:00
pancake 83c25d7eb2 * Initial working version of the flash gui - Renamed to goxf - Needs 'sudo' to be enabled to the user without password - Identify and ban piece files while including them in the list - Support for flashing multiple piece files - progressbar and warn/error messages handled - Supports reboot mobo command
* Make qmode be functional
* Lot of hardcore fixups on squeue_open
  - Should work now everywhere fine asumid UID 1000 as allowed user
  - Reduce timeouts
  - Add push2 method
2008-03-06 17:58:06 +01:00
pancake 2ddb2923c6 * Initial import of the GtkAML gui frontend - Mostly implemented in just one night :)
* Import the squeue c and vapi sources
* Make 0xFFFF run as squeue daemon with -Q flag
* Up to 0.4
2008-03-05 18:38:42 +01:00
29 changed files with 1372 additions and 577 deletions

No files matched your search

+9
View File
@@ -0,0 +1,9 @@
[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;
+16 -5
View File
@@ -1,12 +1,17 @@
include config.mk include config.mk
PREFIX?=/usr/local PREFIX?=/usr/local
DESTDIR?=
all: logot all: logot frontend
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
@@ -20,9 +25,15 @@ clean:
cd logotool && ${MAKE} clean cd logotool && ${MAKE} clean
install: install:
cp src/0xFFFF ${PREFIX}/bin mkdir -p ${DESTDIR}${PREFIX}/bin
cp logotool/logotool ${PREFIX}/bin mkdir -p ${DESTDIR}${PREFIX}/share/applications/
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/
deinstall: deinstall:
rm -f ${PREFIX}/bin/0xFFFF rm -f ${DESTDIR}${PREFIX}/bin/0xFFFF
rm -f ${PREFIX}/bin/logotool rm -f ${DESTDIR}${PREFIX}/bin/logotool
rm -f ${DESTDIR}${PREFIX}/bin/goxf
rm ${DESTDIR}${PREFIX}/share/applications/0xFFFF.desktop
+9 -2
View File
@@ -27,8 +27,15 @@ 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
+4 -2
View File
@@ -1,8 +1,10 @@
VERSION=0.3.2 VERSION=0.4.0
PREFIX=/usr PREFIX=/usr
# NetBSD stuff # NetBSD stuff
CFLAGS+=-I/usr/pkg/include CFLAGS+=-I/usr/pkg/include -O2
LDFLAGS+=-L/usr/pkg/lib -Wl,-R/usr/pkg/lib LDFLAGS+=-L/usr/pkg/lib -Wl,-R/usr/pkg/lib
HAVE_USB=1 HAVE_USB=1
HAVE_GUI=1
+29 -59
View File
@@ -1,79 +1,49 @@
<b>FAQ</b> <h2>FAQ</h2>
This file tries to collect a bunch of common questions/answers about flashing <b>*) How can I set my Internet Tablet into RD mode with 0xFFFF?</b>
<b>*) Why implement a free software flasher?</b> Just type '0xFFFF -r 1' as root
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> <b>*) How can I unpack a FIASCO firmware?
Of course! You're free to do what you want with your device :) Just type '0xFFFF -r 1' as root
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> <b>*) How can I unpack a FIASCO firmware?</b>
Actually 0xFFFF allows you to: Just type '0xFFFF -u FiascoFirmware.bin -e /tmp' as root
- 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> <b>*) How can I flash a new rootfs?
NOLO is the 'server-side' part of the flasher from Nokia. NOLO means Unpack the pieces from the fiasco firmware (the one distributed by Nokia for example) and then type:
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 # 0xFFFF -R -p rootfs.jffs
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 identify my device?</b> <b>*) How can I flash a full FIASCO image?</b>
Theorically n770 and n800 have different USB device ID, but this is not It is not recommended to use, it needs more testing, and is more secure to unpack them first manually
true at all. The first series of the n800 comes with the same usb-id and flash the pieces manually with multiple '-p' flags. If you are brave try:
than n770. That's weird!
So, the only way to identify the device is by asking nolo for the version # 0xFFFF -F FiascoFirmware.fiasco
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 :)
<b>*) Can I unpack fiasco blobs?</b> <h2>Advanced commands</h2>
Actually the fiasco format is not yet supported and not planned in <b>*) How to extract the firmware pieces from a running device?</b>
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. It is possible to dump the firmware pieces from the internal MTD to reconstruct a FIASCO image.
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
@@ -0,0 +1,80 @@
<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 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 identify my device?</b>
Theorically n770 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 n770. 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 n770 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.
-53
View File
@@ -1,53 +0,0 @@
- 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
-11
View File
@@ -1,11 +0,0 @@
OBJ=main.o
BIN=goxf
CFLAGS=`pkg-config gladeui-1.0 libglade-2.0 gmodule-2.0 --cflags`
LDFLAGS=`pkg-config gladeui-1.0 libglade-2.0 gmodule-2.0 --libs`
all: ${OBJ}
${CC} ${LDFLAGS} ${OBJ} -o ${BIN}
clean:
-rm -f ${BIN} ${OBJ}
-279
View File
@@ -1,279 +0,0 @@
<?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/n810
HERMflasher</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<placeholder/>
</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="can_focus">False</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<child>
<widget class="GtkTreeView" id="tree">
<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="file">
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkComboBox" id="piece">
<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>
<property name="response_id">0</property>
<signal name="clicked" handler="gui_remove"/>
<signal name="activate" handler="gui_remove"/>
</widget>
</child>
<child>
<widget class="GtkButton" id="add">
<property name="visible">True</property>
<property name="label" context="yes">Add</property>
<property name="response_id">0</property>
<signal name="clicked" handler="gui_add"/>
<signal name="activate" handler="gui_add"/>
</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="usbhost">
<property name="visible">True</property>
<property name="label" translatable="yes" context="yes">USB host mode</property>
<property name="response_id">0</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="rdmode">
<property name="visible">True</property>
<property name="label" translatable="yes" context="yes">R&amp;D mode</property>
<property name="response_id">0</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="response_id">0</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="pbar">
<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>
<property name="response_id">0</property>
<signal name="clicked" handler="gui_information" object="main_window"/>
<signal name="activate" handler="gui_information" object="main_window"/>
</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>
<property name="response_id">0</property>
<signal name="clicked" handler="gui_run"/>
<signal name="activate" handler="gui_run"/>
</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>
<widget class="GtkAboutDialog" id="information">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="border_width">5</property>
<property name="title" translatable="yes" context="yes">About Glade</property>
<property name="resizable">False</property>
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="has_separator">False</property>
<property name="program_name">Glade</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox3">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="spacing">2</property>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<child>
<widget class="GtkTextView" id="textview1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="pixels_below_lines">2</property>
<property name="editable">False</property>
<property name="cursor_visible">False</property>
</widget>
</child>
</widget>
<packing>
<property name="position">2</property>
</packing>
</child>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area3">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>
-77
View File
@@ -1,77 +0,0 @@
/*
* 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);
GladeXML *xml;
int main(int argc, char **argv)
{
GtkWidget *w;
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);
{
GtkComboBox *piece = GTK_COMBO_BOX(glade_xml_get_widget(xml, "piece"));
gtk_combo_box_set_active(piece, 0);
}
gtk_widget_show_all(w);
gtk_object_unref(GTK_OBJECT(xml));
gtk_main();
return 0;
}
extern void gui_run();
extern void gui_run()
{
printf("run\n");
}
extern void gui_add();
extern void gui_add()
{
GtkTreeView *tree = glade_xml_get_widget(xml, "tree");
GtkFileChooser *file = GTK_FILE_CHOOSER(glade_xml_get_widget(xml, "file"));
GtkComboBox *piece = GTK_COMBO_BOX(glade_xml_get_widget(xml, "piece"));
printf("ADD %s\n", gtk_file_chooser_get_filename(file));
printf("ADD %d\n", gtk_combo_box_get_active(piece));
}
extern void gui_information();
void gui_information()
{
printf("FUCKMENOT!\n");
fflush(stdout);
}
+8 -2
View File
@@ -1,8 +1,14 @@
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: ${OBJ} all: ${BIN}
${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
+6 -3
View File
@@ -1,15 +1,18 @@
include ../config.mk include ../config.mk
OBJ=main.o fiasco.o hexdump.o dump.o flash.o serial.o OBJ=main.o fiasco.o hexdump.o dump.o flash.o serial.o qmode.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'` #LIBS=`${HAVE_USB} && echo -- '-lusb'`
LIBS=`if [ "${HAVE_USB}" = 1 ]; then echo '-lusb'; fi` LIBS=`if [ "${HAVE_USB}" = 1 ]; then echo '-lusb'; fi`
CFLAGS+=-DVERSION=\"${VERSION}\" -Wall -g -I . CFLAGS+=-DVERSION=\"${VERSION}\" -Wall -I .
CFLAGS+=-pedantic -std=c99 -DHAVE_USB=${HAVE_USB} CFLAGS+=-pedantic -std=c99 -DHAVE_USB=${HAVE_USB}
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
all: ${OBJ} all: ${BIN}
${BIN}: ${OBJ}
${CC} ${LDFLAGS} -o ${BIN} ${OBJ} ${LIBS} ${CC} ${LDFLAGS} -o ${BIN} ${OBJ} ${LIBS}
allusb: ${OBJ} allusb: ${OBJ}
+6 -1
View File
@@ -46,8 +46,13 @@ void cmd_help(char *line)
void cmd_info(char *line) void cmd_info(char *line)
{ {
char *p, str[128];
get_sw_version(); get_sw_version();
get_hw_revision(); // get hardware revision: 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();
+48 -14
View File
@@ -27,16 +27,18 @@
#include "main.h" #include "main.h"
#include "hash.h" #include "hash.h"
void (*fiasco_callback)(struct header_t *header) = NULL; int (*fiasco_callback)(struct header_t *header) = NULL;
int openfiasco(char *name) int openfiasco(char *name, char *piece_grep, int v)
{ {
struct header_t header; struct header_t header;
unsigned char buf[128]; unsigned char buf[128];
unsigned char data[128]; unsigned char data[128];
unsigned char *pdata;
unsigned int namelen; unsigned int namelen;
off_t off; off_t off, here;
int i; int i,j;
header.fd = open(name, O_RDONLY); header.fd = open(name, O_RDONLY);
if (header.fd == -1) { if (header.fd == -1) {
@@ -59,21 +61,30 @@ int openfiasco(char *name)
memset(buf,'\0', 128); memset(buf,'\0', 128);
read(header.fd, buf, namelen); read(header.fd, buf, namelen);
printf("Fiasco version: %2d\n", buf[3]); if (v) printf("Fiasco version: %2d\n", buf[3]);
strcpy(header.fwname, (char *)buf+6); strcpy(header.fwname, (char *)buf+6);
if (v)
for(i=6;i<namelen;i+=strlen((char *)(buf+i))+1) for(i=6;i<namelen;i+=strlen((char *)(buf+i))+1)
printf("Name: %s\n", buf+i); printf("Name: %s\n", buf+i);
/* walk the tree */ /* walk the tree */
while(1) { while(1) {
here = lseek(header.fd, 0, SEEK_CUR);
if (read(header.fd, buf, 9)<9) if (read(header.fd, buf, 9)<9)
break; break;
if (buf[0] != 0x54) { // 'T' if (buf[0] != 0x54) { // 'T'
printf("unexpected header at 0x%x, found %02x %02x %02x\n", /* skipping some bytes */
((int)lseek(header.fd, 0, SEEK_CUR))-9, lseek(header.fd, -9, SEEK_CUR);
buf[0], buf[1], buf[2]); for(i=0;buf[0]!=0x54;i++) {
break; j = read(header.fd, buf, 1);
if (j == -1) {
printf("Cannot find next FIASCO header\n");
return close(header.fd);
}
}
if (v) printf("Skipping %d padding bytes\n", i);
lseek(header.fd, -1, SEEK_CUR);
continue;
} }
header.hash = buf[7]<<8|buf[8]; header.hash = buf[7]<<8|buf[8];
@@ -85,15 +96,18 @@ int openfiasco(char *name)
if (data[0] == 0xff) { if (data[0] == 0xff) {
printf(" [eof]\n"); printf(" [eof]\n");
break; break;
} else printf(" %s\n", data); } else if (v) printf(" %s\n", data);
strcpy(header.name, (char *)data); strcpy(header.name, (char *)data);
if (read(header.fd, buf, 9)<9) if (read(header.fd, buf, 9)<9)
break; break;
memcpy(&header.size, buf,4); memcpy(&header.size, buf,4);
header.size = ntohl(header.size); header.size = ntohl(header.size);
if (v) {
printf(" offset: 0x%08x\n", (unsigned int)here);
printf(" size: %d bytes\n", header.size); printf(" size: %d bytes\n", header.size);
printf(" hash: %04x\n", header.hash); printf(" hash: %04x\n", header.hash);
}
//printf("BYTE: %02x %02x %02x %02x %02x\n", //printf("BYTE: %02x %02x %02x %02x %02x\n",
// buf[4], buf[5], buf[6], buf[7], buf[8]); // buf[4], buf[5], buf[6], buf[7], buf[8]);
/* XXX this is not ok */ /* XXX this is not ok */
@@ -104,24 +118,45 @@ int openfiasco(char *name)
i = data[0]; i = data[0];
if (read(header.fd, data, i)<i) if (read(header.fd, data, i)<i)
break; break;
if (data[0]) if (data[0]) {
if (v) {
printf(" version-length: %d\n", i);
printf(" version: %s\n", data); printf(" version: %s\n", data);
}
pdata = data;
while(pdata<data+i) {
strcat(header.name,pdata==data?"-":",");
strcat(header.name, (char*)pdata);
if (v) printf(" sub-version: %s\n", pdata);
pdata = pdata+strlen((char*)pdata)+1;
for(;*pdata=='\0'&&pdata<data+i;pdata=pdata+1);
}
}
strcpy(header.version, (char *)data); strcpy(header.version, (char *)data);
if (read(header.fd, buf+8, 1)<1) if (read(header.fd, buf+8, 1)<1)
break; break;
} }
/* callback */ /* callback */
off = lseek(header.fd, 0, SEEK_CUR); off = lseek(header.fd, 0, SEEK_CUR);
if (v) {
printf(" name: %s\n", header.name);
printf(" body-at: 0x%08x\n", (unsigned int)off);
}
if (piece_grep==NULL || (strstr(header.name, piece_grep))) {
printf("==> (%s) %s\n", piece_grep, header.name);
if (fiasco_callback != NULL) { if (fiasco_callback != NULL) {
fiasco_callback(&header); fiasco_callback(&header);
free(header.data); free(header.data);
continue; continue;
} else {
// ??huh
}
} }
// 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);
} }
return 0; return close(header.fd);
} }
void fiasco_data_read(struct header_t *header) void fiasco_data_read(struct header_t *header)
@@ -173,7 +208,6 @@ int fiasco_add_eof(int fd)
return 0; return 0;
} }
int fiasco_add(int fd, const char *name, const char *file, const char *version) int fiasco_add(int fd, const char *name, const char *file, const char *version)
{ {
int gd,ret; int gd,ret;
+18 -1
View File
@@ -74,7 +74,7 @@ void check_nolo_order()
check_nolo_order_failed(); check_nolo_order_failed();
} }
void flash_image(char *filename, char *piece, char *version) void flash_image(const char *filename, const char *piece, const char *version)
{ {
FILE *fd; FILE *fd;
int vlen = 0; int vlen = 0;
@@ -86,6 +86,23 @@ void flash_image(char *filename, char *piece, char *version)
unsigned char nolofiller[128]; unsigned char nolofiller[128];
ushort hash = do_hash_file(filename); 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;
+34 -4
View File
@@ -20,12 +20,34 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
/* 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
"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
@@ -45,6 +67,9 @@ 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
@@ -54,10 +79,15 @@ 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)) // TODO: this is xloader800, not valid on 770? if (!memcmp(b+0x0c, "NOLOXldr", 8))
return pieces[PIECE_XLOADER]; return pieces[PIECE_XLOADER];
else else
if (!memcmp(b+0x00, "\x00\x00\xa0\xe1\x00\x00\xa0\xe1", 8)) if (!memcmp(b+4,"NOLOXldr",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
@@ -68,5 +98,5 @@ const char *fpid_file(const char *filename)
return pieces[PIECE_ROOTFS]; return pieces[PIECE_ROOTFS];
} }
return piece; return NULL;
} }
+13
View File
@@ -0,0 +1,13 @@
include ../../config.mk
ifeq (${HAVE_GUI},1)
all:
gtkamlc --save-temps --Xcc=-I../squeue ../squeue/squeue.c ../fpid.c ../squeue/squeue.vapi gui.gtkaml 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
+10
View File
@@ -0,0 +1,10 @@
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);
}
}
+356
View File
@@ -0,0 +1,356 @@
<!--
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.3.9" copyright="Copyright (c) 2008 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; int 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>
+119 -34
View File
@@ -1,6 +1,6 @@
/* /*
* 0xFFFF - Open Free Fiasco Firmware Flasher * 0xFFFF - Open Free Fiasco Firmware Flasher
* Copyright (C) 2007 pancake <pancake@youterm.com> * Copyright (C) 2007, 2008 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
@@ -32,6 +32,7 @@ struct usb_dev_handle *dev = NULL;
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;
@@ -40,19 +41,9 @@ int verbose = 0;
int identify = 0; int identify = 0;
int moboreboot = 0; int moboreboot = 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",
@@ -90,12 +81,17 @@ void show_usage()
printf(" -r [0|1] disable/enable R&D mode\n"); printf(" -r [0|1] disable/enable R&D mode\n");
printf(" -R reboot the omap board\n"); printf(" -R reboot the omap board\n");
printf(" -U [0|1] disable/enable the usb host mode\n"); printf(" -U [0|1] disable/enable the usb host mode\n");
#endif
#if HAVE_SQUEUE
printf(" -Q enter shared queues server mode (for gui or remote)\n");
#endif #endif
printf("Local stuff:\n"); printf("Local stuff:\n");
printf(" -s [serial] serial port console (minicom like terminal)\n"); printf(" -s [serial] serial port console (minicom like terminal)\n");
printf(" -h show this help message\n"); printf(" -h show this help message\n");
printf(" -S [subversion] unpacks/flash pieces matching this sub-version information\n");
printf(" -n do not flash or write to disk (simulation)\n");
printf(" -C [/dev/mtd] check bad blocks on mtd\n"); printf(" -C [/dev/mtd] check bad blocks on mtd\n");
printf(" -e [path] dump and extract pieces to path\n"); printf(" -e [path] dump/extract pieces to path\n");
printf(" -F [fiasco] flash a fiasco firmware image\n"); printf(" -F [fiasco] flash a fiasco firmware image\n");
printf(" -H [file] calculate hash for file\n"); printf(" -H [file] calculate hash for file\n");
printf(" -I [piece] identify a firmware piece\n"); printf(" -I [piece] identify a firmware piece\n");
@@ -112,43 +108,104 @@ void show_usage()
exit(0); exit(0);
} }
int unpack_callback(struct header_t *header)
void unpack_callback(struct header_t *header)
{ {
FILE *fd = fopen(header->name, "wb"); FILE *fd;
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;
fd = fopen(header->name, "wb");
if (fd == NULL) { if (fd == NULL) {
printf("Cannot open file.\n"); printf("Cannot open file.\n");
return; return 1;
} }
fiasco_data_read(header);
fwrite(header->data, header->size, 1, fd); 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 = (char *)fpid_file(header->name);
printf("\nFlashing %s (%s)\n", header->name, type);
flash_image(header->name, type, NULL);
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 ); openfiasco(file, NULL ,1);
} }
int fiasco_flash(char *file) int fiasco_flash(const char *file)
{ {
/* TODO */ char *p;
fiasco_callback = NULL; char version[64];
openfiasco( file );
printf("\nTODO: Implement the fiasco flashing here.\n"); if (connect_via_usb()) {
return -1; 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", 0);
openfiasco(file, "secondary", 0);
openfiasco(file, "kernel", 0);
openfiasco(file, "initfs", 0);
openfiasco(file, "rootfs", 0);
return 0;
} }
#if HAVE_USB #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();
@@ -222,7 +279,7 @@ int main(int argc, char **argv)
{ {
int c; int c;
while((c = getopt(argc, argv, "C:cp:PvVhRu:ib:U:r:e:ld:I:D:f:F:s:xH:")) != -1) { while((c = getopt(argc, argv, "QC:cp:PvVhRu:ib:U:r:e:ld:I:D:f:F:s:xH:S:n")) != -1) {
switch(c) { switch(c) {
case 'H': case 'H':
printf("xorpair: %04x\n", do_hash_file(optarg)); printf("xorpair: %04x\n", do_hash_file(optarg));
@@ -235,11 +292,18 @@ int main(int argc, char **argv)
case 'b': case 'b':
boot_cmdline = optarg; boot_cmdline = optarg;
break; break;
case 'S':
subverstr = optarg;
break;
case 'n':
nomode = 1;
break;
case 'U': case 'U':
usb_mode = atoi(optarg); usb_mode = atoi(optarg);
break; break;
case 'F': case 'F':
return fiasco_flash(optarg); fiasco_image = 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,
@@ -286,6 +350,9 @@ int main(int argc, char **argv)
fiasco_image = optarg; fiasco_image = optarg;
unpack = 1; unpack = 1;
break; break;
case 'Q':
qmode = 1;
break;
case 'P': case 'P':
return fiasco_pack(optind, argv); return fiasco_pack(optind, argv);
case 'I': case 'I':
@@ -306,6 +373,12 @@ int main(int argc, char **argv)
} }
} }
if (qmode)
return queue_mode();
if (!unpack && fiasco_image)
return fiasco_flash(fiasco_image);
if (identify) if (identify)
return 0; return 0;
@@ -321,13 +394,17 @@ int main(int argc, char **argv)
&& (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(" [-F fiasco] [-H hash-file] [-I piece] [-p [piece%%]file]] [-r 0|1]\n"); printf("# The Free Fiasco Firmware Flasher v"VERSION"\n"
printf(" [-s serial-dev] [-u fiasco-image] [-U 0|1] | [-P new-fiasco] [piece1] [2] ..\n"); "0xFFFF [-chinlQRvVx] [-C mtd-dev] [-d vid:pid] [-D 0|1|2] [-e path] [-f flags]\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)
chdir(reverseto);
unpack_fiasco_image(fiasco_image); unpack_fiasco_image(fiasco_image);
return 0; return 0;
} }
@@ -347,10 +424,18 @@ int main(int argc, char **argv)
cmd_info(""); cmd_info("");
if (pcs_n) { if (pcs_n) {
int c; char version[64];
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++) {
+14 -4
View File
@@ -4,6 +4,8 @@
#include "hash.h" #include "hash.h"
#include "nolo.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
@@ -11,12 +13,13 @@
// 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(char *filename, char *piece, char *version); void flash_image(const char *filename, const char *piece, const 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(char *file); unsigned long get_file_size(const 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);
@@ -30,6 +33,7 @@ void eprintf(const char *format, ...);
#if HAVE_USB #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);
@@ -80,6 +84,7 @@ enum {
PIECE_INITFS, PIECE_INITFS,
PIECE_ROOTFS, PIECE_ROOTFS,
PIECE_OMAPNAND, PIECE_OMAPNAND,
PIECE_FIASCO,
PIECE_LAST PIECE_LAST
}; };
@@ -98,14 +103,19 @@ extern char *modes[];
extern char *root_devices[]; extern char *root_devices[];
// fiasco // fiasco
int openfiasco(char *name); int openfiasco(char *name, char *grep, int v);
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);
int fiasco_add_eof(int fd); int fiasco_add_eof(int fd);
extern void (*fiasco_callback)(struct header_t *header); extern int (*fiasco_callback)(struct header_t *header);
int fiasco_add(int fd, const char *name, const char *file, const char *version); 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); int nanddump(char *mtddev, unsigned long start_addr, unsigned long length, char *dumpfile, int isbl, int ioob);
//
int reboot_board();
int get_rd_flags();
int get_usb_mode();
int get_nolo_version();
#endif #endif
+19
View File
@@ -0,0 +1,19 @@
#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
+146
View File
@@ -0,0 +1,146 @@
/*
* 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);
} 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
+46 -23
View File
@@ -24,6 +24,8 @@
#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()
{ {
@@ -76,7 +78,8 @@ int get_usb_mode()
return -1; return -1;
} }
printf("Device's USB mode is '%s'\n", (mode) ? "host" : "client"); sprintf(strbuf, "Device's USB mode is '%s'\n", (mode) ? "host" : "client");
printf(strbuf);
return 0; return 0;
} }
@@ -131,27 +134,28 @@ int set_rd_mode(unsigned short mode)
/* /*
* query root device * query root device
*/ */
int get_hw_revision() int get_hw_revision(char *str, int len)
{ {
unsigned char string[512]; unsigned char string[512];
int i = 0; char tmpstr[64];
int i = 0, j=0, mod=0;
if (str == NULL)
str = tmpstr;
memset(string,'\0',512); memset(string,'\0',512);
if (usb_control_msg(dev, CMD_QUERY, NOLO_GET_HWVERSION, 0, 0, (char *)string, 512, 2000) == -1) { 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;
} }
printf("HW revision string: '"); for(i=0;i<44&&i<len;i++) { // XXX ??
for(i=0;i<44;i++) { // XXX ?? if (string[i]>19) {
if (string[i]==0) { if (i>0 && string[i-1]<19)
printf(" "); str[j++] = (++mod%2)?':':',';
} else { str[j++] = string[i];
if (string[i]>19)
printf("%c", string[i]);
} }
} }
printf("'\n"); printf("HW revision string: '%s'\n", str);
return 0; return 0;
} }
@@ -160,11 +164,12 @@ int get_rd_mode()
{ {
char isrd = 1; char isrd = 1;
strbuf[0]='\0';
if (usb_control_msg(dev, CMD_QUERY, NOLO_GET_RDFLAGS, 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;
} }
printf("RD mode is: %s\n", isrd?"on":"off"); sprintf(strbuf, "RD mode is: %s\n", isrd?"on":"off");
return isrd; return isrd;
} }
@@ -173,16 +178,19 @@ int get_root_device()
{ {
unsigned char opcode; unsigned char opcode;
strbuf[0] = '\0';
if (usb_control_msg(dev, CMD_QUERY, NOLO_GET_RDFLAGS, 0, 1, (char *)&opcode, 1, 2000) < 0) { if (usb_control_msg(dev, CMD_QUERY, NOLO_GET_RDFLAGS, 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
printf("Invalid root device received from the device '%d'.\n", opcode); fprintf(stderr, "Invalid root device received from the device '%d'.\n", opcode);
return -1;
} }
printf("Root device is: %s\n", root_devices[opcode]); sprintf(strbuf, "Root device is: %s\n", root_devices[opcode]);
printf(strbuf);
return 0; return 0;
} }
@@ -286,15 +294,23 @@ int get_rd_flags()
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, NOLO_GET_RDFLAGS, 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;
} }
printf("Current rd flag setting:\n"); sprintf(strbuf,
printf("disable OMAP watchdog : %s\n", (flags & 0x02) ? "set" : "not set"); "Current rd flag setting:\n"
printf("disable RETU watchdog : %s\n", (flags & 0x04) ? "set" : "not set"); "disable OMAP watchdog : %s\n"
printf("disable lifeguard reset: %s\n", (flags & 0x08) ? "set" : "not set"); "disable RETU watchdog : %s\n"
printf("enable serial console : %s\n", (flags & 0x10) ? "set" : "not set"); "disable lifeguard reset: %s\n"
printf("disable USB timeout : %s\n", (flags & 0x20) ? "set" : "not set"); "enable serial console : %s\n"
"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");
printf(strbuf);
return 0; return 0;
} }
@@ -306,10 +322,12 @@ int get_nolo_version()
//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, NOLO_GET_VERSION, 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");
exit(1); sprintf(strbuf, "error: Cannot query nolo version. Old bootloader?");
return -1;
} }
printf("NOLO Version %d.%d.%d\n", sprintf(strbuf,
"NOLO Version %d.%d.%d\n",
version >> 20 & 15, version >> 20 & 15,
version >> 16 & 15, version >> 16 & 15,
version >> 8 & 255); version >> 8 & 255);
@@ -320,6 +338,7 @@ int get_nolo_version()
return 0; return 0;
} }
int get_sw_version() int get_sw_version()
{ {
int ret; int ret;
@@ -337,7 +356,11 @@ int get_sw_version()
fprintf(stderr, "error: b0rken swversion read!\n"); fprintf(stderr, "error: b0rken swversion read!\n");
return 0; return 0;
} }
printf("SWVERSION GOT: %s\n", bytes); //???+strlen(bytes)+1)); if (bytes[0]) {
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;
} }
+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(); int get_hw_revision(char *str, int len);
int get_root_device(); int get_root_device();
int set_root_device(unsigned short); int set_root_device(unsigned short);
+294
View File
@@ -0,0 +1,294 @@
#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 (((int)pool) == -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
@@ -0,0 +1,28 @@
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
@@ -0,0 +1,45 @@
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 weak 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
}
}
+14 -2
View File
@@ -22,7 +22,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
unsigned long get_file_size(char *file) unsigned long get_file_size(const char *file)
{ {
FILE *fd = fopen(file, "r"); FILE *fd = fopen(file, "r");
unsigned long len = 0; unsigned long len = 0;
@@ -42,9 +42,18 @@ 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 (qmode) {
char msg[128];
sprintf(msg, "%d%%", pc);
squeue_push2(p, "bar", msg, 0);
} else {
#endif
printf("\x1b[K %3d%% [", pc);
if (columns) if (columns)
cols = atoi(columns); cols = atoi(columns);
cols-=15; cols-=15;
@@ -52,6 +61,9 @@ void progressbar(unsigned long long part, unsigned long long total)
for(tmp=cols-(cols*pc/100);tmp;tmp--) printf("-"); for(tmp=cols-(cols*pc/100);tmp;tmp--) printf("-");
printf("]\r"); printf("]\r");
fflush(stdout); fflush(stdout);
#if HAVE_SQUEUE
}
#endif
} }
void eprintf(const char *format, ...) void eprintf(const char *format, ...)