yocto machine class解析之flashlayout-stm32mp

yocto machine class解析之flashlayout-stm32mp

上一篇文章中我们详细介绍了st-partitions-image class。里面根据配置生成了许多的分区镜像以及分区镜像的一些参数设置。本章节介绍的flashlayout class就会根据上面生成的这些参数来生成特定的.tsv刷机文件供ST的刷机工具使用。

flashlayout介绍

本小节先介绍一些flashlayout tsv文件的格式和说明,方便后续分析具体的实现过程,下面是
build-openstlinuxeglfs-fsmp1a/tmp-glibc/deploy/images/fsmp1a/flashlayout_fs-mp1a-qt/trusted/目录下的
FlashLayout_sdcard_stm32mp157a-fsmp1a-trusted.tsv文件:
在这里插入图片描述

  • Opt: 选项字段可以设置为"-“()、“P”(烧写)、“D”(删除)或"E”(不更新) “PE”(不更新)“PD”(删除并更新)
  • Id: 会根据这个 id 来决定烧写分区
  • Name: 分区名字
  • Type: 指定烧写的类型,仅 uboot 使用。
  • IP:指定烧写的设备类型与编号,比如 emmc0、 emmc1、 nand0 等, 如果 opt 为‘-’ ,那么此字段就为 none
  • Offset:分区的起始位置,表示需要偏移的字节数。
  • Binary: 要烧录的文件

flashlayout-stm32mp class分析

下面我们来详细分析flashlayout-stm32mp class的具体实现,flashlayout-stm32mp文件非常长,一点点过把。

介绍

flashlayout的刷机文件可以通过静态设置也可以通过动态生成,使用ENABLE_FLASHLAYOUT_DEFAULT变量来控制。

  • 如果设置为静态设置的话需要自己先改好一个falshlayout tsv文件,然后设置这个文件的路径到变量FLASHLAYOUT_DEFAULT_SRC,然后一起打包到deploy的生成镜像里面。

  • 动态生成的话需要配置一系列变量,其中tsv文件命名格式所需变量如下:
    <FLASHLAYOUT_BASENAME>[<FLASHLAYOUT_CONFIG_LABEL>][<FLASHLAYOUT_TYPE_LABEL>-FLASHLAYOUT_BOOTSCHEME_LABEL].<FLASHLAYOUT_SUFFIX>
    其中FLASHLAYOUT_BASENAME 默认是 ‘FlashLayout’,FLASHLAYOUT_SUFFIX默认是’tsv’,改写下上面的格式:
    FlashLayout[<FLASHLAYOUT_CONFIG_LABEL>][<FLASHLAYOUT_TYPE_LABEL>-FLASHLAYOUT_BOOTSCHEME_LABEL].tsv
    如上面展示的FlashLayout_sdcard_stm32mp157a-fsmp1a-trusted.tsv可以看到:
    FLASHLAYOUT_CONFIG_LABEL:sdcard
    FLASHLAYOUT_TYPE_LABEL:stm32mp157a
    FLASHLAYOUT_BOOTSCHEME_LABEL:trusted

  • tsv文件所需格式变量:
    <FLASHLAYOUT_PARTITION_ENABLE>(Opt)
    <FLASHLAYOUT_PARTITION_ID>(Id)
    <FLASHLAYOUT_PARTITION_LABEL>(Name)
    <FLASHLAYOUT_PARTITION_TYPE>(Type)
    <FLASHLAYOUT_PARTITION_DEVICE>(IP)
    <FLASHLAYOUT_PARTITION_OFFSET>(Offset)
    <FLASHLAYOUT_PARTITION_BIN2LOAD>(Binary)
    <FLASHLAYOUT_PARTITION_SIZE>: 上面FLASHLAYOUT_PARTITION_OFFSET本来应该手动指定,但是如果配置了FLASHLAYOUT_PARTITION_SIZE这个变量则可以根据分区镜像的大小结合DEVICE_ALIGNMENT_SIZE_指定特定的对齐大小来自动计算下一个分区的OFFSET( 就是本分区的FLASHLAYOUT_PARTITION_DEVICE)

