blob: a51417ca4a9ace7a417ab0fe97969268a04abf78 [file] [log] [blame]
# 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)