1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "bootdata.h"
6 #include "util.h"
7
8 #pragma GCC visibility push(hidden)
9
10 #include <bootdata/decompress.h>
11 #include <zircon/boot/bootdata.h>
12 #include <zircon/syscalls.h>
13 #include <string.h>
14
15 #pragma GCC visibility pop
16
bootdata_get_bootfs(zx_handle_t log,zx_handle_t vmar_self,zx_handle_t bootdata_vmo)17 zx_handle_t bootdata_get_bootfs(zx_handle_t log, zx_handle_t vmar_self,
18 zx_handle_t bootdata_vmo) {
19 size_t off = 0;
20 for (;;) {
21 bootdata_t bootdata;
22 zx_status_t status = zx_vmo_read(bootdata_vmo, &bootdata,
23 off, sizeof(bootdata));
24 check(log, status, "zx_vmo_read failed on bootdata VMO");
25 if (!(bootdata.flags & BOOTDATA_FLAG_V2)) {
26 fail(log, "bootdata v1 no longer supported");
27 }
28
29 switch (bootdata.type) {
30 case BOOTDATA_CONTAINER:
31 if (off == 0) {
32 // Quietly skip container header.
33 bootdata.length = 0;
34 } else {
35 fail(log, "container in the middle of bootdata");
36 }
37 break;
38
39 case BOOTDATA_BOOTFS_BOOT:;
40 const char* errmsg;
41 zx_handle_t bootfs_vmo;
42 status = decompress_bootdata(vmar_self, bootdata_vmo, off,
43 bootdata.length + sizeof(bootdata),
44 &bootfs_vmo, &errmsg);
45 check(log, status, "%s", errmsg);
46
47 // Signal that we've already processed this one.
48 bootdata.type = BOOTDATA_BOOTFS_DISCARD;
49 check(log, zx_vmo_write(bootdata_vmo, &bootdata.type,
50 off + offsetof(bootdata_t, type),
51 sizeof(bootdata.type)),
52 "zx_vmo_write failed on bootdata VMO\n");
53
54 return bootfs_vmo;
55 }
56
57 off += BOOTDATA_ALIGN(sizeof(bootdata) + bootdata.length);
58 }
59
60 fail(log, "no '/boot' bootfs in bootstrap message\n");
61 }
62