yocto 自动挂载分区(基于stmp32mp1)
上一章我们在stm32mp1开发板上实践了创建分区的过程,本节我们再来分析下上小节创建的分区开机时是怎么完成分区的自动挂载的。
答案就在systemd里面:
下面就来详细分析一下这个几个文件
mount-partitons分析
systemd-mount-partitions.bb
先来看看systemd-mount-partitions.bb文件的具体内容:
# Copyright (C) 2018, STMicroelectronics - All Rights Reserved
# Released under the MIT license (see COPYING.MIT for the terms)
SUMMARY = "Mount partitions"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
RDEPENDS_${PN} += " util-linux "
MOUNT_BASENAME = "mount-partitions"
SRC_URI = " \
file://${MOUNT_BASENAME}.service \
file://${MOUNT_BASENAME}.sh \
"
inherit systemd update-rc.d
INITSCRIPT_NAME = "${MOUNT_BASENAME}.sh"
INITSCRIPT_PARAMS = "start 22 5 3 ."
SYSTEMD_PACKAGES = "${@bb.utils.contains('DISTRO_FEATURES','systemd','${PN}','',d)}"
SYSTEMD_SERVICE_${PN} = "${MOUNT_BASENAME}.service"
SYSTEMD_AUTO_ENABLE_${PN} = "enable"
# This list should be set with partition label and associated mountpoint
# <partition_label1>,<partition_mountpoint1> <partition_label2>,<partition_mountpoint2>
MOUNT_PARTITIONS_LIST ?= ""
PARTITIONS_CONFIG ?= ""
# Update MOUNT_PARTITIONS_LIST var with input from PARTITIONS_CONFIG enabled
python set_partitions_list() {
partitionsconfig = (d.getVar('PARTITIONS_CONFIG') or "").split()
if len(partitionsconfig) > 0:
partitionsconfigflags = d.getVarFlags('PARTITIONS_CONFIG')
# The "doc" varflag is special, we don't want to see it here
partitionsconfigflags.pop('doc', None)
for config in partitionsconfig:
for f, v in partitionsconfigflags.items():
if config == f:
items = v.split(',')
# Make sure a mount point is available
if len(items) > 2 and items[1] and items[2]:
bb.debug(1, "Appending '%s,%s' to MOUNT_PARTITIONS_LIST." % (items[1], items[2]))
d.appendVar('MOUNT_PARTITIONS_LIST', ' ' + items[1] + ',' + items[2])
break
}
do_install[prefuncs] += "set_partitions_list"
do_install() {
if [ -n "${MOUNT_PARTITIONS_LIST} " ] ; then
for part in ${MOUNT_PARTITIONS_LIST}
do
part_label=$(echo ${part} | cut -d',' -f1)
mountpoint=$(echo ${part} | cut -d',' -f2)
# Check that list is properly feed
[ -z "${part_label}" ] && bbfatal "MOUNT_PARTITIONS_LIST parsing error: ${part} does not contain partition label"
[ -z "${mountpoint}" ] && bbfatal "MOUNT_PARTITIONS_LIST parsing error: ${part} does not contain partition mountpoint"
done
if ${@bb.utils.contains('DISTRO_FEATURES','systemd','true','false',d)}; then
install -d ${D}${systemd_unitdir}/system ${D}/${base_sbindir}
install -m 644 ${WORKDIR}/${MOUNT_BASENAME}.service ${D}/${systemd_unitdir}/system
install -m 755 ${WORKDIR}/${MOUNT_BASENAME}.sh ${D}/${base_sbindir}/
# Update script
sed 's:^MOUNT_PARTITIONS_LIST=.*$:MOUNT_PARTITIONS_LIST=\"'"${MOUNT_PARTITIONS_LIST}"'\":' -i ${D}/${base_sbindir}/${MOUNT_BASENAME}.sh
fi
install -d ${D}/${INIT_D_DIR}
install -m 755 ${WORKDIR}/${MOUNT_BASENAME}.sh ${D}/${INIT_D_DIR}/
# Update script
sed 's:^MOUNT_PARTITIONS_LIST=.*$:MOUNT_PARTITIONS_LIST=\"'"${MOUNT_PARTITIONS_LIST}"'\":' -i ${D}/${INIT_D_DIR}/${MOUNT_BASENAME}.sh
else
bbfatal "Please set MOUNT_PARTITIONS_LIST with expected partition labels and mount point."
fi
}
FILES_${PN} += " ${systemd_unitdir} ${base_sbindir} ${INIT_D_DIR}"
-
SYSTEMD_AUTO_ENABLE_${PN} = “enable”
控制自动挂载分区功能的使能 -
do_install[prefuncs] += “set_partitions_list”
在install之前添加一个func set_partitions_list
set_partitions_list函数和之前分析的那么多配置文件一样同样依赖于全局配置PARTITIONS_CONFIG,这个配置的内容前面很多文章都介绍了这里就不再复述了,这个函数最终会解析PARTITIONS_CONFIG变量得到一个MOUNT_PARTITIONS_LIST变量,里面保存这需要mount的分区和挂载点。
MOUNT_PARTITIONS_LIST:bootfs,/boot vendorfs,/vendor userfs,/usr/local -
do_install
安装mount-partitions.service 和mount-partitions.sh
mount-partitions.service
可以看到mount-partitions.service实际控制的就是mount-partitions.sh的启动和关闭
mount-partitions.sh
#!/bin/sh -
#===============================================================================
#
# FILE: mount-partitions.sh
#
# USAGE: ./mount-partitions.sh [start|stop]
#
# DESCRIPTION: mount partitions
# ORGANIZATION: STMicroelectronics
# COPYRIGHT: Copyright (C) 2018, STMicroelectronics - All Rights Reserved
# CREATED: 01/09/2018 13:36
# REVISION: ---
#===============================================================================
MOUNT_PARTITIONS_LIST=""
get_type() {
local __resultvar=$1
ROOT_TYPE="unknown"
if [ -f /usr/bin/findmnt ];
then
ROOT_DEVICE=$(findmnt --noheadings --output=SOURCE / | cut -d'[' -f1)
case $ROOT_DEVICE in
ubi*)
ROOT_TYPE="nand"
;;
/dev/mmcblk1*)
ROOT_TYPE="sdmmc"
;;
/dev/mmcblk2*)
ROOT_TYPE="mmc"
;;
/dev/disk/by-*)
LINK=$(/usr/bin/readlink $ROOT_DEVICE | tr '/' ' ' | tr '.' ' ' | sed "s/ //g")
case $LINK in
ubi*)
ROOT_TYPE="nand"
;;
mmcblk1*)
ROOT_TYPE="sdmmc"
;;
mmcblk2*)
ROOT_TYPE="mmc"
;;
esac
;;
esac
else
if [ `cat /proc/cmdline | sed "s/.*mmcblk1.*/mmcblk1/" ` == "mmcblk1" ]; then
ROOT_TYPE="sdmmc"
elif [ `cat /proc/cmdline | sed "s/.*mmcblk2.*/mmcblk2/" ` == "mmcblk2" ]; then
ROOT_TYPE="mmc"
elif [ `cat /proc/cmdline | sed "s/.*ubi0.*/ubi0/" ` == "ubi0" ]; then
ROOT_TYPE="nand"
fi
fi
eval $__resultvar="'$ROOT_TYPE'"
}
found_devices() {
local __resultvar=$1
local __resultopt=$2
local _type=$3
local _search=$4
local _device="unknown"
local _option=" "
case $_type in
nand)
local ubi_volumes=$(ls -1 -d /sys/class/ubi/ubi0_*)
for f in $ubi_volumes;
do
if [ -r $f/name ];
then
cat $f/name | grep -sq "^${_search}"
if [ "$?" -eq 0 ];
then
_device="/dev/$(basename $f)"
_option="-t ubifs"
break;
fi
fi
done
;;
sdmmc)
local sdmmc_parts=$(ls -1 -d /sys/block/mmcblk1/mmcblk1p*)
for f in $sdmmc_parts;
do
if [ -r $f/uevent ];
then
cat $f/uevent | grep PARTNAME | sed "s/PARTNAME=//" | grep -sq "^${_search}"
if [ "$?" -eq 0 ];
then
_device="/dev/$(basename $f)"
break;
fi
fi
done
;;
mmc)
local mmc_parts=$(ls -1 -d /sys/block/mmcblk2/mmcblk2p*)
for f in $mmc_parts;
do
if [ -r $f/uevent ];
then
cat $f/uevent | grep PARTNAME | sed "s/PARTNAME=//" | grep -sq "^${_search}"
if [ "$?" -eq 0 ];
then
_device="/dev/$(basename $f)"
break;
fi
fi
done
;;
esac
eval $__resultvar="'$_device'"
eval $__resultopt="'$_option'"
}
case "$1" in
start)
# mount partitions
get_type TYPE
echo "TYPE of support detected: $TYPE"
for part in $MOUNT_PARTITIONS_LIST
do
part_label=$(echo $part | cut -d',' -f1)
mountpoint=$(echo $part | cut -d',' -f2)
found_devices DEVICE DEVICE_OPTION $TYPE $part_label
echo "$part_label device: $DEVICE"
[ -d $mountpoint ] || mkdir -p $mountpoint
[ -e $DEVICE ] && mount $DEVICE_OPTION $DEVICE $mountpoint
done
;;
stop)
# umount partitions
for part in $MOUNT_PARTITIONS_LIST
do
mountpoint=$(echo $part | cut -d',' -f2)
umount $mountpoint
done
;;
*)
echo "Usage: $0 [start|stop]"
;;
esac
- get_type()
获取当前根文件系统启动的存储介质,支持emmc nand sdmmc - found_devices()
根据不同的启动存储介质找到分区lable对应的实际分区,以mmc启动介质、bootfs为例:
在 /sys/block/mmcblk2/mmcblk2p* 里面查找PARTNAME=bootfs的具体分区,得到/sys/block/mmcblk2/mmcblk2p2,然后就可以执行mount /dev/mmcblk2p3 /boot - 循环遍历MOUNT_PARTITIONS_LIST 里面的配置,来决定执行mount 还是umount动作,对应:
mount-partitons.sh start
mount-partitons.sh stop
最终效果就是
执行 systemctl start mount-partitons.service 挂载所有分区
执行 systemctl stop mount-partitons.service 卸载所有分区
Done