Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S964949AbcJRPsL (ORCPT ); Tue, 18 Oct 2016 11:48:11 -0400 Received: from goliath.siemens.de ([192.35.17.28]:46832 "EHLO goliath.siemens.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S964865AbcJRPsG (ORCPT ); Tue, 18 Oct 2016 11:48:06 -0400 Subject: Re: [PATCH 1/2] scripts/gdb: add lx-fdtdump command To: Peter Griffin , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kernel@stlinux.com, kieran@ksquared.org.uk References: <1476803249-23328-1-git-send-email-peter.griffin@linaro.org> Cc: lee.jones@linaro.org, devicetree@vger.kernel.org From: Jan Kiszka Message-ID: Date: Tue, 18 Oct 2016 17:47:22 +0200 User-Agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); de; rv:1.8.1.12) Gecko/20080226 SUSE/2.0.0.12-1.1 Thunderbird/2.0.0.12 Mnenhy/0.7.5.666 MIME-Version: 1.0 In-Reply-To: <1476803249-23328-1-git-send-email-peter.griffin@linaro.org> Content-Type: text/plain; charset=iso-8859-15 Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5291 Lines: 148 On 2016-10-18 17:07, Peter Griffin wrote: > lx-fdtdump dumps the flatenned device tree passed to the kernel > from the bootloader to a file called fdtdump.dtb to allow 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. > > Signed-off-by: Peter Griffin > --- > scripts/gdb/linux/constants.py.in | 8 +++++ > scripts/gdb/linux/proc.py | 70 ++++++++++++++++++++++++++++++++++++++- > 2 files changed, 77 insertions(+), 1 deletion(-) > > diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in > index 7986f4e..43c6241 100644 > --- a/scripts/gdb/linux/constants.py.in > +++ b/scripts/gdb/linux/constants.py.in > @@ -14,6 +14,7 @@ > > #include > #include > +#include > > /* We need to stringify expanded macros so that they can be parsed */ > > @@ -50,3 +51,10 @@ 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) > + > diff --git a/scripts/gdb/linux/proc.py b/scripts/gdb/linux/proc.py > index 38b1f09..f20fcfa 100644 > --- a/scripts/gdb/linux/proc.py > +++ b/scripts/gdb/linux/proc.py > @@ -16,7 +16,7 @@ from linux import constants > from linux import utils > from linux import tasks > from linux import lists > - > +from struct import * > > class LxCmdLine(gdb.Command): > """ Report the Linux Commandline used in the current kernel. > @@ -195,3 +195,71 @@ values of that process namespace""" > info_opts(MNT_INFO, m_flags))) > > LxMounts() > + > +class LxFdtDump(gdb.Command): > + """Output Flattened Device Tree header and dump FDT blob to a file > + Equivalent to 'cat /proc/fdt > fdtdump.dtb' on a running target""" > + > + def __init__(self): > + super(LxFdtDump, self).__init__("lx-fdtdump", gdb.COMMAND_DATA) > + > + def fdthdr_to_cpu(self, fdt_header): > + > + fdt_header_be = ">IIIIIII" > + fdt_header_le = " + > + 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 constants.LX_CONFIG_OF: > + > + filename = "fdtdump.dtb" Why not specifying the file name as argument? Safer than silently overwriting potentially pre-existing files or failing without alternatives if the current directory is not writable. > + > + 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 to " + filename + "\n") > + > + else: > + gdb.write("Kernel not compiled with CONFIG_OF\n") > + > +LxFdtDump() > Jan -- Siemens AG, Corporate Technology, CT RDA ITP SES-DE Corporate Competence Center Embedded Linux