[RFC 1/4] dtoc: add POC for dtb shrink
Simon Glass
sjg at chromium.org
Mon Jul 6 21:21:54 CEST 2020
Hi Walter,
On Fri, 19 Jun 2020 at 15:11, Walter Lozano <walter.lozano at collabora.com> wrote:
>
> Based on several reports and discussions [1], [2] it is clear that U-Boot's
> footprint is always a concern, and any kind of reduction is an
> improvement.
>
> In particular dtb is one of the sources of footprint increment, as
> U-Boot uses the same dtb as Linux. However is interesting to note that
> U-Boot does not require all the nodes and properties declared in it.
> Some improvements in this sense are already present, such as
> removing properties based on configuration and using specific "u-boot"
> properties to keep only specific node in SPL. However, this require
> manual configuration.
>
> Additionally reducing dtb, will allow ATF for better handing FDT buffer, which
> is an issue in some contexts [3].
>
> In order to improve this situation, this patch adds a proof of concept
> for dtb shrink. The idea behind this is simple, remove all the nodes
> from dtb which compatible string is not supported by any driver present.
> This approach makes sense for those configuration where Linux is
> expected to have its own dtb.
>
> This patch is based on the work of Simon Glass present in [4] which adds
> support to dtoc for parsing compatible strings.
>
> Some early untested results shows that the reduction in size is 50 % in
> case of mx6_cuboxi_defconfig, which is promising.
>
> Some additional reduction could be possible by only keeping the nodes for
> whose compatible string is supported by any enabled driver. However,
> this requires to add extra logic to parse config files and map
> configuration to compatible strings.
>
> This proof of concept uses fdtgrep to implement the node removal, but
> the idea is to implement this logic inside the dtoc for better handling.
>
> [1] http://patchwork.ozlabs.org/project/uboot/patch/20200525093539.1.Ibf2d19439cde35e39192a9d4a8dad23539fae2e6@changeid/
> [2] http://u-boot.10912.n7.nabble.com/PATCH-v1-00-15-add-basic-driver-support-for-broadcom-NS3-soc-tt412411.html#none
> [3] https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/4512
> [4] https://gitlab.denx.de/u-boot/custodians/u-boot-dm/-/tree/dtoc-working
>
> Signed-off-by: Walter Lozano <walter.lozano at collabora.com>
> ---
> tools/dtoc/dtb_platdata.py | 42 +++++++++++++++++++++++++++++++++++---
> 1 file changed, 39 insertions(+), 3 deletions(-)
>
> diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
> index 21cce5afb5..1df13b2cd2 100644
> --- a/tools/dtoc/dtb_platdata.py
> +++ b/tools/dtoc/dtb_platdata.py
> @@ -399,7 +399,10 @@ class DtbPlatdata(object):
> """Scan the driver folders to build a list of driver names and possible
> aliases
> """
> - for (dirpath, dirnames, filenames) in os.walk('/home/sglass/u'):
> + basedir = sys.argv[0].replace('tools/dtoc/dtoc', '')
Instead of this logic, can we pass the source-tree location into dtoc
with a flag? It could default to the current dir perhaps.
> + if basedir == '':
> + basedir = './'
> + for (dirpath, dirnames, filenames) in os.walk(basedir):
> for fn in filenames:
> if not fn.endswith('.c'):
> continue
> @@ -802,6 +805,32 @@ class DtbPlatdata(object):
> self.out(''.join(self.get_buf()))
> self.close_output()
>
> + def shrink(self):
> + """Generate a shrunk version of DTB bases on valid drivers
> +
> + This function removes nodes from dtb which compatible string is not
> + found in drivers. The output is saved in a file with suffix name -shrink.dtb
> + """
> + compat = []
> + cmd = './tools/fdtgrep '
> + #print(self._drivers)
> + for dr in self._drivers.values():
> + compat = compat + dr.compat
> +
> + for cp in compat:
> + #print(cp)
> + cmd += ' -c ' + cp
> +
> + cmd += ' -O dtb -o ' + self._dtb_fname.replace('.dtb', '') + '-shrink.dtb ' + self._dtb_fname
> +
> + if False:
> + with open('dt_shrink.sh', 'w+') as script:
> + script.write(cmd)
> +
> + os.system(cmd)
> +
> + return
> +
> def run_steps(args, dtb_file, config_file, include_disabled, output):
> """Run all the steps of the dtoc tool
>
> @@ -816,6 +845,10 @@ def run_steps(args, dtb_file, config_file, include_disabled, output):
> if not args:
> raise ValueError('Please specify a command: struct, platdata')
>
> + skip_scan = False
> + if args == ['shrink']:
> + skip_scan = True
I think that would be better as a positive variable, like 'scan'.
> +
> plat = DtbPlatdata(dtb_file, config_file, include_disabled)
> plat.scan_drivers()
> plat.scan_dtb()
> @@ -823,14 +856,17 @@ def run_steps(args, dtb_file, config_file, include_disabled, output):
> plat.scan_config()
> plat.scan_reg_sizes()
Are those two needed with this new command?
> plat.setup_output(output)
> - structs = plat.scan_structs()
> - plat.scan_phandles()
> + if not skip_scan:
> + structs = plat.scan_structs()
> + plat.scan_phandles()
>
> for cmd in args[0].split(','):
> if cmd == 'struct':
> plat.generate_structs(structs)
> elif cmd == 'platdata':
> plat.generate_tables()
> + elif cmd == 'shrink':
> + plat.shrink()
> else:
> raise ValueError("Unknown command '%s': (use: struct, platdata)" %
> cmd)
> --
> 2.20.1
>
Regards,
Simon
More information about the U-Boot
mailing list