1*4882a593Smuzhiyun# Copyright (c) 2016 Google, Inc 2*4882a593Smuzhiyun# 3*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0+ 4*4882a593Smuzhiyun# 5*4882a593Smuzhiyun 6*4882a593SmuzhiyunIntroduction 7*4882a593Smuzhiyun------------ 8*4882a593Smuzhiyun 9*4882a593SmuzhiyunFirmware often consists of several components which must be packaged together. 10*4882a593SmuzhiyunFor example, we may have SPL, U-Boot, a device tree and an environment area 11*4882a593Smuzhiyungrouped together and placed in MMC flash. When the system starts, it must be 12*4882a593Smuzhiyunable to find these pieces. 13*4882a593Smuzhiyun 14*4882a593SmuzhiyunSo far U-Boot has not provided a way to handle creating such images in a 15*4882a593Smuzhiyungeneral way. Each SoC does what it needs to build an image, often packing or 16*4882a593Smuzhiyunconcatenating images in the U-Boot build system. 17*4882a593Smuzhiyun 18*4882a593SmuzhiyunBinman aims to provide a mechanism for building images, from simple 19*4882a593SmuzhiyunSPL + U-Boot combinations, to more complex arrangements with many parts. 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun 22*4882a593SmuzhiyunWhat it does 23*4882a593Smuzhiyun------------ 24*4882a593Smuzhiyun 25*4882a593SmuzhiyunBinman reads your board's device tree and finds a node which describes the 26*4882a593Smuzhiyunrequired image layout. It uses this to work out what to place where. The 27*4882a593Smuzhiyunoutput file normally contains the device tree, so it is in principle possible 28*4882a593Smuzhiyunto read an image and extract its constituent parts. 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun 31*4882a593SmuzhiyunFeatures 32*4882a593Smuzhiyun-------- 33*4882a593Smuzhiyun 34*4882a593SmuzhiyunSo far binman is pretty simple. It supports binary blobs, such as 'u-boot', 35*4882a593Smuzhiyun'spl' and 'fdt'. It supports empty entries (such as setting to 0xff). It can 36*4882a593Smuzhiyunplace entries at a fixed location in the image, or fit them together with 37*4882a593Smuzhiyunsuitable padding and alignment. It provides a way to process binaries before 38*4882a593Smuzhiyunthey are included, by adding a Python plug-in. The device tree is available 39*4882a593Smuzhiyunto U-Boot at run-time so that the images can be interpreted. 40*4882a593Smuzhiyun 41*4882a593SmuzhiyunBinman does not yet update the device tree with the final location of 42*4882a593Smuzhiyuneverything when it is done. A simple C structure could be generated for 43*4882a593Smuzhiyunconstrained environments like SPL (using dtoc) but this is also not 44*4882a593Smuzhiyunimplemented. 45*4882a593Smuzhiyun 46*4882a593SmuzhiyunBinman can also support incorporating filesystems in the image if required. 47*4882a593SmuzhiyunFor example x86 platforms may use CBFS in some cases. 48*4882a593Smuzhiyun 49*4882a593SmuzhiyunBinman is intended for use with U-Boot but is designed to be general enough 50*4882a593Smuzhiyunto be useful in other image-packaging situations. 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun 53*4882a593SmuzhiyunMotivation 54*4882a593Smuzhiyun---------- 55*4882a593Smuzhiyun 56*4882a593SmuzhiyunPackaging of firmware is quite a different task from building the various 57*4882a593Smuzhiyunparts. In many cases the various binaries which go into the image come from 58*4882a593Smuzhiyunseparate build systems. For example, ARM Trusted Firmware is used on ARMv8 59*4882a593Smuzhiyundevices but is not built in the U-Boot tree. If a Linux kernel is included 60*4882a593Smuzhiyunin the firmware image, it is built elsewhere. 61*4882a593Smuzhiyun 62*4882a593SmuzhiyunIt is of course possible to add more and more build rules to the U-Boot 63*4882a593Smuzhiyunbuild system to cover these cases. It can shell out to other Makefiles and 64*4882a593Smuzhiyunbuild scripts. But it seems better to create a clear divide between building 65*4882a593Smuzhiyunsoftware and packaging it. 66*4882a593Smuzhiyun 67*4882a593SmuzhiyunAt present this is handled by manual instructions, different for each board, 68*4882a593Smuzhiyunon how to create images that will boot. By turning these instructions into a 69*4882a593Smuzhiyunstandard format, we can support making valid images for any board without 70*4882a593Smuzhiyunmanual effort, lots of READMEs, etc. 71*4882a593Smuzhiyun 72*4882a593SmuzhiyunBenefits: 73*4882a593Smuzhiyun- Each binary can have its own build system and tool chain without creating 74*4882a593Smuzhiyunany dependencies between them 75*4882a593Smuzhiyun- Avoids the need for a single-shot build: individual parts can be updated 76*4882a593Smuzhiyunand brought in as needed 77*4882a593Smuzhiyun- Provides for a standard image description available in the build and at 78*4882a593Smuzhiyunrun-time 79*4882a593Smuzhiyun- SoC-specific image-signing tools can be accomodated 80*4882a593Smuzhiyun- Avoids cluttering the U-Boot build system with image-building code 81*4882a593Smuzhiyun- The image description is automatically available at run-time in U-Boot, 82*4882a593SmuzhiyunSPL. It can be made available to other software also 83*4882a593Smuzhiyun- The image description is easily readable (it's a text file in device-tree 84*4882a593Smuzhiyunformat) and permits flexible packing of binaries 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun 87*4882a593SmuzhiyunTerminology 88*4882a593Smuzhiyun----------- 89*4882a593Smuzhiyun 90*4882a593SmuzhiyunBinman uses the following terms: 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun- image - an output file containing a firmware image 93*4882a593Smuzhiyun- binary - an input binary that goes into the image 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun 96*4882a593SmuzhiyunRelationship to FIT 97*4882a593Smuzhiyun------------------- 98*4882a593Smuzhiyun 99*4882a593SmuzhiyunFIT is U-Boot's official image format. It supports multiple binaries with 100*4882a593Smuzhiyunload / execution addresses, compression. It also supports verification 101*4882a593Smuzhiyunthrough hashing and RSA signatures. 102*4882a593Smuzhiyun 103*4882a593SmuzhiyunFIT was originally designed to support booting a Linux kernel (with an 104*4882a593Smuzhiyunoptional ramdisk) and device tree chosen from various options in the FIT. 105*4882a593SmuzhiyunNow that U-Boot supports configuration via device tree, it is possible to 106*4882a593Smuzhiyunload U-Boot from a FIT, with the device tree chosen by SPL. 107*4882a593Smuzhiyun 108*4882a593SmuzhiyunBinman considers FIT to be one of the binaries it can place in the image. 109*4882a593Smuzhiyun 110*4882a593SmuzhiyunWhere possible it is best to put as much as possible in the FIT, with binman 111*4882a593Smuzhiyunused to deal with cases not covered by FIT. Examples include initial 112*4882a593Smuzhiyunexecution (since FIT itself does not have an executable header) and dealing 113*4882a593Smuzhiyunwith device boundaries, such as the read-only/read-write separation in SPI 114*4882a593Smuzhiyunflash. 115*4882a593Smuzhiyun 116*4882a593SmuzhiyunFor U-Boot, binman should not be used to create ad-hoc images in place of 117*4882a593SmuzhiyunFIT. 118*4882a593Smuzhiyun 119*4882a593Smuzhiyun 120*4882a593SmuzhiyunRelationship to mkimage 121*4882a593Smuzhiyun----------------------- 122*4882a593Smuzhiyun 123*4882a593SmuzhiyunThe mkimage tool provides a means to create a FIT. Traditionally it has 124*4882a593Smuzhiyunneeded an image description file: a device tree, like binman, but in a 125*4882a593Smuzhiyundifferent format. More recently it has started to support a '-f auto' mode 126*4882a593Smuzhiyunwhich can generate that automatically. 127*4882a593Smuzhiyun 128*4882a593SmuzhiyunMore relevant to binman, mkimage also permits creation of many SoC-specific 129*4882a593Smuzhiyunimage types. These can be listed by running 'mkimage -T list'. Examples 130*4882a593Smuzhiyuninclude 'rksd', the Rockchip SD/MMC boot format. The mkimage tool is often 131*4882a593Smuzhiyuncalled from the U-Boot build system for this reason. 132*4882a593Smuzhiyun 133*4882a593SmuzhiyunBinman considers the output files created by mkimage to be binary blobs 134*4882a593Smuzhiyunwhich it can place in an image. Binman does not replace the mkimage tool or 135*4882a593Smuzhiyunthis purpose. It would be possible in some situtions to create a new entry 136*4882a593Smuzhiyuntype for the images in mkimage, but this would not add functionality. It 137*4882a593Smuzhiyunseems better to use the mkiamge tool to generate binaries and avoid blurring 138*4882a593Smuzhiyunthe boundaries between building input files (mkimage) and packaging then 139*4882a593Smuzhiyuninto a final image (binman). 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun 142*4882a593SmuzhiyunExample use of binman in U-Boot 143*4882a593Smuzhiyun------------------------------- 144*4882a593Smuzhiyun 145*4882a593SmuzhiyunBinman aims to replace some of the ad-hoc image creation in the U-Boot 146*4882a593Smuzhiyunbuild system. 147*4882a593Smuzhiyun 148*4882a593SmuzhiyunConsider sunxi. It has the following steps: 149*4882a593Smuzhiyun 150*4882a593Smuzhiyun1. It uses a custom mksunxiboot tool to build an SPL image called 151*4882a593Smuzhiyunsunxi-spl.bin. This should probably move into mkimage. 152*4882a593Smuzhiyun 153*4882a593Smuzhiyun2. It uses mkimage to package U-Boot into a legacy image file (so that it can 154*4882a593Smuzhiyunhold the load and execution address) called u-boot.img. 155*4882a593Smuzhiyun 156*4882a593Smuzhiyun3. It builds a final output image called u-boot-sunxi-with-spl.bin which 157*4882a593Smuzhiyunconsists of sunxi-spl.bin, some padding and u-boot.img. 158*4882a593Smuzhiyun 159*4882a593SmuzhiyunBinman is intended to replace the last step. The U-Boot build system builds 160*4882a593Smuzhiyunu-boot.bin and sunxi-spl.bin. Binman can then take over creation of 161*4882a593Smuzhiyunsunxi-spl.bin (by calling mksunxiboot, or hopefully one day mkimage). In any 162*4882a593Smuzhiyuncase, it would then create the image from the component parts. 163*4882a593Smuzhiyun 164*4882a593SmuzhiyunThis simplifies the U-Boot Makefile somewhat, since various pieces of logic 165*4882a593Smuzhiyuncan be replaced by a call to binman. 166*4882a593Smuzhiyun 167*4882a593Smuzhiyun 168*4882a593SmuzhiyunExample use of binman for x86 169*4882a593Smuzhiyun----------------------------- 170*4882a593Smuzhiyun 171*4882a593SmuzhiyunIn most cases x86 images have a lot of binary blobs, 'black-box' code 172*4882a593Smuzhiyunprovided by Intel which must be run for the platform to work. Typically 173*4882a593Smuzhiyunthese blobs are not relocatable and must be placed at fixed areas in the 174*4882a593Smuzhiyunfirmare image. 175*4882a593Smuzhiyun 176*4882a593SmuzhiyunCurrently this is handled by ifdtool, which places microcode, FSP, MRC, VGA 177*4882a593SmuzhiyunBIOS, reference code and Intel ME binaries into a u-boot.rom file. 178*4882a593Smuzhiyun 179*4882a593SmuzhiyunBinman is intended to replace all of this, with ifdtool left to handle only 180*4882a593Smuzhiyunthe configuration of the Intel-format descriptor. 181*4882a593Smuzhiyun 182*4882a593Smuzhiyun 183*4882a593SmuzhiyunRunning binman 184*4882a593Smuzhiyun-------------- 185*4882a593Smuzhiyun 186*4882a593SmuzhiyunType: 187*4882a593Smuzhiyun 188*4882a593Smuzhiyun binman -b <board_name> 189*4882a593Smuzhiyun 190*4882a593Smuzhiyunto build an image for a board. The board name is the same name used when 191*4882a593Smuzhiyunconfiguring U-Boot (e.g. for sandbox_defconfig the board name is 'sandbox'). 192*4882a593SmuzhiyunBinman assumes that the input files for the build are in ../b/<board_name>. 193*4882a593Smuzhiyun 194*4882a593SmuzhiyunOr you can specify this explicitly: 195*4882a593Smuzhiyun 196*4882a593Smuzhiyun binman -I <build_path> 197*4882a593Smuzhiyun 198*4882a593Smuzhiyunwhere <build_path> is the build directory containing the output of the U-Boot 199*4882a593Smuzhiyunbuild. 200*4882a593Smuzhiyun 201*4882a593Smuzhiyun(Future work will make this more configurable) 202*4882a593Smuzhiyun 203*4882a593SmuzhiyunIn either case, binman picks up the device tree file (u-boot.dtb) and looks 204*4882a593Smuzhiyunfor its instructions in the 'binman' node. 205*4882a593Smuzhiyun 206*4882a593SmuzhiyunBinman has a few other options which you can see by running 'binman -h'. 207*4882a593Smuzhiyun 208*4882a593Smuzhiyun 209*4882a593SmuzhiyunImage description format 210*4882a593Smuzhiyun------------------------ 211*4882a593Smuzhiyun 212*4882a593SmuzhiyunThe binman node is called 'binman'. An example image description is shown 213*4882a593Smuzhiyunbelow: 214*4882a593Smuzhiyun 215*4882a593Smuzhiyun binman { 216*4882a593Smuzhiyun filename = "u-boot-sunxi-with-spl.bin"; 217*4882a593Smuzhiyun pad-byte = <0xff>; 218*4882a593Smuzhiyun blob { 219*4882a593Smuzhiyun filename = "spl/sunxi-spl.bin"; 220*4882a593Smuzhiyun }; 221*4882a593Smuzhiyun u-boot { 222*4882a593Smuzhiyun pos = <CONFIG_SPL_PAD_TO>; 223*4882a593Smuzhiyun }; 224*4882a593Smuzhiyun }; 225*4882a593Smuzhiyun 226*4882a593Smuzhiyun 227*4882a593SmuzhiyunThis requests binman to create an image file called u-boot-sunxi-with-spl.bin 228*4882a593Smuzhiyunconsisting of a specially formatted SPL (spl/sunxi-spl.bin, built by the 229*4882a593Smuzhiyunnormal U-Boot Makefile), some 0xff padding, and a U-Boot legacy image. The 230*4882a593Smuzhiyunpadding comes from the fact that the second binary is placed at 231*4882a593SmuzhiyunCONFIG_SPL_PAD_TO. If that line were omitted then the U-Boot binary would 232*4882a593Smuzhiyunimmediately follow the SPL binary. 233*4882a593Smuzhiyun 234*4882a593SmuzhiyunThe binman node describes an image. The sub-nodes describe entries in the 235*4882a593Smuzhiyunimage. Each entry represents a region within the overall image. The name of 236*4882a593Smuzhiyunthe entry (blob, u-boot) tells binman what to put there. For 'blob' we must 237*4882a593Smuzhiyunprovide a filename. For 'u-boot', binman knows that this means 'u-boot.bin'. 238*4882a593Smuzhiyun 239*4882a593SmuzhiyunEntries are normally placed into the image sequentially, one after the other. 240*4882a593SmuzhiyunThe image size is the total size of all entries. As you can see, you can 241*4882a593Smuzhiyunspecify the start position of an entry using the 'pos' property. 242*4882a593Smuzhiyun 243*4882a593SmuzhiyunNote that due to a device tree requirement, all entries must have a unique 244*4882a593Smuzhiyunname. If you want to put the same binary in the image multiple times, you can 245*4882a593Smuzhiyunuse any unique name, with the 'type' property providing the type. 246*4882a593Smuzhiyun 247*4882a593SmuzhiyunThe attributes supported for entries are described below. 248*4882a593Smuzhiyun 249*4882a593Smuzhiyunpos: 250*4882a593Smuzhiyun This sets the position of an entry within the image. The first byte 251*4882a593Smuzhiyun of the image is normally at position 0. If 'pos' is not provided, 252*4882a593Smuzhiyun binman sets it to the end of the previous region, or the start of 253*4882a593Smuzhiyun the image's entry area (normally 0) if there is no previous region. 254*4882a593Smuzhiyun 255*4882a593Smuzhiyunalign: 256*4882a593Smuzhiyun This sets the alignment of the entry. The entry position is adjusted 257*4882a593Smuzhiyun so that the entry starts on an aligned boundary within the image. For 258*4882a593Smuzhiyun example 'align = <16>' means that the entry will start on a 16-byte 259*4882a593Smuzhiyun boundary. Alignment shold be a power of 2. If 'align' is not 260*4882a593Smuzhiyun provided, no alignment is performed. 261*4882a593Smuzhiyun 262*4882a593Smuzhiyunsize: 263*4882a593Smuzhiyun This sets the size of the entry. The contents will be padded out to 264*4882a593Smuzhiyun this size. If this is not provided, it will be set to the size of the 265*4882a593Smuzhiyun contents. 266*4882a593Smuzhiyun 267*4882a593Smuzhiyunpad-before: 268*4882a593Smuzhiyun Padding before the contents of the entry. Normally this is 0, meaning 269*4882a593Smuzhiyun that the contents start at the beginning of the entry. This can be 270*4882a593Smuzhiyun offset the entry contents a little. Defaults to 0. 271*4882a593Smuzhiyun 272*4882a593Smuzhiyunpad-after: 273*4882a593Smuzhiyun Padding after the contents of the entry. Normally this is 0, meaning 274*4882a593Smuzhiyun that the entry ends at the last byte of content (unless adjusted by 275*4882a593Smuzhiyun other properties). This allows room to be created in the image for 276*4882a593Smuzhiyun this entry to expand later. Defaults to 0. 277*4882a593Smuzhiyun 278*4882a593Smuzhiyunalign-size: 279*4882a593Smuzhiyun This sets the alignment of the entry size. For example, to ensure 280*4882a593Smuzhiyun that the size of an entry is a multiple of 64 bytes, set this to 64. 281*4882a593Smuzhiyun If 'align-size' is not provided, no alignment is performed. 282*4882a593Smuzhiyun 283*4882a593Smuzhiyunalign-end: 284*4882a593Smuzhiyun This sets the alignment of the end of an entry. Some entries require 285*4882a593Smuzhiyun that they end on an alignment boundary, regardless of where they 286*4882a593Smuzhiyun start. If 'align-end' is not provided, no alignment is performed. 287*4882a593Smuzhiyun 288*4882a593Smuzhiyun Note: This is not yet implemented in binman. 289*4882a593Smuzhiyun 290*4882a593Smuzhiyunfilename: 291*4882a593Smuzhiyun For 'blob' types this provides the filename containing the binary to 292*4882a593Smuzhiyun put into the entry. If binman knows about the entry type (like 293*4882a593Smuzhiyun u-boot-bin), then there is no need to specify this. 294*4882a593Smuzhiyun 295*4882a593Smuzhiyuntype: 296*4882a593Smuzhiyun Sets the type of an entry. This defaults to the entry name, but it is 297*4882a593Smuzhiyun possible to use any name, and then add (for example) 'type = "u-boot"' 298*4882a593Smuzhiyun to specify the type. 299*4882a593Smuzhiyun 300*4882a593Smuzhiyun 301*4882a593SmuzhiyunThe attributes supported for images are described below. Several are similar 302*4882a593Smuzhiyunto those for entries. 303*4882a593Smuzhiyun 304*4882a593Smuzhiyunsize: 305*4882a593Smuzhiyun Sets the image size in bytes, for example 'size = <0x100000>' for a 306*4882a593Smuzhiyun 1MB image. 307*4882a593Smuzhiyun 308*4882a593Smuzhiyunalign-size: 309*4882a593Smuzhiyun This sets the alignment of the image size. For example, to ensure 310*4882a593Smuzhiyun that the image ends on a 512-byte boundary, use 'align-size = <512>'. 311*4882a593Smuzhiyun If 'align-size' is not provided, no alignment is performed. 312*4882a593Smuzhiyun 313*4882a593Smuzhiyunpad-before: 314*4882a593Smuzhiyun This sets the padding before the image entries. The first entry will 315*4882a593Smuzhiyun be positionad after the padding. This defaults to 0. 316*4882a593Smuzhiyun 317*4882a593Smuzhiyunpad-after: 318*4882a593Smuzhiyun This sets the padding after the image entries. The padding will be 319*4882a593Smuzhiyun placed after the last entry. This defaults to 0. 320*4882a593Smuzhiyun 321*4882a593Smuzhiyunpad-byte: 322*4882a593Smuzhiyun This specifies the pad byte to use when padding in the image. It 323*4882a593Smuzhiyun defaults to 0. To use 0xff, you would add 'pad-byte = <0xff>'. 324*4882a593Smuzhiyun 325*4882a593Smuzhiyunfilename: 326*4882a593Smuzhiyun This specifies the image filename. It defaults to 'image.bin'. 327*4882a593Smuzhiyun 328*4882a593Smuzhiyunsort-by-pos: 329*4882a593Smuzhiyun This causes binman to reorder the entries as needed to make sure they 330*4882a593Smuzhiyun are in increasing positional order. This can be used when your entry 331*4882a593Smuzhiyun order may not match the positional order. A common situation is where 332*4882a593Smuzhiyun the 'pos' properties are set by CONFIG options, so their ordering is 333*4882a593Smuzhiyun not known a priori. 334*4882a593Smuzhiyun 335*4882a593Smuzhiyun This is a boolean property so needs no value. To enable it, add a 336*4882a593Smuzhiyun line 'sort-by-pos;' to your description. 337*4882a593Smuzhiyun 338*4882a593Smuzhiyunmultiple-images: 339*4882a593Smuzhiyun Normally only a single image is generated. To create more than one 340*4882a593Smuzhiyun image, put this property in the binman node. For example, this will 341*4882a593Smuzhiyun create image1.bin containing u-boot.bin, and image2.bin containing 342*4882a593Smuzhiyun both spl/u-boot-spl.bin and u-boot.bin: 343*4882a593Smuzhiyun 344*4882a593Smuzhiyun binman { 345*4882a593Smuzhiyun multiple-images; 346*4882a593Smuzhiyun image1 { 347*4882a593Smuzhiyun u-boot { 348*4882a593Smuzhiyun }; 349*4882a593Smuzhiyun }; 350*4882a593Smuzhiyun 351*4882a593Smuzhiyun image2 { 352*4882a593Smuzhiyun spl { 353*4882a593Smuzhiyun }; 354*4882a593Smuzhiyun u-boot { 355*4882a593Smuzhiyun }; 356*4882a593Smuzhiyun }; 357*4882a593Smuzhiyun }; 358*4882a593Smuzhiyun 359*4882a593Smuzhiyunend-at-4gb: 360*4882a593Smuzhiyun For x86 machines the ROM positions start just before 4GB and extend 361*4882a593Smuzhiyun up so that the image finished at the 4GB boundary. This boolean 362*4882a593Smuzhiyun option can be enabled to support this. The image size must be 363*4882a593Smuzhiyun provided so that binman knows when the image should start. For an 364*4882a593Smuzhiyun 8MB ROM, the position of the first entry would be 0xfff80000 with 365*4882a593Smuzhiyun this option, instead of 0 without this option. 366*4882a593Smuzhiyun 367*4882a593Smuzhiyun 368*4882a593SmuzhiyunExamples of the above options can be found in the tests. See the 369*4882a593Smuzhiyuntools/binman/test directory. 370*4882a593Smuzhiyun 371*4882a593Smuzhiyun 372*4882a593SmuzhiyunSpecial properties 373*4882a593Smuzhiyun------------------ 374*4882a593Smuzhiyun 375*4882a593SmuzhiyunSome entries support special properties, documented here: 376*4882a593Smuzhiyun 377*4882a593Smuzhiyunu-boot-with-ucode-ptr: 378*4882a593Smuzhiyun optional-ucode: boolean property to make microcode optional. If the 379*4882a593Smuzhiyun u-boot.bin image does not include microcode, no error will 380*4882a593Smuzhiyun be generated. 381*4882a593Smuzhiyun 382*4882a593Smuzhiyun 383*4882a593SmuzhiyunOrder of image creation 384*4882a593Smuzhiyun----------------------- 385*4882a593Smuzhiyun 386*4882a593SmuzhiyunImage creation proceeds in the following order, for each entry in the image. 387*4882a593Smuzhiyun 388*4882a593Smuzhiyun1. GetEntryContents() - the contents of each entry are obtained, normally by 389*4882a593Smuzhiyunreading from a file. This calls the Entry.ObtainContents() to read the 390*4882a593Smuzhiyuncontents. The default version of Entry.ObtainContents() calls 391*4882a593SmuzhiyunEntry.GetDefaultFilename() and then reads that file. So a common mechanism 392*4882a593Smuzhiyunto select a file to read is to override that function in the subclass. The 393*4882a593Smuzhiyunfunctions must return True when they have read the contents. Binman will 394*4882a593Smuzhiyunretry calling the functions a few times if False is returned, allowing 395*4882a593Smuzhiyundependencies between the contents of different entries. 396*4882a593Smuzhiyun 397*4882a593Smuzhiyun2. GetEntryPositions() - calls Entry.GetPositions() for each entry. This can 398*4882a593Smuzhiyunreturn a dict containing entries that need updating. The key should be the 399*4882a593Smuzhiyunentry name and the value is a tuple (pos, size). This allows an entry to 400*4882a593Smuzhiyunprovide the position and size for other entries. The default implementation 401*4882a593Smuzhiyunof GetEntryPositions() returns {}. 402*4882a593Smuzhiyun 403*4882a593Smuzhiyun3. PackEntries() - calls Entry.Pack() which figures out the position and 404*4882a593Smuzhiyunsize of an entry. The 'current' image position is passed in, and the function 405*4882a593Smuzhiyunreturns the position immediately after the entry being packed. The default 406*4882a593Smuzhiyunimplementation of Pack() is usually sufficient. 407*4882a593Smuzhiyun 408*4882a593Smuzhiyun4. CheckSize() - checks that the contents of all the entries fits within 409*4882a593Smuzhiyunthe image size. If the image does not have a defined size, the size is set 410*4882a593Smuzhiyunlarge enough to hold all the entries. 411*4882a593Smuzhiyun 412*4882a593Smuzhiyun5. CheckEntries() - checks that the entries do not overlap, nor extend 413*4882a593Smuzhiyunoutside the image. 414*4882a593Smuzhiyun 415*4882a593Smuzhiyun6. ProcessEntryContents() - this calls Entry.ProcessContents() on each entry. 416*4882a593SmuzhiyunThe default implementatoin does nothing. This can be overriden to adjust the 417*4882a593Smuzhiyuncontents of an entry in some way. For example, it would be possible to create 418*4882a593Smuzhiyunan entry containing a hash of the contents of some other entries. At this 419*4882a593Smuzhiyunstage the position and size of entries should not be adjusted. 420*4882a593Smuzhiyun 421*4882a593Smuzhiyun7. BuildImage() - builds the image and writes it to a file. This is the final 422*4882a593Smuzhiyunstep. 423*4882a593Smuzhiyun 424*4882a593Smuzhiyun 425*4882a593SmuzhiyunAutomatic .dtsi inclusion 426*4882a593Smuzhiyun------------------------- 427*4882a593Smuzhiyun 428*4882a593SmuzhiyunIt is sometimes inconvenient to add a 'binman' node to the .dts file for each 429*4882a593Smuzhiyunboard. This can be done by using #include to bring in a common file. Another 430*4882a593Smuzhiyunapproach supported by the U-Boot build system is to automatically include 431*4882a593Smuzhiyuna common header. You can then put the binman node (and anything else that is 432*4882a593Smuzhiyunspecific to U-Boot, such as u-boot,dm-pre-reloc properies) in that header 433*4882a593Smuzhiyunfile. 434*4882a593Smuzhiyun 435*4882a593SmuzhiyunBinman will search for the following files in arch/<arch>/dts: 436*4882a593Smuzhiyun 437*4882a593Smuzhiyun <dts>-u-boot.dtsi where <dts> is the base name of the .dts file 438*4882a593Smuzhiyun <CONFIG_SYS_SOC>-u-boot.dtsi 439*4882a593Smuzhiyun <CONFIG_SYS_CPU>-u-boot.dtsi 440*4882a593Smuzhiyun <CONFIG_SYS_VENDOR>-u-boot.dtsi 441*4882a593Smuzhiyun u-boot.dtsi 442*4882a593Smuzhiyun 443*4882a593SmuzhiyunU-Boot will only use the first one that it finds. If you need to include a 444*4882a593Smuzhiyunmore general file you can do that from the more specific file using #include. 445*4882a593SmuzhiyunIf you are having trouble figuring out what is going on, you can uncomment 446*4882a593Smuzhiyunthe 'warning' line in scripts/Makefile.lib to see what it has found: 447*4882a593Smuzhiyun 448*4882a593Smuzhiyun # Uncomment for debugging 449*4882a593Smuzhiyun # $(warning binman_dtsi_options: $(binman_dtsi_options)) 450*4882a593Smuzhiyun 451*4882a593Smuzhiyun 452*4882a593SmuzhiyunCode coverage 453*4882a593Smuzhiyun------------- 454*4882a593Smuzhiyun 455*4882a593SmuzhiyunBinman is a critical tool and is designed to be very testable. Entry 456*4882a593Smuzhiyunimplementations target 100% test coverage. Run 'binman -T' to check this. 457*4882a593Smuzhiyun 458*4882a593SmuzhiyunTo enable Python test coverage on Debian-type distributions (e.g. Ubuntu): 459*4882a593Smuzhiyun 460*4882a593Smuzhiyun $ sudo apt-get install python-pip python-pytest 461*4882a593Smuzhiyun $ sudo pip install coverage 462*4882a593Smuzhiyun 463*4882a593Smuzhiyun 464*4882a593SmuzhiyunAdvanced Features / Technical docs 465*4882a593Smuzhiyun---------------------------------- 466*4882a593Smuzhiyun 467*4882a593SmuzhiyunThe behaviour of entries is defined by the Entry class. All other entries are 468*4882a593Smuzhiyuna subclass of this. An important subclass is Entry_blob which takes binary 469*4882a593Smuzhiyundata from a file and places it in the entry. In fact most entry types are 470*4882a593Smuzhiyunsubclasses of Entry_blob. 471*4882a593Smuzhiyun 472*4882a593SmuzhiyunEach entry type is a separate file in the tools/binman/etype directory. Each 473*4882a593Smuzhiyunfile contains a class called Entry_<type> where <type> is the entry type. 474*4882a593SmuzhiyunNew entry types can be supported by adding new files in that directory. 475*4882a593SmuzhiyunThese will automatically be detected by binman when needed. 476*4882a593Smuzhiyun 477*4882a593SmuzhiyunEntry properties are documented in entry.py. The entry subclasses are free 478*4882a593Smuzhiyunto change the values of properties to support special behaviour. For example, 479*4882a593Smuzhiyunwhen Entry_blob loads a file, it sets content_size to the size of the file. 480*4882a593SmuzhiyunEntry classes can adjust other entries. For example, an entry that knows 481*4882a593Smuzhiyunwhere other entries should be positioned can set up those entries' positions 482*4882a593Smuzhiyunso they don't need to be set in the binman decription. It can also adjust 483*4882a593Smuzhiyunentry contents. 484*4882a593Smuzhiyun 485*4882a593SmuzhiyunMost of the time such essoteric behaviour is not needed, but it can be 486*4882a593Smuzhiyunessential for complex images. 487*4882a593Smuzhiyun 488*4882a593Smuzhiyun 489*4882a593SmuzhiyunHistory / Credits 490*4882a593Smuzhiyun----------------- 491*4882a593Smuzhiyun 492*4882a593SmuzhiyunBinman takes a lot of inspiration from a Chrome OS tool called 493*4882a593Smuzhiyun'cros_bundle_firmware', which I wrote some years ago. That tool was based on 494*4882a593Smuzhiyuna reasonably simple and sound design but has expanded greatly over the 495*4882a593Smuzhiyunyears. In particular its handling of x86 images is convoluted. 496*4882a593Smuzhiyun 497*4882a593SmuzhiyunQuite a few lessons have been learned which are hopefully be applied here. 498*4882a593Smuzhiyun 499*4882a593Smuzhiyun 500*4882a593SmuzhiyunDesign notes 501*4882a593Smuzhiyun------------ 502*4882a593Smuzhiyun 503*4882a593SmuzhiyunOn the face of it, a tool to create firmware images should be fairly simple: 504*4882a593Smuzhiyunjust find all the input binaries and place them at the right place in the 505*4882a593Smuzhiyunimage. The difficulty comes from the wide variety of input types (simple 506*4882a593Smuzhiyunflat binaries containing code, packaged data with various headers), packing 507*4882a593Smuzhiyunrequirments (alignment, spacing, device boundaries) and other required 508*4882a593Smuzhiyunfeatures such as hierarchical images. 509*4882a593Smuzhiyun 510*4882a593SmuzhiyunThe design challenge is to make it easy to create simple images, while 511*4882a593Smuzhiyunallowing the more complex cases to be supported. For example, for most 512*4882a593Smuzhiyunimages we don't much care exactly where each binary ends up, so we should 513*4882a593Smuzhiyunnot have to specify that unnecessarily. 514*4882a593Smuzhiyun 515*4882a593SmuzhiyunNew entry types should aim to provide simple usage where possible. If new 516*4882a593Smuzhiyuncore features are needed, they can be added in the Entry base class. 517*4882a593Smuzhiyun 518*4882a593Smuzhiyun 519*4882a593SmuzhiyunTo do 520*4882a593Smuzhiyun----- 521*4882a593Smuzhiyun 522*4882a593SmuzhiyunSome ideas: 523*4882a593Smuzhiyun- Fill out the device tree to include the final position and size of each 524*4882a593Smuzhiyun entry (since the input file may not always specify these) 525*4882a593Smuzhiyun- Use of-platdata to make the information available to code that is unable 526*4882a593Smuzhiyun to use device tree (such as a very small SPL image) 527*4882a593Smuzhiyun- Write an image map to a text file 528*4882a593Smuzhiyun- Allow easy building of images by specifying just the board name 529*4882a593Smuzhiyun- Produce a full Python binding for libfdt (for upstream) 530*4882a593Smuzhiyun- Add an option to decode an image into the constituent binaries 531*4882a593Smuzhiyun- Suppoort hierarchical images (packing of binaries into another binary 532*4882a593Smuzhiyun which is then placed in the image) 533*4882a593Smuzhiyun- Support building an image for a board (-b) more completely, with a 534*4882a593Smuzhiyun configurable build directory 535*4882a593Smuzhiyun- Consider making binman work with buildman, although if it is used in the 536*4882a593Smuzhiyun Makefile, this will be automatic 537*4882a593Smuzhiyun- Implement align-end 538*4882a593Smuzhiyun 539*4882a593Smuzhiyun-- 540*4882a593SmuzhiyunSimon Glass <sjg@chromium.org> 541*4882a593Smuzhiyun7/7/2016 542