加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

MPC8314 (e300核) uboot 调试 一

发布时间:2020-12-15 07:09:30 所属栏目:百科 来源:网络整理
导读:??????? MPC8314 (e300核) uboot 调试 一??????? ??????? 分类:??????????? UBOOT2010-09-21 14:52 2170人阅读 评论(2) 收藏 举报 ??? 历经2个多月,完成了MPC8314最小系统(uboot)及Linux内核和根文件系统的调试。这是我第一次从头开始做小系统和内核的

??????? MPC8314 (e300核) uboot 调试 一???????

??????? 分类:??????????? UBOOT2010-09-21 14:52 2170人阅读 评论(2) 收藏 举报

??? 历经2个多月,完成了MPC8314最小系统(uboot)及Linux内核和根文件系统的调试。这是我第一次从头开始做小系统和内核的移植工作,虽然调试的比较辛苦,但是收获还是很多的。下面就介绍一下调试的过程和一些原理性的东西。

1 MPC8314 上电流程

???

??? 系统上电后,经过若干个时钟后,MPC8314会检测复位配置输入信号CFG_RESET_SOURCE[0:3]来确定硬件配置字源选择,在目标板上可以设置跳线来改变CFG_RESET_SOURCE[0:3],选择硬件配置字源。本系统中的硬件配置字存放在CPLD模拟的Flash空间中。

从相应的地方读取硬件配置字(RCWL,RCWH)后,会设置相应的寄存器。其中RCWH中的BMS位值为1,定义了e300核心的MSR[IP]位初始值,如上图所示,MSR[IP]为1决定中断向量的前缀为0xFFF,启动存储空间的位置为0xFF80_0000~0xFFFF_FFFF;SWEN位为0,禁止软件看门狗;ROMLOC位为0b110,RLEXT位为0b00确定了选择local bus GPCM-16bit ROM为启动ROM。复位向量和本地地址映射的默认启动ROM访问将直接指向ROMLOC指定的接口。选中的启动ROM的本地访问窗口(LBLAW0)将被使能,并初始化基地址LBLAWBAR0为0xFF80_0000,窗口大小为8M。这时,Local Bus上的片选CS0的寄存器值为BR0:0000_0000,OR0:0000_0000。整个4G空间全是ROM,每16M重复一次。

中断向量的前缀为0xFFF,复位向量为100,决定了系统复位后的第一条指令从0xFFF0_0100处获得。

/cpu/mpc83xx/u-boot.lds文件时连接器脚本文件,其中

.text????? :

? {

??? cpu/mpc83xx/start.o (.text)

??? 。 。 。 。 。

?? }

。 。 。 。 。 。

ENTRY(_start)

规定了代码段从/cpu/mpc83xx/start.s开始。而ENTRY(_start)这一句告诉编译器uboot.bin的镜像入口点为start.s中的_start标号。

所以,我们要将UBOOT的代码烧写到16M Flash中偏移15M的地方,保证了从0xFFF0_0100的空间取到的指令为uboot代码。并且还需要保证0xFFF0_0100为start标号。


2 uboot启动流程

2.1 uboot启动概述

??? Uboot的启动是从/cpu/mpc83xx/start.s中的_start标号开始的,经历了 /cpu/mpc83xx/start.s,/cpu/mpc83xx/cpu_init.c ,/lib_ppc/Board.c等几个文件中的多个汇编和C函数,最后会在/lib_ppc/Board.c中的board_init_r函数中进入命令死循环,等待执行键入的命令。其具体的流程如下图所示:

2.2 init_e300_core 函数

??? 初始化e300核心,禁止中断响应,只允许machine check中断和system reset中断,禁止指令和数据地址转换,即关闭MMU,进行实地址转换,设置为supervisor级别,禁止看门狗,无效指令和数据cache,等,为系统创建一个干净可靠的初始环境。

2.3 窗口重映射

从前面MPC8314上电流程可以看出,上电之后,第一条代码是从0xFFF0_0100的地方开始执行的,但是flash并不一定会分配在0xFF00_0000到0xFFFF_FFFF的地方(以我们16M的为例)。在本系统中,Flash的地址就被分配到了0xFE00_0000到0xFEFF_FFFF的地方。所以这其中需要做一个跳转,这正是这段代码中map_flash_by_law1,remap_flash_by_law0等函数要做的,具体的流程可以由下面的五张图来说明:

1 开始时,BR0,OR0为全零,4G全是重复的Flash,CPU通过LBLAW0访问Flash

空间 FF80_0000到 FFFF_FFFF。

2 map_flash_by_law1函数使用LBLAW1映射FE00_0000到FEFF_FFFF这段空间。

3 跳转到FE00_0000这段空间执行代码,由于4G空间重复,只要偏移地址计算正确就

