You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
874 lines
25 KiB
874 lines
25 KiB
#!/bin/bash
|
|
|
|
# Partition alignment value in bytes.
|
|
declare -i partition_alignment
|
|
# Boot partition storage offset in bytes.
|
|
declare -i vfat_storage_offset
|
|
|
|
PART_ALIGN_4MB=4194304
|
|
PART_ALIGN_8MB=8388608
|
|
|
|
# Default 'data' partition size in MiB.
|
|
declare -i data_part_size_mb
|
|
# Default total storage size in MiB.
|
|
declare -i storage_total_size_mb
|
|
|
|
DATA_PART_SIZE_MB=128
|
|
STORAGE_TOTAL_SIZE_MB=8000
|
|
|
|
# Number of required heads in a final image.
|
|
declare -i -r heads=255
|
|
# Number of required sectors in a final image.
|
|
declare -i -r sectors=63
|
|
|
|
declare -a mender_partitions_regular=('boot' 'primary' 'secondary' 'data')
|
|
declare -a mender_partitions_extended=('boot' 'primary' 'secondary' 'n/a' 'data' 'swap')
|
|
declare -a raw_disk_partitions=('boot' 'rootfs')
|
|
|
|
declare -A raw_disk_sizes
|
|
declare -A mender_disk_sizes
|
|
|
|
tool_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
files_dir=${tool_dir}/files
|
|
output_dir=${tool_dir}/output
|
|
build_log=${output_dir}/build.log
|
|
|
|
embedded_base_dir=$output_dir/embedded
|
|
sdimg_base_dir=$output_dir/sdimg
|
|
|
|
embedded_boot_dir=$embedded_base_dir/boot
|
|
embedded_rootfs_dir=$embedded_base_dir/rootfs
|
|
sdimg_boot_dir=$sdimg_base_dir/boot
|
|
sdimg_primary_dir=$sdimg_base_dir/primary
|
|
sdimg_secondary_dir=$sdimg_base_dir/secondary
|
|
sdimg_data_dir=$sdimg_base_dir/data
|
|
|
|
logsetup() {
|
|
[ ! -f $build_log ] && { touch $build_log; }
|
|
echo -n "" > $build_log
|
|
exec > >(tee -a $build_log)
|
|
exec 2>&1
|
|
}
|
|
|
|
log() {
|
|
echo -e "$*"
|
|
}
|
|
|
|
# Takes following arguments:
|
|
#
|
|
# $1 -relative file path
|
|
get_path() {
|
|
echo "$(cd "$(dirname "$1")"; pwd)/$(basename "$1")"
|
|
}
|
|
|
|
get_part_number_from_device() {
|
|
case "$1" in
|
|
/dev/*[0-9]p[1-9])
|
|
echo ${1##*[0-9]p}
|
|
;;
|
|
/dev/[sh]d[a-z][1-9])
|
|
echo ${1##*d[a-z]}
|
|
;;
|
|
ubi[0-9]_[0-9])
|
|
echo ${1##*[0-9]_}
|
|
;;
|
|
[a-z]*\.sdimg[1-9])
|
|
echo ${1##*\.sdimg}
|
|
;;
|
|
/dev/mapper/*[0-9]p[1-9])
|
|
echo ${1##*[0-9]p}
|
|
;;
|
|
*)
|
|
log "Could not determine partition number from $1"
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Takes following arguments:
|
|
#
|
|
# $1 - raw disk image
|
|
# $2 - boot partition start offset (in sectors)
|
|
# $3 - boot partition size (in sectors)
|
|
create_single_disk_partition_table() {
|
|
local device=$1
|
|
local bootstart=$2
|
|
local stopsector=$(( $3 - 1 ))
|
|
|
|
sed -e 's/\s*\([\+0-9a-zA-Z]*\).*/\1/' << EOF | sudo fdisk $device &> /dev/null
|
|
d # delete partition
|
|
n # new partition
|
|
p # primary partition
|
|
1 # partion number 1
|
|
${bootstart}
|
|
+${stopsector}
|
|
a # set boot flag
|
|
w # write the partition table
|
|
q # and we're done
|
|
EOF
|
|
}
|
|
|
|
# Takes following arguments:
|
|
#
|
|
# $1 - raw disk image
|
|
# $2 - root filesystem partition start offset (in sectors)
|
|
# $3 - root filesystem partition size (in sectors)
|
|
create_double_disk_partition_table() {
|
|
local device=$1
|
|
local rootfsstart=$2
|
|
local rootfsstop=$(( $3 - 1 ))
|
|
|
|
sed -e 's/\s*\([\+0-9a-zA-Z]*\).*/\1/' << EOF | sudo fdisk $device &> /dev/null
|
|
d # delete partition
|
|
2
|
|
n
|
|
p
|
|
2
|
|
${rootfsstart}
|
|
+${rootfsstop}
|
|
w # write the partition table
|
|
q # and we're done
|
|
EOF
|
|
}
|
|
|
|
# Takes following arguments:
|
|
#
|
|
# $1 - raw_disk image path
|
|
#
|
|
# Calculates following values:
|
|
#
|
|
# $2 - number of partitions
|
|
# $3 - array of partitions' sizes for raw disk
|
|
#
|
|
get_raw_disk_sizes() {
|
|
local limage=$1
|
|
local rvar_count=$2
|
|
shift 2
|
|
local rvar_array=($@)
|
|
|
|
local lsubname=${limage:0:10}
|
|
local lfdisk="$(fdisk -u -l ${limage})"
|
|
local lparts=($(echo "${lfdisk}" | grep "^${lsubname}" | cut -d' ' -f1))
|
|
local lcount=${#lparts[@]}
|
|
|
|
if [[ $lcount -gt 3 ]]; then
|
|
log "\tError: invalid/unsupported raw disk image. Aborting."
|
|
return 1
|
|
fi
|
|
|
|
local lsectorsize=($(echo "${lfdisk}" | grep '^Sector' | cut -d' ' -f4))
|
|
|
|
local idx_start=2
|
|
local idx_size=4
|
|
|
|
local lfirstpartinfo="$(echo "${lfdisk}" | grep "^${lparts[0]}")"
|
|
|
|
if [[ $lcount -gt 1 ]]; then
|
|
local lsecondpartinfo="$(echo "${lfdisk}" | grep "^${lparts[1]}")"
|
|
eval $rvar_array[prootfs_start]="'$(echo "${lsecondpartinfo}" | tr -s ' ' | cut -d' ' -f${idx_start})'"
|
|
eval $rvar_array[prootfs_size]="'$(echo "${lsecondpartinfo}" | tr -s ' ' | cut -d' ' -f${idx_size})'"
|
|
fi
|
|
|
|
if [[ $lcount -gt 2 ]]; then
|
|
local lthirdpartinfo="$(echo "${lfdisk}" | grep "^${lparts[2]}")"
|
|
eval $rvar_array[pswap_start]="'$(echo "${lthirdpartinfo}" | tr -s ' ' | cut -d' ' -f${idx_start})'"
|
|
eval $rvar_array[pswap_size]="'$(echo "${lthirdpartinfo}" | tr -s ' ' | cut -d' ' -f${idx_size})'"
|
|
fi
|
|
|
|
# Check is first partition is marked as bootable.
|
|
if [[ "$lfirstpartinfo" =~ .*\*.* ]]; then
|
|
((idx_start+=1))
|
|
((idx_size+=1))
|
|
fi
|
|
|
|
eval $rvar_array[pboot_start]="'$(echo "${lfirstpartinfo}" | tr -s ' ' | cut -d' ' -f${idx_start})'"
|
|
eval $rvar_array[pboot_size]="'$(echo "${lfirstpartinfo}" | tr -s ' ' | cut -d' ' -f${idx_size})'"
|
|
eval $rvar_array[sector_size]="'$lsectorsize'"
|
|
|
|
eval $rvar_count="'$lcount'"
|
|
|
|
return 0
|
|
}
|
|
|
|
# Takes the following argument
|
|
# $1 - device type
|
|
#
|
|
# Calculates the following arguments:
|
|
# $2 - partition alignment
|
|
# $3 - vfat storage offset
|
|
|
|
set_mender_disk_alignment() {
|
|
local rvar_partition_alignment=$2
|
|
local rvar_vfat_storage_offset=$3
|
|
|
|
case "$1" in
|
|
"beaglebone" | "qemux86_64")
|
|
local lvar_partition_alignment=${PART_ALIGN_8MB}
|
|
local lvar_vfat_storage_offset=$lvar_partition_alignment
|
|
;;
|
|
"raspberrypi3" | "raspberrypi0w")
|
|
local lvar_partition_alignment=${PART_ALIGN_4MB}
|
|
local lvar_uboot_env_size=$(( $lvar_partition_alignment * 2 ))
|
|
local lvar_vfat_storage_offset=$(( $lvar_partition_alignment + $lvar_uboot_env_size ))
|
|
;;
|
|
esac
|
|
|
|
eval $rvar_partition_alignment="'$lvar_partition_alignment'"
|
|
eval $rvar_vfat_storage_offset="'$lvar_vfat_storage_offset'"
|
|
}
|
|
|
|
# Takes following arguments:
|
|
#
|
|
# $1 - Mender disk image path
|
|
#
|
|
# Calculates following values:
|
|
#
|
|
# $2 - number of partitions
|
|
# $3 - size of the sector (in bytes)
|
|
# $4 - rootfs A partition start offset (in sectors)
|
|
# $5 - rootfs A partition size (in sectors)
|
|
# $6 - rootfs B partition start offset (in sectors)
|
|
# $7 - rootfs B partition size (in sectors)
|
|
get_mender_disk_sizes() {
|
|
local limage=$1
|
|
local rvar_count=$2
|
|
local rvar_sectorsize=$3
|
|
local rvar_rootfs_a_start=$4
|
|
local rvar_rootfs_a_size=$5
|
|
local rvar_rootfs_b_start=$6
|
|
local rvar_rootfs_b_size=$7
|
|
|
|
local lsubname=${limage:0:10}
|
|
local lfdisk="$(fdisk -u -l ${limage})"
|
|
|
|
local lparts=($(echo "${lfdisk}" | grep "^${lsubname}" | cut -d' ' -f1))
|
|
local lcount=${#lparts[@]}
|
|
|
|
if [[ $lcount -ne 4 ]] && [[ $lcount -ne 6 ]]; then
|
|
log "Error: invalid Mender disk image. Aborting."
|
|
return 1
|
|
else
|
|
local lsectorsize=($(echo "${lfdisk}" | grep '^Sector' | cut -d' ' -f4))
|
|
|
|
local lrootfs_a_info="$(echo "${lfdisk}" | grep "^${lparts[1]}")"
|
|
local lrootfs_b_info="$(echo "${lfdisk}" | grep "^${lparts[2]}")"
|
|
|
|
idx_start=2
|
|
idx_size=4
|
|
|
|
local lrootfs_a_start=($(echo "${lrootfs_a_info}" | tr -s ' ' | cut -d' ' -f${idx_start}))
|
|
local lrootfs_a_size=($(echo "${lrootfs_a_info}" | tr -s ' ' | cut -d' ' -f${idx_size}))
|
|
local lrootfs_b_start=($(echo "${lrootfs_b_info}" | tr -s ' ' | cut -d' ' -f${idx_start}))
|
|
local lrootfs_b_size=($(echo "${lrootfs_b_info}" | tr -s ' ' | cut -d' ' -f${idx_size}))
|
|
|
|
eval $rvar_count="'$lcount'"
|
|
eval $rvar_sectorsize="'$lsectorsize'"
|
|
eval $rvar_rootfs_a_start="'$lrootfs_a_start'"
|
|
eval $rvar_rootfs_a_size="'$lrootfs_a_size'"
|
|
eval $rvar_rootfs_b_start="'$lrootfs_b_start'"
|
|
eval $rvar_rootfs_b_size="'$lrootfs_b_size'"
|
|
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
# Takes following arguments:
|
|
#
|
|
# $1 - size variable to be aligned in sectors
|
|
# $2 - size of the sector
|
|
#
|
|
align_partition_size() {
|
|
# Final size is aligned with reference to 'partition_alignment' variable.
|
|
local rvar_size=$1
|
|
local -n ref=$1
|
|
|
|
local size_in_bytes=$(( $ref * $2 ))
|
|
local reminder=$(( ${size_in_bytes} % ${partition_alignment} ))
|
|
|
|
if [ $reminder -ne 0 ]; then
|
|
size_in_bytes=$(( $size_in_bytes - $reminder + ${partition_alignment} ))
|
|
fi
|
|
|
|
local lsize=$(( $size_in_bytes / $2 ))
|
|
|
|
eval $rvar_size="'$lsize'"
|
|
}
|
|
|
|
# Takes following arguments:
|
|
#
|
|
# $1 - number of partition of the raw disk image
|
|
# $2 - mender image partition alignment
|
|
# $3 - mender image's boot partition offset
|
|
# $4 - data partition size (in MB)
|
|
# $5 - array of partitions' sizes for raw image
|
|
#
|
|
# Returns:
|
|
#
|
|
# $6 - array of partitions' sizes for Mender image
|
|
#
|
|
set_mender_disk_sizes() {
|
|
local count=$1
|
|
local alignment=$2
|
|
local offset=$3
|
|
local datasize_mb=$4
|
|
local _raw_sizes=$(declare -p $5)
|
|
eval "declare -A raw_sizes="${_raw_sizes#*=}
|
|
shift 5
|
|
local rvar_array=($@)
|
|
|
|
local sector_size=${raw_sizes[sector_size]}
|
|
local datasize=$(( ($datasize_mb * 1024 * 1024) / $sector_size ))
|
|
|
|
local bootstart=
|
|
local bootsize=
|
|
local rootfsstart=
|
|
local rootfssize=
|
|
local bootflag=
|
|
|
|
if [[ $count -eq 1 ]]; then
|
|
# Default size of the boot partition: 16MiB.
|
|
bootsize=$(( (${alignment} * 2) / ${sector_size} ))
|
|
# Root filesystem size is determined by the size of the single partition.
|
|
rootfssize=${raw_sizes[pboot_size]}
|
|
else
|
|
bootsize=${raw_sizes[pboot_size]}
|
|
rootfssize=${raw_sizes[prootfs_size]}
|
|
fi
|
|
|
|
# Boot partition storage offset is defined from the top down.
|
|
bootstart=$(( ${offset} / ${sector_size} ))
|
|
|
|
align_partition_size bootsize $sector_size
|
|
align_partition_size rootfssize $sector_size
|
|
align_partition_size datasize $sector_size
|
|
|
|
eval $rvar_array[pboot_start]="'$bootstart'"
|
|
eval $rvar_array[pboot_size]="'$bootsize'"
|
|
eval $rvar_array[prootfs_size]="'$rootfssize'"
|
|
eval $rvar_array[pdata_size]="'$datasize'"
|
|
|
|
if [[ $count -eq 3 ]]; then
|
|
# Add space for Swap partition.
|
|
local swapsize=${raw_sizes[pswap_size]}
|
|
align_partition_size swapsize $sector_size
|
|
eval $rvar_array[pswap_size]="'$swapsize'"
|
|
fi
|
|
|
|
eval $rvar_array[sector_size]="'$sector_size'"
|
|
}
|
|
|
|
# Takes following arguments:
|
|
#
|
|
# $1 - partition alignment
|
|
# $2 - array of partitions' sizes for Mender image
|
|
#
|
|
# Returns:
|
|
#
|
|
# #3 - number of partitions of the Mender disk image
|
|
# $4 - final Mender disk image size (in bytes)
|
|
#
|
|
calculate_mender_disk_size() {
|
|
local _mender_sizes=$(declare -p $2)
|
|
eval "declare -A mender_sizes="${_mender_sizes#*=}
|
|
local sector_size=${mender_sizes[sector_size]}
|
|
local rvar_counts=$3
|
|
local rvar_sdimgsize=$4
|
|
|
|
local sdimgsize=$(( (${mender_sizes[pboot_start]} + ${mender_sizes[pboot_size]} + \
|
|
2 * ${mender_sizes[prootfs_size]} + \
|
|
${mender_sizes[pdata_size]}) * $sector_size ))
|
|
|
|
eval $rvar_counts="'4'"
|
|
|
|
if [ -v mender_sizes[pswap_size] ]; then
|
|
log "\tSwap partition found."
|
|
# Add size of the swap partition to the total size.
|
|
sdimgsize=$(( $sdimgsize + (${mender_sizes[pswap_size]} * $sector_size) ))
|
|
# Add alignment used as swap partition offset.
|
|
sdimgsize=$(( $sdimgsize + 2 * ${1} ))
|
|
eval $rvar_counts="'6'"
|
|
fi
|
|
|
|
eval $rvar_sdimgsize="'$sdimgsize'"
|
|
}
|
|
|
|
# Takes following arguments:
|
|
#
|
|
# $1 - number of partition of the Mender image
|
|
# $2 - calculated total size of the Mender image in bytes
|
|
# $3 - expected total size of the Mender image in mb
|
|
# $4 - array of partitions' sizes for Mender image
|
|
#
|
|
# Returns:
|
|
#
|
|
# Size of the rootfs partition updated and adjusted to total storage size
|
|
#
|
|
mender_image_size_to_total_storage_size() {
|
|
local count=$1
|
|
local rvar_image_size=$2
|
|
local -n image_size_bytes=$2
|
|
local storage_size_mb=$3
|
|
|
|
local _mender_sizes=$(declare -p $4)
|
|
eval "declare -A mender_sizes="${_mender_sizes#*=}
|
|
|
|
shift 3
|
|
local rvar_array=($@)
|
|
|
|
local image_size_mb=$(( (($image_size_bytes / 1024) / 1024) ))
|
|
|
|
log "\tAdjust Mender disk image size to the total storage size (${storage_size_mb}MB)."
|
|
|
|
if [ $image_size_mb -gt $storage_size_mb ]; then
|
|
log "\tDefined total storage size of ${3}MB is too small."
|
|
log "\tMinimal required storage is ${image_size_mb}MB. Aborting."
|
|
return 1
|
|
elif [ $image_size_mb -eq $storage_size_mb ]; then
|
|
# Simply continue.
|
|
log "\tCalculated Mender image size exactly fits the defined total storage."
|
|
return 0
|
|
fi
|
|
|
|
# Get spare space for rootfs a/b partitions (in sectors).
|
|
local sector_size=${mender_sizes[sector_size]}
|
|
local image_size_s=$(( $image_size_bytes / $sector_size ))
|
|
local storage_size_bytes=$(( ($storage_size_mb * 1024 * 1024) ))
|
|
local storage_size_s=$(( $storage_size_bytes / $sector_size ))
|
|
local rootfs_overplus_bytes=0
|
|
|
|
local spare_storage_bytes=$(( $storage_size_bytes - $image_size_bytes ))
|
|
|
|
if [ $(($spare_storage_bytes % 2)) -ne 0 ]; then
|
|
log "\tAdditional space for rootfs partitions not divisible by 2.\
|
|
\n\tFinal image will be smaller than ${storage_size_mb}MB"
|
|
fi
|
|
rootfs_overplus_bytes=$(( $spare_storage_bytes / 2 ))
|
|
|
|
local reminder=$(( ${rootfs_overplus_bytes} % ${partition_alignment} ))
|
|
if [ $reminder -ne 0 ]; then
|
|
log "\tAdditional space for rootfs partitions not aligned.\
|
|
\n\tFinal image will be smaller than ${storage_size_mb}MB"
|
|
fi
|
|
rootfs_overplus_bytes=$(($rootfs_overplus_bytes - $reminder))
|
|
rootfs_overplus_s=$(( $rootfs_overplus_bytes / $sector_size ))
|
|
|
|
local prootfs_size=${mender_sizes[prootfs_size]}
|
|
prootfs_size=$(( $prootfs_size + $rootfs_overplus_s ))
|
|
|
|
image_size_bytes=$(( $image_size_bytes + 2 * $rootfs_overplus_bytes ))
|
|
|
|
eval $rvar_array[prootfs_size]="'$prootfs_size'"
|
|
eval $rvar_image_size="'$image_size_bytes'"
|
|
|
|
return 0
|
|
}
|
|
|
|
# Takes following arguments:
|
|
#
|
|
# $1 - raw disk image path
|
|
# $2 - raw disk image size
|
|
create_mender_disk() {
|
|
local lfile=$1
|
|
local lsize=$2
|
|
|
|
# Generates a sparse image
|
|
dd if=/dev/zero of=${lfile} seek=${lsize} bs=1 count=0 >> "$build_log" 2>&1
|
|
}
|
|
|
|
# Takes following arguments:
|
|
#
|
|
# $1 - Mender disk image path
|
|
# $2 - Mender disk image size
|
|
# $3 - partition alignment
|
|
# $4 - array of partitions' sizes for Mender image
|
|
#
|
|
format_mender_disk() {
|
|
local lfile=$1
|
|
local lsize=$2
|
|
local rc=0
|
|
|
|
local _mender_sizes=$(declare -p $4)
|
|
eval "declare -A mender_sizes="${_mender_sizes#*=}
|
|
|
|
local sector_size=${mender_sizes[sector_size]}
|
|
local alignment=$(($3 / ${sector_size}))
|
|
|
|
cylinders=$(( ${lsize} / ${heads} / ${sectors} / ${sector_size} ))
|
|
|
|
pboot_start=${mender_sizes[pboot_start]}
|
|
pboot_size=${mender_sizes[pboot_size]}
|
|
pboot_end=$((${pboot_start} + ${pboot_size} - 1))
|
|
|
|
prootfs_size=${mender_sizes[prootfs_size]}
|
|
|
|
prootfsa_start=$((${pboot_end} + 1))
|
|
prootfsa_end=$((${prootfsa_start} + ${prootfs_size} - 1))
|
|
|
|
prootfsb_start=$((${prootfsa_end} + 1))
|
|
prootfsb_end=$((${prootfsb_start} + ${prootfs_size} - 1))
|
|
|
|
pdata_start=$((${prootfsb_end} + 1))
|
|
pdata_size=${mender_sizes[pdata_size]}
|
|
pdata_end=$((${pdata_start} + ${pdata_size} - 1))
|
|
|
|
if [ -v mender_sizes[pswap_size] ]; then
|
|
local pextended_start=$((${prootfsb_end} + 1))
|
|
|
|
pdata_start=$(($pextended_start + ${alignment}))
|
|
pdata_end=$((${pdata_start} + ${pdata_size} - 1))
|
|
|
|
local pswap_start=$((${pdata_end} + ${alignment} + 1))
|
|
local pswap_size=${mender_sizes[pswap_size]}
|
|
local pswap_end=$((${pswap_start} + ${pswap_size} - 1))
|
|
fi
|
|
|
|
sed -e 's/\s*\([\+0-9a-zA-Z]*\).*/\1/' << EOF | sudo fdisk ${lfile} &> /dev/null
|
|
o # clear the in memory partition table
|
|
x
|
|
h
|
|
${heads}
|
|
s
|
|
${sectors}
|
|
c
|
|
${cylinders}
|
|
r
|
|
w # write the partition table
|
|
q # and we're done
|
|
EOF
|
|
|
|
# Create partition table
|
|
sudo parted -s ${lfile} mklabel msdos || rc=$?
|
|
sudo parted -s ${lfile} unit s mkpart primary fat32 ${pboot_start} ${pboot_end} || rc=$?
|
|
sudo parted -s ${lfile} set 1 boot on || rc=$?
|
|
sudo parted -s ${lfile} -- unit s mkpart primary ext4 ${prootfsa_start} ${prootfsa_end} || rc=$?
|
|
sudo parted -s ${lfile} -- unit s mkpart primary ext4 ${prootfsb_start} ${prootfsb_end} || rc=$?
|
|
|
|
if [ -v mender_sizes[pswap_size] ]; then
|
|
log "\tAdding swap partition."
|
|
sudo parted -s ${lfile} -- unit s mkpart extended ${pextended_start} 100% || rc=$?
|
|
sudo parted -s ${lfile} -- unit s mkpart logical ext4 ${pdata_start} ${pdata_end} || rc=$?
|
|
sudo parted -s ${lfile} -- unit s mkpart logical linux-swap ${pswap_start} ${pswap_end} || rc=$?
|
|
else
|
|
sudo parted -s ${lfile} -- unit s mkpart primary ext4 ${pdata_start} ${pdata_end} || rc=$?
|
|
fi
|
|
|
|
[[ $rc -eq 0 ]] && { log "\tChanges in partition table applied."; }
|
|
|
|
return $rc
|
|
}
|
|
|
|
# Takes following arguments:
|
|
#
|
|
# $1 - raw disk file
|
|
#
|
|
verify_mender_disk() {
|
|
local lfile=$1
|
|
local lcounts=$2
|
|
|
|
local limage=$(basename $lfile)
|
|
local partitions=($(fdisk -l -u ${limage} | cut -d' ' -f1 | grep 'sdimg[1-9]\{1\}$'))
|
|
|
|
local no_of_parts=${#partitions[@]}
|
|
|
|
[[ $no_of_parts -eq $lcounts ]] || \
|
|
{ log "Error: incorrect number of partitions: $no_of_parts. Aborting."; return 1; }
|
|
|
|
return 0
|
|
}
|
|
|
|
# Takes following arguments:
|
|
#
|
|
# $1 - raw disk image
|
|
# $2 - partition mappings holder
|
|
create_device_maps() {
|
|
local -n mappings=$2
|
|
|
|
if [[ -n "$1" ]]; then
|
|
mapfile -t mappings < <( sudo kpartx -v -a $1 | grep 'loop' | cut -d' ' -f3 )
|
|
[[ ${#mappings[@]} -eq 0 ]] \
|
|
&& { log "Error: partition mappings failed. Aborting."; exit 1; }
|
|
else
|
|
log "Error: no device passed. Aborting."
|
|
exit 1
|
|
fi
|
|
|
|
sudo partprobe /dev/${mappings[0]%p*}
|
|
}
|
|
|
|
# Takes following arguments:
|
|
#
|
|
# $1 - partition mappings holder
|
|
detach_device_maps() {
|
|
local mappings=($@)
|
|
|
|
[ ${#mappings[@]} -eq 0 ] && { log "\tPartition mappings cleaned."; return; }
|
|
|
|
local mapper=${mappings[0]%p*}
|
|
|
|
for mapping in ${mappings[@]}
|
|
do
|
|
map_dev=/dev/mapper/"$mapping"
|
|
is_mounted=`grep ${map_dev} /proc/self/mounts | wc -l`
|
|
if [ ${is_mounted} -ne 0 ]; then
|
|
sudo umount -l $map_dev
|
|
fi
|
|
done
|
|
|
|
sudo kpartx -d /dev/$mapper &
|
|
sudo losetup -d /dev/$mapper &
|
|
wait && sync
|
|
}
|
|
|
|
# Takes following arguments:
|
|
#
|
|
# $1 - partition mappings holder
|
|
#
|
|
make_mender_disk_filesystem() {
|
|
local mappings=($@)
|
|
local counts=${#mappings[@]}
|
|
|
|
if [ $counts -eq 4 ]; then
|
|
local labels=(${mender_partitions_regular[@]})
|
|
elif [ $counts -eq 6 ]; then
|
|
local labels=(${mender_partitions_extended[@]})
|
|
fi
|
|
|
|
for mapping in ${mappings[@]}
|
|
do
|
|
map_dev=/dev/mapper/"$mapping"
|
|
part_no=$(get_part_number_from_device $map_dev)
|
|
label=${labels[${part_no} - 1]}
|
|
|
|
case ${part_no} in
|
|
1)
|
|
log "\tCreating MS-DOS filesystem for '$label' partition."
|
|
sudo mkfs.vfat -n ${label} $map_dev >> "$build_log" 2>&1
|
|
;;
|
|
2|3)
|
|
log "\tCreating ext4 filesystem for '$label' partition."
|
|
sudo mkfs.ext4 -L ${label} $map_dev >> "$build_log" 2>&1
|
|
;;
|
|
4)
|
|
if [ $counts -eq 4 ]; then
|
|
log "\tCreating ext4 filesystem for '$label' partition."
|
|
sudo mkfs.ext4 -L ${label} $map_dev >> "$build_log" 2>&1
|
|
else
|
|
continue
|
|
fi
|
|
;;
|
|
5)
|
|
log "\tCreating ext4 filesystem for '$label' partition."
|
|
sudo mkfs.ext4 -L ${label} $map_dev >> "$build_log" 2>&1
|
|
;;
|
|
6)
|
|
log "\tCreating swap area for '$label' partition."
|
|
sudo mkswap -L ${label} $map_dev >> "$build_log" 2>&1
|
|
;;
|
|
*)
|
|
break
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
# Takes following arguments:
|
|
#
|
|
# $1 - partition mappings holder
|
|
mount_raw_disk() {
|
|
local mappings=($@)
|
|
|
|
if [ ${#mappings[@]} -eq 1 ]; then
|
|
local path=$embedded_rootfs_dir
|
|
mkdir -p $path
|
|
sudo mount /dev/mapper/"${mappings[0]}" $path
|
|
return
|
|
fi
|
|
|
|
for mapping in ${mappings[@]}
|
|
do
|
|
local part_no=${mapping#*p*p}
|
|
local path=$embedded_base_dir/${raw_disk_partitions[${part_no} - 1]}
|
|
mkdir -p $path
|
|
sudo mount /dev/mapper/"${mapping}" $path 2>&1 >/dev/null
|
|
done
|
|
}
|
|
|
|
# Takes following arguments:
|
|
#
|
|
# $1 - partition mappings holder
|
|
mount_mender_disk() {
|
|
local mappings=($@)
|
|
local counts=${#mappings[@]}
|
|
|
|
if [ $counts -eq 4 ]; then
|
|
local labels=(${mender_partitions_regular[@]})
|
|
elif [ $counts -eq 6 ]; then
|
|
local labels=(${mender_partitions_extended[@]})
|
|
fi
|
|
|
|
for mapping in ${mappings[@]}
|
|
do
|
|
local part_no=${mapping#*p*p}
|
|
local path=$sdimg_base_dir/${labels[${part_no} - 1]}
|
|
mkdir -p $path
|
|
|
|
case ${part_no} in
|
|
1|2|3)
|
|
sudo mount /dev/mapper/"${mapping}" $path 2>&1 >/dev/null
|
|
;;
|
|
4)
|
|
if [ $counts -eq 4 ]; then
|
|
sudo mount /dev/mapper/"${mapping}" $path 2>&1 >/dev/null
|
|
else
|
|
# Skip extended partition.
|
|
continue
|
|
fi
|
|
;;
|
|
5)
|
|
sudo mount /dev/mapper/"${mapping}" $path 2>&1 >/dev/null
|
|
;;
|
|
6)
|
|
# Skip swap partition.
|
|
continue
|
|
;;
|
|
*)
|
|
break
|
|
;;
|
|
esac
|
|
|
|
done
|
|
}
|
|
|
|
# Takes following arguments
|
|
#
|
|
# $1 - device type
|
|
set_fstab() {
|
|
local mountpoint=
|
|
local blk_device=
|
|
local data_id=4
|
|
local device_type=$1
|
|
local sysconfdir="$sdimg_primary_dir/etc"
|
|
|
|
[ ! -d "${sysconfdir}" ] && { log "Error: cannot find rootfs config dir."; exit 1; }
|
|
|
|
# Erase/create the fstab file.
|
|
sudo install -b -m 644 /dev/null ${sysconfdir}/fstab
|
|
|
|
case "$device_type" in
|
|
"beaglebone")
|
|
mountpoint="/boot/efi"
|
|
blk_device=mmcblk0p
|
|
;;
|
|
"raspberrypi3"|"raspberrypi0w")
|
|
mountpoint="/uboot"
|
|
blk_device=mmcblk0p
|
|
;;
|
|
"qemux86_64")
|
|
mountpoint="/boot/efi"
|
|
blk_device=hda
|
|
data_id=5
|
|
;;
|
|
esac
|
|
|
|
# Add Mender specific entries to fstab.
|
|
sudo bash -c "cat <<- EOF > ${sysconfdir}/fstab
|
|
# stock fstab - you probably want to override this with a machine specific one
|
|
|
|
/dev/root / auto defaults 1 1
|
|
proc /proc proc defaults 0 0
|
|
devpts /dev/pts devpts mode=0620,gid=5 0 0
|
|
tmpfs /run tmpfs mode=0755,nodev,nosuid,strictatime 0 0
|
|
tmpfs /var/volatile tmpfs defaults 0 0
|
|
|
|
# uncomment this if your device has a SD/MMC/Transflash slot
|
|
#/dev/mmcblk0p1 /media/card auto defaults,sync,noauto 0 0
|
|
|
|
# Where the U-Boot environment resides; for devices with SD card support ONLY!
|
|
/dev/${blk_device}1 $mountpoint auto defaults,sync 0 0
|
|
/dev/${blk_device}${data_id} /data auto defaults 0 0
|
|
EOF"
|
|
|
|
if [ "$device_type" == "qemux86_64" ]; then
|
|
# Add entry referring to swap partition.
|
|
sudo tee -a ${sysconfdir}/fstab <<< "/dev/hda6 swap swap defaults 0 0" 2>&1 >/dev/null
|
|
fi
|
|
|
|
log "\tDone."
|
|
}
|
|
|
|
# Takes following arguments
|
|
#
|
|
# $1 - path to source raw disk image
|
|
# $2 - sector start (in 512 blocks)
|
|
# $3 - size (in 512 blocks)
|
|
|
|
extract_file_from_image() {
|
|
log "\tStoring data in $4."
|
|
local cmd="dd if=$1 of=${output_dir}/$4 skip=$2 bs=512 count=$3 conv=sparse"
|
|
$(${cmd}>> "$build_log" 2>&1)
|
|
}
|
|
|
|
# Takes following arguments
|
|
#
|
|
# $1 - device type
|
|
# $2 - partition alignment in bytes
|
|
# $3 - total size in bytes
|
|
# $4 - array of partitions' sizes for Mender image
|
|
#
|
|
create_test_config_file() {
|
|
local device_type=$1
|
|
local alignment=$2
|
|
local mender_image_size_mb=$(( (($3 / 1024) / 1024) ))
|
|
local _mender_sizes=$(declare -p $4)
|
|
eval "declare -A mender_sizes="${_mender_sizes#*=}
|
|
local sector_size=${mender_sizes[sector_size]}
|
|
|
|
local boot_offset=$(( (${mender_sizes[pboot_start]} * $sector_size) ))
|
|
local boot_size_mb=$(( (((${mender_sizes[pboot_size]} * $sector_size) / 1024) / 1024) ))
|
|
local rootfs_size_mb=$(( (((${mender_sizes[prootfs_size]} * $sector_size) / 1024) / 1024) ))
|
|
local data_size_mb=$(( (((${mender_sizes[pdata_size]} * $sector_size) / 1024) / 1024) ))
|
|
|
|
cp ${files_dir}/variables.template ${output_dir}/${device_type}_variables.cfg
|
|
|
|
sed -i '/^MENDER_BOOT_PART_SIZE_MB/s/=.*$/="'${boot_size_mb}'"/' ${output_dir}/${device_type}_variables.cfg
|
|
sed -i '/^MENDER_DATA_PART_SIZE_MB/s/=.*$/="'${data_size_mb}'"/' ${output_dir}/${device_type}_variables.cfg
|
|
sed -i '/^MENDER_DEVICE_TYPE/s/=.*$/="'${device_type}'"/' ${output_dir}/${device_type}_variables.cfg
|
|
sed -i '/^MENDER_PARTITION_ALIGNMENT/s/=.*$/="'${alignment}'"/' ${output_dir}/${device_type}_variables.cfg
|
|
sed -i '/^MENDER_STORAGE_TOTAL_SIZE_MB/s/=.*$/="'${mender_image_size_mb}'"/' ${output_dir}/${device_type}_variables.cfg
|
|
sed -i '/^MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET/s/=.*$/="'${boot_offset}'"/' ${output_dir}/${device_type}_variables.cfg
|
|
sed -i '/^MENDER_CALC_ROOTFS_SIZE/s/=.*$/="'${rootfs_size_mb}'"/' ${output_dir}/${device_type}_variables.cfg
|
|
sed -i '/^MENDER_MACHINE/s/=.*$/="'${device_type}'"/' ${output_dir}/${device_type}_variables.cfg
|
|
sed -i '/^DEPLOY_DIR_IMAGE/s/=.*$/="'${output_dir//\//\\/}'"/' ${output_dir}/${device_type}_variables.cfg
|
|
}
|
|
|
|
# Takes following arguments
|
|
#
|
|
# $1 - device type
|
|
# $2 - parameter name to change
|
|
# $3 - parameter value
|
|
update_test_config_file() {
|
|
local device_type=$1
|
|
|
|
[ ! -f "${output_dir}/${device_type}_variables.cfg" ] && \
|
|
{ log "Error: test configuration file '${device_type}_variables.cfg' not found. Aborting."; return 1; }
|
|
|
|
shift
|
|
|
|
while test ${#} -gt 0
|
|
do
|
|
case "$1" in
|
|
"artifact-name")
|
|
sed -i '/^MENDER_ARTIFACT_NAME/s/=.*$/="'${2}'"/' ${output_dir}/${device_type}_variables.cfg
|
|
;;
|
|
"distro-feature")
|
|
sed -i '/^DISTRO_FEATURES/s/=.*$/="'${2}'"/' ${output_dir}/${device_type}_variables.cfg
|
|
;;
|
|
"mount-location")
|
|
sed -i '/^MENDER_BOOT_PART_MOUNT_LOCATION/s/=.*$/="'${2}'"/' ${output_dir}/${device_type}_variables.cfg
|
|
;;
|
|
esac
|
|
shift 2
|
|
done
|
|
|
|
return 0
|
|
}
|
|
|