aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Swetland <swetland@google.com>2011-01-31 18:40:56 -0800
committerVikram Pandita <vikram.pandita@ti.com>2011-02-01 13:54:59 -0800
commit1fc693805112a647e20c449c455fa0d512d665df (patch)
treeb5fbccd9004207b2d72e68dc883c7d496483343d
parentd7f5dd685edcaa3c66963fd96540979df83ef69b (diff)
downloadu-boot-pandroid-1fc693805112a647e20c449c455fa0d512d665df.tar.gz
panda: mmc: add support for "fastboot oem format"
This will create a minimal MBR+GPT partition table and write it to the sdcard. Signed-off-by: Brian Swetland <swetland@google.com>
-rw-r--r--board/omap4430panda/mmc.c190
1 files changed, 189 insertions, 1 deletions
diff --git a/board/omap4430panda/mmc.c b/board/omap4430panda/mmc.c
index 4bc53f76..bd6d0a42 100644
--- a/board/omap4430panda/mmc.c
+++ b/board/omap4430panda/mmc.c
@@ -27,16 +27,23 @@
*/
#include <common.h>
+#include <mmc.h>
#include <fastboot.h>
+#define EFI_VERSION 0x00010000
#define EFI_ENTRIES 128
#define EFI_NAMELEN 36
-const u8 partition_type[16] = {
+static const u8 partition_type[16] = {
0xa2, 0xa0, 0xd0, 0xeb, 0xe5, 0xb9, 0x33, 0x44,
0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7,
};
+static const u8 random_uuid[16] = {
+ 0xff, 0x1f, 0xf2, 0xf9, 0xd4, 0xa8, 0x0e, 0x5f,
+ 0x97, 0x46, 0x59, 0x48, 0x69, 0xae, 0xc3, 0x4e,
+};
+
struct efi_entry {
u8 type_uuid[16];
u8 uniq_uuid[16];
@@ -46,6 +53,127 @@ struct efi_entry {
u16 name[EFI_NAMELEN];
};
+struct efi_header {
+ u8 magic[8];
+
+ u32 version;
+ u32 header_sz;
+
+ u32 crc32;
+ u32 reserved;
+
+ u64 header_lba;
+ u64 backup_lba;
+ u64 first_lba;
+ u64 last_lba;
+
+ u8 volume_uuid[16];
+
+ u64 entries_lba;
+
+ u32 entries_count;
+ u32 entries_size;
+ u32 entries_crc32;
+} __attribute__((packed));
+
+struct ptable {
+ u8 mbr[512];
+ union {
+ struct efi_header header;
+ u8 block[512];
+ };
+ struct efi_entry entry[EFI_ENTRIES];
+};
+
+static void init_mbr(u8 *mbr, u32 blocks)
+{
+ mbr[0x1be] = 0x00; // nonbootable
+ mbr[0x1bf] = 0xFF; // bogus CHS
+ mbr[0x1c0] = 0xFF;
+ mbr[0x1c1] = 0xFF;
+
+ mbr[0x1c2] = 0xEE; // GPT partition
+ mbr[0x1c3] = 0xFF; // bogus CHS
+ mbr[0x1c4] = 0xFF;
+ mbr[0x1c5] = 0xFF;
+
+ mbr[0x1c6] = 0x01; // start
+ mbr[0x1c7] = 0x00;
+ mbr[0x1c8] = 0x00;
+ mbr[0x1c9] = 0x00;
+
+ memcpy(mbr + 0x1ca, &blocks, sizeof(u32));
+
+ mbr[0x1fe] = 0x55;
+ mbr[0x1ff] = 0xaa;
+}
+
+static void start_ptbl(struct ptable *ptbl, unsigned blocks)
+{
+ struct efi_header *hdr = &ptbl->header;
+
+ memset(ptbl, 0, sizeof(*ptbl));
+
+ init_mbr(ptbl->mbr, blocks - 1);
+
+ memcpy(hdr->magic, "EFI PART", 8);
+ hdr->version = EFI_VERSION;
+ hdr->header_sz = sizeof(struct efi_header);
+ hdr->header_lba = 1;
+ hdr->backup_lba = blocks - 1;
+ hdr->first_lba = 34;
+ hdr->last_lba = blocks - 1;
+ memcpy(hdr->volume_uuid, random_uuid, 16);
+ hdr->entries_lba = 2;
+ hdr->entries_count = EFI_ENTRIES;
+ hdr->entries_size = sizeof(struct efi_entry);
+}
+
+static void end_ptbl(struct ptable *ptbl)
+{
+ struct efi_header *hdr = &ptbl->header;
+ u32 n;
+
+ n = crc32(0, 0, 0);
+ n = crc32(n, (void*) ptbl->entry, sizeof(ptbl->entry));
+ hdr->entries_crc32 = n;
+
+ n = crc32(0, 0, 0);
+ n = crc32(0, (void*) &ptbl->header, sizeof(ptbl->header));
+ hdr->crc32 = n;
+}
+
+int add_ptn(struct ptable *ptbl, u64 first, u64 last, const char *name)
+{
+ struct efi_header *hdr = &ptbl->header;
+ struct efi_entry *entry = ptbl->entry;
+ unsigned n;
+
+ if (first < 34) {
+ printf("partition '%s' overlaps partition table\n", name);
+ return -1;
+ }
+
+ if (last > hdr->last_lba) {
+ printf("partition '%s' does not fit\n", name);
+ return -1;
+ }
+ for (n = 0; n < EFI_ENTRIES; n++, entry++) {
+ if (entry->last_lba)
+ continue;
+ memcpy(entry->type_uuid, partition_type, 16);
+ memcpy(entry->uniq_uuid, random_uuid, 16);
+ entry->uniq_uuid[0] = n;
+ entry->first_lba = first;
+ entry->last_lba = last;
+ for (n = 0; (n < EFI_NAMELEN) && *name; n++)
+ entry->name[n] = *name++;
+ return 0;
+ }
+ printf("out of partition table entries\n");
+ return -1;
+}
+
void import_efi_partition(struct efi_entry *entry)
{
struct fastboot_ptentry e;
@@ -69,6 +197,66 @@ void import_efi_partition(struct efi_entry *entry)
printf("%8d %7dK %s\n", e.start, e.length/0x400, e.name);
}
+struct partition {
+ const char *name;
+ unsigned size_kb;
+};
+
+static struct partition partitions[] = {
+ { "-", 128 },
+ { "xloader", 128 },
+ { "bootloader", 256 },
+ { "-", 512 },
+ { "boot", 8*1024 },
+ { "system", 256*1024 },
+ { "cache", 256*1024 },
+ { "userdata", 512*1024},
+ { "media", 0 },
+ { 0, 0 },
+};
+
+static struct ptable the_ptable;
+
+static int do_format(void)
+{
+ struct ptable *ptbl = &the_ptable;
+ unsigned sector_sz, blocks;
+ unsigned next;
+ int n;
+
+ mmc_info(0, &sector_sz, &blocks);
+ printf("blocks %d\n", blocks);
+
+ start_ptbl(ptbl, blocks);
+ n = 0;
+ next = 0;
+ for (n = 0, next = 0; partitions[n].name; n++) {
+ unsigned sz = partitions[n].size_kb * 2;
+ if (!strcmp(partitions[n].name,"-")) {
+ next += sz;
+ continue;
+ }
+ if (sz == 0)
+ sz = blocks - next;
+ if (add_ptn(ptbl, next, next + sz - 1, partitions[n].name))
+ return -1;
+ next += sz;
+ }
+ end_ptbl(ptbl);
+
+ if (mmc_write(0, (void*) ptbl, 0, sizeof(struct ptable)) != 1)
+ return -1;
+
+ return 0;
+}
+
+int fastboot_oem(const char *cmd)
+{
+ if (!strcmp(cmd,"format"))
+ return do_format();
+ return -1;
+}
+
void board_mmc_init(void)
{
/* nothing to do this early */