#
# --------------------
# Static configuration
# --------------------
# Set ENABLE_FLASHLAYOUT_DEFAULT to '1'.
# Configure FLASHLAYOUT_DEFAULT_SRC with the static flashlayout file locations.
#
# Configuration example (machine file or local.conf):
#   ENABLE_FLASHLAYOUT_DEFAULT = "1"
#   FLASHLAYOUT_DEFAULT_SRC = "files/flashlayouts/FlashLayout_sdcard_stm32mp157c-ev1_sample.tsv"
#
# ---------------------
# Dynamic configuration
# ---------------------
# Set ENABLE_FLASHLAYOUT_DEFAULT to '0'.
# In order to automatically generate flashlayout files as well formated TSV file
# there are some variables to configure.
#
# Naming:
#   <FLASHLAYOUT_BASENAME>[_<FLASHLAYOUT_CONFIG_LABEL>][_<FLASHLAYOUT_TYPE_LABEL>-FLASHLAYOUT_BOOTSCHEME_LABEL].<FLASHLAYOUT_SUFFIX>
#
#   FLASHLAYOUT_BASENAME
#       Default to 'FlashLayout'
#   FLASHLAYOUT_CONFIG_LABEL
#       Set from FLASHLAYOUT_CONFIG_LABELS list (without any '_' in config labels)
#   FLASHLAYOUT_TYPE_LABEL
#       Set from FLASHLAYOUT_TYPE_LABELS list
#   FLASHLAYOUT_BOOTSCHEME_LABEL
#       Set from FLASHLAYOUT_BOOTSCHEME_LABELS list (without any '_' in bootscheme labels)
# Note that both are appended only when FLASHLAYOUT_TYPE_LABELS and FLASHLAYOUT_BOOTSCHEME_LABELS contain more than two labels.
#   FLASHLAYOUT_SUFFIX
#       Default to 'tsv'
#
# File content structure:
#   Opt     Id      Name    Type    IP      Offset  Binary
#   <FLASHLAYOUT_PARTITION_ENABLE>
#           <FLASHLAYOUT_PARTITION_ID>
#                   <FLASHLAYOUT_PARTITION_LABEL>
#                           <FLASHLAYOUT_PARTITION_TYPE>
#                                   <FLASHLAYOUT_PARTITION_DEVICE>
#                                           <FLASHLAYOUT_PARTITION_OFFSET>
#                                                   <FLASHLAYOUT_PARTITION_BIN2LOAD>
#
# Specific configuration:
#   FLASHLAYOUT_PARTITION_SIZE
#       If configured, it allows to compute the next offset to apply in
#       flashlayout file for the following partition.
#       Note that according to the device in use for the partition a specific
#       alignment size can be specified through DEVICE_ALIGNMENT_SIZE_<device>
#       var where <device> is the current FLASHLAYOUT_PARTITION_DEVICE
#
# Note that override is manage for 'FLASHLAYOUT_PARTITION_LABELS' list with:
#   - <bootscheme-label> from FLASHLAYOUT_BOOTSCHEME_LABELS' list
#   - <config-label> from 'FLASHLAYOUT_CONFIG_LABELS' list
# Priority assignment is:
#   It means the 'FLASHLAYOUT_PARTITION_LABELS' value can be overriden by setting:
#   FLASHLAYOUT_PARTITION_LABELS_<bootscheme-label>_<config-label>
#   FLASHLAYOUT_PARTITION_LABELS_<bootscheme-label>
#   FLASHLAYOUT_PARTITION_LABELS_<config-label>
#   FLASHLAYOUT_PARTITION_LABELS
#
# Another override mechanism is also implemented for all other partition variables:
#   FLASHLAYOUT_PARTITION_ENABLE
#   FLASHLAYOUT_PARTITION_ID
#   FLASHLAYOUT_PARTITION_TYPE
#   FLASHLAYOUT_PARTITION_DEVICE
#   FLASHLAYOUT_PARTITION_OFFSET
#   FLASHLAYOUT_PARTITION_BIN2LOAD
# We can override these variable with:
#   - <config-label> from 'FLASHLAYOUT_CONFIG_LABELS' list
#   - <bootscheme-label> from 'FLASHLAYOUT_BOOTSCHEME_LABELS' list
#   - <partition-label> from 'FLASHLAYOUT_PARTITION_LABELS' list
# Priority assignment is:
#   FLASHLAYOUT_PARTITION_xxx_<bootscheme-label>_<config-label>_<partition-label>
#   FLASHLAYOUT_PARTITION_xxx_<bootscheme-label>_<config-label>
#   FLASHLAYOUT_PARTITION_xxx_<bootscheme-label>_<partition-label>
#   FLASHLAYOUT_PARTITION_xxx_<bootscheme-label>
#   FLASHLAYOUT_PARTITION_xxx_<config-label>_<partition-label>
#   FLASHLAYOUT_PARTITION_xxx_<config-label>
#   FLASHLAYOUT_PARTITION_xxx_<partition-label>
#   FLASHLAYOUT_PARTITION_xxx
# -----------------------------------------------------------------------------

变量定义

上面介绍部分大概对生成flashlayout tsv文件有了一定了解,下面看看相关的变量初始化定义:


