sdcard_image-rpi.bbclass: Rewrite sdimage creation class - implemented with parted

This implementation doesn't use loop mounts, it uses mcopy to copy files to partitions.
The partition creation is done with parted. Because of using these tools the
IMAGE_DEPENDS was modified accordingly.
Added a way of selecting the desired GPU firmware.
Because we don't create the rootfs image but we rely on an already created rootfs
image, the stamp is available only in the boot partition.
By default the class needs an ext3 rootfs image. This is because we don't have yet
a way of generating cmdline.txt in order to pass the partition type to the kernel.
By default ext3 is mounted so we use this fs type until this will be selectable while
generating a cmdline file.

Signed-off-by: Andrei Gherzan <andrei@gherzan.ro>
This commit is contained in:
Andrei Gherzan 2012-05-18 22:51:02 +03:00
parent 4b460a3f78
commit 2567ba074c

View File

@ -1,131 +1,99 @@
inherit image #
# Create an image that can by written onto a SD card using dd.
#
# The disk layout used is:
#
# 0 - 1M - reserved for other data
# 1M - BOOT_SPACE - bootloader and kernel
# BOOT_SPACE - SDIMG_SIZE - rootfs
#
# Add the fstypes we need inherit image_types
IMAGE_FSTYPES_append = " tar.bz2 rpi-sdimg"
# Ensure required utilities are present # Set kernel and boot loader
IMAGE_DEPENDS_rpi-sdimg = "genext2fs-native e2fsprogs-native bcm2835-bootfiles bcm2835-kernel-image" IMAGE_BOOTLOADER ?= "bcm2835-bootfiles"
# Register this as an avalable type of image. # Default to 1.4GiB images
IMAGE_TYPES_append = " rpi-sdimg" SDIMG_SIZE ?= "4000"
# Change this to match your host distro # Boot partition volume id
LOSETUP ?= "/sbin/losetup" BOOTDD_VOLUME_ID ?= "${MACHINE}"
# Since these need to go in /etc/fstab we can hardcode them # Addional space for boot partition
# Since the vars are weakly assigned, you can override them from your local.conf BOOT_SPACE ?= "20MiB"
LOOPDEV ?= "/dev/loop1"
LOOPDEV_BOOT ?= "/dev/loop2"
LOOPDEV_FS ?= "/dev/loop3"
# Default to 4GiB images # Use an ext3 by default as rootfs
SDIMG_SIZE ?= "444" SDIMG_ROOTFS_TYPE ?= "ext3"
SDIMG_ROOTFS = "${IMAGE_NAME}.rootfs.${SDIMG_ROOTFS_TYPE}"
# FS type for rootfs # Set GPU firmware image to be used
ROOTFSTYPE ?= "ext4" # arm128 : 128M ARM, 128M GPU split
# arm192 : 192M ARM, 64M GPU split
# arm224 : 224M ARM, 32M GPU split
RPI_GPU_FIRMWARE ?= "arm192"
BOOTPARTNAME ?= "${MACHINE}" IMAGE_DEPENDS_rpi-sdimg = " \
parted-native \
mtools-native \
dosfstools-native \
virtual/kernel \
${IMAGE_BOOTLOADER} \
"
IMAGEDATESTAMP = "${@time.strftime('%Y.%m.%d',time.gmtime())}" # SD card image name
SDIMG = "${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.rpi-sdimg"
# Additional files and/or directories to be copied into the vfat partition from the IMAGE_ROOTFS. # Additional files and/or directories to be copied into the vfat partition from the IMAGE_ROOTFS.
FATPAYLOAD ?= "" FATPAYLOAD ?= ""
IMAGEDATESTAMP = "${@time.strftime('%Y.%m.%d',time.gmtime())}"
IMAGE_CMD_rpi-sdimg () { IMAGE_CMD_rpi-sdimg () {
SDIMG=${WORKDIR}/sd.img # Initialize sdcard image file
dd if=/dev/zero of=${SDIMG} bs=1 count=0 seek=$(expr 1000 \* 1000 \* ${SDIMG_SIZE})
# sanity check fstab entry for boot partition mounting
if [ "x$(cat /etc/fstab | grep ${LOOPDEV_BOOT} | grep ${WORKDIR}/tmp-mnt-boot | grep user || true)" = "x" ]; then
echo "/etc/fstab entries need to be created with the user flag for the loop devices like:"
echo "${LOOPDEV_BOOT} ${WORKDIR}/tmp-mnt-boot vfat user 0 0"
false
fi
# cleanup loops
for loop in ${LOOPDEV} ${LOOPDEV_BOOT} ${LOOPDEV_FS} ; do
${LOSETUP} -d $loop || true
done
# If an SD image is already present, reuse and reformat it
if [ ! -e ${SDIMG} ] ; then
dd if=/dev/zero of=${SDIMG} bs=$(echo '255 * 63 * 512' | bc) count=${SDIMG_SIZE}
fi
${LOSETUP} ${LOOPDEV} ${SDIMG}
# Create partition table # Create partition table
dd if=/dev/zero of=${LOOPDEV} bs=1024 count=1024 parted -s ${SDIMG} mklabel msdos
SIZE=$(/sbin/fdisk -l ${LOOPDEV} | grep Disk | grep bytes | awk '{print $5}') # Create boot partition and mark it as bootable
CYLINDERS=$(echo $SIZE/255/63/512 | bc) parted -s ${SDIMG} mkpart primary fat32 1MiB ${BOOT_SPACE}
{ parted -s ${SDIMG} set 1 boot on
echo ,9,0x0C,* # Create rootfs partition
echo ,,,- parted -s ${SDIMG} mkpart primary ext2 ${BOOT_SPACE} 100%
} | /sbin/sfdisk -D -H 255 -S 63 -C ${CYLINDERS} ${LOOPDEV} parted ${SDIMG} print
# Prepare loop devices for boot and filesystem partitions # Create a vfat image with boot files
BOOT_OFFSET=32256 BOOT_BLOCKS=$(LC_ALL=C parted -s ${SDIMG} unit b print | awk '/ 1 / { print substr($4, 1, length($4 -1)) / 512 /2 }')
FS_OFFSET_SECT=$(/sbin/fdisk -l -u ${LOOPDEV} 2>&1 | grep Linux | perl -p -i -e "s/\s+/ /"|cut -d " " -f 2) mkfs.vfat -n "${BOOTDD_VOLUME_ID}" -S 512 -C ${WORKDIR}/boot.img $BOOT_BLOCKS
FS_OFFSET=$(echo "$FS_OFFSET_SECT * 512" | bc) case "${RPI_GPU_FIRMWARE}" in
FS_SIZE_BLOCKS=$(/sbin/fdisk -l -u ${LOOPDEV} 2>&1 | grep Linux | perl -p -i -e "s/\s+/ /g" \ "arm128" | "arm192" | "arm224")
|cut -d " " -f 4 | cut -d "+" -f 1) mcopy -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/bcm2835-bootfiles/${RPI_GPU_FIRMWARE}_start.elf ::start.elf
;;
LOOPDEV_BLOCKS=$(/sbin/fdisk -l -u ${LOOPDEV} 2>&1 | grep FAT | perl -p -i -e "s/\s+/ /g"|cut -d " " -f 5) *)
LOOPDEV_BYTES=$(echo "$LOOPDEV_BLOCKS * 1024" | bc) bberror "RPI_GPU_FIRMWARE is undefined or value not recongnised. Possible values: arm128, arm192 or arm224."
exit 1
;;
esac
${LOSETUP} -d ${LOOPDEV} # To do
# Copy here a cmdline.txt file generated taking into consideration the partition type
${LOSETUP} ${LOOPDEV_BOOT} ${SDIMG} -o ${BOOT_OFFSET} # of the rootfs
mcopy -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/bcm2835-bootfiles/bootcode.bin ::
/sbin/mkfs.vfat ${LOOPDEV_BOOT} -n ${BOOTPARTNAME} $LOOPDEV_BLOCKS mcopy -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/bcm2835-bootfiles/loader.bin ::
mcopy -i ${WORKDIR}/boot.img -s ${DEPLOY_DIR_IMAGE}/bcm2835-bootfiles/kernel.img ::
# Prepare boot partion. First mount the boot partition, and copy the bootloader and supporting files.
mkdir -p ${WORKDIR}/tmp-mnt-boot
mount $LOOPDEV_BOOT ${WORKDIR}/tmp-mnt-boot
echo "Copying bootloader and prepended kernel.img into the boot partition"
cp -v ${DEPLOY_DIR_IMAGE}/bcm2835-bootfiles/* ${WORKDIR}/tmp-mnt-boot || true
if [ -n ${FATPAYLOAD} ] ; then if [ -n ${FATPAYLOAD} ] ; then
echo "Copying payload into VFAT" echo "Copying payload into VFAT"
for entry in ${FATPAYLOAD} ; do for entry in ${FATPAYLOAD} ; do
# add the || true to stop aborting on vfat issues like not supporting .~lock files # add the || true to stop aborting on vfat issues like not supporting .~lock files
cp -av ${IMAGE_ROOTFS}$entry ${WORKDIR}/tmp-mnt-boot || true mcopy -i ${WORKDIR}/boot.img -s -v ${IMAGE_ROOTFS}$entry :: || true
done done
fi fi
echo "${IMAGE_NAME}-${IMAGEDATESTAMP}" > ${IMAGE_ROOTFS}/etc/image-version-info # Add stamp file
echo "${IMAGE_NAME}-${IMAGEDATESTAMP}" > ${WORKDIR}/image-version-info
cp -v ${IMAGE_ROOTFS}/etc/image-version-info ${WORKDIR}/tmp-mnt-boot || true mcopy -i ${WORKDIR}/boot.img -v ${WORKDIR}//image-version-info ::
# Cleanup VFAT mount # Burn Partitions
echo "Cleaning up VFAT mount" dd if=${WORKDIR}/boot.img of=${SDIMG} conv=notrunc seek=1 bs=1M && sync && sync
umount ${WORKDIR}/tmp-mnt-boot dd if=${SDIMG_ROOTFS} of=${SDIMG} conv=notrunc seek=1 bs=${BOOT_SPACE} && sync && sync
${LOSETUP} -d ${LOOPDEV_BOOT} || true
# Prepare rootfs parition
echo "Creating rootfs loopback"
${LOSETUP} ${LOOPDEV_FS} ${SDIMG} -o ${FS_OFFSET}
FS_NUM_INODES=$(echo $FS_SIZE_BLOCKS / 4 | bc)
case "${ROOTFSTYPE}" in
ext3)
genext2fs -z -N $FS_NUM_INODES -b $FS_SIZE_BLOCKS -d ${IMAGE_ROOTFS} ${LOOPDEV_FS}
tune2fs -L ${IMAGE_NAME} -j ${LOOPDEV_FS}
;;
ext4)
genext2fs -z -N $FS_NUM_INODES -b $FS_SIZE_BLOCKS -d ${IMAGE_ROOTFS} ${LOOPDEV_FS}
tune2fs -L ${IMAGE_NAME} -j -O extents,uninit_bg,dir_index ${LOOPDEV_FS}
;;
*)
echo "Please set ROOTFSTYPE to something supported"
exit 1
;;
esac
${LOSETUP} -d ${LOOPDEV_FS} || true
gzip -c ${WORKDIR}/sd.img > ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}-${IMAGEDATESTAMP}.img.gz
rm -f ${WORKDIR}/sd.img
} }