diff --git a/.gitmodules b/.gitmodules index 1c0fdfd..465203c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "libavr"] path = libavr url = ../libavr.git +[submodule "pureboot"] + path = pureboot + url = ../pureboot.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a5a0ef..d9e7c46 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,16 @@ endif() if(NOT EXISTS ${LIBAVR_ROOT}/CMakeLists.txt) message(FATAL_ERROR "libavr not found at ${LIBAVR_ROOT} - run: git submodule update --init libavr") endif() +# pureboot rides as a pinned submodule too: this board's only way in is its +# resident loader, so the commit that names this firmware names the loader it +# has to hand over to. Consumed for the geometry it exports - the loader links +# the libavr target above, so pureboot's own libavr submodule stays +# uninitialised. +if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/pureboot/CMakeLists.txt) + message(FATAL_ERROR "pureboot not found - run: git submodule update --init pureboot") +endif() add_subdirectory(${LIBAVR_ROOT} libavr-build) +add_subdirectory(pureboot pureboot-build) include(${LIBAVR_ROOT}/cmake/checks.cmake) add_executable(fantemp src/main.cpp) diff --git a/libavr b/libavr index e697920..3678ed7 160000 --- a/libavr +++ b/libavr @@ -1 +1 @@ -Subproject commit e69792013ec53f47defed956fdb93b2ba8c1cc64 +Subproject commit 3678ed7e5bb90f16021390fa3f877e9d1d2129db diff --git a/pureboot b/pureboot new file mode 160000 index 0000000..416ee18 --- /dev/null +++ b/pureboot @@ -0,0 +1 @@ +Subproject commit 416ee188e1724e9b871722d279be9b5eedd4b653 diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index aff37b5..10dceb6 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -25,7 +25,8 @@ if(Python3_FOUND) add_test(NAME fantemp.reachability COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/check_reachability.py --objdump ${CMAKE_OBJDUMP} --elf $ - --image $/fantemp.bin) + --image $/fantemp.bin + --loader-base ${PUREBOOT_BASE_HEX}) else() message(STATUS "Python not found - the reachability check is skipped") endif() diff --git a/test/check_reachability.py b/test/check_reachability.py index 44b57a4..7ec8b31 100644 --- a/test/check_reachability.py +++ b/test/check_reachability.py @@ -35,8 +35,7 @@ import re import subprocess import sys -BOOT_SECTION = 0x7C00 # hfuse d4: BOOTSZ 512 words -LOADER_BASE = 0x7E00 # pureboot's 512-byte slot, at the top +BOOT_SECTION = 0x7C00 # hfuse d4: BOOTSZ 512 words - a fuse fact, not a loader one WDTCSR = 0x60 @@ -45,7 +44,12 @@ def main() -> int: parser.add_argument("--objdump", required=True) parser.add_argument("--elf", type=pathlib.Path, required=True) parser.add_argument("--image", type=pathlib.Path, required=True) + # pureboot's own geometry, from the pinned submodule that exports it, so the + # slot's base is stated once for the loader this firmware is deployed with. + parser.add_argument("--loader-base", required=True, + type=lambda v: int(v, 0), metavar="ADDR") args = parser.parse_args() + loader_base = args.loader_base failures = [] @@ -81,17 +85,17 @@ def main() -> int: if "r24" in held and "r25" in held: sites.append(held["r25"] << 8 | held["r24"]) - want = LOADER_BASE // 2 + want = loader_base // 2 if not sites: failures.append("no call to bootloader::call with a loaded target - the " "hand-over could not be read out of the image") elif wrong := [a for a in sites if a != want]: failures.append(f"the hand-over targets word {[hex(a) for a in wrong]} " f"(byte {[hex(a * 2) for a in wrong]}), not the loader at " - f"0x{LOADER_BASE:04x}") + f"0x{loader_base:04x}") else: print(f" ok all {len(sites)} hand-over site(s) target word 0x{want:04x} " - f"(byte 0x{LOADER_BASE:04x})") + f"(byte 0x{loader_base:04x})") # An icall/ijmp has to exist for that address to be jumped to indirectly. if not re.search(r"\b(icall|ijmp)\b", text):