上次我们聊到将C code 通过工具链编译成机器码,今天这篇和大家介绍CPU boot的过程。对此我们先看下一个哈弗结构的CPU的框架。
CPU通过指令总线从指令存储器里面读取指令进行操作,如果需要数据则从数据存储器里面读取数据处理。下面是一组真实的指令总线和数据总线。
从上面的代码中可以看到,指令总线和数据总线都有地址和数据信号以及一些握手信号。在CPU reset之后,CPU会主动通过指令总线去某个特定的位置读取机器码。下图是CPU接口上一组输入信号,boot_addr_i 就是指令CPU reset 之后从哪里开始读代码。
由此我们可以通过将编译好的机器码放在mem里面,然后设置boot_addr_i 指定到该mem的位置,实现一个最小的CPU boot系统。
实际芯片的模块比这个最小系统复杂很多。存储介质上分为ROM,SRAM和Flash,一些大的芯片还有DDR等。
看到这些存储模块,有些人想了,是不是可以把机器码放在里面?这就要讲到boot的几种模式。
第一种将代码放在SRAM里面直接启动。具体操作的手段是将CPU的boot_addr_i 指定到SRAM的位置,在仿真开始的时候将code load 进 SRAM memory里面即可实现 从SRAM里面boot。SRAM boot的一个问题是每次关电,SRAM都会被清除,无法保存code。
第二种是将代码放在ROM里面,但是很不幸,ROM的空间非常小,如果将整段代码放在ROM里面不太现实。所以很多人将ROM 用作存储引导代码,即bootrom code。然后由bootrom code 跳转到SRAM或者flash执行的位置。
第三种是将代码放在Flash里面。通过bootrom code 从flash里面将代码搬到SRAM里面执行。另外一种方式是通过bootrom code 去配置flash 进入XIP状态,然后CPU直接从flash里面读取指令进行执行。通过这类方式boot的好处是掉电代码没有遗失,是真正产品应用的方式。
上面是三种在我们SOC验证中经常用到的boot方式,真实芯片的boot比这个复杂得多。
以ARM为例,系统boot会被分成三个步骤。
第一级bootloader:引导加载程序,即bootrom code,会选择哪种方式启动系统(EMMC,UART,SPI...)。第一级bootloader执行完之后会跳转到第二级bootloader。
第二级bootloader:用于硬件的初始化,比如初始化时钟,中断,看门狗等,这段代码放在SRAM中执行。执行完这个会跳到第三级bootloader。
第三级bootloader: 这个才是我们C代码的入口,也就是我们写的main函数在这里开始执行。
bootrom是一门比较复杂的系统工程,在真正产品应用中还需要考虑可靠性和安全性。但是对我们SOC验证来说,在系统里面集成最基础的三种boot方式即可满足大部分验证需求。
上期有朋友问我有没有简单的SOC验证环境,答案是有,在公众号后台回复"SOC验证"可获得一个最小系统的SOC验证环境。
感谢大家关注处芯积律,下期我们继续讲讲SOC验证环境启动的一些知识。
作者:IC bug 猎人
原文链接:处芯积律
推荐阅读
更多IC设计技术干货请关注IC设计技术专栏。欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。