• yocto machine class解析之st-partitions-image


    yocto machine class解析之st-partitions-image

    stm32mp157 yocto的meta-st-stm32mp layer中提供了几个class,后续几篇文章重点分析这些class文件:
    在这里插入图片描述第一篇就从st-partitions-image.bbclass 开始,st所有创建image的bb文件都会引用st-partitions-image,包括bootfs userfs vendorfs等image的bb 文件。这个class会在image编译以后生成分区镜像。

    
    ENABLE_PARTITIONS_IMAGE ?= "1"
    
    PARTITIONS_CONFIG ??= ""
    PARTITIONS_IMAGE ??= ""
    PARTITIONS_MOUNTPOINT ??= ""
    
    python __anonymous () {
        # We check first if it is requested to generate any partition images
        if d.getVar('ENABLE_PARTITIONS_IMAGE') != "1":
            bb.note('ENABLE_PARTITIONS_IMAGE not enabled')
            return
    
        # -----------------------------------------------------------------------------
        # Update the partition configuration set by user
        # -----------------------------------------------------------------------------
        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()
        # Init image_summary_list
        image_summary_list = ''
        if len(partitionsconfig) > 0:
            for config in partitionsconfig:
                for f, v in partitionsconfigflags.items():
                    if config == f:
                        items = v.split(',')
                        if items[0]:
                            if len(items) > 5:
                                raise bb.parse.SkipRecipe('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 available, so we're dealing with partition image
                                # PARTITIONS_IMAGE appending
                                bb.debug(1, "Appending '%s' to PARTITIONS_IMAGE." % items[0])
                                d.appendVar('PARTITIONS_IMAGE', ' ' + items[0])
                                # PARTITIONS_MOUNTPOINT appending
                                bb.debug(1, "Appending '%s' to PARTITIONS_MOUNTPOINT." % items[2])
                                d.appendVar('PARTITIONS_MOUNTPOINT', ' ' + items[2])
    
                            # Update IMAGE vars for each partition image
                            if items[1]:
                                bb.debug(1, "Set UBI_VOLNAME to %s for %s partition image." % (items[1], items[0]))
                                d.setVar('UBI_VOLNAME_pn-%s' % d.expand(items[0]), items[1])
                                if d.expand(items[1])[-2:] != 'fs':
                                    bb.debug(1, "Set IMAGE_NAME_SUFFIX to '.%sfs' for %s partition image." % (items[1], items[0]))
                                    d.setVar('IMAGE_NAME_SUFFIX_pn-%s' % d.expand(items[0]), '.' + items[1] + 'fs')
                                else:
                                    bb.debug(1, "Set IMAGE_NAME_SUFFIX to '.%s' for %s partition image." % (items[1], items[0]))
                                    d.setVar('IMAGE_NAME_SUFFIX_pn-%s' % d.expand(items[0]), '.' + items[1])
                            else:
                                bb.fatal('[PARTITIONS_CONFIG] Missing label setting for %s image' % items[0])
                            if items[2]:
                                bb.debug(1, "Set IMAGE_PARTITION_MOUNTPOINT to %s for %s partition image." % (items[2], items[0]))
                                d.setVar('IMAGE_PARTITION_MOUNTPOINT_pn-%s' % d.expand(items[0]), items[2])
                            if items[3]:
                                bb.debug(1, "Set IMAGE_ROOTFS_SIZE to %s for %s partition image." % (items[3], items[0]))
                                d.setVar('IMAGE_ROOTFS_SIZE_pn-%s' % d.expand(items[0]), items[3])
                            else:
                                bb.fatal('[PARTITIONS_CONFIG] Missing size setting for %s image' % items[0])
    
                            # Manage IMAGE_SUMMARY_LIST configuration according to PARTITION_CONFIG set
                            if d.getVar('ENABLE_IMAGE_LICENSE_SUMMARY') == "1":
                                if not items[2]:
                                    # Set '/' as default mountpoint for rootfs in IMAGE_SUMMARY_LIST
                                    items[2] = '/'
                                image_summary_list += items[0] + ':' + items[2] + ';'
    
                            # Manage multiubi volume list STM32MP_UBI_VOLUME
                            if bb.utils.contains('IMAGE_FSTYPES', 'stmultiubi', True, False, d) and d.getVar('ENABLE_MULTIVOLUME_UBI') == "1":
                                bb.debug(1, "Appending '%s' image with %s size to STM32MP_UBI_VOLUME." % (items[0], items[3]))
                                d.appendVar('STM32MP_UBI_VOLUME', ' ' + items[0] + ':' + items[3])
    
                        else:
                            bb.fatal('[PARTITIONS_CONFIG] Missing image setting')
    
                        break
    
        # Reset IMAGE_LIST_SUMMARY with computed partition configuration
        if d.getVar('ENABLE_IMAGE_LICENSE_SUMMARY') == "1":
            bb.debug(1, "Set IMAGE_SUMMARY_LIST with configuration: %s." % image_summary_list)
            d.setVar('IMAGE_SUMMARY_LIST', image_summary_list)
    
        # Init partition list from PARTITIONS_IMAGE
        image_partitions = (d.getVar('PARTITIONS_IMAGE') or "").split()
        # -----------------------------------------------------------------------------
        # Make sure to append the partition build to current image target
        # -----------------------------------------------------------------------------
        if len(image_partitions) > 0:
            # 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 ""
                    # We need to append partition images generation only to image
                    # that are not one of the defined partitions and not the InitRAMFS image.
                    # Without this check we would create circular dependency
                    if current_image_name not in image_partitions and current_image_name != initramfs and current_image_name != initrd:
                        for partition in image_partitions:
                            bb.debug(1, "Appending %s image build to 'do_image_complete' depends tasks." % partition)
                            d.appendVarFlag('do_image_complete', 'depends', ' %s:do_image_complete' % partition)
                        bb.debug(1, "Appending 'image_rootfs_image_clean_task' to IMAGE_PREPROCESS_COMMAND.")
                        d.appendVar('IMAGE_PREPROCESS_COMMAND', 'image_rootfs_image_clean_task;')
                        # Manage multiubi volume build enable for current image
                        if bb.utils.contains('IMAGE_FSTYPES', 'stmultiubi', True, False, d) and d.getVar('ENABLE_MULTIVOLUME_UBI') == "1":
                            bb.debug(1, "Appending 'st_multivolume_ubifs' to IMAGE_POSTPROCESS_COMMAND.")
                            d.appendVar('IMAGE_POSTPROCESS_COMMAND', 'st_multivolume_ubifs;')
    }
    
    image_rootfs_image_clean_task() {
        bbnote "PARTITIONS_IMAGE"
        bbnote ">>> ${PARTITIONS_IMAGE}"
        bbnote "PARTITIONS_MOUNTPOINT"
        bbnote ">>> ${PARTITIONS_MOUNTPOINT}"
        unset i j
        for img in ${PARTITIONS_IMAGE}; do
            i=$(expr $i + 1);
            for part in ${PARTITIONS_MOUNTPOINT}; do
                j=$(expr $j + 1);
                if [ $j -eq $i ]; then
                    bbnote "Expecting to clean folder:"
                    bbnote ">>> ${IMAGE_ROOTFS}/$part"
                    if [ -d ${IMAGE_ROOTFS}/$part ]; then
                        rm -rf ${IMAGE_ROOTFS}/$part/*
                        bbnote ">>> DONE"
                    else
                        bbnote ">>> NOT DONE : $part folder doesn't exist in image rootfs"
                    fi
                fi
            done
            unset j
        done
        unset i
    }
    
    
    • 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

    st-partitions-image.bbclass 整个文件看起来比较长,其实里面大部分都是调试日志。 总共有几部分组成:

    1. 重要的三个变量
      ENABLE_PARTITIONS_IMAGE:用来控制是否使能生成分区镜像,在镜像bb文件中可以覆盖此变量控制该class的功能
      PARTITIONS_CONFIG:设置的分区配置
      PARTITIONS_IMAGE:分区镜像的名字
      PARTITIONS_MOUNTPOINT:分区镜像的挂载点

    2. 一个匿名函数
      以PARTITIONS_CONFIG 为输入,PARTITIONS_IMAGE 和PARTITIONS_MOUNTPOINT 为输出
      通过bitbake -e fs-mp1a-qt可以先看一下最终的变量值:

    PARTITIONS_CONFIG=" bootfs vendorfs rootfs userfs"
    //PARTITIONS_CONFIG[xxxfs] 字段含义
    // "${STM32MP_XXFS_IMAGE},${STM32MP_XXFS_LABEL},${STM32MP_XXFS_MOUNTPOINT},${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"
    
    PARTITIONS_IMAGE=" st-image-bootfs st-image-vendorfs st-image-userfs"
    PARTITIONS_MOUNTPOINT=" /boot /vendor /usr/local"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    下面详细分析python __anonymous是怎么处理的:
    输入变量PARTITIONS_CONFIG:
    PARTITIONS_CONFIG=" bootfs vendorfs rootfs userfs"
    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”

    partitionsconfigflags:
    bootfs “st-image-bootfs,boot,/boot,65536,System”
    vendorfs “st-image-vendorfs,vendorfs,/vendor,16384,FileSystem”
    rootfs “fs-mp1a-qt-openstlinux-eglfs,rootfs,1253376,FileSystem”
    userfs “st-image-userfs,userfs,/usr/local,131072,FileSystem”

    partitionsconfig:
    bootfs vendorfs rootfs userfs

            for config in partitionsconfig:
                for f, v in partitionsconfigflags.items():
                    if config == f:
                        items = v.split(',')
    
    • 1
    • 2
    • 3
    • 4

    上面这段判断可以知道(以第一个bootfs为例) items= {st-image-bootfs boot /boot 65536 System }

                            if len(items) > 2 and items[2]:
                                # Mount point available, so we're dealing with partition image
                                # PARTITIONS_IMAGE appending
                                bb.debug(1, "Appending '%s' to PARTITIONS_IMAGE." % items[0])
                                d.appendVar('PARTITIONS_IMAGE', ' ' + items[0])
                                # PARTITIONS_MOUNTPOINT appending
                                bb.debug(1, "Appending '%s' to PARTITIONS_MOUNTPOINT." % items[2])
                                d.appendVar('PARTITIONS_MOUNTPOINT', ' ' + items[2])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    如果items大于2且items[2]存在,则
    PARTITIONS_IMAGE += items[0] //items[0] = st-image-bootfs
    PARTITIONS_MOUNTPOINT += items[2] //items[2] = /boot

    如此循环下来:
    PARTITIONS_IMAGE =" st-image-bootfs st-image-vendorfs fs-mp1a-qt-openstlinux-eglfs st-image-userfs"
    PARTITIONS_MOUNTPOINT=" /boot /vendor rootfs /usr/local"

    这里PARTITIONS_MOUNTPOINT 和我们通过实际bitbake -e看到的环境变量对不上,我们接着往下分析

                            # Update IMAGE vars for each partition image
                            if items[1]:
                                bb.debug(1, "Set UBI_VOLNAME to %s for %s partition image." % (items[1], items[0]))
                                d.setVar('UBI_VOLNAME_pn-%s' % d.expand(items[0]), items[1])
                                if d.expand(items[1])[-2:] != 'fs':
                                    bb.debug(1, "Set IMAGE_NAME_SUFFIX to '.%sfs' for %s partition image." % (items[1], items[0]))
                                    d.setVar('IMAGE_NAME_SUFFIX_pn-%s' % d.expand(items[0]), '.' + items[1] + 'fs')
                                else:
                                    bb.debug(1, "Set IMAGE_NAME_SUFFIX to '.%s' for %s partition image." % (items[1], items[0]))
                                    d.setVar('IMAGE_NAME_SUFFIX_pn-%s' % d.expand(items[0]), '.' + items[1])
                            else:
                                bb.fatal('[PARTITIONS_CONFIG] Missing label setting for %s image' % items[0])
                            if items[2]:
                                bb.debug(1, "Set IMAGE_PARTITION_MOUNTPOINT to %s for %s partition image." % (items[2], items[0]))
                                d.setVar('IMAGE_PARTITION_MOUNTPOINT_pn-%s' % d.expand(items[0]), items[2])
                            if items[3]:
                                bb.debug(1, "Set IMAGE_ROOTFS_SIZE to %s for %s partition image." % (items[3], items[0]))
                                d.setVar('IMAGE_ROOTFS_SIZE_pn-%s' % d.expand(items[0]), items[3])
                            else:
                                bb.fatal('[PARTITIONS_CONFIG] Missing size setting for %s image' % items[0])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 如果items[1]存在(以第一个bootfs为例)
      UBI_VOLNAME_pn-st-image-bootfs=/boot
    • 如果items[1]的最后2位不是fs结尾则手动添加fs结尾以后设置IMAGE_NAME_SUFFIX_pn变量
      IMAGE_NAME_SUFFIX_pn-st-image-bootfs=.boot
    • 如果items[2]存在
      IMAGE_PARTITION_MOUNTPOINT_pn-st-image-bootfs=/boot
    • 如果items[3]存在
      IMAGE_ROOTFS_SIZE_pn-st-image-bootfs=65536
                            # Manage IMAGE_SUMMARY_LIST configuration according to PARTITION_CONFIG set
                            if d.getVar('ENABLE_IMAGE_LICENSE_SUMMARY') == "1":
                                if not items[2]:
                                    # Set '/' as default mountpoint for rootfs in IMAGE_SUMMARY_LIST
                                    items[2] = '/'
                                image_summary_list += items[0] + ':' + items[2] + ';'
    
                            # Manage multiubi volume list STM32MP_UBI_VOLUME
                            if bb.utils.contains('IMAGE_FSTYPES', 'stmultiubi', True, False, d) and d.getVar('ENABLE_MULTIVOLUME_UBI') == "1":
                                bb.debug(1, "Appending '%s' image with %s size to STM32MP_UBI_VOLUME." % (items[0], items[3]))
                                d.appendVar('STM32MP_UBI_VOLUME', ' ' + items[0] + ':' + items[3])
                               
        # Reset IMAGE_LIST_SUMMARY with computed partition configuration
        if d.getVar('ENABLE_IMAGE_LICENSE_SUMMARY') == "1":
            bb.debug(1, "Set IMAGE_SUMMARY_LIST with configuration: %s." % image_summary_list)
            d.setVar('IMAGE_SUMMARY_LIST', image_summary_list)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 如果环境变量ENABLE_IMAGE_LICENSE_SUMMARY被设置
      image_summary_list += st-image-bootfs:/boot;
      循环下来image_summary_list=“st-image-bootfs:/boot;st-image-vendorfs:/vendor;fs-mp1a-qt-openstlinux-eglfs:rootfs;st-image-userfs:/usr/local;”
      IMAGE_SUMMARY_LIST = image_summary_list

    • 如果IMAGE_FSTYPES 中包含stmultiubi类型且ENABLE_MULTIVOLUME_UBI变量被设置
      STM32MP_UBI_VOLUME +=" st-image-bootfs:65536"
      循环下来STM32MP_UBI_VOLUME=" st-image-bootfs:65536 st-image-vendorfs:16384 fs-mp1a-qt-openstlinux-eglfs:1253376 st-image-userfs:131072"

    这里循环结束,总结一下设置了哪些变量:
    PARTITIONS_IMAGE =" st-image-bootfs st-image-vendorfs fs-mp1a-qt-openstlinux-eglfs st-image-userfs"
    PARTITIONS_MOUNTPOINT=" /boot /vendor rootfs /usr/local"

    UBI_VOLNAME_pn-st-image-bootfs=/boot
    IMAGE_NAME_SUFFIX_pn-st-image-bootfs=.boot
    IMAGE_PARTITION_MOUNTPOINT_pn-st-image-bootfs=/boot
    IMAGE_ROOTFS_SIZE_pn-st-image-bootfs=65536
    
    • 1
    • 2
    • 3
    • 4

    IMAGE_SUMMARY_LIST=“st-image-bootfs:/boot;st-image-vendorfs:/vendor;fs-mp1a-qt-openstlinux-eglfs:rootfs;st-image-userfs:/usr/local;”
    STM32MP_UBI_VOLUME=" st-image-bootfs:65536 st-image-vendorfs:16384 fs-mp1a-qt-openstlinux-eglfs:1253376 st-image-userfs:131072"

    继续分析

        image_partitions = (d.getVar('PARTITIONS_IMAGE') or "").split()
        if len(image_partitions) > 0:
            # 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 ""
                    # We need to append partition images generation only to image
                    # that are not one of the defined partitions and not the InitRAMFS image.
                    # Without this check we would create circular dependency
                    if current_image_name not in image_partitions and current_image_name != initramfs and current_image_name != initrd:
                        for partition in image_partitions:
                            bb.debug(1, "Appending %s image build to 'do_image_complete' depends tasks." % partition)
                            d.appendVarFlag('do_image_complete', 'depends', ' %s:do_image_complete' % partition)
                        bb.debug(1, "Appending 'image_rootfs_image_clean_task' to IMAGE_PREPROCESS_COMMAND.")
                        d.appendVar('IMAGE_PREPROCESS_COMMAND', 'image_rootfs_image_clean_task;')
                        # Manage multiubi volume build enable for current image
                        if bb.utils.contains('IMAGE_FSTYPES', 'stmultiubi', True, False, d) and d.getVar('ENABLE_MULTIVOLUME_UBI') == "1":
                            bb.debug(1, "Appending 'st_multivolume_ubifs' to IMAGE_POSTPROCESS_COMMAND.")
                            d.appendVar('IMAGE_POSTPROCESS_COMMAND', 'st_multivolume_ubifs;')
    
    • 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

    image_partitions = [“st-image-bootfs”, “st-image-vendorfs”, “fs-mp1a-qt-openstlinux-eglfs”, “st-image-userfs” ]
    找到所有非initramfs 、initrd和 image_partitions中包含的image 的 do_image_complete的task,设置他们的依赖:
    do_image_complete[depends] = st-image-bootfs:do_image_complete
    do_image_complete[depends] = st-image-vendorfs:do_image_complete
    do_image_complete[depends] = fs-mp1a-qt-openstlinux-eglfs:do_image_complete
    do_image_complete[depends] = st-image-userfs:do_image_complete
    IMAGE_POSTPROCESS_COMMAND+=st_multivolume_ubifs
    到这里,可以看到所有的iamge 菜谱生成进行必须先等image_partitions 中的镜像生成以后才可以生成。

    这部分分析结束,还有个疑问:bitbake中的变量里面没有rootfs相关的设置,但是分析下来是有的,这里等后续image生成流程都分析完了在回头看看是不是那里过滤掉了。
    PARTITIONS_IMAGE=" st-image-bootfs st-image-vendorfs st-image-userfs"
    PARTITIONS_MOUNTPOINT=" /boot /vendor /usr/local"

    PARTITIONS_IMAGE =" st-image-bootfs st-image-vendorfs fs-mp1a-qt-openstlinux-eglfs st-image-userfs"
    PARTITIONS_MOUNTPOINT=" /boot /vendor rootfs /usr/local"

    1. 一个 task
      image_rootfs_image_clean_task

    最后还生名了一个task,里面比较简单:

        for img in ${PARTITIONS_IMAGE}; do
            i=$(expr $i + 1);
            for part in ${PARTITIONS_MOUNTPOINT}; do
                j=$(expr $j + 1);
                if [ $j -eq $i ]; then
                    bbnote "Expecting to clean folder:"
                    bbnote ">>> ${IMAGE_ROOTFS}/$part"
                    if [ -d ${IMAGE_ROOTFS}/$part ]; then
                        rm -rf ${IMAGE_ROOTFS}/$part/*
                        bbnote ">>> DONE"
                    else
                        bbnote ">>> NOT DONE : $part folder doesn't exist in image rootfs"
                    fi
                fi
            done
            unset j
        done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    最终效果就是把tmp-glibc/work/fsmp1a-ostl-linux-gnueabi/fs-mp1a-qt/1.0-r0/rootfs/boot/*删除(以bootfs为例)

    DONE

  • 相关阅读:
    Mysql的主从复制和读写分离
    第三章 搜索与图论(三)
    获取嵌套结构体字段总数
    python安装.whl文件
    aaaaaa
    小目标检测高效解决方案汇总,附19篇原论文&开源代码
    第三周 青海之行——练练构图,培养你的摄影眼
    【每日练习】LeetCode24
    机器学习基础(三)监督学习的进阶探索
    OSCP-Vulnhub靶机记录-Hack Me Please Walkthrough
  • 原文地址:https://blog.csdn.net/qq_24622489/article/details/128059858