Skip to content

Commit

Permalink
Merge pull request #35 from nathanchance/debootstrap
Browse files Browse the repository at this point in the history
boot-utils: Add support for booting Debian images
  • Loading branch information
nathanchance authored Feb 22, 2021
2 parents 5042d4a + ce8b8a1 commit d59e01f
Show file tree
Hide file tree
Showing 8 changed files with 333 additions and 27 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
qemu-binaries/
rootfs.cpio
16 changes: 16 additions & 0 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,22 @@ Optional parameters:
-d | --debug:
Invokes 'set -x' for debugging the script.

--debian:
By default, the script boots a very simple Busybox based root filesystem.
This option allows the script to boot a full Debian root filesystem,
which can be built using 'build.sh' in the debian folder. Run

$ sudo debian/build.sh -h

for more information on that script.

The kernel should be built with the 'kvm_guest.config' target to boot
successfully. For example on an x86_64 host,

$ make defconfig kvm_guest.config bzImage

will produce a bootable kernel image.

-g | --gdb:
Add '-s -S' to the QEMU invocation to allow debugging via GDB (will invoke
`$GDB_BIN` env var else `gdb-multiarch`).
Expand Down
94 changes: 68 additions & 26 deletions boot-qemu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ function parse_parameters() {
set -x
;;

--debian)
DEBIAN=true
INTERACTIVE=true
;;

-g | --gdb)
GDB=true
INTERACTIVE=true
Expand Down Expand Up @@ -90,6 +95,10 @@ function sanity_check() {
[[ -z ${ARCH} ]] && die "Architecture ('-a') is required but not specified!"
[[ -z ${KERNEL_LOCATION} ]] && die "Kernel image or kernel build folder ('-k') is required but not specified!"

# Some default values
[[ -z ${DEBIAN} ]] && DEBIAN=false
[[ -z ${INTERACTIVE} ]] && INTERACTIVE=false

# KERNEL_LOCATION could be a relative path; turn it into an absolute one with readlink
KERNEL_LOCATION=$(readlink -f "${KERNEL_LOCATION}")

Expand All @@ -103,11 +112,20 @@ function setup_qemu_args() {
[[ ${ARCH} =~ arm32 ]] && ARCH_RTFS_DIR=arm

IMAGES_DIR=${BASE}/images/${ARCH_RTFS_DIR:-${ARCH}}
ROOTFS=${IMAGES_DIR}/rootfs.cpio
if ${DEBIAN}; then
ROOTFS=${IMAGES_DIR}/debian.img
[[ -f ${ROOTFS} ]] || die "'--debian' requires a debian.img. Run 'sudo debian/build.sh -a ${IMAGES_DIR##*/}' to generate it."
else
ROOTFS=${IMAGES_DIR}/rootfs.cpio
fi

APPEND_STRING=""
if ${INTERACTIVE:=false}; then
APPEND_STRING+="rdinit=/bin/sh "
if ${INTERACTIVE}; then
if ${DEBIAN}; then
APPEND_STRING+="root=/dev/vda "
else
APPEND_STRING+="rdinit=/bin/sh "
fi
fi
if ${GDB:=false}; then
APPEND_STRING+="nokaslr "
Expand All @@ -119,7 +137,8 @@ function setup_qemu_args() {
DTB=aspeed-bmc-opp-palmetto.dtb
QEMU_ARCH_ARGS=(
-machine palmetto-bmc
-no-reboot)
-no-reboot
)
QEMU=(qemu-system-arm)
;;

Expand All @@ -128,39 +147,51 @@ function setup_qemu_args() {
DTB=aspeed-bmc-opp-romulus.dtb
QEMU_ARCH_ARGS=(
-machine romulus-bmc
-no-reboot)
-no-reboot
)
QEMU=(qemu-system-arm)
;;

arm32_v7)
ARCH=arm
APPEND_STRING+="console=ttyAMA0 "
# https://lists.nongnu.org/archive/html/qemu-discuss/2018-08/msg00030.html
# VFS: Cannot open root device "vda" or unknown-block(0,0): error -6
${DEBIAN} && HIGHMEM=,highmem=off
QEMU_ARCH_ARGS=(
-machine virt
-no-reboot)
-machine "virt${HIGHMEM}"
-no-reboot
)
QEMU=(qemu-system-arm)
;;

arm64 | arm64be)
ARCH=arm64
KIMAGE=Image.gz
APPEND_STRING+="console=ttyAMA0 "
QEMU_ARCH_ARGS=(
-cpu max
-machine "virt,gic-version=max"
)
if [[ "$(uname -m)" = "aarch64" && -e /dev/kvm ]]; then
ARM64_CPU=host
ARM64_KVM_FLAGS=(-enable-kvm)
QEMU_ARCH_ARGS+=(-enable-kvm)
else
QEMU_ARCH_ARGS+=(-machine "virtualization=true")
fi
if ${DEBIAN}; then
# Booting is so slow without these
QEMU_RAM=2G
QEMU_ARCH_ARGS+=(-smp 4)
fi
QEMU_ARCH_ARGS=(
"${ARM64_KVM_FLAGS[@]}"
-cpu "${ARM64_CPU:-max}"
-machine virt)
QEMU=(qemu-system-aarch64)
;;

mips | mipsel)
KIMAGE=vmlinux
QEMU_ARCH_ARGS=(
-cpu 24Kf
-machine malta)
-machine malta
)
QEMU=(qemu-system-"${ARCH}")
ARCH=mips
;;
Expand All @@ -171,7 +202,8 @@ function setup_qemu_args() {
APPEND_STRING+="console=ttyS0 "
QEMU_ARCH_ARGS=(
-machine bamboo
-no-reboot)
-no-reboot
)
QEMU_RAM=128m
QEMU=(qemu-system-ppc)
;;
Expand All @@ -181,7 +213,8 @@ function setup_qemu_args() {
KIMAGE=vmlinux
QEMU_ARCH_ARGS=(
-machine pseries
-vga none)
-vga none
)
QEMU_RAM=1G
QEMU=(qemu-system-ppc64)
;;
Expand All @@ -193,7 +226,8 @@ function setup_qemu_args() {
-device "ipmi-bmc-sim,id=bmc0"
-device "isa-ipmi-bt,bmc=bmc0,irq=10"
-L "${IMAGES_DIR}/" -bios skiboot.lid
-machine powernv)
-machine powernv
)
QEMU_RAM=2G
QEMU=(qemu-system-ppc64)
;;
Expand All @@ -219,8 +253,14 @@ function setup_qemu_args() {
KIMAGE=bzImage
APPEND_STRING+="console=ttyS0 "
# Use KVM if the processor supports it and the KVM module is loaded (i.e. /dev/kvm exists)
[[ $(grep -c -E 'vmx|svm' /proc/cpuinfo) -gt 0 && -e /dev/kvm ]] &&
QEMU_ARCH_ARGS=("${QEMU_ARCH_ARGS[@]}" -cpu host -d "unimp,guest_errors" -enable-kvm -smp "$(nproc)")
if [[ $(grep -c -E 'vmx|svm' /proc/cpuinfo) -gt 0 && -e /dev/kvm ]]; then
QEMU_ARCH_ARGS=(
-cpu host
-d "unimp,guest_errors"
-enable-kvm
-smp "$(nproc)"
)
fi
case ${ARCH} in
x86) QEMU=(qemu-system-i386) ;;
x86_64) QEMU=(qemu-system-x86_64) ;;
Expand Down Expand Up @@ -268,13 +308,19 @@ function setup_qemu_args() {

# Invoke QEMU
function invoke_qemu() {
rm -rf "${ROOTFS}"
zstd -q -d "${ROOTFS}".zst -o "${ROOTFS}"

green "QEMU location: " "$(dirname "$(command -v "${QEMU[*]}")")" '\n'
green "QEMU version: " "$("${QEMU[@]}" --version | head -n1)" '\n'

[[ -z ${QEMU_RAM} ]] && QEMU_RAM=512m
if ${DEBIAN}; then
QEMU+=(-drive "file=${ROOTFS},format=raw,if=virtio,index=0,media=disk")
else
rm -rf "${ROOTFS}"
zstd -q -d "${ROOTFS}".zst -o "${ROOTFS}"
QEMU+=(-initrd "${ROOTFS}")
fi
# Removing trailing space for aesthetic purposes
[[ -n ${APPEND_STRING} ]] && QEMU+=(-append "${APPEND_STRING%* }")
if ${GDB:=false}; then
while true; do
if lsof -i:1234 &>/dev/null; then
Expand All @@ -285,9 +331,7 @@ function invoke_qemu() {
# Note: no -serial mon:stdio
"${QEMU[@]}" \
"${QEMU_ARCH_ARGS[@]}" \
-append "${APPEND_STRING}" \
-display none \
-initrd "${ROOTFS}" \
-kernel "${KERNEL}" \
-m "${QEMU_RAM}" \
-nodefaults \
Expand All @@ -313,9 +357,7 @@ function invoke_qemu() {
set -x
"${QEMU[@]}" \
"${QEMU_ARCH_ARGS[@]}" \
-append "${APPEND_STRING}" \
-display none \
-initrd "${ROOTFS}" \
-kernel "${KERNEL}" \
-m "${QEMU_RAM}" \
-nodefaults \
Expand Down
1 change: 1 addition & 0 deletions debian/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
tmp.*/
39 changes: 39 additions & 0 deletions debian/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
Usage: ./build.sh <options>

Script description: Builds a Debian filesystem image that can be booted in QEMU.

Required parameters:
-a | --arch:
The architecture to build the image for. Possible values are:
* arm
* arm64
* ppc64le
* s390
* x86_64

Optional parameters:
-l | --ltp:
Builds some test cases from the Linux Test Project that are useful for
finding issues.

-m | --modules-folder:
Path to the "modules" folder in a Linux kernel build tree. They will be
copied into /lib within the image. For example,

$ make INSTALL_MOD_PATH=rootfs modules_install

in a kernel tree will place the modules folder within rootfs/lib/modules
so the value that is passed to this script would be
<full_linux_path_to_kernel_folder>/rootfs/lib/modules. This is useful for
testing that kernel modules can load as well as verifying additional
functionality within QEMU.

-p | --password:
The created user account's password. By default, it is just "password".

-u | --user:
The created user account's name. By default, it is just "user".

-v | --version:
The version of Debian to build. By default, it is the latest stable which
is currently Buster.
Loading

0 comments on commit d59e01f

Please sign in to comment.