1 // Copyright 2018 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 // ZBI Processing Library
6 // This library is meant to be a generic processing library for the ZBI format
7 // defined in system/public/zircon/boot/image.h
8 //
9 // This library has several features:
10 // (1) Zero allocations / Exceptions
11 //     Safe to use at early boot time if necessary or in other situations where
12 //     allocation may not be desirable.
13 // (2) Trivially Portable
14 //     This library attempts to limit the number of dependencies on the
15 //     environment:
16 //      + A C99 compliant compiler
17 //      + Support for sized integer types (uint8_t and uint32_t)
18 //      + zircon/boot/image.h
19 //      + Implementations of memcmp and memcpy
20 // (3) Tested
21 //     Tests for this library can be found at zircon/system/utest/zbi/*
22 
23 #pragma once
24 
25 #include <stddef.h>
26 #include <zircon/boot/image.h>
27 #include <zircon/compiler.h>
28 
29 __BEGIN_CDECLS
30 
31 typedef enum zbi_result {
32     ZBI_RESULT_OK,
33 
34     ZBI_RESULT_ERROR,
35     ZBI_RESULT_BAD_TYPE,
36     ZBI_RESULT_BAD_MAGIC,
37     ZBI_RESULT_BAD_VERSION,
38     ZBI_RESULT_BAD_CRC,
39     ZBI_RESULT_ERR_TRUNCATED,
40 
41     ZBI_RESULT_TOO_BIG,
42 
43     ZBI_RESULT_INCOMPLETE_KERNEL,
44     ZBI_RESULT_INCOMPLETE_BOOTFS,
45 } zbi_result_t;
46 
47 typedef zbi_result_t (*zbi_foreach_cb_t)(zbi_header_t* hdr,
48                                          void* payload,
49                                          void* cookie);
50 
51 // Creates an empty ZBI container in buffer.
52 zbi_result_t zbi_init(void* buffer, const size_t length);
53 
54 // Checks the integrity of the underlying ZBI.
55 // If err is not null and an error is found, err will point to the ZBI entry
56 // in which a problem was found the return value will attempt to specify the
57 // nature of the error.
58 zbi_result_t zbi_check(const void* base, zbi_header_t** err);
59 
60 // Same, but also diagnose ZBI_RESULT_INCOMPLETE_* result codes if the
61 // ZBI is not a valid complete ZBI for the host platform.
62 zbi_result_t zbi_check_complete(const void* base, zbi_header_t** err);
63 
64 // Call `cb` with a pointer to the header and payload of each ZBI item
65 // excluding the root ZBI_TYPE_CONTAINER.
66 //
67 // If any of the callbacks return anything other than ZBI_RESULT_OK, iteration
68 // will cease and zbi_for_each will short circuit and return with the error
69 // result. If all items were successfully processed, ForEach will return
70 // ZBI_RESULT_OK.
71 //
72 // cookie will be passed transparently to each cb and is available for the
73 // client to pass data back from each of the callbacks.
74 zbi_result_t zbi_for_each(const void* base, const zbi_foreach_cb_t cb,
75                           void* cookie);
76 
77 // Creates a new ZBI section and appends it to the end of the ZBI pointed to by
78 // `base`. Assumes that the buffer at `base` has a length of `capacity` which
79 // is likely longer than the size of the ZBI at `base`.
80 //
81 // The new section will be aligned to the ZBI alignment boundary. Any padding
82 // added to achieve this alignment will be zero-filled.
83 //
84 // The caller need not set the ZBI_FLAG_VERSION field of the flags field as it
85 // will be set unconditionally for the new section.
86 //
87 // CRC computation is not currently supported and setting the ZBI_FLAG_CRC32
88 // flag will yield an error.
89 zbi_result_t zbi_append_section(void* base, size_t capacity,
90                                 uint32_t section_length, uint32_t type,
91                                 uint32_t extra, uint32_t flags,
92                                 const void* payload);
93 
94 // Create a new ZBI section and returns a pointer to the payload.
95 zbi_result_t zbi_create_section(void* base, size_t capacity,
96                                 uint32_t section_length, uint32_t type,
97                                 uint32_t extra, uint32_t flags,
98                                 void** payload);
99 
100 __END_CDECLS
101