binman: Allow different operations in FIT generator nodes

At present we only support expanding out FDT nodes. Make the operation
into an @operation property, so that others can be supported.

Re-arrange and tidy up the documentation so that it has separate
headings for each topic.

Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass 2022-02-08 11:50:03 -07:00
parent 98e0de3fb7
commit 6a0b5f8b9c
5 changed files with 274 additions and 49 deletions

View file

@ -553,6 +553,68 @@ For example, this creates an image containing a FIT with U-Boot SPL::
};
};
More complex setups can be created, with generated nodes, as described
below.
Properties (in the 'fit' node itself)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Special properties have a `fit,` prefix, indicating that they should be
processed but not included in the final FIT.
The top-level 'fit' node supports the following special properties:
fit,external-offset
Indicates that the contents of the FIT are external and provides the
external offset. This is passed to mkimage via the -E and -p flags.
fit,fdt-list
Indicates the entry argument which provides the list of device tree
files for the gen-fdt-nodes operation (as below). This is often
`of-list` meaning that `-a of-list="dtb1 dtb2..."` should be passed
to binman.
Substitutions
~~~~~~~~~~~~~
Node names and property values support a basic string-substitution feature.
Available substitutions for '@' nodes (and property values) are:
SEQ:
Sequence number of the generated fdt (1, 2, ...)
NAME
Name of the dtb as provided (i.e. without adding '.dtb')
The `default` property, if present, will be automatically set to the name
if of configuration whose devicetree matches the `default-dt` entry
argument, e.g. with `-a default-dt=sun50i-a64-pine64-lts`.
Available substitutions for property values in these nodes are:
DEFAULT-SEQ:
Sequence number of the default fdt, as provided by the 'default-dt'
entry argument
Available operations
~~~~~~~~~~~~~~~~~~~~
You can add an operation to an '@' node to indicate which operation is
required::
@fdt-SEQ {
fit,operation = "gen-fdt-nodes";
...
};
Available operations are:
gen-fdt-nodes
Generate FDT nodes as above. This is the default if there is no
`fit,operation` property.
Generating nodes from an FDT list (gen-fdt-nodes)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
U-Boot supports creating fdt and config nodes automatically. To do this,
pass an `of-list` property (e.g. `-a of-list=file1 file2`). This tells
binman that you want to generates nodes for two files: `file1.dtb` and
@ -590,32 +652,9 @@ You can create config nodes in a similar way::
This tells binman to create nodes `config-1` and `config-2`, i.e. a config
for each of your two files.
Available substitutions for '@' nodes are:
SEQ:
Sequence number of the generated fdt (1, 2, ...)
NAME
Name of the dtb as provided (i.e. without adding '.dtb')
Note that if no devicetree files are provided (with '-a of-list' as above)
then no nodes will be generated.
The 'default' property, if present, will be automatically set to the name
if of configuration whose devicetree matches the 'default-dt' entry
argument, e.g. with '-a default-dt=sun50i-a64-pine64-lts'.
Available substitutions for '@' property values are
DEFAULT-SEQ:
Sequence number of the default fdt,as provided by the 'default-dt' entry
argument
Properties (in the 'fit' node itself):
fit,external-offset: Indicates that the contents of the FIT are external
and provides the external offset. This is passsed to mkimage via
the -E and -p flags.
Entry: fmap: An entry which contains an Fmap section

View file

