From: Erik M. <er...@us...> - 2002-02-13 00:20:00
|
Update of /cvsroot/blob/blob/src/blob In directory usw-pr-cvs1:/tmp/cvs-serv16728/src/blob Modified Files: partition.c Log Message: The new partition table code, initial part. Next on the list are functions to manipulate the table. Index: partition.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/partition.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- partition.c 3 Jan 2002 16:07:18 -0000 1.2 +++ partition.c 13 Feb 2002 00:19:57 -0000 1.3 @@ -27,49 +27,295 @@ # include <blob/config.h> #endif +#include <blob/command.h> +#include <blob/errno.h> +#include <blob/error.h> #include <blob/flash.h> +#include <blob/init.h> #include <blob/partition.h> #include <blob/serial.h> -#include <blob/error.h> +#include <blob/util.h> +#include <blob/debug.h> +#define next_ptable_entry(s) \ + (blob_partition_t *)((u32)s + s->next) -static partition_table_t flash_partition_table; +/* pointers to the partition tables */ +const blob_partition_t *default_partition_table; +blob_partition_t *flash_partition_table; -/* FIXME: this is for the time being */ -extern int read_bootldr_partition_table(partition_table_t *ptable); +/* copy of the flash partition table in RAM */ +#define MAX_PARTITIONS (64) +static blob_partition_t ptable[MAX_PARTITIONS]; -static int read_partition_table(void) + + +static int check_ptable_magic(const blob_partition_t *entry, u32 magic) { - int rv; - int i; + if(entry->magic != magic) { + deprintf("magic failed at 0x%08x (0x%08x != 0x%08x)\n", + (unsigned int)entry, + entry->magic, + magic); + return -EMAGIC; + } else { + return 0; + } +} - /* so far we only know about bootldr flash partitions */ - rv = read_bootldr_partition_table(&flash_partition_table); + + +/* find the flash partition table */ +static void find_flash_ptable(void) +{ + u32 old_a, a; + int rv; + + /* assume that the architecture dependent code has set + * the flash_partition_table pointer to something valid + */ + if(flash_partition_table->magic == BLOB_FLASH_PART_TABLE_MAGIC) { + dprintf("Immediately found flash partition table at 0x%08x\n", + (unsigned int)flash_partition_table); + return; + } + + /* apparently not. we now assume that the architecture + * dependent code has put the flash_partition_table pointer at + * the start of the flash, so we start scanning the start of + * all flash blocks until we find a partition table. + */ + dprintf("Searching flash partition table... \n"); + rv = flash_get_first_block_address(&a); if(rv < 0) { - printerror(rv, "can't get partition table\n"); - return rv; + dprintf("first block not found\n"); + return; } - SerialOutputString("Flash partition layout:\n"); - for(i = 0; i < flash_partition_table.numpartitions; i++) { - SerialOutputString(" 0x"); - SerialOutputHex(flash_partition_table.partition[i].size); - SerialOutputString(" @ 0x"); - SerialOutputHex(flash_partition_table.partition[i].offset); + dprintf(" block at 0x%08x...\n", a); - if(flash_partition_table.partition[i].flags & PART_LOAD) { - SerialOutputString(", load at 0x"); - SerialOutputHex(flash_partition_table.partition[i].mem_base); - SerialOutputString(", entry point at 0x"); - SerialOutputHex(flash_partition_table.partition[i].entry_point); + while(((blob_partition_t *)a)->magic != BLOB_FLASH_PART_TABLE_MAGIC) { + old_a = a; + rv = flash_get_next_block_address(&a, old_a); + + if(rv < 0){ + dprintf("not found\n"); + return; + } + + dprintf(" block at 0x%08x...\n", a); + } + + dprintf("found at 0x%08x\n", + (unsigned int)a); + flash_partition_table = (blob_partition_t *)a; +} + + + + +/* copy partition table from src to dst. dst can only contain max_dst + * entries. src must be of type magic. also copy invalidated entries + * if copy_invalid != 0 */ +static int copy_ptable(const blob_partition_t *src, blob_partition_t *dst, + u32 magic, int max_dst, int copy_invalid) +{ + int i = 1, rv = 0; + + dprintf("copy from 0x%08x to 0x%08x,\n", + (u32)src, (u32)dst); + dprintf("magic = 0x%08x, max_dst = %d, copy_invalid = %d\n", + magic, max_dst, copy_invalid); + + /* sanity check */ + if(max_dst < 2) { + deprintf("max_dst too small (%i < 2)\n", max_dst); + return -EINVAL; + } + + if(src->magic != magic) { + deprintf("src not of requested type (0x%08x != 0x%08x)\n", + src->magic, magic); + return -EINVAL; + } + + /* copy start of partition table and go to next entry*/ + memcpy(dst, src, src->next); + src = next_ptable_entry(src); + dst = next_ptable_entry(dst); + i++; + + for(;;) { + /* we're at the last one */ + if(i == max_dst) { + rv = -ERANGE; + break; + } + + /* check for a valid entry and copy it */ + rv = check_ptable_magic(src, BLOB_PART_VALID_MAGIC); + if(rv == 0) + goto do_copy; + + /* check for an invalidated entry */ + rv = check_ptable_magic(src, BLOB_PART_INVALID_MAGIC); + if(rv == 0) { + /* only copy when asked */ + if(copy_invalid) + goto do_copy; + else + continue; } + + /* check for a last partition entry and stop if found */ + rv = check_ptable_magic(src, BLOB_PART_LAST_MAGIC); + if(rv == 0) { + rv = 0; + } else { + /* we should NEVER reach this point */ + dprintf("unknown entry at 0x%08x (08%08x)\n", + (unsigned int)src, src->magic); + dprintf("this should not happen, bailing out\n"); + rv = -EMAGIC; + } + break; + + do_copy: + memcpy(dst, src, src->next); + src = next_ptable_entry(src); + dst = next_ptable_entry(dst); + i++; + } + + /* fill out last entry */ + dst->magic = BLOB_PART_LAST_MAGIC; + + dprintf("%d entries copied, returning %d\n", i, rv); + + return rv; +} + + + + +void ptable_print(const blob_partition_t *t) +{ + printf("Partition table for %d kB flash @ 0x%08x:\n", + t->size / 1024, t->offset); + + for(;;) { + t = next_ptable_entry(t); - serial_write('\n'); + switch(t->magic) { + case BLOB_PART_LAST_MAGIC: + return; + + case BLOB_PART_VALID_MAGIC: + printf(" 0x%08x @ 0x%08x (%d kB): '%s'\n", + t->size, t->offset, t->size, t->name); + + if(t->flags & BLOB_PART_FLAG_PTABLE) + printf(" contains partition table\n"); + + if(t->mem_base) + printf(" %sload at 0x%08x\n", + (t->flags & BLOB_PART_FLAG_LOAD) ? + "automatically " : "", + t->mem_base); + + if(t->entry_point) { + printf(" entry point at 0x%08x", + t->entry_point); + if(t->flags & BLOB_PART_FLAG_EXEC) + printf(", automatically execute\n"); + else + printf("\n"); + } + + if(t->flags & BLOB_PART_FLAG_JFFS2) + printf(" contains JFFS2\n"); + + if(t->flags & BLOB_PART_FLAG_CRAMFS) + printf(" contains cramfs\n"); + break; + + case BLOB_PART_INVALID_MAGIC: + dprintf("invalidated entry\n"); + break; + + default: + eprintf("ptable magic failed at 0x%08x\n", (u32)t); + return; + } } +} + + + + +static void ptable_init(void) +{ + int rv; + + /* try to copy the default partition table */ + rv = copy_ptable(default_partition_table, ptable, + BLOB_DEFAULT_PART_TABLE_MAGIC, MAX_PARTITIONS, 0); + + if(rv == 0) { + ptable->magic = BLOB_COPY_PART_TABLE_MAGIC; + dprintf("found default partition table at 0x%08x\n", + (unsigned int)default_partition_table); + } + + /* try to find the flash partition table and try to copy it. + * flash partition table overrides a default partition table. + */ + find_flash_ptable(); + rv = copy_ptable(flash_partition_table, ptable, + BLOB_FLASH_PART_TABLE_MAGIC, MAX_PARTITIONS, 1); + + if(rv == 0) { + ptable->magic = BLOB_COPY_PART_TABLE_MAGIC; + dprintf("found flash partition table at 0x%08x\n", + (unsigned int)flash_partition_table); + } + + /* FIXME: if there is still no flash partition table found we + * could check for a bootldr partition table over here */ + + if(check_ptable_magic(ptable, BLOB_COPY_PART_TABLE_MAGIC) != 0) { + dprintf("no valid partition table found\n"); + + /* construct a minimal partition table */ + ptable[0].magic = BLOB_COPY_PART_TABLE_MAGIC; + ptable[0].next = sizeof(blob_partition_t); + ptable[0].offset = 0; + ptable[0].size = 0; + ptable[1].magic = BLOB_PART_LAST_MAGIC; + } + +#ifdef BLOB_DEBUG + ptable_print(ptable); +#endif +} + +__initlist(ptable_init, INIT_LEVEL_OTHER_STUFF + 2); + + + + +static int ptprint(int argc, char *argv[]) +{ + ptable_print(ptable); return 0; } + +static char ptprint_help[] = "ptprint\n" +"print flash partition table\n"; + +__commandlist(ptprint, "ptprint", ptprint_help); |