1*4882a593SmuzhiyunU-Boot FDT Overlay FIT usage 2*4882a593Smuzhiyun============================ 3*4882a593Smuzhiyun 4*4882a593SmuzhiyunIntroduction 5*4882a593Smuzhiyun------------ 6*4882a593SmuzhiyunIn many cases it is desirable to have a single FIT image support a multitude 7*4882a593Smuzhiyunof similar boards and their expansion options. The same kernel on DT enabled 8*4882a593Smuzhiyunplatforms can support this easily enough by providing a DT blob upon boot 9*4882a593Smuzhiyunthat matches the desired configuration. 10*4882a593Smuzhiyun 11*4882a593SmuzhiyunThis document focuses on specifically using overlays as part of a FIT image. 12*4882a593SmuzhiyunGeneral information regarding overlays including its syntax and building it 13*4882a593Smuzhiyuncan be found in doc/README.fdt-overlays 14*4882a593Smuzhiyun 15*4882a593SmuzhiyunConfiguration without overlays 16*4882a593Smuzhiyun------------------------------ 17*4882a593Smuzhiyun 18*4882a593SmuzhiyunTake a hypothetical board named 'foo' where there are different supported 19*4882a593Smuzhiyunrevisions, reva and revb. Assume that both board revisions can use add a bar 20*4882a593Smuzhiyunadd-on board, while only the revb board can use a baz add-on board. 21*4882a593Smuzhiyun 22*4882a593SmuzhiyunWithout using overlays the configuration would be as follows for every case. 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun /dts-v1/; 25*4882a593Smuzhiyun / { 26*4882a593Smuzhiyun images { 27*4882a593Smuzhiyun kernel@1 { 28*4882a593Smuzhiyun data = /incbin/("./zImage"); 29*4882a593Smuzhiyun type = "kernel"; 30*4882a593Smuzhiyun arch = "arm"; 31*4882a593Smuzhiyun os = "linux"; 32*4882a593Smuzhiyun load = <0x82000000>; 33*4882a593Smuzhiyun entry = <0x82000000>; 34*4882a593Smuzhiyun }; 35*4882a593Smuzhiyun fdt@1 { 36*4882a593Smuzhiyun data = /incbin/("./foo-reva.dtb"); 37*4882a593Smuzhiyun type = "flat_dt"; 38*4882a593Smuzhiyun arch = "arm"; 39*4882a593Smuzhiyun }; 40*4882a593Smuzhiyun fdt@2 { 41*4882a593Smuzhiyun data = /incbin/("./foo-revb.dtb"); 42*4882a593Smuzhiyun type = "flat_dt"; 43*4882a593Smuzhiyun arch = "arm"; 44*4882a593Smuzhiyun }; 45*4882a593Smuzhiyun fdt@3 { 46*4882a593Smuzhiyun data = /incbin/("./foo-reva-bar.dtb"); 47*4882a593Smuzhiyun type = "flat_dt"; 48*4882a593Smuzhiyun arch = "arm"; 49*4882a593Smuzhiyun }; 50*4882a593Smuzhiyun fdt@4 { 51*4882a593Smuzhiyun data = /incbin/("./foo-revb-bar.dtb"); 52*4882a593Smuzhiyun type = "flat_dt"; 53*4882a593Smuzhiyun arch = "arm"; 54*4882a593Smuzhiyun }; 55*4882a593Smuzhiyun fdt@5 { 56*4882a593Smuzhiyun data = /incbin/("./foo-revb-baz.dtb"); 57*4882a593Smuzhiyun type = "flat_dt"; 58*4882a593Smuzhiyun arch = "arm"; 59*4882a593Smuzhiyun }; 60*4882a593Smuzhiyun fdt@6 { 61*4882a593Smuzhiyun data = /incbin/("./foo-revb-bar-baz.dtb"); 62*4882a593Smuzhiyun type = "flat_dt"; 63*4882a593Smuzhiyun arch = "arm"; 64*4882a593Smuzhiyun }; 65*4882a593Smuzhiyun }; 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun configurations { 68*4882a593Smuzhiyun default = "foo-reva.dtb; 69*4882a593Smuzhiyun foo-reva.dtb { 70*4882a593Smuzhiyun kernel = "kernel@1"; 71*4882a593Smuzhiyun fdt = "fdt@1"; 72*4882a593Smuzhiyun }; 73*4882a593Smuzhiyun foo-revb.dtb { 74*4882a593Smuzhiyun kernel = "kernel@1"; 75*4882a593Smuzhiyun fdt = "fdt@2"; 76*4882a593Smuzhiyun }; 77*4882a593Smuzhiyun foo-reva-bar.dtb { 78*4882a593Smuzhiyun kernel = "kernel@1"; 79*4882a593Smuzhiyun fdt = "fdt@3"; 80*4882a593Smuzhiyun }; 81*4882a593Smuzhiyun foo-revb-bar.dtb { 82*4882a593Smuzhiyun kernel = "kernel@1"; 83*4882a593Smuzhiyun fdt = "fdt@4"; 84*4882a593Smuzhiyun }; 85*4882a593Smuzhiyun foo-revb-baz.dtb { 86*4882a593Smuzhiyun kernel = "kernel@1"; 87*4882a593Smuzhiyun fdt = "fdt@5"; 88*4882a593Smuzhiyun }; 89*4882a593Smuzhiyun foo-revb-bar-baz.dtb { 90*4882a593Smuzhiyun kernel = "kernel@1"; 91*4882a593Smuzhiyun fdt = "fdt@6"; 92*4882a593Smuzhiyun }; 93*4882a593Smuzhiyun }; 94*4882a593Smuzhiyun }; 95*4882a593Smuzhiyun 96*4882a593SmuzhiyunNote the blob needs to be compiled for each case and the combinatorial explosion of 97*4882a593Smuzhiyunconfigurations. A typical device tree blob is in the low hunderds of kbytes so a 98*4882a593Smuzhiyunmultitude of configuration grows the image quite a bit. 99*4882a593Smuzhiyun 100*4882a593SmuzhiyunBooting this image is done by using 101*4882a593Smuzhiyun 102*4882a593Smuzhiyun # bootm <addr>#<config> 103*4882a593Smuzhiyun 104*4882a593SmuzhiyunWhere config is one of: 105*4882a593Smuzhiyun foo-reva.dtb, foo-revb.dtb, foo-reva-bar.dtb, foo-revb-bar.dtb, 106*4882a593Smuzhiyun foo-revb-baz.dtb, foo-revb-bar-baz.dtb 107*4882a593Smuzhiyun 108*4882a593SmuzhiyunThis selects the DTB to use when booting. 109*4882a593Smuzhiyun 110*4882a593SmuzhiyunConfiguration using overlays 111*4882a593Smuzhiyun---------------------------- 112*4882a593Smuzhiyun 113*4882a593SmuzhiyunDevice tree overlays can be applied to a base DT and result in the same blob 114*4882a593Smuzhiyunbeing passed to the booting kernel. This saves on space and avoid the combinatorial 115*4882a593Smuzhiyunexplosion problem. 116*4882a593Smuzhiyun 117*4882a593Smuzhiyun /dts-v1/; 118*4882a593Smuzhiyun / { 119*4882a593Smuzhiyun images { 120*4882a593Smuzhiyun kernel@1 { 121*4882a593Smuzhiyun data = /incbin/("./zImage"); 122*4882a593Smuzhiyun type = "kernel"; 123*4882a593Smuzhiyun arch = "arm"; 124*4882a593Smuzhiyun os = "linux"; 125*4882a593Smuzhiyun load = <0x82000000>; 126*4882a593Smuzhiyun entry = <0x82000000>; 127*4882a593Smuzhiyun }; 128*4882a593Smuzhiyun fdt@1 { 129*4882a593Smuzhiyun data = /incbin/("./foo.dtb"); 130*4882a593Smuzhiyun type = "flat_dt"; 131*4882a593Smuzhiyun arch = "arm"; 132*4882a593Smuzhiyun load = <0x87f00000>; 133*4882a593Smuzhiyun }; 134*4882a593Smuzhiyun fdt@2 { 135*4882a593Smuzhiyun data = /incbin/("./reva.dtbo"); 136*4882a593Smuzhiyun type = "flat_dt"; 137*4882a593Smuzhiyun arch = "arm"; 138*4882a593Smuzhiyun load = <0x87fc0000>; 139*4882a593Smuzhiyun }; 140*4882a593Smuzhiyun fdt@3 { 141*4882a593Smuzhiyun data = /incbin/("./revb.dtbo"); 142*4882a593Smuzhiyun type = "flat_dt"; 143*4882a593Smuzhiyun arch = "arm"; 144*4882a593Smuzhiyun load = <0x87fc0000>; 145*4882a593Smuzhiyun }; 146*4882a593Smuzhiyun fdt@4 { 147*4882a593Smuzhiyun data = /incbin/("./bar.dtbo"); 148*4882a593Smuzhiyun type = "flat_dt"; 149*4882a593Smuzhiyun arch = "arm"; 150*4882a593Smuzhiyun load = <0x87fc0000>; 151*4882a593Smuzhiyun }; 152*4882a593Smuzhiyun fdt@5 { 153*4882a593Smuzhiyun data = /incbin/("./baz.dtbo"); 154*4882a593Smuzhiyun type = "flat_dt"; 155*4882a593Smuzhiyun arch = "arm"; 156*4882a593Smuzhiyun load = <0x87fc0000>; 157*4882a593Smuzhiyun }; 158*4882a593Smuzhiyun }; 159*4882a593Smuzhiyun 160*4882a593Smuzhiyun configurations { 161*4882a593Smuzhiyun default = "foo-reva.dtb; 162*4882a593Smuzhiyun foo-reva.dtb { 163*4882a593Smuzhiyun kernel = "kernel@1"; 164*4882a593Smuzhiyun fdt = "fdt@1", "fdt@2"; 165*4882a593Smuzhiyun }; 166*4882a593Smuzhiyun foo-revb.dtb { 167*4882a593Smuzhiyun kernel = "kernel@1"; 168*4882a593Smuzhiyun fdt = "fdt@1", "fdt@3"; 169*4882a593Smuzhiyun }; 170*4882a593Smuzhiyun foo-reva-bar.dtb { 171*4882a593Smuzhiyun kernel = "kernel@1"; 172*4882a593Smuzhiyun fdt = "fdt@1", "fdt@2", "fdt@4"; 173*4882a593Smuzhiyun }; 174*4882a593Smuzhiyun foo-revb-bar.dtb { 175*4882a593Smuzhiyun kernel = "kernel@1"; 176*4882a593Smuzhiyun fdt = "fdt@1", "fdt@3", "fdt@4"; 177*4882a593Smuzhiyun }; 178*4882a593Smuzhiyun foo-revb-baz.dtb { 179*4882a593Smuzhiyun kernel = "kernel@1"; 180*4882a593Smuzhiyun fdt = "fdt@1", "fdt@3", "fdt@5"; 181*4882a593Smuzhiyun }; 182*4882a593Smuzhiyun foo-revb-bar-baz.dtb { 183*4882a593Smuzhiyun kernel = "kernel@1"; 184*4882a593Smuzhiyun fdt = "fdt@1", "fdt@3", "fdt@4", "fdt@5"; 185*4882a593Smuzhiyun }; 186*4882a593Smuzhiyun bar { 187*4882a593Smuzhiyun fdt = "fdt@4"; 188*4882a593Smuzhiyun }; 189*4882a593Smuzhiyun baz { 190*4882a593Smuzhiyun fdt = "fdt@5"; 191*4882a593Smuzhiyun }; 192*4882a593Smuzhiyun }; 193*4882a593Smuzhiyun }; 194*4882a593Smuzhiyun 195*4882a593SmuzhiyunBooting this image is exactly the same as the non-overlay example. 196*4882a593Smuzhiyunu-boot will retrieve the base blob and apply the overlays in sequence as 197*4882a593Smuzhiyunthey are declared in the configuration. 198*4882a593Smuzhiyun 199*4882a593SmuzhiyunNote the minimum amount of different DT blobs, as well as the requirement for 200*4882a593Smuzhiyunthe DT blobs to have a load address; the overlay application requires the blobs 201*4882a593Smuzhiyunto be writeable. 202*4882a593Smuzhiyun 203*4882a593SmuzhiyunConfiguration using overlays and feature selection 204*4882a593Smuzhiyun-------------------------------------------------- 205*4882a593Smuzhiyun 206*4882a593SmuzhiyunAlthough the configuration in the previous section works is a bit inflexible 207*4882a593Smuzhiyunsince it requires all possible configuration options to be laid out before 208*4882a593Smuzhiyunhand in the FIT image. For the add-on boards the extra config selection method 209*4882a593Smuzhiyunmight make sense. 210*4882a593Smuzhiyun 211*4882a593SmuzhiyunNote the two bar & baz configuration nodes. To boot a reva board with 212*4882a593Smuzhiyunthe bar add-on board enabled simply use: 213*4882a593Smuzhiyun 214*4882a593Smuzhiyun # bootm <addr>#foo-reva.dtb#bar 215*4882a593Smuzhiyun 216*4882a593SmuzhiyunWhile booting a revb with bar and baz is as follows: 217*4882a593Smuzhiyun 218*4882a593Smuzhiyun # bootm <addr>#foo-revb.dtb#bar#baz 219*4882a593Smuzhiyun 220*4882a593SmuzhiyunThe limitation for a feature selection configuration node is that a single 221*4882a593Smuzhiyunfdt option is currently supported. 222*4882a593Smuzhiyun 223*4882a593SmuzhiyunPantelis Antoniou 224*4882a593Smuzhiyunpantelis.antoniou@konsulko.com 225*4882a593Smuzhiyun12/6/2017 226