]>
git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arm/mach-rockchip/make_fit_atf.py
3 A script to generate FIT image source for rockchip boards
4 with ARM Trusted Firmware
5 and multiple device trees (given on the command line)
7 usage: $0 <dt_name> [<dt_name> [<dt_name] ...]
14 # pip install pyelftools
15 from elftools
.elf
.elffile
import ELFFile
16 from elftools
.elf
.sections
import SymbolTableSection
17 from elftools
.elf
.segments
import Segment
, InterpSegment
, NoteSegment
19 ELF_SEG_P_TYPE
='p_type'
20 ELF_SEG_P_PADDR
='p_paddr'
21 ELF_SEG_P_VADDR
='p_vaddr'
22 ELF_SEG_P_OFFSET
='p_offset'
23 ELF_SEG_P_FILESZ
='p_filesz'
24 ELF_SEG_P_MEMSZ
='p_memsz'
27 * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd
29 * Minimal dts for a SPL FIT image payload.
31 * SPDX-License-Identifier: GPL-2.0+ X11
36 description = "Configuration to load ATF before U-Boot";
41 description = "U-Boot (64-bit)";
42 data = /incbin/("u-boot-nodtb.bin");
51 DT_IMAGES_NODE_END
="""
59 def append_atf_node(file, atf_index
, phy_addr
):
61 Append ATF DT node to input FIT dts file.
63 data
= 'bl31_0x%08x.bin' % phy_addr
64 print >> file, '\t\tatf@%d {' % atf_index
65 print >> file, '\t\t\tdescription = \"ARM Trusted Firmware\";'
66 print >> file, '\t\t\tdata = /incbin/("%s");' % data
67 print >> file, '\t\t\ttype = "firmware";'
68 print >> file, '\t\t\tarch = "arm64";'
69 print >> file, '\t\t\tos = "arm-trusted-firmware";'
70 print >> file, '\t\t\tcompression = "none";'
71 print >> file, '\t\t\tload = <0x%08x>;' % phy_addr
73 print >> file, '\t\t\tentry = <0x%08x>;' % phy_addr
74 print >> file, '\t\t};'
77 def append_fdt_node(file, dtbs
):
83 dtname
= os
.path
.basename(dtb
)
84 print >> file, '\t\tfdt@%d {' % cnt
85 print >> file, '\t\t\tdescription = "%s";' % dtname
86 print >> file, '\t\t\tdata = /incbin/("%s");' % dtb
87 print >> file, '\t\t\ttype = "flat_dt";'
88 print >> file, '\t\t\tcompression = "none";'
89 print >> file, '\t\t};'
93 def append_conf_section(file, cnt
, dtname
, atf_cnt
):
94 print >> file, '\t\tconfig@%d {' % cnt
95 print >> file, '\t\t\tdescription = "%s";' % dtname
96 print >> file, '\t\t\tfirmware = "atf@1";'
97 print >> file, '\t\t\tloadables = "uboot@1",',
98 for i
in range(1, atf_cnt
):
99 print >> file, '"atf@%d"' % (i
+1),
100 if i
!= (atf_cnt
- 1):
104 print >> file, '\t\t\tfdt = "fdt@1";'
105 print >> file, '\t\t};'
108 def append_conf_node(file, dtbs
, atf_cnt
):
110 Append configeration nodes.
113 print >> file, '\tconfigurations {'
114 print >> file, '\t\tdefault = "config@1";'
116 dtname
= os
.path
.basename(dtb
)
117 append_conf_section(file, cnt
, dtname
, atf_cnt
)
119 print >> file, '\t};'
122 def generate_atf_fit_dts(fit_file_name
, bl31_file_name
, uboot_file_name
, dtbs_file_name
):
124 Generate FIT script for ATF image.
126 if fit_file_name
!= sys
.stdout
:
127 fit_file
= open(fit_file_name
, "wb")
129 fit_file
= sys
.stdout
133 with
open(uboot_file_name
) as uboot_file
:
134 uboot
= ELFFile(uboot_file
)
135 for i
in range(uboot
.num_segments()):
136 seg
= uboot
.get_segment(i
)
137 if ('PT_LOAD' == seg
.__getitem
__(ELF_SEG_P_TYPE
)):
138 p_paddr
= seg
.__getitem
__(ELF_SEG_P_PADDR
)
139 num_load_seg
= num_load_seg
+ 1
141 assert (p_paddr
!= 0xFFFFFFFF and num_load_seg
== 1)
143 print >> fit_file
, DT_HEADER
% p_paddr
145 with
open(bl31_file_name
) as bl31_file
:
146 bl31
= ELFFile(bl31_file
)
147 for i
in range(bl31
.num_segments()):
148 seg
= bl31
.get_segment(i
)
149 if ('PT_LOAD' == seg
.__getitem
__(ELF_SEG_P_TYPE
)):
150 paddr
= seg
.__getitem
__(ELF_SEG_P_PADDR
)
151 p
= seg
.__getitem
__(ELF_SEG_P_PADDR
)
152 append_atf_node(fit_file
, i
+1, paddr
)
154 append_fdt_node(fit_file
, dtbs_file_name
)
155 print >> fit_file
, '%s' % DT_IMAGES_NODE_END
156 append_conf_node(fit_file
, dtbs_file_name
, atf_cnt
)
157 print >> fit_file
, '%s' % DT_END
159 if fit_file_name
!= sys
.stdout
:
162 def generate_atf_binary(bl31_file_name
):
163 with
open(bl31_file_name
) as bl31_file
:
164 bl31
= ELFFile(bl31_file
)
166 num
= bl31
.num_segments()
168 seg
= bl31
.get_segment(i
)
169 if ('PT_LOAD' == seg
.__getitem
__(ELF_SEG_P_TYPE
)):
170 paddr
= seg
.__getitem
__(ELF_SEG_P_PADDR
)
171 file_name
= 'bl31_0x%08x.bin' % paddr
172 with
open(file_name
, "wb") as atf
:
173 atf
.write(seg
.data());
175 def get_bl31_segments_info(bl31_file_name
):
177 Get load offset, physical offset, file size
178 from bl31 elf file program headers.
180 with
open(bl31_file_name
) as bl31_file
:
181 bl31
= ELFFile(bl31_file
)
183 num
= bl31
.num_segments()
184 print 'Number of Segments : %d' % bl31
.num_segments()
186 print 'Segment %d' % i
187 seg
= bl31
.get_segment(i
)
188 ptype
= seg
[ELF_SEG_P_TYPE
]
189 poffset
= seg
[ELF_SEG_P_OFFSET
]
190 pmemsz
= seg
[ELF_SEG_P_MEMSZ
]
191 pfilesz
= seg
[ELF_SEG_P_FILESZ
]
192 print 'type: %s\nfilesz: %08x\nmemsz: %08x\noffset: %08x' % (ptype
, pfilesz
, pmemsz
, poffset
)
193 paddr
= seg
[ELF_SEG_P_PADDR
]
194 print 'paddr: %08x' % paddr
198 bl31_elf
="./bl31.elf"
201 opts
, args
= getopt
.getopt(sys
.argv
[1:], "o:u:b:h")
202 for opt
, val
in opts
:
214 #get_bl31_segments_info("u-boot")
215 #get_bl31_segments_info("bl31.elf")
217 generate_atf_fit_dts(FIT_ITS
, bl31_elf
, uboot_elf
, dtbs
)
218 generate_atf_binary(bl31_elf
);
220 if __name__
== "__main__":