Commit 3dd61046 authored by Duncan Laurie's avatar Duncan Laurie Committed by chrome-bot
Browse files

bootdata: Support new 'extra' header



Update the bootdata header from upstream which includes support for
a new 'extra' header that can contain a checksum, and a fix for the
NVLL tag ID.

Then supply this new header when building the various bootdata items
for the kernel to consume.

BUG=b:38040849
TEST=tested booting kernels with both existing format where the extra
header is optional and new format where this extra header is required

Change-Id: I8927dfd4cd3fbd8f7fac6ebf4b0f83f06c006ff5
Signed-off-by: default avatarDuncan Laurie <dlaurie@google.com>
Reviewed-on: https://chromium-review.googlesource.com/656923

Reviewed-by: default avatarFurquan Shaikh <furquan@chromium.org>
parent 046b78bd
...@@ -35,32 +35,40 @@ ...@@ -35,32 +35,40 @@
#include "vboot/boot_policy.h" #include "vboot/boot_policy.h"
#include "vboot/boot.h" #include "vboot/boot.h"
typedef struct {
bootdata_t hdr_file;
bootdata_t hdr_kernel;
bootdata_kernel_t data_kernel;
} kernel_t;
static int add_bootdata(void **ptr, size_t *avail, bootdata_t *bd, void *data) static int add_bootdata(void **ptr, size_t *avail, bootdata_t *bd, void *data)
{ {
size_t len; size_t len, offset;
bootextra_t extra = {
.magic = BOOTITEM_MAGIC,
.crc32 = BOOTITEM_NO_CRC32,
};
if (!ptr || !avail || !bd || !data) if (!ptr || !avail || !bd || !data)
return -1; return -1;
// Enable extra header
bd->flags |= BOOTDATA_FLAG_EXTRA;
len = BOOTDATA_ALIGN(bd->length); len = BOOTDATA_ALIGN(bd->length);
if ((sizeof(bootdata_t) + len) > *avail) { if ((sizeof(bootdata_t) + sizeof(bootextra_t) + len) > *avail) {
printf("%s: no room for bootdata type=0x%08x size=%u\n", printf("%s: no room for bootdata type=0x%08x size=%u\n",
__func__, bd->type, bd->length); __func__, bd->type, bd->length);
return -1; return -1;
} }
memcpy(*ptr, bd, sizeof(bootdata_t)); // Copy bootdata header into place
memcpy(*ptr + sizeof(bootdata_t), data, bd->length); memcpy(*ptr, bd, sizeof(*bd));
offset = sizeof(*bd);
// Copy bootextra header into place
memcpy(*ptr + offset, &extra, sizeof(extra));
offset += sizeof(extra);
// Copy data into place after headers
memcpy(*ptr + offset, data, bd->length);
// Clear alignment bytes at the end if necessary
if (len > bd->length) if (len > bd->length)
memset(*ptr + sizeof(bootdata_t) + bd->length, 0, memset(*ptr + offset + bd->length, 0, len - bd->length);
len - bd->length);
len += sizeof(bootdata_t); len += offset;
*ptr += len; *ptr += len;
*avail -= len; *avail -= len;
...@@ -95,7 +103,11 @@ static int bootdata_framebuffer_format(struct cb_framebuffer *fb) ...@@ -95,7 +103,11 @@ static int bootdata_framebuffer_format(struct cb_framebuffer *fb)
int bootdata_prepare(struct boot_info *bi) int bootdata_prepare(struct boot_info *bi)
{ {
kernel_t *image = bi->ramdisk_addr; bootdata_t *image = bi->ramdisk_addr;
bootextra_t extra = {
.magic = BOOTITEM_MAGIC,
.crc32 = BOOTITEM_NO_CRC32,
};
bootdata_t hdr; bootdata_t hdr;
void *bptr; void *bptr;
size_t blen; size_t blen;
...@@ -104,9 +116,8 @@ int bootdata_prepare(struct boot_info *bi) ...@@ -104,9 +116,8 @@ int bootdata_prepare(struct boot_info *bi)
printf("%s: bootdata image missing\n", __func__); printf("%s: bootdata image missing\n", __func__);
return -1; return -1;
} }
if (image->hdr_file.type != BOOTDATA_CONTAINER || if (image->type != BOOTDATA_CONTAINER ||
image->hdr_file.extra != BOOTDATA_MAGIC || image->extra != BOOTDATA_MAGIC) {
image->hdr_file.flags != 0) {
printf("%s: invalid bootdata header at %p\n", __func__, image); printf("%s: invalid bootdata header at %p\n", __func__, image);
return -1; return -1;
} }
...@@ -125,12 +136,18 @@ int bootdata_prepare(struct boot_info *bi) ...@@ -125,12 +136,18 @@ int bootdata_prepare(struct boot_info *bi)
// Add container to describe bootdata + ramdisk // Add container to describe bootdata + ramdisk
memset(&hdr, 0, sizeof(hdr)); memset(&hdr, 0, sizeof(hdr));
hdr.type = BOOTDATA_CONTAINER; hdr.type = BOOTDATA_CONTAINER;
hdr.length = image->hdr_file.length + CrosParamSize; hdr.length = image->length + CrosParamSize;
hdr.extra = BOOTDATA_MAGIC; hdr.extra = BOOTDATA_MAGIC;
hdr.flags = BOOTDATA_FLAG_EXTRA;
memcpy(bptr, &hdr, sizeof(hdr)); memcpy(bptr, &hdr, sizeof(hdr));
bptr += sizeof(hdr); bptr += sizeof(hdr);
blen -= sizeof(hdr); blen -= sizeof(hdr);
// Add extra header
memcpy(bptr, &extra, sizeof(extra));
bptr += sizeof(extra);
blen -= sizeof(extra);
// Add serial console descriptor // Add serial console descriptor
if (lib_sysinfo.serial) { if (lib_sysinfo.serial) {
bootdata_uart_t uart = { bootdata_uart_t uart = {
...@@ -186,14 +203,17 @@ int bootdata_prepare(struct boot_info *bi) ...@@ -186,14 +203,17 @@ int bootdata_prepare(struct boot_info *bi)
} }
// Ignore remaining space before the ramdisk // Ignore remaining space before the ramdisk
if ((blen < sizeof(bootdata_t)) || (blen & 7)) { if ((blen < (sizeof(bootdata_t) + sizeof(bootextra_t))) || (blen & 7)) {
printf("%s: invalid bootdata length %zd\n", __func__, blen); printf("%s: invalid bootdata length %zd\n", __func__, blen);
return -1; return -1;
} }
hdr.type = BOOTDATA_IGNORE; hdr.type = BOOTDATA_IGNORE;
hdr.length = blen; hdr.length = blen - sizeof(extra);
hdr.extra = 0; hdr.extra = 0;
hdr.flags = BOOTDATA_FLAG_EXTRA;
memcpy(bptr, &hdr, sizeof(hdr)); memcpy(bptr, &hdr, sizeof(hdr));
bptr += sizeof(hdr);
memcpy(bptr, &extra, sizeof(extra));
return 0; return 0;
} }
...@@ -36,14 +36,35 @@ ...@@ -36,14 +36,35 @@
// lsw of sha256("bootdata") // lsw of sha256("bootdata")
#define BOOTDATA_MAGIC (0x868cf7e6) #define BOOTDATA_MAGIC (0x868cf7e6)
// lsw of sha256("bootitem")
#define BOOTITEM_MAGIC (0xb5781729)
// Round n up to the next 8 byte boundary // Round n up to the next 8 byte boundary
#define BOOTDATA_ALIGN(n) (((n) + 7) & (~7)) #define BOOTDATA_ALIGN(n) (((n) + 7) & (~7))
#define BOOTITEM_NO_CRC32 (~BOOTITEM_MAGIC)
// Bootdata items with the EXTRA flag have a bootextra_t
// between them and the payload, which must have BOOTITEM_MAGIC
// in its magic field, otherwise the file is corrupt.
//
// The bootextra_t is not included in the length of the header.
// Consider the EXTRA flag to indicate a larger v2 header.
//
// The crc32 field must be BOOTITEM_NO_CRC32, unless the CRC32
// flag is present, in which case it must be a valid crc32 of
// the bootitem, bootextra (with crc32 field set to 0), and the
// payload.
#define BOOTDATA_FLAG_EXTRA (0x00010000)
// Bootdata items with the CRC32 flag must have a valid crc32
#define BOOTDATA_FLAG_CRC32 (0x00020000)
// Containers are used to wrap a set of bootdata items // Containers are used to wrap a set of bootdata items
// written to a file or partition. The "length" is the // written to a file or partition. The "length" is the
// length of the set of following bootdata items. The // length of the set of following bootdata items. The
// "extra" is the value BOOTDATA_MAGIC and "flags" is // "extra" is the value BOOTDATA_MAGIC and "flags" is
// set to 0. // set to zero, or indicates bootextra header is present.
#define BOOTDATA_CONTAINER (0x544f4f42) // BOOT #define BOOTDATA_CONTAINER (0x544f4f42) // BOOT
// BOOTFS images. The "extra" field is the decompressed // BOOTFS images. The "extra" field is the decompressed
...@@ -87,7 +108,7 @@ ...@@ -87,7 +108,7 @@
// Memory which will persist across warm boots // Memory which will persist across warm boots
// Content bootdata_lastlog_nvram_t // Content bootdata_lastlog_nvram_t
#define BOOTDATA_LASTLOG_NVRAM (0x4c4c5643) // NVLL #define BOOTDATA_LASTLOG_NVRAM (0x4c4c564e) // NVLL
// E820 Memory Table // E820 Memory Table
// Content: e820entry[] // Content: e820entry[]
...@@ -131,6 +152,13 @@ typedef struct { ...@@ -131,6 +152,13 @@ typedef struct {
uint32_t flags; uint32_t flags;
} bootdata_t; } bootdata_t;
typedef struct {
uint32_t reserved0;
uint32_t reserved1;
uint32_t magic;
uint32_t crc32;
} bootextra_t;
typedef struct { typedef struct {
uint64_t phys_base; uint64_t phys_base;
uint32_t width; uint32_t width;
...@@ -150,6 +178,14 @@ typedef struct { ...@@ -150,6 +178,14 @@ typedef struct {
bootdata_kernel_t data_kernel; bootdata_kernel_t data_kernel;
} magenta_kernel_t; } magenta_kernel_t;
typedef struct {
bootdata_t hdr_file;
bootextra_t ext_file;
bootdata_t hdr_kernel;
bootextra_t ext_kernel;
bootdata_kernel_t data_kernel;
} magenta_kernel2_t;
typedef struct { typedef struct {
uint64_t base; uint64_t base;
uint64_t length; uint64_t length;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment