trace-boot 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. #!/usr/bin/env python3
  2. from shell_helpers import LF
  3. import common
  4. import lkmc.import_path
  5. class Main(common.LkmcCliFunction):
  6. def __init__(self):
  7. super().__init__(
  8. description='''Trace the PIC addresses executed on a Linux kernel boot.
  9. More information at: https://cirosantilli.com/linux-kernel-module-cheat#tracing
  10. '''
  11. )
  12. def timed_main(self):
  13. args = self.get_common_args()
  14. run = lkmc.import_path.import_path_main('run')
  15. if self.env['emulator'] == 'gem5':
  16. args['trace'] = 'Exec,-ExecSymbol,-ExecMicro'
  17. run(**args)
  18. elif self.env['emulator'] == 'qemu':
  19. run_args = args.copy()
  20. run_args['trace'] = 'exec_tb'
  21. run_args['quit_after_boot'] = True
  22. run(**run_args)
  23. qemu_trace2txt = lkmc.import_path.import_path_main('qemu-trace2txt')
  24. qemu_trace2txt(**args)
  25. # Instruction count.
  26. # We could put this on a separate script, but it just adds more arch boilerplate to a new script.
  27. # So let's just leave it here for now since it did not add a significant processing time.
  28. kernel_entry_addr = hex(self.get_elf_entry(self.env['vmlinux']))
  29. nlines = 0
  30. nlines_firmware = 0
  31. with open(self.env['qemu_trace_txt_file'], 'r') as trace_file:
  32. in_firmware = True
  33. for line in trace_file:
  34. line = line.rstrip()
  35. nlines += 1
  36. pc = line.split('=')[-1]
  37. if pc == kernel_entry_addr:
  38. in_firmware = False
  39. if in_firmware:
  40. nlines_firmware += 1
  41. print('''\
  42. instructions {}
  43. entry_address {}
  44. instructions_firmware {}
  45. '''.format(
  46. nlines,
  47. kernel_entry_addr,
  48. nlines_firmware
  49. ),
  50. end=''
  51. )
  52. if __name__ == '__main__':
  53. Main().cli()