# Configure flashlayout file generation
ENABLE_FLASHLAYOUT_CONFIG ??= "1"
# Configure direct use of flashlayout file without automatic file generation
ENABLE_FLASHLAYOUT_DEFAULT ??= "0"
# Configure path for provided flashlayout file
FLASHLAYOUT_DEFAULT_SRC ??= ""
# Configure flashlayout file name default format
FLASHLAYOUT_BASENAME ??= "FlashLayout"
FLASHLAYOUT_SUFFIX   ??= "tsv"
# Configure flashlayout file generation for stm32wrapper4dbg
ENABLE_FLASHLAYOUT_CONFIG_WRAPPER4DBG ??= "0"

# Configure folders for flashlayout file generation
FLASHLAYOUT_DEPLOYDIR ?= "${DEPLOY_DIR}/images/${MACHINE}"
FLASHLAYOUT_TOPDIR ?= "${WORKDIR}/flashlayout-destdir/"
FLASHLAYOUT_SUBDIR ?= "flashlayout_${PN}"
FLASHLAYOUT_DESTDIR = "${FLASHLAYOUT_TOPDIR}/${FLASHLAYOUT_SUBDIR}"

# Init bootscheme and config labels
FLASHLAYOUT_BOOTSCHEME_LABELS ??= ""
FLASHLAYOUT_CONFIG_LABELS ??= ""
# Init partition image list (used to configure partitions)
FLASHLAYOUT_PARTITION_IMAGES ??= ""
# Init partition and type labels
#   Note: possible override with bootscheme and/or config
FLASHLAYOUT_PARTITION_LABELS   ??= ""
FLASHLAYOUT_TYPE_LABELS ??= ""
# Init flashlayout partition vars
#   Note: possible override with bootscheme and/or config and/or partition
FLASHLAYOUT_PARTITION_ENABLE ??= ""
FLASHLAYOUT_PARTITION_ID ??= ""
FLASHLAYOUT_PARTITION_TYPE ??= ""
FLASHLAYOUT_PARTITION_DEVICE ??= ""
FLASHLAYOUT_PARTITION_OFFSET ??= ""
FLASHLAYOUT_PARTITION_BIN2LOAD ??= ""
FLASHLAYOUT_PARTITION_SIZE ??= ""
FLASHLAYOUT_PARTITION_REPLACE_PATTERNS ??= ""

可以看到ENABLE_FLASHLAYOUT_DEFAULT ??= “0” 即默认使用动态生成flashlayout文件,同时初始化了一系列介绍部分提及到的变量,还可以看到配置了默认flashlayout 的存储路径是“${DEPLOY_DIR}/images/${MACHINE}”下面
工作路径是“${WORKDIR}/flashlayout-destdir/flashlayout_${PN}”,如下所示:

在这里插入图片描述

匿名函数分析

下面开始分析出现的第一个函数。
可以看到这个函数似曾相识,在上一篇分析st-partitions-image class中的匿名函数也长的类似,同样用到了PARTITIONS_CONFIG 变量,这个变量的具体内容参考上一节st-partitions-image直接复制过来:
PARTITIONS_CONFIG=" bootfs vendorfs rootfs userfs"
//PARTITIONS_CONFIG[xxxfs] 字段含义
// “ S T M 32 M P X X F S I M A G E , {STM32MP_XXFS_IMAGE}, STM32MPXXFSIMAGE,{STM32MP_XXFS_LABEL}, S T M 32 M P X X F S M O U N T P O I N T , {STM32MP_XXFS_MOUNTPOINT}, STM32MPXXFSMOUNTPOINT,{XXFS_PARTITION_SIZE},System”

PARTITIONS_CONFIG[bootfs] ?= “st-image-bootfs,boot,/boot,65536,System”
PARTITIONS_CONFIG[vendorfs] ?= “st-image-vendorfs,vendorfs,/vendor,16384,FileSystem”
PARTITIONS_CONFIG[rootfs] ?= “fs-mp1a-qt-openstlinux-eglfs,rootfs,1253376,FileSystem”
PARTITIONS_CONFIG[userfs] ?= “st-image-userfs,userfs,/usr/local,131072,FileSystem”

总结下面函数干的事情就是先找到所有do_image_complete 的task,然后过滤掉initrd ramfs bootfs vendorfs rootfs userfs 这几个,
添加一个do_create_flashlayout_config task,执行时机在 do_build 和 do_image_complete中间,执行do_create_flashlayout_config之前还要先执行flashlayout_partition_image_config函数
do_create_flashlayout_config[prefuncs] = flashlayout_partition_image_config


