Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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: |
Expand Down Expand Up @@ -151,6 +152,9 @@ jobs:
contents: read

steps:
- name: Verify Renode installation
run: renode --version

- name: Checkout repository
uses: actions/checkout@v4
with:
Expand Down
5 changes: 4 additions & 1 deletion configs/renode/renode.resc.in
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,7 @@ machine StartGdbServer 3333

@DMBOOT_RENODE_NETWORK@

@DMBOOT_RENODE_START@
@DMBOOT_RENODE_START@

# The test runner waits for complete setup before attaching its GDB monitor.
log "DMBOOT_RENODE_READY"
22 changes: 15 additions & 7 deletions docker/Dockerfile.env
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
50 changes: 50 additions & 0 deletions docker/README.md
Original file line number Diff line number Diff line change
@@ -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
```
23 changes: 18 additions & 5 deletions scripts/run_renode_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
Loading