diff --git a/Makefile b/Makefile index 961f66e..5f8fb69 100644 --- a/Makefile +++ b/Makefile @@ -58,14 +58,14 @@ jtag-loop.bin: jtag-loop.elf jtag-loop.sunxi: jtag-loop.bin mksunxiboot jtag-loop.bin jtag-loop.sunxi -fel-boot.elf: fel-boot.c fel-boot.lds - $(CROSS_COMPILE)gcc -g -Os -fpic -fno-common -fno-builtin -ffreestanding -nostdinc -mno-thumb-interwork -Wall -Wstrict-prototypes -fno-stack-protector -Wno-format-nonliteral -Wno-format-security -fno-toplevel-reorder fel-boot.c -nostdlib -o fel-boot.elf -T fel-boot.lds -Wl,-N +fel-sdboot.elf: fel-sdboot.c fel-sdboot.lds + $(CROSS_COMPILE)gcc -g -Os -fpic -fno-common -fno-builtin -ffreestanding -nostdinc -mno-thumb-interwork -Wall -Wstrict-prototypes -fno-stack-protector -Wno-format-nonliteral -Wno-format-security -fno-toplevel-reorder fel-sdboot.c -nostdlib -o fel-sdboot.elf -T fel-sdboot.lds -Wl,-N -fel-boot.bin: fel-boot.elf - $(CROSS_COMPILE)objcopy -O binary fel-boot.elf fel-boot.bin +fel-sdboot.bin: fel-sdboot.elf + $(CROSS_COMPILE)objcopy -O binary fel-sdboot.elf fel-sdboot.bin -fel-boot.sunxi: fel-boot.bin - mksunxiboot fel-boot.bin fel-boot.sunxi +fel-sdboot.sunxi: fel-sdboot.bin + mksunxiboot fel-sdboot.bin fel-sdboot.sunxi boot_head_sun3i.elf: boot_head_sun3i.S boot_head_sun3i.lds $(CROSS_COMPILE)gcc -g -Os -fpic -fno-common -fno-builtin -ffreestanding -nostdinc -mno-thumb-interwork -Wall -Wstrict-prototypes -fno-stack-protector -Wno-format-nonliteral -Wno-format-security -fno-toplevel-reorder boot_head.S -nostdlib -o boot_head_sun3i.elf -T boot_head.lds -Wl,-N -DMACHID=0x1094 diff --git a/README b/README index 051215b..506930f 100644 --- a/README +++ b/README @@ -26,11 +26,18 @@ fel: th CPU. You activate FEL mode by pushing the usboot/recovery button at poweron. +usb-boot: + Simple wrapper to automate USB booting in FEL mode + See http://linux-sunxi.org/FEL/USBBoot for details + fel-gpio: Simple wrapper around fel-pio and fel to allos GPIO manipulations via FEL + +fel-sdboot: + ARM native sdcard bootloader forcing the device into FEL mode -fel-pio.bin: +fel-pio: ARM native helper for fel-gpio pio: diff --git a/bin/fel-boot-a13_olinuxino.bin b/bin/fel-boot-a13_olinuxino.bin new file mode 100755 index 0000000..2d3ed4b Binary files /dev/null and b/bin/fel-boot-a13_olinuxino.bin differ diff --git a/bin/fel-boot-cubieboard.bin b/bin/fel-boot-cubieboard.bin new file mode 100755 index 0000000..3cceec1 Binary files /dev/null and b/bin/fel-boot-cubieboard.bin differ diff --git a/bin/fel-boot-eoma68-a10.bin b/bin/fel-boot-eoma68-a10.bin new file mode 100755 index 0000000..c877ea5 Binary files /dev/null and b/bin/fel-boot-eoma68-a10.bin differ diff --git a/bin/fel-boot-mele_a1000.bin b/bin/fel-boot-mele_a1000.bin new file mode 100755 index 0000000..7c6a31f Binary files /dev/null and b/bin/fel-boot-mele_a1000.bin differ diff --git a/bin/fel-sdboot.sunxi b/bin/fel-sdboot.sunxi new file mode 100644 index 0000000..6d3bbb2 Binary files /dev/null and b/bin/fel-sdboot.sunxi differ diff --git a/bin/ramboot.scr b/bin/ramboot.scr new file mode 100644 index 0000000..944aa58 Binary files /dev/null and b/bin/ramboot.scr differ diff --git a/fel-gpio b/fel-gpio index dc10c2a..11bb194 100755 --- a/fel-gpio +++ b/fel-gpio @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/sh -e pio_to_sram=0x2000 sram_to_pio=0x2004 @@ -13,6 +13,7 @@ fi ./fel read 0x3000 0x228 pio.reg ./pio -i pio.reg print > pio.old cat pio.old | fgrep -v '<0><0><0><0>' + while read cmd; do ./pio -i pio.reg -o pio.reg $cmd ./fel write 0x3000 pio.reg @@ -20,6 +21,6 @@ while read cmd; do ./fel exe 0x2000 ./fel read 0x3000 0x228 pio.reg ./pio -i pio.reg print > pio.new - diff -U0 pio.old pio.new + diff -U0 pio.old pio.new || true mv -f pio.new pio.old done diff --git a/fel-boot.c b/fel-sdboot.c similarity index 100% rename from fel-boot.c rename to fel-sdboot.c diff --git a/fel.c b/fel.c index 2b1ef4d..10720ce 100644 --- a/fel.c +++ b/fel.c @@ -138,7 +138,7 @@ void aw_fel_get_version(libusb_device_handle *usb) { struct aw_fel_version { char signature[8]; - uint32_t unknown_08; /* 0x00162300 */ + uint32_t soc_id; /* 0x00162300 */ uint32_t unknown_0a; /* 1 */ uint16_t protocol; /* 1 */ uint8_t unknown_12; /* 0x44 */ @@ -151,14 +151,22 @@ void aw_fel_get_version(libusb_device_handle *usb) aw_usb_read(usb, &buf, sizeof(buf)); aw_read_fel_status(usb); - buf.unknown_08 = le32toh(buf.unknown_08); + buf.soc_id = le32toh(buf.soc_id); buf.unknown_0a = le32toh(buf.unknown_0a); buf.protocol = le32toh(buf.protocol); buf.scratchpad = le16toh(buf.scratchpad); buf.pad[0] = le32toh(buf.pad[0]); buf.pad[1] = le32toh(buf.pad[1]); - printf("%.8s %08x %08x ver=%04x %02x %02x scratchpad=%08x %08x %08x\n", buf.signature, buf.unknown_08, buf.unknown_0a, buf.protocol, buf.unknown_12, buf.unknown_13, buf.scratchpad, buf.pad[0], buf.pad[1]); + const char *soc_name="unknown"; + switch ((buf.soc_id >> 8) & 0xFFFF) { + case 0x1623: soc_name="A10";break; + case 0x1625: soc_name="A13";break; + case 0x1633: soc_name="A31";break; + case 0x1651: soc_name="A20";break; + } + + printf("%.8s soc=%08x(%s) %08x ver=%04x %02x %02x scratchpad=%08x %08x %08x\n", buf.signature, buf.soc_id, soc_name, buf.unknown_0a, buf.protocol, buf.unknown_12, buf.unknown_13, buf.scratchpad, buf.pad[0], buf.pad[1]); } void aw_fel_read(libusb_device_handle *usb, uint32_t offset, void *buf, size_t len) @@ -271,6 +279,7 @@ int main(int argc, char **argv) { int rc; libusb_device_handle *handle = NULL; + int iface_detached = -1; rc = libusb_init(NULL); assert(rc == 0); @@ -290,10 +299,17 @@ int main(int argc, char **argv) handle = libusb_open_device_with_vid_pid(NULL, 0x1f3a, 0xefe8); if (!handle) { - fprintf(stderr, "A10 USB FEL device not found!"); + fprintf(stderr, "ERROR: Allwinner USB FEL device not found!\n"); exit(1); } rc = libusb_claim_interface(handle, 0); +#if defined(__linux__) + if (rc != LIBUSB_SUCCESS) { + libusb_detach_kernel_driver(handle, 0); + iface_detached = 0; + rc = libusb_claim_interface(handle, 0); + } +#endif assert(rc == 0); while (argc > 1 ) { @@ -338,5 +354,10 @@ int main(int argc, char **argv) argv+=skip; } +#if defined(__linux__) + if (iface_detached >= 0) + libusb_attach_kernel_driver(handle, iface_detached); +#endif + return 0; } diff --git a/nand-part.c b/nand-part.c index 4e9e38b..a7db88e 100644 --- a/nand-part.c +++ b/nand-part.c @@ -49,12 +49,15 @@ #include #include #include +#include #include #include /* BLKRRPART */ #include "nand-part.h" #define MAX_NAME 16 +void printmbrheader(MBR *mbr); + typedef struct tag_CRC32_DATA { __u32 CRC; //int的大小是32位 @@ -94,6 +97,8 @@ __u32 calc_crc32(void * buffer, __u32 length) MBR *_get_mbr(int fd, int mbr_num) { MBR *mbr; + const char * magic = "softw311"; + unsigned version = 0x100; /*request mbr space*/ mbr = malloc(sizeof(MBR)); @@ -109,6 +114,17 @@ MBR *_get_mbr(int fd, int mbr_num) { /*checksum*/ printf("check partition table copy %d: ", mbr_num); + printmbrheader(mbr); + if(strncmp((char *)mbr->magic, magic, 8)) + { + printf("magic %8.8s is not %8s\n", mbr->magic, magic); + return NULL; + } + if(mbr->version != version) + { + printf("version 0x%08x is not 0x%08x\n", mbr->version, version); + return NULL; + } if(*(__u32 *)mbr == calc_crc32((__u32 *)mbr + 1,MBR_SIZE - 4)) { printf("OK\n"); @@ -130,6 +146,30 @@ __s32 _free_mbr(MBR *mbr) return 0; } +void printmbrheader(MBR *mbr) +{ + printf("mbr: version 0x%08x, magic %8.8s\n", mbr->version, mbr->magic); +} + +void printmbr(MBR *mbr) +{ + int part_cnt; + + printmbrheader(mbr); + for(part_cnt = 0; part_cnt < mbr->PartCount && part_cnt < MAX_PART_COUNT; part_cnt++) + { + if(1 || (mbr->array[part_cnt].user_type == 2) || (mbr->array[part_cnt].user_type == 0)) + { + printf("partition %2d: class = %12s, name = %12s, partition start = %8d, partition size = %8d user_type=%d\n", + part_cnt, + mbr->array[part_cnt].classname, + mbr->array[part_cnt].name, + mbr->array[part_cnt].addrlo, + mbr->array[part_cnt].lenlo, + mbr->array[part_cnt].user_type); + } + } +} void checkmbrs(int fd) { int part_cnt = 0; diff --git a/pio.c b/pio.c index ea2bf35..e48a660 100644 --- a/pio.c +++ b/pio.c @@ -392,7 +392,7 @@ int main(int argc, char **argv) } } if (in) { - if (fread(buf, sizeof(buf), 1, in) != 1) { + if (fread(buf, PIO_REG_SIZE, 1, in) != 1) { perror("read input"); exit(1); } @@ -414,7 +414,7 @@ int main(int argc, char **argv) exit(1); } } - if (fwrite(buf, sizeof(buf), 1, out) != 1) { + if (fwrite(buf, PIO_REG_SIZE, 1, out) != 1) { perror("write output"); exit(1); } diff --git a/script_fex.c b/script_fex.c index 50e8d2b..361e86b 100644 --- a/script_fex.c +++ b/script_fex.c @@ -326,7 +326,7 @@ int script_parse_fex(FILE *in, const char *filename, struct script *script) perror("malloc"); } } - } else if (isdigit(*p)) { + } else if (isdigit(*p) || (*p == '-' && isdigit(*(p+1)))) { long long v = 0; char *end; v = strtoll(p, &end, 0); diff --git a/usb-boot b/usb-boot new file mode 100755 index 0000000..a999236 --- /dev/null +++ b/usb-boot @@ -0,0 +1,60 @@ +#!/bin/sh -e +top=`dirname $0` +if [ $# -lt 2 ]; then + echo "Usage: $0 board u-boot.bin [boot.scr|-] [kernel script.bin [initramfs]]" + exit 1 +fi +board=$1; shift || (echo "ERROR: Board must be specified"; exit 1;) +uboot=$1; shift || (echo "ERROR: u-boot.bin must be specified"; exit 1;) +bootscr=$top/felboot/ramboot.scr +if [ ! -f $bootscr ]; then + bootscr=$top/bin/ramboot.scr +fi +case "$1" in +*.scr) bootscr="$1"; shift + ;; +esac +kernel=$1; shift || true +scriptbin=$1; shift || true +initramfs=$1; shift || true +fel() { + echo fel "$@" + $top/fel $@ +} +case $board in +*/*) felboot=$board + ;; +*) + felboot=$top/felboot/fel-boot-${board}.bin + if [ ! -f $felboot ]; then + felboot=$top/bin/fel-boot-${board}.bin + fi + ;; +esac +if [ ! -f $felboot ]; then + echo "ERROR: Can't find fel-boot binary for ${board}" + exit 1 +fi +if [ ! -f $bootscr ]; then + echo "ERROR: Can't fint boot script '${bootscr}'" + exit 1 +fi +fel write 0x2000 $felboot +fel exe 0x2000 +sleep 1 # Wait for DRAM initialization to complete +if [ -n "$uboot" ]; then + fel write 0x4a000000 $uboot +fi +if [ -n "$bootscr" ]; then + fel write 0x41000000 $bootscr +fi +if [ -n "$kernel" ]; then + if [ -n "$scriptbin" ]; then + fel write 0x43000000 $scriptbin + fi + fel write 0x44000000 $kernel + if [ -n "$initramfs" ]; then + fel write 0x4c000000 $initramfs + fi +fi +fel exe 0x4a000000