common/recipes-utils/vboot-utils/files/memdump.py (74 lines of code) (raw):

#!/usr/bin/env python3 # # Copyright 2022-present Facebook. All Rights Reserved. # # This program file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License # along with this program in a file named COPYING; if not, write to the # Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301 USA # import argparse import mmap import os import sys import traceback VERSION = 1 EC_SUCCESS = 0 EC_EXCEPT = 255 def page_align_down(addr): return (addr >> 12) << 12 def page_align_up(addr): return ((addr + (1 << 12) - 1) >> 12) << 12 def dump_data(mm, base, start, end): n = 16 cur = start while cur < end: n = n if cur + n < end else end - cur data = mm[cur : cur + n] print(f"{base + cur:#08x}: ", " ".join([f"{b:02x}" for b in data])) cur += n def main(addr, len, binary): try: memfn = None map_base = page_align_down(addr) map_size = page_align_up(addr + len) - map_base data_off = addr - map_base memfn = os.open("/dev/mem", os.O_RDONLY | os.O_SYNC) with mmap.mmap( memfn, map_size, mmap.MAP_SHARED, mmap.PROT_READ, offset=map_base, ) as mm: if binary: sys.stdout.buffer.write(mm[data_off : data_off + len]) else: dump_data(mm, map_base, data_off, data_off + len) finally: if memfn is not None: os.close(memfn) return EC_SUCCESS if __name__ == "__main__": parser = argparse.ArgumentParser(description="dump the physical memory") parser.add_argument( "--version", action="version", version="%(prog)s-v{}".format(VERSION), ) parser.add_argument( "addr", type=lambda x: int(x, 0), help="physical memory address", ) parser.add_argument( "len", nargs="?", type=lambda x: int(x, 0), default=16, help="dump length in bytes, default 16", ) parser.add_argument( "-b", "--binary", action="store_true", help="out put as raw binary can pipe feed to hexdump", ) args = parser.parse_args() try: sys.exit(main(args.addr, args.len, args.binary)) except Exception as e: print("Exception: %s" % (str(e))) traceback.print_exc() sys.exit(EC_EXCEPT)