diff options
author | Uwe Hermann <uwe@debian.org> | 2008-12-28 05:47:51 +0100 |
---|---|---|
committer | Andrej Shadura <andrewsh@debian.org> | 2008-12-28 05:47:51 +0100 |
commit | f9a2b90ffbd7f69e59ac8b5c2f1f6d3092313801 (patch) | |
tree | ac945c56ede6a03847e7eec16f3c63e32599b742 | |
parent | e1b659b4b5702eaa32ed6ff594ab555044255a71 (diff) |
Import Upstream version 0.0+r4880
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | doc/dfu-util.1 | 115 | ||||
-rw-r--r-- | src/commands.c | 2 | ||||
-rw-r--r-- | src/main.c | 98 | ||||
-rw-r--r-- | src/sam7dfu.c | 13 |
5 files changed, 185 insertions, 44 deletions
diff --git a/configure.ac b/configure.ac index 593a909..9f141c7 100644 --- a/configure.ac +++ b/configure.ac @@ -7,7 +7,6 @@ AC_CONFIG_AUX_DIR(m4) AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION) #AC_CONFIG_SRCDIR([src/atmel.c]) AM_CONFIG_HEADER([config.h]) -AC_C_BIGENDIAN AM_MAINTAINER_MODE diff --git a/doc/dfu-util.1 b/doc/dfu-util.1 new file mode 100644 index 0000000..3ccf044 --- /dev/null +++ b/doc/dfu-util.1 @@ -0,0 +1,115 @@ +.TH DFU-UTIL 1 "February 29, 2008" +.SH NAME +dfu-util \- Device firmware update (DFU) USB programmer +.SH SYNOPSIS +.B dfu-util \fR[\fB\-ldpciatUDRhV\fR] +.SH DESCRIPTION +.B dfu-util +is a program that implements the host (PC) side of the USB DFU +(Universal Serial Bus Device Firmware Upgrade) protocol. +.sp +In the OpenMoko project (for example), this program is used to communicate +with the specially enhanced u-boot boot loader, which implements the DFU +device side. +.SH OPTIONS +.TP +.B "\-l, \-\-list" +List the currently attached DFU capable USB devices. +.TP +.BR "\-d, \-\-device" " VENDOR:PRODUCT" +Specify vendor/product ID of the DFU device. Both +.B VENDOR +and +.B PRODUCT +are hex-numbers which must start with +.BR 0x . +Example: +.sp +.B " $ dfu-util --device 0x1457:0x5119" +.sp +If you only have one standards-compliant DFU device attached to your PC, +this is optional. However, as soon as you have multiple DFU devices, +dfu-util will detect this and abort, asking you to specify which device +it shall use. +.TP +.BR "\-p, \-\-path" " BUS-PORT. ... .PORT" +Specify the path to the DFU device. +.TP +.BR "\-c, \-\-cfg" " CONFIG-NR" +Specify the configuration of the DFU device. +.TP +.BR "\-i, \-\-intf" " INTF-NR" +Specify the DFU interface number. +.TP +.BR "\-a, \-\-alt" " ALT" +Specify the altsetting of the DFU interface by name or by number. +.TP +.B "\-t, \-\-transfer-size" +Specify the number of bytes per USB transfer. If you don't supply this +option, the maximum possible size for your combination of host OS and +USB device is chosen (for optimal performance). +.TP +.BR "\-U, \-\-upload" " FILE" +Read firmware from device into +.BR FILE . +.sp +.B Note: +Upload support is currently broken. +.TP +.BR "\-D, \-\-download" " FILE" +Write firmware from +.B FILE +into device. +.TP +.B "\-R, \-\-reset" +Issue USB reset signalling once we're finished. +.TP +.B "\-h, \-\-help" +Show a help text and exit. +.TP +.B "\-V, \-\-version" +Show version information and exit. +.SH EXAMPLES +Here are some examples for the usage of dfu-util in the OpenMoko project +(working with the Neo1973 hardware): +.PP +Flashing the rootfs: +.br +.B " $ dfu-util -a rootfs -R -D /path/to/openmoko-devel-image.jffs2" +.PP +Flashing the kernel: +.br +.B " $ dfu-util -a kernel -R -D /path/to/uImage" +.PP +Flashing the bootloader: +.br +.B " $ dfu-util -a u-boot -R -D /path/to/u-boot.bin" +.PP +Copying a kernel into RAM: +.br +.B " $ dfu-util -a 0 -R -D /path/to/uImage" +.sp +Once this has finished, the kernel will be available at the default load +address of 0x32000000 in Neo1973 RAM. +.sp +.B Note: +You cannot transfer more than 2MB of data into RAM using this method. +.SH BUGS +Please see +.B http://wiki.openmoko.org/wiki/Dfu-util +for some limitations and bugs in the current dfu-util code. +.PP +Please report any further bugs at +.B http://bugzilla.openmoko.org +or on the openmoko-kernel mailing list at +.BR openmoko-kernel@lists.openmoko.org . +.SH LICENCE +.B dfu-util +is covered by the GNU General Public License (GPL), version 2 or later. +.SH AUTHORS +Weston Schmidt <weston_schmidt@yahoo.com> +.br +Harald Welte <hwelte@hmw-consulting.de> +.PP +This manual page was written by Uwe Hermann <uwe@hermann-uwe.de>. +It is licensed under the terms of the GNU GPL (version 2 or later). diff --git a/src/commands.c b/src/commands.c index e782be6..929db6b 100644 --- a/src/commands.c +++ b/src/commands.c @@ -340,7 +340,7 @@ static int execute_upload( struct usb_dev_handle *device, if ( 0 > sam7dfu_do_upload(device, interface, 256, /* FIXME */ args.com_flash_data.file) ) { - fprintf( stderr, "Download failed.\n" ); + fprintf( stderr, "Upload failed.\n" ); return -1; } } @@ -1,7 +1,7 @@ /* * dfu-util * - * (C) 2007 by OpenMoko, Inc. + * (C) 2007-2008 by OpenMoko, Inc. * Written by Harald Welte <laforge@openmoko.org> * * Based on existing code of dfu-programmer-0.4 @@ -26,8 +26,6 @@ #include <getopt.h> #include <usb.h> #include <errno.h> -#include <byteswap.h> -#include <endian.h> #include "dfu.h" #include "usb_dfu.h" @@ -41,17 +39,13 @@ #include <usbpath.h> #endif -/* define a portable macro for swapping a 16bit word */ -#if defined(WORDS_BIGENDIAN) -# if defined(__APPLE__) && defined (OSX) -# include <libkern/OSByteOrder.h> -# define LE2CPU16(x) OSSwapInt16(x) -# else -# define LE2CPU16(x) bswap_16(x) -# endif -#else -# define LE2CPU16(x) (x) -#endif +/* define a portable function for reading a 16bit little-endian word */ +unsigned short get_int16_le(const void *p) +{ + const unsigned char *cp = p; + + return ( cp[0] ) | ( ((unsigned short)cp[1]) << 8 ); +} int debug; static int verbose = 0; @@ -168,15 +162,20 @@ static int print_dfu_if(struct dfu_if *dfu_if, void *v) int if_name_str_idx; char name[MAX_STR_LEN+1] = "UNDEFINED"; - if_name_str_idx = dev->config[dfu_if->configuration].interface[dfu_if->interface].altsetting[dfu_if->altsetting].iInterface; + if_name_str_idx = dev->config[dfu_if->configuration] + .interface[dfu_if->interface] + .altsetting[dfu_if->altsetting].iInterface; if (if_name_str_idx) { if (!dfu_if->dev_handle) dfu_if->dev_handle = usb_open(dfu_if->dev); if (dfu_if->dev_handle) - usb_get_string_simple(dfu_if->dev_handle, if_name_str_idx, name, MAX_STR_LEN); + usb_get_string_simple(dfu_if->dev_handle, + if_name_str_idx, name, + MAX_STR_LEN); } - printf("Found %s: [0x%04x:0x%04x] devnum=%u, cfg=%u, intf=%u, alt=%u, name=\"%s\"\n", + printf("Found %s: [0x%04x:0x%04x] devnum=%u, cfg=%u, intf=%u, " + "alt=%u, name=\"%s\"\n", dfu_if->flags & DFU_IFF_DFU ? "DFU" : "Runtime", dev->descriptor.idVendor, dev->descriptor.idProduct, dev->devnum, dfu_if->configuration, dfu_if->interface, @@ -434,7 +433,7 @@ int main(int argc, char **argv) int page_size = getpagesize(); int ret; - printf("dfu-util - (C) 2007 by OpenMoko Inc.\n" + printf("dfu-util - (C) 2007-2008 by OpenMoko Inc.\n" "This program is Free Software and has ABSOLUTELY NO WARRANTY\n\n"); memset(dif, 0, sizeof(*dif)); @@ -446,7 +445,8 @@ int main(int argc, char **argv) while (1) { int c, option_index = 0; - c = getopt_long(argc, argv, "hVvld:p:c:i:a:t:U:D:R", opts, &option_index); + c = getopt_long(argc, argv, "hVvld:p:c:i:a:t:U:D:R", opts, + &option_index); if (c == -1) break; @@ -581,43 +581,53 @@ int main(int argc, char **argv) printf("Claiming USB DFU Runtime Interface...\n"); if (usb_claim_interface(_rt_dif.dev_handle, _rt_dif.interface) < 0) { - fprintf(stderr, "Cannot claim interface: %s\n", usb_strerror()); + fprintf(stderr, "Cannot claim interface: %s\n", + usb_strerror()); exit(1); } printf("Determining device status: "); if (dfu_get_status(_rt_dif.dev_handle, _rt_dif.interface, &status ) < 0) { - fprintf(stderr, "error get_status: %s\n", usb_strerror()); + fprintf(stderr, "error get_status: %s\n", + usb_strerror()); exit(1); } - printf("state = %s, status = %d\n", dfu_state_to_string(status.bState), status.bStatus); + printf("state = %s, status = %d\n", + dfu_state_to_string(status.bState), status.bStatus); switch (status.bState) { case DFU_STATE_appIDLE: case DFU_STATE_appDETACH: - printf("Device really in Runtime Mode, send DFU detach request...\n"); - if (dfu_detach(_rt_dif.dev_handle, _rt_dif.interface, 1000) < 0) { - fprintf(stderr, "error detaching: %s\n", usb_strerror()); + printf("Device really in Runtime Mode, send DFU " + "detach request...\n"); + if (dfu_detach(_rt_dif.dev_handle, + _rt_dif.interface, 1000) < 0) { + fprintf(stderr, "error detaching: %s\n", + usb_strerror()); exit(1); break; } printf("Resetting USB...\n"); ret = usb_reset(_rt_dif.dev_handle); if (ret < 0 && ret != -ENODEV) - fprintf(stderr, "error resetting after detach: %s\n", + fprintf(stderr, + "error resetting after detach: %s\n", usb_strerror()); sleep(2); break; case DFU_STATE_dfuERROR: printf("dfuERROR, clearing status\n"); - if (dfu_clear_status(_rt_dif.dev_handle, _rt_dif.interface) < 0) { - fprintf(stderr, "error clear_status: %s\n", usb_strerror()); + if (dfu_clear_status(_rt_dif.dev_handle, + _rt_dif.interface) < 0) { + fprintf(stderr, "error clear_status: %s\n", + usb_strerror()); exit(1); break; } break; default: - fprintf(stderr, "WARNING: Runtime device already in DFU state ?!?\n"); + fprintf(stderr, "WARNING: Runtime device already " + "in DFU state ?!?\n"); goto dfustate; break; } @@ -646,9 +656,9 @@ int main(int argc, char **argv) fprintf(stderr, "Lost device after RESET?\n"); exit(1); } else if (num_devs > 1) { - fprintf(stderr, "More than one DFU capable USB device found, " - "you might try `--list' and then disconnect all but one " - "device\n"); + fprintf(stderr, "More than one DFU capable USB " + "device found, you might try `--list' and " + "then disconnect all but one device\n"); exit(1); } if (!get_first_dfu_device(dif)) @@ -657,7 +667,8 @@ int main(int argc, char **argv) printf("Opening USB Device...\n"); dif->dev_handle = usb_open(dif->dev); if (!dif->dev_handle) { - fprintf(stderr, "Cannot open device: %s\n", usb_strerror()); + fprintf(stderr, "Cannot open device: %s\n", + usb_strerror()); exit(1); } } else { @@ -690,7 +701,8 @@ dfustate: exit(1); } else if (num_ifs == 1) { if (!get_first_dfu_if(dif)) { - fprintf(stderr, "Can't find the single available DFU IF\n"); + fprintf(stderr, "Can't find the single available " + "DFU IF\n"); exit(1); } } else if (num_ifs > 1 && !dif->flags & (DFU_IFF_IFACE|DFU_IFF_ALT)) { @@ -703,13 +715,15 @@ dfustate: #if 0 printf("Setting Configuration %u...\n", dif->configuration); if (usb_set_configuration(dif->dev_handle, dif->configuration) < 0) { - fprintf(stderr, "Cannot set configuration: %s\n", usb_strerror()); + fprintf(stderr, "Cannot set configuration: %s\n", + usb_strerror()); exit(1); } #endif printf("Claiming USB DFU Interface...\n"); if (usb_claim_interface(dif->dev_handle, dif->interface) < 0) { - fprintf(stderr, "Cannot claim interface: %s\n", usb_strerror()); + fprintf(stderr, "Cannot claim interface: %s\n", + usb_strerror()); exit(1); } @@ -726,7 +740,8 @@ status_again: fprintf(stderr, "error get_status: %s\n", usb_strerror()); exit(1); } - printf("state = %s, status = %d\n", dfu_state_to_string(status.bState), status.bStatus); + printf("state = %s, status = %d\n", + dfu_state_to_string(status.bState), status.bStatus); switch (status.bState) { case DFU_STATE_appIDLE: @@ -737,7 +752,8 @@ status_again: case DFU_STATE_dfuERROR: printf("dfuERROR, clearing status\n"); if (dfu_clear_status(dif->dev_handle, dif->interface) < 0) { - fprintf(stderr, "error clear_status: %s\n", usb_strerror()); + fprintf(stderr, "error clear_status: %s\n", + usb_strerror()); exit(1); } goto status_again; @@ -746,7 +762,8 @@ status_again: case DFU_STATE_dfuUPLOAD_IDLE: printf("aborting previous incomplete transfer\n"); if (dfu_abort(dif->dev_handle, dif->interface) < 0) { - fprintf(stderr, "can't send DFU_ABORT: %s\n", usb_strerror()); + fprintf(stderr, "can't send DFU_ABORT: %s\n", + usb_strerror()); exit(1); } goto status_again; @@ -765,8 +782,7 @@ status_again: "descriptor: %s\n", usb_strerror()); transfer_size = page_size; } else { - func_dfu.wTransferSize = LE2CPU16(func_dfu.wTransferSize); - transfer_size = func_dfu.wTransferSize; + transfer_size = get_int16_le(&func_dfu.wTransferSize); } } diff --git a/src/sam7dfu.c b/src/sam7dfu.c index 536b2e1..e309bc7 100644 --- a/src/sam7dfu.c +++ b/src/sam7dfu.c @@ -1,5 +1,7 @@ /* This is supposed to be a "real" DFU implementation, just as specified in the * USB DFU 1.0 Spec. Not overloaded like the Atmel one... + * + * (C) 2007-2008 by Harald Welte <laforge@gnumonks.org> */ #include <stdio.h> @@ -36,6 +38,10 @@ int sam7dfu_do_upload(struct usb_dev_handle *usb_handle, int interface, goto out_free; } + printf("bytes_per_hash=%u\n", xfer_size); + printf("Starting upload: ["); + fflush(stdout); + while (1) { int rc, write_rc; rc = dfu_upload(usb_handle, interface, xfer_size, buf); @@ -45,7 +51,7 @@ int sam7dfu_do_upload(struct usb_dev_handle *usb_handle, int interface, } write_rc = write(fd, buf, rc); if (write_rc < rc) { - fprintf(stderr, "Short write: %s\n", + fprintf(stderr, "Short file write: %s\n", strerror(errno)); ret = total_bytes; goto out_close; @@ -56,9 +62,14 @@ int sam7dfu_do_upload(struct usb_dev_handle *usb_handle, int interface, ret = total_bytes; goto out_close; } + putchar('#'); + fflush(stdout); } ret = 0; + printf("] finished!\n"); + fflush(stdout); + out_close: close(fd); out_free: |