diff options
author | Duncan Laurie <dlaurie@chromium.org> | 2016-03-30 09:35:20 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-04-11 14:36:41 -0700 |
commit | e98431f52ba7501823dc7ef28eb2dc9c7c927629 (patch) | |
tree | 4ba2003aaa22d625d3afa39fc076bf95df5d5cbd | |
parent | 723b3c09debfa350f7a17e7927116c3535ac081b (diff) | |
download | vboot-e98431f52ba7501823dc7ef28eb2dc9c7c927629.tar.gz |
crossystem: Move mosys based VbNv functions to shared code
The code to read/write vbnv with mosys was implemented in the
ARM specific code so move it to the generic crosystem code
so it can be used on x86.
No functional changes in this commit.
BUG=chrome-os-partner:51846
BRANCH=none
TEST=emerge-chell vboot_reference; emerge-oak vboot_reference
Change-Id: I3fe18fadb924094e710427208976328caf12a009
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/336310
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
-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; +} |