[bootdata] further movement toward new bootdata headers

- bootloader, kernel, userboot, and devmgr now support FLAG_EXTRA
  for container headers as well as item headers
- bootloader generates new style headers for prepended bootdata
  items when it detects a new style container header
- mkbootfs generates large container headers when generating
  bootdata images with crc32 enabled
- bootloader version bumped to 0.6.0 to mark the point of
  compatibility needed for kernels once we throw the switch
  to use new headers exclusively

Change-Id: Ifcb78d62f882ddd869da8d73ffe774a0f7937bc0
Esse commit está contido em:
Brian Swetland
2017-08-29 12:54:08 -07:00
commit de CQ bot account: commit-bot@chromium.org
commit 71b934bd5b
11 arquivos alterados com 224 adições e 415 exclusões
-1
Ver Arquivo
@@ -46,7 +46,6 @@ EFI_SOURCES := \
$(LOCAL_DIR)/src/osboot.c \
$(LOCAL_DIR)/src/cmdline.c \
$(LOCAL_DIR)/src/magenta.c \
$(LOCAL_DIR)/src/legacy.c \
$(LOCAL_DIR)/src/misc.c \
$(LOCAL_DIR)/src/netboot.c \
$(LOCAL_DIR)/src/netifc.c \
-340
Ver Arquivo
@@ -1,340 +0,0 @@
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <inttypes.h>
#include <stdio.h>
#include <string.h>
#include <xefi.h>
#include "osboot.h"
#include <magenta/boot/bootdata.h>
typedef struct {
uint8_t* zeropage;
uint8_t* cmdline;
void* image;
uint32_t pages;
} kernel_t;
#define E820_IGNORE 0
#define E820_RAM 1
#define E820_RESERVED 2
#define E820_ACPI 3
#define E820_NVS 4
#define E820_UNUSABLE 5
static inline const char* e820name(int e820) {
switch (e820) {
case E820_IGNORE: return "IGNORE";
case E820_RAM: return "RAM";
case E820_RESERVED: return "RESERVED";
case E820_ACPI: return "ACPI";
case E820_NVS: return "NVS";
case E820_UNUSABLE: return "UNUSABLE";
}
return "";
}
struct e820entry {
uint64_t addr;
uint64_t size;
uint32_t type;
} __attribute__((packed));
static unsigned e820type(unsigned uefi_mem_type) {
switch (uefi_mem_type) {
case EfiReservedMemoryType:
case EfiPalCode:
return E820_RESERVED;
case EfiRuntimeServicesCode:
case EfiRuntimeServicesData:
#if WITH_RUNTIME_SERVICES
return E820_RESERVED;
#else
return E820_RAM;
#endif
case EfiACPIReclaimMemory:
return E820_ACPI;
case EfiACPIMemoryNVS:
return E820_NVS;
case EfiLoaderCode:
case EfiLoaderData:
case EfiBootServicesCode:
case EfiBootServicesData:
case EfiConventionalMemory:
return E820_RAM;
case EfiMemoryMappedIO:
case EfiMemoryMappedIOPortSpace:
return E820_IGNORE;
default:
if (uefi_mem_type >= 0x80000000) {
return E820_RAM;
}
return E820_UNUSABLE;
}
}
static unsigned char scratch[32768];
static struct e820entry e820table[128];
static int process_memory_map(efi_system_table* sys, size_t* _key, int silent) {
efi_memory_descriptor* mmap;
struct e820entry* entry = e820table;
size_t msize, off;
size_t mkey, dsize;
uint32_t dversion;
unsigned n, type;
efi_status r;
msize = sizeof(scratch);
mmap = (efi_memory_descriptor*)scratch;
mkey = dsize = dversion = 0;
r = sys->BootServices->GetMemoryMap(&msize, mmap, &mkey, &dsize, &dversion);
if (!silent)
printf("r=%zx msz=%zx key=%zx dsz=%zx dvn=%x\n", r, msize, mkey, dsize, dversion);
if (r != EFI_SUCCESS) {
return -1;
}
if (msize > sizeof(scratch)) {
if (!silent)
printf("Memory Table Too Large (%zu entries)\n", (msize / dsize));
return -1;
}
for (off = 0, n = 0; off < msize; off += dsize) {
mmap = (efi_memory_descriptor*)(scratch + off);
type = e820type(mmap->Type);
if (type == E820_IGNORE) {
continue;
}
if ((n > 0) && (entry[n - 1].type == type)) {
if ((entry[n - 1].addr + entry[n - 1].size) == mmap->PhysicalStart) {
entry[n - 1].size += mmap->NumberOfPages * PAGE_SIZE;
continue;
}
}
entry[n].addr = mmap->PhysicalStart;
entry[n].size = mmap->NumberOfPages * PAGE_SIZE;
entry[n].type = type;
n++;
if (n == 128) {
if (!silent)
printf("E820 Table Too Large (%zu raw entries)\n", (msize / dsize));
return -1;
}
}
*_key = mkey;
return n;
}
#define ZP_E820_COUNT 0x1E8 // byte
#define ZP_SETUP 0x1F1 // start of setup structure
#define ZP_SETUP_SECTS 0x1F1 // byte (setup_size/512-1)
#define ZP_JUMP 0x200 // jump instruction
#define ZP_HEADER 0x202 // word "HdrS"
#define ZP_VERSION 0x206 // half 0xHHLL
#define ZP_LOADER_TYPE 0x210 // byte
#define ZP_RAMDISK_BASE 0x218 // word (ptr or 0)
#define ZP_RAMDISK_SIZE 0x21C // word (bytes)
#define ZP_EXTRA_MAGIC 0x220 // word
#define ZP_CMDLINE 0x228 // word (ptr)
#define ZP_SYSSIZE 0x1F4 // word (size/16)
#define ZP_XLOADFLAGS 0x236 // half
#define ZP_E820_TABLE 0x2D0 // 128 entries
#define ZP_ACPI_RSD 0x080 // word phys ptr
#define ZP_FB_BASE 0x090
#define ZP_FB_WIDTH 0x094
#define ZP_FB_HEIGHT 0x098
#define ZP_FB_STRIDE 0x09C
#define ZP_FB_FORMAT 0x0A0
#define ZP_FB_REGBASE 0x0A4
#define ZP_FB_SIZE 0x0A8
#define ZP_MAGIC_VALUE 0xDBC64323
#define ZP8(p, off) (*((uint8_t*)((p) + (off))))
#define ZP16(p, off) (*((uint16_t*)((p) + (off))))
#define ZP32(p, off) (*((uint32_t*)((p) + (off))))
static void install_memmap(kernel_t* k, struct e820entry* memmap, unsigned count) {
memcpy(k->zeropage + ZP_E820_TABLE, memmap, sizeof(*memmap) * count);
ZP8(k->zeropage, ZP_E820_COUNT) = count;
}
static void start_deprecated(kernel_t* k) {
// 64bit entry is at offset 0x200
uint64_t entry = (uint64_t)(k->image + 0x200);
// ebx = 0, ebp = 0, edi = 0, esi = zeropage
__asm__ __volatile__(
"movl $0, %%ebp \n"
"cli \n"
"jmp *%[entry] \n" ::[entry] "a"(entry),
[zeropage] "S"(k->zeropage),
"b"(0), "D"(0));
for (;;)
;
}
static int load_deprecated(efi_boot_services* bs, uint8_t* image, size_t sz, kernel_t* k) {
uint32_t setup_sz;
uint32_t image_sz;
uint32_t setup_end;
efi_physical_addr mem;
k->zeropage = NULL;
k->cmdline = NULL;
k->image = NULL;
k->pages = 0;
if (sz < 1024) {
// way too small to be a kernel
goto fail;
}
if (ZP32(image, ZP_HEADER) != 0x53726448) {
printf("kernel: invalid setup magic %08x\n", ZP32(image, ZP_HEADER));
goto fail;
}
if (ZP16(image, ZP_VERSION) < 0x020B) {
printf("kernel: unsupported setup version %04x\n", ZP16(image, ZP_VERSION));
goto fail;
}
setup_sz = (ZP8(image, ZP_SETUP_SECTS) + 1) * 512;
image_sz = (ZP32(image, ZP_SYSSIZE) * 16);
setup_end = ZP_JUMP + ZP8(image, ZP_JUMP + 1);
printf("setup %d image %d hdr %04x-%04x\n", setup_sz, image_sz, ZP_SETUP, setup_end);
// image size may be rounded up, thus +15
if ((setup_sz < 1024) || ((setup_sz + image_sz) > (sz + 15))) {
printf("kernel: invalid image size\n");
goto fail;
}
mem = 0xFF000;
if (bs->AllocatePages(AllocateMaxAddress, EfiLoaderData, 1, &mem)) {
printf("kernel: cannot allocate 'zero page'\n");
goto fail;
}
k->zeropage = (void*)mem;
mem = 0xFF000;
if (bs->AllocatePages(AllocateMaxAddress, EfiLoaderData, 1, &mem)) {
printf("kernel: cannot allocate commandline\n");
goto fail;
}
k->cmdline = (void*)mem;
mem = 0x100000;
k->pages = BYTES_TO_PAGES(image_sz);
if (bs->AllocatePages(AllocateAddress, EfiLoaderData, k->pages + 1, &mem)) {
printf("kernel: cannot allocate kernel\n");
goto fail;
}
k->image = (void*)mem;
// setup zero page, copy setup header from kernel binary
memset(k->zeropage, 0, PAGE_SIZE);
memcpy(k->zeropage + ZP_SETUP, image + ZP_SETUP, setup_end - ZP_SETUP);
memcpy(k->image, image + setup_sz, image_sz);
// empty commandline for now
ZP32(k->zeropage, ZP_CMDLINE) = (uint64_t)k->cmdline;
k->cmdline[0] = 0;
// default to no ramdisk
ZP32(k->zeropage, ZP_RAMDISK_BASE) = 0;
ZP32(k->zeropage, ZP_RAMDISK_SIZE) = 0;
// undefined bootloader
ZP8(k->zeropage, ZP_LOADER_TYPE) = 0xFF;
printf("kernel @%p, zeropage @%p, cmdline @%p\n",
k->image, k->zeropage, k->cmdline);
return 0;
fail:
if (k->image) {
bs->FreePages((efi_physical_addr)k->image, k->pages);
}
if (k->cmdline) {
bs->FreePages((efi_physical_addr)k->cmdline, 1);
}
if (k->zeropage) {
bs->FreePages((efi_physical_addr)k->zeropage, 1);
}
return -1;
}
int boot_deprecated(efi_handle img, efi_system_table* sys,
void* image, size_t sz,
void* ramdisk, size_t rsz,
void* cmdline, size_t csz) {
efi_boot_services* bs = sys->BootServices;
kernel_t kernel;
efi_status r;
size_t key;
int n, i;
efi_graphics_output_protocol* gop;
bs->LocateProtocol(&GraphicsOutputProtocol, NULL, (void**)&gop);
printf("boot_kernel() from %p (%zu bytes)\n", image, sz);
if (ramdisk && rsz) {
printf("ramdisk at %p (%zu bytes)\n", ramdisk, rsz);
}
if (load_deprecated(sys->BootServices, image, sz, &kernel)) {
printf("Failed to load kernel image\n");
return -1;
}
ZP32(kernel.zeropage, ZP_EXTRA_MAGIC) = ZP_MAGIC_VALUE;
ZP32(kernel.zeropage, ZP_ACPI_RSD) = find_acpi_root(img, sys);
ZP32(kernel.zeropage, ZP_FB_BASE) = (uint32_t)gop->Mode->FrameBufferBase;
ZP32(kernel.zeropage, ZP_FB_WIDTH) = (uint32_t)gop->Mode->Info->HorizontalResolution;
ZP32(kernel.zeropage, ZP_FB_HEIGHT) = (uint32_t)gop->Mode->Info->VerticalResolution;
ZP32(kernel.zeropage, ZP_FB_STRIDE) = (uint32_t)gop->Mode->Info->PixelsPerScanLine;
ZP32(kernel.zeropage, ZP_FB_FORMAT) = get_mx_pixel_format(gop);
ZP32(kernel.zeropage, ZP_FB_REGBASE) = 0;
ZP32(kernel.zeropage, ZP_FB_SIZE) = 256 * 1024 * 1024;
if (cmdline) {
memcpy(kernel.cmdline, cmdline, csz);
}
if (ramdisk && rsz) {
ZP32(kernel.zeropage, ZP_RAMDISK_BASE) = (uint32_t) (uintptr_t) ramdisk;
ZP32(kernel.zeropage, ZP_RAMDISK_SIZE) = rsz;
}
n = process_memory_map(sys, &key, 0);
for (i = 0; i < n; i++) {
struct e820entry* e = e820table + i;
printf("%016" PRIx64 " %016" PRIx64 " %s\n",
e->addr, e->size, e820name(e->type));
}
r = sys->BootServices->ExitBootServices(img, key);
if (r == EFI_INVALID_PARAMETER) {
n = process_memory_map(sys, &key, 1);
r = sys->BootServices->ExitBootServices(img, key);
if (r) {
printf("Cannot ExitBootServices! (2) %s\n", xefi_strerror(r));
return -1;
}
} else if (r) {
printf("Cannot ExitBootServices! (1) %s\n", xefi_strerror(r));
return -1;
}
install_memmap(&kernel, e820table, n);
start_deprecated(&kernel);
return 0;
}
+120 -49
Ver Arquivo
@@ -49,41 +49,94 @@ static void start_magenta(uint64_t entry, void* bootdata) {
;
}
static bool with_extra = false;
static bootextra_t default_extra = {
.reserved0 = 0,
.reserved1 = 0,
.magic = BOOTITEM_MAGIC,
.crc32 = BOOTITEM_NO_CRC32,
};
static int add_bootdata(void** ptr, size_t* avail,
bootdata_t* bd, void* data) {
size_t len = BOOTDATA_ALIGN(bd->length);
if ((sizeof(bootdata_t) + len) > *avail) {
printf("boot: no room for bootdata type=%08x size=%08x\n",
bd->type, bd->length);
return -1;
if (with_extra) {
size_t len = BOOTDATA_ALIGN(bd->length);
if ((sizeof(bootdata_t) + sizeof(bootextra_t) + len) > *avail) {
printf("boot: no room for bootdata type=%08x size=%08x\n",
bd->type, bd->length);
return -1;
}
bd->flags |= BOOTDATA_FLAG_EXTRA;
memcpy(*ptr, bd, sizeof(bootdata_t));
memcpy((*ptr) + sizeof(bootdata_t), &default_extra, sizeof(bootextra_t));
memcpy((*ptr) + sizeof(bootdata_t) + sizeof(bootextra_t), data, len);
len += sizeof(bootdata_t) + sizeof(bootextra_t);
(*ptr) += len;
(*avail) -= len;
} else {
size_t len = BOOTDATA_ALIGN(bd->length);
if ((sizeof(bootdata_t) + len) > *avail) {
printf("boot: no room for bootdata type=%08x size=%08x\n",
bd->type, bd->length);
return -1;
}
memcpy(*ptr, bd, sizeof(bootdata_t));
memcpy((*ptr) + sizeof(bootdata_t), data, len);
len += sizeof(bootdata_t);
(*ptr) += len;
(*avail) -= len;
}
memcpy(*ptr, bd, sizeof(bootdata_t));
memcpy((*ptr) + sizeof(bootdata_t), data, len);
len += sizeof(bootdata_t);
(*ptr) += len;
(*avail) -= len;
return 0;
}
static int header_check(void* image, size_t sz) {
magenta_kernel_t* kernel = image;
if ((sz < sizeof(magenta_kernel_t)) ||
(kernel->hdr_kernel.type != BOOTDATA_KERNEL)) {
printf("boot: invalid magenta kernel header\n");
return -1;
static int header_check(void* image, size_t sz, uint64_t* _entry,
size_t* _hsz, size_t* _flen, size_t* _klen) {
bootdata_t* bd = image;
size_t hsz, flen, klen;
uint64_t entry;
if (bd->flags & BOOTDATA_FLAG_EXTRA) {
hsz = sizeof(bootdata_t) + sizeof(bootextra_t);
magenta_kernel2_t* kernel2 = image;
if ((sz < sizeof(magenta_kernel2_t)) ||
(kernel2->hdr_kernel.type != BOOTDATA_KERNEL) ||
((kernel2->hdr_kernel.flags & BOOTDATA_FLAG_EXTRA) == 0)) {
printf("boot: invalid magenta kernel header\n");
return -1;
}
flen = BOOTDATA_ALIGN(kernel2->hdr_file.length);
klen = BOOTDATA_ALIGN(kernel2->hdr_kernel.length);
entry = kernel2->data_kernel.entry64;
} else {
hsz = sizeof(bootdata_t);
magenta_kernel_t* kernel = image;
if ((sz < sizeof(magenta_kernel_t)) ||
(kernel->hdr_kernel.type != BOOTDATA_KERNEL)) {
printf("boot: invalid magenta kernel header\n");
return -1;
}
flen = BOOTDATA_ALIGN(kernel->hdr_file.length);
klen = BOOTDATA_ALIGN(kernel->hdr_kernel.length);
entry = kernel->data_kernel.entry64;
}
uint32_t flen = BOOTDATA_ALIGN(kernel->hdr_file.length);
if (flen > (sz - sizeof(bootdata_t))) {
if (flen > (sz - hsz)) {
printf("boot: invalid magenta kernel header (bad flen)\n");
return -1;
}
uint32_t klen = BOOTDATA_ALIGN(kernel->hdr_kernel.length);
if (klen > (sz - (sizeof(bootdata_t) * 2))) {
if (klen > (sz - (hsz * 2))) {
printf("boot: invalid magenta kernel header (bad klen)\n");
return -1;
}
if (_entry) {
*_entry = entry;
}
if (_hsz) {
*_hsz = hsz;
*_flen = flen;
*_klen = klen;
}
return 0;
}
@@ -93,45 +146,54 @@ int boot_magenta(efi_handle img, efi_system_table* sys,
void* cmdline, size_t csz) {
efi_boot_services* bs = sys->BootServices;
uint64_t entry;
if (header_check(image, isz)) {
if (header_check(image, isz, &entry, NULL, NULL, NULL)) {
return -1;
}
if ((ramdisk == NULL) || (rsz < sizeof(bootdata_t))) {
if ((ramdisk == NULL) || (rsz < (sizeof(bootdata_t) + sizeof(bootextra_t)))) {
printf("boot: ramdisk missing or too small\n");
return -1;
}
magenta_kernel_t* kernel = image;
bootdata_t* hdr0 = ramdisk;
if ((hdr0->type != BOOTDATA_CONTAINER) ||
(hdr0->extra != BOOTDATA_MAGIC) ||
(hdr0->flags != 0)) {
(hdr0->extra != BOOTDATA_MAGIC)) {
printf("boot: ramdisk has invalid bootdata header\n");
return -1;
}
if ((hdr0->length > (rsz - sizeof(bootdata_t)))) {
// If the ramdisk container header is a new/large header,
// generate all our prepended headers in the same style...
size_t hsz = sizeof(bootdata_t);
if (hdr0->flags & BOOTDATA_FLAG_EXTRA) {
with_extra = true;
hsz += sizeof(bootextra_t);
}
if ((hdr0->length > (rsz - hsz))) {
printf("boot: ramdisk has invalid bootdata length\n");
return -1;
}
// osboot ensures we have FRONT_BYTES ahead of the
// ramdisk to prepend our own bootdata items.
//
// We used sizeof(hdr) up front but will overwrite
// the header at the start of the ramdisk so it works
// out in the end.
bootdata_t hdr;
void* bptr = ramdisk - FRONT_BYTES;
size_t blen = FRONT_BYTES;
// We create a new container header of the same size
// as the one at the start of the ramdisk
hdr.type = BOOTDATA_CONTAINER;
hdr.length = hdr0->length + FRONT_BYTES;
hdr.extra = BOOTDATA_MAGIC;
hdr.flags = 0;
hdr.flags = with_extra ? BOOTDATA_FLAG_EXTRA : 0;
memcpy(bptr, &hdr, sizeof(hdr));
bptr += sizeof(hdr);
if (with_extra) {
memcpy(bptr, &default_extra, sizeof(default_extra));
bptr += sizeof(default_extra);
}
// pass kernel commandline
hdr.type = BOOTDATA_CMDLINE;
@@ -235,15 +297,18 @@ int boot_magenta(efi_handle img, efi_system_table* sys,
}
// fill the remaining gap between pre-data and ramdisk image
if ((blen < sizeof(bootdata_t)) || (blen & 7)) {
if ((blen < hsz) || (blen & 7)) {
goto fail;
}
hdr.type = BOOTDATA_IGNORE;
hdr.length = blen - sizeof(bootdata_t);
hdr.length = blen - hsz;
memcpy(bptr, &hdr, sizeof(hdr));
if (with_extra) {
memcpy(bptr + sizeof(hdr), &default_extra, sizeof(default_extra));
}
// jump to the kernel
start_magenta(kernel->data_kernel.entry64, ramdisk - FRONT_BYTES);
start_magenta(entry, ramdisk - FRONT_BYTES);
fail:
bs->FreePages(mem, pages);
@@ -255,17 +320,14 @@ static char cmdline[CMDLINE_MAX];
int mxboot(efi_handle img, efi_system_table* sys,
void* image, size_t sz) {
if (header_check(image, sz)) {
size_t hsz, flen, klen;
if (header_check(image, sz, NULL, &hsz, &flen, &klen)) {
return -1;
}
magenta_kernel_t* kernel = image;
uint32_t flen = BOOTDATA_ALIGN(kernel->hdr_file.length);
uint32_t klen = BOOTDATA_ALIGN(kernel->hdr_kernel.length);
// ramdisk portion is file - headers - kernel len
uint32_t rlen = flen - sizeof(bootdata_t) - klen;
uint32_t roff = (sizeof(bootdata_t) * 2) + klen;
uint32_t rlen = flen - hsz - klen;
uint32_t roff = (hsz * 2) + klen;
if (rlen == 0) {
printf("mxboot: no ramdisk?!\n");
return -1;
@@ -273,7 +335,7 @@ int mxboot(efi_handle img, efi_system_table* sys,
// allocate space for the ramdisk
efi_boot_services* bs = sys->BootServices;
size_t rsz = rlen + sizeof(bootdata_t) + FRONT_BYTES;
size_t rsz = rlen + hsz + FRONT_BYTES;
size_t pages = BYTES_TO_PAGES(rsz);
void* ramdisk = NULL;
efi_status r = bs->AllocatePages(AllocateAnyPages, EfiLoaderData, pages,
@@ -289,15 +351,25 @@ int mxboot(efi_handle img, efi_system_table* sys,
hdr->length = rlen;
hdr->extra = BOOTDATA_MAGIC;
hdr->flags = 0;
memcpy(ramdisk + sizeof(bootdata_t), image + roff, rlen);
rlen += sizeof(bootdata_t);
if (hsz != sizeof(bootdata_t)) {
hdr->flags |= BOOTDATA_FLAG_EXTRA;
memcpy(hdr + 1, &default_extra, sizeof(default_extra));
}
memcpy(ramdisk + hsz, image + roff, rlen);
rlen += hsz;
printf("ramdisk @ %p\n", ramdisk);
size_t csz = cmdline_to_string(cmdline, sizeof(cmdline));
// shrink original image header to include only the kernel
kernel->hdr_file.length = sizeof(bootdata_t) + klen;
if (hsz == sizeof(bootdata_t)) {
magenta_kernel_t* kernel = image;
kernel->hdr_file.length = hsz + klen;
} else {
magenta_kernel2_t* kernel2 = image;
kernel2->hdr_file.length = hsz + klen;
}
return boot_magenta(img, sys, image, roff, ramdisk, rlen, cmdline, csz);
}
@@ -310,10 +382,9 @@ int boot_kernel(efi_handle img, efi_system_table* sys,
bootdata_t* bd = image;
if ((bd->type == BOOTDATA_CONTAINER) &&
(bd->extra == BOOTDATA_MAGIC) &&
(bd->flags == 0)) {
(bd->extra == BOOTDATA_MAGIC)) {
return boot_magenta(img, sys, image, sz, ramdisk, rsz, cmdline, csz);
} else {
return boot_deprecated(img, sys, image, sz, ramdisk, rsz, cmdline, csz);
return -1;
}
}
+22 -1
Ver Arquivo
@@ -23,6 +23,27 @@
LOCAL_DATA(_setup_start)
#if ENABLE_NEW_BOOTDATA
/* bootdata file header */
.int BOOTDATA_CONTAINER
.int PHYS(__data_end) - PHYS_LOAD_ADDRESS - 32
.int BOOTDATA_MAGIC
.int BOOTDATA_FLAG_EXTRA
.int 0
.int 0
.int BOOTITEM_MAGIC
.int BOOTITEM_NO_CRC32
/* bootdata kernel header */
.int BOOTDATA_KERNEL
.int PHYS(__data_end) - PHYS_LOAD_ADDRESS - 64
.int 0
.int BOOTDATA_FLAG_EXTRA
.int 0
.int 0
.int BOOTITEM_MAGIC
.int BOOTITEM_NO_CRC32
#else
/* bootdata file header */
.int BOOTDATA_CONTAINER
.int PHYS(__data_end) - PHYS_LOAD_ADDRESS - 16
@@ -34,7 +55,7 @@ LOCAL_DATA(_setup_start)
.int PHYS(__data_end) - PHYS_LOAD_ADDRESS - 32
.int 0
.int 0
#endif
.quad PHYS(_entry64)
.quad 0
+4
Ver Arquivo
@@ -532,6 +532,10 @@ static void process_bootdata(bootdata_t* root) {
size_t offset = sizeof(bootdata_t);
const size_t length = (root->length);
if (root->flags & BOOTDATA_FLAG_EXTRA) {
offset += sizeof(bootextra_t);
}
while (offset < length) {
uintptr_t ptr = reinterpret_cast<const uintptr_t>(root);
bootdata_t* section = reinterpret_cast<bootdata_t*>(ptr + offset);
+9 -4
Ver Arquivo
@@ -137,18 +137,23 @@ extern "C" void boot_alloc_reserve(uintptr_t phys, size_t _len);
static void process_bootdata(bootdata_t* hdr, uintptr_t phys, bool verify) {
if ((hdr->type != BOOTDATA_CONTAINER) ||
(hdr->extra != BOOTDATA_MAGIC) ||
(hdr->flags != 0)) {
(hdr->extra != BOOTDATA_MAGIC)) {
printf("bootdata: invalid %08x %08x %08x %08x\n",
hdr->type, hdr->length, hdr->extra, hdr->flags);
return;
}
size_t total_len = hdr->length + sizeof(*hdr);
size_t hsz = sizeof(bootdata_t);
if (hdr->flags & BOOTDATA_FLAG_EXTRA) {
hsz += sizeof(bootextra_t);
}
size_t total_len = hdr->length + hsz;
printf("bootdata: @ %p (%zu bytes)\n", hdr, total_len);
bootdata_t* bd = hdr + 1;
bootdata_t* bd = reinterpret_cast<bootdata_t*>(reinterpret_cast<char*>(hdr) + hsz);
size_t remain = hdr->length;
while (remain > sizeof(bootdata_t)) {
remain -= sizeof(bootdata_t);
+4
Ver Arquivo
@@ -170,6 +170,10 @@ KERNEL_CPPFLAGS :=
KERNEL_ASMFLAGS :=
KERNEL_LDFLAGS :=
ifeq ($(call TOBOOL,$(ENABLE_NEW_BOOTDATA)),true)
KERNEL_COMPILEFLAGS += -DENABLE_NEW_BOOTDATA=1
endif
# Build flags for modules that want frame pointers.
# crashlogger, ngunwind, backtrace use this so that the simplisitic unwinder
# will work with them. These are recorded here so that modules don't need
+3
Ver Arquivo
@@ -257,6 +257,9 @@ static void setup_bootfs(void) {
size_t len = bootdata.length;
size_t off = sizeof(bootdata);
if (bootdata.flags & BOOTDATA_FLAG_EXTRA) {
off += sizeof(bootextra_t);
}
while (len > sizeof(bootdata)) {
mx_status_t status = mx_vmo_read(vmo, &bootdata, off, sizeof(bootdata), &actual);
+53 -19
Ver Arquivo
@@ -245,7 +245,7 @@ okay:
return 0;
}
int import_file_as(const char* fn, uint32_t type, uint32_t hdrlen) {
int import_file_as(const char* fn, uint32_t type, uint32_t hdrlen, bootdata_t* hdr) {
// bootdata file
struct stat s;
if (stat(fn, &s) != 0) {
@@ -254,7 +254,11 @@ int import_file_as(const char* fn, uint32_t type, uint32_t hdrlen) {
}
if (type == ITEM_BOOTDATA) {
if (s.st_size < sizeof(bootdata_t)) {
size_t hsz = sizeof(bootdata_t);
if (hdr->flags & BOOTDATA_FLAG_EXTRA) {
hsz += sizeof(bootextra_t);
}
if (s.st_size < hsz) {
fprintf(stderr, "error: bootdata file too small '%s'\n", fn);
return -1;
}
@@ -262,13 +266,10 @@ int import_file_as(const char* fn, uint32_t type, uint32_t hdrlen) {
fprintf(stderr, "error: bootdata file misaligned '%s'\n", fn);
return -1;
}
if (s.st_size != (hdrlen + sizeof(bootdata_t))) {
if (s.st_size != (hdrlen + hsz)) {
fprintf(stderr, "error: bootdata header size mismatch '%s'\n", fn);
return -1;
}
// The header itself is not copied
s.st_size -= sizeof(bootdata_t);
}
fsentry_t* e;
@@ -289,8 +290,7 @@ int import_file(const char* fn, bool system) {
bootdata_t hdr;
if ((fread(&hdr, sizeof(hdr), 1, fp) != 1) ||
(hdr.type != BOOTDATA_CONTAINER) ||
(hdr.extra != BOOTDATA_MAGIC) ||
(hdr.flags != 0)) {
(hdr.extra != BOOTDATA_MAGIC)) {
// not a bootdata file, must be a manifest...
rewind(fp);
@@ -298,7 +298,7 @@ int import_file(const char* fn, bool system) {
return import_manifest(fp, fn, item);
} else {
fclose(fp);
return import_file_as(fn, ITEM_BOOTDATA, hdr.length);
return import_file_as(fn, ITEM_BOOTDATA, hdr.length, &hdr);
}
}
@@ -583,11 +583,19 @@ ssize_t copybootdatafile(int fd, const char* fn, size_t len) {
goto fail;
}
if ((hdr.type != BOOTDATA_CONTAINER) ||
(hdr.extra != BOOTDATA_MAGIC) ||
(hdr.flags != 0)) {
(hdr.extra != BOOTDATA_MAGIC)) {
fprintf(stderr, "error: '%s' is not a bootdata file\n", fn);
goto fail;
}
len -= sizeof(hdr);
if (hdr.flags & BOOTDATA_FLAG_EXTRA) {
bootextra_t extra;
if ((r = readx(fdi, &extra, sizeof(extra))) < 0) {
fprintf(stderr, "error: '%s' cannot read extra header\n", fn);
goto fail;
}
len -= sizeof(extra);
}
if ((hdr.length != len)) {
fprintf(stderr, "error: '%s' header length (%u) != %zd\n", fn, hdr.length, len);
goto fail;
@@ -836,8 +844,13 @@ int write_bootdata(const char* fn, item_t* item, bool extra) {
return -1;
}
size_t hdrsize = sizeof(bootdata_t);
if (extra) {
hdrsize += sizeof(bootextra_t);
}
// Leave room for file header
if (lseek(fd, sizeof(bootdata_t), SEEK_SET) != sizeof(bootdata_t)) {
if (lseek(fd, hdrsize, SEEK_SET) != hdrsize) {
fprintf(stderr, "error: cannot seek\n");
goto fail;
}
@@ -879,14 +892,24 @@ int write_bootdata(const char* fn, item_t* item, bool extra) {
bootdata_t filehdr = {
.type = BOOTDATA_CONTAINER,
.length = file_end - sizeof(bootdata_t),
.length = file_end - hdrsize,
.extra = BOOTDATA_MAGIC,
.flags = 0,
.flags = extra ? BOOTDATA_FLAG_EXTRA : 0,
};
if (writex(fd, &filehdr, sizeof(filehdr)) < 0) {
goto fail;
}
if (extra) {
bootextra_t fileextra = {
.reserved0 = 0,
.reserved1 = 1,
.magic = BOOTITEM_MAGIC,
.crc32 = BOOTITEM_NO_CRC32,
};
if (writex(fd, &fileextra, sizeof(fileextra)) < 0) {
goto fail;
}
}
close(fd);
return 0;
@@ -911,14 +934,25 @@ int dump_bootdata(const char* fn) {
if ((hdr.type != BOOTDATA_CONTAINER) ||
(hdr.extra != BOOTDATA_MAGIC) ||
(hdr.flags != 0) ||
(hdr.length < sizeof(hdr))) {
fprintf(stderr, "error: invalid bootdata header\n");
goto fail;
}
size_t off = sizeof(hdr);
if (hdr.flags & BOOTDATA_FLAG_EXTRA) {
bootextra_t extra;
if (readx(fd, &extra, sizeof(extra)) < 0) {
fprintf(stderr, "error: cannot read extra header\n");
goto fail;
}
if (extra.magic != BOOTITEM_MAGIC) {
fprintf(stderr, "error: invalid extra header\n");
goto fail;
}
off += sizeof(bootextra_t);
}
size_t end = off + hdr.length;
while (off < end) {
if (readx(fd, &hdr, sizeof(hdr)) < 0) {
fprintf(stderr, "error: cannot read section header\n");
@@ -1077,7 +1111,7 @@ int main(int argc, char **argv) {
return -1;
}
have_kernel = 1;
if (import_file_as(argv[1], ITEM_KERNEL, 0) < 0) {
if (import_file_as(argv[1], ITEM_KERNEL, 0, NULL) < 0) {
return -1;
}
argc--;
@@ -1093,7 +1127,7 @@ int main(int argc, char **argv) {
}
have_cmdline = true;
if (import_file_as(argv[1], ITEM_CMDLINE, 0) < 0) {
if (import_file_as(argv[1], ITEM_CMDLINE, 0, NULL) < 0) {
return -1;
}
argc--;
+8
Ver Arquivo
@@ -160,6 +160,14 @@ typedef struct {
bootdata_kernel_t data_kernel;
} 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 {
uint64_t base;
uint64_t length;
+1 -1
Ver Arquivo
@@ -9,7 +9,7 @@
// clang-format off
#define BOOTLOADER_VERSION "0.5.7"
#define BOOTLOADER_VERSION "0.6.0"
#define NB_MAGIC 0xAA774217
#define NB_DEBUGLOG_MAGIC 0xAEAE1123