欢迎文明转载。

              参考说明:文中有参考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。

                       

spacer.gif

spacer.gif

spacer.gif

spacer.gif




      这个表格告诉我们,我们可以使用的是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/p_w_picpaths/3/3d/SEC_Users_Manual_S5P4418_Users_Manual_Preliminary_Ver.0.10.pdf