summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuncan Laurie <dlaurie@chromium.org>2016-03-30 09:35:20 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-04-11 14:36:41 -0700
commite98431f52ba7501823dc7ef28eb2dc9c7c927629 (patch)
tree4ba2003aaa22d625d3afa39fc076bf95df5d5cbd
parent723b3c09debfa350f7a17e7927116c3535ac081b (diff)
downloadvboot-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.c112
-rw-r--r--host/include/crossystem_vbnv.h35
-rw-r--r--host/lib/crossystem.c122
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;
+}