Skip to content

Commit

Permalink
scripts/gdb: add lx-fdtdump command
Browse files Browse the repository at this point in the history
lx-fdtdump dumps the flattened device tree passed to the kernel from the
bootloader to the filename specified as the command argument.  If no
argument is provided it defaults to fdtdump.dtb.  This then allows
further post processing on the machine running GDB.  The fdt header is
also also printed in the GDB console.  For example:

  (gdb) lx-fdtdump
  fdt_magic:         0xD00DFEED
  fdt_totalsize:     0xC108
  off_dt_struct:     0x38
  off_dt_strings:    0x3804
  off_mem_rsvmap:    0x28
  version:           17
  last_comp_version: 16
  Dumped fdt to fdtdump.dtb

  >fdtdump fdtdump.dtb | less

This command is useful as the bootloader can often re-write parts of the
device tree, and this can sometimes cause the kernel to not boot.

Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Peter Griffin <[email protected]>
Signed-off-by: Kieran Bingham <[email protected]>
Cc: Jason Wessel <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
petegriffin authored and torvalds committed Jul 12, 2017
1 parent 59224ac commit 821f744
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 0 deletions.
7 changes: 7 additions & 0 deletions scripts/gdb/linux/constants.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include <linux/fs.h>
#include <linux/mount.h>
#include <linux/of_fdt.h>

/* We need to stringify expanded macros so that they can be parsed */

Expand Down Expand Up @@ -50,3 +51,9 @@ LX_VALUE(MNT_NOEXEC)
LX_VALUE(MNT_NOATIME)
LX_VALUE(MNT_NODIRATIME)
LX_VALUE(MNT_RELATIME)

/* linux/of_fdt.h> */
LX_VALUE(OF_DT_HEADER)

/* Kernel Configs */
LX_CONFIG(CONFIG_OF)
73 changes: 73 additions & 0 deletions scripts/gdb/linux/proc.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from linux import utils
from linux import tasks
from linux import lists
from struct import *


class LxCmdLine(gdb.Command):
Expand Down Expand Up @@ -195,3 +196,75 @@ def invoke(self, arg, from_tty):
info_opts(MNT_INFO, m_flags)))

LxMounts()


class LxFdtDump(gdb.Command):
"""Output Flattened Device Tree header and dump FDT blob to the filename
specified as the command argument. Equivalent to
'cat /proc/fdt > fdtdump.dtb' on a running target"""

def __init__(self):
super(LxFdtDump, self).__init__("lx-fdtdump", gdb.COMMAND_DATA,
gdb.COMPLETE_FILENAME)

def fdthdr_to_cpu(self, fdt_header):

fdt_header_be = ">IIIIIII"
fdt_header_le = "<IIIIIII"

if utils.get_target_endianness() == 1:
output_fmt = fdt_header_le
else:
output_fmt = fdt_header_be

return unpack(output_fmt, pack(fdt_header_be,
fdt_header['magic'],
fdt_header['totalsize'],
fdt_header['off_dt_struct'],
fdt_header['off_dt_strings'],
fdt_header['off_mem_rsvmap'],
fdt_header['version'],
fdt_header['last_comp_version']))

def invoke(self, arg, from_tty):

if not constants.LX_CONFIG_OF:
raise gdb.GdbError("Kernel not compiled with CONFIG_OF\n")

if len(arg) == 0:
filename = "fdtdump.dtb"
else:
filename = arg

py_fdt_header_ptr = gdb.parse_and_eval(
"(const struct fdt_header *) initial_boot_params")
py_fdt_header = py_fdt_header_ptr.dereference()

fdt_header = self.fdthdr_to_cpu(py_fdt_header)

if fdt_header[0] != constants.LX_OF_DT_HEADER:
raise gdb.GdbError("No flattened device tree magic found\n")

gdb.write("fdt_magic: 0x{:02X}\n".format(fdt_header[0]))
gdb.write("fdt_totalsize: 0x{:02X}\n".format(fdt_header[1]))
gdb.write("off_dt_struct: 0x{:02X}\n".format(fdt_header[2]))
gdb.write("off_dt_strings: 0x{:02X}\n".format(fdt_header[3]))
gdb.write("off_mem_rsvmap: 0x{:02X}\n".format(fdt_header[4]))
gdb.write("version: {}\n".format(fdt_header[5]))
gdb.write("last_comp_version: {}\n".format(fdt_header[6]))

inf = gdb.inferiors()[0]
fdt_buf = utils.read_memoryview(inf, py_fdt_header_ptr,
fdt_header[1]).tobytes()

try:
f = open(filename, 'wb')
except:
raise gdb.GdbError("Could not open file to dump fdt")

f.write(fdt_buf)
f.close()

gdb.write("Dumped fdt blob to " + filename + "\n")

LxFdtDump()

0 comments on commit 821f744

Please sign in to comment.