@ -14,7 +14,14 @@ from dtoc import fdt_util
from dtoc.fdt import Fdt
from patman import tools
# Supported operations, with the fit,operation property
OP_GEN_FDT_NODES = range(1)
OPERATIONS = {
'gen-fdt-nodes': OP_GEN_FDT_NODES,
}
class Entry_fit(Entry_section):
"""Flat Image Tree (FIT)
This calls mkimage to create a FIT (U-Boot Flat Image Tree) based on the
@ -47,6 +54,68 @@ class Entry_fit(Entry_section):
};
};
More complex setups can be created, with generated nodes, as described
below.
Properties (in the 'fit' node itself)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Special properties have a `fit,` prefix, indicating that they should be
processed but not included in the final FIT.
The top-level 'fit' node supports the following special properties:
fit,external-offset
Indicates that the contents of the FIT are external and provides the
external offset. This is passed to mkimage via the -E and -p flags.
fit,fdt-list
Indicates the entry argument which provides the list of device tree
files for the gen-fdt-nodes operation (as below). This is often
`of-list` meaning that `-a of-list="dtb1 dtb2..."` should be passed
to binman.
Substitutions
~~~~~~~~~~~~~
Node names and property values support a basic string-substitution feature.
Available substitutions for '@' nodes (and property values) are:
SEQ:
Sequence number of the generated fdt (1, 2, ...)
NAME
Name of the dtb as provided (i.e. without adding '.dtb')
The `default` property, if present, will be automatically set to the name
if of configuration whose devicetree matches the `default-dt` entry
argument, e.g. with `-a default-dt=sun50i-a64-pine64-lts`.
Available substitutions for property values in these nodes are:
DEFAULT-SEQ:
Sequence number of the default fdt, as provided by the 'default-dt'
entry argument
Available operations
~~~~~~~~~~~~~~~~~~~~
You can add an operation to an '@' node to indicate which operation is
required::
@fdt-SEQ {
fit,operation = "gen-fdt-nodes";
...
};
Available operations are:
gen-fdt-nodes
Generate FDT nodes as above. This is the default if there is no
`fit,operation` property.
Generating nodes from an FDT list (gen-fdt-nodes)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
U-Boot supports creating fdt and config nodes automatically. To do this,
pass an `of-list` property (e.g. `-a of-list=file1 file2`). This tells
binman that you want to generates nodes for two files: `file1.dtb` and
@ -84,31 +153,8 @@ class Entry_fit(Entry_section):
This tells binman to create nodes `config-1` and `config-2`, i.e. a config
for each of your two files.
Available substitutions for '@' nodes are:
SEQ:
Sequence number of the generated fdt (1, 2, ...)
NAME
Name of the dtb as provided (i.e. without adding '.dtb')
Note that if no devicetree files are provided (with '-a of-list' as above)
then no nodes will be generated.
The 'default' property, if present, will be automatically set to the name
if of configuration whose devicetree matches the 'default-dt' entry
argument, e.g. with '-a default-dt=sun50i-a64-pine64-lts'.
Available substitutions for '@' property values are
DEFAULT-SEQ:
Sequence number of the default fdt,as provided by the 'default-dt' entry
argument
Properties (in the 'fit' node itself):
fit,external-offset: Indicates that the contents of the FIT are external
and provides the external offset. This is passsed to mkimage via
the -E and -p flags.
"""
def __init__(self, section, etype, node):
"""
@ -142,6 +188,26 @@ class Entry_fit(Entry_section):
self.ReadEntries()
super().ReadNode()
def _get_operation(self, subnode):
"""Get the operation referenced by a subnode
Args:
subnode (Node): Subnode (of the FIT) to check
Returns:
int: Operation to perform
Raises:
ValueError: Invalid operation name
"""
oper_name = subnode.props.get('fit,operation')
if not oper_name:
return OP_GEN_FDT_NODES
oper = OPERATIONS.get(oper_name.value)
if not oper:
self.Raise(f"Unknown operation '{oper_name.value}'")
return oper
def ReadEntries(self):
def _process_prop(pname, prop):
"""Process special properties
@ -172,8 +238,8 @@ class Entry_fit(Entry_section):
return
fsw.property(pname, prop.bytes)
def _generate_node(subnode, depth, in_images):
"""Generate nodes from a template
def _scan_gen_fdt_nodes(subnode, depth, in_images):
"""Generate FDT nodes
This creates one node for each member of self._fdts using the
provided template. If a property value contains 'NAME' it is
@ -211,6 +277,25 @@ class Entry_fit(Entry_section):
else:
self.Raise("Generator node requires 'fit,fdt-list' property")
def _scan_node(subnode, depth, in_images):
"""Generate nodes from a template
This creates one node for each member of self._fdts using the
provided template. If a property value contains 'NAME' it is
replaced with the filename of the FDT. If a property value contains
SEQ it is replaced with the node sequence number, where 1 is the
first.
Args:
subnode (None): Generator node to process
depth: Current node depth (0 is the base 'fit' node)
in_images: True if this is inside the 'images' node, so that
'data' properties should be generated
"""
oper = self._get_operation(subnode)
if oper == OP_GEN_FDT_NODES:
_scan_gen_fdt_nodes(subnode, depth, in_images)
def _AddNode(base_node, depth, node):
"""Add a node to the FIT
@ -251,7 +336,7 @@ class Entry_fit(Entry_section):
# fsw.add_node() or _AddNode() for it.
pass
elif self.GetImage().generate and subnode.name.startswith('@'):
_generate_node(subnode, depth, in_images)
_scan_node(subnode, depth, in_images)
else:
with fsw.add_node(subnode.name):
_AddNode(base_node, depth + 1, subnode)

View file

@ -5303,6 +5303,24 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
data = self._DoReadFile('222_tee_os.dts')
self.assertEqual(TEE_OS_DATA, data[:len(TEE_OS_DATA)])
def testFitFdtOper(self):
"""Check handling of a specified FIT operation"""
entry_args = {
'of-list': 'test-fdt1 test-fdt2',
'default-dt': 'test-fdt2',
}
self._DoReadFileDtb(
'223_fit_fdt_oper.dts',
entry_args=entry_args,
extra_indirs=[os.path.join(self._indir, TEST_FDT_SUBDIR)])[0]
def testFitFdtBadOper(self):
"""Check handling of an FDT map when the section cannot be found"""
with self.assertRaises(ValueError) as exc:
self._DoReadFileDtb('224_fit_bad_oper.dts')
self.assertIn("Node '/binman/fit': Unknown operation 'unknown'",
str(exc.exception))
if __name__ == "__main__":
unittest.main()

View file

@ -0,0 +1,56 @@
// SPDX-License-Identifier: GPL-2.0+
/dts-v1/;
/ {
#address-cells = <1>;
#size-cells = <1>;
binman {
u-boot {
};
fit {
description = "test-desc";
#address-cells = <1>;
fit,fdt-list = "of-list";
images {
kernel {
description = "Vanilla Linux kernel";
type = "kernel";
arch = "ppc";
os = "linux";
compression = "gzip";
load = <00000000>;
entry = <00000000>;
hash-1 {
algo = "crc32";
};
hash-2 {
algo = "sha1";
};
u-boot {
};
};
@fdt-SEQ {
fit,operation = "gen-fdt-nodes";
description = "fdt-NAME.dtb";
type = "flat_dt";
compression = "none";
};
};
configurations {
default = "@config-DEFAULT-SEQ";
@config-SEQ {
description = "conf-NAME.dtb";
firmware = "uboot";
loadables = "atf";
fdt = "fdt-SEQ";
};
};
};
u-boot-nodtb {
};
};
};

View file

@ -0,0 +1,27 @@
// SPDX-License-Identifier: GPL-2.0+
/dts-v1/;
/ {
#address-cells = <1>;
#size-cells = <1>;
binman {
fit {
description = "test-desc";
#address-cells = <1>;
fit,fdt-list = "of-list";
images {
@fdt-SEQ {
fit,operation = "unknown";
description = "fdt-NAME.dtb";
type = "flat_dt";
compression = "none";
};
};
};
fdtmap {
};
};
};