kernel-fitimage.bbclass 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. inherit kernel-uboot kernel-artifact-names uboot-sign
  2. python __anonymous () {
  3. kerneltypes = d.getVar('KERNEL_IMAGETYPES') or ""
  4. if 'fitImage' in kerneltypes.split():
  5. depends = d.getVar("DEPENDS")
  6. depends = "%s u-boot-tools-native dtc-native" % depends
  7. d.setVar("DEPENDS", depends)
  8. uarch = d.getVar("UBOOT_ARCH")
  9. if uarch == "arm64":
  10. replacementtype = "Image"
  11. elif uarch == "mips":
  12. replacementtype = "vmlinuz.bin"
  13. elif uarch == "x86":
  14. replacementtype = "bzImage"
  15. elif uarch == "microblaze":
  16. replacementtype = "linux.bin"
  17. else:
  18. replacementtype = "zImage"
  19. # Override KERNEL_IMAGETYPE_FOR_MAKE variable, which is internal
  20. # to kernel.bbclass . We have to override it, since we pack zImage
  21. # (at least for now) into the fitImage .
  22. typeformake = d.getVar("KERNEL_IMAGETYPE_FOR_MAKE") or ""
  23. if 'fitImage' in typeformake.split():
  24. d.setVar('KERNEL_IMAGETYPE_FOR_MAKE', typeformake.replace('fitImage', replacementtype))
  25. image = d.getVar('INITRAMFS_IMAGE')
  26. if image:
  27. d.appendVarFlag('do_assemble_fitimage_initramfs', 'depends', ' ${INITRAMFS_IMAGE}:do_image_complete')
  28. # Verified boot will sign the fitImage and append the public key to
  29. # U-Boot dtb. We ensure the U-Boot dtb is deployed before assembling
  30. # the fitImage:
  31. if d.getVar('UBOOT_SIGN_ENABLE') == "1":
  32. uboot_pn = d.getVar('PREFERRED_PROVIDER_u-boot') or 'u-boot'
  33. d.appendVarFlag('do_assemble_fitimage', 'depends', ' %s:do_deploy' % uboot_pn)
  34. }
  35. # Options for the device tree compiler passed to mkimage '-D' feature:
  36. UBOOT_MKIMAGE_DTCOPTS ??= ""
  37. #
  38. # Emit the fitImage ITS header
  39. #
  40. # $1 ... .its filename
  41. fitimage_emit_fit_header() {
  42. cat << EOF >> ${1}
  43. /dts-v1/;
  44. / {
  45. description = "U-Boot fitImage for ${DISTRO_NAME}/${PV}/${MACHINE}";
  46. #address-cells = <1>;
  47. EOF
  48. }
  49. #
  50. # Emit the fitImage section bits
  51. #
  52. # $1 ... .its filename
  53. # $2 ... Section bit type: imagestart - image section start
  54. # confstart - configuration section start
  55. # sectend - section end
  56. # fitend - fitimage end
  57. #
  58. fitimage_emit_section_maint() {
  59. case $2 in
  60. imagestart)
  61. cat << EOF >> ${1}
  62. images {
  63. EOF
  64. ;;
  65. confstart)
  66. cat << EOF >> ${1}
  67. configurations {
  68. EOF
  69. ;;
  70. sectend)
  71. cat << EOF >> ${1}
  72. };
  73. EOF
  74. ;;
  75. fitend)
  76. cat << EOF >> ${1}
  77. };
  78. EOF
  79. ;;
  80. esac
  81. }
  82. #
  83. # Emit the fitImage ITS kernel section
  84. #
  85. # $1 ... .its filename
  86. # $2 ... Image counter
  87. # $3 ... Path to kernel image
  88. # $4 ... Compression type
  89. fitimage_emit_section_kernel() {
  90. kernel_csum="sha1"
  91. ENTRYPOINT="${UBOOT_ENTRYPOINT}"
  92. if [ -n "${UBOOT_ENTRYSYMBOL}" ]; then
  93. ENTRYPOINT=`${HOST_PREFIX}nm vmlinux | \
  94. awk '$3=="${UBOOT_ENTRYSYMBOL}" {print "0x"$1;exit}'`
  95. fi
  96. cat << EOF >> ${1}
  97. kernel@${2} {
  98. description = "Linux kernel";
  99. data = /incbin/("${3}");
  100. type = "kernel";
  101. arch = "${UBOOT_ARCH}";
  102. os = "linux";
  103. compression = "${4}";
  104. load = <${UBOOT_LOADADDRESS}>;
  105. entry = <${ENTRYPOINT}>;
  106. hash@1 {
  107. algo = "${kernel_csum}";
  108. };
  109. };
  110. EOF
  111. }
  112. #
  113. # Emit the fitImage ITS DTB section
  114. #
  115. # $1 ... .its filename
  116. # $2 ... Image counter
  117. # $3 ... Path to DTB image
  118. fitimage_emit_section_dtb() {
  119. dtb_csum="sha1"
  120. dtb_loadline=""
  121. dtb_ext=${DTB##*.}
  122. if [ "${dtb_ext}" = "dtbo" ]; then
  123. if [ -n "${UBOOT_DTBO_LOADADDRESS}" ]; then
  124. dtb_loadline="load = <${UBOOT_DTBO_LOADADDRESS}>;"
  125. fi
  126. elif [ -n "${UBOOT_DTB_LOADADDRESS}" ]; then
  127. dtb_loadline="load = <${UBOOT_DTB_LOADADDRESS}>;"
  128. fi
  129. cat << EOF >> ${1}
  130. fdt@${2} {
  131. description = "Flattened Device Tree blob";
  132. data = /incbin/("${3}");
  133. type = "flat_dt";
  134. arch = "${UBOOT_ARCH}";
  135. compression = "none";
  136. ${dtb_loadline}
  137. hash@1 {
  138. algo = "${dtb_csum}";
  139. };
  140. };
  141. EOF
  142. }
  143. #
  144. # Emit the fitImage ITS setup section
  145. #
  146. # $1 ... .its filename
  147. # $2 ... Image counter
  148. # $3 ... Path to setup image
  149. fitimage_emit_section_setup() {
  150. setup_csum="sha1"
  151. cat << EOF >> ${1}
  152. setup@${2} {
  153. description = "Linux setup.bin";
  154. data = /incbin/("${3}");
  155. type = "x86_setup";
  156. arch = "${UBOOT_ARCH}";
  157. os = "linux";
  158. compression = "none";
  159. load = <0x00090000>;
  160. entry = <0x00090000>;
  161. hash@1 {
  162. algo = "${setup_csum}";
  163. };
  164. };
  165. EOF
  166. }
  167. #
  168. # Emit the fitImage ITS ramdisk section
  169. #
  170. # $1 ... .its filename
  171. # $2 ... Image counter
  172. # $3 ... Path to ramdisk image
  173. fitimage_emit_section_ramdisk() {
  174. ramdisk_csum="sha1"
  175. ramdisk_ctype="none"
  176. ramdisk_loadline=""
  177. ramdisk_entryline=""
  178. if [ -n "${UBOOT_RD_LOADADDRESS}" ]; then
  179. ramdisk_loadline="load = <${UBOOT_RD_LOADADDRESS}>;"
  180. fi
  181. if [ -n "${UBOOT_RD_ENTRYPOINT}" ]; then
  182. ramdisk_entryline="entry = <${UBOOT_RD_ENTRYPOINT}>;"
  183. fi
  184. case $3 in
  185. *.gz)
  186. ramdisk_ctype="gzip"
  187. ;;
  188. *.bz2)
  189. ramdisk_ctype="bzip2"
  190. ;;
  191. *.lzma)
  192. ramdisk_ctype="lzma"
  193. ;;
  194. *.lzo)
  195. ramdisk_ctype="lzo"
  196. ;;
  197. *.lz4)
  198. ramdisk_ctype="lz4"
  199. ;;
  200. esac
  201. cat << EOF >> ${1}
  202. ramdisk@${2} {
  203. description = "${INITRAMFS_IMAGE}";
  204. data = /incbin/("${3}");
  205. type = "ramdisk";
  206. arch = "${UBOOT_ARCH}";
  207. os = "linux";
  208. compression = "${ramdisk_ctype}";
  209. ${ramdisk_loadline}
  210. ${ramdisk_entryline}
  211. hash@1 {
  212. algo = "${ramdisk_csum}";
  213. };
  214. };
  215. EOF
  216. }
  217. #
  218. # Emit the fitImage ITS configuration section
  219. #
  220. # $1 ... .its filename
  221. # $2 ... Linux kernel ID
  222. # $3 ... DTB image name
  223. # $4 ... ramdisk ID
  224. # $5 ... config ID
  225. # $6 ... default flag
  226. fitimage_emit_section_config() {
  227. conf_csum="sha1"
  228. if [ -n "${UBOOT_SIGN_ENABLE}" ] ; then
  229. conf_sign_keyname="${UBOOT_SIGN_KEYNAME}"
  230. fi
  231. # Test if we have any DTBs at all
  232. sep=""
  233. conf_desc=""
  234. kernel_line=""
  235. fdt_line=""
  236. ramdisk_line=""
  237. setup_line=""
  238. default_line=""
  239. if [ -n "${2}" ]; then
  240. conf_desc="Linux kernel"
  241. sep=", "
  242. kernel_line="kernel = \"kernel@${2}\";"
  243. fi
  244. if [ -n "${3}" ]; then
  245. conf_desc="${conf_desc}${sep}FDT blob"
  246. sep=", "
  247. fdt_line="fdt = \"fdt@${3}\";"
  248. fi
  249. if [ -n "${4}" ]; then
  250. conf_desc="${conf_desc}${sep}ramdisk"
  251. sep=", "
  252. ramdisk_line="ramdisk = \"ramdisk@${4}\";"
  253. fi
  254. if [ -n "${5}" ]; then
  255. conf_desc="${conf_desc}${sep}setup"
  256. setup_line="setup = \"setup@${5}\";"
  257. fi
  258. if [ "${6}" = "1" ]; then
  259. default_line="default = \"conf@${3}\";"
  260. fi
  261. cat << EOF >> ${1}
  262. ${default_line}
  263. conf@${3} {
  264. description = "${6} ${conf_desc}";
  265. ${kernel_line}
  266. ${fdt_line}
  267. ${ramdisk_line}
  268. ${setup_line}
  269. hash@1 {
  270. algo = "${conf_csum}";
  271. };
  272. EOF
  273. if [ ! -z "${conf_sign_keyname}" ] ; then
  274. sign_line="sign-images = "
  275. sep=""
  276. if [ -n "${2}" ]; then
  277. sign_line="${sign_line}${sep}\"kernel\""
  278. sep=", "
  279. fi
  280. if [ -n "${3}" ]; then
  281. sign_line="${sign_line}${sep}\"fdt\""
  282. sep=", "
  283. fi
  284. if [ -n "${4}" ]; then
  285. sign_line="${sign_line}${sep}\"ramdisk\""
  286. sep=", "
  287. fi
  288. if [ -n "${5}" ]; then
  289. sign_line="${sign_line}${sep}\"setup\""
  290. fi
  291. sign_line="${sign_line};"
  292. cat << EOF >> ${1}
  293. signature@1 {
  294. algo = "${conf_csum},rsa2048";
  295. key-name-hint = "${conf_sign_keyname}";
  296. ${sign_line}
  297. };
  298. EOF
  299. fi
  300. cat << EOF >> ${1}
  301. };
  302. EOF
  303. }
  304. #
  305. # Assemble fitImage
  306. #
  307. # $1 ... .its filename
  308. # $2 ... fitImage name
  309. # $3 ... include ramdisk
  310. fitimage_assemble() {
  311. kernelcount=1
  312. dtbcount=""
  313. DTBS=""
  314. ramdiskcount=${3}
  315. setupcount=""
  316. rm -f ${1} arch/${ARCH}/boot/${2}
  317. fitimage_emit_fit_header ${1}
  318. #
  319. # Step 1: Prepare a kernel image section.
  320. #
  321. fitimage_emit_section_maint ${1} imagestart
  322. uboot_prep_kimage
  323. fitimage_emit_section_kernel ${1} "${kernelcount}" linux.bin "${linux_comp}"
  324. #
  325. # Step 2: Prepare a DTB image section
  326. #
  327. if [ -n "${KERNEL_DEVICETREE}" ]; then
  328. dtbcount=1
  329. for DTB in ${KERNEL_DEVICETREE}; do
  330. if echo ${DTB} | grep -q '/dts/'; then
  331. bbwarn "${DTB} contains the full path to the the dts file, but only the dtb name should be used."
  332. DTB=`basename ${DTB} | sed 's,\.dts$,.dtb,g'`
  333. fi
  334. DTB_PATH="arch/${ARCH}/boot/dts/${DTB}"
  335. if [ ! -e "${DTB_PATH}" ]; then
  336. DTB_PATH="arch/${ARCH}/boot/${DTB}"
  337. fi
  338. DTB=$(echo "${DTB}" | tr '/' '_')
  339. DTBS="${DTBS} ${DTB}"
  340. fitimage_emit_section_dtb ${1} ${DTB} ${DTB_PATH}
  341. done
  342. fi
  343. #
  344. # Step 3: Prepare a setup section. (For x86)
  345. #
  346. if [ -e arch/${ARCH}/boot/setup.bin ]; then
  347. setupcount=1
  348. fitimage_emit_section_setup ${1} "${setupcount}" arch/${ARCH}/boot/setup.bin
  349. fi
  350. #
  351. # Step 4: Prepare a ramdisk section.
  352. #
  353. if [ "x${ramdiskcount}" = "x1" ] ; then
  354. # Find and use the first initramfs image archive type we find
  355. for img in cpio.lz4 cpio.lzo cpio.lzma cpio.xz cpio.gz ext2.gz cpio; do
  356. initramfs_path="${DEPLOY_DIR_IMAGE}/${INITRAMFS_IMAGE_NAME}.${img}"
  357. echo "Using $initramfs_path"
  358. if [ -e "${initramfs_path}" ]; then
  359. fitimage_emit_section_ramdisk ${1} "${ramdiskcount}" "${initramfs_path}"
  360. break
  361. fi
  362. done
  363. fi
  364. fitimage_emit_section_maint ${1} sectend
  365. # Force the first Kernel and DTB in the default config
  366. kernelcount=1
  367. if [ -n "${dtbcount}" ]; then
  368. dtbcount=1
  369. fi
  370. #
  371. # Step 5: Prepare a configurations section
  372. #
  373. fitimage_emit_section_maint ${1} confstart
  374. if [ -n "${DTBS}" ]; then
  375. i=1
  376. for DTB in ${DTBS}; do
  377. dtb_ext=${DTB##*.}
  378. if [ "${dtb_ext}" = "dtbo" ]; then
  379. fitimage_emit_section_config ${1} "" "${DTB}" "" "" "`expr ${i} = ${dtbcount}`"
  380. else
  381. fitimage_emit_section_config ${1} "${kernelcount}" "${DTB}" "${ramdiskcount}" "${setupcount}" "`expr ${i} = ${dtbcount}`"
  382. fi
  383. i=`expr ${i} + 1`
  384. done
  385. fi
  386. fitimage_emit_section_maint ${1} sectend
  387. fitimage_emit_section_maint ${1} fitend
  388. #
  389. # Step 6: Assemble the image
  390. #
  391. uboot-mkimage \
  392. ${@'-D "${UBOOT_MKIMAGE_DTCOPTS}"' if len('${UBOOT_MKIMAGE_DTCOPTS}') else ''} \
  393. -f ${1} \
  394. arch/${ARCH}/boot/${2}
  395. #
  396. # Step 7: Sign the image and add public key to U-Boot dtb
  397. #
  398. if [ "x${UBOOT_SIGN_ENABLE}" = "x1" ] ; then
  399. uboot-mkimage \
  400. ${@'-D "${UBOOT_MKIMAGE_DTCOPTS}"' if len('${UBOOT_MKIMAGE_DTCOPTS}') else ''} \
  401. -F -k "${UBOOT_SIGN_KEYDIR}" \
  402. ${@'-K "${DEPLOY_DIR_IMAGE}/${UBOOT_DTB_BINARY}"' if len('${UBOOT_DTB_BINARY}') else ''} \
  403. -r arch/${ARCH}/boot/${2}
  404. fi
  405. }
  406. do_assemble_fitimage() {
  407. if echo ${KERNEL_IMAGETYPES} | grep -wq "fitImage"; then
  408. cd ${B}
  409. fitimage_assemble fit-image.its fitImage
  410. fi
  411. }
  412. addtask assemble_fitimage before do_install after do_compile
  413. do_assemble_fitimage_initramfs() {
  414. if echo ${KERNEL_IMAGETYPES} | grep -wq "fitImage" && \
  415. test -n "${INITRAMFS_IMAGE}" ; then
  416. cd ${B}
  417. fitimage_assemble fit-image-${INITRAMFS_IMAGE}.its fitImage-${INITRAMFS_IMAGE} 1
  418. fi
  419. }
  420. addtask assemble_fitimage_initramfs before do_deploy after do_install
  421. kernel_do_deploy[vardepsexclude] = "DATETIME"
  422. kernel_do_deploy_append() {
  423. # Update deploy directory
  424. if echo ${KERNEL_IMAGETYPES} | grep -wq "fitImage"; then
  425. echo "Copying fit-image.its source file..."
  426. install -m 0644 ${B}/fit-image.its ${DEPLOYDIR}/fitImage-its-${KERNEL_FIT_NAME}.its
  427. ln -snf fitImage-its-${KERNEL_FIT_NAME}.its ${DEPLOYDIR}/fitImage-its-${KERNEL_FIT_LINK_NAME}
  428. echo "Copying linux.bin file..."
  429. install -m 0644 ${B}/linux.bin ${DEPLOYDIR}/fitImage-linux.bin-${KERNEL_FIT_NAME}.bin
  430. ln -snf fitImage-linux.bin-${KERNEL_FIT_NAME}.bin ${DEPLOYDIR}/fitImage-linux.bin-${KERNEL_FIT_LINK_NAME}
  431. if [ -n "${INITRAMFS_IMAGE}" ]; then
  432. echo "Copying fit-image-${INITRAMFS_IMAGE}.its source file..."
  433. install -m 0644 ${B}/fit-image-${INITRAMFS_IMAGE}.its ${DEPLOYDIR}/fitImage-its-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_NAME}.its
  434. ln -snf fitImage-its-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_NAME}.its ${DEPLOYDIR}/fitImage-its-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_LINK_NAME}
  435. echo "Copying fitImage-${INITRAMFS_IMAGE} file..."
  436. install -m 0644 ${B}/arch/${ARCH}/boot/fitImage-${INITRAMFS_IMAGE} ${DEPLOYDIR}/fitImage-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_NAME}.bin
  437. ln -snf fitImage-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_NAME}.bin ${DEPLOYDIR}/fitImage-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_LINK_NAME}
  438. fi
  439. fi
  440. }