#!/bin/bash ############################################################################## # parabola-imagebuilder # # # # Copyright (C) 2017 Andreas Grapentin # # # # This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation, either version 3 of the License, or # # (at your option) any later version. # # # # This program is distributed in the hope that it will be useful, # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # # GNU General Public License for more details. # # # # You should have received a copy of the GNU General Public License # # along with this program. If not, see . # ############################################################################## # this is a convenience script to start a created VM ############################################################################## # common directories startdir="$(pwd)" export TOPBUILDDIR="$startdir"/build export TOPSRCDIR="$startdir"/src mkdir -p "$TOPBUILDDIR" chown "$SUDO_USER" "$TOPBUILDDIR" # shellcheck source=src/shared/common.sh . "$TOPSRCDIR"/shared/common.sh # sanity checks if [ "$(id -u)" -ne 0 ]; then die -e "$ERROR_INVOCATION" "must be root" fi # shellcheck source=src/qemu.sh . "$TOPSRCDIR"/qemu.sh check_kernel_arch() { echo -n "checking for kernel name ..." local kernel kernel=$(find "$1" -maxdepth 1 -type f -iname '*vmlinu*' | head -n1) [ -n "$kernel" ] || kernel=no echo "$(basename "$kernel")" [ "x$kernel" != "xno" ] || return # check if the kernel has an elf header and extract arch echo -n "checking for kernel elf header ... " set -o pipefail machine=$(readelf -h "$kernel" 2>/dev/null | grep Machine | awk '{print $2}') || machine=no set +o pipefail echo "$machine" [ "x$machine" != "xno" ] && return # no elf header? maybe arm? echo -n "checking for ARM boot executable ... " local is_arm=no file "$kernel" | grep -q 'ARM boot executable' && is_arm=yes echo "$is_arm" [ "x$is_arm" == "xyes" ] && machine=ARM [ "x$machine" != "xno" ] && return # no idea, just bail. error "unable to extract kernel arch from image" return "$ERROR_MISSING" } qemu_setargs_arm() { qemu_args=( -snapshot -nographic -machine vexpress-a9 -cpu cortex-a9 -m 1G -kernel "$1"/vmlinuz-linux-libre -dtb "$1"/dtbs/linux-libre/vexpress-v2p-ca9.dtb -initrd "$1"/initramfs-linux-libre.img --append "console=ttyAMA0 rw root=/dev/mmcblk0p3" -drive if=sd,driver=raw,cache=writeback,file="$2" ) } qemu_setargs_riscv64() { qemu_args=( -snapshot -nographic -machine virt -m 2G -kernel "$1"/bbl -append "console=ttyS0 rw root=/dev/vda" -drive file="${3}p3",format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -object rng-random,filename=/dev/urandom,id=rng0 -device virtio-rng-device,rng=rng0 -device virtio-net-device,netdev=usernet -netdev user,id=usernet ) } boot_from_image() { [ -f "$1" ] || die "$1: image does not exist" local loopdev qemu_img_losetup "$1" || return # mount the boot partition mkdir -p "$TOPBUILDDIR"/mnt mount "${loopdev}p1" "$TOPBUILDDIR"/mnt || return trap_add "umount -R $TOPBUILDDIR/mnt" INT TERM EXIT local machine check_kernel_arch "$TOPBUILDDIR"/mnt || return case "$machine" in RISC-V) arch=riscv64 ;; ARM) arch=arm ;; *) error "unrecognized machine '$machine'" return "$ERROR_UNSPECIFIED" ;; esac qemu_args=() "qemu_setargs_$arch" "$TOPBUILDDIR"/mnt "$1" "$loopdev" QEMU_AUDIO_DRV=none "qemu-system-$arch" "${qemu_args[@]}" } boot_from_image "$1" || die "boot failed"