Yocto:NXP s32g emmc镜像生成过程分析(分区大小,起始地址如何确定)

Yocto:NXP s32g emmc镜像生成过程分析_xiliu542的博客-CSDN博客

一、分区起始地址和大小确定

上一篇通过分析编译Log介绍了emmc镜像的生成过程。但是分区大小和分区的起始地址是如何确定的呢?下面就简单分析一下。

 从boot.img分区来入手,从上面log可以看到boot分区是从4096KB地址开始的,结束地址是69632KB.

往上翻可以看到一些信息UBOOT_BOOTSAPCE_OFFSET和BOOT_SPACE_ALIGEND这几个变量。

 搜索一下UBOOT_BOOTSAPCE_OFFSET,发现是定义在sources/meta-alb/conf/machine/include/s32-gen1-board.inc中为0,也就是uboot是烧录到emmc的0地址。

 在搜索 一下BOOT_SPACE_ALIGEND

 其在sources/meta-alb/classes/image_types_fsl_sdcard.bbclass中赋值, 进去看这个文件,其中IMAGE_CMD_sdcard是关键函数,里面计算了boot.img,rootfs分区的起始地址和大小

IMAGE_CMD_sdcard () {

    if [ -n "${UBOOT_BOOTSPACE_OFFSET}" ]; then //${UBOOT_BOOTSPACE_OFFSET}变量不为空前面定义了变量值为"0"
        UBOOT_BOOTSPACE_OFFSET=$(printf "%d" ${UBOOT_BOOTSPACE_OFFSET}) //UBOOT_BOOTSPACE_OFFSET赋值为整数0
    else
        UBOOT_BOOTSPACE_OFFSET=$(expr ${UBOOT_BOOTSPACE_SEEK} \* 512)
    fi

    # Align boot partition and calculate total SD card image size
    //BOOT_SPACE应该指的就是存放boot.img分区大小,目前定义的时65536KB, BASE_IMAGE_ROOTFS_ALIGNMENT是4096KB对齐
    BOOT_SPACE_ALIGNED=$(expr ${BOOT_SPACE} + ${BASE_IMAGE_ROOTFS_ALIGNMENT} - 1)
    BOOT_SPACE_ALIGNED=$(expr ${BOOT_SPACE_ALIGNED} - ${BOOT_SPACE_ALIGNED} % ${BASE_IMAGE_ROOTFS_ALIGNMENT})
    //上面计算完后BOOT_SPACE_ALIGED=65536
    # If the size has not been preset, we default to flash image
    # sizes if available turned into [KiB] or to a hardcoded mini
    # default of 4MB.
    if [ -z "${IMAGE_ROOTFS_ALIGNMENT}" ]; then
        if [ -n "${FLASHIMAGE_SIZE}" ]; then
            IMAGE_ROOTFS_ALIGNMENT=$(expr ${FLASHIMAGE_SIZE} \* 1024)
        else
            IMAGE_ROOTFS_ALIGNMENT=${BASE_IMAGE_ROOTFS_ALIGNMENT}
        fi
    fi
    //这里SDCARD_SIZE=4096+65536=69632

    # Compute final size of SDCard image and start offset of each rootfs partition
    SDCARD_SIZE=$(expr ${IMAGE_ROOTFS_ALIGNMENT} + ${BOOT_SPACE_ALIGNED})
    if [ -n "${SDCARD_ROOTFS_REAL}" ]; then
        SDCARD_ROOTFS_REAL_START=${SDCARD_SIZE} //这里计算rootfs实际分区起始地址SDCARD_ROOTFS_REAL_START=69632
        //下面重新计算SDCARD_SIZE=69632+524288+4096=598016, 这里有个关键点 ROOTFS_SIZE=524288是哪里来的?       
        SDCARD_SIZE=$(expr ${SDCARD_SIZE} + ${ROOTFS_SIZE} + ${BASE_IMAGE_ROOTFS_ALIGNMENT})
        bbdebug 1 "${ROOTFS_SIZE}  ${BASE_IMAGE_ROOTFS_ALIGNMENT} ${SDCARD_ROOTFS_REAL_START}"
    else
        SDCARD_ROOTFS_REAL_START="0"
    fi
    if [ -n "${SDCARD_ROOTFS_EXTRA1_FILE}" ]; then
        SDCARD_ROOTFS_EXTRA1_START=${SDCARD_SIZE}
        SDCARD_SIZE=$(expr ${SDCARD_SIZE} + ${SDCARD_ROOTFS_EXTRA1_SIZE} + ${BASE_IMAGE_ROOTFS_ALIGNMENT})
    else
        SDCARD_ROOTFS_EXTRA1_START="0"
    fi
    if [ -n "${SDCARD_ROOTFS_EXTRA2_FILE}" ]; then
        SDCARD_ROOTFS_EXTRA2_START=${SDCARD_SIZE}
        SDCARD_SIZE=$(expr ${SDCARD_SIZE} + ${SDCARD_ROOTFS_EXTRA2_SIZE} + ${BASE_IMAGE_ROOTFS_ALIGNMENT})
    else
        SDCARD_ROOTFS_EXTRA2_START="0"
    fi

    cd ${IMGDEPLOYDIR}

    # Initialize a sparse file
    dd if=/dev/zero of=${SDCARD} bs=1 count=0 seek=$(expr 1024 \* ${SDCARD_SIZE})

    # Additional elements for the raw image, copying the approach of the flashimage class
    generate_sdcardimage_entry "${SDCARDIMAGE_EXTRA1_FILE}" "SDCARDIMAGE_EXTRA1_OFFSET" "${SDCARDIMAGE_EXTRA1_OFFSET}" "${SDCARD}"
    generate_sdcardimage_entry "${SDCARDIMAGE_EXTRA2_FILE}" "SDCARDIMAGE_EXTRA2_OFFSET" "${SDCARDIMAGE_EXTRA2_OFFSET}" "${SDCARD}"
    generate_sdcardimage_entry "${SDCARDIMAGE_EXTRA3_FILE}" "SDCARDIMAGE_EXTRA3_OFFSET" "${SDCARDIMAGE_EXTRA3_OFFSET}" "${SDCARD}"
    generate_sdcardimage_entry "${SDCARDIMAGE_EXTRA4_FILE}" "SDCARDIMAGE_EXTRA4_OFFSET" "${SDCARDIMAGE_EXTRA4_OFFSET}" "${SDCARD}"
    generate_sdcardimage_entry "${SDCARDIMAGE_EXTRA5_FILE}" "SDCARDIMAGE_EXTRA5_OFFSET" "${SDCARDIMAGE_EXTRA5_OFFSET}" "${SDCARD}"
    generate_sdcardimage_entry "${SDCARDIMAGE_EXTRA6_FILE}" "SDCARDIMAGE_EXTRA6_OFFSET" "${SDCARDIMAGE_EXTRA6_OFFSET}" "${SDCARD}"
    generate_sdcardimage_entry "${SDCARDIMAGE_EXTRA7_FILE}" "SDCARDIMAGE_EXTRA7_OFFSET" "${SDCARDIMAGE_EXTRA7_OFFSET}" "${SDCARD}"
    generate_sdcardimage_entry "${SDCARDIMAGE_EXTRA8_FILE}" "SDCARDIMAGE_EXTRA8_OFFSET" "${SDCARDIMAGE_EXTRA8_OFFSET}" "${SDCARD}"
    generate_sdcardimage_entry "${SDCARDIMAGE_EXTRA9_FILE}" "SDCARDIMAGE_EXTRA9_OFFSET" "${SDCARDIMAGE_EXTRA9_OFFSET}" "${SDCARD}"

    ${SDCARD_GENERATION_COMMAND} ${SDCARD_ROOTFS_REAL_START} ${SDCARD_ROOTFS_EXTRA1_START} ${SDCARD_ROOTFS_EXTRA2_START}
    cd -
}

上面的BOOT_SPACE就是boot.img分区的大小,定义在

 上面主要做了:1. uboot是从0地址开始,大小是4MB,是没有文件系统的。

        2.boot.img分区是从4096KB地址开始,大小是65536KB, 分区格式是fat32

        3.rootfs分区是从69632KB地址开始,大小是524288KB, 分区格式是ext4

上面函数里面其实有个问题就是${ROOTFS_SIZE}是哪里赋值定义的?搜索了下ROOTFS_SIZE没有地方直接定义,但是有个地方引起了我的注意,就是image.bbclass 里面的d.setVar('ROOTFS_SIZE', str(rootfs_size))

进去看一下sources/poky/meta/classes/image.bbclass文件

python set_image_size () {
        rootfs_size = get_rootfs_size(d)
        d.setVar('ROOTFS_SIZE', str(rootfs_size))
        d.setVarFlag('ROOTFS_SIZE', 'export', '1')
}

 通过get_rootfs_size函数获取到rootfs_size,然后设置ROOTFS_SIZE

那get_rootfs_size是如何计算rootfs的大小的呢?

def get_rootfs_size(d):
    import subprocess

    rootfs_alignment = int(d.getVar('IMAGE_ROOTFS_ALIGNMENT')) //rootfs_alignement = 4096
    overhead_factor = float(d.getVar('IMAGE_OVERHEAD_FACTOR')) //定义在sources/meta-alb/recipes-fsl/images/fsl-image-auto.bb:68:# IMAGE_OVERHEAD_FACTOR = "1.3"
    rootfs_req_size = int(d.getVar('IMAGE_ROOTFS_SIZE')) //这里有个默认值9216 sources/poky/meta/recipes-core/images/core-image-minimal.bb:11:IMAGE_ROOTFS_SIZE ?= "9216"
    rootfs_extra_space = eval(d.getVar('IMAGE_ROOTFS_EXTRA_SPACE')) //没有定义所以这里为0
    rootfs_maxsize = d.getVar('IMAGE_ROOTFS_MAXSIZE') //没有定义所以这里为0
    image_fstypes = d.getVar('IMAGE_FSTYPES') or '' 
    initramfs_fstypes = d.getVar('INITRAMFS_FSTYPES') or '' 
    initramfs_maxsize = d.getVar('INITRAMFS_MAXSIZE')

    //下面${IMAGE_ROOTFS}这个变量指的是build_s32g399ardb3/tmp/work/s32g399ardb3-fsl-linux/fsl-image-auto/1.0-r0/rootfs, 也就是编译出来的根文件目录
    //调用系统的du -ks build_s32g399ardb3/tmp/work/s32g399ardb3-fsl-linux/fsl-image-auto/1.0-r0/rootfs 计算大小
    output = subprocess.check_output(['du', '-ks',
                                      d.getVar('IMAGE_ROOTFS')])
    #bb.debug(1, '%s' % (d.getVar('IMAGE_ROOTFS')))
    size_kb = int(output.split()[0]) //获取到rootfs文件夹的大小

    base_size = size_kb * overhead_factor //rootfs大小乘以1.3
    bb.debug(1, '%f = %d * %f' % (base_size, size_kb, overhead_factor))
    base_size2 = max(base_size, rootfs_req_size) + rootfs_extra_space
    bb.debug(1, '%f = max(%f, %d)[%f] + %d' % (base_size2, base_size, rootfs_req_size, max(base_size, rootfs_req_size), rootfs_extra_space))

    base_size = base_size2
    if base_size != int(base_size):
        base_size = int(base_size + 1)
    else:
        base_size = int(base_size)
    bb.debug(1, '%f = int(%f)' % (base_size, base_size2))

    base_size_saved = base_size
    base_size += rootfs_alignment - 1
    base_size -= base_size % rootfs_alignment //重新计算base_size以4096对齐
    bb.debug(1, '%d = aligned(%d)' % (base_size, base_size_saved))

    # Do not check image size of the debugfs image. This is not supposed
    # to be deployed, etc. so it doesn't make sense to limit the size
    # of the debug.
    if (d.getVar('IMAGE_BUILDING_DEBUGFS') or "") == "true":
        bb.debug(1, 'returning debugfs size %d' % (base_size))
        return base_size

    # Check the rootfs size against IMAGE_ROOTFS_MAXSIZE (if set)
    if rootfs_maxsize:
        rootfs_maxsize_int = int(rootfs_maxsize)
        if base_size > rootfs_maxsize_int:
            bb.fatal("The rootfs size %d(K) exceeds IMAGE_ROOTFS_MAXSIZE: %d(K)" % \
                (base_size, rootfs_maxsize_int))

    # Check the initramfs size against INITRAMFS_MAXSIZE (if set)
    if image_fstypes == initramfs_fstypes != ''  and initramfs_maxsize:
        initramfs_maxsize_int = int(initramfs_maxsize)
        if base_size > initramfs_maxsize_int:
            bb.error("The initramfs size %d(K) exceeds INITRAMFS_MAXSIZE: %d(K)" % \
                (base_size, initramfs_maxsize_int))
            bb.error("You can set INITRAMFS_MAXSIZE a larger value. Usually, it should")
            bb.fatal("be less than 1/2 of ram size, or you may fail to boot it.\n")

    bb.debug(1, 'returning %d' % (base_size))
    #bb.error('base_size %d' % (base_size))
    return base_size

