⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bootldr.c

📁 linux下的MTD设备驱动源代码,配合jffs2 yaffss2文件系统.
💻 C
字号:
/* * Read flash partition table from Compaq Bootloader * * Copyright 2001 Compaq Computer Corporation. * * $Id: bootldr.c,v 1.6 2001/10/02 15:05:11 dwmw2 Exp $ * * Use consistent with the GNU GPL is permitted, * provided that this copyright notice is * preserved in its entirety in all copies and derived works. * * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED, * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS * FITNESS FOR ANY PARTICULAR PURPOSE. * *//* * Maintainer: Jamey Hicks (jamey.hicks@compaq.com) */#include <linux/kernel.h>#include <linux/slab.h>#include <linux/mtd/mtd.h>#include <linux/mtd/partitions.h>#include <asm/setup.h>#include <linux/bootmem.h>#define FLASH_PARTITION_NAMELEN 32enum LFR_FLAGS {   LFR_SIZE_PREFIX = 1,		/* prefix data with 4-byte size */   LFR_PATCH_BOOTLDR = 2,	/* patch bootloader's 0th instruction */   LFR_KERNEL = 4,		/* add BOOTIMG_MAGIC, imgsize and VKERNEL_BASE to head of programmed region (see bootldr.c) */   LFR_EXPAND = 8               /* expand partition size to fit rest of flash */};// the tags are parsed too early to malloc or alloc_bootmem so we'll fix it// for now#define MAX_NUM_PARTITIONS 8typedef struct FlashRegion {   char name[FLASH_PARTITION_NAMELEN];   unsigned long base;   unsigned long size;   enum LFR_FLAGS flags;} FlashRegion;typedef struct BootldrFlashPartitionTable {  int magic; /* should be filled with 0x646c7470 (btlp) BOOTLDR_PARTITION_MAGIC */  int npartitions;  struct FlashRegion partition[8];} BootldrFlashPartitionTable;#define BOOTLDR_MAGIC      0x646c7462        /* btld: marks a valid bootldr image */#define BOOTLDR_PARTITION_MAGIC  0x646c7470  /* btlp: marks a valid bootldr partition table in params sector */#define BOOTLDR_MAGIC_OFFSET 0x20 /* offset 0x20 into the bootldr */#define BOOTCAP_OFFSET 0X30 /* offset 0x30 into the bootldr */#define BOOTCAP_WAKEUP	(1<<0)#define BOOTCAP_PARTITIONS (1<<1) /* partition table stored in params sector */#define BOOTCAP_PARAMS_AFTER_BOOTLDR (1<<2) /* params sector right after bootldr sector(s), else in last sector */static struct BootldrFlashPartitionTable Table;static struct BootldrFlashPartitionTable *partition_table = NULL;int parse_bootldr_partitions(struct mtd_info *master, struct mtd_partition **pparts){	struct mtd_partition *parts;	int ret, retlen, i;	int npartitions = 0;	long partition_table_offset;	long bootmagic = 0;	long bootcap = 0;	int namelen = 0;	char *names; #if 0	/* verify bootldr magic */	ret = master->read(master, BOOTLDR_MAGIC_OFFSET, sizeof(long), &retlen, (void *)&bootmagic);	if (ret) 		goto out;        if (bootmagic != BOOTLDR_MAGIC)                goto out;	/* see if bootldr supports partition tables and where to find the partition table */	ret = master->read(master, BOOTCAP_OFFSET, sizeof(long), &retlen, (void *)&bootcap);	if (ret) 		goto out;	if (!(bootcap & BOOTCAP_PARTITIONS))		goto out;	if (bootcap & BOOTCAP_PARAMS_AFTER_BOOTLDR)		partition_table_offset = master->erasesize;	else		partition_table_offset = master->size - master->erasesize;	printk(__FUNCTION__ ": partition_table_offset=%#lx\n", partition_table_offset);	printk(__FUNCTION__ ": ptable_addr=%#lx\n", ptable_addr);	/* Read the partition table */	partition_table = (struct BootldrFlashPartitionTable *)kmalloc(PAGE_SIZE, GFP_KERNEL);	if (!partition_table)		return -ENOMEM;	ret = master->read(master, partition_table_offset,			   PAGE_SIZE, &retlen, (void *)partition_table);	if (ret)	    goto out;#endif	if (!partition_table)	    return -ENOMEM;		printk(__FUNCTION__ ": magic=%#x\n", partition_table->magic);	printk(__FUNCTION__ ": numPartitions=%#x\n", partition_table->npartitions);	/* check for partition table magic number */	if (partition_table->magic != BOOTLDR_PARTITION_MAGIC) 		goto out;	npartitions = (partition_table->npartitions > MAX_NUM_PARTITIONS)?	    MAX_NUM_PARTITIONS:partition_table->npartitions;		printk(__FUNCTION__ ": npartitions=%#x\n", npartitions);	for (i = 0; i < npartitions; i++) {		namelen += strlen(partition_table->partition[i].name) + 1;	}	parts = kmalloc(sizeof(*parts)*npartitions + namelen, GFP_KERNEL);	if (!parts) {		ret = -ENOMEM;		goto out;	}	names = (char *)&parts[npartitions];	memset(parts, 0, sizeof(*parts)*npartitions + namelen);	// from here we use the partition table	for (i = 0; i < npartitions; i++) {                struct FlashRegion *partition = &partition_table->partition[i];		const char *name = partition->name;		parts[i].name = names;		names += strlen(name) + 1;		strcpy(parts[i].name, name);                if (partition->flags & LFR_EXPAND)                        parts[i].size = MTDPART_SIZ_FULL;                else                        parts[i].size = partition->size;		parts[i].offset = partition->base;		parts[i].mask_flags = 0;				printk("        partition %s o=%x s=%x\n", 		       parts[i].name, parts[i].offset, parts[i].size);	}	ret = npartitions;	*pparts = parts; out:#if 0	if (partition_table)		kfree(partition_table);#endif		return ret;}static int __init parse_tag_ptable(const struct tag *tag){    char buf[128];    int i;    int j;        partition_table = &Table;#ifdef CONFIG_DEBUG_LL        sprintf(buf,"ptable: magic = = 0x%lx  npartitions= %d \n",	    tag->u.ptable.magic,tag->u.ptable.npartitions);    printascii(buf);        for (i=0; i<tag->u.ptable.npartitions; i++){	sprintf(buf,"ptable: partition name = %s base= 0x%lx  size= 0x%lx flags= 0x%lx\n",	    (char *) (&tag->u.ptable.partition[i].name[0]),		tag->u.ptable.partition[i].base,		tag->u.ptable.partition[i].size,		tag->u.ptable.partition[i].flags);	printascii(buf);    }#endif    memcpy((void *)partition_table,(void *) (&(tag->u.ptable)),sizeof(partition_table) +	sizeof(struct FlashRegion)*tag->u.ptable.npartitions);        return 0;}__tagtable(ATAG_PTABLE, parse_tag_ptable);EXPORT_SYMBOL(parse_bootldr_partitions);MODULE_LICENSE("GPL");MODULE_AUTHOR("Compaq Computer Corporation");MODULE_DESCRIPTION("Parsing code for Compaq bootldr partitions");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -