Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
qemu-binaries/
rootfs.cpio

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't this mean then that each time we decompress an initrd, that the directory is now dirty?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I just moved it to images/.gitignore.

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should the value assigned to HIGHMEM be a quoted string?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shellcheck does not complain but I can update that if you feel it is worthwhile.

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