/* * Copyright (C) 2015 Hardkernel Co,. Ltd * Dongjin Kim * * SPDX-License-Identifier: GPL-2.0+ */ #include #include #include #include /* FIXME: Is block size always 512? */ #define bytes_to_lba(x) ((x) / 512) #define gbytes_to_lba(x) ((x) * 1024 * 1024 * 2) #define SZ_RESERVED (48 * SZ_1K + 512) /* BL1 + MBR */ #define SZ_BOOTLOADER (720 * SZ_1K) #define SZ_BOOTMESSAGE (4 * SZ_1K) static struct fbt_partition { const char *name; lbaint_t lba; } partitions[] = { { .name = "-reserved", .lba = bytes_to_lba(SZ_RESERVED) }, { .name = "bootloader", .lba = bytes_to_lba(SZ_BOOTLOADER - (SZ_RESERVED + SZ_BOOTMESSAGE)) }, { .name = "bcb", /* Bootloader control block */ .lba = bytes_to_lba(SZ_BOOTMESSAGE) }, { .name = "env", /* "environment" */ .lba = bytes_to_lba(CONFIG_ENV_SIZE) }, { .name = "dtb", /* Device Tree */ .lba = bytes_to_lba(SZ_64K) }, { .name = "boot", /* Boot image */ .lba = bytes_to_lba(16 * SZ_1M) }, { .name = "recovery", /* Recovery Image */ .lba = bytes_to_lba(12 * SZ_1M) }, { .name = "logo", /* Logo */ .lba = bytes_to_lba(2 * SZ_1M) } }; static struct dos_partition { const char *name; int part; u8 type; lbaint_t lba; } dos_partitions[] = { { .name = "cache", .part = 2, .type = 0x83, .lba = bytes_to_lba(512 * SZ_1M), }, { .name = "system", .part = 3, .type = 0x83, .lba = gbytes_to_lba(1), }, { .name = "userdata", .part = 4, .type = 0x83, .lba = gbytes_to_lba(3), }, { .name = "vfat", .part = 1, .type = 0x0c, .lba = -1, }, }; static int n = 0; static int valid_partition_number(int part) { return (1 <= part) && (part <= ARRAY_SIZE(dos_partitions)); } /* * Initiate dos partition index and return the first sector (lba) */ lbaint_t board_dos_partition_start(void) { int n; lbaint_t next = 0; for (n = 0 ; n < ARRAY_SIZE(partitions); n++) next += partitions[n].lba; return next; } /* * Get the partition detail, partition number and its type, as well as * return the number of sectors to allocate for the partition. */ lbaint_t board_dos_partition_next(int *part, u8 *type) { if (!valid_partition_number(n + 1)) return 0; struct dos_partition *p = &dos_partitions[n++]; *part = p->part; /* partition number */ *type = p->type; /* partition type */ /* Use remained sectors for this partition */ if (p->lba == -1) return -1; return p->lba; } /* * Return the partition name of given partition number. Since DOS partition * does not support name on its partition table, the partition names are * predefined upon each partition number. */ char *board_dos_partition_name(int part, char* name) { int i; if (!valid_partition_number(part)) return NULL; for (i = 0; i < ARRAY_SIZE(dos_partitions); i++) { /* Partition number is same with given to seek */ if (dos_partitions[i].part == part) { strcpy(name, dos_partitions[i].name); return name; } } return NULL; } /* * Initiate the fastboot partition entries with internal system partitions and * DOS partition table. */ int board_partition_init(void) { struct mmc *mmc; fastboot_ptentry ptn; lbaint_t next = 0; lbaint_t len; int n = 0; fastboot_flash_reset_ptn(); mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV); for (n = 0 ; mmc && n < ARRAY_SIZE(partitions); n++) { len = partitions[n].lba; /* Skip to add the partition if start with '-', but move forward * to next position as much as its size */ if (partitions[n].name[0] == '-') { next += len; continue; } /* 'env' partition contains U-boot's environment fields, it * could be damaged by fastboot if its offset is invalid with * defined by CONFIG_ENV_OFFSET. */ if (!strcmp(partitions[n].name, "env") && (bytes_to_lba(CONFIG_ENV_OFFSET) != next)) { printf("WARNING!!: Invalid offset of 'env' partition," " it must be " LBAFU " but " LBAFU "\n", next, (lbaint_t)bytes_to_lba(CONFIG_ENV_OFFSET)); } if (len == 0) len = mmc->block_dev.lba - next; strncpy((char*)&ptn.name, partitions[n].name, sizeof(ptn.name)); ptn.start = next; ptn.length = len; /* Add the partition to fastboot partition entry table */ fastboot_flash_add_ptn(&ptn); next += len; } fastboot_load_dos_partition(); return 0; } int board_fastboot_pre_flash(block_dev_desc_t *dev_desc, lbaint_t start, void *buffer) { if (start == 0) { /* MUST be trying to modify MBR, hence at least DOS partition * table have to be kept. So buffer to flashing will be * overwritten with exist partition table. */ u8 mbr[512]; if (dev_desc->block_read(dev_desc->dev, start, 1, mbr) != 1) { printf("fastboot: can't read MBR from device %d\n", dev_desc->dev); return -EIO; } memcpy(buffer + 0x1be, &mbr[0x1be], 512 - 0x1be); } return 0; }