也可以从编译log看到计算rootfs_size的过程

NOTE: recipe fsl-image-auto-1.0-r0: task do_image_sdcard: Started
DEBUG: fsl-image-auto-1.0-r0 do_image_sdcard: Executing python function set_image_size
DEBUG: fsl-image-auto-1.0-r0 do_image_sdcard: 520598.000000 = 400460 * 1.300000
DEBUG: fsl-image-auto-1.0-r0 do_image_sdcard: 520598.000000 = max(520598.000000, 9216)[520598.000000] + 0
DEBUG: fsl-image-auto-1.0-r0 do_image_sdcard: 520598.000000 = int(520598.000000)
DEBUG: fsl-image-auto-1.0-r0 do_image_sdcard: 524288 = aligned(520598)
DEBUG: fsl-image-auto-1.0-r0 do_image_sdcard: returning 524288
DEBUG: fsl-image-auto-1.0-r0 do_image_sdcard: Python function set_image_size finished
DEBUG: fsl-image-auto-1.0-r0 do_image_sdcard: Executing shell function do_image_sdcard

所以rootfs分区的大小目前不是固定大小,而是根据编译出来的rootfs大小来去确定的。

二、分区大小修改

1.如果想修改存放boot.img分区大小只需修改sources/meta-alb/conf/machine/include/s32-base.inc中的BOOT_SPACE ?= "65536", 注意单位是KB

