summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChe-Liang Chiou <clchiou@chromium.org>2011-07-22 20:39:45 +0800
committerSimon Glass <sjg@chromium.org>2011-08-29 10:59:10 -0700
commitcf2414a7b3d7bd2e7ee363fd6e356a3e4d9339a7 (patch)
tree0c1df789498b09c8bb85371b33aad3f79b6d259e /lib
parent4ddaee01e37ed491ce7c45586ab96e5bbb905ab4 (diff)
CHROMIUM: reunify boot_kernel
During the code migration to the redesigned vboot_reference API, the boot_kernel (formerly named load_kernel_helper) was divided and its private functions were taken out to keep U-Boot compilable $ git log --oneline -3 -- lib/chromeos/load_kernel_helper.c 6cdb577 CHROMIUM: remove codes based on deprecated API of vboot_reference 29c5f74 CHROMIUM: Separate cmdline update part from load_kernel_helper library. f853479 CHROMIUM: Separate the pre-boot FDT update part from load_kernel_helper library. The commit 29c5f74 and f853479 took out the private functions for updating kernel command line and embedding crossystem data into a device tree. The functions are the guts of boot_kernel and serve no purpose other than helping boot kernel. In fact, if you diff load_kernel_helper and boot_kernel, you will find they are virtually identical, except that functions based on deprecated APIs of vboot_reference are removed in boot_kernel. As the code migration has been completed, it is time for the private functions to reunite with the boot_kernel. BUG=chromium-os:16542 TEST=boot on Aebl Change-Id: I6512d7a5197c41df7a2e9cc5d90c40be87b468b0 Reviewed-on: http://gerrit.chromium.org/gerrit/4573 Reviewed-by: Che-Liang Chiou <clchiou@chromium.org> Tested-by: Che-Liang Chiou <clchiou@chromium.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/chromeos/Makefile3
-rw-r--r--lib/chromeos/boot_kernel.c241
-rw-r--r--lib/chromeos/cmdline_updater.c109
-rw-r--r--lib/chromeos/preboot_fdt_update.c44
-rw-r--r--lib/vboot/Makefile3
-rw-r--r--lib/vboot/main_entry.c2
6 files changed, 243 insertions, 159 deletions
diff --git a/lib/chromeos/Makefile b/lib/chromeos/Makefile
index e21429a399..751bc42df2 100644
--- a/lib/chromeos/Makefile
+++ b/lib/chromeos/Makefile
@@ -12,12 +12,11 @@ include $(TOPDIR)/config.mk
LIB = $(obj)libchromeos.a
-COBJS-$(CONFIG_CHROMEOS) += cmdline_updater.o
+COBJS-$(CONFIG_CHROMEOS) += boot_kernel.o
COBJS-$(CONFIG_CHROMEOS) += crossystem_data.o
COBJS-$(CONFIG_CHROMEOS) += fdt_decode.o
COBJS-$(CONFIG_CHROMEOS) += firmware_storage_spi.o
COBJS-$(CONFIG_CHROMEOS) += memory_wipe.o
-COBJS-$(CONFIG_CHROMEOS) += preboot_fdt_update.o
# TODO(sjg): This MMC code is not needed as yet, and needs slight changes
# to build now
diff --git a/lib/chromeos/boot_kernel.c b/lib/chromeos/boot_kernel.c
new file mode 100644
index 0000000000..16cd1dc364
--- /dev/null
+++ b/lib/chromeos/boot_kernel.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2011 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.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ */
+
+#include <common.h>
+#include <part.h>
+#include <chromeos/boot_kernel.h>
+#include <chromeos/common.h>
+#include <chromeos/crossystem_data.h>
+
+#include <load_kernel_fw.h>
+#include <vboot_api.h>
+
+#define PREFIX "boot_kernel: "
+
+/*
+ * We uses a static variable to communicate with fit_update_fdt_before_boot().
+ * For more information, please see commit log.
+ */
+static crossystem_data_t *g_crossystem_data = NULL;
+
+/* defined in common/cmd_bootm.c */
+int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+
+/* Maximum kernel command-line size */
+#define CROS_CONFIG_SIZE 4096
+
+/* Size of the x86 zeropage table */
+#define CROS_PARAMS_SIZE 4096
+
+/* Extra buffer to string replacement */
+#define EXTRA_BUFFER 4096
+
+/**
+ * This loads kernel command line from the buffer that holds the loaded kernel
+ * image. This function calculates the address of the command line from the
+ * bootloader address.
+ *
+ * @param bootloader_address is the address of the bootloader in the buffer
+ * @return kernel config address
+ */
+static char *get_kernel_config(char *bootloader_address)
+{
+ /* Use the bootloader address to find the kernel config location. */
+ return bootloader_address - CROS_PARAMS_SIZE - CROS_CONFIG_SIZE;
+}
+
+static uint32_t get_dev_num(const block_dev_desc_t *dev)
+{
+ return dev->dev;
+}
+
+/* assert(0 <= val && val < 99); sprintf(dst, "%u", val); */
+static char *itoa(char *dst, int val)
+{
+ if (val > 9)
+ *dst++ = '0' + val / 10;
+ *dst++ = '0' + val % 10;
+ return dst;
+}
+
+/* copied from x86 bootstub code; sprintf(dst, "%02x", val) */
+static void one_byte(char *dst, uint8_t val)
+{
+ dst[0] = "0123456789abcdef"[(val >> 4) & 0x0F];
+ dst[1] = "0123456789abcdef"[val & 0x0F];
+}
+
+/* copied from x86 bootstub code; display a GUID in canonical form */
+static char *emit_guid(char *dst, uint8_t *guid)
+{
+ one_byte(dst, guid[3]); dst += 2;
+ one_byte(dst, guid[2]); dst += 2;
+ one_byte(dst, guid[1]); dst += 2;
+ one_byte(dst, guid[0]); dst += 2;
+ *dst++ = '-';
+ one_byte(dst, guid[5]); dst += 2;
+ one_byte(dst, guid[4]); dst += 2;
+ *dst++ = '-';
+ one_byte(dst, guid[7]); dst += 2;
+ one_byte(dst, guid[6]); dst += 2;
+ *dst++ = '-';
+ one_byte(dst, guid[8]); dst += 2;
+ one_byte(dst, guid[9]); dst += 2;
+ *dst++ = '-';
+ one_byte(dst, guid[10]); dst += 2;
+ one_byte(dst, guid[11]); dst += 2;
+ one_byte(dst, guid[12]); dst += 2;
+ one_byte(dst, guid[13]); dst += 2;
+ one_byte(dst, guid[14]); dst += 2;
+ one_byte(dst, guid[15]); dst += 2;
+ return dst;
+}
+
+/**
+ * This replaces:
+ * %D -> device number
+ * %P -> partition number
+ * %U -> GUID
+ * in kernel command line.
+ *
+ * For example:
+ * ("root=/dev/sd%D%P", 2, 3) -> "root=/dev/sdc3"
+ * ("root=/dev/mmcblk%Dp%P", 0, 5) -> "root=/dev/mmcblk0p5".
+ *
+ * @param src - input string
+ * @param devnum - device number of the storage device we will mount
+ * @param partnum - partition number of the root file system we will mount
+ * @param guid - guid of the kernel partition
+ * @param dst - output string; a copy of [src] with special characters replaced
+ */
+static void update_cmdline(char *src, int devnum, int partnum, uint8_t *guid,
+ char *dst)
+{
+ int c;
+
+ // sanity check on inputs
+ if (devnum < 0 || devnum > 25 || partnum < 1 || partnum > 99) {
+ VBDEBUG(PREFIX "insane input: %d, %d\n", devnum, partnum);
+ devnum = 0;
+ partnum = 3;
+ }
+
+ while ((c = *src++)) {
+ if (c != '%') {
+ *dst++ = c;
+ continue;
+ }
+
+ switch ((c = *src++)) {
+ case '\0':
+ /* input ends in '%'; is it not well-formed? */
+ src--;
+ break;
+ case 'D':
+ /*
+ * TODO: Do we have any better way to know whether %D
+ * is replaced by a letter or digits? So far, this is
+ * done by a rule of thumb that if %D is followed by a
+ * 'p' character, then it is replaced by digits.
+ */
+ if (*src == 'p')
+ dst = itoa(dst, devnum);
+ else
+ *dst++ = 'a' + devnum;
+ break;
+ case 'P':
+ dst = itoa(dst, devnum);
+ break;
+ case 'U':
+ dst = emit_guid(dst, guid);
+ break;
+ default:
+ *dst++ = '%';
+ *dst++ = c;
+ break;
+ }
+ }
+
+ *dst = '\0';
+}
+
+/**
+ * This boots kernel specified in [kparmas].
+ *
+ * @param kparams kparams returned from VbSelectAndLoadKernel()
+ * @param cdata crossystem data pointer
+ * @return LOAD_KERNEL_INVALID if it fails to boot; otherwise it never returns
+ * to its caller
+ */
+int boot_kernel(VbSelectAndLoadKernelParams *kparams, crossystem_data_t *cdata)
+{
+ char cmdline_buf[CROS_CONFIG_SIZE + EXTRA_BUFFER];
+ char cmdline_out[CROS_CONFIG_SIZE + EXTRA_BUFFER];
+ char load_address[32];
+ char *argv[2] = {"bootm", load_address};
+ char *cmdline;
+
+ /*
+ * casting bootloader_address of uint64_t type to uintptr_t before
+ * further casting it to char * to avoid compiler warning "cast to
+ * pointer from integer of different size" on 32-bit address machine.
+ */
+ cmdline = get_kernel_config((char *)
+ (uintptr_t)kparams->bootloader_address);
+ strncpy(cmdline_buf, cmdline, CROS_CONFIG_SIZE);
+
+ /* if we have init bootargs, append it */
+ if ((cmdline = getenv("bootargs"))) {
+ strcat(cmdline_buf, " ");
+ strncat(cmdline_buf, cmdline, EXTRA_BUFFER - 1);
+ }
+
+ VBDEBUG(PREFIX "cmdline before update: %s\n", cmdline_buf);
+
+ update_cmdline(cmdline_buf,
+ get_dev_num(kparams->disk_handle),
+ kparams->partition_number + 1,
+ kparams->partition_guid,
+ cmdline_out);
+
+ setenv("bootargs", cmdline_out);
+ VBDEBUG(PREFIX "cmdline after update: %s\n", getenv("bootargs"));
+
+ g_crossystem_data = cdata;
+
+ sprintf(load_address, "0x%p", kparams->kernel_buffer);
+ do_bootm(NULL, 0, sizeof(argv)/sizeof(*argv), argv);
+
+ VBDEBUG(PREFIX "failed to boot; is kernel broken?\n");
+ return LOAD_KERNEL_INVALID;
+}
+
+/*
+ * This function does the last chance FDT update before booting to kernel.
+ * Currently we modify the FDT by embedding crossystem data. So before
+ * calling bootm(), g_crossystem_data should be set.
+ */
+int fit_update_fdt_before_boot(char *fdt, ulong *new_size)
+{
+ uint32_t ns;
+
+ if (!g_crossystem_data) {
+ VBDEBUG(PREFIX "warning: g_crossystem_data is NULL\n");
+ return 0;
+ }
+
+ if (crossystem_data_embed_into_fdt(g_crossystem_data, fdt, &ns)) {
+ VBDEBUG(PREFIX "crossystem_data_embed_into_fdt() failed\n");
+ return 0;
+ }
+
+ *new_size = ns;
+ return 0;
+}
diff --git a/lib/chromeos/cmdline_updater.c b/lib/chromeos/cmdline_updater.c
deleted file mode 100644
index d431adfb7d..0000000000
--- a/lib/chromeos/cmdline_updater.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2011 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.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- */
-
-#include <common.h>
-#include <chromeos/common.h>
-#include <chromeos/cmdline_updater.h>
-
-#define PREFIX "cmdline_updater: "
-
-/* assert(0 <= val && val < 99); sprintf(dst, "%u", val); */
-static char *itoa(char *dst, int val)
-{
- if (val > 9)
- *dst++ = '0' + val / 10;
- *dst++ = '0' + val % 10;
- return dst;
-}
-
-/* copied from x86 bootstub code; sprintf(dst, "%02x", val) */
-static void one_byte(char *dst, uint8_t val)
-{
- dst[0] = "0123456789abcdef"[(val >> 4) & 0x0F];
- dst[1] = "0123456789abcdef"[val & 0x0F];
-}
-
-/* copied from x86 bootstub code; display a GUID in canonical form */
-static char *emit_guid(char *dst, uint8_t *guid)
-{
- one_byte(dst, guid[3]); dst += 2;
- one_byte(dst, guid[2]); dst += 2;
- one_byte(dst, guid[1]); dst += 2;
- one_byte(dst, guid[0]); dst += 2;
- *dst++ = '-';
- one_byte(dst, guid[5]); dst += 2;
- one_byte(dst, guid[4]); dst += 2;
- *dst++ = '-';
- one_byte(dst, guid[7]); dst += 2;
- one_byte(dst, guid[6]); dst += 2;
- *dst++ = '-';
- one_byte(dst, guid[8]); dst += 2;
- one_byte(dst, guid[9]); dst += 2;
- *dst++ = '-';
- one_byte(dst, guid[10]); dst += 2;
- one_byte(dst, guid[11]); dst += 2;
- one_byte(dst, guid[12]); dst += 2;
- one_byte(dst, guid[13]); dst += 2;
- one_byte(dst, guid[14]); dst += 2;
- one_byte(dst, guid[15]); dst += 2;
- return dst;
-}
-
-/* This replaces %D, %P, and %U in kernel command line */
-void update_cmdline(char *src, int devnum, int partnum, uint8_t *guid,
- char *dst)
-{
- int c;
-
- // sanity check on inputs
- if (devnum < 0 || devnum > 25 || partnum < 1 || partnum > 99) {
- VBDEBUG(PREFIX "insane input: %d, %d\n", devnum, partnum);
- devnum = 0;
- partnum = 3;
- }
-
- while ((c = *src++)) {
- if (c != '%') {
- *dst++ = c;
- continue;
- }
-
- switch ((c = *src++)) {
- case '\0':
- /* input ends in '%'; is it not well-formed? */
- src--;
- break;
- case 'D':
- /*
- * TODO: Do we have any better way to know whether %D
- * is replaced by a letter or digits? So far, this is
- * done by a rule of thumb that if %D is followed by a
- * 'p' character, then it is replaced by digits.
- */
- if (*src == 'p')
- dst = itoa(dst, devnum);
- else
- *dst++ = 'a' + devnum;
- break;
- case 'P':
- dst = itoa(dst, devnum);
- break;
- case 'U':
- dst = emit_guid(dst, guid);
- break;
- default:
- *dst++ = '%';
- *dst++ = c;
- break;
- }
- }
-
- *dst = '\0';
-}
diff --git a/lib/chromeos/preboot_fdt_update.c b/lib/chromeos/preboot_fdt_update.c
deleted file mode 100644
index 06615aebba..0000000000
--- a/lib/chromeos/preboot_fdt_update.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2011 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.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- */
-
-#include <common.h>
-#include <chromeos/common.h>
-#include <chromeos/crossystem_data.h>
-
-#define PREFIX "preboot_fdt_update: "
-
-/*
- * We uses a static variable to communicate with fit_update_fdt_before_boot().
- * For more information, please see commit log.
- */
-static crossystem_data_t *g_crossystem_data = NULL;
-
-void set_crossystem_data(crossystem_data_t *cdata)
-{
- g_crossystem_data = cdata;
-}
-
-int fit_update_fdt_before_boot(char *fdt, ulong *new_size)
-{
- uint32_t ns;
-
- if (!g_crossystem_data) {
- VBDEBUG(PREFIX "warning: g_crossystem_data is NULL\n");
- return 0;
- }
-
- if (crossystem_data_embed_into_fdt(g_crossystem_data, fdt, &ns)) {
- VBDEBUG(PREFIX "crossystem_data_embed_into_fdt() failed\n");
- return 0;
- }
-
- *new_size = ns;
- return 0;
-}
diff --git a/lib/vboot/Makefile b/lib/vboot/Makefile
index 6e0b9c9922..b209529113 100644
--- a/lib/vboot/Makefile
+++ b/lib/vboot/Makefile
@@ -12,14 +12,11 @@ include $(TOPDIR)/config.mk
LIB = $(obj)libvboot.a
-COBJS-$(CONFIG_CHROMEOS_VBOOT) += boot_kernel.o
COBJS-$(CONFIG_CHROMEOS_VBOOT) += bootstub_entry.o
COBJS-$(CONFIG_CHROMEOS_VBOOT) += firmware_cache.o
COBJS-$(CONFIG_CHROMEOS_VBOOT) += global_data.o
COBJS-$(CONFIG_CHROMEOS_VBOOT) += main_entry.o
-COBJS-$(CONFIG_CHROMEOS_TWOSTOP) += boot_kernel.o
-
COBJS := $(COBJS-y)
OBJS := $(addprefix $(obj),$(COBJS))
diff --git a/lib/vboot/main_entry.c b/lib/vboot/main_entry.c
index c6b67d5ba8..66eff92987 100644
--- a/lib/vboot/main_entry.c
+++ b/lib/vboot/main_entry.c
@@ -9,8 +9,8 @@
*/
#include <common.h>
+#include <chromeos/boot_kernel.h>
#include <chromeos/common.h>
-#include <vboot/boot_kernel.h>
#include <vboot/entry_points.h>
#include <vboot/global_data.h>
#include <vboot_api.h>