run: port argparse

This commit is contained in:
Ciro Santilli
2018-08-26 22:35:47 +01:00
parent f532a6dcf4
commit 561c08a286
3 changed files with 448 additions and 481 deletions

View File

@@ -9577,79 +9577,6 @@ Otherwise, it becomes very difficult to keep everything working across path refa
|`-q` |QEMU | |`-q` |QEMU |
|=== |===
==== run
....
./run [OPTIONS] [-- EXTRA_RUN_ARGS]
....
`EXTRA_RUN_ARGS` gets appended to the end of the emulator command line.
[options="header"]
|===
|Name |Argument name |Description
|`-c` |`NCPUS` |Emulate `NCPUS` guest CPUs.
|`-D` | |Run GDB on the emulator itself.
|`-d` | |Wait for GDB to connect before starting execution.
|`-E` |`CMDSTR` |Replace the normal init with a minimal init that just evals
with given `CMDSTR` bash command string. Example:
`-E 'insmod /hello.ko;'`
|`-e` |`CLI_OPTIONS` |Pass an extra Linux kernel command line options,
and place them before the dash separator `-`.
Only options that come before the `-`, i.e. "standard"
options, should be passed with this option.
Example: `./run -a arm -e 'init=/poweroff.out'`
|`-F` |`CMDSTR` |Much like `-f`, but base64 encodes the string.
Mnemonic: `-F` is to `-f` what `-E` is to `-e`.
|`-f` |`CLI_OPTIONS` |Pass an extra Linux kernel command line options,
add a dash `-` separator, and place the options after the dash.
Intended for custom options understood by our `init` scripts,
most of which are prefixed by `lkmc_`, e.g.:
`./run -f 'lkmc_eval="wget google.com" lkmc_lala=y'`
Mnenomic: comes after `-e`.
|`-G` | |Pass extra options to the gem5 executable.
Do not confuse with the arguments passed to config scripts,
like `fs.py`. Example: `./run -G '--debug-flags=Exec --debug' -g`
|`-h` | |Show this help message.
|`-I` | |Run with initramfs.
|`-i` | |Run with initrd.
|`-K` | |Use KVM. Only works if guest arch == host arch.
|`-k` | |Enable KGDB.
|`-L` |`VARIANT` |Linux kernel build variant.
|`-l` |`CHECKPOINT` |Restore the nth most recently taken gem5 checkpoint according to
directory timestamps.
|`-M` |`VARIANT` |gem5 build output variant.
|`-m` | |Set the memory size of the guest. E.g.: `-m 512M`. Default: `256M`.
The default is the minimum amount that boots all archs without extra
options added. Anything lower will lead some arch to fail to boot.
Any
|`-R` | |Replay a QEMU run record deterministically.
|`-r` | |Record a QEMU run record for later replay with `-R`.
|`-P` | |Run the downloaded prebuilt images.
|`-Q` |`VARIANT`` |QEMU build variant.
|`-T` |`TRACE_TYPES` |Set trace events to be enabled.
If not given, gem5 tracing is completely disabled, while QEMU tracing
is enabled but uses default traces that are very rare and don't affect
performance. `./configure --enable-trace-backends=simple` seems to enable
some traces by default, e.g. `pr_manager_run`, and I don't know how to
get rid of them.
|`-U` | |Pass extra parameters to the program running on the `-u` tmux split.
|`-u` | |Create a tmUx split the window.
You must already be inside of a `tmux` session to use this option.
* on the main window, run the emulator as usual
* on the split:
** if on QEMU and `-d` is given, GDB
** if on gem5, the gem5 terminal
|`-V` | |Run QEMU with VNC instead of the default SDL.
Connect to it with: `vinagre localhost:5900`.
|`-X` |`EXTRA_OPTS` |Extra options that did not fit into `A-z`!
This string is parsed by `getopt` on a separate parse step with different
meanings for each flag.
|`-X-b` | |Use `fs_bigLITTLE.py` instead of `fs.py` on gem5 simulation.
Ignored by QEMU.
|`-x` | |Run in graphic mode. Mnemonic: X11.
|===
==== runtc ==== runtc
The link:runtc[] helper script runs a Tool Chain executable built by Buildroot. The link:runtc[] helper script runs a Tool Chain executable built by Buildroot.

View File

@@ -32,13 +32,17 @@ def get_argparse(**kwargs):
Return an argument parser with common arguments set. Return an argument parser with common arguments set.
""" """
global this global this
arch_choices = []
for key in this.arch_map:
arch_choices.append(key)
arch_choices.append(this.arch_map[key])
default_build_id='default' default_build_id='default'
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.RawTextHelpFormatter, formatter_class=argparse.RawTextHelpFormatter,
**kwargs **kwargs
) )
parser.add_argument( parser.add_argument(
'-a', '--arch', default='x86_64', '-a', '--arch', choices=arch_choices, default='x86_64',
help='CPU architecture. Default: %(default)s' help='CPU architecture. Default: %(default)s'
) )
parser.add_argument( parser.add_argument(
@@ -72,8 +76,8 @@ Default: %(default)s
'--port-offset', type=int, '--port-offset', type=int,
help="""\ help="""\
Increase the ports to be used such as for GDB by an offset to run multiple Increase the ports to be used such as for GDB by an offset to run multiple
instances in parallel. Equals the run ID if that is an integer. instances in parallel.
Default: %(default)s Default: the run ID (-n) if that is an integer, otherwise 0.
""" """
) )
parser.add_argument( parser.add_argument(
@@ -106,18 +110,14 @@ def setup(parser):
""" """
global this global this
args = parser.parse_args() args = parser.parse_args()
if args.arch == 'a' or args.arch == 'arm': if args.arch in this.arch_map:
args.arch = 'arm' args.arch = this.arch_map[args.arch]
if args.arch == 'arm':
gem5_arch = 'ARM' gem5_arch = 'ARM'
elif args.arch == 'A' or args.arch == 'aarch64': elif args.arch == 'aarch64':
args.arch = 'aarch64'
gem5_arch = 'ARM' gem5_arch = 'ARM'
elif args.arch == 'x' or args.arch == 'x86_64': elif args.arch == 'x86_64':
args.arch = 'x86_64'
gem5_arch = 'X86' gem5_arch = 'X86'
else:
print('unknown arch: {}'.format(args.arch), file=sys.stderr)
sys.exit(2)
this.buildroot_dir = os.path.join(root_dir, 'buildroot') this.buildroot_dir = os.path.join(root_dir, 'buildroot')
this.arch_dir = args.arch this.arch_dir = args.arch
if args.suffix is not None: if args.suffix is not None:
@@ -209,6 +209,11 @@ bench_boot = os.path.join(out_dir, 'bench-boot.txt')
common_dir = os.path.join(out_dir, 'common') common_dir = os.path.join(out_dir, 'common')
# Other default variables. # Other default variables.
arch_map = {
'a': 'arm',
'A': 'aarch64',
'x': 'x86_64',
}
gem5_cpt_pref = '^cpt\.' gem5_cpt_pref = '^cpt\.'
sha = subprocess.check_output(['git', '-C', root_dir, 'log', '-1', '--format=%H']).decode().rstrip() sha = subprocess.check_output(['git', '-C', root_dir, 'log', '-1', '--format=%H']).decode().rstrip()

827
run
View File

@@ -1,397 +1,432 @@
#!/usr/bin/env bash #!/usr/bin/env python3
. "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common" import common
parser = common.get_argparse(
description='Run Linux on an emulator'
)
parser.add_argument(
'-c', '--cpus', default=1, type=int,
help='Number of guest CPUs to emulate. Default: %(default)s'
)
parser.add_argument(
'-D', '--debug-vm', default=False, action='store_true',
help='Run GDB on the emulator itself.'
)
parser.add_argument(
'-d', '--debug', default=False, action='store_true',
help='Wait for GDB to connect before starting execution'
)
parser.add_argument(
'-E', '--eval',
help="""\
Replace the normal init with a minimal init that just evals with given
`CMDSTR` bash command string. Example: `-E 'insmod /hello.ko;'`
"""
)
parser.add_argument(
'-e', '--kernel-cli-extra',
help="""\
Pass an extra Linux kernel command line options, and place them before
the dash separator `-`. Only options that come before the `-`, i.e.
"standard" options, should be passed with this option.
Example: `./run -a arm -e 'init=/poweroff.out'`
"""
)
parser.add_argument(
'-F', '--kernel-cli-extra-after-dash-base64',
help="""\
Much like `-f`, but base64 encodes the string. Mnemonic:
`-F` is to `-f` what `-E` is to `-e`.)
"""
)
parser.add_argument(
'-f', '--kernel-cli-extra-after-dash',
help="""\
Pass an extra Linux kernel command line options, add a dash `-`
separator, and place the options after the dash. Intended for custom
options understood by our `init` scripts, most of which are prefixed
by `lkmc_`, e.g.: `./run -f 'lkmc_eval="wget google.com" lkmc_lala=y'`
Mnenomic: comes after `-e`.
"""
)
parser.add_argument(
'-G', '--gem5-exe-args',
help="""\
Pass extra options to the gem5 executable.
Do not confuse with the arguments passed to config scripts,
like `fs.py`. Example: `./run -G '--debug-flags=Exec --debug' -g`.
"""
)
parser.add_argument(
'--gem5-biglittle', default=False, action='store_true',
help='Use fs_bigLITTLE.py instead of fs.py'
)
group = parser.add_mutually_exclusive_group()
group.add_argument(
'-I', '--initramfs', default=False, action='store_true',
help='Use initramfs instead of a root filesystem'
)
group.add_argument(
'-i', '--initrd', default=False, action='store_true',
help='Use initrd instead of a root filesystem'
)
parser.add_argument(
'-K', '--kvm', default=False, action='store_true',
help='Use KVM. Only works if guest arch == host arch'
)
parser.add_argument(
'-k', '--kgdb', default=False, action='store_true'
)
parser.add_argument(
'-l', '--gem5-restore-last-checkpoint', type=int,
help="""\
Restore the nth most recently taken gem5 checkpoint according to directory
timestamps.
"""
)
parser.add_argument(
'-m', '--memory', default='256M',
help="""\
Set the memory size of the guest. E.g.: `-m 512M`. We try to keep the default
at the minimal ammount amount that boots all archs. Anything lower could lead
some arch to fail to boot.
Default: %(default)s
"""
)
parser.add_argument(
'-P', '--prebuilt', default=False, action='store_true',
help='Run the downloaded prebuilt images.'
)
group = parser.add_mutually_exclusive_group()
group.add_argument(
'-R', '--qemu-replay', default=False, action='store_true',
help='Replay a QEMU run record deterministically'
)
group.add_argument(
'-r', '--qemu-record', default=False, action='store_true',
help='Record a QEMU run record for later replay with `-R`'
)
parser.add_argument(
'-T', '--trace',
help="""\
Set trace events to be enabled. If not given, gem5 tracing is completely
disabled, while QEMU tracing is enabled but uses default traces that are very
rare and don't affect performance, because `./configure
--enable-trace-backends=simple` seems to enable some traces by default, e.g.
`pr_manager_run`, and I don't know how to get rid of them.
"""
)
parser.add_argument(
'-U', '--tmux-args',
help='Pass extra parameters to the program running on the `-u` tmux split'
)
parser.add_argument(
'-u', '--tmux', default=False, action='store_true',
help="""\
Create a tmUx split the window. You must already be inside of a `tmux` session
to use this option:
* on the main window, run the emulator as usual
* on the split:
** if on QEMU and `-d` is given, GDB
** if on gem5, the gem5 terminal
"""
)
parser.add_argument(
'-x', '--graphic', default=False, action='store_true',
help='Run in graphic mode. Mnemonic: X11'
)
parser.add_argument(
'-V', '--vnc', default=False, action='store_true',
help="""\
Run QEMU with VNC instead of the default SDL. Connect to it with:
`vinagre localhost:5900`.
"""
)
parser.add_argument(
'extra_emulator_args', nargs='?',
help='Extra options to append at the end of the emulator command line'
)
args = common.setup(parser)
# CLI handling. #if args.debug_vm:
cpus=1 # debug_vm="gdb -q -ex start --args"
debug_vm= #if args.debug:
debug=false # extra_flags_qemu="${extra_flags_qemu} -S"
kgdb=false #F)
kvm=false # extra_append_after_dash="${extra_append_after_dash} lkmc_eval_base64=\"$(printf "${OPTARG}" | base64)\""
# nokaslr: # ;;
# - https://unix.stackexchange.com/questions/397939/turning-off-kaslr-to-debug-linux-kernel-using-qemu-and-gdb #f)
# - https://stackoverflow.com/questions/44612822/unable-to-debug-kernel-with-qemu-gdb/49840927#49840927 # extra_append_after_dash="${extra_append_after_dash} ${OPTARG}"
# Turned on by default since v4.12 # ;;
extra_append='console_msg_format=syslog nokaslr norandmaps panic=-1 printk.devkmsg=on printk.time=y' #if args.kgdb:
extra_append_after_dash= # extra_append="$extra_append kgdbwait"
extra_flags= #if args.vnc:
extra_flags_qemu= # vnc = ['-vnc', ':0']
extra_opts= #
gem5opts= ## nokaslr:
gem5_fsbiglittle=false ## - https://unix.stackexchange.com/questions/397939/turning-off-kaslr-to-debug-linux-kernel-using-qemu-and-gdb
gem5_restore_last_checkpoint= ## - https://stackoverflow.com/questions/44612822/unable-to-debug-kernel-with-qemu-gdb/49840927#49840927
lkmc_eval= ## Turned on by default since v4.12
initrd=false #extra_append='console_msg_format=syslog nokaslr norandmaps panic=-1 printk.devkmsg=on printk.time=y'
initramfs=false #
memory=256M ## A dummy value that is already turned on by default and does not produce large output,
nographic=true ## just to prevent QEMU from emitting a warning that '' is not valid.
prebuilt=false #trace_type=pr_manager_run
rr= #
root= #
tmux=false #if "$debug" && "$kvm"; then
tmux_args= # echo 'error: -d and -K are incompatible' 1>&2
trace_enabled=false # exit 1
# A dummy value that is already turned on by default and does not produce large output, #fi
# just to prevent QEMU from emitting a warning that '' is not valid. #if "$initrd" || "$initramfs"; then
trace_type=pr_manager_run # ramfs=true
vnc= #else
while getopts "c:DdE:e:F:f:G:hIiKkl:m:PRrT:U:uVX:x${common_getopts_flags}" OPT; do # ramfs=false
case "$OPT" in #fi
c) #if [ -n "$lkmc_eval" ]; then
cpus="$OPTARG" # if "$ramfs"; then
;; # initarg="rdinit"
D) # else
debug_vm="gdb -q -ex start --args \\ # initarg="init"
" # fi
;; # extra_append="${extra_append} ${initarg}=/eval_base64.sh"
d) # extra_append_after_dash="${extra_append_after_dash} lkmc_eval=\"$(printf "$lkmc_eval" | base64)\""
debug=true #fi
extra_flags_qemu="${extra_flags_qemu} -S \\ #if "$nographic"; then
" # if [ "$common_arch" = x86_64 ]; then
;; # extra_append="${extra_append} console=ttyS0"
E) # fi
lkmc_eval="$OPTARG" # extra_flags_qemu="${extra_flags_qemu}-nographic \\
;; #"
e) #fi
extra_append="${extra_append} ${OPTARG}" #if [ -n "$extra_append_after_dash" ]; then
;; # extra_append="${extra_append} - ${extra_append_after_dash}"
F) #fi
extra_append_after_dash="${extra_append_after_dash} lkmc_eval_base64=\"$(printf "${OPTARG}" | base64)\"" #
;; #if "$common_gem5"; then
f) # memory="${memory}B"
extra_append_after_dash="${extra_append_after_dash} ${OPTARG}" # if "$trace_enabled"; then
;; # gem5opts="${gem5opts} --debug-flags='${trace_type}' \\
G) #"
gem5opts="$OPTARG \\ # fi
" # gem5_common="\
;; #M5_PATH='${common_gem5_system_dir}' \\
h) #${debug_vm}\
echo "https://github.com/cirosantilli/linux-kernel-module-cheat#run" 2>&1 #'${common_executable}' \\
exit #--debug-file=trace.txt \\
;; #${gem5opts}\
I) #-d '${common_m5out_dir}' \\
initramfs=true #"
;; # if "$gem5_fsbiglittle"; then
i) # if [ -n "$gem5_restore_last_checkpoint" ]; then
initrd=true # extra_flags="${extra_flags}\
;; #--restore-from='${common_m5out_dir}/$(ls -crt "$common_m5out_dir" | grep -E "$common_gem5_cpt_pref" | tail -n "$gem5_restore_last_checkpoint" | head -n 1)' \\
K) #"
kvm=true # fi
;; # cmd="${gem5_common}\
k) #"${common_gem5_default_src_dir}/configs/example/arm/fs_bigLITTLE.py" \\
extra_append="$extra_append kgdbwait" #--big-cpus=2 \\
# For those who want to try KDB. #--cpu-type=atomic \\
#extra_append="$extra_append kgdbwait kgdboc=kbd" #--disk="${common_images_dir}/rootfs.ext2" \\
kgdb=true #--dtb "${common_gem5_system_dir}/arm/dt/armv8_gem5_v1_big_little_2_2.dtb" \\
;; #--kernel="${common_vmlinux}" \\
l) #--little-cpus=2 \\
gem5_restore_last_checkpoint="${OPTARG}" #"
;; # else
m) # if [ -n "$gem5_restore_last_checkpoint" ]; then
memory="$OPTARG" # latest_cpt_basename="$(ls -crt "$common_m5out_dir" | grep -E "$common_gem5_cpt_pref" | tail -n "$gem5_restore_last_checkpoint" | head -n 1)"
;; # n="$(ls -1 "$common_m5out_dir" | grep -E "$common_gem5_cpt_pref" | sort -k 2 -n -t . | grep -n "$latest_cpt_basename" | cut -d : -f 1)"
P) # extra_flags="${extra_flags}-r ${n} \\
prebuilt=true #"
;; # fi
R) # gem5_common="\
rr=replay #${gem5_common}\
;; #'${common_gem5_src_dir}/configs/example/fs.py' \\
r) #--disk-image='${common_images_dir}/rootfs.ext2' \\
rr=record #--kernel='${common_vmlinux}' \\
;; #--mem-size='${memory}' \\
T) #--num-cpus='${cpus}' \\
trace_enabled=true #--script='${common_gem5_readfile_file}' \\
trace_type="$OPTARG" #"
;; # if [ "$common_arch" = x86_64 ]; then
U) # if "$kvm"; then
tmux_args="$OPTARG" # extra_flags="${extra_flags} --cpu-type=X86KvmCPU"
;; # fi
u) # cmd="\
tmux=true #${gem5_common}\
;; #--command-line='earlyprintk=ttyS0 console=ttyS0 lpj=7999923 root=/dev/sda ${extra_append}' \\
X) #"
extra_opts="${extra_opts} ${OPTARG}" # elif [ "$common_arch" = arm ] || [ "$common_arch" = aarch64 ]; then
;; # # TODO why is it mandatory to pass mem= here? Not true for QEMU.
x) # # Anything smaller than physical blows up as expected, but why can't it auto-detect the right value?
nographic=false # cmd="${gem5_common}\
;; #--command-line='earlyprintk=pl011,0x1c090000 console=ttyAMA0 lpj=19988480 rw loglevel=8 mem=${memory} root=/dev/sda ${extra_append}' \\
V) #--dtb-file='${common_gem5_system_dir}/arm/dt/$([ "$common_arch" = arm ] && echo "armv7_gem5_v1_${cpus}cpu" || echo "armv8_gem5_v1_${cpus}cpu").dtb' \\
vnc="-vnc :0 \\ #--machine-type=VExpress_GEM5_V1 \\
" #"
;; # fi
?) # fi
common_getopts_case "$OPT" #else
;; # mkdir -p "$common_qemu_run_dir"
esac # if [ -z "$debug_vm" ]; then
done # serial_monitor="-serial mon:stdio \\
shift "$(($OPTIND - 1))" #"
OPTIND=1 # else
if [ -n "$extra_opts" ]; then # serial_monitor=
while getopts b OPT $extra_opts; do # fi
case "$OPT" in # if "$kvm"; then
b) # extra_flags="${extra_flags}-enable-kvm \\
gem5_fsbiglittle=true #"
;; # fi
?) # if "$kgdb"; then
exit 2 # extra_flags_qemu="${extra_flags_qemu}-serial 'tcp::${common_gdb_port},server,nowait' \\
;; #"
esac # fi
done # if "$prebuilt"; then
fi # common_mkdir
common_setup # qemu_executable="qemu-system-${common_arch}"
if "$debug" && "$kvm"; then # else
echo 'error: -d and -K are incompatible' 1>&2 # qemu_executable="${common_qemu_exec}"
exit 1 # fi
fi # extra_flags="${extra_flags_qemu}${extra_flags}"
if "$initrd" || "$initramfs"; then # qemu_common="\
ramfs=true #${debug_vm}\
else #${qemu_executable} \\
ramfs=false #-device rtl8139,netdev=net0 \\
fi #-gdb 'tcp::${common_gdb_port}' \\
if [ -n "$lkmc_eval" ]; then #-kernel '${common_linux_image}' \\
if "$ramfs"; then #-m '${memory}' \\
initarg="rdinit" #-monitor 'telnet::${common_qemu_monitor_port},server,nowait' \\
else #-netdev 'user,hostfwd=tcp::${common_qemu_hostfwd_generic_port}-:${common_qemu_hostfwd_generic_port},hostfwd=tcp::${common_qemu_hostfwd_ssh_port}-:22,id=net0' \\
initarg="init" #-no-reboot \\
fi #${serial_monitor}\
extra_append="${extra_append} ${initarg}=/eval_base64.sh" #-smp '${cpus}' \\
extra_append_after_dash="${extra_append_after_dash} lkmc_eval=\"$(printf "$lkmc_eval" | base64)\"" #-trace 'enable=${trace_type},file=${common_qemu_run_dir}/trace.bin' \\
fi #-virtfs 'local,path=${common_9p_dir},mount_tag=host_scratch,security_model=mapped,id=host_scratch' \\
if "$nographic"; then #-virtfs 'local,path=${common_buildroot_out_dir}/build,mount_tag=host_out,security_model=mapped,id=host_out' \\
if [ "$common_arch" = x86_64 ]; then #${vnc}"
extra_append="${extra_append} console=ttyS0" # if "$initrd"; then
fi # extra_flags="${extra_flags} -initrd '${common_images_dir}/rootfs.cpio' \\
extra_flags_qemu="${extra_flags_qemu}-nographic \\ #"
" # fi
fi #
if [ -n "$extra_append_after_dash" ]; then # # Disk related options.
extra_append="${extra_append} - ${extra_append_after_dash}" # if "$ramfs"; then
fi # # TODO why is this needed, and why any string works.
# root='root=/dev/anything'
if "$common_gem5"; then # else
memory="${memory}B" # if [ ! "$common_arch" = mips64 ]; then
if "$trace_enabled"; then # if [ -n "$rr" ]; then
gem5opts="${gem5opts} --debug-flags='${trace_type}' \\ # driveif=none
" # rrid=',id=img-direct'
fi # root='root=/dev/sda'
gem5_common="\ # snapshot=
M5_PATH='${common_gem5_system_dir}' \\ # else
${debug_vm}\ # driveif=virtio
'${common_executable}' \\ # root='root=/dev/vda'
--debug-file=trace.txt \\ # rrid=
${gem5opts}\ # snapshot=,snapshot
-d '${common_m5out_dir}' \\ # fi
" # extra_flags="${extra_flags}-drive 'file=${common_qcow2_file},format=qcow2,if=${driveif}${snapshot}${rrid}' \\
if "$gem5_fsbiglittle"; then #"
if [ -n "$gem5_restore_last_checkpoint" ]; then # if [ -n "$rr" ]; then
extra_flags="${extra_flags}\ # extra_flags="${extra_flags}\
--restore-from='${common_m5out_dir}/$(ls -crt "$common_m5out_dir" | grep -E "$common_gem5_cpt_pref" | tail -n "$gem5_restore_last_checkpoint" | head -n 1)' \\ #-drive driver=blkreplay,if=none,image=img-direct,id=img-blkreplay \\
" #-device ide-hd,drive=img-blkreplay \\
fi #"
cmd="${gem5_common}\ # fi
"${common_gem5_default_src_dir}/configs/example/arm/fs_bigLITTLE.py" \\ # fi
--big-cpus=2 \\ # fi
--cpu-type=atomic \\ #
--disk="${common_images_dir}/rootfs.ext2" \\ # if [ -n "$rr" ]; then
--dtb "${common_gem5_system_dir}/arm/dt/armv8_gem5_v1_big_little_2_2.dtb" \\ # extra_flags="${extra_flags}\
--kernel="${common_vmlinux}" \\ #-object filter-replay,id=replay,netdev=net0 \\
--little-cpus=2 \\ #-icount 'shift=7,rr=${rr},rrfile=${common_qemu_rrfile}' \\
" #"
else # virtio_gpu_pci=
if [ -n "$gem5_restore_last_checkpoint" ]; then # else
latest_cpt_basename="$(ls -crt "$common_m5out_dir" | grep -E "$common_gem5_cpt_pref" | tail -n "$gem5_restore_last_checkpoint" | head -n 1)" # virtio_gpu_pci="-device virtio-gpu-pci \\
n="$(ls -1 "$common_m5out_dir" | grep -E "$common_gem5_cpt_pref" | sort -k 2 -n -t . | grep -n "$latest_cpt_basename" | cut -d : -f 1)" #"
extra_flags="${extra_flags}-r ${n} \\ # fi
" # case "$common_arch" in
fi # x86_64)
gem5_common="\ # if "$kgdb"; then
${gem5_common}\ # extra_append="${extra_append} kgdboc=ttyS0,115200"
'${common_gem5_src_dir}/configs/example/fs.py' \\ # fi
--disk-image='${common_images_dir}/rootfs.ext2' \\ # cmd="\
--kernel='${common_vmlinux}' \\ #${qemu_common}\
--mem-size='${memory}' \\ #-M pc \\
--num-cpus='${cpus}' \\ #-append '${root} nopat ${extra_append}' \\
--script='${common_gem5_readfile_file}' \\ #-device edu \\
" #"
if [ "$common_arch" = x86_64 ]; then # ;;
if "$kvm"; then # arm|aarch64)
extra_flags="${extra_flags} --cpu-type=X86KvmCPU" # if "$kgdb"; then
fi # extra_append="${extra_append} kgdboc=ttyAMA0,115200"
cmd="\ # fi
${gem5_common}\ # if [ "$common_arch" = arm ]; then
--command-line='earlyprintk=ttyS0 console=ttyS0 lpj=7999923 root=/dev/sda ${extra_append}' \\ # cpu=cortex-a15
" # else
elif [ "$common_arch" = arm ] || [ "$common_arch" = aarch64 ]; then # cpu=cortex-a57
# TODO why is it mandatory to pass mem= here? Not true for QEMU. # fi
# Anything smaller than physical blows up as expected, but why can't it auto-detect the right value? # # highmem=off needed since v3.0.0 due to:
cmd="${gem5_common}\ # # http://lists.nongnu.org/archive/html/qemu-discuss/2018-08/msg00034.html
--command-line='earlyprintk=pl011,0x1c090000 console=ttyAMA0 lpj=19988480 rw loglevel=8 mem=${memory} root=/dev/sda ${extra_append}' \\ # cmd="\
--dtb-file='${common_gem5_system_dir}/arm/dt/$([ "$common_arch" = arm ] && echo "armv7_gem5_v1_${cpus}cpu" || echo "armv8_gem5_v1_${cpus}cpu").dtb' \\ #${qemu_common}\
--machine-type=VExpress_GEM5_V1 \\ #-M virt,highmem=off \\
" #-append '${root} ${extra_append}' \\
fi #-cpu "$cpu" \\
fi #${virtio_gpu_pci}\
else #"
mkdir -p "$common_qemu_run_dir" # ;;
if [ -z "$debug_vm" ]; then # mips64)
serial_monitor="-serial mon:stdio \\ # if ! "$ramfs"; then
" # root='root=/dev/hda'
else # extra_flags="${extra_flags}-drive 'file=${common_qcow2_file},format=qcow2${snapshot}' \\
serial_monitor= #"
fi # fi
if "$kvm"; then # cmd="\
extra_flags="${extra_flags}-enable-kvm \\ #${qemu_common}\
" #-M malta \\
fi #-append '${root} ${extra_append}' \\
if "$kgdb"; then #-cpu I6400 \\
extra_flags_qemu="${extra_flags_qemu}-serial 'tcp::${common_gdb_port},server,nowait' \\ #"
" # ;;
fi # esac
if "$prebuilt"; then #fi
common_mkdir #if "$tmux"; then
qemu_executable="qemu-system-${common_arch}" # if "$common_gem5"; then
else # eval "./tmu 'sleep 2;./gem5-shell -n ${common_run_id} ${tmux_args};'"
qemu_executable="${common_qemu_exec}" # elif "$debug"; then
fi # eval "./tmu ./rungdb -a '${common_arch} -L ${common_linux_variant}' -n ${common_run_id} ${tmux_args}"
extra_flags="${extra_flags_qemu}${extra_flags}" # fi
qemu_common="\ #fi
${debug_vm}\ #if [ -n "${1:-}" ]; then
${qemu_executable} \\ # extra_flags="${extra_flags}${@} \\
-device rtl8139,netdev=net0 \\ #"
-gdb 'tcp::${common_gdb_port}' \\ #fi
-kernel '${common_linux_image}' \\ #cmd="time \\
-m '${memory}' \\ #${cmd}${extra_flags}"
-monitor 'telnet::${common_qemu_monitor_port},server,nowait' \\ #if [ -z "$debug_vm" ]; then
-netdev 'user,hostfwd=tcp::${common_qemu_hostfwd_generic_port}-:${common_qemu_hostfwd_generic_port},hostfwd=tcp::${common_qemu_hostfwd_ssh_port}-:22,id=net0' \\ # cmd="${cmd}\
-no-reboot \\ #|& tee >(ts -s %.s > ${common_termout_file})\
${serial_monitor}\ #"
-smp '${cpus}' \\ #fi
-trace 'enable=${trace_type},file=${common_qemu_run_dir}/trace.bin' \\ #"${common_root_dir}/eeval" "$cmd" "${common_run_dir}/run.sh"
-virtfs 'local,path=${common_9p_dir},mount_tag=host_scratch,security_model=mapped,id=host_scratch' \\ #cmd_out=$?
-virtfs 'local,path=${common_buildroot_out_dir}/build,mount_tag=host_out,security_model=mapped,id=host_out' \\ #if [ "$cmd_out" -ne 0 ]; then
${vnc}" # exit "$cmd_out"
if "$initrd"; then #fi
extra_flags="${extra_flags} -initrd '${common_images_dir}/rootfs.cpio' \\ #
" ## Check if guest panicked.
fi #if "$common_gem5"; then
# # We have to do some parsing here because gem5 exits with status 0 even when panic happens.
# Disk related options. # #
if "$ramfs"; then # # Grepping for '^panic: ' does not work because some errors don't show that message
# TODO why is this needed, and why any string works. # panic_msg='--- BEGIN LIBC BACKTRACE ---$'
root='root=/dev/anything' #else
else # panic_msg='Kernel panic - not syncing'
if [ ! "$common_arch" = mips64 ]; then #fi
if [ -n "$rr" ]; then #if grep -E -e "$panic_msg" -q "$common_termout_file"; then
driveif=none # echo 'Simulation error detected by parsing logs. Exiting with status 1.'
rrid=',id=img-direct' # exit 1
root='root=/dev/sda' #fi
snapshot=
else
driveif=virtio
root='root=/dev/vda'
rrid=
snapshot=,snapshot
fi
extra_flags="${extra_flags}-drive 'file=${common_qcow2_file},format=qcow2,if=${driveif}${snapshot}${rrid}' \\
"
if [ -n "$rr" ]; then
extra_flags="${extra_flags}\
-drive driver=blkreplay,if=none,image=img-direct,id=img-blkreplay \\
-device ide-hd,drive=img-blkreplay \\
"
fi
fi
fi
if [ -n "$rr" ]; then
extra_flags="${extra_flags}\
-object filter-replay,id=replay,netdev=net0 \\
-icount 'shift=7,rr=${rr},rrfile=${common_qemu_rrfile}' \\
"
virtio_gpu_pci=
else
virtio_gpu_pci="-device virtio-gpu-pci \\
"
fi
case "$common_arch" in
x86_64)
if "$kgdb"; then
extra_append="${extra_append} kgdboc=ttyS0,115200"
fi
cmd="\
${qemu_common}\
-M pc \\
-append '${root} nopat ${extra_append}' \\
-device edu \\
"
;;
arm|aarch64)
if "$kgdb"; then
extra_append="${extra_append} kgdboc=ttyAMA0,115200"
fi
if [ "$common_arch" = arm ]; then
cpu=cortex-a15
else
cpu=cortex-a57
fi
# highmem=off needed since v3.0.0 due to:
# http://lists.nongnu.org/archive/html/qemu-discuss/2018-08/msg00034.html
cmd="\
${qemu_common}\
-M virt,highmem=off \\
-append '${root} ${extra_append}' \\
-cpu "$cpu" \\
${virtio_gpu_pci}\
"
;;
mips64)
if ! "$ramfs"; then
root='root=/dev/hda'
extra_flags="${extra_flags}-drive 'file=${common_qcow2_file},format=qcow2${snapshot}' \\
"
fi
cmd="\
${qemu_common}\
-M malta \\
-append '${root} ${extra_append}' \\
-cpu I6400 \\
"
;;
esac
fi
if "$tmux"; then
if "$common_gem5"; then
eval "./tmu 'sleep 2;./gem5-shell -n ${common_run_id} ${tmux_args};'"
elif "$debug"; then
eval "./tmu ./rungdb -a '${common_arch} -L ${common_linux_variant}' -n ${common_run_id} ${tmux_args}"
fi
fi
if [ -n "${1:-}" ]; then
extra_flags="${extra_flags}${@} \\
"
fi
cmd="time \\
${cmd}${extra_flags}"
if [ -z "$debug_vm" ]; then
cmd="${cmd}\
|& tee >(ts -s %.s > ${common_termout_file})\
"
fi
"${common_root_dir}/eeval" "$cmd" "${common_run_dir}/run.sh"
cmd_out=$?
if [ "$cmd_out" -ne 0 ]; then
exit "$cmd_out"
fi
# Check if guest panicked.
if "$common_gem5"; then
# We have to do some parsing here because gem5 exits with status 0 even when panic happens.
#
# Grepping for '^panic: ' does not work because some errors don't show that message
panic_msg='--- BEGIN LIBC BACKTRACE ---$'
else
panic_msg='Kernel panic - not syncing'
fi
if grep -E -e "$panic_msg" -q "$common_termout_file"; then
echo 'Simulation error detected by parsing logs. Exiting with status 1.'
exit 1
fi