上手飞凌OKMX6UL-C开发板,256M NAND Flash,256M DDR3,支持从SD卡启动烧写程序。原来没接触过,通过这两天阅读 IMX6ULRM,有了初步的认识,特进行记录。
1.imx6ul启动方式的选择
imx6ul的启动方式通过内部寄存器Boot Mode[1:0]和电子熔丝位的值或是IO引脚的电平量的组合来决定启动方式的选择。
寄存器Boot Mode[1:0]的值以复位时读入的Boot1 和 Boot0引脚的电平量为依据。
开发板OKMX6UL-C采用内部启动(internal BOOT)的方式,配合相应GPIO引脚选择启动方式。GPIO引脚对应的Boot_CFG配置表:
从上面的配置可以得出:BOOT_MODE[1:0]= 10 b, BOOT_CFG[7:4]= 010x b 选择的是从SD卡启动。
2.SD卡启动流程
SD卡启动还可以设置Fast Boot,High Speed 模式,具体参照手册 IMX6ULRM 的8.5.3.1 Expansion Device eFUSE Configuration,这里采用默认的模式。
SD/eSD普通启动模式初始化开始后,SD/eSD的速率设置为 347.22kHz。在identification阶段,ROOM启动代码会检测电压值,以及SD卡的容量。
在sd卡初始化过程中,ROOT启动代码会尝试给SD卡设置boot 分区。如果失败了,启动代码会将此卡识别为普通的sd卡;如果成功了,会将此卡识别为eSD卡。
等初始化完成后,启动代码会切换到高速(普通模式25M,高速模式50M)。
在启动过程,程序镜像必须包含以下几个部分:
2.1. Image vector table(IVT) - ROOM启动代码用以检查程序镜像其他部分(Boot Data 、DCD等)存放地址的指针表,分配了固定的地址。
2.2. Boot data - 存有程序镜像地址、镜像大小、和插入标志的表
2.3. DCD - IC configuration data
2.4. User code and data
Image vector table(IVT) 包含程序镜像的入口,DCD的指针,和一些其他启动用到指针。IVT存放在固定的位置,不用的启动设备位置不一样,如下表:
可见,sd卡IVT存放在偏移量 1K bytes的位置,启动代码会首先找到这个地址查看IVT,然后读取4K 镜像代码到iram,开始执行。
3.sd卡的制作
从上可知,用于烧写的程序的sd卡需要特殊制作,将uboot镜像放在偏移地址1K的位置,这样 imx6ul 的irom启动代码才能读到uboot镜像,进而执行uboot烧写程序的流程。
sd卡制作脚本部分片段:
cat << EOM
Partitioning Boot
EOM
mkfs.vfat -F 32 -n "boot" ${DRIVE}1
fi
export START_DIR=$PWD
export PATH_TO_SDBOOT=boot
export PATH_TO_TMP_DIR=$START_DIR/tmp
echo " "
echo "Mount the partitions "
rm -rf $PATH_TO_SDBOOT
mkdir $PATH_TO_SDBOOT
sudo mount -t vfat ${DRIVE}1 boot/
echo " "
echo "Emptying partitions "
echo " "
sudo rm -rf $PATH_TO_SDBOOT/*
cat << EOM
Copying files now... will take minutes
Copying boot partition
EOM
echo "untar update.tar.bz2 to boot partition"
sudo tar xvf update.tar.bz2 -C ${PATH_TO_SDBOOT}
echo "Buring th u-boot.imx to sdcard"
dd if=/dev/zero of=${DRIVE} bs=1k seek=384 conv=fsync count=129
dd if=boot/bin/u-boot.imx of=${DRIVE} bs=1k seek=1 conv=fsync
dd if=boot/bin/u-boot.imx of=${DRIVE} bs=1k seek=1 conv=fsync ,这条语句把uboot镜像u-boot.imx放到sd卡的1k地址处,启动后iroom启动代码会读取到u-boot.imx,将4k的代码读到iram,开始运行uboot。
指令解析:dd 转换、复制文件
参数: if=FIle 从File中读取数据
of=File 写数据到File
bs 一次读写的数据字节数
seek=BLOCKS 写文件时跳过BLOCKS * bs字节再写,如上 seek*bs=1K,即从SD卡的1k位置开始写数据