PowerPC从NorFlash启动的过程

来源:互联网 发布:清华同方教学软件 编辑:程序博客网 时间:2024/06/05 15:33

写在最前面:

    本文介绍的是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

0 0
原创粉丝点击