python __anonymous () {
    # -----------------------------------------------------------------------------
    # Make sure to add the flashlayout file creation after ROOTFS build
    # So we should identify image ROOTFS build and only the ROOTFS (for now)
    # As we know that PARTITIONS may be built as part of ROOTFS build, let's
    # avoid amending the partition images
    # -----------------------------------------------------------------------------
    if d.getVar('ENABLE_FLASHLAYOUT_CONFIG') == "1":
        # Gather all current tasks
        tasks = filter(lambda k: d.getVarFlag(k, "task", True), d.keys())
        for task in tasks:
            # Check that we are dealing with image recipe
            if task == 'do_image_complete':
                # Init current image name
                current_image_name = d.getVar('PN') or ""
                # Init RAMFS image if any
                initramfs = d.getVar('INITRAMFS_IMAGE') or ""
                # Init INITRD image if any
                initrd = d.getVar('INITRD_IMAGE') or ""
                # Init partition list from PARTITIONS_CONFIG
                image_partitions = []
                # Append image_partitions list with all configured partition images:

                partitionsconfigflags = d.getVarFlags('PARTITIONS_CONFIG')
                # The "doc" varflag is special, we don't want to see it here
                partitionsconfigflags.pop('doc', None)
                partitionsconfig = (d.getVar('PARTITIONS_CONFIG') or "").split()
                if len(partitionsconfig) > 0:
                    for config in partitionsconfig:
                        for f, v in partitionsconfigflags.items():
                            if config == f:
                                items = v.split(',')
                                # Make sure about PARTITIONS_CONFIG contents
                                if items[0] and len(items) > 5:
                                    bb.fatal('[PARTITIONS_CONFIG] Only image,label,mountpoint,size,type can be specified!')
                                # Make sure that we're dealing with partition image and not rootfs image
                                if len(items) > 2 and items[2]:
                                    # Mount point is available, so we're dealing with partition image
                                    # Append image to image_partitions list
                                    image_partitions.append(d.expand(items[0]))
                                break

                # We need to clearly identify ROOTFS build, not InitRAMFS/initRD one (if any), not partition one either
                if current_image_name not in image_partitions and current_image_name != initramfs and current_image_name != initrd:
                    # We add the flashlayout file creation task just after the do_image_complete for ROOTFS build
                    bb.build.addtask('do_create_flashlayout_config', 'do_build', 'do_image_complete', d)
                    # We add also the function that feeds the FLASHLAYOUT_PARTITION_* vars from PARTITIONS_CONFIG
                    d.appendVarFlag('do_create_flashlayout_config', 'prefuncs', ' flashlayout_partition_image_config')
}

do_create_flashlayout_config任务

上面知道每个image的bb都添加了一个do_create_flashlayout_config 任务和flashlayout_partition_image_config函数,那么下面的重点自然就是这两部分了。先从flashlayout_partition_image_config开始

flashlayout_partition_image_config

flashlayout_partition_image_config同样用到了PARTITIONS_CONFIG变量
以PARTITIONS_CONFIG[bootfs] ?= “st-image-bootfs,boot,/boot,65536,System” 为例, 实际做事如下:
FLASHLAYOUT_PARTITION_IMAGES +=boot
FLASHLAYOUT_PARTITION_BIN2LOAD_boot = st-image-bootfs + "-${DISTRO}-${MACHINE}.ext4
FLASHLAYOUT_PARTITION_SIZE_boot = 65536
FLASHLAYOUT_PARTITION_TYPE_boot = System
FLASHLAYOUT_PARTITION_ID_boot = $part_id
part_id 区分bin(从4开始)还是其他(从33开始)动态自增

PARTITIONS_CONFIG里面的其他镜像以此类推,那么下面这个图里还没有确定的就是P mmc0 0x00284400这几个部分了,
在这里插入图片描述继续看do_create_flashlayout_config任务