2.修改rootfs分区大小,可以修改IMAGE_OVERHEAD_FACTOR。那么将rootfs分区改成固定大小可以通过修改IMAGE_ROOTFS_SIZE。这两个变量都可以通过在sources/meta-alb/recipes-fsl/images/fsl-image-auto.bb定义如下:

 三、增加自定义分区和大小

   这个我的想法就是修改generate_nxp_sdcard函数,增加自己定义的分区,具体没有做。

generate_nxp_sdcard () {
    # Get partitions' start offsets passed as parameters
    SDCARD_ROOTFS_REAL_START="$1"
    SDCARD_ROOTFS_EXTRA1_START="$2"
    SDCARD_ROOTFS_EXTRA2_START="$3"

    # Create partition table
    parted -s ${SDCARD} mklabel msdos
    parted -s ${SDCARD} unit KiB mkpart primary fat32 ${IMAGE_ROOTFS_ALIGNMENT} $(expr ${IMAGE_ROOTFS_ALIGNMENT} \+ ${BOOT_SPACE_ALIGNED})
    create_rootfs_partition ${SDCARD_ROOTFS_REAL_START} ${ROOTFS_SIZE} ${SDCARD_ROOTFS_REAL}
    create_rootfs_partition ${SDCARD_ROOTFS_EXTRA1_START} ${SDCARD_ROOTFS_EXTRA1_SIZE} ${SDCARD_ROOTFS_EXTRA1_FILE}
    create_rootfs_partition ${SDCARD_ROOTFS_EXTRA2_START} ${SDCARD_ROOTFS_EXTRA2_SIZE} ${SDCARD_ROOTFS_EXTRA2_FILE}
    parted ${SDCARD} print

    # Fill optional Layerscape RCW into the boot block
    if [ -n "${SDCARD_RCW_NAME}" ]; then
            dd if=${DEPLOY_DIR_IMAGE}/${SDCARD_RCW_NAME} of=${SDCARD} conv=notrunc seek=8 bs=512
    fi

    _burn_bootloader

    _generate_boot_image 1

    # Burn Partitions
    dd if=${WORKDIR}/boot.img of=${SDCARD} conv=notrunc,fsync seek=1 bs=$(expr ${IMAGE_ROOTFS_ALIGNMENT} \* 1024)
    write_rootfs_partition ${SDCARD_ROOTFS_REAL_START} ${ROOTFS_SIZE} ${SDCARD_ROOTFS_REAL}
    write_rootfs_partition ${SDCARD_ROOTFS_EXTRA1_START} ${SDCARD_ROOTFS_EXTRA1_SIZE} ${SDCARD_ROOTFS_EXTRA1_FILE}
    write_rootfs_partition ${SDCARD_ROOTFS_EXTRA2_START} ${SDCARD_ROOTFS_EXTRA2_SIZE} ${SDCARD_ROOTFS_EXTRA2_FILE}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值