diff --git a/tools/labs/.gitignore b/tools/labs/.gitignore index 0f4ec23c13ab1e..ce629ee0746336 100644 --- a/tools/labs/.gitignore +++ b/tools/labs/.gitignore @@ -6,5 +6,7 @@ rootfs.img disk1.img disk2.img /*core-image-*.ext4 +/*core-image-*.bz2 .modinst /out/ +/rootfs diff --git a/tools/labs/qemu/Makefile b/tools/labs/qemu/Makefile index 7a2e97b570fa00..aaff3f6195d3a1 100644 --- a/tools/labs/qemu/Makefile +++ b/tools/labs/qemu/Makefile @@ -40,6 +40,7 @@ TEMPDIR := $(shell mktemp -u) $(KCONFIG): qemu/kernel_config.x86 cp $^ $@ $(MAKE) -C $(KDIR) olddefconfig + $(MAKE) -C $(KDIR) mod2yesconfig zImage: $(ZIMAGE) @@ -94,4 +95,41 @@ clean:: -rm -f disk1.img disk2.img -rm -f pipe1.in pipe1.out pipe2.in pipe2.out -.PHONY: boot gdb clean tap0 tap1 +# Run with one of the following: +# make -j$(nproc) console +# make -j$(nproc) gui + +# Attach debugger with +# make gdb + +# Stop with +# sync # make sure all filesystem changes are propagated +# CTRL-A X # kill qemu, faster and more reliable than poweroff etc. + +# Compile in skel directories with something like: +# alias kmake='make -C "$HOME/src/linux/" M="$(pwd)"' +# kmake + +YOCTO_ROOTFS = core-image-minimal-qemu$(ARCH).tar.bz2 + +console: $(ZIMAGE) rootfs + MODE=console qemu/run-qemu.sh + +gui: + MODE=gui qemu/run-qemu.sh + +rootfs: $(YOCTO_ROOTFS) + mkdir -p rootfs + tar -xf core-image-minimal-qemux86.tar.bz2 -C rootfs + sed -i 's@/sbin/getty@& -n -l "/sbin/rootlogin"@' rootfs/bin/start_getty + printf '%s\n' '#!/bin/sh' '/bin/login -f root' > rootfs/sbin/rootlogin + chmod +x rootfs/sbin/rootlogin + mkdir -p rootfs/home/root/skels + echo "//10.0.2.2/skels /home/root/skels cifs port=4450,guest,user=dummy 0 0" >> rootfs/etc/fstab + +$(YOCTO_ROOTFS): + wget $(YOCTO_URL)/$(YOCTO_ROOTFS) + + + +.PHONY: console gui boot gdb clean tap0 tap1 diff --git a/tools/labs/qemu/kernel_config.x86 b/tools/labs/qemu/kernel_config.x86 index c55e7dbe5ca2b9..16d0690f4627b1 100644 --- a/tools/labs/qemu/kernel_config.x86 +++ b/tools/labs/qemu/kernel_config.x86 @@ -32,7 +32,7 @@ CONFIG_DEVTMPFS=y CONFIG_BLK_DEV_LOOP=y CONFIG_VIRTIO_BLK=y CONFIG_NETDEVICES=y -CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE=y CONFIG_VIRTIO_NET=y CONFIG_VIRTIO_CONSOLE=y # CONFIG_HW_RANDOM is not set @@ -97,3 +97,18 @@ CONFIG_UPROBE_EVENTS=y CONFIG_LOCKDEP=y # kernel lock tracing: CONFIG_LOCK_STAT=y + +# for qemu serial console ttyS0: +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y + +# for qemu default netdev: +CONFIG_E1000=y + +# for CIFS/SMB/samba rootfs and share +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_CIFS=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +CONFIG_CIFS_ROOT=y diff --git a/tools/labs/qemu/run-qemu.sh b/tools/labs/qemu/run-qemu.sh new file mode 100755 index 00000000000000..d57df18a30da92 --- /dev/null +++ b/tools/labs/qemu/run-qemu.sh @@ -0,0 +1,114 @@ +#!/bin/bash + +die() { echo "$0: error: $@" >&2; exit 1; } + +script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" > /dev/null && pwd)" + +base_dir=${ROOT:-"$(readlink -f "$script_dir/..")"} +arch=${ARCH:-"x86"} +kernel=${ZIMAGE:-"$(readlink -f "$base_dir/../../arch/$arch/boot/bzImage")"} +rootfs=${ROOTFS:-"$(readlink -f "$base_dir/rootfs")"} +skels=${SKELS:-"$(readlink -f "$base_dir/skels")"} + +mode="${MODE:-console}" +case "$mode" in + console) + qemu_display="-nographic" + linux_console="console=ttyS0" + ;; + gui) + # QEMU_DISPLAY = sdl, gtk, ... + qemu_display="-display ${QEMU_DISPLAY:-"sdl"}" + linux_console="" + ;; + *) echo "unknown mode '$MODE'" >&2; exit 1 ;; +esac + +case "$arch" in + x86) qemu_arch=i386 ;; + arm) qemu_arch=arm ;; + *) echo "unknown architecture '$arch'" >&2; exit 1 ;; +esac + +smbd=${SMBD:-"smbd"} + +qemu=${QEMU:-"qemu-system-$qemu_arch"} +qemu_kvm=${QEMU_KVM:-"-enable-kvm -cpu host"} +qemu_cpus=${QEMU_CPUS:-"1"} +qemu_mem=${QEMU_MEM:-"512"} +qemu_display=${QEMU_DISPLAY:-"$qemu_display"} +qemu_addopts=${QEMU_ADD_OPTS:-""} +linux_console=${LINUX_CONSOLE:-"$linux_console"} +linux_loglevel=${LINUX_LOGLEVEL:-"15"} +linux_term=${LINUX_TERM:-"TERM=xterm"} +linux_addcmdline=${LINUX_ADD_CMDLINE:-""} + +linux_cmdline=${LINUX_CMDLINE:-"root=/dev/cifs rw ip=dhcp cifsroot=//10.0.2.2/rootfs,port=4450,guest,user=dummy $linux_console loglevel=$linux_loglevel $linux_term $linux_addcmdline"} + +tmp_dir=$(mktemp -d) +user=$(id -un) + +cat << EOF > "$tmp_dir/smbd.conf" +[global] + interfaces = 127.0.0.1 + smb ports = 4450 + private dir = $tmp_dir + bind interfaces only = yes + pid directory = $tmp_dir + lock directory = $tmp_dir + state directory = $tmp_dir + cache directory = $tmp_dir + ncalrpc dir = $tmp_dir/ncalrpc + log file = $tmp_dir/log.smbd + smb passwd file = $tmp_dir/smbpasswd + security = user + map to guest = Bad User + load printers = no + printing = bsd + disable spoolss = yes + usershare max shares = 0 + + server min protocol = NT1 + unix extensions = yes + + server role = standalone server + public = yes + writeable = yes + #admin users = root + #create mask = 0777 + #directory mask = 0777 + force user = $user + force group = $user + + +[rootfs] + path = $rootfs +[skels] + path = $skels +EOF + +[ -x "$(command -v "$smbd")" ] || die "samba ('$smbd') not found" +[ -x "$(command -v "$qemu")" ] || die "qemu ('$qemu') not found" + +mkdir -p "$skels" + +"$smbd" --no-process-group -s "$tmp_dir/smbd.conf" -l "$tmp_dir" >/dev/null 2>/dev/null & + +"$qemu" \ + $qemu_kvm \ + -smp "$qemu_cpus" -m "$qemu_mem" \ + -no-reboot \ + -kernel "$kernel" \ + -append "$linux_cmdline" \ + -gdb tcp::1234 \ + $qemu_display \ + $qemu_addopts + +# This seems to reset to the mode the terminal was prior to launching QEMU +# Inspired by +# https://github.com/landley/toybox/blob/990e0e7a40e4509c7987a190febe5d867f412af6/toys/other/reset.c#L26-L28 +# man 4 console_codes, ESC [ ? 7 h +printf '\e[?7h' + +pkill -F "$tmp_dir/smbd.pid" +rm -rf "$tmp_dir"