Skip to content

Commit

Permalink
esp-qcom-image: Add an image recipe to generate esp binary
Browse files Browse the repository at this point in the history
ESP (EFI System Partition) is used by UEFI to start kernel and
various utilities. An ESP contains the bootloaders, kernel image,
dtb and optionally initrd. ESP is formatted as a FAT filesystem.

Add esp-qcom-image recipe to generate an ESP binary for qcom boards
by combining systemd-boot as bootloader, Linux kernel UKI, systemd.efi,
and optional UEFI DTB files.

This change also brought in a small utility bbclass that can produce a
a FAT image with given content. This bbclass is used by esp-qcom-image
to produce a FAT filesystem.

Signed-off-by: Viswanath Kraleti <quic_vkraleti@quicinc.com>
  • Loading branch information
quic-vkraleti committed Nov 22, 2023
1 parent ef3eebe commit 4f34f3a
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 0 deletions.
68 changes: 68 additions & 0 deletions classes/image-vfat.bbclass
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Based on OE-core's image-live.bbclass implementation

DEPENDS:append = " \
dosfstools-native \
mtools-native \
"

BOOTIMG_VOLUME_ID ?= "BOOT"
BOOTIMG_EXTRA_SPACE ?= "512"
MKDOSFS_EXTRAOPTS ?= "-S 512"

build_fat_img() {
FATSOURCEDIR=$1
FATIMG=$2

# Calculate the size required for the final image including the
# data and filesystem overhead.
# Sectors: 512 bytes
# Blocks: 1024 bytes

# Determine the sector count just for the data
SECTORS=$(expr $(du --apparent-size -ks ${FATSOURCEDIR} | cut -f 1) \* 2)

# Account for the filesystem overhead. This includes directory
# entries in the clusters as well as the FAT itself.
# Assumptions:
# FAT32 (12 or 16 may be selected by mkdosfs, but the extra
# padding will be minimal on those smaller images and not
# worth the logic here to caclulate the smaller FAT sizes)
# < 16 entries per directory
# 8.3 filenames only

# 32 bytes per dir entry
DIR_BYTES=$(expr $(find ${FATSOURCEDIR} | tail -n +2 | wc -l) \* 32)
# 32 bytes for every end-of-directory dir entry
DIR_BYTES=$(expr $DIR_BYTES + $(expr $(find ${FATSOURCEDIR} -type d | tail -n +2 | wc -l) \* 32))
# 4 bytes per FAT entry per sector of data
FAT_BYTES=$(expr $SECTORS \* 4)
# 4 bytes per FAT entry per end-of-cluster list
FAT_BYTES=$(expr $FAT_BYTES + $(expr $(find ${FATSOURCEDIR} -type d | tail -n +2 | wc -l) \* 4))

# Use a ceiling function to determine FS overhead in sectors
DIR_SECTORS=$(expr $(expr $DIR_BYTES + 511) / 512)
# There are two FATs on the image
FAT_SECTORS=$(expr $(expr $(expr $FAT_BYTES + 511) / 512) \* 2)
SECTORS=$(expr $SECTORS + $(expr $DIR_SECTORS + $FAT_SECTORS))

# Determine the final size in blocks accounting for some padding
BLOCKS=$(expr $(expr $SECTORS / 2) + ${BOOTIMG_EXTRA_SPACE})

# mkdosfs will sometimes use FAT16 when it is not appropriate,
# resulting in a boot failure from SYSLINUX. Use FAT32 for
# images larger than 512MB, otherwise let mkdosfs decide.
if [ $(expr $BLOCKS / 1024) -gt 512 ]; then
FATSIZE="-F 32"
fi

# mkdosfs will fail if ${FATIMG} exists. Since we are creating an
# new image, it is safe to delete any previous image.
if [ -e ${FATIMG} ]; then
rm ${FATIMG}
fi

mkdosfs ${FATSIZE} -n ${BOOTIMG_VOLUME_ID} ${MKDOSFS_EXTRAOPTS} -C ${FATIMG} ${BLOCKS}

# Copy FATSOURCEDIR recursively into the image file directly
mcopy -i ${FATIMG} -s ${FATSOURCEDIR}/* ::/
}
50 changes: 50 additions & 0 deletions recipes-kernel/images/esp-qcom-image.bb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
DESCRIPTION = "EFI System Partition Image to boot Qualcomm boards"
COMPATIBLE_HOST = '(x86_64.*|arm.*|aarch64.*)-(linux.*)'

PACKAGE_INSTALL = " \
systemd-boot \
systemd-bootconf \
"

inherit image image-vfat

IMAGE_FSTYPES = ""
IMAGE_FSTYPES_DEBUGFS = ""

LINGUAS_INSTALL = ""

EFI_PROVIDER = "systemd-boot"
EFIIMGDIR = "${IMAGE_ROOTFS}/boot"
EFIIMG = "${IMGDEPLOYDIR}/esp-${MACHINE}.bin"
require conf/image-uefi.conf

UEFI_DEFAULT_DTB ?= ""

do_rootfs[depends] += " \
dosfstools-native:do_populate_sysroot \
mtools-native:do_populate_sysroot \
systemd-boot:do_deploy \
virtual/kernel:do_deploy \
"

# UKI image and systemd-boot efi are placed under deploydir.
# They need to be part of this image. Explicitly copy into rootfs
do_image () {
mkdir -p ${EFIIMGDIR}

#Kernel uki efi
mkdir -p ${EFIIMGDIR}/EFI/Linux
install -m 0644 ${DEPLOY_DIR_IMAGE}/linux-${MACHINE}.efi ${EFIIMGDIR}/EFI/Linux/

#systemd-boot efi
mkdir -p ${EFIIMGDIR}/${EFIDIR}
install -m 0644 ${DEPLOY_DIR_IMAGE}/systemd-${EFI_BOOT_IMAGE} ${EFIIMGDIR}/${EFIDIR}/${EFI_BOOT_IMAGE}

# Uefi dtb
if [ -f ${DEPLOY_DIR_IMAGE}/${UEFI_DEFAULT_DTB} ]; then
install -m 0644 ${DEPLOY_DIR_IMAGE}/${UEFI_DEFAULT_DTB} ${EFIIMGDIR}
fi

# Create a vfat image
build_fat_img ${EFIIMGDIR} ${EFIIMG}
}

0 comments on commit 4f34f3a

Please sign in to comment.