summaryrefslogtreecommitdiff
path: root/cgpt
diff options
context:
space:
mode:
Diffstat (limited to 'cgpt')
-rw-r--r--cgpt/cgpt.c58
-rw-r--r--cgpt/cgpt.h17
-rw-r--r--cgpt/cgpt_add.c108
-rw-r--r--cgpt/cgpt_boot.c9
-rw-r--r--cgpt/cgpt_common.c403
-rw-r--r--cgpt/cgpt_create.c34
-rw-r--r--cgpt/cgpt_find.c83
-rw-r--r--cgpt/cgpt_legacy.c7
-rw-r--r--cgpt/cgpt_prioritize.c15
-rw-r--r--cgpt/cgpt_repair.c6
-rw-r--r--cgpt/cgpt_show.c155
-rw-r--r--cgpt/cmd_create.c6
-rw-r--r--cgpt/flash_ts.c423
-rw-r--r--cgpt/flash_ts.h35
-rw-r--r--cgpt/flash_ts_api.h25
-rw-r--r--cgpt/flash_ts_drv.c72
16 files changed, 94 insertions, 1362 deletions
diff --git a/cgpt/cgpt.c b/cgpt/cgpt.c
index ccf73184..38092006 100644
--- a/cgpt/cgpt.c
+++ b/cgpt/cgpt.c
@@ -52,45 +52,6 @@ void Usage(void) {
printf("\nFor more detailed usage, use %s COMMAND -h\n\n", progname);
}
-static int is_pow2(size_t v) {
- return v && (v & (v - 1)) == 0;
-}
-
-static int parse_nand_option(const char *arg) {
- int bytes_per_page, pages_per_block, fts_block_offset, fts_block_size;
-
- if ('=' != arg[0])
- return -1;
-
- arg++;
- bytes_per_page = atoi(arg);
- arg = strchr(arg, ',');
- if (!arg)
- return -1;
-
- arg++;
- pages_per_block = atoi(arg);
- arg = strchr(arg, ',');
- if (!arg)
- return -1;
-
- arg++;
- fts_block_offset = atoi(arg);
- arg = strchr(arg, ',');
- if (!arg)
- return -1;
-
- arg++;
- fts_block_size = atoi(arg);
- if (fts_block_size == 0 || !is_pow2(pages_per_block) ||
- !is_pow2(bytes_per_page) || bytes_per_page < 512) {
- return -1;
- }
- EnableNandImage(bytes_per_page, pages_per_block, fts_block_offset,
- fts_block_size);
- return 0;
-}
-
int main(int argc, char *argv[]) {
int i;
int match_count = 0;
@@ -103,25 +64,6 @@ int main(int argc, char *argv[]) {
else
progname = argv[0];
-
- for (i = 1; i < argc; ++i) {
- if (0 == strncmp(argv[i], "-N", 2)) {
- if (!parse_nand_option(argv[i] + 2)) {
- int j;
-
- // Remove it form the list.
- for (j = i; j < argc - 1; j++)
- argv[j] = argv[j + 1];
- argc--;
- break;
- }
- // Bad nand config.
- printf("Nand option must fit: -N=<bytes_per_page>,<pages_per_block>,"
- "<block_offset_of_partition>,<block_size_of_partition>\n");
- return CGPT_FAILED;
- }
- }
-
if (argc < 2) {
Usage();
return CGPT_FAILED;
diff --git a/cgpt/cgpt.h b/cgpt/cgpt.h
index bb3438a0..ff9e1064 100644
--- a/cgpt/cgpt.h
+++ b/cgpt/cgpt.h
@@ -13,7 +13,6 @@
#include "cgpt_endian.h"
#include "cgptlib.h"
#include "gpt.h"
-#include "mtdlib.h"
struct legacy_partition {
uint8_t status;
@@ -43,23 +42,11 @@ void PMBRToStr(struct pmbr *pmbr, char *str, unsigned int buflen);
// Handle to the drive storing the GPT.
struct drive {
uint64_t size; /* total size (in bytes) */
- int is_mtd;
GptData gpt;
- MtdData mtd;
struct pmbr pmbr;
int fd; /* file descriptor */
};
-struct nand_layout {
- int enabled;
- int use_host_ioctl; /* Use ioctl() on /dev/fts to read/write. */
- int bytes_per_page, pages_per_block, fts_block_offset, fts_block_size;
-};
-
-/* Write a NAND/MTD image instead of GPT. */
-void EnableNandImage(int bytes_per_page, int pages_per_block,
- int fts_block_offset, int fts_block_size);
-
// Opens a block device or file, loads raw GPT data from it.
// 'mode' should be O_RDONLY or O_RDWR.
// If 'drive_size' is 0, both the partitions and GPT structs reside on the same
@@ -156,11 +143,9 @@ int ResolveType(const Guid *type, char *buf);
int SupportedType(const char *name, Guid *type);
void PrintTypes(void);
void EntryDetails(GptEntry *entry, uint32_t index, int raw);
-void MtdEntryDetails(MtdDiskPartition *entry, uint32_t index, int raw);
uint32_t GetNumberOfEntries(const struct drive *drive);
GptEntry *GetEntry(GptData *gpt, int secondary, uint32_t entry_index);
-MtdDiskPartition *MtdGetEntry(MtdData *mtd, int secondary, uint32_t index);
void SetPriority(struct drive *drive, int secondary, uint32_t entry_index,
int priority);
@@ -184,8 +169,6 @@ int IsSynonymous(const GptHeader* a, const GptHeader* b);
int IsUnused(struct drive *drive, int secondary, uint32_t index);
int IsKernel(struct drive *drive, int secondary, uint32_t index);
-int LookupMtdTypeForGuid(const Guid *type);
-const Guid *LookupGuidForMtdType(int type);
// Optional. Applications that need this must provide an implementation.
//
diff --git a/cgpt/cgpt_add.c b/cgpt/cgpt_add.c
index 9bbc3fb5..d6b3cabd 100644
--- a/cgpt/cgpt_add.c
+++ b/cgpt/cgpt_add.c
@@ -95,32 +95,6 @@ static int GptSetEntryAttributes(struct drive *drive,
return 0;
}
-static int MtdSetEntryAttributes(struct drive *drive,
- uint32_t index,
- CgptAddParams *params) {
- MtdDiskPartition *entry;
-
- entry = MtdGetEntry(&drive->mtd, PRIMARY, index);
- if (params->set_begin) {
- uint64_t start = params->begin * drive->mtd.sector_bytes;
- memcpy(&entry->starting_offset, &start, sizeof(params->begin));
- }
- if (params->set_size) {
- uint64_t start;
- uint64_t end;
- MtdGetPartitionSize(entry, &start, NULL, NULL);
- end = start + params->size * drive->mtd.sector_bytes - 1;
- memcpy(&entry->ending_offset, &end, sizeof(end));
- }
- if (params->set_type)
- MtdSetEntryType(entry, LookupMtdTypeForGuid(&params->type_guid));
- if (params->label) {
- strncpy(entry->label, params->label, sizeof(entry->label));
- }
-
- return 0;
-}
-
// This is an internal helper function which assumes no NULL args are passed.
// It sets the given attribute values for a single entry at the given index.
static int SetEntryAttributes(struct drive *drive,
@@ -153,26 +127,20 @@ static int SetEntryAttributes(struct drive *drive,
}
static int CgptCheckAddValidity(struct drive *drive) {
- if (drive->is_mtd) {
- if (drive->mtd.primary.crc32 != MtdHeaderCrc(&drive->mtd.primary)) {
- Error("MTD header CRC is invalid\n");
- return -1;
- }
- } else {
- int gpt_retval;
- if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive->gpt))) {
- Error("GptSanityCheck() returned %d: %s\n",
- gpt_retval, GptError(gpt_retval));
- return -1;
- }
+ int gpt_retval;
+ if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive->gpt))) {
+ Error("GptSanityCheck() returned %d: %s\n",
+ gpt_retval, GptError(gpt_retval));
+ return -1;
+ }
- if (((drive->gpt.valid_headers & MASK_BOTH) != MASK_BOTH) ||
- ((drive->gpt.valid_entries & MASK_BOTH) != MASK_BOTH)) {
- Error("one of the GPT header/entries is invalid.\n"
- "please run 'cgpt repair' before adding anything.\n");
- return -1;
- }
+ if (((drive->gpt.valid_headers & MASK_BOTH) != MASK_BOTH) ||
+ ((drive->gpt.valid_entries & MASK_BOTH) != MASK_BOTH)) {
+ Error("one of the GPT header/entries is invalid.\n"
+ "please run 'cgpt repair' before adding anything.\n");
+ return -1;
}
+
return 0;
}
@@ -264,10 +232,6 @@ int CgptGetPartitionDetails(CgptAddParams *params) {
Error("either partition or unique_id must be specified\n");
goto bad;
}
- if (drive.is_mtd) {
- Error("MTD partitions cannot be specified by unique_id\n");
- goto bad;
- }
for (index = 0; index < max_part; index++) {
GptEntry *entry = GetEntry(&drive.gpt, PRIMARY, index);
if (GuidEqual(&entry->unique, &params->unique_guid)) {
@@ -282,22 +246,13 @@ int CgptGetPartitionDetails(CgptAddParams *params) {
}
index = params->partition - 1;
- if(drive.is_mtd) {
- MtdDiskPartition *entry = MtdGetEntry(&drive.mtd, PRIMARY, index);
- const Guid *guid = LookupGuidForMtdType(MtdGetEntryType(entry));
- memcpy(&params->type_guid, guid, sizeof(params->type_guid));
- memset(&params->unique_guid, 0, sizeof(params->unique_guid));
- MtdGetPartitionSizeInSectors(entry, &params->begin, NULL, &params->size);
- params->raw_value = entry->flags;
- } else {
- // GPT-specific code
- GptEntry *entry = GetEntry(&drive.gpt, PRIMARY, index);
- params->begin = entry->starting_lba;
- params->size = entry->ending_lba - entry->starting_lba + 1;
- memcpy(&params->type_guid, &entry->type, sizeof(Guid));
- memcpy(&params->unique_guid, &entry->unique, sizeof(Guid));
- params->raw_value = entry->attrs.fields.gpt_att;
- }
+ // GPT-specific code
+ GptEntry *entry = GetEntry(&drive.gpt, PRIMARY, index);
+ params->begin = entry->starting_lba;
+ params->size = entry->ending_lba - entry->starting_lba + 1;
+ memcpy(&params->type_guid, &entry->type, sizeof(Guid));
+ memcpy(&params->unique_guid, &entry->unique, sizeof(Guid));
+ params->raw_value = entry->attrs.fields.gpt_att;
params->successful = GetSuccessful(&drive, PRIMARY, index);
params->tries = GetTries(&drive, PRIMARY, index);
@@ -338,22 +293,6 @@ static int GptAdd(struct drive *drive, CgptAddParams *params, uint32_t index) {
return 0;
}
-static int MtdAdd(struct drive *drive, CgptAddParams *params, uint32_t index) {
- MtdDiskPartition *entry, backup;
- entry = MtdGetEntry(&drive->mtd, PRIMARY, index);
- memcpy(&backup, entry, sizeof(backup));
-
- if (SetEntryAttributes(drive, index, params) ||
- MtdSetEntryAttributes(drive, index, params)) {
- memcpy(entry, &backup, sizeof(*entry));
- return -1;
- }
-
- UpdateAllEntries(drive);
-
- return 0;
-}
-
int CgptAdd(CgptAddParams *params) {
struct drive drive;
uint32_t index;
@@ -373,13 +312,8 @@ int CgptAdd(CgptAddParams *params) {
goto bad;
}
- if (drive.is_mtd) {
- if (MtdAdd(&drive, params, index))
- goto bad;
- } else {
- if (GptAdd(&drive, params, index))
- goto bad;
- }
+ if (GptAdd(&drive, params, index))
+ goto bad;
// Write it all out.
return DriveClose(&drive, 1);
diff --git a/cgpt/cgpt_boot.c b/cgpt/cgpt_boot.c
index 928210b5..f4323962 100644
--- a/cgpt/cgpt_boot.c
+++ b/cgpt/cgpt_boot.c
@@ -79,15 +79,6 @@ int CgptBoot(CgptBootParams *params) {
return CGPT_FAILED;
}
- if (drive.is_mtd) {
- /* This command manipulates the legacy MBR sector present at the beginning
- * of the GPT structures, and so doesn't apply to MTD drives.
- */
- Error("'boot' command unsupported in MTD mode\n");
- retval = CGPT_FAILED;
- goto done;
- }
-
if (CGPT_OK != ReadPMBR(&drive)) {
Error("Unable to read PMBR\n");
goto done;
diff --git a/cgpt/cgpt_common.c b/cgpt/cgpt_common.c
index 1e7b5ab4..1438dfb3 100644
--- a/cgpt/cgpt_common.c
+++ b/cgpt/cgpt_common.c
@@ -25,24 +25,11 @@
#include "cgpt.h"
#include "cgptlib_internal.h"
#include "crc32.h"
-#include "flash_ts.h"
-#include "flash_ts_api.h"
#include "vboot_host.h"
static const char kErrorTag[] = "ERROR";
static const char kWarningTag[] = "WARNING";
-struct nand_layout nand;
-
-void EnableNandImage(int bytes_per_page, int pages_per_block,
- int fts_block_offset, int fts_block_size) {
- nand.enabled = 1;
- nand.bytes_per_page = bytes_per_page;
- nand.pages_per_block = pages_per_block;
- nand.fts_block_offset = fts_block_offset;
- nand.fts_block_size = fts_block_size;
-}
-
static void LogToStderr(const char *tag, const char *format, va_list ap) {
fprintf(stderr, "%s: ", tag);
vfprintf(stderr, format, ap);
@@ -156,161 +143,6 @@ int Save(struct drive *drive, const uint8_t *buf,
return CGPT_OK;
}
-static int get_hex_char_value(char ch) {
- if (ch >= '0' && ch <= '9') {
- return ch - '0';
- }
- if (ch >= 'a' && ch <= 'f') {
- return ch - 'a' + 10;
- }
- if (ch >= 'A' && ch <= 'F') {
- return ch - 'A' + 10;
- }
- return -1;
-}
-
-static int TryInitMtd(const char *dev) {
- static int already_inited = 0;
- if (already_inited)
- return nand.use_host_ioctl;
-
- already_inited = 1;
-
- /* If we're running on the live system, we can just use /dev/fts and not
- * actually need the specific parameters. This needs to be accessed via
- * ioctl and not normal I/O.
- */
- if (!strcmp(dev, FTS_DEVICE) && !access(FTS_DEVICE, R_OK | W_OK)) {
- nand.enabled = 1;
- nand.use_host_ioctl = 1;
- return 1;
- }
- return 0;
-}
-
-int FlashGet(const char *key, uint8_t *data, uint32_t *bufsz) {
- char *hex = (char*)malloc(*bufsz * 2);
- char *read;
- uint32_t written = 0;
-
- if (nand.use_host_ioctl) {
- struct flash_ts_io_req req;
- strncpy(req.key, key, sizeof(req.key));
- int fd = open(FTS_DEVICE, O_RDWR);
- if (fd < 0)
- return -1;
- if (ioctl(fd, FLASH_TS_IO_GET, &req))
- return -1;
- strncpy(hex, req.val, *bufsz * 2);
- close(fd);
- } else {
- flash_ts_get(key, hex, *bufsz * 2);
- }
-
- /* Hex -> binary */
- for (read = hex; read < hex + *bufsz * 2 && *read != '\0'; read += 2) {
- int c0, c1;
- c0 = get_hex_char_value(read[0]);
- c1 = get_hex_char_value(read[1]);
- if (c0 < 0 || c1 < 0) {
- free(hex);
- return -1;
- }
-
- data[written++] = (c0 << 4) + c1;
- }
- *bufsz = written;
- free(hex);
- return 0;
-}
-
-int FlashSet(const char *key, const uint8_t *data, uint32_t bufsz) {
- char *hex = (char*)malloc(bufsz * 2 + 1);
- const char *hex_chars = "0123456789ABCDEF";
- int ret;
- uint32_t i;
-
- /* Binary -> hex, we need some encoding because FTS only stores C strings */
- for (i = 0; i < bufsz; i++) {
- hex[i * 2] = hex_chars[data[i] >> 4];
- hex[i * 2 + 1] = hex_chars[data[i] & 0xF];
- }
- /* Buffer must be NUL-terminated. */
- hex[bufsz * 2] = '\0';
- if (nand.use_host_ioctl) {
- struct flash_ts_io_req req;
- strncpy(req.key, key, sizeof(req.key));
- strncpy(req.val, hex, sizeof(req.val));
- free(hex);
- int fd = open(FTS_DEVICE, O_RDWR);
- if (fd < 0)
- return -1;
- if (ioctl(fd, FLASH_TS_IO_SET, &req))
- return -1;
- close(fd);
- return 0;
- }
- ret = flash_ts_set(key, hex);
- free(hex);
- return ret;
-}
-
-int MtdLoad(struct drive *drive, int sector_bytes) {
- int ret;
- uint32_t sz;
- MtdData *mtd = &drive->mtd;
-
- mtd->sector_bytes = sector_bytes;
- mtd->drive_sectors = drive->size / mtd->sector_bytes;
-
- if (!nand.use_host_ioctl) {
- ret = flash_ts_init(mtd->fts_block_offset,
- mtd->fts_block_size,
- mtd->flash_page_bytes,
- mtd->flash_block_bytes,
- mtd->sector_bytes, /* Needed for Load() and Save() */
- drive);
- if (ret)
- return ret;
- }
-
- memset(&mtd->primary, 0, sizeof(mtd->primary));
- sz = sizeof(mtd->primary);
- ret = FlashGet(MTD_DRIVE_SIGNATURE, (uint8_t *)&mtd->primary, &sz);
- if (ret)
- return ret;
-
- /* Read less than expected */
- if (sz < MTD_DRIVE_V1_SIZE)
- memset(&mtd->primary, 0, sizeof(mtd->primary));
-
- if (nand.use_host_ioctl) {
- /* If we are using /dev/fts, we can't stat() the size, so re-use
- * our internal value to set it.
- */
- drive->size = mtd->primary.last_offset + 1;
- mtd->drive_sectors = drive->size / mtd->sector_bytes;
- }
-
- mtd->current_kernel = -1;
- mtd->current_priority = 0;
- mtd->modified = 0;
- return 0;
-}
-
-int MtdSave(struct drive *drive) {
- MtdData *mtd = &drive->mtd;
-
- if (!mtd->modified)
- return 0;
-
- mtd->primary.crc32 = 0;
- mtd->primary.crc32 = Crc32(&mtd->primary, MTD_DRIVE_V1_SIZE);
-
- return FlashSet(MTD_DRIVE_SIGNATURE, (uint8_t *)&mtd->primary,
- sizeof(mtd->primary));
-}
-
static int GptLoad(struct drive *drive, uint32_t sector_bytes) {
drive->gpt.sector_bytes = sector_bytes;
if (drive->size % drive->gpt.sector_bytes) {
@@ -446,7 +278,6 @@ static int ObtainDriveSize(int fd, uint64_t* size, uint32_t* sector_bytes) {
int DriveOpen(const char *drive_path, struct drive *drive, int mode,
uint64_t drive_size) {
uint32_t sector_bytes;
- int is_mtd = nand.enabled;
require(drive_path);
require(drive);
@@ -455,47 +286,32 @@ int DriveOpen(const char *drive_path, struct drive *drive, int mode,
memset(drive, 0, sizeof(struct drive));
drive->gpt.stored_on_device = GPT_STORED_ON_DEVICE;
- if (TryInitMtd(drive_path)) {
- is_mtd = 1;
- sector_bytes = 512; /* bytes */
- } else {
- drive->fd = open(drive_path, mode | O_LARGEFILE | O_NOFOLLOW);
- if (drive->fd == -1) {
- Error("Can't open %s: %s\n", drive_path, strerror(errno));
- return CGPT_FAILED;
- }
-
- sector_bytes = 512;
- uint64_t gpt_drive_size;
- if (ObtainDriveSize(drive->fd, &gpt_drive_size, &sector_bytes) != 0) {
- Error("Can't get drive size and bytes per sector for %s: %s\n",
- drive_path, strerror(errno));
- goto error_close;
- }
+ drive->fd = open(drive_path, mode | O_LARGEFILE | O_NOFOLLOW);
+ if (drive->fd == -1) {
+ Error("Can't open %s: %s\n", drive_path, strerror(errno));
+ return CGPT_FAILED;
+ }
- drive->gpt.gpt_drive_sectors = gpt_drive_size / sector_bytes;
- if (drive_size == 0) {
- drive->size = gpt_drive_size;
- drive->gpt.stored_on_device = GPT_STORED_ON_DEVICE;
- } else {
- drive->size = drive_size;
- drive->gpt.stored_on_device = GPT_STORED_OFF_DEVICE;
- }
+ sector_bytes = 512;
+ uint64_t gpt_drive_size;
+ if (ObtainDriveSize(drive->fd, &gpt_drive_size, &sector_bytes) != 0) {
+ Error("Can't get drive size and bytes per sector for %s: %s\n",
+ drive_path, strerror(errno));
+ goto error_close;
}
- drive->is_mtd = is_mtd;
-
- if (is_mtd) {
- drive->mtd.fts_block_offset = nand.fts_block_offset;
- drive->mtd.fts_block_size = nand.fts_block_size;
- drive->mtd.flash_page_bytes = nand.bytes_per_page;
- drive->mtd.flash_block_bytes = nand.pages_per_block * nand.bytes_per_page;
- if (MtdLoad(drive, sector_bytes)) {
- goto error_close;
- }
+
+ drive->gpt.gpt_drive_sectors = gpt_drive_size / sector_bytes;
+ if (drive_size == 0) {
+ drive->size = gpt_drive_size;
+ drive->gpt.stored_on_device = GPT_STORED_ON_DEVICE;
} else {
- if (GptLoad(drive, sector_bytes)) {
- goto error_close;
- }
+ drive->size = drive_size;
+ drive->gpt.stored_on_device = GPT_STORED_OFF_DEVICE;
+ }
+
+
+ if (GptLoad(drive, sector_bytes)) {
+ goto error_close;
}
// We just load the data. Caller must validate it.
@@ -511,14 +327,8 @@ int DriveClose(struct drive *drive, int update_as_needed) {
int errors = 0;
if (update_as_needed) {
- if (drive->is_mtd) {
- if (MtdSave(drive)) {
- errors++;
- }
- } else {
- if (GptSave(drive)) {
+ if (GptSave(drive)) {
errors++;
- }
}
}
@@ -816,44 +626,16 @@ const static struct {
const Guid *type;
char *name;
char *description;
- int mtd_type;
} supported_types[] = {
- {&guid_chromeos_firmware, "firmware", "ChromeOS firmware",
- MTD_PARTITION_TYPE_CHROMEOS_FIRMWARE},
- {&guid_chromeos_kernel, "kernel", "ChromeOS kernel",
- MTD_PARTITION_TYPE_CHROMEOS_KERNEL},
- {&guid_chromeos_rootfs, "rootfs", "ChromeOS rootfs",
- MTD_PARTITION_TYPE_CHROMEOS_ROOTFS},
- {&guid_linux_data, "data", "Linux data",
- MTD_PARTITION_TYPE_LINUX_DATA},
- {&guid_chromeos_reserved, "reserved", "ChromeOS reserved",
- MTD_PARTITION_TYPE_CHROMEOS_RESERVED},
- {&guid_efi, "efi", "EFI System Partition",
- MTD_PARTITION_TYPE_EFI},
- {&guid_unused, "unused", "Unused (nonexistent) partition",
- MTD_PARTITION_TYPE_UNUSED},
+ {&guid_chromeos_firmware, "firmware", "ChromeOS firmware"},
+ {&guid_chromeos_kernel, "kernel", "ChromeOS kernel"},
+ {&guid_chromeos_rootfs, "rootfs", "ChromeOS rootfs"},
+ {&guid_linux_data, "data", "Linux data"},
+ {&guid_chromeos_reserved, "reserved", "ChromeOS reserved"},
+ {&guid_efi, "efi", "EFI System Partition"},
+ {&guid_unused, "unused", "Unused (nonexistent) partition"},
};
-int LookupMtdTypeForGuid(const Guid *type) {
- int i;
- for (i = 0; i < ARRAY_COUNT(supported_types); ++i) {
- if (!memcmp(type, supported_types[i].type, sizeof(Guid))) {
- return supported_types[i].mtd_type;
- }
- }
- return MTD_PARTITION_TYPE_OTHER;
-}
-
-const Guid *LookupGuidForMtdType(int type) {
- int i;
- for (i = 0; i < ARRAY_COUNT(supported_types); ++i) {
- if (supported_types[i].mtd_type == type) {
- return supported_types[i].type;
- }
- }
- return NULL;
-}
-
/* Resolves human-readable GPT type.
* Returns CGPT_OK if found.
* Returns CGPT_FAILED if no known type found. */
@@ -899,9 +681,6 @@ static GptHeader* GetGptHeader(const GptData *gpt) {
}
uint32_t GetNumberOfEntries(const struct drive *drive) {
- if (drive->is_mtd)
- return MTD_MAX_PARTITIONS;
-
GptHeader *header = GetGptHeader(&drive->gpt);
if (!header)
return 0;
@@ -933,130 +712,74 @@ GptEntry *GetEntry(GptData *gpt, int secondary, uint32_t entry_index) {
return (GptEntry*)(&entries[stride * entry_index]);
}
-MtdDiskPartition* MtdGetEntry(MtdData *mtd, int secondary, uint32_t index) {
- if (index >= MTD_MAX_PARTITIONS)
- return NULL;
- return &mtd->primary.partitions[index];
-}
-
void SetPriority(struct drive *drive, int secondary, uint32_t entry_index,
int priority) {
require(priority >= 0 && priority <= CGPT_ATTRIBUTE_MAX_PRIORITY);
- if (drive->is_mtd) {
- MtdDiskPartition *e = MtdGetEntry(&drive->mtd, secondary, entry_index);
- MtdSetEntryPriority(e, priority);
- } else {
- GptEntry *entry;
- entry = GetEntry(&drive->gpt, secondary, entry_index);
- SetEntryPriority(entry, priority);
- }
+ GptEntry *entry;
+ entry = GetEntry(&drive->gpt, secondary, entry_index);
+ SetEntryPriority(entry, priority);
}
int GetPriority(struct drive *drive, int secondary, uint32_t entry_index) {
- if (drive->is_mtd) {
- MtdDiskPartition *e = MtdGetEntry(&drive->mtd, secondary, entry_index);
- return MtdGetEntryPriority(e);
- } else {
- GptEntry *entry;
- entry = GetEntry(&drive->gpt, secondary, entry_index);
- return GetEntryPriority(entry);
- }
+ GptEntry *entry;
+ entry = GetEntry(&drive->gpt, secondary, entry_index);
+ return GetEntryPriority(entry);
}
void SetTries(struct drive *drive, int secondary, uint32_t entry_index,
int tries) {
require(tries >= 0 && tries <= CGPT_ATTRIBUTE_MAX_TRIES);
- if (drive->is_mtd) {
- MtdDiskPartition *e = MtdGetEntry(&drive->mtd, secondary, entry_index);
- MtdSetEntryTries(e, tries);
- } else {
- GptEntry *entry;
- entry = GetEntry(&drive->gpt, secondary, entry_index);
- SetEntryTries(entry, tries);
- }
+ GptEntry *entry;
+ entry = GetEntry(&drive->gpt, secondary, entry_index);
+ SetEntryTries(entry, tries);
}
int GetTries(struct drive *drive, int secondary, uint32_t entry_index) {
- if (drive->is_mtd) {
- MtdDiskPartition *e = MtdGetEntry(&drive->mtd, secondary, entry_index);
- return MtdGetEntryTries(e);
- } else {
- GptEntry *entry;
- entry = GetEntry(&drive->gpt, secondary, entry_index);
- return GetEntryTries(entry);
- }
+ GptEntry *entry;
+ entry = GetEntry(&drive->gpt, secondary, entry_index);
+ return GetEntryTries(entry);
}
void SetSuccessful(struct drive *drive, int secondary, uint32_t entry_index,
int success) {
require(success >= 0 && success <= CGPT_ATTRIBUTE_MAX_SUCCESSFUL);
- if (drive->is_mtd) {
- MtdDiskPartition *e = MtdGetEntry(&drive->mtd, secondary, entry_index);
- MtdSetEntrySuccessful(e, success);
- } else {
- GptEntry *entry;
- entry = GetEntry(&drive->gpt, secondary, entry_index);
- SetEntrySuccessful(entry, success);
- }
+ GptEntry *entry;
+ entry = GetEntry(&drive->gpt, secondary, entry_index);
+ SetEntrySuccessful(entry, success);
}
int GetSuccessful(struct drive *drive, int secondary, uint32_t entry_index) {
- if (drive->is_mtd) {
- MtdDiskPartition *e = MtdGetEntry(&drive->mtd, secondary, entry_index);
- return MtdGetEntrySuccessful(e);
- } else {
- GptEntry *entry;
- entry = GetEntry(&drive->gpt, secondary, entry_index);
- return GetEntrySuccessful(entry);
- }
+ GptEntry *entry;
+ entry = GetEntry(&drive->gpt, secondary, entry_index);
+ return GetEntrySuccessful(entry);
}
void SetRaw(struct drive *drive, int secondary, uint32_t entry_index,
uint32_t raw) {
- if (drive->is_mtd) {
- MtdDiskPartition *e = MtdGetEntry(&drive->mtd, secondary, entry_index);
- e->flags = raw;
- } else {
- GptEntry *entry;
- entry = GetEntry(&drive->gpt, secondary, entry_index);
- entry->attrs.fields.gpt_att = (uint16_t)raw;
- }
+ GptEntry *entry;
+ entry = GetEntry(&drive->gpt, secondary, entry_index);
+ entry->attrs.fields.gpt_att = (uint16_t)raw;
}
void UpdateAllEntries(struct drive *drive) {
- if (drive->is_mtd) {
- drive->mtd.modified = 1;
- drive->mtd.primary.crc32 = MtdHeaderCrc(&drive->mtd.primary);
- } else {
- RepairEntries(&drive->gpt, MASK_PRIMARY);
- RepairHeader(&drive->gpt, MASK_PRIMARY);
+ RepairEntries(&drive->gpt, MASK_PRIMARY);
+ RepairHeader(&drive->gpt, MASK_PRIMARY);
- drive->gpt.modified |= (GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1 |
- GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES2);
- UpdateCrc(&drive->gpt);
- }
+ drive->gpt.modified |= (GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1 |
+ GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES2);
+ UpdateCrc(&drive->gpt);
}
int IsUnused(struct drive *drive, int secondary, uint32_t index) {
- if (drive->is_mtd) {
- MtdDiskPartition *e = MtdGetEntry(&drive->mtd, secondary, index);
- return MtdGetEntryType(e) == MTD_PARTITION_TYPE_UNUSED;
- } else {
- GptEntry *entry;
- entry = GetEntry(&drive->gpt, secondary, index);
- return GuidIsZero(&entry->type);
- }
+ GptEntry *entry;
+ entry = GetEntry(&drive->gpt, secondary, index);
+ return GuidIsZero(&entry->type);
}
int IsKernel(struct drive *drive, int secondary, uint32_t index) {
- if (drive->is_mtd) {
- MtdDiskPartition *e = MtdGetEntry(&drive->mtd, secondary, index);
- return MtdGetEntryType(e) == MTD_PARTITION_TYPE_CHROMEOS_KERNEL;
- } else {
- GptEntry *entry;
- entry = GetEntry(&drive->gpt, secondary, index);
- return GuidEqual(&entry->type, &guid_chromeos_kernel);
- }
+ GptEntry *entry;
+ entry = GetEntry(&drive->gpt, secondary, index);
+ return GuidEqual(&entry->type, &guid_chromeos_kernel);
}
diff --git a/cgpt/cgpt_create.c b/cgpt/cgpt_create.c
index 18e2f51b..298e2ae5 100644
--- a/cgpt/cgpt_create.c
+++ b/cgpt/cgpt_create.c
@@ -88,31 +88,6 @@ static int GptCreate(struct drive *drive, CgptCreateParams *params) {
return 0;
}
-static int MtdCreate(struct drive *drive, CgptCreateParams *params) {
- MtdDiskLayout *h = &drive->mtd.primary;
- memset(h, 0, sizeof(*h));
- drive->mtd.modified = 1;
-
- if (!params->zap) {
- // Prep basic parameters
- memcpy(h->signature, MTD_DRIVE_SIGNATURE, sizeof(h->signature));
- h->size = sizeof(*h);
- h->first_offset = 0;
- h->last_offset = (drive->mtd.drive_sectors * drive->mtd.sector_bytes) - 1;
- h->crc32 = MtdHeaderCrc(h);
- }
- if (params->size) {
- h->last_offset = params->size - 1;
- drive->size = params->size;
- drive->mtd.drive_sectors = drive->size / drive->mtd.sector_bytes;
- } else if (!drive->mtd.drive_sectors) {
- Error("MTD create with params->size == 0 && drive->mtd.drive_sectors == 0");
- return -1;
- }
-
- return 0;
-}
-
int CgptCreate(CgptCreateParams *params) {
struct drive drive;
@@ -123,13 +98,8 @@ int CgptCreate(CgptCreateParams *params) {
params->drive_size))
return CGPT_FAILED;
- if (drive.is_mtd) {
- if (MtdCreate(&drive, params))
- goto bad;
- } else {
- if (GptCreate(&drive, params))
- goto bad;
- }
+ if (GptCreate(&drive, params))
+ goto bad;
// Write it all out
return DriveClose(&drive, 1);
diff --git a/cgpt/cgpt_find.c b/cgpt/cgpt_find.c
index 7d9ec8df..c3193040 100644
--- a/cgpt/cgpt_find.c
+++ b/cgpt/cgpt_find.c
@@ -83,20 +83,6 @@ static void showmatch(CgptFindParams *params, char *filename,
EntryDetails(entry, partnum - 1, params->numeric);
}
-// This needs to handle /dev/mmcblk0 -> /dev/mmcblk0p3, /dev/sda -> /dev/sda3
-static void mtd_showmatch(CgptFindParams *params, char *filename,
- int partnum, MtdDiskPartition *entry) {
- char * format = "%s%d\n";
- if (strncmp("/dev/mmcblk", filename, 11) == 0)
- format = "%sp%d\n";
- if (params->numeric)
- printf("%d\n", partnum);
- else
- printf(format, filename, partnum);
- if (params->verbose > 0)
- MtdEntryDetails(entry, partnum - 1, params->numeric);
-}
-
// This returns true if a GPT partition matches the search criteria. If a match
// isn't found (or if the file doesn't contain a GPT), it returns false. The
// filename and partition number that matched is left in a global, since we
@@ -144,69 +130,6 @@ static int gpt_search(CgptFindParams *params, struct drive *drive,
return retval;
}
-static int mtd_match_type_to_guid(const MtdDiskPartition *e, const Guid *guid) {
- return LookupMtdTypeForGuid(guid) == MtdGetEntryType(e);
-}
-
-static int mtd_match_content(CgptFindParams *params, struct drive *drive,
- MtdDiskPartition *entry) {
- uint64_t start, part_size;
-
- if (!params->matchlen)
- return 1;
-
- // Ensure that the region we want to match against is inside the partition.
- MtdGetPartitionSize(entry, &start, NULL, &part_size);
- if (params->matchoffset + params->matchlen > part_size) {
- return 0;
- }
-
- // Read the partition data.
- if (!FillBuffer(params,
- drive->fd,
- start + params->matchoffset,
- params->matchlen)) {
- Error("unable to read partition data\n");
- return 0;
- }
-
- // Compare it
- if (0 == memcmp(params->matchbuf, params->comparebuf, params->matchlen)) {
- return 1;
- }
-
- // Nope.
- return 0;
-}
-
-static int mtd_search(CgptFindParams *params, struct drive *drive,
- char *filename) {
- int i;
- int retval = 0;
- for (i = 0; i < GetNumberOfEntries(drive); ++i) {
- MtdDiskPartition *e = MtdGetEntry(&drive->mtd, ANY_VALID, i);
-
- if (IsUnused(drive, ANY_VALID, i))
- continue;
-
- int found = 0;
-
- // Only searches by type are possible right now
- if (params->set_type && mtd_match_type_to_guid(e, &params->type_guid)) {
- found = 1;
- }
-
- if (found && mtd_match_content(params, drive, e)) {
- params->hits++;
- retval++;
- mtd_showmatch(params, filename, i+1, e);
- if (!params->match_partnum)
- params->match_partnum = i+1;
- }
- }
- return retval;
-}
-
static int do_search(CgptFindParams *params, char *fileName) {
int retval;
struct drive drive;
@@ -214,11 +137,7 @@ static int do_search(CgptFindParams *params, char *fileName) {
if (CGPT_OK != DriveOpen(fileName, &drive, O_RDONLY, params->drive_size))
return 0;
- if (drive.is_mtd) {
- retval = mtd_search(params, &drive, fileName);
- } else {
- retval = gpt_search(params, &drive, fileName);
- }
+ retval = gpt_search(params, &drive, fileName);
(void) DriveClose(&drive, 0);
diff --git a/cgpt/cgpt_legacy.c b/cgpt/cgpt_legacy.c
index 07607690..b7582123 100644
--- a/cgpt/cgpt_legacy.c
+++ b/cgpt/cgpt_legacy.c
@@ -19,13 +19,6 @@ int CgptLegacy(CgptLegacyParams *params) {
params->drive_size))
return CGPT_FAILED;
- if (drive.is_mtd) {
- // This command requires GPT mode.
- Error("'legacy' command unsupported in MTD mode\n");
- DriveClose(&drive, 0);
- return CGPT_FAILED;
- }
-
h1 = (GptHeader *)drive.gpt.primary_header;
h2 = (GptHeader *)drive.gpt.secondary_header;
if (params->efipart) {
diff --git a/cgpt/cgpt_prioritize.c b/cgpt/cgpt_prioritize.c
index 019638d2..2bfc4843 100644
--- a/cgpt/cgpt_prioritize.c
+++ b/cgpt/cgpt_prioritize.c
@@ -110,17 +110,10 @@ int CgptPrioritize(CgptPrioritizeParams *params) {
params->drive_size))
return CGPT_FAILED;
- if (drive.is_mtd) {
- if (drive.mtd.primary.crc32 != MtdHeaderCrc(&drive.mtd.primary)) {
- Error("MTD header crc failure\n");
- return CGPT_FAILED;
- }
- } else {
- if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive.gpt))) {
- Error("GptSanityCheck() returned %d: %s\n",
- gpt_retval, GptError(gpt_retval));
- return CGPT_FAILED;
- }
+ if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive.gpt))) {
+ Error("GptSanityCheck() returned %d: %s\n",
+ gpt_retval, GptError(gpt_retval));
+ return CGPT_FAILED;
}
max_part = GetNumberOfEntries(&drive);
diff --git a/cgpt/cgpt_repair.c b/cgpt/cgpt_repair.c
index 98899026..1880ea5b 100644
--- a/cgpt/cgpt_repair.c
+++ b/cgpt/cgpt_repair.c
@@ -19,12 +19,6 @@ int CgptRepair(CgptRepairParams *params) {
params->drive_size))
return CGPT_FAILED;
- if (drive.is_mtd) {
- // Nothing to do
- DriveClose(&drive, 0);
- return 0;
- }
-
int gpt_retval = GptSanityCheck(&drive.gpt);
if (params->verbose)
printf("GptSanityCheck() returned %d: %s\n",
diff --git a/cgpt/cgpt_show.c b/cgpt/cgpt_show.c
index 32d62d38..68a185cb 100644
--- a/cgpt/cgpt_show.c
+++ b/cgpt/cgpt_show.c
@@ -66,20 +66,6 @@ void PrintSignature(const char *indent, const char *sig, size_t n, int raw) {
printf("\n");
}
-static void MtdHeaderDetails(MtdDiskLayout *header, const char *indent,
- int raw) {
- PrintSignature(indent, (char*)header->signature, sizeof(header->signature),
- raw);
-
- printf("%sSize: %d\n", indent, header->size);
- printf("%sCRC: 0x%08x %s\n", indent, header->crc32,
- (MtdHeaderCrc(header) != header->crc32) ? "(INVALID)" : "");
- printf("%sFirst offset: %llu\n", indent,
- (unsigned long long)header->first_offset);
- printf("%sLast offset: %llu\n", indent,
- (unsigned long long)header->last_offset);
-}
-
static void HeaderDetails(GptHeader *header, GptEntry *entries,
const char *indent, int raw) {
PrintSignature(indent, header->signature, sizeof(header->signature), raw);
@@ -110,45 +96,6 @@ static void HeaderDetails(GptHeader *header, GptEntry *entries,
);
}
-void MtdEntryDetails(MtdDiskPartition *entry, uint32_t index, int raw) {
- const Guid *guid = LookupGuidForMtdType(MtdGetEntryType(entry));
- char type[256];
- char contents[256];
- char name[sizeof(entry->label) + 1];
- uint64_t start, size;
- if (guid) {
- ResolveType(guid, type);
- } else {
- snprintf(type, sizeof(type), "MTD partition type %d",
- MtdGetEntryType(entry));
- }
-
- MtdGetPartitionSizeInSectors(entry, &start, NULL, &size);
-
- // Provide a NUL if we are at maximum size.
- name[sizeof(name)-1] = '\0';
- memcpy(name, entry->label, sizeof(entry->label));
- require(snprintf(contents, sizeof(contents),
- "Label: \"%s\"", name) < sizeof(contents));
-
- printf(PARTITION_FMT, (int)start, (int)size, index+1, contents);
- printf(PARTITION_MORE, "Type: ", type);
-
- if (raw && MtdGetEntryType(entry) == MTD_PARTITION_TYPE_CHROMEOS_KERNEL) {
- int tries = MtdGetEntryTries(entry);
- int successful = MtdGetEntrySuccessful(entry);
- int priority = MtdGetEntryPriority(entry);
- require(snprintf(contents, sizeof(contents),
- "priority=%d tries=%d successful=%d",
- priority, tries, successful) < sizeof(contents));
- printf(PARTITION_MORE, "Attr: ", contents);
- } else {
- require(snprintf(contents, sizeof(contents),
- "[%x]", entry->flags) < sizeof(contents));
- printf(PARTITION_MORE, "Attr: ", contents);
- }
-}
-
void EntryDetails(GptEntry *entry, uint32_t index, int raw) {
char contents[256]; // scratch buffer for formatting output
uint8_t label[GPT_PARTNAME_LEN];
@@ -194,18 +141,6 @@ void EntryDetails(GptEntry *entry, uint32_t index, int raw) {
}
}
-void MtdEntriesDetails(struct drive *drive, int secondary, int raw) {
- uint32_t i;
-
- for (i = 0; i < GetNumberOfEntries(drive); ++i) {
- MtdDiskPartition *entry;
- entry = MtdGetEntry(&drive->mtd, secondary, i);
- if (IsUnused(drive, secondary, i))
- continue;
- MtdEntryDetails(entry, i, raw);
- }
-}
-
void EntriesDetails(struct drive *drive, const int secondary, int raw) {
uint32_t i;
@@ -220,87 +155,6 @@ void EntriesDetails(struct drive *drive, const int secondary, int raw) {
}
}
-int MtdShow(struct drive *drive, CgptShowParams *params) {
- if (params->partition) { // show single partition
- if (params->partition > GetNumberOfEntries(drive)) {
- Error("invalid partition number: %d\n", params->partition);
- return CGPT_FAILED;
- }
-
- uint32_t index = params->partition - 1;
- MtdDiskPartition *entry = MtdGetEntry(&drive->mtd, ANY_VALID, index);
- char buf[256]; // scratch buffer for string conversion
- const Guid *guid;
- uint64_t start, size;
-
- MtdGetPartitionSizeInSectors(entry, &start, NULL, &size);
-
- if (params->single_item) {
- switch(params->single_item) {
- case 'b':
- printf("%u\n", (int)start);
- break;
- case 's':
- printf("%u\n", (int)size);
- break;
- case 't':
- guid = LookupGuidForMtdType(MtdGetEntryType(entry));
- GuidToStr(guid, buf, sizeof(buf));
- printf("%s\n", buf);
- break;
- case 'S':
- printf("%d\n", GetSuccessful(drive, ANY_VALID, index));
- break;
- case 'T':
- printf("%d\n", GetTries(drive, ANY_VALID, index));
- break;
- case 'P':
- printf("%d\n", GetPriority(drive, ANY_VALID, index));
- break;
- case 'A':
- printf("0x%x\n", entry->flags);
- break;
- }
- } else {
- printf(TITLE_FMT, "start", "size", "part", "contents");
- MtdEntryDetails(entry, index, params->numeric);
- }
- } else if (params->quick) { // show all partitions, quickly
- uint32_t i;
- char type[GUID_STRLEN];
-
- for (i = 0; i < GetNumberOfEntries(drive); ++i) {
- MtdDiskPartition *entry = MtdGetEntry(&drive->mtd, ANY_VALID, i);
- const Guid *guid = LookupGuidForMtdType(MtdGetEntryType(entry));
- uint64_t start, size;
-
- MtdGetPartitionSizeInSectors(entry, &start, NULL, &size);
-
- if (IsUnused(drive, ANY_VALID, i))
- continue;
-
- if (!params->numeric && guid) {
- ResolveType(guid, type);
- } else {
- snprintf(type, sizeof(type), "MTD partition type %d",
- MtdGetEntryType(entry));
- }
- printf(PARTITION_FMT, (int)start, (int)size, i+1, type);
- }
- } else { // show all partitions
- if (params->debug || params->verbose) {
- char indent[64];
-
- require(snprintf(indent, sizeof(indent), GPT_MORE) < sizeof(indent));
- MtdHeaderDetails(&drive->mtd.primary, indent, 0);
- }
- printf(TITLE_FMT, "start", "size", "part", "contents");
- MtdEntriesDetails(drive, PRIMARY, params->numeric);
- }
-
- return CGPT_OK;
-}
-
static int GptShow(struct drive *drive, CgptShowParams *params) {
int gpt_retval;
if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive->gpt))) {
@@ -486,13 +340,8 @@ int CgptShow(CgptShowParams *params) {
params->drive_size))
return CGPT_FAILED;
- if (drive.is_mtd) {
- if (MtdShow(&drive, params))
- return CGPT_FAILED;
- } else {
- if (GptShow(&drive, params))
- return CGPT_FAILED;
- }
+ if (GptShow(&drive, params))
+ return CGPT_FAILED;
DriveClose(&drive, 0);
return CGPT_OK;
diff --git a/cgpt/cmd_create.c b/cgpt/cmd_create.c
index 47137bdc..34f59cbc 100644
--- a/cgpt/cmd_create.c
+++ b/cgpt/cmd_create.c
@@ -19,7 +19,6 @@ static void Usage(void)
" default 0, meaning partitions and GPT structs are\n"
" both on DRIVE\n"
" -z Zero the sectors of the GPT table and entries\n"
- " -s NUM Size (in bytes) of the disk (MTD only)\n"
" -p NUM Size (in blocks) of the disk to pad between the\n"
" primary GPT header and its entries, default 0\n"
"\n", progname);
@@ -34,7 +33,7 @@ int cmd_create(int argc, char *argv[]) {
char *e = 0;
opterr = 0; // quiet, you
- while ((c=getopt(argc, argv, ":hzs:p:D:")) != -1)
+ while ((c=getopt(argc, argv, ":hzp:D:")) != -1)
{
switch (c)
{
@@ -49,9 +48,6 @@ int cmd_create(int argc, char *argv[]) {
case 'z':
params.zap = 1;
break;
- case 's':
- params.size = strtoull(optarg, &e, 0);
- break;
case 'p':
params.padding = strtoull(optarg, &e, 0);
if (!*optarg || (e && *e))
diff --git a/cgpt/flash_ts.c b/cgpt/flash_ts.c
deleted file mode 100644
index f37c4acc..00000000
--- a/cgpt/flash_ts.c
+++ /dev/null
@@ -1,423 +0,0 @@
-/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/* *** THIS CODE HAS NOT BEEN SECURITY REVIEWED ***
- * It lives in the firmware directory because that's where it needs to go
- * eventually, but at the moment it is used only by usermode tools.
- * Security review must be completed before this code is used in the
- * firmware.
- * See issue 246680
- */
-
-#include "flash_ts.h"
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "utility.h"
-
-// These match the linux driver
-#define FLASH_TS_MAGIC 0x53542a46
-
-#define FLASH_TS_HEADER_SIZE 16
-#define FLASH_TS_MAX_SIZE 16384
-#define FLASH_TS_MAX_ELEMENT_SIZE (FLASH_TS_MAX_SIZE - FLASH_TS_HEADER_SIZE)
-
-typedef struct {
- uint32_t magic;
- uint32_t crc;
- uint32_t length;
- uint32_t version;
- char data[FLASH_TS_MAX_ELEMENT_SIZE];
-} __attribute__((packed)) flash_ts;
-
-typedef struct {
- size_t start_block; // Partition start offset (in erase blocks)
- size_t end_block; // Partition end offset (in erase blocks)
- size_t chunk_size; // Minimum element size
- size_t pages_per_block, chunks_per_block, pages_per_chunk;
- nand_geom nand;
-
- size_t cached_block;
- size_t current_block;
-
- flash_ts current;
- flash_ts temp;
-} flash_ts_state;
-
-
-static flash_ts_state state;
-
-size_t pow2(size_t x) {
- size_t v = 1;
- while (v < x)
- v <<= 1;
- return v;
-}
-
-static inline uint32_t flash_ts_crc(const flash_ts *cache)
-{
- const unsigned char *p;
- uint32_t crc = 0;
- size_t len;
-
- /* skip magic and crc fields */
- len = cache->length + 2 * sizeof(uint32_t);
- p = (const unsigned char*)&cache->length;
-
- while (len--) {
- int i;
-
- crc ^= *p++;
- for (i = 0; i < 8; i++)
- crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
- }
- return crc ^ ~0;
-}
-
-static inline int flash_ts_check_crc(const flash_ts *ts) {
- return ts->crc == flash_ts_crc(ts);
-}
-
-static int is_blank(const void *ptr, size_t sz) {
- const unsigned char *p = (const unsigned char*)ptr;
- const unsigned char *end = p + sz;
- while (p < end)
- if (*p++ != 0xff)
- return 0;
- return 1;
-}
-
-static int is_pow2(size_t v) {
- return v && (v & (v - 1)) == 0;
-}
-
-/* Scan the entire partition to find the latest version */
-static void flash_ts_scan_partition(flash_ts_state *ts) {
- size_t block;
-
- for (block = ts->start_block; block < ts->end_block; block++) {
- if (!nand_is_bad_block(&ts->nand, block)) {
- size_t chunk;
- size_t page_base = block * ts->pages_per_block;
-
- for (chunk = 0; chunk < ts->chunks_per_block;
- chunk++, page_base += ts->pages_per_chunk) {
- if (nand_read_page(&ts->nand, page_base,
- &ts->temp, sizeof(ts->temp))) {
- continue;
- }
- if (ts->temp.magic != FLASH_TS_MAGIC ||
- ts->temp.version <= ts->current.version ||
- !flash_ts_check_crc(&ts->temp)) {
- if (is_blank(&ts->temp, sizeof(ts->temp))) {
- // Since we only write sequentially, a blank chunk means no more
- // data in this block.
- break;
- }
- continue;
- }
-
- // It's good & newer than our current version
- VBDEBUG(("Found good version %d\n", ts->temp.version));
- ts->current_block = block;
- Memcpy(&ts->current, &ts->temp, sizeof(ts->current));
- }
- }
- }
-}
-
-static char *flash_ts_search(flash_ts *ts, const char *key) {
- char *str = &ts->data[0];
- size_t keylen = strlen(key);
-
- while(*str && str + keylen < &ts->data[ts->length]) {
- // Format: name=value\0name2=value2\0 ... keyn=valuen\0\0
- if (!Memcmp(str, key, keylen) && str[keylen] == '=') {
- return &str[keylen + 1];
- } else {
- str += strlen(str) + 1; // Skip to next key
- }
- }
- return NULL;
-}
-
-static int flash_ts_find_writeable_chunk(flash_ts_state *ts, uint32_t block) {
- uint32_t page_base = block * ts->pages_per_block;
- uint32_t page_end = (block + 1) * ts->pages_per_block;
-
- for(; page_base < page_end; page_base += ts->pages_per_chunk) {
- if(!nand_read_page(&ts->nand, page_base,
- &ts->temp, sizeof(ts->temp))) {
- if (is_blank(&ts->temp, sizeof(ts->temp)))
- return page_base;
- }
- }
-
- return -1;
-}
-
-static int in_range(const flash_ts_state *ts, uint32_t block) {
- return block >= ts->start_block && block < ts->end_block;
-}
-
-static int flash_try_write(flash_ts_state *ts, uint32_t page) {
- return nand_write_page(&ts->nand, page, &ts->current, sizeof(ts->current)) ||
- nand_read_page(&ts->nand, page, &ts->temp, sizeof(ts->temp)) ||
- Memcmp(&ts->current, &ts->temp, sizeof(ts->current));
-}
-
-
-static int flash_ts_find_writeable_spot(flash_ts_state *ts,
- uint32_t *page_ofs) {
- uint32_t block;
- if (in_range(ts, ts->cached_block)) {
- // We have a starting position to scan from
- block = ts->cached_block;
- } else {
- block = ts->start_block;
- VBDEBUG(("Cached block not in range - starting from %u\n", block));
- }
- for (; block < ts->end_block; block++) {
- int chunk;
- if (nand_is_bad_block(&ts->nand, block)) {
- VBDEBUG(("Skipping bad block %u\n", block));
- continue;
- }
-
- chunk = flash_ts_find_writeable_chunk(ts, block);
- if (chunk < 0) {
- VBDEBUG(("No free chunks in block %u\n", block));
- continue;
- }
-
- VBDEBUG(("Free chunk %d in block %u\n", chunk, block));
- *page_ofs = chunk;
- ts->cached_block = block;
- return 0;
- }
- return -1;
-}
-
-static int flash_try_erase(flash_ts_state *ts, int block) {
- return nand_is_bad_block(&ts->nand, block) ||
- nand_erase_block(&ts->nand, block);
-}
-
-static int flash_erase_any_block(flash_ts_state *ts, uint32_t hint) {
- uint32_t block;
- for (block = hint; block < ts->end_block; block++) {
- if (!flash_try_erase(ts, block)) {
- ts->cached_block = block;
- VBDEBUG(("Erased block %u\n", block));
- return 0;
- }
- }
-
- if (hint > ts->end_block)
- hint = ts->end_block;
-
- for (block = ts->start_block; block < hint; block++) {
- if (!flash_try_erase(ts, block)) {
- ts->cached_block = block;
- VBDEBUG(("Erased block %u\n", block));
- return 0;
- }
- }
- return -1;
-}
-
-static int flash_ts_write(flash_ts_state *ts) {
- int passes = 3;
- uint32_t page;
-
-
- ts->cached_block = ts->current_block;
- ts->current.version++;
- ts->current.crc = flash_ts_crc(&ts->current);
- VBDEBUG(("flash_ts_write() - %u bytes, crc %08X\n",
- ts->current.length, ts->current.crc));
-
- while(passes--) {
- if (flash_ts_find_writeable_spot(ts, &page)) {
- if (ts->cached_block == ts->end_block) {
- uint32_t block;
-
- // Partition full!
- // Erase a block to get some space
- if (in_range(ts, ts->current_block) &&
- ts->current_block != ts->end_block - 1) {
- // We don't want to overwrite our good copy if we can avoid it.
- block = ts->current_block + 1;
- } else {
- block = ts->start_block;
- }
- VBDEBUG(("Partition full - begin erasing from block %u\n", block));
-
- // Erase block, and try again.
- if (flash_erase_any_block(ts, block)) {
- // Failed to erase anything, so abort.
- VBDEBUG(("All erases failed, aborting\n"));
- return -ENOMEM;
- }
- continue;
- } else {
- // Try again, re-scan everything.
- ts->cached_block = ts->end_block;
- continue;
- }
- }
-
- if (flash_try_write(ts, page)) {
- // Write failure, or read-back failure, try again with the next block.
- VBDEBUG(("Write failure, retry\n"));
- ts->cached_block++;
- continue;
- }
-
- VBDEBUG(("Successfully written v%u @ %u\n", ts->current.version, page));
- ts->current_block = ts->cached_block;
- return 0;
- }
-
- VBDEBUG(("Out of tries\n"));
- return -EAGAIN;
-}
-
-// Set value, returns 0 on success
-int flash_ts_set(const char *key, const char *value) {
- flash_ts *ts = &state.current;
- char *at;
- size_t keylen = strlen(key);
- size_t value_len = strlen(value);
-
- if (keylen == 0) {
- VBDEBUG(("0-length key - illegal\n"));
- return -1;
- }
-
- if (strchr(key, '=')) {
- VBDEBUG(("key contains '=' - illegal\n"));
- return -1;
- }
-
- Memcpy(&state.temp, &state.current, sizeof(state.temp));
-
- at = flash_ts_search(ts, key);
- if (at) {
- size_t old_value_len;
-
- // Already exists
- if (!strcmp(at, value)) {
- // No change
- VBDEBUG(("Values are the same, not writing\n"));
- return 0;
- }
-
- old_value_len = strlen(at);
- if (value_len == old_value_len) {
- // Overwrite it
- Memcpy(at, value, value_len);
- VBDEBUG(("Values are the same length, overwrite\n"));
- } else {
- // Remove it
- // if value_len == 0, then we're done
- // if value_len != old_value_len, then we do the append below
- char *src = at - (keylen + 1);
- char *end = &ts->data[ts->length];
- char *from = at + old_value_len + 1;
-
- VBDEBUG(("Delete old value\n"));
- memmove(src, from, end - from);
- ts->length -= (from-src);
- ts->data[ts->length - 1] = '\0';
- at = NULL; // Enter the append branch below
- }
- } else if (value_len == 0) {
- // Removing non-existent entry
- return 0;
- }
-
- if (!at && value_len > 0) {
- // Append it
-
- if (ts->length + keylen + 1 + value_len + 1 > FLASH_TS_MAX_ELEMENT_SIZE) {
- // Not enough space, restore previous
- VBDEBUG(("Not enough space to write %d data bytes\n", (int)value_len));
- Memcpy(&state.current, &state.temp, sizeof(state.temp));
- return -1;
- }
-
- VBDEBUG(("Append new value\n"));
- at = &ts->data[ts->length - 1];
- strcpy(at, key);
- at[keylen] = '=';
- strcpy(at + keylen + 1, value);
- ts->length += keylen + 1 + value_len + 1;
- ts->data[ts->length-1] = '\0';
- }
-
- return flash_ts_write(&state);
-}
-
-void flash_ts_get(const char *key, char *value, unsigned int size) {
- flash_ts_state *ts = &state;
- const char *at;
-
- at = flash_ts_search(&ts->current, key);
- if (at) {
- strncpy(value, at, size);
- } else {
- *value = '\0';
- }
-}
-
-int flash_ts_init(unsigned int start_block, unsigned int blocks,
- unsigned int szofpg, unsigned int szofblk,
- unsigned int szofsector, void *user) {
- flash_ts_state *ts = &state;
-
- if (!is_pow2(szofpg) || !is_pow2(szofblk) || !is_pow2(szofsector) ||
- szofsector > szofpg || szofpg > szofblk || blocks == 0)
- return -ENODEV;
-
- Memset(ts, 0, sizeof(*ts));
-
- // Page <= chunk <= block
- // Page is minimum writable unit
- // Chunk is actual write unit
- // Block is erase unit
- ts->start_block = start_block;
- ts->end_block = start_block + blocks;
- ts->pages_per_block = szofblk / szofpg;
-
- ts->nand.user = user;
- ts->nand.szofpg = szofpg;
- ts->nand.szofblk = szofblk;
- ts->nand.szofsector = szofsector;
-
- // Calculate our write size, this mirrors the linux driver's logic
- ts->chunk_size = pow2((sizeof(flash_ts) + szofpg - 1) & ~(szofpg - 1));
- if (!is_pow2(ts->chunk_size))
- return -ENODEV;
-
- ts->pages_per_chunk = ts->chunk_size / szofpg;
- if (ts->pages_per_chunk == 0 || ts->chunk_size > szofblk)
- return -ENODEV;
-
- ts->chunks_per_block = szofblk / ts->chunk_size;
-
- ts->current.version = 0;
- ts->current.length = 1;
- ts->current.magic = FLASH_TS_MAGIC;
- ts->current.crc = flash_ts_crc(&ts->current);
- ts->current.data[0] = '\0';
- ts->current_block = ts->end_block;
-
- flash_ts_scan_partition(ts);
-
- return 0;
-}
diff --git a/cgpt/flash_ts.h b/cgpt/flash_ts.h
deleted file mode 100644
index e5771bb1..00000000
--- a/cgpt/flash_ts.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#ifndef _FLASH_TS_H
-#define _FLASH_TS_H
-
-typedef struct {
- unsigned int szofpg; /* Erase unit */
- unsigned int szofblk; /* Write unit */
- unsigned int szofsector; /* Sector size used by the rest of cgpt */
- void *user;
-} nand_geom;
-
-int flash_ts_init(unsigned int start_block, unsigned int blocks,
- unsigned int szofpg, unsigned int szofblk,
- unsigned int szofsector, void *user);
-
-/* Get/set value, returns 0 on success */
-int flash_ts_set(const char *key, const char *value);
-void flash_ts_get(const char *key, char *value, unsigned int size);
-
-/* Get value as an integer, if missing/invalid return 'default_value' */
-int flash_ts_get_int(const char *key, int default_value);
-
-
-/* These must be implemented outside the driver. */
-int nand_read_page(const nand_geom *nand, int page, void *buf, int size);
-int nand_write_page(const nand_geom *nand, int page, const void *buf, int size);
-int nand_erase_block(const nand_geom *nand, int block);
-int nand_is_bad_block(const nand_geom *nand, int block);
-
-
-
-#endif /* _FLASH_TS_H */
diff --git a/cgpt/flash_ts_api.h b/cgpt/flash_ts_api.h
deleted file mode 100644
index 47264a4d..00000000
--- a/cgpt/flash_ts_api.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#ifndef _LINUX_FLASH_TS_H_
-#define _LINUX_FLASH_TS_H_
-
-#include <asm/ioctl.h>
-#include <asm/types.h>
-
-#define FLASH_TS_MAX_KEY_SIZE 64
-#define FLASH_TS_MAX_VAL_SIZE 2048
-
-struct flash_ts_io_req {
- char key[FLASH_TS_MAX_KEY_SIZE];
- char val[FLASH_TS_MAX_VAL_SIZE];
-};
-
-#define FLASH_TS_IO_MAGIC 0xFE
-#define FLASH_TS_IO_SET _IOW(FLASH_TS_IO_MAGIC, 0, struct flash_ts_io_req)
-#define FLASH_TS_IO_GET _IOWR(FLASH_TS_IO_MAGIC, 1, struct flash_ts_io_req)
-
-#define FTS_DEVICE "/dev/fts"
-
-#endif /* _LINUX_FLASH_TS_H_ */
diff --git a/cgpt/flash_ts_drv.c b/cgpt/flash_ts_drv.c
deleted file mode 100644
index 4709b37c..00000000
--- a/cgpt/flash_ts_drv.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * Utility for ChromeOS-specific GPT partitions, Please see corresponding .c
- * files for more details.
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "flash_ts.h"
-#include "cgpt.h"
-
-inline int page_to_sector(const nand_geom *nand, int page) {
- return page * (nand->szofpg / nand->szofsector);
-}
-
-int nand_read_page(const nand_geom *nand, int page, void *buf, int size) {
- uint8_t *page_buff;
-
- if (Load((struct drive *)nand->user, &page_buff,
- page_to_sector(nand, page), nand->szofsector,
- (size + nand->szofsector - 1) / nand->szofsector)) {
-
- // page may be not erased. return default data.
- memset(buf, 0xff, size);
- return 0;
- }
- memcpy(buf, page_buff, size);
- free(page_buff);
- return 0;
-}
-
-int nand_write_page(const nand_geom *nand,
- int page, const void *buf, int buf_size) {
- void *page_buff;
- int ret;
- int sectors = (buf_size + nand->szofsector - 1) / nand->szofsector;
- int size = nand->szofsector * sectors;
-
- page_buff = malloc(size);
- if (!page_buff)
- return -1;
-
- memset(page_buff, 0xff, size);
- memcpy(page_buff, buf, buf_size);
-
- ret = Save((struct drive *)nand->user, page_buff, page_to_sector(nand, page),
- nand->szofsector, sectors);
- free(page_buff);
- return ret;
-}
-
-int nand_erase_block(const nand_geom *nand, int block) {
- int sector = block * (nand->szofblk / nand->szofsector);
- int res;
- void *erase_buff = malloc(nand->szofblk);
- if (!erase_buff)
- return -1;
-
- memset(erase_buff, 0xff, nand->szofblk);
- res = Save((struct drive *)nand->user, erase_buff, sector,
- nand->szofsector, nand->szofblk / nand->szofsector);
- free(erase_buff);
- return res;
-}
-
-int nand_is_bad_block(const nand_geom *nand, int block) {
- return 0;
-}