[U-Boot] [PATCH 9/9] dfu: Support larger than memory transfers.
Pantelis Antoniou
panto at antoniou-consulting.com
Fri Jan 4 18:23:03 CET 2013
Hi Kasim,
On Jan 3, 2013, at 10:30 AM, kasim ling wrote:
> Hi, Pantelis,
> A little confusion about FAT fs write supporting,
>
>
> On Sat, Dec 1, 2012 at 12:51 AM, Pantelis Antoniou
> <panto at antoniou-consulting.com> wrote:
>>
>> We didn't support upload/download larger than available memory.
>> This is pretty bad when you have to update your root filesystem for
>> example.
>>
>> This patch removes the limitation (and the crashes when you transfered
>> any file larger than 4MB).
>> On top of that reduces the huge dfu buffer from 4MB to just 64K, which
>> was over the top.
>>
>> The sequence number is a 16 bit counter; make sure we
>> handle rollover correctly. This fixes the wrong transfers for
>> large (> 256MB) images.
>>
>> Also utilize a variable to handle initialization, so that we
>> don't rely on just the counter sent by the host.
>>
>> Signed-off-by: Pantelis Antoniou <panto at antoniou-consulting.com>
>> ---
>> drivers/dfu/dfu.c | 244 +++++++++++++++++++++++++++++++++++++++-----------
>> drivers/dfu/dfu_mmc.c | 82 +++++++++++------
>> include/dfu.h | 21 ++++-
>> 3 files changed, 264 insertions(+), 83 deletions(-)
>
>> diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c
>> index 083d745..29a2c2e 100644
>> --- a/drivers/dfu/dfu_mmc.c
>> +++ b/drivers/dfu/dfu_mmc.c
>> @@ -22,6 +22,7 @@
>> #include <common.h>
>> #include <malloc.h>
>> #include <errno.h>
>> +#include <div64.h>
>> #include <dfu.h>
>>
>> enum dfu_mmc_op {
>> @@ -30,35 +31,48 @@ enum dfu_mmc_op {
>> };
>>
>> static int mmc_block_op(enum dfu_mmc_op op, struct dfu_entity *dfu,
>> - void *buf, long *len)
>> + u64 offset, void *buf, long *len)
>> {
>> char cmd_buf[DFU_CMD_BUF_SIZE];
>> + u32 blk_start, blk_count;
>>
>> - sprintf(cmd_buf, "mmc %s 0x%x %x %x",
>> - op == DFU_OP_READ ? "read" : "write",
>> - (unsigned int) buf,
>> - dfu->data.mmc.lba_start,
>> - dfu->data.mmc.lba_size);
>> -
>> - if (op == DFU_OP_READ)
>> + /* if buf == NULL return total size of the area */
>> + if (buf == NULL) {
>> *len = dfu->data.mmc.lba_blk_size * dfu->data.mmc.lba_size;
>> + return 0;
>> + }
>> +
>> + blk_start = dfu->data.mmc.lba_start +
>> + (u32)lldiv(offset, dfu->data.mmc.lba_blk_size);
>> + blk_count = *len / dfu->data.mmc.lba_blk_size;
>> + if (blk_start + blk_count >
>> + dfu->data.mmc.lba_start + dfu->data.mmc.lba_size) {
>> + debug("%s: block_op out of bounds\n", __func__);
>> + return -1;
>> + }
>> +
>> + sprintf(cmd_buf, "mmc %s %p %x %x",
>> + op == DFU_OP_READ ? "read" : "write",
>> + buf, blk_start, blk_count);
>>
>> debug("%s: %s 0x%p\n", __func__, cmd_buf, cmd_buf);
>> return run_command(cmd_buf, 0);
>> }
>>
>> -static inline int mmc_block_write(struct dfu_entity *dfu, void *buf, long *len)
>> +static inline int mmc_block_write(struct dfu_entity *dfu,
>> + u64 offset, void *buf, long *len)
>> {
>> - return mmc_block_op(DFU_OP_WRITE, dfu, buf, len);
>> + return mmc_block_op(DFU_OP_WRITE, dfu, offset, buf, len);
>> }
>>
>> -static inline int mmc_block_read(struct dfu_entity *dfu, void *buf, long *len)
>> +static inline int mmc_block_read(struct dfu_entity *dfu,
>> + u64 offset, void *buf, long *len)
>> {
>> - return mmc_block_op(DFU_OP_READ, dfu, buf, len);
>> + return mmc_block_op(DFU_OP_READ, dfu, offset, buf, len);
>> }
>>
>> static int mmc_file_op(enum dfu_mmc_op op, struct dfu_entity *dfu,
>> - void *buf, long *len)
>> + u64 offset, void *buf, long *len)
>> {
>> char cmd_buf[DFU_CMD_BUF_SIZE];
>> char *str_env;
>> @@ -66,12 +80,17 @@ static int mmc_file_op(enum dfu_mmc_op op, struct dfu_entity *dfu,
>>
>> switch (dfu->layout) {
>> case DFU_FS_FAT:
>> - sprintf(cmd_buf, "fat%s mmc %d:%d 0x%x %s %lx",
>> + sprintf(cmd_buf, "fat%s mmc %d:%d 0x%x %s %lx %llx",
>> op == DFU_OP_READ ? "load" : "write",
>> dfu->data.mmc.dev, dfu->data.mmc.part,
>> - (unsigned int) buf, dfu->name, *len);
>> + (unsigned int) buf, dfu->name, *len, offset);
> Did you tested it on FAT partitions? According to do_fat_fswrite()
> defined in common/cmd_fat.c, the "fatwrite" command does not support
> "offset" argument.
>
No I haven't had a use case either for fat or ext2/3/4.
So I guess it is as broken as it was before.
If you want to write to a file, make sure it's smaller than the
DFU buffer.
One of these days the file access functions must be fixed.
>
> Thanks,
> Alex
Regards
-- Pantelis
More information about the U-Boot
mailing list