// 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" #pragma GCC visibility push(hidden) #include #include #include #include #pragma GCC visibility pop 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"); }