| # Copyright 2024 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. |
| """Generates device tree blob for booting GBL""" |
| |
| # GBL currently relies on device tree for passing platform specific data such |
| # as ZBI items, permanent attributes etc. The script generates a software blob |
| # containing a pre-generated device tree with placeholder bytes for poplulating |
| # these data. Once the custom GBL EFI protocols are implemented which support |
| # these, the script and the device tree mechanism can be removed. |
| # |
| # The scripts can't be run by Fuchsia build system because it requires the |
| # pylibfdt module which isn't included. |
| |
| import os |
| import pathlib |
| import subprocess |
| import textwrap |
| |
| from libfdt import FdtSw |
| |
| SCRIPT_DIR = pathlib.Path(os.path.dirname(os.path.realpath(__file__))) |
| |
| # Value from `sizeof(AvbAtxPermanentAttributes)`. |
| PERM_ATTR_SIZE = 1052 |
| |
| # SHA256 |
| PERM_ATTR_HASH_SIZE = 32 |
| |
| ZBI_BLOB_CAPACITY = 4096 |
| |
| if __name__ == "__main__": |
| sw = FdtSw() |
| sw.finish_reservemap() |
| with sw.add_node(""): |
| with sw.add_node("zircon"): |
| sw.property("zbi-blob", b"\x00" * ZBI_BLOB_CAPACITY) |
| with sw.add_node("gbl"): |
| sw.property( |
| "avb-cert-permanent-attributes", b"\x00" * PERM_ATTR_SIZE |
| ) |
| sw.property( |
| "avb-cert-permanent-attributes-hash", |
| b"\x00" * PERM_ATTR_HASH_SIZE, |
| ) |
| sw.property("stop-in-fastboot", b"\x00") |
| fdt = sw.as_fdt() |
| # Get the property offset relative to dt struct section |
| zbi_blob = fdt.first_property_offset(fdt.subnode_offset(0, "zircon")) |
| per_attr = fdt.first_property_offset(fdt.subnode_offset(0, "gbl")) |
| per_attr_hash = fdt.next_property_offset(per_attr) |
| stop_in_fastboot = fdt.next_property_offset(per_attr_hash) |
| |
| # Computes the absolute offset for property payloads relative to the start |
| # of FDT. This is done by adding the DT struct offset and skipping the |
| # `tag`, `len`, `nameoff` fields (12 bytes in total) in the property |
| # structure: |
| # |
| # struct fdt_property { |
| # fdt32_t tag; |
| # fdt32_t len; |
| # fdt32_t nameoff; |
| # char data[0]; |
| # }; |
| zbi_blob += fdt.off_dt_struct() + 12 |
| per_attr += fdt.off_dt_struct() + 12 |
| per_attr_hash += fdt.off_dt_struct() + 12 |
| stop_in_fastboot += fdt.off_dt_struct() + 12 |
| |
| cc_file = SCRIPT_DIR / "gbl_dt.cc" |
| cc_file.write_text( |
| textwrap.dedent( |
| f"""// Copyright 2024 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 <span> |
| |
| // This file is generated by {os.path.basename(__file__)} |
| namespace {{ |
| uint8_t dt[] = {{{''.join([f'0x{b:02x},' for b in fdt.as_bytearray()])}}}; |
| |
| const size_t kZbiBlobOffset = {zbi_blob}; |
| const size_t kZbiBlobSize = {ZBI_BLOB_CAPACITY}; |
| const size_t kPermAttrOffset = {per_attr}; |
| const size_t kPermAttrSize = {PERM_ATTR_SIZE}; |
| const size_t kPermAttrHashOffset = {per_attr_hash}; |
| const size_t kPermAttrHashSize = {PERM_ATTR_HASH_SIZE}; |
| const size_t kStopInFastbootOffset = {stop_in_fastboot}; |
| }} |
| |
| namespace gigaboot {{ |
| std::span<uint8_t> GblFdt() {{ |
| return {{dt , sizeof(dt)}}; |
| }} |
| |
| std::span<uint8_t> GblFdtZbiBlob() {{ |
| return {{dt + kZbiBlobOffset, kZbiBlobSize}}; |
| }} |
| |
| std::span<uint8_t> GblFdtPermAttr() {{ |
| return {{dt + kPermAttrOffset, kPermAttrSize}}; |
| }} |
| |
| std::span<uint8_t> GblFdtPermAttrHash() {{ |
| return {{dt + kPermAttrHashOffset, kPermAttrHashSize}}; |
| }} |
| |
| std::span<uint8_t> GblFdtStopInFastboot() {{ |
| return {{dt + kStopInFastbootOffset, 1}}; |
| }} |
| }} |
| """ |
| ) |
| ) |
| |
| subprocess.run(["fx", "format-code", f"--files={cc_file}"], cwd=SCRIPT_DIR) |