python flashlayout_partition_image_config() {
    """
    Set the different flashlayout partition vars for the configure partition
    images.
    Based on PARTITIONS_CONFIG, feed:
        FLASHLAYOUT_PARTITION_IMAGES
        FLASHLAYOUT_PARTITION_ID_
        FLASHLAYOUT_PARTITION_TYPE_
        FLASHLAYOUT_PARTITION_SIZE_
        FLASHLAYOUT_PARTITION_BIN2LOAD_
    """

    partitionsconfigflags = d.getVarFlags('PARTITIONS_CONFIG')
    # The "doc" varflag is special, we don't want to see it here
    partitionsconfigflags.pop('doc', None)
    partitionsconfig = (d.getVar('PARTITIONS_CONFIG') or "").split()

    if len(partitionsconfig) > 0:
        # Init default partition id for binary type and other
        id_bin = 4
        id_oth = 33
        for config in partitionsconfig:
            for f, v in partitionsconfigflags.items():
                if config == f:
                    items = v.split(',')
                    # Make sure about PARTITIONS_CONFIG contents
                    if items[0] and len(items) > 5:
                        bb.fatal('[PARTITIONS_CONFIG] Only image,label,mountpoint,size,type can be specified!')
                    if items[1]:
                        bb.debug(1, "Appending %s to FLASHLAYOUT_PARTITION_IMAGES." % items[1])
                        d.appendVar('FLASHLAYOUT_PARTITION_IMAGES', ' ' + items[1])
                    else:
                        bb.fatal('[PARTITIONS_CONFIG] Missing image label setting')
                    # Init flashlayout label
                    fl_label = d.expand(items[1])
                    if items[2] == '':
                        # There is no mountpoint specified, so we apply rootfs image format
                        bb.debug(1, "Set FLASHLAYOUT_PARTITION_BIN2LOAD_%s to %s." % (fl_label, items[0] + "-${MACHINE}.ext4"))
                        d.setVar('FLASHLAYOUT_PARTITION_BIN2LOAD_%s' % fl_label, items[0] + "-${MACHINE}.ext4")
                    else:
                        bb.debug(1, "Set FLASHLAYOUT_PARTITION_BIN2LOAD_%s to %s." % (fl_label, items[0] + "-${DISTRO}-${MACHINE}.ext4"))
                        d.setVar('FLASHLAYOUT_PARTITION_BIN2LOAD_%s' % fl_label, items[0] + "-${DISTRO}-${MACHINE}.ext4")
                    if items[3]:
                        bb.debug(1, "Set FLASHLAYOUT_PARTITION_SIZE_%s to %s." % (fl_label, items[3]))
                        d.setVar('FLASHLAYOUT_PARTITION_SIZE_%s' % fl_label, items[3])
                    else:
                        bb.fatal('[PARTITIONS_CONFIG] Missing PARTITION_SIZE setting for % label' % fl_label)
                    if items[4]:
                        bb.debug(1, "Set FLASHLAYOUT_PARTITION_TYPE_%s to %s." % (fl_label, items[4]))
                        d.setVar('FLASHLAYOUT_PARTITION_TYPE_%s' % fl_label, items[4])
                        # Compute partition id according to type set
                        if items[4] == 'Binary':
                            part_id = '0x{0:0{1}X}'.format(id_bin, 2)
                            id_bin = id_bin + 1
                        else:
                            part_id = '0x{0:0{1}X}'.format(id_oth, 2)
                            id_oth = id_oth + 1
                        bb.debug(1, "Set FLASHLAYOUT_PARTITION_ID_%s to %s." % (fl_label, part_id))
                        d.setVar('FLASHLAYOUT_PARTITION_ID_%s' % fl_label, "%s" % part_id)
                    else:
                        bb.fatal('[PARTITIONS_CONFIG] Missing PARTITION_TYPE setting for % label' % fl_label)
                    break
}
do_create_flashlayout_config

在分析do_create_flashlayout_config task具体任务之前先看一下跟task相关的一些设置:

python do_create_flashlayout_config() {
}

do_create_flashlayout_config[dirs] = "${FLASHLAYOUT_DESTDIR}"

FLASHLAYOUT_DEPEND_TASKS ?= ""
do_create_flashlayout_config[depends] += "${FLASHLAYOUT_DEPEND_TASKS}"

SSTATETASKS += "do_create_flashlayout_config"
do_create_flashlayout_config[cleandirs] = "${FLASHLAYOUT_TOPDIR}"
do_create_flashlayout_config[sstate-inputdirs] = "${FLASHLAYOUT_TOPDIR}"
do_create_flashlayout_config[sstate-outputdirs] = "${FLASHLAYOUT_DEPLOYDIR}/"


FLASHLAYOUT_LABELS_VARS = "CONFIG_LABELS PARTITION_LABELS TYPE_LABELS"
FLASHLAYOUT_LABELS_OVERRIDES = "${@' '.join('%s %s %s_%s' % (b, c, b, c) for b in d.getVar('FLASHLAYOUT_BOOTSCHEME_LABELS').split() for c in d.getVar('FLASHLAYOUT_CONFIG_LABELS').split())}"
do_create_flashlayout_config[vardeps] += "${@' '.join(['FLASHLAYOUT_%s_%s' % (v, o) for v in d.getVar('FLASHLAYOUT_LABELS_VARS').split() for o in d.getVar('FLASHLAYOUT_LABELS_OVERRIDES').split()])}"

FLASHLAYOUT_PARTITION_VARS = "ENABLE ID TYPE DEVICE OFFSET BIN2LOAD SIZE REPLACE_PATTERNS"
FLASHLAYOUT_PARTITION_CONFIGURED = "${@" ".join(map(lambda o: "%s" % d.getVar("FLASHLAYOUT_PARTITION_LABELS_%s" % o), d.getVar('FLASHLAYOUT_LABELS_OVERRIDES').split()))}"
FLASHLAYOUT_PARTITION_OVERRIDES = "${@' '.join('%s %s %s_%s' % (o, p, o, p) for o in d.getVar('FLASHLAYOUT_LABELS_OVERRIDES').split() for p in d.getVar('FLASHLAYOUT_PARTITION_CONFIGURED').split())}"
do_create_flashlayout_config[vardeps] += "${@' '.join(['FLASHLAYOUT_PARTITION_%s_%s' % (v, o) for v in d.getVar('FLASHLAYOUT_PARTITION_VARS').split() for o in d.getVar('FLASHLAYOUT_PARTITION_OVERRIDES').split()])}"

FLASHLAYOUT_DEVICE_VARS = "ALIGNMENT_SIZE BOARD_ENABLE START_OFFSET"
FLASHLAYOUT_PARTITION_DEVICE_CONFIGURED = "${@" ".join(map(lambda p: "%s" % d.getVar("DEVICE_%s" % p), d.getVar('DEVICE_STORAGE_NAMES').split()))}"
do_create_flashlayout_config[vardeps] += "${@' '.join(['DEVICE_%s_%s' % (v, o) for v in d.getVar('FLASHLAYOUT_DEVICE_VARS').split() for o in d.getVar('FLASHLAYOUT_PARTITION_DEVICE_CONFIGURED').split()])}"

指定do_create_flashlayout_config 任务的

  • 工作路径为“${WORKDIR}/flashlayout-destdir/flashlayout_${PN}”
  • depends依赖(暂时为空)
  • SSTATETASKS 添加上do_create_flashlayout_config任务,同时指定共享状态的工作路径。
  • 设置do_create_flashlayout_config会用到的环境变量依赖列表

下面分析具体的do_create_flashlayout_config任务主体函数


