diff options
-rw-r--r-- | Makefile | 18 | ||||
-rw-r--r-- | cgpt/cgpt_find.c | 119 | ||||
-rw-r--r-- | cgpt/cgpt_nor.c | 10 |
3 files changed, 87 insertions, 60 deletions
@@ -187,6 +187,12 @@ ifneq (${TPM2_MODE},) CFLAGS += -DTPM2_MODE endif +# Support devices with GPT in SPI-NOR (for nand device) +# TODO(b:184812319): Consider removing this code if nobody uses it. +ifneq (${GPT_SPI_NOR},) +CFLAGS += -DGPT_SPI_NOR +endif + # Enable boot from external disk when switching to dev mode ifneq ($(filter-out 0,${BOOT_EXTERNAL_ON_DEV}),) CFLAGS += -DBOOT_EXTERNAL_ON_DEV=1 @@ -498,7 +504,6 @@ HOSTLIB_SRCS = \ cgpt/cgpt_create.c \ cgpt/cgpt_edit.c \ cgpt/cgpt_find.c \ - cgpt/cgpt_nor.c \ cgpt/cgpt_prioritize.c \ cgpt/cgpt_show.c \ firmware/2lib/2common.c \ @@ -535,6 +540,10 @@ HOSTLIB_SRCS = \ host/lib21/host_misc.c \ ${TLCL_SRCS} +ifneq (${GPT_SPI_NOR},) +HOSTLIB_SRCS += cgpt/cgpt_nor.c +endif + HOSTLIB_OBJS = ${HOSTLIB_SRCS:%.c=${BUILD}/%.o} ALL_OBJS += ${HOSTLIB_OBJS} @@ -552,7 +561,6 @@ CGPT_SRCS = \ cgpt/cgpt_edit.c \ cgpt/cgpt_find.c \ cgpt/cgpt_legacy.c \ - cgpt/cgpt_nor.c \ cgpt/cgpt_prioritize.c \ cgpt/cgpt_repair.c \ cgpt/cgpt_show.c \ @@ -566,6 +574,10 @@ CGPT_SRCS = \ cgpt/cmd_repair.c \ cgpt/cmd_show.c +ifneq (${GPT_SPI_NOR},) +CGPT_SRCS += cgpt/cgpt_nor.c +endif + CGPT_OBJS = ${CGPT_SRCS:%.c=${BUILD}/%.o} ALL_OBJS += ${CGPT_OBJS} @@ -948,7 +960,7 @@ ${CGPT_WRAPPER}: ${CGPT_WRAPPER_OBJS} ${UTILLIB} ${Q}${LD} -o ${CGPT_WRAPPER} ${LDFLAGS} $^ ${LDLIBS} .PHONY: cgpt -cgpt: ${CGPT} ${CGPT_WRAPPER} +cgpt: ${CGPT} $(if ${GPT_SPI_NOR},cgpt_wrapper) # on FreeBSD: install misc/e2fsprogs-libuuid from ports, # or e2fsprogs-libuuid from its binary package system. diff --git a/cgpt/cgpt_find.c b/cgpt/cgpt_find.c index 6f4bbae5..8046aad3 100644 --- a/cgpt/cgpt_find.c +++ b/cgpt/cgpt_find.c @@ -96,19 +96,6 @@ static void showmatch(CgptFindParams *params, const char *filename, EntryDetails(entry, partnum - 1, params->numeric); } -// This handles the MTD devices. ChromeOS uses /dev/mtdX for kernel partitions, -// /dev/ubiblockX_0 for root partitions, and /dev/ubiX for stateful partition. -static void chromeos_mtd_show(CgptFindParams *params, const char *filename, - int partnum, GptEntry *entry) { - if (GuidEqual(&guid_chromeos_kernel, &entry->type)) { - printf("/dev/mtd%d\n", partnum); - } else if (GuidEqual(&guid_chromeos_rootfs, &entry->type)) { - printf("/dev/ubiblock%d_0\n", partnum); - } else { - printf("/dev/ubi%d_0\n", partnum); - } -} - // 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 @@ -214,51 +201,29 @@ static char *is_wholedev(const char *basename) { return 0; } -// This scans all the physical devices it can find, looking for a match. It -// returns true if any matches were found, false otherwise. -static int scan_real_devs(CgptFindParams *params) { +#ifdef GPT_SPI_NOR +// This handles the MTD devices. ChromeOS uses /dev/mtdX for kernel partitions, +// /dev/ubiblockX_0 for root partitions, and /dev/ubiX for stateful partition. +static void chromeos_mtd_show(CgptFindParams *params, const char *filename, + int partnum, GptEntry *entry) { + if (GuidEqual(&guid_chromeos_kernel, &entry->type)) { + printf("/dev/mtd%d\n", partnum); + } else if (GuidEqual(&guid_chromeos_rootfs, &entry->type)) { + printf("/dev/ubiblock%d_0\n", partnum); + } else { + printf("/dev/ubi%d_0\n", partnum); + } +} + +static int scan_spi_gpt(CgptFindParams *params) { int found = 0; char partname[MAX_PARTITION_NAME_LEN]; - char partname_prev[MAX_PARTITION_NAME_LEN]; FILE *fp; - char *pathname; - - fp = fopen(PROC_PARTITIONS, "re"); - if (!fp) { - perror("can't read " PROC_PARTITIONS); - return found; - } - size_t line_length = 0; char *line = NULL; - partname_prev[0] = '\0'; - while (getline(&line, &line_length, fp) != -1) { - int ma, mi; - long long unsigned int sz; - - if (sscanf(line, " %d %d %llu %127[^\n ]", &ma, &mi, &sz, partname) != 4) - continue; - - /* Only check devices that have partitions under them. - * We can tell by checking that an entry like "sda" is immediately - * followed by one like "sda0". */ - if (!strncmp(partname_prev, partname, strlen(partname_prev)) && - strlen(partname_prev)) { - if ((pathname = is_wholedev(partname_prev))) { - if (do_search(params, pathname)) { - found++; - } - } - } - - strcpy(partname_prev, partname); - } - - fclose(fp); fp = fopen(PROC_MTD, "re"); if (!fp) { - free(line); return found; } @@ -299,6 +264,60 @@ cleanup: free(line); return found; } +#else +// Stub +static int scan_spi_gpt(CgptFindParams *params) { + return 0; +} +#endif + +// This scans all the physical devices it can find, looking for a match. It +// returns true if any matches were found, false otherwise. +static int scan_real_devs(CgptFindParams *params) { + int found = 0; + char partname[MAX_PARTITION_NAME_LEN]; + char partname_prev[MAX_PARTITION_NAME_LEN]; + FILE *fp; + char *pathname; + + fp = fopen(PROC_PARTITIONS, "re"); + if (!fp) { + perror("can't read " PROC_PARTITIONS); + return found; + } + + size_t line_length = 0; + char *line = NULL; + partname_prev[0] = '\0'; + while (getline(&line, &line_length, fp) != -1) { + int ma, mi; + long long unsigned int sz; + + if (sscanf(line, " %d %d %llu %127[^\n ]", &ma, &mi, &sz, partname) != 4) + continue; + + /* Only check devices that have partitions under them. + * We can tell by checking that an entry like "sda" is immediately + * followed by one like "sda0". */ + if (!strncmp(partname_prev, partname, strlen(partname_prev)) && + strlen(partname_prev)) { + if ((pathname = is_wholedev(partname_prev))) { + if (do_search(params, pathname)) { + found++; + } + } + } + + strcpy(partname_prev, partname); + } + + fclose(fp); + free(line); + + found += scan_spi_gpt(params); + + return found; +} void CgptFind(CgptFindParams *params) { diff --git a/cgpt/cgpt_nor.c b/cgpt/cgpt_nor.c index 40306676..f7e65e87 100644 --- a/cgpt/cgpt_nor.c +++ b/cgpt/cgpt_nor.c @@ -49,7 +49,7 @@ int GetMtdSize(const char *mtd_device, uint64_t *size) { return ret; } -// TODO(b:184559695): Remove these functions and use subprocess_run everywhere. +// TODO(b:184812319): Remove these functions and use subprocess_run everywhere. int ForkExecV(const char *cwd, const char *const argv[]) { pid_t pid = fork(); if (pid == -1) { @@ -202,6 +202,7 @@ int RemoveDir(const char *dir) { // Read RW_GPT from NOR flash to "rw_gpt" in a temp dir |temp_dir_template|. // |temp_dir_template| is passed to mkdtemp() so it must satisfy all // requirements by mkdtemp. +// TODO(b:184812319): Replace this function with flashrom_read. int ReadNorFlash(char *temp_dir_template) { int ret = 0; @@ -215,9 +216,6 @@ int ReadNorFlash(char *temp_dir_template) { // Read RW_GPT section from NOR flash to "rw_gpt". ret++; - // TODO(b:184559695): Add parameter to subprocess_run to change directory - // before exec. Also, NULL parameter is a glibc extension that _might_ - // break FreeBSD. char *cwd = getcwd(NULL, 0); if (!cwd) { Error("Cannot get current directory.\n"); @@ -247,6 +245,7 @@ out_free: } // Write "rw_gpt" back to NOR flash. We write the file in two parts for safety. +// TODO(b:184812319): Replace this function with flashrom_write. int WriteNorFlash(const char *dir) { int ret = 0; @@ -258,9 +257,6 @@ int WriteNorFlash(const char *dir) { ret++; int nr_fails = 0; - // TODO(b:184559695): Add parameter to subprocess_run to change directory - // before exec. Also, NULL parameter is a glibc extension that _might_ - // break FreeBSD. char *cwd = getcwd(NULL, 0); if (!cwd) { Error("Cannot get current directory.\n"); |