blob: 1413df0aad3f81001ff2b8870e9331ae37fc97c7 [file] [log] [blame]
// 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 "bootdata.h"
#include "util.h"
#include <bootdata/decompress.h>
#include <zircon/boot/bootdata.h>
#include <zircon/syscalls.h>
#include <string.h>
zx_handle_t bootdata_get_bootfs(zx_handle_t log, zx_handle_t vmar_self,
zx_handle_t bootdata_vmo) {
size_t off = 0;
for (;;) {
bootdata_t bootdata;
zx_status_t status = zx_vmo_read(bootdata_vmo, &bootdata,
off, sizeof(bootdata));
check(log, status, "zx_vmo_read failed on bootdata VMO");
if (!(bootdata.flags & BOOTDATA_FLAG_V2)) {
fail(log, "bootdata v1 no longer supported");
}
switch (bootdata.type) {
case BOOTDATA_CONTAINER:
if (off == 0) {
// Quietly skip container header.
bootdata.length = 0;
} else {
fail(log, "container in the middle of bootdata");
}
break;
case BOOTDATA_BOOTFS_BOOT:;
const char* errmsg;
zx_handle_t bootfs_vmo;
status = decompress_bootdata(vmar_self, bootdata_vmo, off,
bootdata.length + sizeof(bootdata),
&bootfs_vmo, &errmsg);
check(log, status, "%s", errmsg);
// Signal that we've already processed this one.
bootdata.type = BOOTDATA_BOOTFS_DISCARD;
check(log, zx_vmo_write(bootdata_vmo, &bootdata.type,
off + offsetof(bootdata_t, type),
sizeof(bootdata.type)),
"zx_vmo_write failed on bootdata VMO\n");
return bootfs_vmo;
}
off += BOOTDATA_ALIGN(sizeof(bootdata) + bootdata.length);
}
fail(log, "no '/boot' bootfs in bootstrap message\n");
}