2007-04-20 18:20:22 +02:00
|
|
|
/*
|
2007-06-30 03:58:18 +02:00
|
|
|
* 0xFFFF - Open Free Fiasco Firmware Flasher
|
|
|
|
|
* Copyright (C) 2007 pancake <pancake@youterm.com>
|
2007-04-20 18:20:22 +02:00
|
|
|
*
|
2007-06-30 03:58:18 +02:00
|
|
|
* 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.
|
2007-04-20 18:20:22 +02:00
|
|
|
*
|
2007-06-30 03:58:18 +02:00
|
|
|
* 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.
|
2007-04-20 18:20:22 +02:00
|
|
|
*
|
2007-06-30 03:58:18 +02:00
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2007-04-20 18:20:22 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "main.h"
|
2007-04-25 21:05:03 +02:00
|
|
|
#include "query.h"
|
2007-04-20 18:20:22 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <getopt.h>
|
|
|
|
|
|
|
|
|
|
/* global pr0n */
|
|
|
|
|
struct usb_device *device = NULL;
|
|
|
|
|
struct usb_dev_handle *dev = NULL;
|
2007-05-01 15:01:23 +02:00
|
|
|
char *fiasco_image = NULL;
|
|
|
|
|
char *boot_cmdline = NULL;
|
|
|
|
|
char *reverseto = NULL;
|
|
|
|
|
int rd_mode = -1;
|
|
|
|
|
int rd_flags = -1;
|
|
|
|
|
int usb_mode = -1;
|
|
|
|
|
int root_device = -1;
|
|
|
|
|
int verbose = 0;
|
|
|
|
|
int identify = 0;
|
|
|
|
|
int reboot = 0;
|
|
|
|
|
int unpack = 0;
|
|
|
|
|
int info = 0;
|
2007-04-20 18:20:22 +02:00
|
|
|
|
|
|
|
|
/* global structs */
|
|
|
|
|
char *pieces[] = {
|
|
|
|
|
"xloader", // xloader.bin
|
|
|
|
|
"secondary", // secondary.bin
|
|
|
|
|
"kernel", // zImage
|
|
|
|
|
"initfs", // jffs'd initfs
|
|
|
|
|
"rootfs", // 80mB of blob
|
|
|
|
|
"omap-nand", // 8kB of food for the nand
|
|
|
|
|
NULL
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
char *modes[]={
|
|
|
|
|
"host",
|
|
|
|
|
"peripheral",
|
|
|
|
|
NULL
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
char *root_devices[] = {
|
|
|
|
|
"flash",
|
|
|
|
|
"mmc",
|
|
|
|
|
"usb",
|
|
|
|
|
NULL
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void show_title()
|
|
|
|
|
{
|
2007-06-10 00:38:55 +02:00
|
|
|
printf("0xFFFF v%s // The Free Fiasco Firmware Flasher\n", VERSION);
|
2007-04-20 18:20:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void show_usage()
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
show_title();
|
|
|
|
|
|
2007-06-10 00:38:55 +02:00
|
|
|
printf(" -b [arg] boots the kernel with arguments\n");
|
|
|
|
|
printf(" -e [path] dump and extract pieces to path\n");
|
|
|
|
|
printf(" -r [0|1] disable/enable R&D mode\n");
|
2007-06-10 05:41:50 +02:00
|
|
|
printf(" -f <flags> set the given RD flags (see '-f help')\n");
|
2007-06-10 00:38:55 +02:00
|
|
|
printf(" -p [[p%%]file] piece-of-firmware %% file-where-this-piece-is\n");
|
|
|
|
|
printf(" -u [fiasco] unpack target fiasco image\n");
|
|
|
|
|
printf(" -U [0|1] disable/enable the usb host mode\n");
|
|
|
|
|
printf(" -s [serial] serial port console (minicom like terminal)\n");
|
2007-06-10 16:15:30 +02:00
|
|
|
printf(" -C [/dev/mtd] check bad blocks on mtd\n");
|
2007-06-10 05:41:50 +02:00
|
|
|
printf(" -c console prompt mode\n");
|
2007-06-10 00:38:55 +02:00
|
|
|
printf(" -h show this help message\n");
|
|
|
|
|
printf(" -i show device information (let standby mode)\n");
|
|
|
|
|
printf(" -I [piece] identify a firmware piece\n");
|
|
|
|
|
printf(" -l list supported usb device ids\n");
|
|
|
|
|
printf(" -d [vid:pid] injects a usb device into the supported list\n");
|
|
|
|
|
printf(" -D [0|1|2] sets the root device to flash (0), mmc (1) or usb (2)\n");
|
|
|
|
|
printf(" -R reboot the omap board\n");
|
2007-06-11 02:29:11 +02:00
|
|
|
printf(" -x extract configuration entries from /dev/mtd1\n");
|
2007-06-10 00:38:55 +02:00
|
|
|
printf(" -v be verbose and noisy\n");
|
|
|
|
|
printf(" -V show 0xFFFF version information\n");
|
2007-04-20 18:20:22 +02:00
|
|
|
printf("Pieces are: ");
|
|
|
|
|
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)
|
|
|
|
|
// TODO: commandline shell prompt for nolo comm
|
|
|
|
|
|
|
|
|
|
exit(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void unpack_fiasco_image(char *file)
|
|
|
|
|
{
|
|
|
|
|
fiasco_read_image(file);
|
|
|
|
|
// TODO
|
|
|
|
|
}
|
|
|
|
|
|
2007-06-10 05:41:50 +02:00
|
|
|
int connect_via_usb()
|
2007-04-20 18:20:22 +02:00
|
|
|
{
|
2007-06-14 23:32:52 +02:00
|
|
|
struct usb_device_descriptor udd;
|
|
|
|
|
struct devices it_device;
|
|
|
|
|
int c = 0;
|
|
|
|
|
static char pbc[]={'/','-','\\', '|'};
|
|
|
|
|
|
2007-06-10 05:41:50 +02:00
|
|
|
// usb_set_debug(5);
|
|
|
|
|
usb_init();
|
|
|
|
|
|
2007-06-14 23:32:52 +02:00
|
|
|
/* Tries to get access to the Internet Tablet and retries
|
|
|
|
|
* if any of the neccessary steps fail.
|
|
|
|
|
*
|
|
|
|
|
* 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 in the boot stage any more).
|
|
|
|
|
*/
|
|
|
|
|
while(!dev) {
|
2007-06-10 05:41:50 +02:00
|
|
|
usleep(0xc350); // 0.5s
|
2007-06-14 23:32:52 +02:00
|
|
|
|
|
|
|
|
if(!usb_device_found(&udd, &it_device)) {
|
|
|
|
|
printf("\rWaiting for device... %c", pbc[++c%4]);
|
|
|
|
|
fflush(stdout);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2007-06-10 05:41:50 +02:00
|
|
|
|
2007-06-14 23:32:52 +02:00
|
|
|
/* open device */
|
|
|
|
|
if(!(dev = usb_open(device))) {
|
|
|
|
|
perror("usb_open");
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
2007-06-10 05:41:50 +02:00
|
|
|
|
2007-06-14 23:32:52 +02:00
|
|
|
if ( usb_claim_interface(dev, 2) < 0) { // 2 or 0
|
|
|
|
|
D perror("usb_claim_interface");
|
|
|
|
|
|
|
|
|
|
// Something is broken if closing fails.
|
|
|
|
|
if(usb_close(dev)) {
|
|
|
|
|
perror("usb_close");
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dev = NULL;
|
|
|
|
|
|
|
|
|
|
// Try again later.
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (usb_set_altinterface(dev, 1) < 0) {
|
|
|
|
|
D perror("usb_set_altinterface");
|
|
|
|
|
|
|
|
|
|
// 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);
|
2007-06-10 05:41:50 +02:00
|
|
|
|
|
|
|
|
/* go go go! */
|
|
|
|
|
while(get_status());
|
|
|
|
|
|
|
|
|
|
sleep(1); // take breath
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
|
|
|
{
|
2007-04-20 18:20:22 +02:00
|
|
|
int c;
|
|
|
|
|
|
2007-06-11 02:29:11 +02:00
|
|
|
while((c = getopt(argc, argv, "C:cp:vVhRu:ib:U:r:e:ld:I:D:f:s:x")) != -1) {
|
2007-04-20 18:20:22 +02:00
|
|
|
switch(c) {
|
2007-06-11 02:29:11 +02:00
|
|
|
case 'x':
|
|
|
|
|
return dump_config();
|
2007-06-10 05:41:50 +02:00
|
|
|
case 'c':
|
|
|
|
|
return console_prompt();
|
2007-04-20 18:20:22 +02:00
|
|
|
case 'd':
|
|
|
|
|
sscanf(optarg, "%04hx:%04hx",
|
|
|
|
|
&supported_devices[SUPPORTED_DEVICES-2].vendor_id,
|
|
|
|
|
&supported_devices[SUPPORTED_DEVICES-2].product_id);
|
|
|
|
|
supported_devices[SUPPORTED_DEVICES-2].name = strdup("user");
|
|
|
|
|
break;
|
2007-04-20 18:27:31 +02:00
|
|
|
case 'D':
|
|
|
|
|
root_device = atoi(optarg);
|
|
|
|
|
break;
|
2007-04-20 18:20:22 +02:00
|
|
|
case 'e':
|
|
|
|
|
reverseto = optarg;
|
|
|
|
|
break;
|
2007-06-10 00:38:55 +02:00
|
|
|
case 's':
|
|
|
|
|
return console(optarg);
|
2007-04-25 21:47:53 +02:00
|
|
|
case 'f':
|
2007-04-26 00:30:46 +02:00
|
|
|
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);
|
|
|
|
|
}
|
2007-04-25 21:47:53 +02:00
|
|
|
rd_flags = (unsigned short) strtoul(optarg, NULL, 16);
|
2007-04-20 18:20:22 +02:00
|
|
|
case 'U':
|
|
|
|
|
usb_mode = atoi(optarg);
|
|
|
|
|
break;
|
|
|
|
|
case 'r':
|
2007-04-25 21:47:53 +02:00
|
|
|
rd_mode = atoi(optarg);
|
2007-04-20 18:20:22 +02:00
|
|
|
break;
|
|
|
|
|
case 'b':
|
|
|
|
|
boot_cmdline = optarg;
|
|
|
|
|
break;
|
|
|
|
|
case 'u':
|
|
|
|
|
fiasco_image = optarg;
|
|
|
|
|
unpack = 1;
|
|
|
|
|
break;
|
|
|
|
|
case 'p':
|
|
|
|
|
add_piece(optarg);
|
|
|
|
|
break;
|
|
|
|
|
case 'l':
|
|
|
|
|
list_valid_devices();
|
|
|
|
|
return 0;
|
|
|
|
|
case 'I':
|
|
|
|
|
printf("%s: %s\n", fpid_file(optarg), optarg);
|
|
|
|
|
identify = 1;
|
|
|
|
|
break;
|
2007-06-10 16:15:30 +02:00
|
|
|
case 'C':
|
|
|
|
|
return check_badblocks(optarg);
|
2007-04-20 18:20:22 +02:00
|
|
|
case 'i':
|
|
|
|
|
info = 1;
|
|
|
|
|
break;
|
|
|
|
|
case 'v':
|
|
|
|
|
verbose = 1;
|
|
|
|
|
break;
|
|
|
|
|
case 'h':
|
|
|
|
|
show_usage();
|
|
|
|
|
break;
|
|
|
|
|
case 'V':
|
|
|
|
|
printf("%s\n", VERSION);
|
|
|
|
|
return 0;
|
|
|
|
|
case 'R':
|
|
|
|
|
reboot = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (identify)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
// flags ok?
|
|
|
|
|
if ( (fiasco_image == NULL)
|
|
|
|
|
&& (boot_cmdline == NULL)
|
|
|
|
|
&& (reverseto == NULL)
|
|
|
|
|
&& (pcs_n == 0)
|
2007-04-25 21:47:53 +02:00
|
|
|
&& (rd_flags == -1)
|
|
|
|
|
&& (rd_mode == -1)
|
2007-04-20 18:20:22 +02:00
|
|
|
&& (info == 0)
|
|
|
|
|
&& (reboot == 0)
|
2007-05-01 15:01:23 +02:00
|
|
|
&& (usb_mode == -1)
|
2007-04-20 18:27:31 +02:00
|
|
|
&& (root_device == -1))
|
2007-04-20 18:20:22 +02:00
|
|
|
{
|
2007-04-20 18:27:31 +02:00
|
|
|
printf("Usage: 0xFFFF [-hvVRi] [-e path] [-U 0|1] [-p [piece%%]file [-p ...]]\n");
|
2007-06-11 02:29:11 +02:00
|
|
|
printf(" [-b boot-args] [-I piece [-I ...]] [-u fiasco-image] [-x]\n");
|
2007-06-10 16:15:30 +02:00
|
|
|
printf(" [-D 0|1|2] [-F rd flags] [-s serial-dev] [-c] [-C mtd-dev]\n");
|
2007-04-20 18:20:22 +02:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (unpack) {
|
|
|
|
|
unpack_fiasco_image(fiasco_image);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (reverseto) {
|
|
|
|
|
reverse_extract_pieces(reverseto);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2007-06-14 23:32:52 +02:00
|
|
|
if (connect_via_usb()) {
|
|
|
|
|
fprintf(stderr, "Cannot connect to device. It is possibly not in boot stage.\n");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2007-04-20 18:20:22 +02:00
|
|
|
|
|
|
|
|
// if (info)
|
2007-06-10 05:41:50 +02:00
|
|
|
cmd_info("");
|
2007-04-25 21:05:03 +02:00
|
|
|
|
2007-04-20 18:20:22 +02:00
|
|
|
if (pcs_n) {
|
|
|
|
|
int c;
|
|
|
|
|
|
|
|
|
|
check_nolo_order();
|
2007-04-25 21:05:03 +02:00
|
|
|
get_sw_version();
|
|
|
|
|
get_nolo_version();
|
2007-04-20 18:20:22 +02:00
|
|
|
|
|
|
|
|
for(c=0;c<pcs_n;c++) {
|
|
|
|
|
printf("Flashing %s (%s)\n", pcs[c].type, pcs[c].name);
|
|
|
|
|
flash_image(pcs[c].name, pcs[c].type, pcs[c].vers);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-04-25 21:47:53 +02:00
|
|
|
if (rd_mode != -1)
|
|
|
|
|
set_rd_mode(rd_mode);
|
|
|
|
|
|
|
|
|
|
if (rd_flags != -1)
|
|
|
|
|
set_rd_flags(rd_flags);
|
|
|
|
|
|
2007-04-20 18:27:31 +02:00
|
|
|
if (root_device != -1)
|
|
|
|
|
set_root_device(root_device);
|
|
|
|
|
|
2007-04-25 21:47:53 +02:00
|
|
|
if (usb_mode != -1)
|
2007-04-25 21:05:03 +02:00
|
|
|
set_usb_mode(usb_mode);
|
2007-04-20 18:20:22 +02:00
|
|
|
|
|
|
|
|
if (boot_cmdline)
|
|
|
|
|
boot_board(boot_cmdline);
|
|
|
|
|
|
|
|
|
|
if (reboot)
|
|
|
|
|
reboot_board();
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|