control.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. # Copyright (c) 2016 Google, Inc
  2. # Written by Simon Glass <sjg@chromium.org>
  3. #
  4. # SPDX-License-Identifier: GPL-2.0+
  5. #
  6. # Creates binary images from input files controlled by a description
  7. #
  8. from collections import OrderedDict
  9. import os
  10. import sys
  11. import tools
  12. import command
  13. import fdt_select
  14. import fdt_util
  15. from image import Image
  16. import tout
  17. # List of images we plan to create
  18. # Make this global so that it can be referenced from tests
  19. images = OrderedDict()
  20. def _ReadImageDesc(binman_node):
  21. """Read the image descriptions from the /binman node
  22. This normally produces a single Image object called 'image'. But if
  23. multiple images are present, they will all be returned.
  24. Args:
  25. binman_node: Node object of the /binman node
  26. Returns:
  27. OrderedDict of Image objects, each of which describes an image
  28. """
  29. images = OrderedDict()
  30. if 'multiple-images' in binman_node.props:
  31. for node in binman_node.subnodes:
  32. images[node.name] = Image(node.name, node)
  33. else:
  34. images['image'] = Image('image', binman_node)
  35. return images
  36. def _FindBinmanNode(fdt):
  37. """Find the 'binman' node in the device tree
  38. Args:
  39. fdt: Fdt object to scan
  40. Returns:
  41. Node object of /binman node, or None if not found
  42. """
  43. for node in fdt.GetRoot().subnodes:
  44. if node.name == 'binman':
  45. return node
  46. return None
  47. def Binman(options, args):
  48. """The main control code for binman
  49. This assumes that help and test options have already been dealt with. It
  50. deals with the core task of building images.
  51. Args:
  52. options: Command line options object
  53. args: Command line arguments (list of strings)
  54. """
  55. global images
  56. if options.full_help:
  57. pager = os.getenv('PAGER')
  58. if not pager:
  59. pager = 'more'
  60. fname = os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])),
  61. 'README')
  62. command.Run(pager, fname)
  63. return 0
  64. # Try to figure out which device tree contains our image description
  65. if options.dt:
  66. dtb_fname = options.dt
  67. else:
  68. board = options.board
  69. if not board:
  70. raise ValueError('Must provide a board to process (use -b <board>)')
  71. board_pathname = os.path.join(options.build_dir, board)
  72. dtb_fname = os.path.join(board_pathname, 'u-boot.dtb')
  73. if not options.indir:
  74. options.indir = ['.']
  75. options.indir.append(board_pathname)
  76. try:
  77. tout.Init(options.verbosity)
  78. try:
  79. tools.SetInputDirs(options.indir)
  80. tools.PrepareOutputDir(options.outdir, options.preserve)
  81. fdt = fdt_select.FdtScan(dtb_fname)
  82. node = _FindBinmanNode(fdt)
  83. if not node:
  84. raise ValueError("Device tree '%s' does not have a 'binman' "
  85. "node" % dtb_fname)
  86. images = _ReadImageDesc(node)
  87. for image in images.values():
  88. # Perform all steps for this image, including checking and
  89. # writing it. This means that errors found with a later
  90. # image will be reported after earlier images are already
  91. # completed and written, but that does not seem important.
  92. image.GetEntryContents()
  93. image.GetEntryPositions()
  94. image.PackEntries()
  95. image.CheckSize()
  96. image.CheckEntries()
  97. image.ProcessEntryContents()
  98. image.BuildImage()
  99. finally:
  100. tools.FinaliseOutputDir()
  101. finally:
  102. tout.Uninit()
  103. return 0