Ticket #1843 (closed defect: fixed)
u-boot's DFU upload garbles data at block boundary
|Reported by:||wiml||Owned by:||laforge|
|Blocking:||#676||Estimated Completion (week):|
I was trying to verify my downloaded kernel by re-uploading it again to compare. The uploaded version differed in an interesting way: at offset 0x01f000, exactly 0x20000 bytes were missing (so that the uploaded file contained at 0x01f000 the data that was at 0x03f000 in the original file). This does not seem to be a dfu-util bug, but a u-boot bug.
Looking at the u-boot source code, I think the problem is in handle_upload() in usbdfu.c, where it handles the wraparound at the end of the NAND block. There are three bugs here:
- when it copies a new blockful of data, it copies it into the same buffer that urb->buffer was already pointing to, thus overwriting the beginning of the last buffer before it is sent back to the requestor
- it then calls memcpy() to copy the beginning of the newly-read block to after the end of the buffer that urb->buffer is pointing to. If ds->nand->erasesize is the same as the _buf array, then this will write past the end of the _buf array and smash some other item in RAM.
- if a requested buffer exactly reaches the end of the block that's been buffered in ds->buf, then handle_upload() will read a new NAND block into the buffer even though it is not needed. (The test for (len > remain) should probably go before the test for ds->ptr, not after?)
I would submit a patch, but I don't have a build environment set up for uboot (or any jtag hardware for recovery from bad flashing, for that matter) --- this is just from reading the uboot-dfu.patch file in svn.
I also wonder if this is related to ticket #676, although the comments in that bug indicate corruption starting at 0x3001, not 0x1f000, so it may be unrelated.
- Keywords dfu added
- Owner changed from openmoko-devel to openmoko-kernel
- Component changed from unknown to System Software
- Owner changed from openmoko-kernel to laforge
- Status changed from new to assigned