diff options
author | Anton Gerasimov <anton@advancedtelematic.com> | 2016-10-25 11:08:50 +0200 |
---|---|---|
committer | Anton Gerasimov <anton@advancedtelematic.com> | 2016-10-27 11:35:21 +0200 |
commit | 1b73e59ec2703605ad20ea7b42516cb382a5436a (patch) | |
tree | 1b5f5c79a1744f5af1faf9dfc93476282e3ad202 | |
parent | eadecc11aac1b0de7a0841213f647e35ccf5a6a1 (diff) |
OSTree-enabled image for raspberry Pi
Bug-AGL: SPEC-254
v2 [jsmoeller]: change rpi fdt addr to 200M (fix cma),
re-add inherit gobject-introspection (!)
v3 [oytis]: move boot logic to editable uEnv.txt
Change-Id: Ic54aadc8377ed1e2a8f2f4ab87db2a7a6660cd15
Signed-off-by: Anton Gerasimov <anton@advancedtelematic.com>
Signed-off-by: Jan-Simon Möller <jsmoeller@linuxfoundation.org>
11 files changed, 261 insertions, 6 deletions
diff --git a/meta-sota/classes/image_types_ostree.bbclass b/meta-sota/classes/image_types_ostree.bbclass index 4353af7..f3eafd7 100644 --- a/meta-sota/classes/image_types_ostree.bbclass +++ b/meta-sota/classes/image_types_ostree.bbclass @@ -9,6 +9,9 @@ IMAGE_DEPENDS_ostree = "ostree-native:do_populate_sysroot \ export OSTREE_REPO export OSTREE_BRANCHNAME +RAMDISK_EXT ?= ".ext4.gz" +RAMDISK_EXT_arm = ".ext4.gz.u-boot" + IMAGE_CMD_ostree () { if [ -z "$OSTREE_REPO" ]; then bbfatal "OSTREE_REPO should be set in your local.conf" @@ -93,7 +96,7 @@ IMAGE_CMD_ostree () { checksum=`sha256sum ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE} | cut -f 1 -d " "` cp ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE} boot/vmlinuz-${checksum} - cp ${DEPLOY_DIR_IMAGE}/${OSTREE_INITRAMFS_IMAGE}-${MACHINE}.ext4.gz boot/initramfs-${checksum} + cp ${DEPLOY_DIR_IMAGE}/${OSTREE_INITRAMFS_IMAGE}-${MACHINE}${RAMDISK_EXT} boot/initramfs-${checksum} cd ${WORKDIR} diff --git a/meta-sota/classes/sdcard_image-rpi-ota.bbclass b/meta-sota/classes/sdcard_image-rpi-ota.bbclass new file mode 100644 index 0000000..12c1f40 --- /dev/null +++ b/meta-sota/classes/sdcard_image-rpi-ota.bbclass @@ -0,0 +1,191 @@ +inherit image_types +inherit linux-raspberrypi-base + +# +# Create an image that can by written onto a SD card using dd. +# +# The disk layout used is: +# +# 0 -> IMAGE_ROOTFS_ALIGNMENT - reserved for other data +# IMAGE_ROOTFS_ALIGNMENT -> BOOT_SPACE - bootloader and kernel +# BOOT_SPACE -> SDIMG_OTA_SIZE - rootfs +# + +# Default Free space = 1.3x +# Use IMAGE_OVERHEAD_FACTOR to add more space +# <---------> +# 4MiB 40MiB SDIMG_OTA_ROOTFS +# <-----------------------> <----------> <----------------------> +# ------------------------ ------------ ------------------------ +# | IMAGE_ROOTFS_ALIGNMENT | BOOT_SPACE | OTAROOT_SIZE | +# ------------------------ ------------ ------------------------ +# ^ ^ ^ ^ +# | | | | +# 0 4MiB 4MiB + 40MiB 4MiB + 40Mib + SDIMG_OTA_ROOTFS + +# This image depends on the rootfs image +IMAGE_TYPEDEP_rpi-sdimg-ota = "${SDIMG_OTA_ROOTFS_TYPE}" + +# Set kernel and boot loader +IMAGE_BOOTLOADER ?= "bcm2835-bootfiles" + +# Set initramfs extension +KERNEL_INITRAMFS ?= "" + +# Kernel image name +SDIMG_OTA_KERNELIMAGE_raspberrypi ?= "kernel.img" +SDIMG_OTA_KERNELIMAGE_raspberrypi2 ?= "kernel7.img" + +# Boot partition volume id +BOOTDD_VOLUME_ID ?= "${MACHINE}" + +# Boot partition size [in KiB] (will be rounded up to IMAGE_ROOTFS_ALIGNMENT) +BOOT_SPACE ?= "40960" + +# Set alignment to 4MB [in KiB] +IMAGE_ROOTFS_ALIGNMENT = "4096" + +# Use an uncompressed ext3 by default as rootfs +SDIMG_OTA_ROOTFS_TYPE ?= "otaimg" +SDIMG_OTA_ROOTFS = "${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}.${SDIMG_OTA_ROOTFS_TYPE}" + +IMAGE_DEPENDS_rpi-sdimg-ota = " \ + parted-native \ + mtools-native \ + dosfstools-native \ + virtual/kernel:do_deploy \ + ${IMAGE_BOOTLOADER} \ + u-boot \ + " +IMAGE_TYPEDEP_rpi-sdimg-ota = "otaimg" + +# SD card image name +SDIMG_OTA = "${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.rpi-sdimg-ota" + +# Compression method to apply to SDIMG_OTA after it has been created. Supported +# compression formats are "gzip", "bzip2" or "xz". The original .rpi-sdimg-ota file +# is kept and a new compressed file is created if one of these compression +# formats is chosen. If SDIMG_OTA_COMPRESSION is set to any other value it is +# silently ignored. +#SDIMG_OTA_COMPRESSION ?= "" + +# Additional files and/or directories to be copied into the vfat partition from the IMAGE_ROOTFS. +FATPAYLOAD ?= "" + +IMAGEDATESTAMP = "${@time.strftime('%Y.%m.%d',time.gmtime())}" +IMAGE_CMD_rpi-sdimg-ota[vardepsexclude] += "IMAGEDATESTAMP" +IMAGE_CMD_rpi-sdimg-ota[vardepsexclude] += "DATETIME" + +IMAGE_CMD_rpi-sdimg-ota () { + + # Align partitions + OTAROOT_SIZE=`du -Lb ${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}.${SDIMG_OTA_ROOTFS_TYPE} | cut -f1` + OTAROOT_SIZE=$(expr ${OTAROOT_SIZE} / 1024 + 1) + BOOT_SPACE_ALIGNED=$(expr ${BOOT_SPACE} + ${IMAGE_ROOTFS_ALIGNMENT} - 1) + BOOT_SPACE_ALIGNED=$(expr ${BOOT_SPACE_ALIGNED} - ${BOOT_SPACE_ALIGNED} % ${IMAGE_ROOTFS_ALIGNMENT}) + SDIMG_OTA_SIZE=$(expr ${IMAGE_ROOTFS_ALIGNMENT} + ${BOOT_SPACE_ALIGNED} + $OTAROOT_SIZE) + + echo "Creating filesystem with Boot partition ${BOOT_SPACE_ALIGNED} KiB and RootFS $OTAROOT_SIZE KiB" + + # Check if we are building with device tree support + DTS="${@get_dts(d, None)}" + + # Initialize sdcard image file + dd if=/dev/zero of=${SDIMG_OTA} bs=1024 count=0 seek=${SDIMG_OTA_SIZE} + + # Create partition table + parted -s ${SDIMG_OTA} mklabel msdos + # Create boot partition and mark it as bootable + parted -s ${SDIMG_OTA} unit KiB mkpart primary fat32 ${IMAGE_ROOTFS_ALIGNMENT} $(expr ${BOOT_SPACE_ALIGNED} \+ ${IMAGE_ROOTFS_ALIGNMENT}) + parted -s ${SDIMG_OTA} set 1 boot on + # Create rootfs partition to the end of disk + parted -s ${SDIMG_OTA} -- unit KiB mkpart primary ext2 $(expr ${BOOT_SPACE_ALIGNED} \+ ${IMAGE_ROOTFS_ALIGNMENT}) -1s + parted ${SDIMG_OTA} print + + # Create a vfat image with boot files + BOOT_BLOCKS=$(LC_ALL=C parted -s ${SDIMG_OTA} unit b print | awk '/ 1 / { print substr($4, 1, length($4 -1)) / 512 /2 }') + rm -f ${WORKDIR}/boot.img + mkfs.vfat -n "${BOOTDD_VOLUME_ID}" -S 512 -C ${WORKDIR}/boot.img $BOOT_BLOCKS + sync + + mcopy -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/bcm2835-bootfiles/* ::/ + + if test -n "${DTS}"; then + # Device Tree Overlays are assumed to be suffixed by '-overlay.dtb' string and will be put in a dedicated folder + DT_OVERLAYS="${@split_overlays(d, 0)}" + DT_ROOT="${@split_overlays(d, 1)}" + + # Copy board device trees to root folder + for DTB in ${DT_ROOT}; do + DTB_BASE_NAME=`basename ${DTB} .dtb` + + mcopy -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-${DTB_BASE_NAME}.dtb ::${DTB_BASE_NAME}.dtb + done + + # Copy device tree overlays to dedicated folder + mmd -i ${WORKDIR}/boot.img overlays + for DTB in ${DT_OVERLAYS}; do + DTB_BASE_NAME=`basename ${DTB} .dtb` + mcopy -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-${DTB_BASE_NAME}.dtb ::overlays/${DTB_BASE_NAME}.dtbo + done + fi + + case "${KERNEL_IMAGETYPE}" in + "uImage") + mcopy -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/u-boot.bin ::${SDIMG_OTA_KERNELIMAGE} + ;; + *) + bbfatal "Kernel uImage is required for OTA image. Please set KERNEL_IMAGETYPE to \"uImage\"" + ;; + esac + + if [ -n ${FATPAYLOAD} ] ; then + echo "Copying payload into VFAT" + for entry in ${FATPAYLOAD} ; do + # add the || true to stop aborting on vfat issues like not supporting .~lock files + mcopy -i ${WORKDIR}/boot.img -s -v ${IMAGE_ROOTFS}$entry :: || true + done + fi + + # Add stamp file + echo "${IMAGE_NAME}-${IMAGEDATESTAMP}" > ${WORKDIR}/image-version-info + mcopy -i ${WORKDIR}/boot.img -v ${WORKDIR}//image-version-info :: + + # Burn Partitions + sync + dd if=${WORKDIR}/boot.img of=${SDIMG_OTA} conv=notrunc seek=1 bs=$(expr ${IMAGE_ROOTFS_ALIGNMENT} \* 1024) && sync && sync + # If SDIMG_OTA_ROOTFS_TYPE is a .xz file use xzcat + if echo "${SDIMG_OTA_ROOTFS_TYPE}" | egrep -q "*\.xz" + then + xzcat ${SDIMG_OTA_ROOTFS} | dd of=${SDIMG_OTA} conv=notrunc seek=1 bs=$(expr 1024 \* ${BOOT_SPACE_ALIGNED} + ${IMAGE_ROOTFS_ALIGNMENT} \* 1024) && sync && sync + else + dd if=${SDIMG_OTA_ROOTFS} of=${SDIMG_OTA} conv=notrunc seek=1 bs=$(expr 1024 \* ${BOOT_SPACE_ALIGNED} + ${IMAGE_ROOTFS_ALIGNMENT} \* 1024) && sync && sync + fi + + # Optionally apply compression + case "${SDIMG_OTA_COMPRESSION}" in + "gzip") + gzip -k9 "${SDIMG_OTA}" + ;; + "bzip2") + bzip2 -k9 "${SDIMG_OTA}" + ;; + "xz") + xz -k "${SDIMG_OTA}" + ;; + esac +} + +ROOTFS_POSTPROCESS_COMMAND += " rpi_generate_sysctl_config ; " + +rpi_generate_sysctl_config() { + # systemd sysctl config + test -d ${IMAGE_ROOTFS}${sysconfdir}/sysctl.d && \ + echo "vm.min_free_kbytes = 8192" > ${IMAGE_ROOTFS}${sysconfdir}/sysctl.d/rpi-vm.conf + + # sysv sysctl config + IMAGE_SYSCTL_CONF="${IMAGE_ROOTFS}${sysconfdir}/sysctl.conf" + test -e ${IMAGE_ROOTFS}${sysconfdir}/sysctl.conf && \ + sed -e "/vm.min_free_kbytes/d" -i ${IMAGE_SYSCTL_CONF} + echo "" >> ${IMAGE_SYSCTL_CONF} && echo "vm.min_free_kbytes = 8192" >> ${IMAGE_SYSCTL_CONF} +} diff --git a/meta-sota/recipes-bsp/bootfiles/bcm2835-bootfiles.bbappend b/meta-sota/recipes-bsp/bootfiles/bcm2835-bootfiles.bbappend new file mode 100644 index 0000000..74aa6b1 --- /dev/null +++ b/meta-sota/recipes-bsp/bootfiles/bcm2835-bootfiles.bbappend @@ -0,0 +1 @@ +RDEPENDS_${PN} += " u-boot-otascript" diff --git a/meta-sota/recipes-bsp/bootfiles/rpi-config_git.bbappend b/meta-sota/recipes-bsp/bootfiles/rpi-config_git.bbappend new file mode 100644 index 0000000..6e53993 --- /dev/null +++ b/meta-sota/recipes-bsp/bootfiles/rpi-config_git.bbappend @@ -0,0 +1,3 @@ +do_deploy_append() { + echo "device_tree_address=0x0c800000" >> ${DEPLOYDIR}/bcm2835-bootfiles/config.txt +} diff --git a/meta-sota/recipes-bsp/u-boot-otascript/u-boot-otascript.bb b/meta-sota/recipes-bsp/u-boot-otascript/u-boot-otascript.bb new file mode 100644 index 0000000..9f5f0ca --- /dev/null +++ b/meta-sota/recipes-bsp/u-boot-otascript/u-boot-otascript.bb @@ -0,0 +1,26 @@ +DESCRIPTION = "Boot script for launching OTA-enabled images on raspberrypi" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" + +DEPENDS = "u-boot-mkimage-native" + +COMPATIBLE_MACHINE = "raspberrypi" + +SRC_URI = "file://boot.scr \ + file://uEnv.txt" + +S = "${WORKDIR}" + +inherit deploy + +do_deploy() { + install -d ${DEPLOYDIR}/bcm2835-bootfiles + + mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n "Ostree boot script" -d ${S}/boot.scr ${DEPLOYDIR}/bcm2835-bootfiles/boot.scr + install -m 0755 ${S}/uEnv.txt ${DEPLOYDIR}/bcm2835-bootfiles/uEnv.txt +} + +addtask deploy before do_package after do_install +do_deploy[dirs] += "${DEPLOYDIR}/bcm2835-bootfiles" + +PACKAGE_ARCH = "${MACHINE_ARCH}" diff --git a/meta-sota/recipes-bsp/u-boot-otascript/u-boot-otascript/boot.scr b/meta-sota/recipes-bsp/u-boot-otascript/u-boot-otascript/boot.scr new file mode 100644 index 0000000..dc13f85 --- /dev/null +++ b/meta-sota/recipes-bsp/u-boot-otascript/u-boot-otascript/boot.scr @@ -0,0 +1,3 @@ +fatload mmc 0:1 $loadaddr /uEnv.txt +env import -t $loadaddr $filesize +run bootcmd diff --git a/meta-sota/recipes-bsp/u-boot-otascript/u-boot-otascript/uEnv.txt b/meta-sota/recipes-bsp/u-boot-otascript/u-boot-otascript/uEnv.txt new file mode 100644 index 0000000..f6c0570 --- /dev/null +++ b/meta-sota/recipes-bsp/u-boot-otascript/u-boot-otascript/uEnv.txt @@ -0,0 +1,7 @@ +fdt_addr_r=0x0c800000 +bootcmd_dtb=fdt addr $fdt_addr_r; fdt get value bootargs_fdt /chosen bootargs +bootcmd_otenv=ext2load mmc 0:2 $loadaddr /boot/loader/uEnv.txt; env import -t $loadaddr $filesize +bootcmd_args=setenv bootargs "$bootargs $bootargs_fdt ostree_root=/dev/mmcblk0p2 root=/dev/ram0 rw rootwait rootdelay=2 ramdisk_size=8192" +bootcmd_load=ext2load mmc 0:2 $kernel_addr_r "/boot"$kernel_image; ext2load mmc 0:2 $ramdisk_addr_r "/boot"$ramdisk_image +bootcmd_run=bootm $kernel_addr_r $ramdisk_addr_r $fdt_addr_r +bootcmd=run bootcmd_dtb; run bootcmd_otenv; run bootcmd_args; run bootcmd_load; run bootcmd_run diff --git a/meta-sota/recipes-bsp/u-boot/u-boot_2016.11.bb b/meta-sota/recipes-bsp/u-boot/u-boot_2016.11.bb new file mode 100644 index 0000000..a05b37f --- /dev/null +++ b/meta-sota/recipes-bsp/u-boot/u-boot_2016.11.bb @@ -0,0 +1,7 @@ +require recipes-bsp/u-boot/u-boot.inc + +DEPENDS += "dtc-native" + +SRCREV = "5ea3e51fc481613a8dee8c02848d1b42c81ad892" + +PV = "v2016.11+git${SRCPV}" diff --git a/meta-sota/recipes-core/images/initramfs-ostree-image.bb b/meta-sota/recipes-core/images/initramfs-ostree-image.bb index e4123d4..8eea07c 100644 --- a/meta-sota/recipes-core/images/initramfs-ostree-image.bb +++ b/meta-sota/recipes-core/images/initramfs-ostree-image.bb @@ -13,9 +13,9 @@ IMAGE_LINGUAS = "" LICENSE = "MIT" -# was ${INITRAMFS_FSTYPES} which defaults to cpio.gz -# due to xattr, we need ext3/4 IMAGE_FSTYPES = "ext4.gz" +IMAGE_FSTYPES_append_arm = " ext4.gz.u-boot" + inherit core-image IMAGE_ROOTFS_SIZE = "8192" diff --git a/meta-sota/recipes-sota/ostree/ostree_git.bb b/meta-sota/recipes-sota/ostree/ostree_git.bb index c2aeb2f..87f7138 100644 --- a/meta-sota/recipes-sota/ostree/ostree_git.bb +++ b/meta-sota/recipes-sota/ostree/ostree_git.bb @@ -2,7 +2,7 @@ SUMMARY = "Tool for managing bootable, immutable, versioned filesystem trees" LICENSE = "GPLv2+" LIC_FILES_CHKSUM = "file://COPYING;md5=5f30f0716dfdd0d91eb439ebec522ec2" -inherit autotools-brokensep pkgconfig systemd +inherit autotools-brokensep pkgconfig systemd gobject-introspection INHERIT_remove_class-native = "systemd" diff --git a/templates/feature/agl-sota/50_local.conf.inc b/templates/feature/agl-sota/50_local.conf.inc index 05cf3cf..eff85b5 100644 --- a/templates/feature/agl-sota/50_local.conf.inc +++ b/templates/feature/agl-sota/50_local.conf.inc @@ -6,13 +6,27 @@ IMAGE_INSTALL_append = " ostree" IMAGE_CLASSES += "image_types_ostree image_types_ota" IMAGE_FSTYPES += "otaimg" +IMAGE_CLASSES_append_raspberrypi = " sdcard_image-rpi-ota" +IMAGE_CLASSES_append_raspberrypi2 = " sdcard_image-rpi-ota" + +IMAGE_CLASSES_remove_raspberrypi = " sdcard_image-rpi-gdp" +IMAGE_CLASSES_remove_raspberrypi2 = " sdcard_image-rpi-gdp" + +IMAGE_FSTYPES += "${@'rpi-sdimg-ota' if d.getVar('MACHINE', True) in [ 'raspberrypi', 'raspberrypi2', 'raspberrypi3' ] else ''}" + +IMAGE_FSTYPES_remove_raspberrypi = "rpi-sdimg" +IMAGE_FSTYPES_remove_raspberrypi2 = "rpi-sdimg" + UBOOT_MACHINE_qemux86 = "qemu-x86_defconfig" UBOOT_MACHINE_qemux86-64 = "qemu-x86_defconfig" +UBOOT_MACHINE_raspberrypi3 = "rpi_3_32b_defconfig" + +KERNEL_IMAGETYPE_arm = "uImage" PREFERRED_PROVIDER_virtual/bootloader_qemux86 ?= "u-boot-ota" PREFERRED_PROVIDER_virtual/bootloader_qemux86-64 ?= "u-boot-ota" -PREFERRED_PROVIDER_virtual/bootloader_raspberrypi3 ?= "u-boot-ota" -PREFERRED_PROVIDER_virtual/bootloader_raspberrypi2 ?= "u-boot-ota" +PREFERRED_PROVIDER_virtual/bootloader_raspberrypi3 ?= "u-boot" +PREFERRED_PROVIDER_virtual/bootloader_raspberrypi2 ?= "u-boot" # Please redefine OSTREE_REPO in order to have a persistent OSTree repo OSTREE_REPO ?= "${DEPLOY_DIR_IMAGE}/ostree_repo" |