为系统运行适配平台的cpu内核为ppc603,cpu型号为mpc8247。嵌入式系统驱动开发,这里,我所专注的层次为bsp层。万事万物皆有开头,而这里关于系统bsp层的开头就“住在”start.s文件中,今天就来一探其中的究竟。
文件最开头定义的是堆栈的大小,为64k。
接下来所做的工作是对核的几个关键寄存器进行初始化,如下图所示:
图中的注释已经阐述的比较明白了,对于每种寄存器在这里就不展开具体介绍,大家如果感兴趣可以去看相关的说明手册。
接下来,到比较关键的部分了,话不多说,先上张截图压压惊
要熟悉start.s中的流程,还需要了解powerpc平台中的汇编语言,以上有几个指令这里还是介绍一下分别为:li 、mflr、lwz、stw。
li:立即数加载指令,何谓立即数相当于高级语言中的常量,它是直接出现在指令中的数,不用存储在寄存器中或存储器中的数(度娘说的),所以这里, li r0, 0,意思是将r0中的值设置为0。
mflr:Move From Link Register,取出链接寄存器的值。这里,mflr r4,意思是将链接寄存器中记录的地址放入r4中,也就是说r4中存放了函数loadrfi的地址值。
lwz: 加载字指令(偏移地址寻址)。这里,lwz r4 , 0(r4),意思是从r4中读取4字节的数,放入r4中。r4中就有rfi的操作码了。
stw:字存储(偏移地址寻址)。这里,stw r4,0x900(r0),意思是将r4的32位内容存储到有效地址为0x900存储器中。
下一个部分,就我个人而言,可能是最重要的部分或者说是由于该部分的缺失使我在后面的中断调试部分浪费了较多的精力和时间。所以在适配板卡驱动的各位同仁,如若你们的中断控制器部分代码一切就为,可就是无法进入中断,可以检查一下,汇编部分关于中断的配置。
以上是有关于中断的处理代码,接下来对以上代码进行分析。PowerPC指令为32位长,指令内仅有16位用于加载常量值,由于地址最多可达到64位,所以采用每次一段的方式载入地址,汇编程序中的@符号指示汇编程序给出了一个符号值的特殊处理形式:@highest:表示一个常量的第48-63位;@higher:表示一个常量的第32-48位;@h:16-31位;@l:0-15位。
lis r3, excstart@h
ori r3, r3, excstart@l
将excstart地址值载入r3
lis r4, excend@h
ori r4, r4, excend@l
将excend地址值载入r4
subf r5, r3, r4 //将r4-r3的值放入r5中
li r4, 0x2 //设置r4的值为0x2
srw r6, r5, r4 //将r5右移2位,放入r6
mtctr r6 //加载r6中的值
lis r5, 0x900@h
ori r5, r5, 0x900@l //将0x900放入r5
isync //强制等待指令执行完毕(指的是进入0x900地址处执行的指令)
lis r7, 0x500@h
ori r7, r7, 0x500@l //将0x500放入r7
isync //强制等待指令执行完毕(指的是进入0x500地址处执行的指令)
vector_code_install:
lwz r6, 0(r3) //将r3中的值放入r6
stw r6, 0(r5) //将r6中的内容放入0x900处
stw r6, 0(r7) //将r6中的内容放入0x500处
addi r7, r7, 0x4 //将r7中的值加0x4
addi r5, r5, 0x4 //将r5中的值加0x4
addi r3, r3, 0x4 //将r3中的值加0x4
bdnz vector_code_install //跳转至vector_code_install
sync //保证寄存器与内存的读写操作完毕
这里的excstart和excend为发生中断时,跳转的起始地址与终止地址。
接着看下一段,截图如下:
li r4, 32 //将一立即数32放入r4中
mtctr r4 //加载r4中的值
li r3, 0 //将一立即数0放入r3中
isync //等待指令执行完毕
sysALoop:
tlbie r3 //将r3对应的有效地址转化无效
addi r3,r3,0x1000 //将r3中值加0x1000
bdnz sysALoop //跳转入sysALoop
sync //等待内存读写完毕
说实话以上这一段汇编的具体目的是什么还是没搞明白。
接下来的一段汇编截图如下所示:
这一段与操作cache想关,注释也比较清晰就一一展开分析了。