Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support to use qemu-system to run linux aarch64 binaries #153

Merged
merged 9 commits into from
Oct 15, 2018
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ sudo: required
matrix:
include:
# Linux
- env: TARGET=aarch64-unknown-linux-gnu CPP=1 DYLIB=1 STD=1 OPENSSL=0.5.5 RUN=1
- env: TARGET=aarch64-unknown-linux-gnu CPP=1 DYLIB=1 STD=1 OPENSSL=0.5.5 RUN=1 RUNNERS="qemu-user qemu-system" CROSS_DEBUG=1
- env: TARGET=arm-unknown-linux-gnueabi CPP=1 DYLIB=1 STD=1 OPENSSL=0.5.5 RUN=1
- env: TARGET=armv7-unknown-linux-gnueabihf CPP=1 DYLIB=1 STD=1 OPENSSL=0.5.5 RUN=1
- env: TARGET=i586-unknown-linux-gnu CPP=1 DYLIB=1 STD=1 OPENSSL=0.5.5 RUN=1
Expand Down
34 changes: 28 additions & 6 deletions ci/script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ EOF
$td

pushd $td
cross test --manifest-path testcrate/Cargo.toml --target $TARGET
cross_test --manifest-path testcrate/Cargo.toml --target $TARGET
popd

rm -rf $td
Expand All @@ -113,7 +113,7 @@ EOF
https://github.com/japaric/cortest $td

pushd $td
cross run --target $TARGET --example hello --release
cross_run --target $TARGET --example hello --release
popd

rm -rf $td
Expand All @@ -127,9 +127,9 @@ EOF
mkdir examples tests
echo "fn main() { println!(\"Example!\"); }" > examples/e.rs
echo "#[test] fn t() {}" > tests/t.rs
cross run --target $TARGET
cross run --target $TARGET --example e
cross test --target $TARGET
cross_run --target $TARGET
cross_run --target $TARGET --example e
cross_test --target $TARGET
popd

rm -rf $td
Expand All @@ -147,7 +147,7 @@ EOF
pushd $td
cargo update -p gcc
if [ $RUN ]; then
cross run --target $TARGET
cross_run --target $TARGET
else
cross build --target $TARGET
fi
Expand Down Expand Up @@ -180,4 +180,26 @@ EOF
fi
}

cross_run() {
if [ -z "$RUNNERS" ]; then
cross run "$@"
else
for runner in $RUNNERS; do
echo -e "[target.$TARGET]\nrunner = \"$runner\"" > Cross.toml
cross run "$@"
done
fi
}

cross_test() {
if [ -z "$RUNNERS" ]; then
cross test "$@"
else
for runner in $RUNNERS; do
echo -e "[target.$TARGET]\nrunner = \"$runner\"" > Cross.toml
cross test "$@"
done
fi
}

main
21 changes: 16 additions & 5 deletions docker/aarch64-unknown-linux-gnu/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,26 @@ COPY cmake.sh /
RUN apt-get purge --auto-remove -y cmake && \
bash /cmake.sh 3.5.1

COPY openssl.sh qemu.sh /
RUN apt-get install -y --no-install-recommends \
g++-aarch64-linux-gnu \
libc6-dev-arm64-cross && \
bash /openssl.sh linux-aarch64 aarch64-linux-gnu- && \
bash /qemu.sh aarch64
libc6-dev-arm64-cross

COPY openssl.sh /
RUN bash /openssl.sh linux-aarch64 aarch64-linux-gnu-

COPY qemu.sh /
RUN bash /qemu.sh aarch64 linux softmmu

COPY dropbear.sh /
RUN bash /dropbear.sh

COPY linux-image.sh /
RUN bash /linux-image.sh aarch64

COPY linux-runner /

ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc \
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUNNER=qemu-aarch64 \
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUNNER="/linux-runner aarch64" \
CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc \
CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++ \
OPENSSL_DIR=/openssl \
Expand Down
57 changes: 57 additions & 0 deletions docker/dropbear.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
set -ex