python do_create_flashlayout_config() {
    import re
    import shutil

    # We check first if it is requested to generate any flashlayout files
    if d.getVar("ENABLE_FLASHLAYOUT_CONFIG") != "1":
        bb.note('ENABLE_FLASHLAYOUT_CONFIG not enabled')
        return

    # Create destination folder for flashlayout files
    bb.utils.remove(d.getVar('FLASHLAYOUT_DESTDIR'), recurse=True)
    bb.utils.mkdirhier(d.getVar('FLASHLAYOUT_DESTDIR'))

    # We check if user as define a static flashlayout file to use instead of dynamic generation
    if d.getVar("ENABLE_FLASHLAYOUT_DEFAULT") == "1":
        bb.note('ENABLE_FLASHLAYOUT_DEFAULT enabled')
        flashlayout_src = d.getVar("FLASHLAYOUT_DEFAULT_SRC")
        if not flashlayout_src:
            bb.fatal("FLASHLAYOUT_DEFAULT_SRC not defined, please set a proper value")
        if not flashlayout_src.strip():
            bb.fatal("No static flashlayout file configured, nothing to do")
        for fl_src in flashlayout_src.split():
            found, f = flashlayout_search(d, fl_src)
            if found:
                flashlayout_staticname=os.path.basename(f)
                flashlayout_file = os.path.join(d.getVar('FLASHLAYOUT_DESTDIR'), flashlayout_staticname)
                shutil.copy2(f, flashlayout_file)
                bb.note('Copy %s to output file %s' % (f, flashlayout_file))
            else:
                bb.fatal("Configure static file: %s not found" % fl_src)
        return

    # Set bootschemes for partition var override configuration
    bootschemes = d.getVar('FLASHLAYOUT_BOOTSCHEME_LABELS')
    if not bootschemes:
        bb.fatal("FLASHLAYOUT_BOOTSCHEME_LABELS not defined, nothing to do")
    if not bootschemes.strip():
        bb.fatal("No bootschemes, nothing to do")
    # Make sure there is no '_' in FLASHLAYOUT_BOOTSCHEME_LABELS
    for bootscheme in bootschemes.split():
        if re.match('.*_.*', bootscheme):
            bb.fatal("Please remove all '_' for bootschemes defined in FLASHLAYOUT_BOOTSCHEME_LABELS")
    bb.note('FLASHLAYOUT_BOOTSCHEME_LABELS: %s' % bootschemes)

    for bootscheme in bootschemes.split():
        bb.note('*** Loop for bootscheme label: %s' % bootscheme)
        # Get the different flashlayout config label
        configs = expand_var('FLASHLAYOUT_CONFIG_LABELS', bootscheme, '', '', d)
        # Make sure there is no '_' in FLASHLAYOUT_CONFIG_LABELS
        for config in configs.split():
            if re.match('.*_.*', config):
                bb.fatal("Please remove all '_' for configs defined in FLASHLAYOUT_CONFIG_LABELS")
        bb.note('FLASHLAYOUT_CONFIG_LABELS: %s' % configs)

        if configs.strip() == 'none':
            bb.note("FLASHLAYOUT_CONFIG_LABELS is none, so no flashlayout file to generate.")
            continue
        # Create bootscheme subfolder for flashlayout files
        flashlayout_subfolder_path = os.path.join(d.getVar('FLASHLAYOUT_DESTDIR'), bootscheme)
        bb.utils.mkdirhier(flashlayout_subfolder_path)

        for config in configs.split():
            bb.note('*** Loop for config label: %s' % config)
            # Set labeltypes list
            labeltypes = expand_var('FLASHLAYOUT_TYPE_LABELS', bootscheme, config, '', d)
            bb.note('FLASHLAYOUT_TYPE_LABELS: %s' % labeltypes)
            if labeltypes.strip() == 'none':
                bb.note("FLASHLAYOUT_TYPE_LABELS is none, so no flashlayout file to generate.")
                continue
            for labeltype in labeltypes.split():
                bb.note('*** Loop for label type: %s' % labeltype)
                # Init current label
                current_label = labeltype
                # Init flashlayout file name
                if config == 'none':
                    config_append = ''
                else:
                    config_append = '_' + config
                if len(labeltypes.split()) < 2 and len(bootschemes.split()) < 2:
                    labeltype_append = ''
                else:
                    labeltype_append = '_' + labeltype + '-' + bootscheme
                flashlayout_file = os.path.join(flashlayout_subfolder_path, d.expand("${FLASHLAYOUT_BASENAME}%s%s.${FLASHLAYOUT_SUFFIX}" % (config_append, labeltype_append)))
                # Get the partition list to write in flashlayout file
                partitions = expand_var('FLASHLAYOUT_PARTITION_LABELS', bootscheme, config, '', d)
                bb.note('FLASHLAYOUT_PARTITION_LABELS: %s' % partitions)
                if partitions == 'none':
                    bb.note("FLASHLAYOUT_PARTITION_LABELS is none, so no flashlayout file to generate.")
                    continue
                # Generate flashlayout file for labeltype
                try:
                    with open(flashlayout_file, 'w') as fl_file:
                        # Write to flashlayout file the first line header
                        fl_file.write('#Opt\tId\tName\tType\tIP\tOffset\tBinary\n')
                        # Init partition next offset to 'none'
                        partition_nextoffset = "none"
                        # Init partition previous device to 'none'
                        partition_prevdevice = "none"
                        for partition in partitions.split():
                            bb.note('*** Loop for partition: %s' % partition)
                            # Init partition settings
                            partition_enable = expand_var('FLASHLAYOUT_PARTITION_ENABLE', bootscheme, config, partition, d)
                            partition_id = expand_var('FLASHLAYOUT_PARTITION_ID', bootscheme, config, partition, d)
                            partition_name = partition
                            partition_type = expand_var('FLASHLAYOUT_PARTITION_TYPE', bootscheme, config, partition, d)
                            partition_device = get_device(bootscheme, config, partition, d)
                            # Reset partition_nextoffset to 'none' in case partition device has changed
                            if partition_device != partition_prevdevice:
                                partition_nextoffset = "none"
                            # Save partition current device to previous one for next loop
                            partition_prevdevice = partition_device
                            # Get partition offset
                            partition_offset, partition_nextoffset = get_offset(partition_nextoffset, partition_device, bootscheme, config, partition, d)
                            # Get binary name
                            partition_bin2load = get_binaryname(labeltype, bootscheme, config, partition, d)
                            # Be verbose in log file
                            bb.note('>>> Layout inputs: %s' % fl_file.name)
                            bb.note('>>> FLASHLAYOUT_PARTITION_ENABLE:      %s' % partition_enable)
                            bb.note('>>> FLASHLAYOUT_PARTITION_ID:          %s' % partition_id)
                            bb.note('>>> FLASHLAYOUT_PARTITION_LABEL:       %s' % partition_name)
                            bb.note('>>> FLASHLAYOUT_PARTITION_TYPE:        %s' % partition_type)
                            bb.note('>>> FLASHLAYOUT_PARTITION_DEVICE:      %s' % partition_device)
                            bb.note('>>> FLASHLAYOUT_PARTITION_OFFSET:      %s' % partition_offset)
                            bb.note('>>> FLASHLAYOUT_PARTITION_BIN2LOAD:    %s' % partition_bin2load)
                            bb.note('>>> done')
                            # Get the supported labels for current storage device
                            partition_device_alias = d.getVar('DEVICE_%s' % partition_device) or ""
                            partition_type_supported_labels = d.getVar('DEVICE_BOARD_ENABLE_%s' % partition_device_alias) or "none"
                            # Check if partition type is supported for the current label
                            if partition_device != 'none' and current_label not in partition_type_supported_labels.split():
                                bb.note('>>> FLASHLAYOUT_PARTITION_DEVICE (%s, alias %s) is not supported for current label (%s): partition %s not appended in flashlayout file' % (partition_device, partition_device_alias, current_label, partition_name))
                                bb.note('>>> DEVICE_BOARD_ENABLE_%s: %s' % (partition_device_alias, partition_type_supported_labels))
                                continue
                            # Write to flashlayout file the partition configuration
                            fl_file.write('%s\t%s\t%s\t%s\t%s\t%s\t%s\n' %
                                         (partition_enable, partition_id, partition_name, partition_type, partition_device, partition_offset, partition_bin2load))
                except OSError:
                    bb.fatal('Unable to open %s' % (fl_file))

                if d.getVar("ENABLE_FLASHLAYOUT_CONFIG_WRAPPER4DBG") == "1":
                    bb.note('*** Loop for flashlayout for the wrapper for debug %s' % labeltype)

                    tmp_flashlayout_file = os.path.join(flashlayout_subfolder_path, "flashlayout.tmp")
                    debug_flashlayout = False

                    try:
                        with open(flashlayout_file, 'r') as fl_file:
                            try:
                                with open(tmp_flashlayout_file, 'w') as debug_fl_file:
                                    for line in fl_file:
                                        if re.match('^.*/tf-a.*$', line) :
                                            line_tmp = re.sub(r'(.*)/',r'\1/debug/debug-', line)
                                            filename = re.sub(r'.*[\t ](.*)$',r'\1', line_tmp).strip()
                                            if os.path.isfile(os.path.join(d.getVar('DEPLOY_DIR_IMAGE'), filename)):
                                                line = line_tmp
                                                debug_flashlayout = True

                                        debug_fl_file.write('%s' % (line))
                            except OSError:
                                bb.fatal('Unable to open %s' % (debug_fl_file))
                    except OSError:
                        bb.fatal('Unable to open %s' % (fl_file))
                    if debug_flashlayout:
                        flashlayout_wrapper4dbg_subfolder_path = os.path.join(d.getVar('FLASHLAYOUT_DESTDIR'), bootscheme, "debug")
                        bb.utils.mkdirhier(flashlayout_wrapper4dbg_subfolder_path)
                        # Wrapper4dbg output filename
                        debug_flashlayout_file = os.path.join(flashlayout_wrapper4dbg_subfolder_path,d.expand("debug-${FLASHLAYOUT_BASENAME}%s%s.${FLASHLAYOUT_SUFFIX}" % (config_append, labeltype_append)))
                        bb.note(">>> Update tf-a in %s" %  (debug_flashlayout_file))
                        os.rename(tmp_flashlayout_file, debug_flashlayout_file)
                    else:
                        os.remove(tmp_flashlayout_file)
}

函数非常长,大概有170行,重点总结一下实际做的事:

  1. 如果使能了静态flashlayout生成则做一些检查,然后将自定义的flashlayout tsv文件拷贝到工作路径下
  2. 定义了一系列函数初始化变量、获取device的名字、计算offset等函数,然后根据BOOTSCHEME_LABELS 划分子目录,创建文件、写入每一行的具体内容,最终做一些校验。

do_create_flashlayout_config 任务里面非常繁杂,但是大概浏览一遍能差不多明白创建流程,这个class留了几个变量是被inc文件设置的,比如:
FLASHLAYOUT_DEPEND_TASKS
FLASHLAYOUT_BOOTSCHEME_LABELS
FLASHLAYOUT_CONFIG_LABELS

这些其实都在 machine/conf/inc st-machine-flashlayout-stm32mp.inc里面做了详细的配置。

总结:通过对st-partitions-image 还有flashlayout-stm32mp两个class的分析,STM32MP1创建分区和刷机文件好像变得越来越清晰,是时候该动起来创建自己的分区了,详见下一篇文章!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值