From 6d5a39893fc27b4a909ff0536405adecff5afc38 Mon Sep 17 00:00:00 2001 From: Patryk Kubiak Date: Wed, 14 Oct 2026 21:50:50 +0200 Subject: [PATCH] Fixes for ubuntu 24.04 --- .github/workflows/build.yml | 4 +++ configs/renode/renode.resc.in | 5 +++- docker/Dockerfile.env | 22 ++++++++++----- docker/README.md | 50 +++++++++++++++++++++++++++++++++++ scripts/run_renode_tests.sh | 23 ++++++++++++---- 5 files changed, 91 insertions(+), 13 deletions(-) create mode 100644 docker/README.md diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 069afa5..b714779 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -54,6 +54,7 @@ jobs: arm-none-eabi-objcopy --version arm-none-eabi-size --version cmake --version + file --version - name: Build dmod examples and create test DMP package run: | @@ -151,6 +152,9 @@ jobs: contents: read steps: + - name: Verify Renode installation + run: renode --version + - name: Checkout repository uses: actions/checkout@v4 with: diff --git a/configs/renode/renode.resc.in b/configs/renode/renode.resc.in index 959696a..6e543f7 100644 --- a/configs/renode/renode.resc.in +++ b/configs/renode/renode.resc.in @@ -16,4 +16,7 @@ machine StartGdbServer 3333 @DMBOOT_RENODE_NETWORK@ -@DMBOOT_RENODE_START@ \ No newline at end of file +@DMBOOT_RENODE_START@ + +# The test runner waits for complete setup before attaching its GDB monitor. +log "DMBOOT_RENODE_READY" diff --git a/docker/Dockerfile.env b/docker/Dockerfile.env index 3f40a04..288d2b8 100644 --- a/docker/Dockerfile.env +++ b/docker/Dockerfile.env @@ -2,21 +2,29 @@ FROM chocotechnologies/dmod:1.0.4 RUN apt-get update -qq && apt-get install -y \ wget \ - libncurses5 \ + file \ + libncurses6 \ policykit-1 \ - libgtk2.0-0 \ + libgtk2.0-0t64 \ screen \ uml-utilities \ libc6-dev \ gcc \ python3 \ - python3-pip + python3-pip \ + && rm -rf /var/lib/apt/lists/* -# Install Renode +# The .deb depends on GTK# 2 packages unavailable on Ubuntu 24.04. +# Use the portable distribution, which bundles its Mono runtime, instead. ENV RENODE_VERSION="1.15.3" -RUN wget -q https://github.com/renode/renode/releases/download/v${RENODE_VERSION}/renode_${RENODE_VERSION}_amd64.deb -RUN dpkg -i ./renode_${RENODE_VERSION}_amd64.deb || apt-get install -f -y -RUN rm ./renode_${RENODE_VERSION}_amd64.deb +ENV RENODE_DIR=/opt/renode +ENV PATH="${RENODE_DIR}:${PATH}" +RUN wget -q "https://github.com/renode/renode/releases/download/v${RENODE_VERSION}/renode-${RENODE_VERSION}.linux-portable.tar.gz" -O /tmp/renode.tar.gz \ + && mkdir -p "${RENODE_DIR}" \ + && tar -xzf /tmp/renode.tar.gz --strip-components=1 -C "${RENODE_DIR}" \ + && rm /tmp/renode.tar.gz \ + && renode --version \ + && file --version # Install dmffs RUN dmf-get make_dmffs --type dmf diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 0000000..aab64d7 --- /dev/null +++ b/docker/README.md @@ -0,0 +1,50 @@ +# Building the Ubuntu 24.04 images + +The image tags are intentionally reused: `dmod:1.0.4` and `dmboot:1.0.0`. +Build the images in dependency order so that dmboot uses the updated dmod base. + +From the **dmod** repository: + +```sh +docker build -t chocotechnologies/dmod-env:latest -f Docker/Dockerfile.env . +docker build -t chocotechnologies/dmod:1.0.4 -f Docker/Dockerfile . +``` + +From the **dmod-boot** repository: + +```sh +docker build -t chocotechnologies/dmboot-env:1.0.0 -f docker/Dockerfile.env . +docker build -t chocotechnologies/dmboot:1.0.0 \ + --build-arg ENV_IMAGE_VERSION=1.0.0 -f docker/Dockerfile . +``` + +Do not pull an older published base over the locally rebuilt image between +these steps. After publishing replacement images, consumers should pull the +same tags again to refresh their local copies. + +Renode 1.15.3 uses the portable distribution, which includes its Mono runtime. +Its Debian package depends on GTK# 2 packages unavailable in Ubuntu 24.04. +Do not use `dpkg -i ... || apt-get install -f`: apt can remove Renode to repair +dependencies and still return success. The image build checks that both +`renode` and the `file` command used by CI actually run. + +The emulation test waits for `DMBOOT_RENODE_READY` at the end of the generated +Renode script before connecting its GDB monitor. Portable Renode can take +longer than five seconds to initialize; a fixed startup sleep is insufficient. + +Check the resulting image: + +```sh +docker run --rm chocotechnologies/dmboot:1.0.0 sh -ec \ + 'cat /etc/os-release; renode --version; file --version; arm-none-eabi-gcc --version' +``` + +Run the full emulation suite, including the required TAP network test, from a +clean checkout with initialized submodules: + +```sh +docker run --rm --cap-add=NET_ADMIN --device=/dev/net/tun \ + -e DMBOOT_TEST_NETWORK=1 \ + -v "$PWD:/workspace" -w /workspace \ + chocotechnologies/dmboot:1.0.0 ./scripts/run_renode_tests.sh +``` diff --git a/scripts/run_renode_tests.sh b/scripts/run_renode_tests.sh index 2224a2b..ddefd6c 100755 --- a/scripts/run_renode_tests.sh +++ b/scripts/run_renode_tests.sh @@ -48,6 +48,7 @@ NETWORK_TEST_SCRIPT="$SOURCE_DIR/scripts/test_renode_network.py" TAP_INTERFACE=tap0 # Timeouts (seconds) +RENODE_READY_TIMEOUT=60 # Upper bound only: step 4 stops as soon as the monitor reads the ring header MONITOR_READY_TIMEOUT=60 UART_TIMEOUT=90 @@ -57,7 +58,7 @@ TOUCH_TIMEOUT=120 NETWORK_TIMEOUT=120 # Renode has to outlive the monitor and the UART, SD card, LCD, touch and network tests TESTS_TIMEOUT=$((UART_TIMEOUT + SDCARD_TIMEOUT + LCD_TIMEOUT + TOUCH_TIMEOUT + NETWORK_TIMEOUT)) -CONNECT_TIMEOUT=$((MONITOR_READY_TIMEOUT + TESTS_TIMEOUT + 60)) +CONNECT_TIMEOUT=$((RENODE_READY_TIMEOUT + MONITOR_READY_TIMEOUT + TESTS_TIMEOUT + 60)) # The network test needs a TAP interface: root and /dev/net/tun NETWORK_TEST=0 @@ -126,14 +127,26 @@ echo "[3/9] Starting Renode emulation..." CONNECT_LOG="$BUILD_DIR/connect.log" # No frame of an earlier run may pass for one of this run rm -f "$LCD_FRAME_FILE" +# Clear a previous run's readiness marker before the background process starts. +: > "$CONNECT_LOG" timeout "$CONNECT_TIMEOUT" cmake --build "$BUILD_DIR" --target connect > "$CONNECT_LOG" 2>&1 & CONNECT_PID=$! -echo "Waiting for Renode GDB server to start (PID $CONNECT_PID)..." -sleep 5 +echo "Waiting for Renode setup to finish (PID $CONNECT_PID)..." +# The generated script emits this after the GDB server and all peripherals +# are configured. Do not probe GDB by connecting: disconnecting a probe can +# resume the guest before the monitor attaches. +RENODE_READY_PATTERN="DMBOOT_RENODE_READY" +RENODE_DEADLINE=$((SECONDS + RENODE_READY_TIMEOUT)) +while [ "$SECONDS" -lt "$RENODE_DEADLINE" ] && kill -0 "$CONNECT_PID" 2>/dev/null; do + if grep -Fq "$RENODE_READY_PATTERN" "$CONNECT_LOG"; then + break + fi + sleep 1 +done -if ! ps -p "$CONNECT_PID" > /dev/null 2>&1; then - echo "✗ Renode failed to start" +if ! kill -0 "$CONNECT_PID" 2>/dev/null || ! grep -Fq "$RENODE_READY_PATTERN" "$CONNECT_LOG"; then + echo "✗ Renode failed to become ready within ${RENODE_READY_TIMEOUT}s" echo "--- connect.log ---" cat "$CONNECT_LOG" exit 1