[Skiboot] [PATCH v2 4/7] core/nvram: add support for skiboot config strings

Oliver O'Halloran oohall at gmail.com
Wed Aug 17 15:32:51 AEST 2016


This allows the ibm,skiboot partition to be used to store NUL terminated
key=value OF configuration strings. These strings can be written using
the nvram utility found in the linux powerpc-utils package. Currently
the only use case for this is passing command line arguments to the
boot kernel so only ASCII strings are supported. The 0xFF binary
escaping mechanism for configuration strings is not supported.

Signed-off-by: Oliver O'Halloran <oohall at gmail.com>
---
 core/nvram-format.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/nvram.h     |  2 ++
 2 files changed, 70 insertions(+)

diff --git a/core/nvram-format.c b/core/nvram-format.c
index 5d15a60f05b5..227147efbaa9 100644
--- a/core/nvram-format.c
+++ b/core/nvram-format.c
@@ -179,3 +179,71 @@ int nvram_check(void *nvram_image, const uint32_t nvram_size)
  failed:
 	return -1;
 }
+
+static const char *find_next_key(const char *start, const char *end)
+{
+	/*
+	 * Unused parts of the partition are set to NUL. If we hit two
+	 * NULs in a row then we assume that we have hit the end of the
+	 * partition.
+	 */
+	if (*start == 0)
+		return NULL;
+
+	while (start < end) {
+		if (*start == 0)
+			return start + 1;
+
+		start++;
+	}
+
+	return NULL;
+}
+
+/*
+ * nvram_query() - Searches skiboot NVRAM partition for a key=value pair.
+ *
+ * Returns a pointer to a NUL terminated string that contains the value
+ * associated with the given key.
+ */
+const char *nvram_query(const char *key)
+{
+	const char *part_end = (const char *) skiboot_part_hdr +
+		skiboot_part_hdr->len * 16 - 1;
+	const char *start = (const char *) skiboot_part_hdr +
+		sizeof(*skiboot_part_hdr);
+	int key_len = strlen(key);
+
+	if (!key_len) {
+		prlog(PR_WARNING, "NVRAM: search key is empty!\n");
+		return NULL;
+	}
+
+	if (key_len > 32)
+		prlog(PR_WARNING, "NVRAM: search key '%s' is longer than 32 chars\n", key);
+
+	while (start) {
+		int remaining = part_end - start;
+
+		prlog(PR_TRACE, "NVRAM: '%s' (%lu)\n",
+			start, strlen(start));
+
+		if (key_len + 1 > remaining)
+			return NULL;
+
+		if (!strncmp(key, start, key_len) && start[key_len] == '=') {
+			const char *value = &start[key_len + 1];
+
+			prlog(PR_DEBUG, "NVRAM: Searched for '%s' found '%s'\n",
+				key, value);
+
+			return value;
+		}
+
+		start = find_next_key(start, part_end);
+	}
+
+	prlog(PR_DEBUG, "NVRAM: '%s' not found\n", key);
+
+	return NULL;
+}
diff --git a/include/nvram.h b/include/nvram.h
index c90c5712a2f7..19f8eff633e4 100644
--- a/include/nvram.h
+++ b/include/nvram.h
@@ -21,4 +21,6 @@ int nvram_format(void *nvram_image, uint32_t nvram_size);
 int nvram_check(void *nvram_image, uint32_t nvram_size);
 void nvram_reinit(void);
 
+const char *nvram_query(const char *name);
+
 #endif /* __NVRAM_H */
-- 
2.5.5



More information about the Skiboot mailing list