Carpe diem, c'est la vie.
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
|
Here is the original:
And here is a copy that I modified a bit to report kindles it detects in various modes:
PHP Code:
/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Copyright (C) 2010 Amaury Pouly * * 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 2 * of the License, or (at your option) any later version. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <libusb.h> //#include <usb.h> #include <stdint.h>
void put32le(uint8_t *buf, uint32_t i) { *buf++ = i & 0xff; *buf++ = (i >> 8) & 0xff; *buf++ = (i >> 16) & 0xff; *buf++ = (i >> 24) & 0xff; }
void put32be(uint8_t *buf, uint32_t i) { *buf++ = (i >> 24) & 0xff; *buf++ = (i >> 16) & 0xff; *buf++ = (i >> 8) & 0xff; *buf++ = i & 0xff; }
struct dev_info_t { uint16_t vendor_id; uint16_t product_id; unsigned xfer_size; };
struct dev_info_t g_dev_info[] = { {0x15A2, 0x0052, 1024}, /* i.MX50 USB Downloader */ {0x1949, 0x0004, 1024}, /* lab126 Kindle USB Drive */ {0x1949, 0xD0D0, 1024}, /* lab126 fastboot */ };
int main(int argc, char **argv) { int ret; FILE *f; int i, xfer_size, nr_xfers, recv_size;
if(argc != 3) { printf("usage: %s <xfer size> <file>\n", argv[0]); printf("If <xfer size> is set to zero, the preferred one is used.\n"); return 1; }
char *end; xfer_size = strtol(argv[1], &end, 0); if(end != (argv[1] + strlen(argv[1]))) { printf("Invalid transfer size !\n"); return 1; } libusb_device_handle *dev; libusb_init(NULL); libusb_set_debug(NULL, 3);
for(unsigned i = 0; i < sizeof(g_dev_info) / sizeof(g_dev_info[0]); i++) { dev = libusb_open_device_with_vid_pid(NULL, g_dev_info[i].vendor_id, g_dev_info[i].product_id); if(dev == NULL) continue; if(xfer_size == 0) xfer_size = g_dev_info[i].xfer_size; printf("Found a match for %04x:%04x\n", g_dev_info[i].vendor_id, g_dev_info[i].product_id); break; } if(dev == NULL) { printf("Cannot open device\n"); return 1; } libusb_detach_kernel_driver(dev, 0); libusb_detach_kernel_driver(dev, 4); libusb_claim_interface (dev, 0); libusb_claim_interface (dev, 4); if(!dev) { printf("No dev\n"); exit(1); }
f = fopen(argv[2], "r"); if(f == NULL) { perror("cannot open file"); return 1; } fseek(f, 0, SEEK_END); size_t size = ftell(f); fseek(f, 0, SEEK_SET);
printf("Transfer size: %d\n", xfer_size); nr_xfers = (size + xfer_size - 1) / xfer_size; uint8_t *file_buf = malloc(nr_xfers * xfer_size); memset(file_buf, 0xff, nr_xfers * xfer_size); // pad with 0xff if(fread(file_buf, size, 1, f) != 1) { perror("read error"); fclose(f); return 1; } fclose(f); uint8_t *xfer_buf = malloc(1 + xfer_size); uint8_t *p = xfer_buf; *p++ = 0x01; /* Report id */ /* Command block wrapper */ *p++ = 'B'; /* Signature */ *p++ = 'L'; *p++ = 'T'; *p++ = 'C'; put32le(p, 0x1); /* Tag */ p += 4; put32le(p, size); /* Payload size */ p += 4; *p++ = 0; /* Flags (host to device) */ p += 2; /* Reserved */ /* Command descriptor block */ *p++ = 0x02; /* Firmware download */ put32be(p, size); /* Download size */ ret = libusb_control_transfer(dev, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, 0x9, 0x201, 0, xfer_buf, xfer_size + 1, 1000); if(ret < 0) { printf("transfer error at init step\n"); return 1; }
for(i = 0; i < nr_xfers; i++) { xfer_buf[0] = 0x2; memcpy(&xfer_buf[1], &file_buf[i * xfer_size], xfer_size); ret = libusb_control_transfer(dev, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, 0x9, 0x202, 0, xfer_buf, xfer_size + 1, 1000); if(ret < 0) { printf("transfer error at send step %d\n", i); return 1; } }
ret = libusb_interrupt_transfer(dev, 0x81, xfer_buf, xfer_size, &recv_size, 1000); if(ret < 0) { printf("transfer error at final stage\n"); return 1; } printf("ret %i\n", ret); return 0; }
And here is my Makefile:
PHP Code:
DEFINES=-DCRYPTO_LIBUSB CC=gcc LD=gcc CFLAGS=-g -std=c99 -W -Wall `pkg-config --cflags libusb-1.0` $(DEFINES) LDFLAGS=`pkg-config --libs libusb-1.0` BINS=sbloader fastboot
all: $(BINS)
%.o: %.c $(CC) $(CFLAGS) -c -o $@ $<
sbloader: sbloader.o $(LD) -o $@ $^ $(LDFLAGS)
fastboot: fastboot.o $(LD) -o $@ $^ protocol.o engine.o util_linux.o usb_linux.o -lpthread
clean: rm -fr *.o
veryclean: rm -rf $(BINS)
Enjoy!
EDIT: My simple modifications to this sbloader.c program are not yet complete. It is one of my many "in-progress" projects. It needs more work to upload files to the kindle. And the makefile is for a version or fastboot that has similar changes. I plan to merge them to support both usb downloader and fastboot in one program, to simplify the "simple debricking" process. And I want to add a GUI wrapper too.
EDIT: Notice in the Makefile that you need to install libusb-1.0 to compile this.
Last edited by geekmaster; 03-09-2012 at 10:22 AM.
|