• 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_BOOTSCHEME_LABEL].
      其中FLASHLAYOUT_BASENAME 默认是 ‘FlashLayout’,FLASHLAYOUT_SUFFIX默认是’tsv’,改写下上面的格式:
      FlashLayout[][-FLASHLAYOUT_BOOTSCHEME_LABEL].tsv
      如上面展示的FlashLayout_sdcard_stm32mp157a-fsmp1a-trusted.tsv可以看到:
      FLASHLAYOUT_CONFIG_LABEL:sdcard
      FLASHLAYOUT_TYPE_LABEL:stm32mp157a
      FLASHLAYOUT_BOOTSCHEME_LABEL:trusted

    • tsv文件所需格式变量:
      (Opt)
      (Id)
      (Name)
      (Type)
      (IP)
      (Offset)
      (Binary)
      : 上面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_BOOTSCHEME_LABEL].
    #
    #   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
    #   
    #           
    #                   
    #                           
    #                                   
    #                                           
    #                                                   
    #
    # 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_
    #       var where  is the current FLASHLAYOUT_PARTITION_DEVICE
    #
    # Note that override is manage for 'FLASHLAYOUT_PARTITION_LABELS' list with:
    #   -  from FLASHLAYOUT_BOOTSCHEME_LABELS' list
    #   -  from 'FLASHLAYOUT_CONFIG_LABELS' list
    # Priority assignment is:
    #   It means the 'FLASHLAYOUT_PARTITION_LABELS' value can be overriden by setting:
    #   FLASHLAYOUT_PARTITION_LABELS__
    #   FLASHLAYOUT_PARTITION_LABELS_
    #   FLASHLAYOUT_PARTITION_LABELS_
    #   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:
    #   -  from 'FLASHLAYOUT_CONFIG_LABELS' list
    #   -  from 'FLASHLAYOUT_BOOTSCHEME_LABELS' list
    #   -  from 'FLASHLAYOUT_PARTITION_LABELS' list
    # Priority assignment is:
    #   FLASHLAYOUT_PARTITION_xxx___
    #   FLASHLAYOUT_PARTITION_xxx__
    #   FLASHLAYOUT_PARTITION_xxx__
    #   FLASHLAYOUT_PARTITION_xxx_
    #   FLASHLAYOUT_PARTITION_xxx__
    #   FLASHLAYOUT_PARTITION_xxx_
    #   FLASHLAYOUT_PARTITION_xxx_
    #   FLASHLAYOUT_PARTITION_xxx
    # -----------------------------------------------------------------------------
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82

    变量定义

    上面介绍部分大概对生成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 ??= ""
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    可以看到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')
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    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
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    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()])}"
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    指定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)
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174

    函数非常长,大概有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创建分区和刷机文件好像变得越来越清晰,是时候该动起来创建自己的分区了,详见下一篇文章!

  • 相关阅读:
    java90-Character方法大小写转换
    部署LVS-DR 集群及实验
    NoSQL - MongoDB 常见的shell操作 - 安装
    【图像处理】:Otsu算法最大类间方差法(大津算法:附源码)
    Java中string和stringbuffer和stringbuilder的区别是什么【杭州多测师】【杭州多测师_王sir】...
    浅谈潍坊风尚米兰能耗监测系统的应用
    参加CSDN第六期编程竞赛感想
    栅形状的影响及可靠性的优化
    Dubbo分布式日志链路追踪
    Windows 10 python pcl 安装与测试
  • 原文地址:https://blog.csdn.net/qq_24622489/article/details/128160517