mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-08-21 01:18:52 +09:00
![Afzal Mohammed](/assets/img/avatar_default.png)
DFU spec mentions it as a method to upgrade firmware (software stored in writable non-volatile memory). It also says other potential uses of DFU is beyond scope of the spec. Here such a beyond the scope use is being attempted - directly pumping binary images from host via USB to RAM. This facility is a developer centric one in that it gives advantage over upgrading non-volatile memory for testing new images every time during development and/or testing. Directly putting image onto RAM would speed up upgrade process. This and convenience was the initial thoughts that led to doing this, speed improvement over MMC was only 1 second though - 6 sec on RAM as opposed to 7 sec on MMC in beagle bone, perhaps enabling cache and/or optimizing DFU framework to avoid multiple copy for ram (if worth) may help, and on other platforms and other boot media like NAND maybe improvement would be higher. And for a platform that doesn't yet have proper DFU suppport for non-volatile media's, DFU to RAM can be used. Another minor advantage would be to increase life of mmc/nand as it would be less used during development/testing. usage: <image name> ram <start address> <size> eg. kernel ram 0x81000000 0x1000000 Downloading images to RAM using DFU is not something new, this is acheived in openmoko also. DFU on RAM can be used for extracting RAM contents to host using dfu upload. Perhaps this can be extended to io for squeezing out register dump through usb, if it is worth. Signed-off-by: Afzal Mohammed <afzal.mohd.ma@gmail.com> Cc: Heiko Schocher <hs@denx.de> Cc: Marek Vasut <marex@denx.de> Cc: Lukasz Majewski <l.majewski@samsung.com> Cc: Pantelis Antoniou <panto@antoniou-consulting.com> Cc: Gerhard Sittig <gsi@denx.de> Acked-by: Marek Vasut <marex@denx.de> Acked-by: Lukasz Majewski <l.majewski@samsung.com> Acked-by: Heiko Schocher <hs@denx.de>
165 lines
3.4 KiB
C
165 lines
3.4 KiB
C
/*
|
|
* dfu.h - DFU flashable area description
|
|
*
|
|
* Copyright (C) 2012 Samsung Electronics
|
|
* authors: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
|
|
* Lukasz Majewski <l.majewski@samsung.com>
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0+
|
|
*/
|
|
|
|
#ifndef __DFU_ENTITY_H_
|
|
#define __DFU_ENTITY_H_
|
|
|
|
#include <common.h>
|
|
#include <linux/list.h>
|
|
#include <mmc.h>
|
|
|
|
enum dfu_device_type {
|
|
DFU_DEV_MMC = 1,
|
|
DFU_DEV_ONENAND,
|
|
DFU_DEV_NAND,
|
|
DFU_DEV_RAM,
|
|
};
|
|
|
|
enum dfu_layout {
|
|
DFU_RAW_ADDR = 1,
|
|
DFU_FS_FAT,
|
|
DFU_FS_EXT2,
|
|
DFU_FS_EXT3,
|
|
DFU_FS_EXT4,
|
|
DFU_RAM_ADDR,
|
|
};
|
|
|
|
enum dfu_op {
|
|
DFU_OP_READ = 1,
|
|
DFU_OP_WRITE,
|
|
};
|
|
|
|
struct mmc_internal_data {
|
|
/* RAW programming */
|
|
unsigned int lba_start;
|
|
unsigned int lba_size;
|
|
unsigned int lba_blk_size;
|
|
|
|
/* FAT/EXT */
|
|
unsigned int dev;
|
|
unsigned int part;
|
|
};
|
|
|
|
struct nand_internal_data {
|
|
/* RAW programming */
|
|
u64 start;
|
|
u64 size;
|
|
|
|
unsigned int dev;
|
|
unsigned int part;
|
|
/* for nand/ubi use */
|
|
unsigned int ubi;
|
|
};
|
|
|
|
struct ram_internal_data {
|
|
void *start;
|
|
unsigned int size;
|
|
};
|
|
|
|
static inline unsigned int get_mmc_blk_size(int dev)
|
|
{
|
|
return find_mmc_device(dev)->read_bl_len;
|
|
}
|
|
|
|
#define DFU_NAME_SIZE 32
|
|
#define DFU_CMD_BUF_SIZE 128
|
|
#ifndef CONFIG_SYS_DFU_DATA_BUF_SIZE
|
|
#define CONFIG_SYS_DFU_DATA_BUF_SIZE (1024*1024*8) /* 8 MiB */
|
|
#endif
|
|
#ifndef CONFIG_SYS_DFU_MAX_FILE_SIZE
|
|
#define CONFIG_SYS_DFU_MAX_FILE_SIZE CONFIG_SYS_DFU_DATA_BUF_SIZE
|
|
#endif
|
|
|
|
struct dfu_entity {
|
|
char name[DFU_NAME_SIZE];
|
|
int alt;
|
|
void *dev_private;
|
|
int dev_num;
|
|
enum dfu_device_type dev_type;
|
|
enum dfu_layout layout;
|
|
|
|
union {
|
|
struct mmc_internal_data mmc;
|
|
struct nand_internal_data nand;
|
|
struct ram_internal_data ram;
|
|
} data;
|
|
|
|
int (*read_medium)(struct dfu_entity *dfu,
|
|
u64 offset, void *buf, long *len);
|
|
|
|
int (*write_medium)(struct dfu_entity *dfu,
|
|
u64 offset, void *buf, long *len);
|
|
|
|
int (*flush_medium)(struct dfu_entity *dfu);
|
|
|
|
struct list_head list;
|
|
|
|
/* on the fly state */
|
|
u32 crc;
|
|
u64 offset;
|
|
int i_blk_seq_num;
|
|
u8 *i_buf;
|
|
u8 *i_buf_start;
|
|
u8 *i_buf_end;
|
|
long r_left;
|
|
long b_left;
|
|
|
|
u32 bad_skip; /* for nand use */
|
|
|
|
unsigned int inited:1;
|
|
};
|
|
|
|
int dfu_config_entities(char *s, char *interface, int num);
|
|
void dfu_free_entities(void);
|
|
void dfu_show_entities(void);
|
|
int dfu_get_alt_number(void);
|
|
const char *dfu_get_dev_type(enum dfu_device_type t);
|
|
const char *dfu_get_layout(enum dfu_layout l);
|
|
struct dfu_entity *dfu_get_entity(int alt);
|
|
char *dfu_extract_token(char** e, int *n);
|
|
void dfu_trigger_reset(void);
|
|
bool dfu_reset(void);
|
|
int dfu_init_env_entities(char *interface, int dev);
|
|
|
|
int dfu_read(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
|
|
int dfu_write(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
|
|
/* Device specific */
|
|
#ifdef CONFIG_DFU_MMC
|
|
extern int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s);
|
|
#else
|
|
static inline int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s)
|
|
{
|
|
puts("MMC support not available!\n");
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONFIG_DFU_NAND
|
|
extern int dfu_fill_entity_nand(struct dfu_entity *dfu, char *s);
|
|
#else
|
|
static inline int dfu_fill_entity_nand(struct dfu_entity *dfu, char *s)
|
|
{
|
|
puts("NAND support not available!\n");
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONFIG_DFU_RAM
|
|
extern int dfu_fill_entity_ram(struct dfu_entity *dfu, char *s);
|
|
#else
|
|
static inline int dfu_fill_entity_ram(struct dfu_entity *dfu, char *s)
|
|
{
|
|
puts("RAM support not available!\n");
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
#endif /* __DFU_ENTITY_H_ */
|