会顺序执行。

4? remap_flash_by_law0函数设置BR0为FE00_0000,OR0大小为16M。

5 remap_flash_by_law0函数设置LBLAW0窗口映射FE00_0000到FE7F_FFFF区域,并

清除LBLAW1。

2.4 Dcache 中分配空间做堆栈

程序跑到这里,就要进入第一个C函数了,C函数的运行需要堆栈空间,但这时,RAM还没有初始化,只能在Dcache中锁定一定的空间,用于C的堆栈空间。

lock_ram_in_cache函数在Dcache中锁定4k的空间。

下面的几行代码将堆栈指针指向刚刚分配好的Dcache空间。

lis r1,(CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@h

ori r1,r1,(CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@l

li? r0,0??????

stwu??? r0,-4(r1)

2.5 cpu_init_f 函数

???

??? 该函数是系统执行的第一个C语言的函数,主要是做一些CPU 寄存器的初始化,其中最重要的部分是初始化Local Access Windows的值和Local Bus上的片选BR,OR的值。这些值需要在/include/configs/MPC8315ERDB.h中配置好。

2.6 board_init_f 函数

该函数为板级初始化的第一个函数,会对板子上很多硬件外设做初始化,其中最重要的为init_sequence数组,该数组里面包含了很多板级的硬件初始化函数,在board_init_f函数中会依次的调用该数组中的函数去初始化各个硬件,该数组如下:

init_fnc_t *init_sequence[] = {

#if defined(CONFIG_BOARD_EARLY_INIT_F)

??? board_early_init_f,

#endif

#if !defined(CONFIG_8xx_CPUCLK_DEFAULT)

??? get_clocks,???? /* get CPU and bus clocks (etc.) */

#if defined(CONFIG_TQM8xxL) && !defined(CONFIG_TQM866M) /

??? && !defined(CONFIG_TQM885D)

??? adjust_sdram_tbs_8xx,

#endif

??? init_timebase,

#endif

#ifdef CFG_ALLOC_DPRAM

#if !defined(CONFIG_CPM2)

??? dpram_init,

#endif

#endif

#if defined(CONFIG_BOARD_POSTCLK_INIT)

??? board_postclk_init,

#endif

??? env_init,

#if defined(CONFIG_8xx_CPUCLK_DEFAULT)

??? get_clocks_866,???? /* get CPU and bus clocks according to the environment variable */

??? sdram_adjust_866,?? /* adjust sdram refresh rate according to the new clock */

??? init_timebase,

#endif

??? init_baudrate,

??? serial_init,

??? console_init_f,

??? display_options,

#if defined(CONFIG_8260)

??? prt_8260_rsr,

??? prt_8260_clks,

#endif /* CONFIG_8260 */

#if defined(CONFIG_MPC83XX)

??? prt_83xx_rsr,

#endif

??? checkcpu,

#if defined(CONFIG_MPC5xxx)

??? prt_mpc5xxx_clks,

#endif /* CONFIG_MPC5xxx */

#if defined(CONFIG_MPC8220)

??? prt_mpc8220_clks,

#endif

??? checkboard,

??? INIT_FUNC_WATCHDOG_INIT

#if defined(CONFIG_MISC_INIT_F)

??? misc_init_f,

#endif

??? INIT_FUNC_WATCHDOG_RESET

#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)

??? init_func_i2c,

#endif

#if defined(CONFIG_DTT)???? /* Digital Thermometers and Thermostats */

??? dtt_init,

#endif

#ifdef CONFIG_POST

??? post_init_f,

#endif

??? INIT_FUNC_WATCHDOG_RESET

??? init_func_ram,

#if defined(CFG_DRAM_TEST)

??? testdram,

#endif /* CFG_DRAM_TEST */

??? INIT_FUNC_WATCHDOG_RESET

??? NULL,?????????? /* Terminate this list */

};

可以看到时钟,内存,串口,控制台等初始化函数的调用,其中串口的初始化要先于内存初始化。

2.7 relocate_code 函数

到目前为止,boot代码都是在Flash中运行,但是代码最终是要到RAM中运行的,在上面的board_init_f函数中已经将RAM初始化好了,具备了在RAM中运行程序的能力,现在relocate_code函数需要做两个事情:

1 从Flash中拷贝uboot的代码到RAM

??? 2 记下现在执行代码的偏移,跳转到RAM中相应的位置执行。

2.8 board_init_r 函数

???

??? 该函数为板级初始化的第二阶段,主要是初始化PCI,PCIE,网口,Flash等设备,关闭看门狗,把前面借dcache做堆栈的空间解锁,还给cache。在一切设备都初始化好后,便会进去main_loop的死循环中。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读