【转】PowerPC non-DPAA 平台上的…

本文详细介绍了PowerPC (PPC) 架构下多种启动方式的原理与实现,重点讲解了从NOR flash启动的过程,包括U-Boot image的位置、核心如何读取以及相关配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

09年在MPC8536E上做启动开发的工作,当时的目标就是将“从NOR flash/NAND flash/SD卡/SPI flash启动”这几中方式用比较统一的方式来实现,并将patch推到Wolfgang的U-Boot tree上。下面是当时开发时做的一些记录,所以基于的U-Boot code是09年的,但变化不大,重要的是原理。


PowerPC CPU可以从不同的存储介质上启动,最常用的是从NOR flash启动,还可以从NAND flash启动,从SD卡启动,从SPI flash启动。为什么需要这么多种的启动方式?需求驱动,本来NOR flash是启动设备的最佳选择,能擦除且字节访问,但容量不够大,所以在单板设计中还可能需要另外一种存储介质去存放kernel image,根文件系统什么的,比如使用NAND flash,这时问题就来了,系统中既然有个NAND flash,能不能将bootloader也放在NAND flash中,从而可以从NAND flash启动?但人家NAND flash志存高远,当时设计的目的是为了取代硬盘而不是作为非易失行存储介质去和NOR flash抢饭碗,像U盘,SD卡,记忆棒,还有固态硬盘SSD神马的,内部都是NAND flash,这也就注定了NAND flash是以block为单位访问的,但我们CPU只能是字节访问,所以要想从NAND flash启动还得需要eLBC controller的帮忙(NOR/NAND一般都挂在local bus控制器上)。从SD卡上启动就更进一步了,整个系统都在一块卡上,拎着想去哪就去哪,呵呵。下面就开始扯吧,先会扯一点CPU地址空间,LAW,TLB,cache什么的,然后是各个不同启动机制的介绍,U-Boot启动代码的解析还有相关的patch介绍,在Wolfgang 的git tree上,还有开发碰到的问题等等。。。

下面这些问题应该能从本文中找到答案:


1. CPU的基础知识和各种启动方式的原理

   U-Boot image存放在NOR flash/NAND flash/SPI flash/SD 卡的什么位置?

   CPU core启动时怎么去相应的存储介质读取U-Boot image?

   - U-Boot image的连接地址和image在存储介质存放的地址有关系吗?

   CPU的一些基础知识:地址空间AS0/AS1,TLB,LAW


2. 启动代码的一些重要细节

   - U-Boot在L1 Dcache中建立的stack

   - 怎么将L2 Cache初始化为SRAM?

   - SRAM的空间怎么分配?

   - CPU怎么在地址空间(AS0/AS1)进行切换?为什么要切换?

   - 代码relocate的过程。比如从NAND flash到L2 SRAM,在到DDR。

   - 代码在L2 SRAM运行时,需要使用L2 SRAM作为堆栈,怎么建立相应的堆栈?


1. 基础


1.1 CPU地址空间

先来张MPC8536E的架构框图:




什么是地址空间呢?在手册上也叫local address map,就是core能够访问到的36bit的地址空间。这个地址空间包括各个功能模块能够访问到的地址空间,DDR SDRAM空间以及CCSR地址空间。CPU core是怎么访问SOC上的各个功能模块的?比如eLBC控制器,DDR控制器,PCI控制器等等。通过LAW(Local AccessWindow)寄存器来配置。每个LAW寄存器将一段地址空间和相应的功能模块连接起来,从core出来的物理地址和各个LAW的地址进行比较,如果在某个LAW指定的地址空间,那么就将这个交易发送给该LAW指定的功能模块。

每个LAW可指定的地址空间大小为4K-32G。

特别提醒:LAWBA[BASE_ADDR]域必须和地址空间大小对齐。


在这个地址空间中有三段地址是比较特殊的:


1.CCSR的地址空间

这段地址空间只需要通过CCSBAR寄存器来指定起始地址,地址空间大小是固定的1M空间(e500 core是1M,e500mc是16M)。

CCSRBARConfiguration,Control, and Status Registers Base Address Register)的缺省值是0xFF700000


访问该空间的TLB在设置时,需要将IG位置1.


2.L2 SRAM地址空间

MPC8536E有512K的L2 cache,该cache可以配置为SRAM使用,此时需要通过L2CTL[L2SRAM]域来指定L2SRAM的大小,通过L2SRBAR寄存器指定其实地址。


3.缺省的8M bootrom地址空间