main() {
local version=2017.75 \
td=$(mktemp -d)

local dependencies=(
autoconf
automake
bzip2
curl
make
zlib1g-dev
)

apt-get update
local purge_list=()
for dep in ${dependencies[@]}; do
if ! dpkg -L $dep; then
apt-get install --no-install-recommends -y $dep
purge_list+=( $dep )
fi
done

pushd $td

curl -L https://matt.ucc.asn.au/dropbear/dropbear-$version.tar.bz2 | \
tar --strip-components=1 -xj

# Remove some unwanted message
sed -i '/skipping hostkey/d' cli-kex.c
sed -i '/failed to identify current user/d' cli-runopts.c

./configure \
--disable-syslog \
--disable-shadow \
--disable-lastlog \
--disable-utmp \
--disable-utmpx \
--disable-wtmp \
--disable-wtmpx \
--disable-pututline \
--disable-pututxline

nice make -j$(nproc) PROGRAMS=dbclient
cp dbclient /usr/local/bin/

# Clean up
apt-get purge --auto-remove -y ${purge_list[@]}

popd

rm -rf $td
rm $0
}

main "${@}"
179 changes: 179 additions & 0 deletions docker/linux-image.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
set -ex

main() {
# arch in the rust target
local arch=$1 \
kversion=4.9.0-8

# select debian arch and kernel version
case $arch in
aarch64)
arch=arm64
kernel=$kversion-arm64
;;
*)
echo "Invalid arch: $arch"
exit 1
;;
esac

local dependencies=(
cpio
sharutils
)

local purge_list=()
apt-get update
for dep in ${dependencies[@]}; do
if ! dpkg -L $dep; then
apt-get install --no-install-recommends -y $dep
purge_list+=( $dep )
fi
done

# Download packages
mv /etc/apt/sources.list /etc/apt/sources.list.bak
echo "deb http://http.debian.net/debian/ stretch main" > \
/etc/apt/sources.list
echo "deb http://security.debian.org/ stretch/updates main" >> \
/etc/apt/sources.list

# Old ubuntu does not support --add-architecture, so we directly change multiarch file
if [ -f /etc/dpkg/dpkg.cfg.d/multiarch ]; then
cp /etc/dpkg/dpkg.cfg.d/multiarch /etc/dpkg/dpkg.cfg.d/multiarch.bak
fi
dpkg --add-architecture $arch || echo "foreign-architecture $arch" > /etc/dpkg/dpkg.cfg.d/multiarch
# Add debian keys
apt-key adv --recv-key --keyserver keyserver.ubuntu.com EF0F382A1A7B6500
apt-key adv --recv-key --keyserver keyserver.ubuntu.com 9D6D8F6BC857C906
apt-key adv --recv-key --keyserver keyserver.ubuntu.com 8B48AD6246925553
apt-key adv --recv-key --keyserver keyserver.ubuntu.com 7638D0442B90D010
apt-get update

mkdir -p -m 777 /qemu/$arch
cd /qemu/$arch
apt-get -t stretch -d --no-install-recommends download \
busybox:$arch \
dropbear-bin:$arch \
libc6:$arch \
libgcc1:$arch \
libssl1*:$arch \
libstdc++6:$arch \
linux-image-$kernel:$arch \
ncurses-base \
zlib1g:$arch
cd /qemu

