欢迎文明转载。
参考说明:文中有参考aven_paul博主的S5P4418启动镜像分析一文,具体参考http://blog.csdn.net/aven_paul/article/details/46772285
S5P4418是四核cortex-A9的SOC,这么强大的处理器非操作系统不能充分发挥其性能,但是对于打算深入了解和学习更好的使用它来说,裸机编程更能让你了解从Power on -> internalRom --> boot mode choose --> Loading & Launch bootloader(BL1 --> BL2 )->......的详细过程,更能体现从SOC到board再到program的层层衔接,丝丝相扣的严谨设计。本文由于使用nanoPi2硬件,只能使用SD作为boot源,因此以SD卡为基础描述裸机编程的实现。
通过S5P4418启动镜像分析我们了解到。SD卡内的镜像是这样的,
Block 0
Sd/emmc卡信息
Block 1
Nsih.bin
Block2
2ndboot.bin
Block63
Nsih.bin
Block64
u-boot.bin
并有网友已经以把自己的程序.bin替换u-boot.bin的方式实现出来,见“点亮user Led”http://weibo.com/p/1001603914482173772682,同时文中给出了修改SD卡内绝对位置数据的方法,即使用winhex工具定位到绝对位置并修改。
根据网友的这些文章,我觉得应该能对裸机编程有个初步的概念,但是同时给我们带来一些疑惑,而且2ndboot不提供源码,对于我们希望刨根问底的人来说,总感觉缺少点东西不能把控,那可不可以把我们的程序直接替换2ndboot.bin来跑裸机呢?想到就马上动手去试,不过还有些前提工作要做。
1. 找到2ndboot.bin被internalRom搬运到什么地方来Launch?
2. 如果用替代2ndboot.bin的方法来做的话,我们的bin最大可以做到多大呢?
带着这些一文,我们还是要去官方手册找答案
首先,我们要看看系统的memory map
看这个map,我们会发现InternalRAM的地址是0xFFFF0000,根据手册我们知道InternalRAM有32KB。好,是不是InternalRom会把2ndboot的内容loading到这个地址来运行呢?为此我们重新编译了“点亮user LED”的例子里的三个文件,只是将链接指令改为arm-linux-ld -Ttext=0xffff0000 start.o main.o -o main了。我们把生成的main.bin用winhex放到SD卡的block2也就是0x400位置,把卡插入nanoPi2的bootSD卡槽,上电,very good ,LED闪烁起来了。
是不是就完了呢?也许..吧,也许还没有
既然能动了,我们也希望知道为什么
好,继续看官方手册第3章 System boot。由于我们使用的是 Internal ROM boot,使用SD卡启动,因此切换到3.4.4节SDHCBOOT。
这个表格告诉我们,我们可以使用的是1to32block,我们的点亮LED的程序小于只有1k不到,所以不会超出范围,下面红框圈住的这句话,描述InternalROM将SD卡里的数据从Block1开始load到InternalRAM,我们的main.bin是写入SD卡的block2来替代2ndboot的,按照道理应该是0xFFFF0000+0x200才是我们的main.bin的放置位置,我们将编译器连接修改一下am-linux-ld -Ttext=0xFFFF0200 start.o main.o -o main。完整编译后将main.bin用winhex写入SD卡的0x400处,将卡插入nanoPi2,上电,LED开始闪烁,跟连接地址0xffff0000的效果一样,这是为什么呢?
带着疑问,我重新查看了start.s,发现内部用到的跳转指令b start 和b main全部是相对位置跳转。同时我继续看官方手册关于Nsih的相关说明。
原来,block1中存放的Nsih是迁移后的exception vector 。当系统reset后,通过exception vector 看到,其跳转到Reset_Handler处。Reset_Handler指向向的是哪里呢?我们找打了官方的镜像提取出其中Nsih信息后,发现,该地址正是0xFFFF0200。
也就是说,系统reset后通过InternalRom的加载,又经过exception vector的跳转,跳到了我们的被InternalROM Load到InternalRAM中的地址中去的main.bin中来运行来了。
同时也就意味着,如果使用arm-linux-ld -Ttext=0xffff0000 是不妥的,一旦main.bin中出现绝对跳转,程序将跑飞。
总结一下:要将自己的程序替换2ndboot来实现SD卡启动的裸机编程
1. 将main.bin写入SD卡的block2即0x400处;
2. 如果main.bin小于15KB,则编译时的链接器的-Ttext=0xFFFF0200
3.2. 如果main.bin大于15kB(512*(32-1)),则需要先写在0x400处写入一个从main.bin中分离出的包含load其余代码的小于15KB的部分,通过这个15k的代码将main中其余的部分加载到内存,如果main.bin大于InternalRAM,则需要自己写外部DRAM的代码。这部分暂时不在本文中讨论。
提交审核完了,发现粘贴进来得图片都显示不出来了,图片基本来自手册的截图,所以编辑一下给出S5P4418的手册链接供参考。http://wiki.friendlyarm.com/wiki/images/3/3d/SEC_Users_Manual_S5P4418_Users_Manual_Preliminary_Ver.0.10.pdf