]> git.baikalelectronics.ru Git - openembedded-baikal.git/commitdiff
Add functions for building fit-image
authorBaikal Electronics <support@baikalelectronics.ru>
Mon, 26 Sep 2022 00:03:39 +0000 (03:03 +0300)
committerBaikal Electronics <support@baikalelectronics.ru>
Mon, 26 Sep 2022 00:03:39 +0000 (03:03 +0300)
meta-baikal/recipes-core/images/core-image-minimal.bbappend
meta-baikal/recipes-kernel/linux/linux-baikal_5.15.bb
meta-baikal/recipes-kernel/linux/linux-fit.inc [new file with mode: 0644]
meta-baikal/recipes-kernel/linux/linux-umulti.inc [new file with mode: 0644]

index 55efb8cd10ded7486def82d5e259a45ccd9ae5ea..3e58b35d4addd873187cbfdd74f22257b08a838d 100644 (file)
@@ -1,4 +1,4 @@
-IMAGE_ROOTFS_SIZE = "16384"
+IMAGE_ROOTFS_SIZE = "32768"
 IMAGE_NAME = "${PN}-baikal"
 
 RDEPENDS:append = " kernel-modules"
index f5645466d7c70bc25b1f3a302986810a00c9fac4..3d43ae8d6dc071d26fc7f482bf47b6dc0b0e7cad 100644 (file)
@@ -1,4 +1,5 @@
 require recipes-kernel/linux/linux-baikal.inc
+require recipes-kernel/linux/linux-umulti.inc
 
 inherit externalsrc
 inherit kernel-uimage
diff --git a/meta-baikal/recipes-kernel/linux/linux-fit.inc b/meta-baikal/recipes-kernel/linux/linux-fit.inc
new file mode 100644 (file)
index 0000000..a1ec87c
--- /dev/null
@@ -0,0 +1,371 @@
+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
+}
diff --git a/meta-baikal/recipes-kernel/linux/linux-umulti.inc b/meta-baikal/recipes-kernel/linux/linux-umulti.inc
new file mode 100644 (file)
index 0000000..5b850f8
--- /dev/null
@@ -0,0 +1,76 @@
+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"