一般soc会定义8MBbootRom启动地址空间(0xFF80_0000–0xFFFF_FFFF),在core复位启动访问第一条指令时能够直接访问指定启动设备的地址空间。启动设备可以指定挂在eLBC上的NAND flashNOR flash,或者指定SDCARD/SPI flash


上述地址空间配置优先级:

L2SRBAR指定的地址优先于其他方式指定的地址空间;

CCSRBAR指定的地址空间不能和DDR控制器指定的地址空间重复,否则,cpu行为是未定义的;

LAW之间的地址如果重复,则低编号LAW覆盖高编号LAW的地址空间;


1.2 TLB


TLB简单说就是将程序虚拟地址转化为物理地址的一个查找表。TLB使用WIMGE字段来指定所访问地址空间的属性。以后会单独写下TLB,比如怎么配置TLB,怎么查找TLB,TLB在U-Boot和内核的使用,内核进程切换时TLB的切换操作等。


在启动的时候,所有L1/L2MMU中的TLB Entry都为无效的,除了TLB1Entry0,Entry被赋予以下数值来指定地址空间0(AS0)中的4KB启动地址空间(0xFFFF_F000– 0xFFFF_FFFF)。在U-Boot代码中,这段4K代码被称为bootpage,即cpu/mpc85xx/start.S中的bootpg汇编代码。

E500 core在复位的时候会去0xFFFF_FFFC去读取第一条指令,该指令一般是一条跳转指令,跳转到bootpg的头部去执行。




1.2.1 TLB WIMGE

WIMGE字段是e500内核进行虚实地址转化时,用来描述TLB对应的物理地址空间的访问属性字段。这几个字段配置和Cache的MESI协议来保持Cache一致性。


? Write-throughrequired (W)

若此位为1,说明对该物理地址空间访问时采用cache-through策略;

若此位为0,说明对该物理地址空间访问时采用cache-back策略;


? Caching inhibited (I)

若此位为1,说明对该物理地址空间访问时不使用L1 cache

若此位为0,说明对该物理地址空间访问时使用L1 cache


? Memory coherency required (M)

若此位为1,说明对该物理地址空间访问时需要进行存储一致性处理;


? Guarded(G)

若此位为1,说明对该物理地址空间访问时需要对相应的地址空间进行保护,阻止PowerPC的猜测访问;


? Endianness(E)

若此位为1,说明对该物理地址空间访问时采用小端模式;

若此位为0,说明对该物理地址空间访问时采用大端模式;


想更多了解write through/write back,cache inhibited和guarded怎么影响Cache一致性,请参阅EREF。


2.boot from NOR flash


一般NOR flash挂接在CPU的eLBC控制器上,通过CS0来片选。要想从NOR flash启动,首先将编译好的512K U-Boot image烧写到NOR flash的最后512K中。CPU core启动时会去0xFFFFFFFC处取第一条指令执行,一般是一条跳转指令跳转到bootpage的地方,因为NOR flash是可以字节访问的,随后CPU会顺序执行NOR flash中的代码。


2.1 eLBC


eLBC通过GPCM连接NOR flash,通过FCM来连接NAND flash

BR0/OR0– BR7/OR7 指定eLBC 8个片选信号所对应的地址空间和属性。CS0连接启动设备,比如从NOR flash启动时,NOR flash必须连接到CS0上。从NAND flash启动时,NAND flash必须连接到CS0上。对于既有NOR flash又有NAND flash的单板,并且支持两种启动模式的话,需要CPLD来动态切换CS0片选信号指向启动设备。

当选择从NOR flash启动时,CS0是作为启动片选信号输出,选择的地址和空间由BR0OR0信息来决定,该寄存器启动值如下,显然访问的是从0– 0xFFFFFFFF4G地址空间。该片选信号一直按照此种方式运行直到第一次更改BR0OR0的值



在往NORflash烧写U-Boot程序时,是将512Kimage写到flash的最后512K字节,即eff8_0000开始的地方。core启动时第一条指令是FFFF_FFFC实际上读取的就是就是efff_fffc处的指令(0x4BFF_F004)。


2.2 启动过程


首先一个问题是U-Boot image要烧写到NOR flash的哪个地址?是由CPU和NOR flash的硬件连线决定的。同时该地址也决定了U-Boot的CONFIG_SYS_TEXT_BASE的值,该值在config.mk文件中赋值给-Ttext,也就是U-Boot image中text段的起始地址。


关于 ld script的内容可以参考《Using ld - The GNU linker》的小册子。这里只提下面几个参数:

1. -T指定使用的script文件

2. -e指定image的开始执行的地址

3. -Ttext: 和--section-start .text同义,该字段的意思是给text段指定绝对地址。


#ifndef CONFIG_SYS_TEXT_BASE

