diff options
-rw-r--r-- | host/arch/arm/lib/crossystem_arch.c | 112 | ||||
-rw-r--r-- | host/include/crossystem_vbnv.h | 35 | ||||
-rw-r--r-- | host/lib/crossystem.c | 122 |
3 files changed, 158 insertions, 111 deletions
diff --git a/host/arch/arm/lib/crossystem_arch.c b/host/arch/arm/lib/crossystem_arch.c index 76c6d3a1..309235dc 100644 --- a/host/arch/arm/lib/crossystem_arch.c +++ b/host/arch/arm/lib/crossystem_arch.c @@ -24,9 +24,7 @@ #include "host_common.h" #include "crossystem.h" #include "crossystem_arch.h" - -#define MOSYS_CROS_PATH "/usr/sbin/mosys" -#define MOSYS_ANDROID_PATH "/system/bin/mosys" +#include "crossystem_vbnv.h" /* Base name for firmware FDT files */ #define FDT_BASE_PATH "/proc/device-tree/firmware/chromeos" @@ -50,22 +48,6 @@ #define SECTOR_SIZE 512 #define MAX_NMMCBLK 9 -static int InAndroid() { - int fd; - struct stat s; - - /* In Android, mosys utility located in /system/bin - check if file exists. Using fstat because for some - reason, stat() was seg faulting in Android */ - fd = open(MOSYS_ANDROID_PATH, O_RDONLY); - if (fstat(fd, &s) == 0) { - close(fd); - return 1; - } - close(fd); - return 0; -} - static int FindEmmcDev(void) { int mmcblk; unsigned value; @@ -253,98 +235,6 @@ out: return ret; } -static int ExecuteMosys(char * const argv[], char *buf, size_t bufsize) { - int status, mosys_to_crossystem[2]; - pid_t pid; - ssize_t n; - - if (pipe(mosys_to_crossystem) < 0) { - VBDEBUG(("pipe() error\n")); - return -1; - } - - if ((pid = fork()) < 0) { - VBDEBUG(("fork() error\n")); - close(mosys_to_crossystem[0]); - close(mosys_to_crossystem[1]); - return -1; - } else if (!pid) { /* Child */ - close(mosys_to_crossystem[0]); - /* Redirect pipe's write-end to mosys' stdout */ - if (STDOUT_FILENO != mosys_to_crossystem[1]) { - if (dup2(mosys_to_crossystem[1], STDOUT_FILENO) != STDOUT_FILENO) { - VBDEBUG(("stdout dup2() failed (mosys)\n")); - close(mosys_to_crossystem[1]); - exit(1); - } - } - /* Execute mosys */ - execv(InAndroid() ? MOSYS_ANDROID_PATH : MOSYS_CROS_PATH, argv); - /* We shouldn't be here; exit now! */ - VBDEBUG(("execv() of mosys failed\n")); - close(mosys_to_crossystem[1]); - exit(1); - } else { /* Parent */ - close(mosys_to_crossystem[1]); - if (bufsize) { - bufsize--; /* Reserve 1 byte for '\0' */ - while ((n = read(mosys_to_crossystem[0], buf, bufsize)) > 0) { - buf += n; - bufsize -= n; - } - *buf = '\0'; - } else { - n = 0; - } - close(mosys_to_crossystem[0]); - if (n < 0) - VBDEBUG(("read() error while reading output from mosys\n")); - if (waitpid(pid, &status, 0) < 0 || status) { - VBDEBUG(("waitpid() or mosys error\n")); - fprintf(stderr, "waitpid() or mosys error\n"); - return -1; - } - if (n < 0) - return -1; - } - return 0; -} - -static int VbReadNvStorage_mosys(VbNvContext* vnc) { - char hexstring[VBNV_BLOCK_SIZE * 2 + 32]; /* Reserve extra 32 bytes */ - char * const argv[] = { - InAndroid() ? MOSYS_ANDROID_PATH : MOSYS_CROS_PATH, - "nvram", "vboot", "read", NULL - }; - char hexdigit[3]; - int i; - - if (ExecuteMosys(argv, hexstring, sizeof(hexstring))) - return -1; - hexdigit[2] = '\0'; - for (i = 0; i < VBNV_BLOCK_SIZE; i++) { - hexdigit[0] = hexstring[i * 2]; - hexdigit[1] = hexstring[i * 2 + 1]; - vnc->raw[i] = strtol(hexdigit, NULL, 16); - } - return 0; -} - -static int VbWriteNvStorage_mosys(VbNvContext* vnc) { - char hexstring[VBNV_BLOCK_SIZE * 2 + 1]; - char * const argv[] = { - InAndroid() ? MOSYS_ANDROID_PATH : MOSYS_CROS_PATH, - "nvram", "vboot", "write", hexstring, NULL - }; - int i; - - for (i = 0; i < VBNV_BLOCK_SIZE; i++) - snprintf(hexstring + i * 2, 3, "%02x", vnc->raw[i]); - hexstring[sizeof(hexstring) - 1] = '\0'; - if (ExecuteMosys(argv, NULL, 0)) - return -1; - return 0; -} static int VbReadNvStorage_disk(VbNvContext* vnc) { int nvctx_fd = -1; diff --git a/host/include/crossystem_vbnv.h b/host/include/crossystem_vbnv.h new file mode 100644 index 00000000..64e0c7c7 --- /dev/null +++ b/host/include/crossystem_vbnv.h @@ -0,0 +1,35 @@ +/* Copyright 2016 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. + * + * vboot nv storage related functions exported for use by userspace programs + */ + +#ifndef VBOOT_REFERENCE_CROSSYSTEM_VBNV_H_ +#define VBOOT_REFERENCE_CROSSYSTEM_VBNV_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <vboot_nvstorage.h> + +/** + * Attempt to read VbNvContext using mosys. + * + * Returns 0 if success, non-zero if error. + */ +int VbReadNvStorage_mosys(VbNvContext* vnc); + +/** + * Attempt to write VbNvContext using mosys. + * + * Returns 0 if success, non-zero if error. + */ +int VbWriteNvStorage_mosys(VbNvContext* vnc); + +#ifdef __cplusplus +} +#endif + +#endif /* VBOOT_REFERENCE_CROSSYSTEM_VBNV_H_ */ diff --git a/host/lib/crossystem.c b/host/lib/crossystem.c index fd5cd9eb..bcbf4dd4 100644 --- a/host/lib/crossystem.c +++ b/host/lib/crossystem.c @@ -10,11 +10,17 @@ #include <sys/stat.h> #include <unistd.h> #include <ctype.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <fcntl.h> +#include <unistd.h> #include "host_common.h" #include "crossystem.h" #include "crossystem_arch.h" +#include "crossystem_vbnv.h" #include "utility.h" #include "vboot_common.h" #include "vboot_nvstorage.h" @@ -23,6 +29,9 @@ /* Filename for kernel command line */ #define KERNEL_CMDLINE_PATH "/proc/cmdline" +#define MOSYS_CROS_PATH "/usr/sbin/mosys" +#define MOSYS_ANDROID_PATH "/system/bin/mosys" + /* Fields that GetVdatString() can get */ typedef enum VdatStringField { VDAT_STRING_TIMERS = 0, /* Timer values */ @@ -717,3 +726,116 @@ int VbSetSystemPropertyString(const char* name, const char* value) { return -1; } + + +static int InAndroid() { + int fd; + struct stat s; + + /* In Android, mosys utility located in /system/bin + check if file exists. Using fstat because for some + reason, stat() was seg faulting in Android */ + fd = open(MOSYS_ANDROID_PATH, O_RDONLY); + if (fstat(fd, &s) == 0) { + close(fd); + return 1; + } + close(fd); + return 0; +} + + +static int ExecuteMosys(char * const argv[], char *buf, size_t bufsize) { + int status, mosys_to_crossystem[2]; + pid_t pid; + ssize_t n; + + if (pipe(mosys_to_crossystem) < 0) { + VBDEBUG(("pipe() error\n")); + return -1; + } + + if ((pid = fork()) < 0) { + VBDEBUG(("fork() error\n")); + close(mosys_to_crossystem[0]); + close(mosys_to_crossystem[1]); + return -1; + } else if (!pid) { /* Child */ + close(mosys_to_crossystem[0]); + /* Redirect pipe's write-end to mosys' stdout */ + if (STDOUT_FILENO != mosys_to_crossystem[1]) { + if (dup2(mosys_to_crossystem[1], STDOUT_FILENO) != STDOUT_FILENO) { + VBDEBUG(("stdout dup2() failed (mosys)\n")); + close(mosys_to_crossystem[1]); + exit(1); + } + } + /* Execute mosys */ + execv(InAndroid() ? MOSYS_ANDROID_PATH : MOSYS_CROS_PATH, argv); + /* We shouldn't be here; exit now! */ + VBDEBUG(("execv() of mosys failed\n")); + close(mosys_to_crossystem[1]); + exit(1); + } else { /* Parent */ + close(mosys_to_crossystem[1]); + if (bufsize) { + bufsize--; /* Reserve 1 byte for '\0' */ + while ((n = read(mosys_to_crossystem[0], buf, bufsize)) > 0) { + buf += n; + bufsize -= n; + } + *buf = '\0'; + } else { + n = 0; + } + close(mosys_to_crossystem[0]); + if (n < 0) + VBDEBUG(("read() error while reading output from mosys\n")); + if (waitpid(pid, &status, 0) < 0 || status) { + VBDEBUG(("waitpid() or mosys error\n")); + fprintf(stderr, "waitpid() or mosys error\n"); + return -1; + } + if (n < 0) + return -1; + } + return 0; +} + + +int VbReadNvStorage_mosys(VbNvContext* vnc) { + char hexstring[VBNV_BLOCK_SIZE * 2 + 32]; /* Reserve extra 32 bytes */ + char * const argv[] = { + InAndroid() ? MOSYS_ANDROID_PATH : MOSYS_CROS_PATH, + "nvram", "vboot", "read", NULL + }; + char hexdigit[3]; + int i; + + if (ExecuteMosys(argv, hexstring, sizeof(hexstring))) + return -1; + hexdigit[2] = '\0'; + for (i = 0; i < VBNV_BLOCK_SIZE; i++) { + hexdigit[0] = hexstring[i * 2]; + hexdigit[1] = hexstring[i * 2 + 1]; + vnc->raw[i] = strtol(hexdigit, NULL, 16); + } + return 0; +} + + +int VbWriteNvStorage_mosys(VbNvContext* vnc) { + char hexstring[VBNV_BLOCK_SIZE * 2 + 1]; + char * const argv[] = { + InAndroid() ? MOSYS_ANDROID_PATH : MOSYS_CROS_PATH, + "nvram", "vboot", "write", hexstring, NULL + }; + int i; + + for (i = 0; i < VBNV_BLOCK_SIZE; i++) + snprintf(hexstring + i * 2, 3, "%02x", vnc->raw[i]); + hexstring[sizeof(hexstring) - 1] = '\0'; + if (ExecuteMosys(argv, NULL, 0)) + return -1; + return 0; +} |