在boards.cfg中,可以看到在该文件末尾定义Nanopi2/Nanopc开发板的一些属性
# Status, Arch, CPU:SPLCPU, SoC, Vendor, Board name, Target, Options, Maintainers
Active arm slsiap s5p4418 s5p4418 nanopi2 s5p4418_nanopi2 -
从该行可以看出来,该开发板使用的soc使用arm架构,但是使用的cpu是slsiap。众所周知,在arm架构中根本不存在这样的CPU,通过其他途径获知NanoPi2/NanoPC-T2使用的soc(s5p4418)采用的是armv7的指令集,而这里为什么又定义为slsiap呢?我觉得是或许是这个soc需要用到的代码跟其他armv7指令集的代码有些不同,为了不影响其他开发板的代码,设置cpu是slsiap,这样定位的启动代码目录应该是arch/arm/cpu/slsiap/,恰好该目录下也存在一个start.S汇编文件,但是打开start.S就立马傻眼了,因为里面啥代码都没有,这样的代码架构确实跟其他开发板的架构不同,真奇葩。
分析该目录下的u-boot.lds发现把SDIR/start.o (.text*)放置在了镜像的首要位置。继续分析SDIR是何许人也。
在arch/arm/slsiap目录下存在一个config.mk.找到了SDIR=arch/arm/cpu$(if $(CPU),/$(CPU),)$(if $(SOC),/$(SOC),)
分析一下的语法:$(if(CPU),/$(CPU))
虽然我以前也没有遇到过这样的语法,但是我猜是这样的定义:如果CPU有定义,那么该结果为定义CPU型号目录。
在NanoPi2/NanoPC-T2中,CPU为slsiap,SOC为s5p4418
SDIR最后结果应该是SDIR=arch/arm/cpu/slsiap/s5p4418/
在SDIR目录下,确定存在着另外一个stat.S文件。
现在分析一下start.S文件
在reset中首先调用了save_boot_params,但是看了下这个函数什么都没做,可以无视这个函数,接下来是让CPU进入管理模式,禁止IRQ和FIQ,这跟Exynos4412没有什么区别。
接下来是
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_cp15
bl cpu_init_crit
#endif
在include/configs/s5p4418_nanopi2.h中没有找到CONFIG_SKIP_LOWLEVEL_INIT这个宏定义,那么就会执行cpu_init_cp15和cpu_init_crit。
cpu_init_cp15貌似只要属于一种CPU都一样的,没啥差别,这就不讲了,其实我也不是太详细是怎么实现的,反正是设计到了一些特殊的寄存器了。
cpu_init_crit,该程序同样位于该start.S
在cpu_init_crit会调用lowlevel_init,lowlevel_init位于low_init.S文件中,该函数也是有点看不懂,也就没有详细去深入理解,跟功能没啥联系,跟CPU有关,不去理他。
接下来是重定位代码段,会从代码存储空间拷贝到DDR内存中,然后跳转到DDR中执行代码