CPU上电后如何从flash上获取程序并执行,不同厂家不同型号CPU也往往不同,但是大体是相同的:从flash上读取。从flash上读取是最传统和常规的方式,也是项目会采用的方式。
(1)各厂家的芯片如何从flash上读取程序来运行?
上电时根据某些GPIO的电平,来选择进入到不同模式,如启动还是烧写?选择从哪种flash启动,如nor,nand,emmc。
(2)对于imx6ul,有两个需要关注的启动电平。
一个是启动模式:是烧写还是启动。一个是从哪里启动,是nor,nand,emmc?
这些如何实现的我们无需关注,都是硬件固话好的模式,我们只需要知道,当我们想烧写,或者想启动的时候如何去配置这些引脚的电平状态即可。而什么样的电平决定了什么样的启动状态,在手册中有详细说明。
IMX6ULLRM.pdf Chapter 8 System Boot
对于我们的开发板,我们需要关注:
imx6ul有三种启动模式,是烧写01(USB下载),或者是10内部引导启动(从flash启动)。其他的可以不关注。
用户根据不同项目,往往需求不同,有公司选择nor,有选择nand,有emmc启动的。为了更好的适合更多用户,芯片厂家往往会让自家芯片支持更多的flash启动。这里我们重点关注nand或者emmc,这是当前的主流。
在IMX6ULLRM.pdf Chapter 5中 Boot Device Select,上电后,这些特殊引脚,默认为输入状态,CPU通过获取到这些输入引脚的电平,选择对应的flash进行启动。
同时,imx6u可以通过这些引脚告诉CPU更丰富的信息,从而更高效的实现启动。
EMMC启动都设置了哪些GPIO引脚:
用户的需求是,上电从flash启动,那么CPU通过上面的硬件配置获取了信息,那么如果启动执行程序?
imx6ul内部有一块boot ROM,这部分是CPU设计时实现的,上电后会首先运行。boot ROM会去读取上面设置好的硬件信息。
然后读取程序到内存中开始运行,因此boot ROM需要做:
一般的,很多选手都学习过S3C2400 一款十分经典,适合初学的平台,目前虽已停产多年,但学习资料,很多。它的实现方式是,CPU固定的从flash上读取4K大小代码,然后运行,运行时通过此4K代码,完成代码重定向到内存,然后在内存中运行。
imx6ul是boot ROM完成从flash到内存中的操作,所以boot ROM很重要的就是要知道,从哪里拷贝程序,程序有多大,从哪里拷贝到哪里。而这些信息不再通过外部硬件来告知boot ROM,而是通过存储在flash起始的一片位置,boot ROM获取后,在完成后续操作。因此,烧写到flash上的映像文件,出了程序业务本身,还需要包含一些额外的信息会boot ROM,用于启动前期工作。
那么包含哪些信息呢?不同厂家不同,我们针对imx6ul为例。
以上表明了从那里找到有用数据。
typedef struct {
ivt_header_t header;
uint32_t entry;//程序链接地址
uint32_t reserved1;
uint32_t dcd_ptr;//内存中DCD数据地址
uint32_t boot_data_ptr;//内存中boot data数据地址(整个image所在地址)
uint32_t self;//内存中ivt地址
uint32_t csf;
uint32_t reserved2;
} flash_header_v2_t;
boot_data_ptr指明了boot date所在地址,里面是一个结构体如下:
typedef struct {
uint32_t start;//整个映像文件在内存中的起始地址
uint32_t size;//大小
uint32_t plugin;
} boot_data_t;
boot_data_t指明了复制到哪里去,复制多大。