# Install packages
root=root-$arch
mkdir -p $root/{bin,etc/dropbear,root,sys,dev,proc,sbin,usr/{bin,sbin},var/log}
for deb in $arch/*deb; do
dpkg -x $deb $root/
done

# kernel
cp $root/boot/vmlinu* kernel

# initrd
mkdir -p $root/modules
cp \
$root/lib/modules/*/kernel/drivers/net/virtio_net.ko \
$root/lib/modules/*/kernel/drivers/virtio/* \
$root/lib/modules/*/kernel/fs/9p/9p.ko \
$root/lib/modules/*/kernel/fs/fscache/fscache.ko \
$root/lib/modules/*/kernel/net/9p/9pnet.ko \
$root/lib/modules/*/kernel/net/9p/9pnet_virtio.ko \
$root/modules || true # some file may not exist
rm -rf $root/boot
rm -rf $root/lib/modules

cat << 'EOF' > $root/etc/hosts
127.0.0.1 localhost qemu
EOF

cat << 'EOF' > $root/etc/hostname
qemu
EOF

cat << 'EOF' > $root/etc/passwd
root::0:0:root:/root:/bin/sh
EOF

cat << 'EOF' | uudecode -o $root/etc/dropbear/dropbear_rsa_host_key
begin 600 dropbear_rsa_host_key
M````!W-S:"UR<V$````#`0`!```!`0"N!-<%K,3Z.!Z,OEMB2.N\O.$IWQ*F
M#5%(_;(^2YKY_J_.RQW/7U@_MK&J#!Z0_\;EH#98ZW*E1\.<FF%P/*Y.W56-
M31.'EJE`TN@=T5EC(8"Y%3'ZBYH)^WIVJ]S*G/_;#RH\_?S"U^1L_<<.F`O+
MZVI?*]\KTDOT&QV0#B-M;"%_7:\>+3[X=QMH,B<HM$+0E[\B6*^!XKLR@V,K
M)<V80HHK:_#;D]26XKN&CB./EZAC%4)78R!G""4HT@UK<5I4B^$/""`,?*\T
M>*4$RYULV,V3X6]K:7@Q?80"#WXGGQZNFN6CZ7LTDX(F6J[\]F5<0`HEOF:Z
MX;^53`L'4I/A```!``$L:$Z*#6<^3@+O%.[-#/5H+.C'3\#QQZN[1;J>L`8I
MZ_&T'!"J'/Y+?R?55G:M^=]R*-&I3TOJYZA8@&H51ZOAF59'1_>>Z@?E4#)$
MQU)X/RWH51ZB5KSDWJS:D'7GD(!?NAY`C'7\)I:_4)J")QBV/P"RJQGHG'%B
M1BT2LE6676>`1K,0\NIMZTKQNB(IC+88<7#8%_-=P<&6<"9LH>60TSS?3?-C
MN`T36YB/3^<(Q;`N1NT>I9EZS`BAC^-?.:,R\7EL"<4>7E=]^1]B\K9])AQU
MBM\]M;4V(S(6KH-I.4[6>9E+@\UEM.J6:[2LUEEJDG:G:+:/EVF^Y75@(S$`
M``"!`.O+KW=&*CBCHL"11&SVO4/K]$R-]7MV7,3RR)Q[X'0;6.?4JHW!3VR6
M*FGBY--37ZD-+UV.8_+"$<?B"#&K$.[V)F7V2\UY!7(0FZ@A2`0ADDY*J-_B
M4AU&.*GP#F/!I([:?E],.>6PH9)(/E.\G19#G0K`LRM?JWS!58&;D0C1````
M@0"\[@NYWSTW(?Q@:_A*1Y3/AKYO5?S=0"<2>#V-AH6W-NCSDTSRP=2D79FS
M"D?[;.)V>8'#9&I3"MU@+:2\Z%$0-MG0+J'(0>T1_C6?*C=4U0I$DI<=@D]1
H_&DE8Y(OT%%EPG]!$H&5HX*),_D1A2\P=R.7G'`0L%YM-79Y"T">$0``
`
end
EOF

# dropbear complains when this file is missing
touch $root/var/log/lastlog

cat << 'EOF' > $root/init
#!/bin/busybox sh

set -e

/bin/busybox --install

mount -t devtmpfs devtmpfs /dev
mount -t proc none /proc
mount -t sysfs none /sys
mkdir /dev/pts
mount -t devpts none /dev/pts/

# some archs does not have virtio modules
insmod /modules/virtio.ko || true
insmod /modules/virtio_ring.ko || true
insmod /modules/virtio_mmio.ko || true
insmod /modules/virtio_pci.ko || true
insmod /modules/virtio_net.ko || true
insmod /modules/fscache.ko
insmod /modules/9pnet.ko
insmod /modules/9pnet_virtio.ko || true
insmod /modules/9p.ko

ifconfig lo 127.0.0.1
ifconfig eth0 10.0.2.15
route add default gw 10.0.2.2 eth0

mkdir /target
mount -t 9p -o trans=virtio target /target -oversion=9p2000.L || true

exec dropbear -F -E -B
EOF

chmod +x $root/init
cd $root && find . | cpio --create --format='newc' --quiet | gzip > ../initrd.gz

# Clean up
rm -rf /qemu/$root /qemu/$arch
mv -f /etc/apt/sources.list.bak /etc/apt/sources.list
if [ -f /etc/dpkg/dpkg.cfg.d/multiarch.bak ]; then
mv /etc/dpkg/dpkg.cfg.d/multiarch.bak /etc/dpkg/dpkg.cfg.d/multiarch
fi
# can fail if arch is used (amd64 and/or i386)
dpkg --remove-architecture $arch || true
apt-get update
apt-get purge --auto-remove -y ${purge_list[@]}
ls -lh /qemu
}

main "${@}"
Loading