booting linux-libre

This commit is contained in:
Andreas Grapentin 2018-02-01 10:54:30 +01:00
parent 0f257f4480
commit 3c719ced1c
No known key found for this signature in database
GPG Key ID: 7171986E4B745536
6 changed files with 164 additions and 128 deletions

37
README

@ -3,14 +3,19 @@ parabola-arm-imagebuilder
=========================
this is a collection of scripts creating parabola arm images for use with qemu
with the goal of building parabola arm packages on these machines.
with the original goal of building parabola arm packages on these machines.
Development focus has since shifted towards creating parabola-arm release
tarballs.
to create a new virtual machine, run
$> sudo ./create.sh
the creation script makes use of several files and packages present on already
setup parabola development machines. if your setup is different, you might
have to modify the scripts accordingly.
optionally, to create a new virtual machine with a packaging environment, run:
$> DEVSETUP=1 sudo ./create.sh
the packaging environment setup script makes use of several files and packages
present on already setup parabola development machines. if your setup is
different, you might have to modify src/stage3.sh accordingly.
Places the scripts check the host machine for configuration files are:
/etc/makepkg.conf - for PACKAGER and GPGKEY
@ -20,7 +25,7 @@ The scripts assume that the following programs are available and in $PATH:
qemu-img, qemu-system-arm
wget
parted
mkfs.vfat, mkfs.ext4
mkfs.vfat, mkfs.ext4, mkswap
bsdtar
scp, ssh, ssh-keygen
pacman
@ -30,7 +35,21 @@ The scripts also assume that you like vim :)
to open a shell into the created machine, run
$> ./start.sh [path to created image]
you are logged in as user parabola with password parabola. passwordless sudo is
setup and the package tree and a build chroot are prepared. have fun. also
check out the .bashrc of the parabola user in the created virtual machine, for
batch build integration based on task-spooler.
the start.sh script assumes that you want a throwaway session, so it will start
the virtual machine in snapshot mode and drop you into an ssh session. Once you
exit that session, the machine is shutdown and changes made to the image are
discarded. This behavior can be changed using the following environment
variables:
FOREGROUND : set this to 1 to start a qemu serial connection instead of a ssh
session. Useful to capture boot output.
PERSISTENT : set this to 1 to make persistent changes to the image that are
not discarded on shutdown.
The username and password for the created image is parabola:parabola, or
root:parabola respectively. If a packaging environment is setup, the system is
configured for passwordless sudo for the parabola user and the package tree and
a build chroot are prepared. have fun. also check out the .bashrc of the
parabola user in the created virtual machine, for batch build integration based
on task-spooler.

@ -27,15 +27,15 @@ die() { echo "$*" 1>&2 ; exit 1; }
[ $(id -u) -ne 0 ] && die "must be root"
[ -z "${SUDO_USER:-}" ] && die "SUDO_USER not set"
export OUTFILE=${OUTFILE:-armv7h.img}
export SIZE=${SIZE:-64G}
export ARCHTARBALL=${ARCHTARBALL:-ArchLinuxARM-armv7-latest.tar.gz}
export OUTFILE="${OUTFILE:-armv7h.img}"
export SIZE="${SIZE:-64G}"
export ARCHTARBALL="${ARCHTARBALL:-ArchLinuxARM-armv7-latest.tar.gz}"
export _builddir=build
mkdir -p $_builddir
chown $SUDO_USER $_builddir
mkdir -p "$_builddir"
chown $SUDO_USER "$_builddir"
export _outfile=$_builddir/$(basename $OUTFILE)
export _outfile="$_builddir/$(basename "$OUTFILE")"
# prepare the empty image
./src/stage0.sh
@ -48,11 +48,11 @@ export _outfile=$_builddir/$(basename $OUTFILE)
./src/stage2.sh
# setup package development environment
./src/stage3.sh
[ -n "${DEVSETUP:-}" ] && ./src/stage3.sh
# cleanup
chown $SUDO_USER $_outfile
mv -v $_outfile $OUTFILE
rm -rf $_builddir
mv -v "$_outfile" "$OUTFILE"
rm -rf "$_builddir"
echo "all done :)"

