本文主要是介绍PowerPC从NorFlash启动的过程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
写在最前面:
本文介绍的是PowerPC从NorFlash启动的过程及NorFLASH在启动过程中地址空间的设置。基于的硬件是飞思卡尔的PowerPC -> P2020。软件是u-boot+Linux。ARM平台原理也都是相通的,大家可以借鉴。这篇文章完全看懂的话,你首先要了解一些:处理器的架构,启动方式和流程。我假设读者已经懂了。
我的NorFlash硬件连接的方式
备注:我用FPGA做了地址锁存。同时使得FPGA变成了PowerPC的LocalBus外设。
PPC从NorFlash启动的秘密
在PPC从NorFlash启动时,很多人不太明白各种相关的地址空间的映射。至少我做PPC多年了,以前一直就是这样理解的:PPC启动时,会访问一个特定的地址,从这个地址上读取第一条指令,然后继续执行。这个理解是没错的,但是不够透彻。今天我在这里写个明白。
首先PPC在启动的过程中,会访问一个特定的地址,这个地址是被内核决定了的。比如采用e500内核架构的PowerPC,他的复位地址是在0xfffffffc上,也就是说当系统产生复位之后,PowerPC会去这个地址上取到第一条指令。“BOOK E-兼容的内核,并没有沿用和AIM版本的PowerPC架构相同的复位向量。复位的地址更换为0xFFFFFFFC”*这句话翻译自E500CORERM手册(你可以在飞思卡尔的官网上下载到 E500CORERM Rev. 1, 4/2005)。
此时,如果你把PowerPC配置为从NorFlash启动的话,“在系统未初始化之前,boot片选的操作,允许地址对于一个boot ROM解析,LCS0_N是boot片选的输出。他的操作和系统复位之后的其他片选型号的操作是不同的。当系统复位之后,LCS0_N允许访问每一种LocalBUS的入口,直到BR0和OR0被配置。”(翻译自P2020的使用手册12.4.2.5)。
这两段话结合起来,我们就应该明白了,为何上电没有配置,PPC就可以访问LocalBUS总线。上电之后。LCS0_N的操作寄存器被硬件配置,并且可以通过LocalBUS,透出e500内核的访问空间。
NorFlash初始化在u-boot中的相关内容
(1) 第一段相关的代码———地址空间映射
首先我们快进一下(假使你对PPC的启动流程很熟悉)现在已经初始化了PPC的寄存器空间也就是说PPC的寄存器空间已经可以使用了(这些东西一般在u-boot对应的CPU的start.S中的cpu_init_early_f),PPC也在内核的地址空间上也划分出了可以访问FLASH物理空间的TLB(这部分内容一般在tlb.c中,init_tlbs(),使用tlb_table[i]结构体完成一系列内核entry的配置)。在这个时候,你的NorFlash应该已经可以在PPC的默认状态下可读了。
详细的初始化流程:
首先在boot/cup/mpc85xx/start.S中,运行到了 bl cpu_init_early_f 跳转到boot/cup/mpc85xx/cpu_init_early.ccpu_init_early_f()函数。在这个函数中设置了PPC的CCSR寄存器的访问空间(此时PPC的大多数寄存器都可以访问了)。然后依旧在这个函数(cpu_init_early_f())中跳转到了init_tlbs();在这个函数中初始化了PPC的大部分内核的访问空间(TLB)。此时e500内核可以访问NorFlash所在的地址空间了,但是他在道理上依旧应该是无法访问Norflash(但是我们现在就是在NorFlash中启动啊,怎么能说是不能访问呢?这个问题请查阅本文第二小节,PPC从NorFlash启动的秘密)。
然后程序在boot/cup/mpc85xx/start.S中继续执行,执行到了bl cpu_init_f 跳转到了boot/cup/mpc85xx/cpu_init.c,在这个函数中,程序配置了BR0,OR0寄存器。从这个时候开始,NorFlash已经可以按照配置的内容,正常使用了。附1小节,列出两段代码,来帮助理解内核访问的地址空间和LocalBus的配置。
(2)第二段相关的代码———Flash的初始化
现在我们的程序应该已经跑到了u-boot的board_init_r()函数中。然后执行到了flash_init()(这个函数的返回值是flash的大小)。在这个函数中,得到了Flash的大小。
(3)第三段相关的代码———Flash的读写擦操作
这部分内容就是NorFlash的驱动程序。能看懂这篇文章的想必都熟的不能再熟了,就不再赘述了。
附1 内核访问的地址空间与Localbus的配置
(1)内核地址空间的配置通过这个函数。
void init_tlbs(void)
{inti;for(i = 0; i < num_tlb_entries; i++) {write_tlb(tlb_table[i].mas0,tlb_table[i].mas1,tlb_table[i].mas2,tlb_table[i].mas3,tlb_table[i].mas7);}return;
}
其中,tlb_table的结构体如下
struct fsl_e_tlb_entry tlb_table[] = {/*这里我只是摘取的一部分代码,这里删除了很多代码*//*W**G* - Flash/promjet, localbus *//*This will be changed to *I*G* after relocation to RAM. */SET_TLB_ENTRY(1,CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE_PHYS,MAS3_SX|MAS3_SR, MAS2_W|MAS2_G,0, 2, BOOKE_PAGESZ_256M, 1),/*这里我只是摘取的一部分代码,这里删除了很多代码*/
};
通过
SET_TLB_ENTRY(1,CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE_PHYS,MAS3_SX|MAS3_SR, MAS2_W|MAS2_G,0, 2, BOOKE_PAGESZ_256M, 1),
可以看到u-boot首先配置了一块256M的地址空间,起始位置在CONFIG_SYS_FLASH_BASE,给内核使用。
(2)LocalBus的配置
if (! memctl->br1 & 1) {
#if defined(CONFIG_SYS_BR0_PRELIM)&& defined(CONFIG_SYS_OR0_PRELIM)memctl->br0= CONFIG_SYS_BR0_PRELIM;memctl->or0= CONFIG_SYS_OR0_PRELIM;
#endif#if defined(CONFIG_SYS_BR1_PRELIM) &&defined(CONFIG_SYS_OR1_PRELIM)memctl->or1= CONFIG_SYS_OR1_PRELIM;memctl->br1= CONFIG_SYS_BR1_PRELIM;
#endif}
用这一段代码,CPU又配置了LocalBUS的CS0的寄存器,配置了CS0的片选地址空间及其他信息。自此,NorFlash所有相关的初始化结束。
文章更新记录:
V1.00 吉超 起草了这个文档。shmilyduo@icloud.com
这篇关于PowerPC从NorFlash启动的过程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!