ZHDA191 June 2026 TDA4VE-Q1
可执行有效载荷作为独立的覆盖包生成。
下面是一个示例“package_overlay.py”脚本,用于从“bin”文件生成覆盖包。
#!/usr/bin/env python3
import struct
import sys
from pathlib import Path
# Must match BootApp_OverlayPkgHeader / boot_app side checks
BOOTAPP_OVERLAY_MAGIC = 0x4F56524C # 'OVRL'
# Header layout (32 bytes)
# uint32_t magic;
# uint32_t totalSize;
# uint32_t codeSize;
# uint32_t entryOffset;
# uint32_t flags;
# uint32_t reserved[3];
HEADER_FMT = "<8I"
HEADER_SIZE = struct.calcsize(HEADER_FMT)
def make_pkg(bin_path: Path,
out_path: Path,
entry_offset: int = 0,
flags: int = 0,
prepad: int = 0) -> None:
code = bin_path.read_bytes()
if len(code) == 0:
raise ValueError(f"Empty binary: {bin_path}")
if entry_offset < 0:
raise ValueError(f"entry_offset must be >= 0: {entry_offset}")
if prepad < 0:
raise ValueError(f"prepad must be >= 0: {prepad}")
# For XIP packages, TI objcopy emits the binary without preserving the
# absolute load address. If the linker aligns .text from header_end
# 0x...20 to 0x...40, the raw binary still starts at file offset 0.
# Add explicit padding after the OVRL header so the first binary byte is
# physically placed at the same address used by the linker.
payload = (b"\x00" * prepad) + code
code_size = len(payload)
total_size = HEADER_SIZE + code_size
header = struct.pack(
HEADER_FMT,
BOOTAPP_OVERLAY_MAGIC, # magic
total_size, # totalSize
code_size, # codeSize, including any XIP prepad
entry_offset, # entryOffset from first byte after header
flags, # flags
0, 0, 0 # reserved[3]
)
out_path.write_bytes(header + payload)
print(f"Created {out_path}")
print(f" totalSize : {total_size}")
print(f" codeSize : {code_size}")
print(f" entryOffset : {entry_offset}")
print(f" flags : {flags}")
print(f" prepad : {prepad}")
def main() -> int:
if len(sys.argv) not in (3, 4, 5, 6):
print("Usage: package_overlay.py <input.bin> <output.pkg> [entry_offset] [flags] [prepad]")
return 1
in_path = Path(sys.argv[1])
out_path = Path(sys.argv[2])
entry_offset = int(sys.argv[3], 0) if len(sys.argv) >= 4 else 0
flags = int(sys.argv[4], 0) if len(sys.argv) >= 5 else 0
prepad = int(sys.argv[5], 0) if len(sys.argv) >= 6 else 0
make_pkg(in_path, out_path, entry_offset, flags, prepad)
return 0
if __name__ == "__main__":
raise SystemExit(main())下面是一个示例 shell 脚本“build_payloads.sh”,用于生成有效载荷 payloadA.pkg、payloadB.pkg 和 payloadC.pkg。
#!/usr/bin/env bash
set -e
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
OUT_DIR=${OUT_DIR:-$SCRIPT_DIR/out}
TIARMCLANG=${TIARMCLANG:-tiarmclang}
TIARMLNK=${TIARMLNK:-tiarmlnk}
TIARMOBJCOPY=${TIARMOBJCOPY:-tiarmobjcopy}
SLOT_ADDR=${SLOT_ADDR:-0x41C70000}
mkdir -p "$OUT_DIR"
prepare_linker_cmd() {
local addr=$1
local out_cmd=$2
sed "s/0x41C70000/${addr}/g" "$SCRIPT_DIR/emmc_overlay_payload.cmd" > "$out_cmd"
}
build_one() {
local tag=$1
local src=$2
local obj="$OUT_DIR/${tag}.o"
local elf="$OUT_DIR/${tag}.elf"
local bin="$OUT_DIR/${tag}.bin"
local pkg="$OUT_DIR/payload${tag^^}.pkg"
local lnk="$OUT_DIR/${tag}.cmd"
echo "[build] ${tag^^}: slot=${SLOT_ADDR} src=${src}"
prepare_linker_cmd "$SLOT_ADDR" "$lnk"
$TIARMCLANG -mcpu=cortex-r5 -mthumb -Oz -ffreestanding -fno-builtin -nostdlib \
-c -I"$SCRIPT_DIR/../include" "$SCRIPT_DIR/$src" -o "$obj"
$TIARMLNK -o "$elf" "$obj" -c "$lnk" --cinit_compression=off
$TIARMOBJCOPY -O binary "$elf" "$bin"
python3 "$SCRIPT_DIR/package_overlay.py" "$bin" "$pkg" 0x0 0x0 0x0
}
build_one a emmc_overlay_payload_a.c
build_one b emmc_overlay_payload_b.c
build_one c emmc_overlay_payload_c.c
cat <<MSG
Done. Copy these files to the FAT partition root used by boot_app:
$OUT_DIR/payloadA.pkg -> 0:/payloadA.pkg
$OUT_DIR/payloadB.pkg -> 0:/payloadB.pkg
$OUT_DIR/payloadC.pkg -> 0:/payloadC.pkg
MSG
每个包均包含
• 覆盖包标头
• 可执行代码段
• 运行时入口点信息
使用以下命令可生成有效载荷包
SLOT_ADDR=0x41C70000 ./build_payloads.sh生成的包文件随后被复制到 eMMC FATFS 分区。
图 5-1 覆盖有效载荷包生成流程.
图 5-2 覆盖包格式.