install armhf/armv7 under qemu on Alpine Linux

2019-05-05

this script is just template, please tweak/adapt it for particular use case.
when script finishes there will be boot-armv7.sh in dir to boot newly installed alpine
usual disclaimer: no one is responsible for any damage/loss by using this

#!/bin/sh
# script will install armhf or armv7 in dirs which need to be adjusted
# to user will
# also network bridge for tuntap need to be set, bellow is example if
# there is already br0 set on the host

#user="username"

# for network access some tap and bridge interface are need
#comment out next three lines if tap interface is not set
sudo modprobe tun
sudo /sbin/ip tuntap add dev alp mode tap user $USER
sudo /sbin/ip link set alp master br0
sudo /sbin/ip link set up alp

#desired arch
#arch="armhf"
arch="armv7"
topdir="/work/devel/alpine"
workdir="$topdir/qemu/$arch"
initdir="initdir"
#workdisk size
WDS="2G"
release="3.10"
subrel=${release}.5
targz="alpine-uboot-$subrel-$arch.tar.gz"
sudo apk add squashfs-tools util-linux coreutils qemu-system-arm qemu-img parted

mkdir -p $workdir
cd $workdir

# download tar ball if it is no already downloaded
if [ ! -f $topdir/$targz ]; then
  wget -O $topdir/$targz http://dl-cdn.alpinelinux.org/alpine/v$release/releases/$arch/$targz
fi

#cp $topdir/$targz .
qemu-img create $arch-install.img 256M
parted -s $arch-install.img mktable msdos
parted -s $arch-install.img unit s -- mkpart primary ext4 2048 -1
mkdir mnt

losetup -o 1048576 /dev/loop2 $arch-install.img
mkfs.ext4 -L install /dev/loop2
sudo mount /dev/loop2 mnt/

sudo tar xf $topdir/$targz -C mnt

sed -i -e "s/ quiet/,sd_mod,scsi_mod,ext4,ahci_platform,rng-core,virtio_rng,virtio-scsi console=ttyAMA0/g" mnt/extlinux/extlinux.conf

mkdir $initdir
cd $initdir
gunzip -c ../mnt/boot/initramfs-vanilla  | cpio -i
kver=`ls lib/modules/`

cd ..
unsquashfs mnt/boot/modloop-vanilla
#cp squashfs-root/modules/$kver/kernel/drivers/ata/ahci.ko $initdir/lib/modules/$kver/kernel/drivers/ata/
#cp squashfs-root/modules/$kver/kernel/drivers/ata/libahci* $initdir/lib/modules/$kver/kernel/drivers/ata/
cp squashfs-root/modules/$kver/kernel/drivers/ata/* $initdir/lib/modules/$kver/kernel/drivers/ata/
mkdir -p $initdir/lib/modules/$kver/kernel/drivers/char/hw_random/char/hw_random/
cp squashfs-root/modules/$kver/kernel/drivers/char/hw_random/rng-core.ko $initdir/lib/modules/$kver/kernel/drivers/char/hw_random/
cp squashfs-root/modules/$kver/kernel/drivers/char/hw_random/virtio-rng.ko $initdir/lib/modules/$kver/kernel/drivers/char/hw_random/
depmod -b $initdir -F squashfs-root/modules/$kver/modules.symbols $kver


cd $initdir
find . | cpio -H newc -o | gzip -9 > ../mnt/boot/initramfs-vanilla

cd ..

echo "copy install guest script to install img"
mkdir boot
cp mnt/boot/initramfs-vanilla boot/
cp mnt/boot/vmlinuz-vanilla boot/
cp mnt/boot/dtbs/vexpress-v2p-ca15-tc1.dtb boot/
cp mnt/u-boot/qemu_arm/u-boot.bin boot/

setupscript="setup-guest.sh"
# create setup-guest.sh script
cat >mnt/$setupscript<<EOF
#!/bin/sh
echo "select dhcp"
setup-interfaces
ifup eth0
echo "select chrony"
setup-ntp
setup-apkrepos
apk add util-linux e2fsprogs udev parted
/etc/init.d/udev start
parted -s /dev/vda mktable msdos
parted -s /dev/vda unit s -- mkpart primary ext4 2048 526335
parted -s /dev/vda unit s -- mkpart primary ext4 526336 -1
parted -s /dev/vda -- set 1 boot on
mkfs.ext4 -L bootfs /dev/vda1
sync
mkfs.ext4 -L rootfs /dev/vda2
sync
mount /dev/vda2 /mnt
mkdir /mnt/boot
mount /dev/vda1 /mnt/boot
setup-disk -m sys /mnt
mkdir /mnt/boot/extlinux
cp /media/mmcblk0p1/extlinux/extlinux.conf  /mnt/boot/extlinux/extlinux.conf
sed -i -e "s/=ttyAMA0/=ttyAMA0 root=\/dev\/vda2 rw rootwait/g" /mnt/boot/extlinux/extlinux.conf
sync
echo
echo "install completed. You can tweak installation under /mnt dir"
echo "You can tweak boot kernel parameters or adding drivers  by editing /mnt/boot/extlinux/extlinux.conf"
echo "when finish *do not* reboot, but poweroff"
echo
echo "'umount /mnt' and run 'fsck.ext4 /dev/vda1'"
umount /mnt/boot
umount /mnt
fsck.ext4 /dev/vda1
#poweroff

EOF

sudo chmod 0744 mnt/$setupscript

sync
sudo umount mnt
losetup -d /dev/loop2

qemu-img create $arch-work.img $WDS
sync
# optinal clean dirs
rm -rf $initdir squashfs-root mnt

echo "starting install ..."
echo "when boot finish login as root (no password)"
echo "there is a script which should install Alpine on second disk image"
echo "could be started by '/media/mmcblk0p1/setup-guest.sh"
echo "ignore error about missing syslinux"
pwd
sleep 10

cd $arch
NETWORK="-netdev tap,id=hostnet0,ifname=alp,script=no,downscript=no -device virtio-net-device,netdev=hostnet0,id=net0,mac=52:55:00:d1:53:01"
qemu-system-arm -machine vexpress-a15 -cpu cortex-a15 -m 1024 \
 -kernel boot/vmlinuz-vanilla -initrd boot/initramfs-vanilla -dtb boot/vexpress-v2p-ca15-tc1.dtb \
 -append 'modules=loop,squashfs,sd-mod,scsi_mod,usb-storage,ext4,virtio_net console=ttyAMA0' \
 -nographic \
 -rtc base=utc,clock=host \
 -sd $arch-install.img \
 -drive if=none,file=$arch-work.img,id=disk1,format=raw -device virtio-blk-device,drive=disk1 \
 $NETWORK

bootscript=boot-armv7.sh
cat >$bootscript<<EOF
#!/bin/sh
NETWORK="-netdev tap,id=hostnet0,ifname=alp,script=no,downscript=no -device virtio-net-device,netdev=hostnet0,id=net0,mac=52:55:00:d1:53:01"
qemu-system-arm -machine virt -cpu cortex-a15 -m 1024 -bios boot/u-boot.bin \
 -drive if=none,file=armv7-work.img,id=disk1,format=raw \
 -device virtio-blk-device,drive=disk1 -nographic \
 -rtc base=utc,clock=host \
 $NETWORK

EOF
chmod 0744 $bootscript