IMX6 uboot SPL 模式启动

it2024-05-06  62

IMX6 uboot SPL 模式启动

uboot 版本 2016.03;linux版本4.1.15 uboot设置: 1、设置CONFIG_SPL=y, 打开SPL功能需要: 在 make menuconfig 中 Boot images 菜单下打开 Enable SPL 2、设置CONFIG_SPL_OS_BOOT宏,从SPL跳转到kernel需要打开此宏: 在 make menuconfig中没找到,直接在 include\configs\mx6_common.h 文件中增加 #define CONFIG_SPL_OS_BOOT 3、设置相关参数: 由于eMMC硬件存在boot0,boot1,UDA三个分区,目前spl存储在boot0分区,而根据kernel和dtb存储位置分为下面三种模式:

模式kernel存储位置MMCSD_MODE_RAWemmc的uda区MMCSD_MODE_EMMCBOOT存储在emmc的启动区MMCSD_MODE_FSemmc的uda区的自定义分区中

模式设置 arch/arm/imx-commom/spl.c

u32 spl_boot_mode(void) { switch (spl_boot_device()) { /* for MMC return either RAW or FAT mode */ case BOOT_DEVICE_MMC1: case BOOT_DEVICE_MMC2: #if defined(CONFIG_SPL_FAT_SUPPORT) return MMCSD_MODE_FS; #elif defined(CONFIG_SUPPORT_EMMC_BOOT) return MMCSD_MODE_EMMCBOOT; #else return MMCSD_MODE_RAW; #endif break; default: puts("spl: ERROR: unsupported device\n"); hang(); } }

各模式执行的操作如下: common/spl/spl_mmc.c

int spl_mmc_load_image(u32 boot_device) { /* 删除一些无关的代码*/ boot_mode = spl_boot_mode(); err = -EINVAL; switch (boot_mode) { case MMCSD_MODE_EMMCBOOT: /* * We need to check what the partition is configured to. * 1 and 2 match up to boot0 / boot1 and 7 is user data * which is the first physical partition (0). */ part = (mmc->part_config >> 3) & PART_ACCESS_MASK; if (part == 7) part = 0; err = mmc_switch_part(0, part); if (err) { return err; } /* Fall through 注意:没有break */ case MMCSD_MODE_RAW: if (!spl_start_uboot()) { err = mmc_load_image_raw_os(mmc); if (!err) return err; } err = mmc_load_image_raw_partition(mmc, CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION); if (!err) return err; #if defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR) err = mmc_load_image_raw_sector(mmc, CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); if (!err) return err; #endif /* If RAW mode fails, try FS mode. 注意:没有break*/ case MMCSD_MODE_FS: err = spl_mmc_do_fs_boot(mmc); if (!err) return err; break; case MMCSD_MODE_UNDEFINED: } return err; }

3.1 MMCSD_MODE_RAW模式: 需要关闭CONFIG_SUPPORT_EMMC_BOOT 和CONFIG_SPL_FAT_SUPPORT宏,前者在include\configs\mx6_common.h中屏蔽该红定义

/* MMC */ #define CONFIG_MMC #define CONFIG_CMD_MMC #define CONFIG_GENERIC_MMC #define CONFIG_BOUNCE_BUFFER #define CONFIG_FSL_ESDHC #define CONFIG_FSL_USDHC /* #define CONFIG_SUPPORT_EMMC_BOOT 屏蔽 */

后者默认无。

需要设置以下宏:

CONFIG_SYS_SPL_ARGS_ADDR dtb加载ram位置,可以自定义关键是不能覆盖kernel的内存位置,查询 include\configs\mx6_common.h可知imx6D默认的kernel地址为CONFIG_SYS_LOAD_ADDR =CONFIG_LOADADDR = 0x12000000;考虑到kernel长度,参考之前的u-boot设置将 dtb内存地址设置为0x18000000. CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR dtb emmc存储块地址,不能覆盖同区的kernel和可能同区的spl,本例设置为0x1000 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS dtb 块长度, CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR kernel emmc存储块地址,不要和dtb重叠,本例设置为0x2000

建议在inlude/configs/imx6_spl.h文件中增加,如下:

/* MMC support */ #if defined(CONFIG_SPL_MMC_SUPPORT) #define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 138 /* offset 69KB */ #define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS 800 /* 400 KB */ #define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 1 #define CONFIG_SYS_MONITOR_LEN (CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS/2*1024) /* Falcon Mode - MMC support: args@2MB kernel@4MB */ #define CONFIG_SYS_SPL_ARGS_ADDR 0x18000000 //dtb file ram addr #define CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR 0x1000 // 2M #define CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS 640 #define CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR 0x2000 /* 4MB */ #endif

需要重载spl_start_uboot函数,保证其返回0

3.2 MMCSD_MODE_EMMCBOOT模式 kernel和dtb放置在启动分区中,启动分区由程序读取eMMC的寄存器获取,可以为boot0,boot1或者uda,需要: 设置MMCSD_MODE_RAW模式下的各个参数、打开CONFIG_SUPPORT_EMMC_BOOT宏、关闭CONFIG_SPL_FAT_SUPPORT宏。 注意boot0分区大小有限,kernel和dtb可能会放不下。

3.3 MMCSD_MODE_FS 模式 kernel文件存储在uda区的分区中,并且分区是FAT分区。 此模式下需要也需要设置RAW模式下的各项宏,宏定义无所谓因为内部并不使用。 并且还需要设置下面的后三个宏

/* MMC support */ #if defined(CONFIG_SPL_MMC_SUPPORT) #define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 138 /* offset 69KB */ #define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS 800 /* 400 KB */ #define CONFIG_SYS_MONITOR_LEN (CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS/2*1024) #define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 1 /* uda区的分区,p1~n中p后面的数字*/ #define CONFIG_SPL_FS_LOAD_ARGS_NAME "test.dtb" /* dtb的文件名 */ #define CONFIG_SPL_FS_LOAD_KERNEL_NAME "uImage" /* uImage的文件名 */ #endif

同时需要打开CONFIG_SPL_FAT_SUPPORT宏。

kernel设置: 主要是生成uImage文件,查询 include\configs\mx6_common.h 从CONFIG_LOADADDR 获取内核LOADADDR地址,用下面指令应用即可。

export LOADADDR=0x12000000 make uImage

mfgtools工具设置: 根据前述3种模式,按照宏定义将文件写入相应位置即可,由于开发板的emmc boot区只有2MB大小,无法保存kernel文件,所以试验了后面两种模式: 1、raw模式: 1.1、确认Profiles\Linux\OS Firmware\mksdcard.sh.tar中的mksdcard.sh文件,确保sfdisk命令保留了足够的起始空间给kernel和dtb使用。

#!/bin/sh # partition size in MB BOOT_ROM_SIZE=10 # wait for the SD/MMC device node ready while [ ! -e $1 ] do sleep 1 echo “wait for $1 appear” done # call sfdisk to create partition table # destroy the partition table node=$1 dd if=/dev/zero of=${node} bs=1024 count=1 # 保留了${BOOT_ROM_SIZE}M = 10M空间 sfdisk --force ${node} << EOF ${BOOT_ROM_SIZE}M,500M,0c 600M,,83 EOF

1.2 将kernel和dtb写入宏定义的位置

<!-- access boot partition --> <CMD state="Updater" type="push" body="$ echo 0 > /sys/block/mmcblk3boot0/force_ro">access boot partition 1</CMD> <CMD state="Updater" type="push" body="send" file="files/SPL">Sending SPL</CMD> <CMD state="Updater" type="push" body="$ dd if=$FILE of=/dev/mmcblk3boot0 bs=512 seek=2 conv=fsync">write SPL to mmc3 boot0</CMD> <CMD state="Updater" type="push" body="$ echo 1 > /sys/block/mmcblk3boot0/force_ro"> re-enable read-only access </CMD> <CMD state="Updater" type="push" body="$ mmc bootpart enable 1 1 /dev/mmcblk3">enable boot partion 1 to boot</CMD> <CMD state="Updater" type="push" body="send" file="files/uImage">Sending kernel uImage</CMD> <CMD state="Updater" type="push" body="$ dd if=$FILE of=/dev/mmcblk3 bs=1M seek=4 conv=fsync">write uImage to mmc 0x200 sector</CMD> <CMD state="Updater" type="push" body="send" file="files/c90-nvp6324-imx6q-qiyang.dtb">Sending Device Tree file</CMD> <CMD state="Updater" type="push" body="$ dd if=$FILE of=/dev/mmcblk3 bs=1M seek=2 conv=fsync">write dtb to mmc 0x100 sector</CMD>

2 FS模式 将kernel和dtb按照定义的文件名烧写到宏定义的分区

<CMD state="Updater" type="push" body="send" file="mksdcard.sh.tar">Sending partition shell</CMD> <CMD state="Updater" type="push" body="$ tar xf $FILE "> Partitioning...</CMD> <CMD state="Updater" type="push" body="$ sh mksdcard.sh /dev/mmcblk3"> Partitioning...</CMD> <CMD state="Updater" type="push" body="$ while [ ! -e /dev/mmcblk%mmc%p1 ]; do sleep 1; echo \"waiting...\"; done ">Waiting for the partition ready</CMD> <CMD state="Updater" type="push" body="$ mkfs.vfat /dev/mmcblk%mmc%p1">Formatting rootfs partition</CMD> <CMD state="Updater" type="push" body="$ mkdir -p /mnt/mmcblk%mmc%p1"/> <CMD state="Updater" type="push" body="$ mount -t vfat /dev/mmcblk%mmc%p1 /mnt/mmcblk%mmc%p1"/> <!-- burn zImage --> <CMD state="Updater" type="push" body="send" file="files/uImage">Sending kernel uImage</CMD> <CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk%mmc%p1/uImage">write kernel image to sd card</CMD> <!-- burn dtb --> <CMD state="Updater" type="push" body="send" file="files/c90-nvp6324-imx6q-qiyang.dtb">Sending Device Tree file</CMD> <CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk%mmc%p1/test.dtb">write device tree to sd card</CMD> <CMD state="Updater" type="push" body="$ umount /mnt/mmcblk%mmc%p1">Unmounting vfat partition</CMD>

参考文件: iMX6Q Sabresd Board SPL Mode

最新回复(0)