gem5: document that arm v4.18 kernel boot was fixed

Fixed by gem5 commit 33b311d8d8b8d527d500d62a35b50be63e41b556

Automatically pass parnic_on_panic for archs that support it.
This commit is contained in:
Ciro Santilli 六四事件 法轮功
2018-10-28 00:00:01 +00:00
parent ceb64ab8e1
commit 11fedc6045
3 changed files with 28 additions and 49 deletions

View File

@@ -408,14 +408,6 @@ If you forgot to open the shell and gem5 exit, you can inspect the terminal outp
less "$(./getvar --gem5 termout_file)" less "$(./getvar --gem5 termout_file)"
.... ....
TODO: `arm` boot broken on kernel 4.18 with:
....
Internal error: Oops - undefined instruction
....
Workaround by checking out kernel 4.17 as explained at <<linux-kernel-build-variants>>. Bisected down to kernel 1d4238c56f9816ce0f9c8dbe42d7f2ad81cb6613, gem5 is not implementing the `CSDB` instruction.
More gem5 information is present at: <<gem5>> More gem5 information is present at: <<gem5>>
Good next steps are: Good next steps are:
@@ -2501,6 +2493,8 @@ where `$$` is the PID of the shell itself: https://stackoverflow.com/questions/2
== initrd == initrd
TODO: broken, get working.
The kernel can boot from an CPIO file, which is a directory serialization format much like tar: https://superuser.com/questions/343915/tar-vs-cpio-what-is-the-difference The kernel can boot from an CPIO file, which is a directory serialization format much like tar: https://superuser.com/questions/343915/tar-vs-cpio-what-is-the-difference
The bootloader, which for us is QEMU itself, is then configured to put that CPIO into memory, and tell the kernel that it is there. The bootloader, which for us is QEMU itself, is then configured to put that CPIO into memory, and tell the kernel that it is there.
@@ -4618,32 +4612,27 @@ One possibility that gets close would be to use <<gdb>> to break at the `panic`
====== Exit gem5 on panic ====== Exit gem5 on panic
gem5 actually detects panics and outputs: gem5 actually detects panics automatically by parsing kernel symbols and detecting when the PC reaches the address of the `panic` function.
.... We enable the `system.panic_on_panic` option by default on `arm` and `aarch64`, which makes gem5 exit immediately in case of panic, which is awesome!
warn: Kernel panic in simulated kernel
....
before hanging forever. TODO: why doesn't x86 support it as well? Trying to set `system.panic_on_panic` there fails with:
We can make gem5 ff52563a214c71fcd1e21e9f00ad839612032e3b `fs.py` quit instead of hang with `system.panic_on_panic`:
....
patch -d "$(./getvar gem5_src_dir)" -p1 < patches/manual/gem5-panic.patch
./run --arch arm --eval-busybox 'echo c > /proc/sysrq-trigger' --gem5
....
Source: link:patches/manual/gem5-panic.patch[].
It does not seem to be exposed to `fs.py`.
TODO: fs.py x86 does not have it:
.... ....
AttributeError: Class LinuxX86System has no parameter panic_on_panic AttributeError: Class LinuxX86System has no parameter panic_on_panic
.... ....
However TODO it still exits with status 0... so we are just parsing the logs for now, as for QEMU. This seems to happen because the abort that is used to quit at link:https://github.com/gem5/gem5/blob/ff52563a214c71fcd1e21e9f00ad839612032e3b/src/base/logging.hh#L124[src/base/logging.hh]: If we don't set `system.panic_on_panic`, then gem5 prints to:
....
warn: Kernel panic in simulated kernel
....
and then hanging forever.
TODO however, even with `system.panic_on_panic` the gem5 exit status is still 0... so we are just parsing the logs for now, as for QEMU.
This seems to happen because the abort that is used to quit at link:https://github.com/gem5/gem5/blob/ff52563a214c71fcd1e21e9f00ad839612032e3b/src/base/logging.hh#L124[src/base/logging.hh]:
.... ....
void exit_helper() M5_ATTR_NORETURN { exit(); ::abort(); } void exit_helper() M5_ATTR_NORETURN { exit(); ::abort(); }
@@ -4670,7 +4659,7 @@ abortHandler(int sigtype)
Raised on the mailing list at: https://www.mail-archive.com/gem5-users@gem5.org/msg15863.html Raised on the mailing list at: https://www.mail-archive.com/gem5-users@gem5.org/msg15863.html
Detection seems to be symbol based: it parses the kernel image, and triggers when the PC reaches the address of a symbol: https://github.com/gem5/gem5/blob/1da285dfcc31b904afc27e440544d006aae25b38/src/arch/arm/linux/system.cc#L73 The implementation of panic detection happens at: https://github.com/gem5/gem5/blob/1da285dfcc31b904afc27e440544d006aae25b38/src/arch/arm/linux/system.cc#L73
.... ....
kernelPanicEvent = addKernelFuncEventOrPanic<Linux::KernelPanicEvent>( kernelPanicEvent = addKernelFuncEventOrPanic<Linux::KernelPanicEvent>(

View File

@@ -1,11 +0,0 @@
diff --git a/configs/example/fs.py b/configs/example/fs.py
index 4031fd05e..0f502a34a 100644
--- a/configs/example/fs.py
+++ b/configs/example/fs.py
@@ -395,5 +395,6 @@ if buildEnv['TARGET_ISA'] == "arm" and options.generate_dtb:
sys = getattr(root, sysname)
sys.dtb_filename = create_dtb_for_system(sys, '%s.dtb' % sysname)
+test_sys.panic_on_panic = True
Simulation.setWorkCountOptions(test_sys, options)
Simulation.run(options, root, test_sys, FutureClass)

21
run
View File

@@ -145,26 +145,27 @@ def main(args, extra_args=None):
cpt_dirs = common.gem_list_checkpoint_dirs() cpt_dirs = common.gem_list_checkpoint_dirs()
cpt_dir = cpt_dirs[-args.gem5_restore] cpt_dir = cpt_dirs[-args.gem5_restore]
extra_emulator_args.extend(['-r', str(sorted(cpt_dirs).index(cpt_dir) + 1)]) extra_emulator_args.extend(['-r', str(sorted(cpt_dirs).index(cpt_dir) + 1)])
cmd += [ cmd.extend([
common.gem5_fs_file, common.gem5_fs_file,
'--disk-image', common.disk_image, '--disk-image', common.disk_image,
'--kernel', common.image, '--kernel', common.image,
'--mem-size', memory, '--mem-size', memory,
'--num-cpus', str(args.cpus), '--num-cpus', str(args.cpus),
'--script', common.gem5_readfile, '--script', common.gem5_readfile,
] ])
if args.arch == 'x86_64': if args.arch == 'x86_64':
if args.kvm: if args.kvm:
cmd += ['--cpu-type', 'X86KvmCPU'] cmd.extend(['--cpu-type', 'X86KvmCPU'])
cmd += ['--command-line', 'earlyprintk=ttyS0 console=ttyS0 lpj=7999923 root=/dev/sda {}'.format(kernel_cli)] cmd.extend(['--command-line', 'earlyprintk=ttyS0 console=ttyS0 lpj=7999923 root=/dev/sda {}'.format(kernel_cli)])
elif args.arch == 'arm' or args.arch == 'aarch64': elif args.arch == 'arm' or args.arch == 'aarch64':
# TODO why is it mandatory to pass mem= here? Not true for QEMU. # TODO why is it mandatory to pass mem= here? Not true for QEMU.
# Anything smaller than physical blows up as expected, but why can't it auto-detect the right value? # Anything smaller than physical blows up as expected, but why can't it auto-detect the right value?
cmd += [ cmd.extend([
'--command-line', 'earlyprintk=pl011,0x1c090000 console=ttyAMA0 lpj=19988480 rw loglevel=8 mem={} root=/dev/sda {}'.format(memory, kernel_cli), '--command-line', 'earlyprintk=pl011,0x1c090000 console=ttyAMA0 lpj=19988480 rw loglevel=8 mem={} root=/dev/sda {}'.format(memory, kernel_cli),
'--dtb-filename', os.path.join(common.gem5_system_dir, 'arm', 'dt', 'armv{}_gem5_v1_{}cpu.dtb'.format(common.armv, args.cpus)), '--dtb-filename', os.path.join(common.gem5_system_dir, 'arm', 'dt', 'armv{}_gem5_v1_{}cpu.dtb'.format(common.armv, args.cpus)),
'--machine-type', common.machine, '--machine-type', common.machine,
] '--param', 'system.panic_on_panic = True',
])
if not args.baremetal is None: if not args.baremetal is None:
cmd.append('--bare-metal') cmd.append('--bare-metal')
if args.arch == 'aarch64': if args.arch == 'aarch64':
@@ -175,7 +176,7 @@ def main(args, extra_args=None):
if args.gem5_restore is not None: if args.gem5_restore is not None:
cpt_dir = common.gem_list_checkpoint_dirs()[-args.gem5_restore] cpt_dir = common.gem_list_checkpoint_dirs()[-args.gem5_restore]
extra_emulator_args.extend(['--restore-from', os.path.join(common.m5out_dir, cpt_dir)]) extra_emulator_args.extend(['--restore-from', os.path.join(common.m5out_dir, cpt_dir)])
cmd += [ cmd.extend([
os.path.join(common.gem5_src_dir, 'configs', 'example', 'arm', 'fs_bigLITTLE.py'), os.path.join(common.gem5_src_dir, 'configs', 'example', 'arm', 'fs_bigLITTLE.py'),
'--big-cpus', '2', '--big-cpus', '2',
'--cpu-type', 'atomic', '--cpu-type', 'atomic',
@@ -183,13 +184,13 @@ def main(args, extra_args=None):
'--dtb', os.path.join(common.gem5_system_dir, 'arm', 'dt', 'armv8_gem5_v1_big_little_2_2.dtb'), '--dtb', os.path.join(common.gem5_system_dir, 'arm', 'dt', 'armv8_gem5_v1_big_little_2_2.dtb'),
'--kernel', common.image, '--kernel', common.image,
'--little-cpus', '2' '--little-cpus', '2'
] ])
elif args.gem5_script == 'se': elif args.gem5_script == 'se':
assert(args.exec_image is not None) assert(args.exec_image is not None)
cmd += [common.gem5_se_file, '-c', args.exec_image] cmd.extend([common.gem5_se_file, '-c', args.exec_image])
if args.debug_guest: if args.debug_guest:
# https://stackoverflow.com/questions/49296092/how-to-make-gem5-wait-for-gdb-to-connect-to-reliably-break-at-start-kernel-of-th # https://stackoverflow.com/questions/49296092/how-to-make-gem5-wait-for-gdb-to-connect-to-reliably-break-at-start-kernel-of-th
cmd += ['--param', 'system.cpu[0].wait_for_remote_gdb = True'] cmd.extend(['--param', 'system.cpu[0].wait_for_remote_gdb = True'])
else: else:
if not os.path.exists(common.image): if not os.path.exists(common.image):
raise_image_not_found() raise_image_not_found()