#define CONFIG_SYS_TEXT_BASE    0xeff80000

#endif

LDFLAGS_u-boot += -T $(obj)u-boot.lds $(LDFLAGS_FINAL)

ifneq ($(CONFIG_SYS_TEXT_BASE),)

LDFLAGS_u-boot += -Ttext $(CONFIG_SYS_TEXT_BASE)

endif


以MPC8536DS单板来看下CPU 和 NOR flash的硬件连线:



使用的NOR flash芯片是128MB的29GL01GP,通过单板上的一个拨线开关可以将128M的flash划分为4个bank,每个bank 32M。

通过上图可以看到CPU地址线的使用如下:

0 1 2 3

4 5 6

7-30

31

读取flash时,高4位不会用到,所以分配该4位主要看U_Boot的地址空间分配。在8536DS中分配的是e

Localbus地址空间是从e000_0000efff_efff.

Promjete0000000-e7ffffff

NOR flash:

e8000000-efffffff


通过FPGA来设置flash25/26两位地址线,相当于把NOR flash划分为4region

连接NOR flash的低24位数据线(32M)

通过16bit的数据线连接NORflash,所以不care最低位

1110


10 0

10 1

11 0

11 1


0_0…0=> e800_0000 – e9ff_ffff

0_0…0=> ea00_0000 – ebff_ffff

0_0…0=> ec00_0000 – edff_ffff

0_0…0=> ee00_0000 – efff_ffff


x



在往NOR flash烧写U-Boot程序时,是将512Kimage写到flash的最后512K字节,即eff8_0000开始的地方。core启动时,会去地址FFFF_FFFC获取第一条指令实际上读取的就是efff_fffc处的指令,因为CPU高4位数据线根本就没有连接到NOR flash上

那么在地址efff_fffc地方存放的是什么指令,需要看U-Bootld script,因为ld script决定了U-Boot image每个段存放的内容。


U-Boot image使用的load scriptor 是u-boot.lds


SECTIONS

{

......


.text :

{

*(.text)

*(.got1)

}:text

_etext= .;

PROVIDE(etext = .);


.= (. + 0x00FF) & 0xFFFFFF00;

_erotext= .;

PROVIDE(erotext = .);

......

.bootpg RESET_VECTOR_ADDRESS - 0xffc :

{

cpu/mpc85xx/start.o(.bootpg)

}:text = 0xffff


.resetvec RESET_VECTOR_ADDRESS :

{

*(.resetvec)

}:text = 0xffff


.= RESET_VECTOR_ADDRESS + 0x4;


.= ALIGN(4);

_end= . ;

PROVIDE(end = .);

}

"board/freescale/mpc8536ds/config.mk"

ifndefTEXT_BASE

TEXT_BASE= 0xeff80000

Endif


RESET_VECTOR_ADDRESS= 0xeffffffc

"cpu/mpc85xx/resetvec.S"


.section.resetvec,"ax"

b_start_e500



从上面的ldscript可以看出,u-boot image最后的4个字节存放的是启动向量,即一条跳转到bootpg的跳转指令(0x4BFF_F004)。可以通过objdump u-boot 找到U-Boot image最后4个字节的内容。


显然core启动时读取的就是这条指令0x4BFF_F004,这条指令是条跳转指令(因为OP = 010010),core的指令译码单元会执行如下的计算来得到跳转到的地址:

010010  11 1111 1111 1111 0000 0000 01 0 0

-------|-----------------------------------|--|---

OP     | LI                                |AA|LK

--------------------------------------------------


EXTS(LI || 0b00) => 0xFFFFF004

CIA              => 0xFFFFFFFC

-------------------------------

                    0xFFFFF000


通过objdump u-boot可以看到effff000出存放的代码,对应的是start.S文件中的4k 的启动代码段bootpg。

effff000<_start_e500>:

effff000: 38 00 00 02 li r0,2

effff004: 7c 12 fb a6 mtdbcr0 r0

effff008: 7c 13 fb a6 mtspr 1011,r0

effff00c: 7c 30 4a a6 mfspr r1,304

effff010: 7c 30 4b a6 mtspr 304,r1

effff014: 3c 40 00 01 lis r2,1

effff018: 60 42 00 01 ori r2,r2,1

effff01c: 7c 52 fb a6 mtdbcr0 r2

effff020: 4c 00 01 2c isync

effff024: 7c 53 fb a6 mtspr 1011,r2

effff028: 4c 00 01 2c isync

effff02c: 7c 00 04 ac sync


"cpu/mpc85xx/start.S"


.section.bootpg,"ax"

.globl_start_e500


_start_e500:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值