Skip to content

Commit 3c96527

Browse files
JamesReynoldsJames ReynoldsJames Reynoldslukechilds
committed
Add experimental support for Pi 2/3 emulation (#4)
1. Added 'fatcat' to extract from the boot filesystem from a standard RPI image 2. Added qemu-system-aarch64 to support raspi3 machines 3. Extracted images to search for kernel7/8.img and correct dtb files to boot kernel 4. Disabled nic for raspi2/3 as USB is not supported (yet) Co-authored-by: James Reynolds <james.reynolds@cristiesoftware.com> Co-authored-by: James Reynolds <james.reynolds@cristie.com> Co-authored-by: Luke Childs <lukechilds123@gmail.com>
1 parent 4bb1b91 commit 3c96527

File tree

3 files changed

+107
-14
lines changed

3 files changed

+107
-14
lines changed

Dockerfile

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Build stage for qemu-system-arm
2-
FROM debian:stable-slim AS qemu-system-arm-builder
2+
FROM debian:stable-slim AS qemu-builder
33
ARG QEMU_VERSION=4.2.0
44
ENV QEMU_TARBALL="qemu-${QEMU_VERSION}.tar.xz"
55
WORKDIR /qemu
@@ -28,11 +28,35 @@ RUN apt-get -y install python build-essential libglib2.0-dev libpixman-1-dev
2828
RUN apt-get -y install libfdt-dev zlib1g-dev
2929
# Not required or specified anywhere but supress build warnings
3030
RUN apt-get -y install flex bison
31-
RUN "qemu-${QEMU_VERSION}/configure" --static --target-list=arm-softmmu
31+
RUN "qemu-${QEMU_VERSION}/configure" --static --target-list=arm-softmmu,aarch64-softmmu
3232
RUN make -j$(nproc)
3333

3434
RUN # Strip the binary, this gives a substantial size reduction!
35-
RUN strip "arm-softmmu/qemu-system-arm"
35+
RUN strip "arm-softmmu/qemu-system-arm" "aarch64-softmmu/qemu-system-aarch64"
36+
37+
38+
# Build stage for fatcat
39+
FROM debian:stable-slim AS fatcat-builder
40+
ARG FATCAT_VERSION=v1.1.0
41+
ARG FATCAT_CHECKSUM="303efe2aa73cbfe6fbc5d8af346d0f2c70b3f996fc891e8859213a58b95ad88c"
42+
ENV FATCAT_TARBALL="${FATCAT_VERSION}.tar.gz"
43+
WORKDIR /fatcat
44+
45+
RUN # Update package lists
46+
RUN apt-get update
47+
48+
RUN # Pull source
49+
RUN apt-get -y install wget
50+
RUN wget "https://github.com/Gregwar/fatcat/archive/${FATCAT_TARBALL}"
51+
RUN echo "${FATCAT_CHECKSUM} ${FATCAT_TARBALL}" | sha256sum --check
52+
53+
RUN # Extract source tarball
54+
RUN tar xvf "${FATCAT_TARBALL}"
55+
56+
RUN # Build source
57+
RUN apt-get -y install build-essential cmake
58+
RUN cmake fatcat-* -DCMAKE_CXX_FLAGS='-static'
59+
RUN make -j$(nproc)
3660

3761

3862
# Build the dockerpi VM image
@@ -41,7 +65,9 @@ LABEL maintainer="Luke Childs <lukechilds123@gmail.com>"
4165
ARG RPI_KERNEL_URL="https://github.com/dhruvvyas90/qemu-rpi-kernel/archive/afe411f2c9b04730bcc6b2168cdc9adca224227c.zip"
4266
ARG RPI_KERNEL_CHECKSUM="295a22f1cd49ab51b9e7192103ee7c917624b063cc5ca2e11434164638aad5f4"
4367

44-
COPY --from=qemu-system-arm-builder /qemu/arm-softmmu/qemu-system-arm /usr/local/bin/qemu-system-arm
68+
COPY --from=qemu-builder /qemu/arm-softmmu/qemu-system-arm /usr/local/bin/qemu-system-arm
69+
COPY --from=qemu-builder /qemu/aarch64-softmmu/qemu-system-aarch64 /usr/local/bin/qemu-system-aarch64
70+
COPY --from=fatcat-builder /fatcat/fatcat /usr/local/bin/fatcat
4571

4672
ADD $RPI_KERNEL_URL /tmp/qemu-rpi-kernel.zip
4773

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,21 @@ If you only want to mount your own image, you can download a much slimmer VM onl
4848
docker run -it -v /2019-09-26-raspbian-buster-lite.img:/sdcard/filesystem.img lukechilds/dockerpi:vm
4949
```
5050

51+
## Which machines are supported?
52+
53+
By default a Raspberry Pi 1 is virtualised, however experimental support has been added for Pi 2 and Pi 3 machines.
54+
55+
You can specify a machine by passing the name as a CLI argument:
56+
57+
```
58+
docker run -it lukechilds/dockerpi pi1
59+
docker run -it lukechilds/dockerpi pi2
60+
docker run -it lukechilds/dockerpi pi3
61+
```
62+
63+
> **Note:** Pi 2 and Pi 3 support is currently experimental. Networking doesn't work and QEMU hangs once the machines are powered down requiring you to `docker kill` the container. More information here: https://github.com/lukechilds/dockerpi/pull/4.
64+
65+
5166
## Wait, what?
5267

5368
A full ARM environment is created by using Docker to bootstrap a QEMU virtual machine. The Docker QEMU process virtualises a machine with a single core ARM11 CPU and 256MB RAM, just like the Raspberry Pi. The official Raspbian image is mounted and booted along with a modified QEMU compatible kernel.

entrypoint.sh

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/bin/sh
22

3+
target="${1:-pi1}"
34
image_path="/sdcard/filesystem.img"
45
zip_path="/filesystem.zip"
56

@@ -8,22 +9,73 @@ if [ ! -e $image_path ]; then
89
if [ -e $zip_path ]; then
910
echo "Extracting fresh filesystem..."
1011
unzip $zip_path
11-
mv *.img $image_path
12+
mv -- *.img $image_path
1213
else
1314
exit 1
1415
fi
1516
fi
1617

17-
exec qemu-system-arm \
18-
--machine versatilepb \
18+
fat_path="/fat.img"
19+
if [ "${target}" != "pi1" ]; then
20+
echo "Extracting partitions"
21+
fdisk -l ${image_path} \
22+
| awk "/^[^ ]*1/{print \"dd if=${image_path} of=${fat_path} bs=512 skip=\"\$4\" count=\"\$6}" \
23+
| sh
24+
fi
25+
if [ "${target}" = "pi2" ]; then
26+
emulator=qemu-system-arm
27+
machine=raspi2
28+
memory=1024m
29+
kernel_pattern=kernel7.img
30+
dtb_pattern=bcm2709-rpi-2-b.dtb
31+
nic=''
32+
elif [ "${target}" = "pi3" ]; then
33+
emulator=qemu-system-aarch64
34+
machine=raspi3
35+
memory=1024m
36+
kernel_pattern=kernel8.img
37+
dtb_pattern=bcm2710-rpi-3-b-plus.dtb
38+
nic=''
39+
elif [ "${target}" = "pi1" ]; then
40+
emulator=qemu-system-arm
41+
kernel="/root/qemu-rpi-kernel/kernel-qemu-4.19.50-buster"
42+
dtb="/root/qemu-rpi-kernel/versatile-pb.dtb"
43+
machine=versatilepb
44+
memory=256m
45+
root=/dev/sda2
46+
nic='--net nic --net user,hostfwd=tcp::5022-:22'
47+
else
48+
echo "Target ${target} not supported"
49+
echo "Supported targets: pi1 pi2 pi3"
50+
exit 2
51+
fi
52+
53+
if [ -f "${fat_path}" ]; then
54+
echo "Extracting boot filesystem"
55+
fat_folder="/fat"
56+
mkdir -p "${fat_folder}"
57+
fatcat -x "${fat_folder}" "${fat_path}"
58+
echo "Searching for kernel='${kernel_pattern}'"
59+
kernel=$(find "${fat_folder}" -name "${kernel_pattern}")
60+
echo "Searching for dtb='${dtb_pattern}'"
61+
dtb=$(find "${fat_folder}" -name "${dtb_pattern}")
62+
root=/dev/mmcblk0p2
63+
fi
64+
if [ "${kernel}" = "" ] || [ "${dtb}" = "" ]; then
65+
echo "Missing kernel='${kernel}' or dtb='${dtb}'"
66+
exit 2
67+
fi
68+
69+
echo "Booting QEMU machine \"${machine}\" with kernel=${kernel} dtb=${dtb}"
70+
exec ${emulator} \
71+
--machine "${machine}" \
1972
--cpu arm1176 \
20-
--m 256M \
21-
--hda /sdcard/filesystem.img \
22-
--net nic \
23-
--net user,hostfwd=tcp::5022-:22 \
24-
--dtb /root/qemu-rpi-kernel/versatile-pb.dtb \
25-
--kernel /root/qemu-rpi-kernel/kernel-qemu-4.19.50-buster \
26-
--append "root=/dev/sda2 panic=1" \
73+
--m "${memory}" \
74+
--hda "${image_path}" \
75+
${nic} \
76+
--dtb "${dtb}" \
77+
--kernel "${kernel}" \
78+
--append "rw earlyprintk loglevel=8 console=ttyAMA0,115200 dwc_otg.lpm_enable=0 root=${root} rootwait panic=1" \
2779
--no-reboot \
2880
--display none \
2981
--serial mon:stdio

0 commit comments

Comments
 (0)