summaryrefslogtreecommitdiffstats
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c343
1 files changed, 343 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..7812ae1
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2007
+ * pancake <pancake@youterm.com>
+ *
+ * 0xFFFF 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 0xFFFF 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 0xFFFF; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "main.h"
+#include <usb.h>
+#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;
+char *fiasco_image = NULL;
+char *boot_cmdline = NULL;
+char *reverseto = NULL;
+int rdflags = -1;
+int usb_mode = -1;
+int verbose = 0;
+int identify = 0;
+int reboot = 0;
+int unpack = 0;
+int info = 0;
+
+/* 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
+};
+
+struct devices {
+ char *name;
+ unsigned short vendor_id;
+ unsigned short product_id;
+ unsigned short flags;
+};
+
+#define SUPPORTED_DEVICES 5
+struct devices supported_devices[SUPPORTED_DEVICES] = {
+ { "unkn", 0x421, 0x3f00, 0x0000 }, // probably a development board
+ { "n770", 0x421, 0x0105, 0x0001 }, // my n770
+ { "n800", 0x421, 0x04c3, 0x0001 }, // a n800
+ { 0 },
+ { 0 }
+};
+
+int is_valid_device(struct usb_device_descriptor *udd)
+{
+ int i;
+ struct devices ptr = supported_devices[0];
+
+ for(i=0 ; ptr.vendor_id; ptr = supported_devices[++i])
+ if ((udd->idVendor == ptr.vendor_id)
+ && (udd->idProduct == ptr.product_id)) {
+ printf("found %s (%04x:%04x)\n",
+ ptr.name, ptr.vendor_id, ptr.product_id);
+ return 1;
+ }
+
+ return 0;
+}
+
+void list_valid_devices()
+{
+ int i;
+ struct devices ptr = supported_devices[0];
+
+ for(i=0; ptr.vendor_id; ptr = supported_devices[++i])
+ printf("%04x:%04x %s\n", ptr.vendor_id, ptr.product_id, ptr.name);
+}
+
+int usb_device_found(struct usb_device_descriptor *udd)
+{
+ if (usb_find_busses() < 0) {
+ fprintf(stderr, "error: no usb busses found.\n");
+ exit(1);
+ } else {
+ if (usb_find_devices() < 0) {
+ fprintf(stderr, "error: no devices found.\n");
+ exit(1);
+ } else {
+ struct usb_bus *bus;
+ for (bus = usb_busses; bus; bus = bus->next) {
+ 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 (is_valid_device(udd)) {
+ device = dev;
+ return 1;
+ }
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+/*------------- devices -----------------------*/
+
+void show_title()
+{
+ printf("0xFFFF v%s - The Free Fiasco Firmware Flasher\n", VERSION);
+}
+
+void show_usage()
+{
+ int i;
+ show_title();
+
+ printf(" -b [arg] boots the kernel with arguments\n");
+ printf(" -e [path] dump and extract pieces to path\n");
+ printf(" -p [[p%%]file] piece-of-firmware %% file-where-this-piece-is\n");
+ printf(" -r [0|1] disable/enable R&D mode\n");
+ printf(" -u [fiasco] unpack target fiasco image\n");
+ printf(" -U [0|1] disable/enable the usb host mode\n");
+ 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(" -R reboot the omap board\n");
+ printf(" -v be verbose and noisy\n");
+ printf(" -V show 0xFFFF version information\n");
+ 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
+}
+
+int query_sw_version()
+{
+ int ret;
+ char bytes[1024];
+
+ strcpy(bytes, "version:sw-release");
+ ret = usb_control_msg(dev, CMD_WRITE, 18, 0, 0, (char *)&bytes, 18, 2000);
+ if (ret<0) {
+ fprintf(stderr, "error: cannot write query 18\n");
+ return 0;
+ }
+ ret = usb_control_msg(dev, CMD_QUERY, 20, 0, 0, (char *)&bytes, 512, 2000);
+ if (ret<0) {
+ fprintf(stderr, "error: b0rken swversion read!\n");
+ return 0;
+ }
+ printf("SWVERSION GOT: %s\n", bytes); //???+strlen(bytes)+1));
+ return 1;
+}
+
+int main(int argc, char **argv)
+{
+ struct usb_device_descriptor udd;
+ int c;
+
+ while((c = getopt(argc, argv, "p:vVhRu:ib:U:r:e:ld:I:")) != -1) {
+ switch(c) {
+ 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;
+ case 'e':
+ reverseto = optarg;
+ break;
+ case 'U':
+ usb_mode = atoi(optarg);
+ break;
+ case 'r':
+ rdflags = atoi(optarg);
+ 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;
+ 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)
+ && (rdflags == -1)
+ && (info == 0)
+ && (reboot == 0)
+ && (usb_mode == -1))
+ {
+ printf("Usage: 0xFFFF [-hvVRi] [-e path] [-U 0|1] [-p [piece%]file [-p ...]]\n");
+ printf(" [-b boot-args] [-I piece [-I ...]] [-u fiasco-image]\n");
+ return 1;
+ }
+
+ if (unpack) {
+ unpack_fiasco_image(fiasco_image);
+ return 0;
+ }
+
+ if (reverseto) {
+ reverse_extract_pieces(reverseto);
+ return 0;
+ }
+
+ // usb_set_debug(5);
+ usb_init();
+
+ while(!usb_device_found(&udd)) {
+ char pbc[]={'/','-','\\', '|'};
+ usleep(0xc350); // 0.5s
+ printf("\rWaiting for device... %c", pbc[++c%4]);
+ fflush(stdout);
+ }
+
+ /*/ open device */
+ dev = usb_open(device);
+ if (dev == NULL) {
+ perror("usb_open");
+ return 1;
+ }
+ // TODO
+ if ( usb_claim_interface(dev, 2) < 0) { // 2 or 0
+ perror("usb_claim_interface");
+ return 1;
+ }
+
+ if (usb_set_altinterface(dev, 1) < 0) {
+ perror("usb_set_altinterface");
+ return 1;
+ }
+
+ set_rd_mode(rdflags);
+
+ /* go go go! */
+ while(get_status());
+
+ // if (info)
+ sleep(1); // take breath
+ query_root_device(); // only for flashing
+ query_rdmode_device();
+ query_hw_revision(); // get hardware revision:
+
+ if (pcs_n) {
+ int c;
+
+ check_nolo_order();
+ query_sw_version();
+ query_nolo_version();
+
+ 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);
+ }
+ }
+
+ if (usb_mode!=-1)
+ set_usb_host_mode(usb_mode);
+
+ if (boot_cmdline)
+ boot_board(boot_cmdline);
+
+ if (reboot)
+ reboot_board();
+
+ return 0;
+}