@ -20,8 +20,10 @@
set -eu
# setup an available loop device
_loopdev=$(losetup -f --show $_outfile)
_bootdir="$_builddir/boot"
_rootdir="$_builddir/root"
_loopdev=$(losetup -f --show "$_outfile")
# setup an error exit handler for cleanup
function cleanup {
@ -30,8 +32,8 @@ function cleanup {
umount $_loopdev$part || true
done
losetup -d $_loopdev || true
rm -rf $_builddir/boot $_builddir/root
rm -f $_outfile
rm -rf "$_bootdir" "$_rootdir"
rm -f "$_outfile"
}
trap cleanup ERR
@ -56,16 +58,16 @@ mkswap ${_loopdev}p2
mkfs.ext4 ${_loopdev}p3
# install the base image
mkdir -p $_builddir/boot
mkdir $_builddir/root
mount ${_loopdev}p1 $_builddir/boot
mount ${_loopdev}p3 $_builddir/root
bsdtar -vxpf $ARCHTARBALL -C $_builddir/root
mkdir -p "$_bootdir"
mkdir -p "$_rootdir"
mount ${_loopdev}p1 "$_bootdir"
mount ${_loopdev}p3 "$_rootdir"
bsdtar -vxpf $ARCHTARBALL -C "$_rootdir"
sync
# fill the boot partition and create fstab
mv -v $_builddir/root/boot/* $_builddir/boot
cat >> $_builddir/root/etc/fstab << EOF
mv -v "$_rootdir"/boot/* "$_bootdir"
cat >> "$_rootdir"/etc/fstab << EOF
/dev/mmcblk0p1 /boot vfat defaults 0 0
/dev/mmcblk0p2 none swap defaults 0 0
EOF
@ -74,16 +76,16 @@ EOF
mkdir -p keys
test -f keys/id_rsa || ssh-keygen -N '' -f keys/id_rsa
chown $SUDO_USER keys/id_rsa*
mkdir -m 700 $_builddir/root/root/.ssh
install -m 600 -o 0 -g 0 keys/id_rsa.pub $_builddir/root/root/.ssh/authorized_keys
mkdir -m 700 "$_rootdir"/root/.ssh
install -m 600 -o 0 -g 0 keys/id_rsa.pub "$_rootdir"/root/.ssh/authorized_keys
# create and install ssh host keys
for cipher in dsa ecdsa ed25519 rsa; do
if [ ! -f keys/ssh_host_${cipher}_key ]; then
ssh-keygen -N '' -t ${cipher} -f keys/ssh_host_${cipher}_key
fi
install -m 600 -o 0 -g 0 keys/ssh_host_${cipher}_key $_builddir/root/etc/ssh
install -m 644 -o 0 -g 0 keys/ssh_host_${cipher}_key.pub $_builddir/root/etc/ssh
install -m 600 -o 0 -g 0 keys/ssh_host_${cipher}_key "$_rootdir"/etc/ssh
install -m 644 -o 0 -g 0 keys/ssh_host_${cipher}_key.pub "$_rootdir"/etc/ssh
done
# tie up any loose ends
@ -91,4 +93,4 @@ for part in p1 p3; do
umount $_loopdev$part
done
losetup -d $_loopdev
rm -rf $_builddir/boot $_builddir/root
rm -rf "$_bootdir" "$_rootdir"

@ -20,26 +20,26 @@
set -eu
_scriptfile=$_builddir/migrate.sh
_pidfile=$_builddir/qemu.pid
_scriptfile="$_builddir"/migrate.sh
_pidfile="$_builddir"/qemu-$$.pid
_bootdir="$_builddir"/boot-$$
_loopdev=$(sudo losetup -f --show $_outfile)
_bootdir=.boot
# register cleanup handler to stop the started VM
function cleanup {
test -f $_pidfile && (kill -9 $(cat $_pidfile) || true)
rm -f $_pidfile
test -f "$_pidfile" && (kill -9 $(cat "$_pidfile") || true)
rm -f "$_pidfile"
umount ${_loopdev}p1
losetup -d $_loopdev
rm -rf $_bootdir
rm -f $_scriptfile
rm -rf "$_bootdir"
rm -f "$_scriptfile"
}
trap cleanup ERR
# create the migration script, adapted from
# https://wiki.parabola.nu/Migration_from_Arch_ARM
cat > $_scriptfile << 'EOF'
cat > "$_scriptfile" << 'EOF'
#!/bin/bash
set -eu
@ -80,32 +80,39 @@ pacman --noconfirm -S pacman
mv /etc/pacman.conf{.pacnew,}
pacman --noconfirm -Syuu
pacman --noconfirm -S your-freedom
# FIXME: we should install the linux-libre kernel, but it won't boot in qemu yet
# yes | pacman -S linux-libre
yes | pacman -S linux-libre
# cleanup users
userdel -r alarm
useradd -mU parabola
echo 'parabola:parabola' | chpasswd
echo 'root:parabola' | chpasswd
# cleanup hostname
echo "parabola-arm" > /etc/hostname
# enable UTF-8 locale
sed -i 's/#en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen
locale-gen
sed -i 's/LANG.*/LANG=en_US.UTF-8/' /etc/locale.conf
EOF
chmod +x $_scriptfile
chmod +x "$_scriptfile"
# start the VM
mkdir -p $_bootdir
mkdir -p "$_bootdir"
mount ${_loopdev}p1 $_bootdir
QEMU_AUDIO_DRV=none qemu-system-arm \
-M vexpress-a9 \
-m 1G \
-dtb $_bootdir/dtbs/vexpress-v2p-ca9.dtb \
-kernel $_bootdir/zImage \
-dtb "$_bootdir"/dtbs/vexpress-v2p-ca9.dtb \
-kernel "$_bootdir"/zImage \
--append "root=/dev/mmcblk0p3 rw roottype=ext4 console=ttyAMA0" \
-drive if=sd,driver=raw,cache=writeback,file=$_outfile \
-drive if=sd,driver=raw,cache=writeback,file="$_outfile" \
-display none \
-net user,hostfwd=tcp::2022-:22 \
-net nic \
-daemonize \
-pidfile $_pidfile
-pidfile "$_pidfile"
# wait for ssh to be up
while ! ssh -p 2022 -i keys/id_rsa root@localhost -o StrictHostKeyChecking=no true 2>/dev/null; do
@ -113,16 +120,14 @@ while ! ssh -p 2022 -i keys/id_rsa root@localhost -o StrictHostKeyChecking=no tr
done && echo
# copy and execute the migration script
scp -P 2022 -i keys/id_rsa $_scriptfile root@localhost:
ssh -p 2022 -i keys/id_rsa root@localhost "./$(basename $_scriptfile)"
scp -P 2022 -i keys/id_rsa "$_scriptfile" root@localhost:
ssh -p 2022 -i keys/id_rsa root@localhost "./$(basename "$_scriptfile")"
# stop the VM
ssh -p 2022 -i keys/id_rsa root@localhost "nohup shutdown -h now &>/dev/null & exit"
while kill -0 $(cat $_pidfile) 2> /dev/null; do echo -n . && sleep 5; done && echo
rm -f $_pidfile
while kill -0 $(cat "$_pidfile") 2> /dev/null; do echo -n . && sleep 5; done && echo
# cleanup
umount ${_loopdev}p1
losetup -d $_loopdev
rm -rf $_bootdir
rm $_scriptfile
rm -rf "$_bootdir" "$_scriptfile" "$_pidfile"

@ -20,26 +20,26 @@
set -eu
_scriptfile=$_builddir/migrate.sh
_pidfile=$_builddir/qemu.pid
_scriptfile="$_builddir"/migrate.sh
_pidfile="$_builddir"/qemu-$$.pid
_bootdir="$_builddir"/boot-$$
_loopdev=$(sudo losetup -f --show $_outfile)
_bootdir=.boot
_loopdev=$(sudo losetup -f --show "$_outfile")
# register cleanup handler to stop the started VM
function cleanup {
test -f $_pidfile && (kill -9 $(cat $_pidfile) || true)
rm -f $_pidfile
test -f "$_pidfile" && (kill -9 $(cat "$_pidfile") || true)
rm -f "$_pidfile"
umount ${_loopdev}p1
losetup -d $_loopdev
rm -rf $_bootdir
rm -f $_scriptfile
rm -rf "$_bootdir"
rm -f "$_scriptfile"
}
trap cleanup ERR
# create the package build preparation script, adapted from
# https://wiki.parabola.nu/Package_maintainer_guide
(source /etc/makepkg.conf && cat > $_scriptfile << EOF
(source /etc/makepkg.conf && cat > "$_scriptfile" << EOF
#!/bin/bash
set -eu
@ -115,30 +115,33 @@ alias tspc='while tsp | grep -q running; do tsp -c; done'
alias librecommit='if tsp | grep " \$(pwd)\\$" >/dev/null; then tspr; fi && git commit -m "\$(pwd | rev | cut -d"/" -f1-2 | rev): updated to \$(bash -c "source PKGBUILD && echo \\\$pkgver")"'
IEOF
# enable UTF-8 locale
sed -i 's/#en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen
locale-gen
sed -i 's/LANG.*/LANG=en_US.UTF-8/' /etc/locale.conf
EOF
)
chmod +x $_scriptfile
chmod +x "$_scriptfile"
# start the VM
mkdir -p $_bootdir
mount ${_loopdev}p1 $_bootdir
mkdir -p "$_bootdir"
mount ${_loopdev}p1 "$_bootdir"
_board="vexpress-a9"
_cpu="cortex-a9"
_memory="1G"
_kernel="$_bootdir"/vmlinuz-linux-libre
_dtb="$_bootdir"/dtbs/linux-libre/vexpress-v2p-ca9.dtb
_initrd="$_bootdir"/initramfs-linux-libre.img
QEMU_AUDIO_DRV=none qemu-system-arm \
-M vexpress-a9 \
-m 1G \
-dtb $_bootdir/dtbs/vexpress-v2p-ca9.dtb \
-kernel $_bootdir/zImage \
-M $_board \
-cpu $_cpu \
-m $_memory \
-kernel "$_kernel" \
-dtb "$_dtb" \
-initrd "$_initrd" \
--append "root=/dev/mmcblk0p3 rw roottype=ext4 console=ttyAMA0" \
-drive if=sd,driver=raw,cache=writeback,file=$_outfile \
-drive if=sd,driver=raw,cache=writeback,file="$_outfile" \
-display none \
-net user,hostfwd=tcp::2022-:22 \
-net nic \
-daemonize \
-pidfile $_pidfile
-pidfile "$_pidfile"
# wait for ssh to be up
while ! ssh -p 2022 -i keys/id_rsa root@localhost -o StrictHostKeyChecking=no true 2>/dev/null; do
@ -146,24 +149,19 @@ while ! ssh -p 2022 -i keys/id_rsa root@localhost -o StrictHostKeyChecking=no tr
done && echo
# copy the current users keys to the VM
scp -rP 2022 -i keys/id_rsa $(sudo -iu $SUDO_USER pwd)/.gnupg root@localhost:/home/parabola/
scp -rP 2022 -i keys/id_rsa $(sudo -iu $SUDO_USER pwd)/.ssh root@localhost:/home/parabola/
scp -rP 2022 -i keys/id_rsa $(sudo -iu $SUDO_USER pwd)/.gitconfig root@localhost:/home/parabola/
scp -rP 2022 -i keys/id_rsa "$(sudo -iu $SUDO_USER pwd)"/.gnupg root@localhost:/home/parabola/
scp -rP 2022 -i keys/id_rsa "$(sudo -iu $SUDO_USER pwd)"/.ssh root@localhost:/home/parabola/
scp -rP 2022 -i keys/id_rsa "$(sudo -iu $SUDO_USER pwd)"/.gitconfig root@localhost:/home/parabola/
# copy and execute the migration script
scp -P 2022 -i keys/id_rsa $_scriptfile root@localhost:
ssh -p 2022 -i keys/id_rsa root@localhost "./$(basename $_scriptfile)"
# open a shell for debugging
# ssh -p 2022 -i keys/id_rsa root@localhost
scp -P 2022 -i keys/id_rsa "$_scriptfile" root@localhost:
ssh -p 2022 -i keys/id_rsa root@localhost "./$(basename "$_scriptfile")"
# stop the VM
ssh -p 2022 -i keys/id_rsa root@localhost "nohup shutdown -h now &>/dev/null & exit"
while kill -0 $(cat $_pidfile) 2> /dev/null; do echo -n . && sleep 5; done && echo
rm -f $_pidfile
while kill -0 $(cat "$_pidfile") 2> /dev/null; do echo -n . && sleep 5; done && echo
# cleanup
umount ${_loopdev}p1
losetup -d $_loopdev
rm -rf $_bootdir
rm $_scriptfile
rm -rf "$_bootdir" "$_scriptfile" "$_pidfile"

@ -21,62 +21,74 @@
set -eu
_builddir=build
mkdir -p $_builddir
mkdir -p "$_builddir"
_imagefile=$1
_pidfile=$_builddir/qemu-$$.pid
_bootdir=$_builddir/boot-$$
_pidfile="$_builddir"/qemu-$$.pid
_bootdir="$_builddir"/boot-$$
_loopdev=$(sudo losetup -f --show $_imagefile)
_loopdev=$(sudo losetup -f --show "$_imagefile")
sudo partprobe $_loopdev
_localport=$((2022 + $(find $_builddir -iname 'qemu-*.pid' | wc -l)))
touch $_pidfile
touch "$_pidfile"
# register a cleanup error handler
function cleanup {
test -f $_pidfile && (sudo kill -9 $(cat $_pidfile) || true)
rm -f $_pidfile
test -f "$_pidfile" && (sudo kill -9 $(cat "$_pidfile") || true)
rm -f "$_pidfile"
sudo umount ${_loopdev}p1
sudo losetup -d $_loopdev
rm -rf $_bootdir
rm -rf "$_bootdir"
}
trap cleanup ERR
# start the VM
mkdir -p $_bootdir
sudo mount ${_loopdev}p1 $_bootdir
# FIXME: archlinuxarm rust will SIGILL on cortex-a9 cpus, using cortex-a15 for now
mkdir -p "$_bootdir"
sudo mount ${_loopdev}p1 "$_bootdir"
_board="vexpress-a9"
# FIXME: archlinuxarm rust SIGILLs on cortex-a9 cpus, using cortex-a15 for now
_cpu="cortex-a15"
_memory="1G"
_snapshot=""
[ -z "${PERSISTENT:-}" ] && _snapshot="-snapshot"
_daemonize="-nographic -serial mon:stdio"
[ -z "${FOREGROUND:-}" ] && _daemonize="-daemonize -pidfile \"$_pidfile\" -net user,hostfwd=tcp::2022-:22 -net nic -display none"
if [ -f "$_bootdir"/zImage ]; then
_kernel="$_bootdir"/zImage
_dtb="$_bootdir"/dtbs/vexpress-v2p-ca9.dtb
_initrd="$_bootdir"/initramfs-linux.img
else
_kernel="$_bootdir"/vmlinuz-linux-libre
_dtb="$_bootdir"/dtbs/linux-libre/vexpress-v2p-ca9.dtb
_initrd="$_bootdir"/initramfs-linux-libre.img
fi
QEMU_AUDIO_DRV=none qemu-system-arm \
-M vexpress-a9 \
-cpu cortex-a15 \
-m 1G \
-dtb $_bootdir/dtbs/vexpress-v2p-ca9.dtb \
-kernel $_bootdir/zImage \
-M $_board \
-cpu $_cpu \
-m $_memory \
-kernel "$_kernel" \
-dtb "$_dtb" \
-initrd "$_initrd" \
--append "root=/dev/mmcblk0p3 rw roottype=ext4 console=ttyAMA0" \
-drive if=sd,driver=raw,cache=writeback,file=$_imagefile \
-display none \
-net user,hostfwd=tcp::$_localport-:22 \
-net nic \
-daemonize \
-snapshot \
-pidfile $_pidfile
-drive if=sd,driver=raw,cache=writeback,file="$_imagefile" \
$_daemonize \
$_snapshot
if [ -z "${FOREGROUND:-}" ]; then
# wait for ssh to be up
_sshopts="-o StrictHostKeyChecking=no -o ConnectTimeout=5"
while ! ssh -p $_localport -i keys/id_rsa root@localhost $_sshopts true 2>/dev/null; do
echo -n . && sleep 5
done && echo
_sshopts="-o StrictHostKeyChecking=no -o ConnectTimeout=5"
while ! ssh -p 2022 -i keys/id_rsa root@localhost $_sshopts true 2>/dev/null; do
echo -n . && sleep 5
done && echo
# open a session
ssh -p $_localport -i keys/id_rsa parabola@localhost
# open a session
ssh -p 2022 -i keys/id_rsa parabola@localhost
# shutdown the VM
ssh -p $_localport -i keys/id_rsa root@localhost "nohup shutdown -h now &>/dev/null & exit"
while sudo kill -0 $(cat $_pidfile) 2> /dev/null; do echo -n . && sleep 5; done && echo
rm -f $_pidfile
# shutdown the VM
ssh -p 2022 -i keys/id_rsa root@localhost "nohup shutdown -h now &>/dev/null & exit"
while sudo kill -0 $(cat "$_pidfile") 2> /dev/null; do echo -n . && sleep 5; done && echo
fi
# cleanup
sudo umount ${_loopdev}p1
sudo losetup -d $_loopdev
rm -rf $_bootdir
rm -rf "$_bootdir" "$_pidfile"