diff --git a/README.adoc b/README.adoc index a774d4f..f93e4f2 100644 --- a/README.adoc +++ b/README.adoc @@ -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)" .... -TODO: `arm` boot broken on kernel 4.18 with: - -.... -Internal error: Oops - undefined instruction -.... - -Workaround by checking out kernel 4.17 as explained at <>. Bisected down to kernel 1d4238c56f9816ce0f9c8dbe42d7f2ad81cb6613, gem5 is not implementing the `CSDB` instruction. - More gem5 information is present at: <> Good next steps are: @@ -2501,6 +2493,8 @@ where `$$` is the PID of the shell itself: https://stackoverflow.com/questions/2 == 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 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 <> to break at the `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. -.... -warn: Kernel panic in simulated kernel -.... +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! -before hanging forever. - -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: +TODO: why doesn't x86 support it as well? Trying to set `system.panic_on_panic` there fails with: .... 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(); } @@ -4670,7 +4659,7 @@ abortHandler(int sigtype) 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( diff --git a/patches/manual/gem5-panic.patch b/patches/manual/gem5-panic.patch deleted file mode 100644 index 301f053..0000000 --- a/patches/manual/gem5-panic.patch +++ /dev/null @@ -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) diff --git a/run b/run index 3b05bf3..baebcf2 100755 --- a/run +++ b/run @@ -145,26 +145,27 @@ def main(args, extra_args=None): cpt_dirs = common.gem_list_checkpoint_dirs() cpt_dir = cpt_dirs[-args.gem5_restore] extra_emulator_args.extend(['-r', str(sorted(cpt_dirs).index(cpt_dir) + 1)]) - cmd += [ + cmd.extend([ common.gem5_fs_file, '--disk-image', common.disk_image, '--kernel', common.image, '--mem-size', memory, '--num-cpus', str(args.cpus), '--script', common.gem5_readfile, - ] + ]) if args.arch == 'x86_64': if args.kvm: - cmd += ['--cpu-type', 'X86KvmCPU'] - cmd += ['--command-line', 'earlyprintk=ttyS0 console=ttyS0 lpj=7999923 root=/dev/sda {}'.format(kernel_cli)] + cmd.extend(['--cpu-type', 'X86KvmCPU']) + cmd.extend(['--command-line', 'earlyprintk=ttyS0 console=ttyS0 lpj=7999923 root=/dev/sda {}'.format(kernel_cli)]) elif args.arch == 'arm' or args.arch == 'aarch64': # 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? - cmd += [ + cmd.extend([ '--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)), '--machine-type', common.machine, - ] + '--param', 'system.panic_on_panic = True', + ]) if not args.baremetal is None: cmd.append('--bare-metal') if args.arch == 'aarch64': @@ -175,7 +176,7 @@ def main(args, extra_args=None): if args.gem5_restore is not None: cpt_dir = common.gem_list_checkpoint_dirs()[-args.gem5_restore] 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'), '--big-cpus', '2', '--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'), '--kernel', common.image, '--little-cpus', '2' - ] + ]) elif args.gem5_script == 'se': 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: # 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: if not os.path.exists(common.image): raise_image_not_found()