--- /dev/null
+inherit kernel-uboot kernel-artifact-names uboot-sign
+
+DEPENDS:append = " u-boot-tools-native dtc-native"
+
+FIT_GENERATE_KEYS = "1"
+UBOOT_SIGN_ENABLE = "1"
+
+FIT_DESC ?= "Kernel fitImage for ${DISTRO_NAME}/${PV}/${MACHINE}"
+FIT_CONF_PREFIX ?= "conf-"
+FIT_HASH_ALG ?= "sha1"
+FIT_SIGN_ALG ?= "rsa2048"
+
+UBOOT_SIGN_KEYDIR = "keys"
+UBOOT_SIGN_KEYNAME = "baikal"
+UBOOT_SIGN_IMG_KEYNAME = "baikal"
+UBOOT_MKIMAGE_DTCOPTS = "-I dts -O dtb -p 2000"
+
+fitimage_emit_fit_header() {
+ cat << EOF >> $1
+/dts-v1/;
+
+/ {
+ description = "${FIT_DESC}";
+ #address-cells = <1>;
+EOF
+}
+
+fitimage_emit_section_maint() {
+ case $2 in
+ imagestart)
+ cat << EOF >> $1
+
+ images {
+EOF
+ ;;
+ confstart)
+ cat << EOF >> $1
+
+ configurations {
+EOF
+ ;;
+ sectend)
+ cat << EOF >> $1
+ };
+EOF
+ ;;
+ fitend)
+ cat << EOF >> $1
+};
+EOF
+ ;;
+ esac
+}
+
+fitimage_emit_section_kernel() {
+
+ kernel_csum="crc32"
+ kernel_sign_algo="${FIT_SIGN_ALG}"
+ kernel_sign_keyname="${UBOOT_SIGN_IMG_KEYNAME}"
+
+ ENTRYPOINT="${UBOOT_ENTRYPOINT}"
+ if [ -n "${UBOOT_ENTRYSYMBOL}" ]; then
+ cd ${B}
+ ENTRYPOINT=`${HOST_PREFIX}nm vmlinux | \
+ awk '$3=="${UBOOT_ENTRYSYMBOL}" {print "0x"$1;exit}'`
+ cd -
+ fi
+
+ cat << EOF >> $1
+ kernel-$2 {
+ description = "Linux kernel";
+ data = /incbin/("$3");
+ type = "${UBOOT_MKIMAGE_KERNEL_TYPE}";
+ arch = "${UBOOT_ARCH}";
+ os = "linux";
+ compression = "$4";
+ load = <${UBOOT_LOADADDRESS}>;
+ entry = <$ENTRYPOINT>;
+ hash-1 {
+ algo = "$kernel_csum";
+ };
+ };
+EOF
+ if [ "${UBOOT_SIGN_ENABLE}" = "1" -a "${FIT_SIGN_INDIVIDUAL}" = "1" -a -n "$kernel_sign_keyname" ] ; then
+ sed -i '$ d' $1
+ cat << EOF >> $1
+ signature-1 {
+ algo = "$kernel_csum,$kernel_sign_algo";
+ key-name-hint = "$kernel_sign_keyname";
+ };
+ };
+EOF
+ fi
+}
+
+fitimage_emit_section_dtb() {
+
+ dtb_csum="crc32"
+ dtb_sign_algo="${FIT_SIGN_ALG}"
+ dtb_sign_keyname="${UBOOT_SIGN_IMG_KEYNAME}"
+
+ dtb_loadline=""
+ dtb_ext=${DTB##*.}
+ if [ "${dtb_ext}" = "dtbo" ]; then
+ if [ -n "${UBOOT_DTBO_LOADADDRESS}" ]; then
+ dtb_loadline="load = <${UBOOT_DTBO_LOADADDRESS}>;"
+ fi
+ elif [ -n "${UBOOT_DTB_LOADADDRESS}" ]; then
+ dtb_loadline="load = <${UBOOT_DTB_LOADADDRESS}>;"
+ fi
+ cat << EOF >> $1
+ fdt-$2 {
+ description = "Flattened Device Tree blob";
+ data = /incbin/("$3");
+ type = "flat_dt";
+ arch = "${UBOOT_ARCH}";
+ compression = "none";
+ $dtb_loadline
+ hash-1 {
+ algo = "$dtb_csum";
+ };
+ };
+EOF
+ if [ "${UBOOT_SIGN_ENABLE}" = "1" -a "${FIT_SIGN_INDIVIDUAL}" = "1" -a -n "$dtb_sign_keyname" ] ; then
+ sed -i '$ d' $1
+ cat << EOF >> $1
+ signature-1 {
+ algo = "$dtb_csum,$dtb_sign_algo";
+ key-name-hint = "$dtb_sign_keyname";
+ };
+ };
+EOF
+ fi
+}
+
+fitimage_emit_section_ramdisk() {
+
+ ramdisk_csum="crc32"
+ ramdisk_sign_algo="${FIT_SIGN_ALG}"
+ ramdisk_sign_keyname="${UBOOT_SIGN_IMG_KEYNAME}"
+ ramdisk_loadline=""
+ ramdisk_entryline=""
+
+ if [ -n "${UBOOT_RD_LOADADDRESS}" ]; then
+ ramdisk_loadline="load = <${UBOOT_RD_LOADADDRESS}>;"
+ fi
+ if [ -n "${UBOOT_RD_ENTRYPOINT}" ]; then
+ ramdisk_entryline="entry = <${UBOOT_RD_ENTRYPOINT}>;"
+ fi
+
+ cat << EOF >> $1
+ ramdisk-$2 {
+ description = "${INITRAMFS_IMAGE}";
+ data = /incbin/("$3");
+ type = "ramdisk";
+ arch = "${UBOOT_ARCH}";
+ os = "linux";
+ compression = "$4";
+ $ramdisk_loadline
+ $ramdisk_entryline
+ hash-1 {
+ algo = "$ramdisk_csum";
+ };
+ };
+EOF
+ if [ "${UBOOT_SIGN_ENABLE}" = "1" -a "${FIT_SIGN_INDIVIDUAL}" = "1" -a -n "$ramdisk_sign_keyname" ] ; then
+ sed -i '$ d' $1
+ cat << EOF >> $1
+ signature-1 {
+ algo = "$ramdisk_csum,$ramdisk_sign_algo";
+ key-name-hint = "$ramdisk_sign_keyname";
+ };
+ };
+EOF
+ fi
+}
+
+fitimage_emit_section_config() {
+
+ conf_csum="${FIT_HASH_ALG}"
+ conf_sign_algo="${FIT_SIGN_ALG}"
+ conf_padding_algo="${FIT_PAD_ALG}"
+ if [ "${UBOOT_SIGN_ENABLE}" = "1" ] ; then
+ conf_sign_keyname="${UBOOT_SIGN_KEYNAME}"
+ fi
+
+ its_file="$1"
+ kernel_id="$2"
+ dtb_image="$3"
+ ramdisk_id="$4"
+ config_id="$5"
+ default_flag="$6"
+
+ # Test if we have any DTBs at all
+ sep=""
+ conf_desc=""
+ conf_node="${FIT_CONF_PREFIX}"
+ kernel_line=""
+ fdt_line=""
+ ramdisk_line=""
+ default_line=""
+
+ # conf node name is selected based on dtb ID if it is present,
+ # otherwise its selected based on kernel ID
+ conf_node=$conf_node$5
+
+ if [ -n "$kernel_id" ]; then
+ conf_desc="Linux kernel"
+ sep=", "
+ kernel_line="kernel = \"kernel-$kernel_id\";"
+ fi
+
+ if [ -n "$dtb_image" ]; then
+ conf_desc="$conf_desc${sep}FDT blob"
+ sep=", "
+ fdt_line="fdt = \"fdt-$dtb_image\";"
+ fi
+
+ if [ -n "$ramdisk_id" ]; then
+ conf_desc="$conf_desc${sep}ramdisk"
+ sep=", "
+ ramdisk_line="ramdisk = \"ramdisk-$ramdisk_id\";"
+ fi
+
+ if [ "$default_flag" = "1" ]; then
+ # default node is selected based on dtb ID if it is present,
+ # otherwise its selected based on kernel ID
+ if [ -n "$dtb_image" ]; then
+ default_line="default = \"${FIT_CONF_PREFIX}$dtb_image\";"
+ else
+ default_line="default = \"${FIT_CONF_PREFIX}$kernel_id\";"
+ fi
+ fi
+
+ cat << EOF >> $its_file
+ $default_line
+ $conf_node {
+ description = "$conf_desc";
+ $kernel_line
+ $fdt_line
+ $ramdisk_line
+ hash-1 {
+ algo = "$conf_csum";
+ };
+EOF
+
+ if [ -n "$conf_sign_keyname" ] ; then
+ cat << EOF >> $its_file
+ signature-1 {
+ algo = "$conf_csum,$conf_sign_algo";
+ key-name-hint = "$conf_sign_keyname";
+ };
+EOF
+ fi
+
+ cat << EOF >> $its_file
+ };
+EOF
+}
+
+fitimage_assemble() {
+ rm -f $1
+
+ fitimage_emit_fit_header $1
+
+ fitimage_emit_section_maint $1 imagestart
+
+ fitimage_emit_section_kernel $1 1 "${BAIKAL_KERNEL}" "${BAIKAL_COMP_ALG}"
+
+ dtbcount=1
+ fitimage_emit_section_dtb $1 ${MACHINE}.dtb ${MACHINE}.dtb
+
+ initramfs_path="${BAIKAL_INITRAMFS}"
+ if [ -e "$initramfs_path" ]; then
+ bbnote "Found initramfs image: $initramfs_path"
+ fitimage_emit_section_ramdisk $1 1 "$initramfs_path" "${BAIKAL_COMP_ALG}"
+ break
+ else
+ bbfatal "Did not find initramfs image: $initramfs_path"
+ fi
+
+ initrd_path="${BAIKAL_INITRD}"
+ if [ -e "$initrd_path" ]; then
+ bbnote "Found initramfs image: $initrd_path"
+ fitimage_emit_section_ramdisk $1 2 "$initrd_path" "${BAIKAL_COMP_ALG}"
+ break
+ else
+ bbfatal "Did not find initramfs image: $initrd_path"
+ fi
+
+ fitimage_emit_section_maint $1 sectend
+
+ fitimage_emit_section_maint $1 confstart
+
+ fitimage_emit_section_config $1 1 1 2 1 1
+ fitimage_emit_section_config $1 1 1 1 2 0
+
+ fitimage_emit_section_maint $1 sectend
+
+ fitimage_emit_section_maint $1 fitend
+
+ ${UBOOT_MKIMAGE} \
+ ${@'-D "${UBOOT_MKIMAGE_DTCOPTS}"' if len('${UBOOT_MKIMAGE_DTCOPTS}') else ''} \
+ -f $1 $2
+
+ if [ "x${UBOOT_SIGN_ENABLE}" = "x1" ] ; then
+ add_key_to_u_boot=""
+ if [ -n "${UBOOT_DTB_BINARY}" ]; then
+ add_key_to_u_boot="-K ${UBOOT_DTB_BINARY}"
+ fi
+ ${UBOOT_MKIMAGE_SIGN} \
+ ${@'-D "${UBOOT_MKIMAGE_DTCOPTS}"' if len('${UBOOT_MKIMAGE_DTCOPTS}') else ''} \
+ -F -k "${UBOOT_SIGN_KEYDIR}" \
+ $add_key_to_u_boot \
+ -r $2 \
+ ${UBOOT_MKIMAGE_SIGN_ARGS}
+ fi
+}
+
+do_assemble_fitimage_initramfs() {
+ cd ${BAIKAL_IMAGES}
+ do_baikal_generate_rsa_keys
+ if [ -n "${INITRAMFS_IMAGE}" ]; then
+ fitimage_assemble umulti.its uMulti 1
+ fi
+}
+
+do_baikal_generate_rsa_keys() {
+ if [ "${UBOOT_SIGN_ENABLE}" = "0" ] && [ "${FIT_GENERATE_KEYS}" = "1" ]; then
+ bbwarn "FIT_GENERATE_KEYS is set to 1 even though UBOOT_SIGN_ENABLE is set to 0. The keys will not be generated as they won't be used."
+ fi
+
+ if [ "${UBOOT_SIGN_ENABLE}" = "1" ] && [ "${FIT_GENERATE_KEYS}" = "1" ]; then
+
+ # Generate keys to sign configuration nodes, only if they don't already exist
+ if [ ! -f "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_KEYNAME}".key ] || \
+ [ ! -f "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_KEYNAME}".crt ]; then
+
+ # make directory if it does not already exist
+ mkdir -p "${UBOOT_SIGN_KEYDIR}"
+
+ bbnote "Generating RSA private key for signing fitImage"
+ openssl genrsa ${FIT_KEY_GENRSA_ARGS} -out \
+ "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_KEYNAME}".key \
+ "${FIT_SIGN_NUMBITS}"
+
+ bbnote "Generating certificate for signing fitImage"
+ openssl req ${FIT_KEY_REQ_ARGS} "${FIT_KEY_SIGN_PKCS}" \
+ -key "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_KEYNAME}".key \
+ -out "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_KEYNAME}".crt
+ fi
+
+ # Generate keys to sign image nodes, only if they don't already exist
+ if [ ! -f "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_IMG_KEYNAME}".key ] || \
+ [ ! -f "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_IMG_KEYNAME}".crt ]; then
+
+ # make directory if it does not already exist
+ mkdir -p "${UBOOT_SIGN_KEYDIR}"
+
+ bbnote "Generating RSA private key for signing fitImage"
+ openssl genrsa ${FIT_KEY_GENRSA_ARGS} -out \
+ "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_IMG_KEYNAME}".key \
+ "${FIT_SIGN_NUMBITS}"
+
+ bbnote "Generating certificate for signing fitImage"
+ openssl req ${FIT_KEY_REQ_ARGS} "${FIT_KEY_SIGN_PKCS}" \
+ -key "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_IMG_KEYNAME}".key \
+ -out "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_IMG_KEYNAME}".crt
+ fi
+ fi
+}
--- /dev/null
+require recipes-kernel/linux/linux-fit.inc
+
+UBOOT_RD_LOADADDRESS ?= "0x80000000"
+UBOOT_RD_ENTRYPOINT ?= "0x80000000"
+
+UBOOT_RDI_LOADADDRESS ?= "0x86000000"
+UBOOT_RDI_ENTRYPOINT ?= "0x86000000"
+
+BAIKAL_COMP_ALG ?= "lzma"
+BAIKAL_COMP_ALG_EXTENSION ?= ".lzma"
+
+BAIKAL_KERNEL = "${MACHINE}.vmlinux.bin${BAIKAL_COMP_ALG_EXTENSION}"
+BAIKAL_INITRAMFS = "initramfs${BAIKAL_COMP_ALG_EXTENSION}"
+BAIKAL_INITRD = "initrd${BAIKAL_COMP_ALG_EXTENSION}"
+
+UBOOT_DTB_BINARY = "${WORKDIR}/baikal.dtb"
+UBOOT_DTS_FILE = "${WORKDIR}/baikal.dts"
+
+baikal_do_uinitramfs () {
+ uboot-mkimage -A ${UBOOT_ARCH} -O linux -T ramdisk -C ${BAIKAL_COMP_ALG} \
+ -a ${UBOOT_RD_LOADADDRESS} -e ${UBOOT_RD_ENTRYPOINT} \
+ -d "${BAIKAL_IMAGES}/initramfs${BAIKAL_COMP_ALG_EXTENSION}" \
+ -n "-" \
+ ${BAIKAL_IMAGES}/${MACHINE}.uInitramfs
+}
+
+baikal_do_uinitrd () {
+ uboot-mkimage -A ${UBOOT_ARCH} -O linux -T ramdisk -C ${BAIKAL_COMP_ALG} \
+ -a ${UBOOT_RDI_LOADADDRESS} -e ${UBOOT_RDI_ENTRYPOINT} \
+ -d "${BAIKAL_IMAGES}/initrd${BAIKAL_COMP_ALG_EXTENSION}" \
+ -n "+" \
+ ${BAIKAL_IMAGES}/${MACHINE}.uInitrd
+}
+
+baikal_do_ubootdtb () {
+ cat << EOF >> ${UBOOT_DTS_FILE}
+/dts-v1/;
+
+/ {
+ model = "Keys";
+ compatible = "be,baikal-t";
+
+ signature {
+ key-baikal {
+ required = "conf";
+ algo = "sha1,rsa2048";
+ key-name-hint = "baikal";
+ sign-images = "fdt", "kernel";
+ };
+ };
+};
+EOF
+ dtc -I dts -O dtb ${UBOOT_DTS_FILE} -o ${UBOOT_DTB_BINARY}
+}
+
+python baikal_entrysymbol () {
+ sys_map = d.getVar('B') + 'System.map'
+ with open(sys_map) as smap:
+ ln = smap.readline()
+ d.setVar('UBOOT_LOADADDRESS', '0x' + ln[8:16])
+ while True:
+ ln = smap.readline().split()
+ if ln[2] != 'kernel_entry':
+ continue
+ d.setVar('UBOOT_ENTRYPOINT', '0x' + ln[0][8:16])
+ break
+}
+
+baikal_do_umulti () {
+ baikal_do_ubootdtb
+ do_assemble_fitimage_initramfs
+}
+
+do_deploy[prefuncs] += "baikal_entrysymbol"
+
+do_deploy[prefuncs] += "baikal_do_umulti"