drivers/mtd/parsers/redboot.c

Source file repositories/reference/linux-study-clean/drivers/mtd/parsers/redboot.c

File Facts

System
Linux kernel
Corpus path
drivers/mtd/parsers/redboot.c
Extension
.c
Size
8383 bytes
Lines
324
Domain
Driver Families
Bucket
drivers/mtd
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct fis_image_desc {
	unsigned char name[16];      // Null terminated name
	u32	  flash_base;    // Address within FLASH of image
	u32	  mem_base;      // Address in memory where it executes
	u32	  size;          // Length of image
	u32	  entry_point;   // Execution entry point
	u32	  data_length;   // Length of actual data
	unsigned char _pad[256 - (16 + 7 * sizeof(u32))];
	u32	  desc_cksum;    // Checksum over image descriptor
	u32	  file_cksum;    // Checksum over image data
};

struct fis_list {
	struct fis_image_desc *img;
	struct fis_list *next;
};

static int directory = CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK;
module_param(directory, int, 0);

static inline int redboot_checksum(struct fis_image_desc *img)
{
	/* RedBoot doesn't actually write the desc_cksum field yet AFAICT */
	return 1;
}

static void parse_redboot_of(struct mtd_info *master)
{
	struct device_node *np;
	struct device_node *npart;
	u32 dirblock;
	int ret;

	np = mtd_get_of_node(master);
	if (!np)
		return;

	npart = of_get_child_by_name(np, "partitions");
	if (!npart)
		return;

	ret = of_property_read_u32(npart, "fis-index-block", &dirblock);
	of_node_put(npart);
	if (ret)
		return;

	/*
	 * Assign the block found in the device tree to the local
	 * directory block pointer.
	 */
	directory = dirblock;
}

static int parse_redboot_partitions(struct mtd_info *master,
				    const struct mtd_partition **pparts,
				    struct mtd_part_parser_data *data)
{
	int nrparts = 0;
	struct fis_image_desc *buf;
	struct mtd_partition *parts;
	struct fis_list *fl = NULL, *tmp_fl;
	int ret, i;
	size_t retlen;
	char *names;
	char *nullname;
	int namelen = 0;
	int nulllen = 0;
	int numslots;
	unsigned long offset;
#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
	static char nullstring[] = "unallocated";
#endif

	parse_redboot_of(master);

	if (directory < 0) {
		offset = master->size + directory * master->erasesize;
		while (mtd_block_isbad(master, offset)) {
			if (!offset) {
nogood:
				pr_notice("Failed to find a non-bad block to check for RedBoot partition table\n");
				return -EIO;
			}
			offset -= master->erasesize;
		}
	} else {
		offset = (unsigned long) directory * master->erasesize;
		while (mtd_block_isbad(master, offset)) {
			offset += master->erasesize;
			if (offset == master->size)

Annotation

Implementation Notes