diff --git a/README.adoc b/README.adoc index 0dac338..8d1804c 100644 --- a/README.adoc +++ b/README.adoc @@ -14756,19 +14756,17 @@ where 120 == 0x78 (it logs addresses in decimal? Really??) and the size 4 which Now that we are here, we might as well learn how to log the data that was fetched from DRAM. -Fist we determine the expected bytes from: +Fist we determine the expected bytes from the <>: .... -./run-toolchain --arch aarch64 objdump -- \ - -D "$(./getvar --arch aarch64 userland_build_dir)/arch/aarch64/freestanding/linux/hello.out" +./disas --arch aarch64 --userland userland/arch/aarch64/freestanding/linux/hello.S _start .... which shows us the initial instruction encodings near the entry point `_start`: .... -0000000000400078 <_start>: - 400078: d2800020 mov x0, #0x1 // #1 - 40007c: 100000e1 adr x1, 400098 + 0x0000000000400078 <+0>: 20 00 80 d2 mov x0, #0x1 // #1 + 0x000000000040007c <+4>: e1 00 00 10 adr x1, 0x400098 .... Now, TODO :-) The `DRAM` logs don't contain data. Maybe this can be done with https://github.com/gem5/gem5/blob/9fc9c67b4242c03f165951775be5cd0812f2a705/src/mem/comm_monitor.hh#L55[`CommMonitor`], but it is no exposed on fs.py @@ -17874,16 +17872,10 @@ link:userland/c/atomic.c[] Demonstrates `atomic_int` and `thrd_create`. -Disassembly with GDB at LKMC 619fef4b04bddc4a5a38aec5e207dd4d5a25d206 + 1: +<> at LKMC 619fef4b04bddc4a5a38aec5e207dd4d5a25d206 + 1: .... -./run-toolchain \ - --arch aarch64 gdb \ - -- \ - -batch \ - -ex 'disas/rs my_thread_main' $(./getvar \ - --arch aarch64 userland_build_dir)/c/atomic.out \ -; +./disas --arch aarch64 --userland userland/c/atomic.c my_thread_main .... shows on ARM: @@ -24499,10 +24491,10 @@ link:userland/gcc/busy_loop.c[] The hard part is how to prevent the compiler from optimizing it away: https://stackoverflow.com/questions/7083482/how-to-prevent-gcc-from-optimizing-out-a-busy-wait-loop/58758133#58758133 -Disassembly analysis: +<> analysis: .... -./run-toolchain --arch aarch64 gdb -- -nh -batch -ex 'disas/rs busy_loop' "$(./getvar --arch aarch64 userland_build_dir)/gcc/busy_loop.out" +./disas --arch aarch64 --userland userland/gcc/busy_loop.out busy_loop .... which contains at LKMC eb22fd3b6e7fff7e9ef946a88b208debf5b419d5: @@ -25362,6 +25354,14 @@ you can save some typing and get portability across directory structure changes ./run-toolchain --arch aarch64 objdump -- -D a.out .... +This plays nicely with <> e.g. you could disassembly link:userland/c/hello.c[] with: + +.... +./run-toolchain --arch aarch64 objdump -- -D $(./getvar --arch aarch64 userland_build_dir)/c/hello.out +.... + +however disassembly is such a common use case that we have a shortcut for it: <>. + Alternatively, if you just need a variable to feed into your own Build system, you can also use <>: .... @@ -25374,12 +25374,28 @@ which outputs as of LKMC b15a0e455d691afa49f3b813ad9b09394dfb02b7: /path/to/linux-kernel-module-cheat/out/buildroot/build/default/aarch64/host/usr/bin/aarch64-buildroot-linux-gnu .... -Since disassembly of a single function with GDB is such a common use case https://stackoverflow.com/questions/22769246/how-to-disassemble-one-single-function-using-objdump[], we have a shortcut for it: +===== disas + +Since disassembly of a single function of a LKMC executable with GDB is such a common use case for <> via https://stackoverflow.com/questions/22769246/how-to-disassemble-one-single-function-using-objdump[], we have this shortcut for it. + +For example to disassemle a function from an <>: .... ./disas --arch aarch64 --userland userland/c/hello.c main .... +or to disassemble a function from the <>: + +.... +./disas --arch aarch64 start_kernel +.... + +and a <> executable: + +.... +./disas --arch aarch64 --baremetal baremetal/arch/aarch64/no_bootloader/exit.S _start +.... + === Rebuild Buildroot while running It is not possible to rebuild the root filesystem while running QEMU because QEMU holds the file qcow2 file: diff --git a/common.py b/common.py index 9badba5..852a0a0 100644 --- a/common.py +++ b/common.py @@ -1166,6 +1166,10 @@ Incompatible archs are skipped. # Image if env['baremetal']: env['image'] = self.resolve_baremetal_executable(env['baremetal'][0]) + # This is needed because the Linux kerne limage for certain emulators like QEMU + # might not be in plain ELF format, but rather some crazy compressed kernel format. + # https://cirosantilli.com/linux-kernel-module-cheat#vmlinux-vs-bzimage-vs-zimage-vs-image + env['image_elf'] = env['image'] source_path_noext = os.path.splitext(join( env['root_dir'], env['image'][len(env['baremetal_build_dir']) + 1:] @@ -1178,6 +1182,7 @@ Incompatible archs are skipped. break elif env['userland']: env['image'] = self.resolve_userland_executable(env['userland'][0]) + env['image_elf'] = env['image'] source_path_noext = os.path.splitext(join( env['userland_source_dir'], env['image'][len(env['userland_build_dir']) + 1:] @@ -1195,6 +1200,7 @@ Incompatible archs are skipped. else: if not env['_args_given']['linux_exec']: env['image'] = env['linux_image'] + env['image_elf'] = env['vmlinux'] if env['_args_given']['linux_exec']: env['image'] = env['linux_exec'] if env['emulator'] == 'gem5': diff --git a/disas b/disas index 4e65529..81014de 100755 --- a/disas +++ b/disas @@ -18,7 +18,7 @@ Disassemble one function of the given executable. https://cirosantilli.com/linux-kernel-module-cheat#run-toolchain ''', ) - self.add_argument('function', help='Which function to disassemble.') + self.add_argument('function', default='main', help='Which function to disassemble.') def timed_main(self): lkmc.import_path.import_path_main('run-toolchain')( @@ -28,7 +28,7 @@ https://cirosantilli.com/linux-kernel-module-cheat#run-toolchain '-batch', '-ex', 'disas/rs {}'.format(self.env['function']), - self.env['image'], + self.env['image_elf'], ], quiet=True, **self.get_common_args() diff --git a/run-gdb b/run-gdb index f7c90f3..9a02246 100755 --- a/run-gdb +++ b/run-gdb @@ -171,17 +171,14 @@ by default due to --continue if this breakpoint is reached. else: break_at = [] if self.env['userland']: - image = self.env['image'] linux_full_system = False if self.env['gdbserver']: before.extend([ '-ex', 'set sysroot {}'.format(self.env['buildroot_staging_dir']), ]) elif self.env['baremetal']: - image = self.env['image'] linux_full_system = False else: - image = self.env['vmlinux'] linux_full_system = True cmd = ( [self.env['gdb_path'], LF] + @@ -200,7 +197,7 @@ by default due to --continue if this breakpoint is reached. port = self.env['gdb_port'] target = 'remote localhost:{}'.format(port) cmd.extend([ - '-ex', 'file {}'.format(image), LF, + '-ex', 'file {}'.format(self.env['image_elf']), LF, '-ex', 'target {}'.format(target), LF, ]) if not self.env['kgdb']: