powerpc uboot链接脚本大改造

在做完了linux由arm处理器核移植到ppc处理器核的工作后,还需要进行uboot的移植,之前对uboot的分析文章都是基于arm平台,感兴趣的朋友可以看看,链接如下:
http://blog.csdn.net/column/details/uboot-note.html
借这次ppc移植工作,也学习了ppc uboot的相关知识,顺道写几篇文章记录下。
工作背景是公司处理器由arm处理器核cortex A8换为ppc处理器核ppc460s,现在处于FPGA仿真验证阶段,SOC的外设控制器都没有变化.

uboot版本号:2014.04
平台:powerpc460s

根据之前arm版本uboot的移植经验,一次完整的uboot移植我觉得可以分为3步:
(1)根据需求,对uboot进行配置,链接等方面的修改,加入必须的板级支持函数(先为空函数即可),保证uboot可以编译链接通过。
(2)由start.s开始,按照uboot启动流程对调用到的各个关键函数进行功能调试。保证uboot正常启动进入命令行。
(3)对各个模块驱动单独调试。

因此我修改boards.cfg,修改配置文件,确定代码段首地址,内存首地址等基本要素。期望能够直接编过。
但是看了ppc460s处理器的链接脚本后,我觉得问题比我想象中要复杂一点。
根据我的实际需求需要对ppc的链接脚本进行改造,其实就是将uboot镜像中各个section进行重新布局。今天趁十一假期,来记录下对ppc uboot链接脚本的改造过程。
首先来分析下原版uboot针对ppc460s处理器各个section的布局,ppc460s属于ppc4xx系列,因此链接脚本是arch/powerpc/cpu/ppc4xx/u-boot.lds。结合arch/powerpc/cpu/ppc4xx/start.S等启动代码,我画出了ppc4xx系列处理器uboot段布局图如下。
这里写图片描述
bootpg和resetvec位于4G地址空间顶端的4k空间,其余段则位于指定的地址。虚线表明了处理器上电后执行流程。
这里就需要简单说明下ppc4xx系列处理器的一点特性,ppc4xx系列处理器很大的一个特点是MMU常开,上电即开启。
上电后ppc4xx有一个shadow TLB将地址空间最顶端的4k进行映射,具体映射到哪里,这就要看处理器内部逻辑如何填该TLB,以及外部总线的地址仲裁如何布局物理地址空间,这点询问SOC的IC设计人员就可以知道。
初上电的ppc4xx处理器只能访问顶端4K空间,并且上电取指地址是0xfffffffc,因此在针对ppc4xx系列处理器,bootloader的设计一般就是0xfffffffc处为跳转指令,跳转至4k起始地址执行,在该4k代码中对需要进行访问的地址空间进行TLB映射,保证之后主代码所在物理地址的映射,最后跳转到主代码段执行。
可以看出uboot的设计就是遵循这个特点,上电首先执行jump _start_440,跳转到4k起点执行,初始化TLB之后jump _start,进入代码段执行。
因此uboot完全可以作为ppc4xx处理器的bootloader来使用,上电直接执行uboot。

但是对于我们公司处理器,却产生了一些问题,问题如下:
(1)公司处理器逻辑将顶端4k空间映射到片内64k的ROM中,该ROM存放公司开发的bootloader,uboot太大放不进去
(2)uboot实际相当于一个二级bootloader,由公司一级bootloader加载uboot启动,uboot进行必要的配置和参数准备,再去启动kernel
(3)公司处理器的需求是uboot直接运行在内存中,仅仅起一个承上启下的作用,为kernel传参。
从公司处理器的需求来看,所需要的uboot并不是一个完整的bootloader,而仅仅是在内存中运行,为kernel准备参数,加载启动kernel就可以。这样uboot的段布局就需要改造一下。

根据这个需求,对uboot的链接布局我提出来的改进方案如下:
(1)顶部跳转和地址空间映射的任务由一级bootloader完成,uboot仅需要直接在内存中运行即可,因此考虑将bootpg以及resetvec去掉。
(2)原代码段执行是由_start_440–>_start跳转来切入的,现在需要手动指定uboot入口为_start。

针对第一条改进方案,起初考虑过保留bootpg,但是由于bootpg在地址空间的顶端4k,根据实际的处理器地址空间分布,我的代码段启动地址CONFIG_SYS_TEXT_BASE是在内存的0x80e80000,需要注意的是这个地址是一个虚拟地址,因为公司一级bootloader中已经完成了地址空间的映射,都是平映射。但是这样uboot最终链接生成u-boot.bin时,就会有1G大小,这是因为最高位置的段bootpg和最低位置的段text之间间隔了将近1G,生成镜像时这之间的空隙是需要预留出来的,来保证加载是能够将各个段加载正确位置。

这里就想到一个问题,难道别的ppc4xx处理器,如果使用uboot作为一级bootloader,text段在内存中,而内存地址距离地址空间顶端很远,编译出来的u-boot.bin就会非常大吗?
查看别的ppc4xx处理器的相关代码,发现解决方法是在4k代码中将内存映射到接近顶端4k的地址,同时修改CONFIG_SYS_TEXT_BASE为该地址。这样编译链接出来的u-boot.bin就不大了。

因此我上面的考虑,有一个很重要的前提是我在4k代码中为需要使用的地址空间做了平映射。公司处理器的一级bootloader中的确是这样做的。

这样想来,对于我的uboot,bootpg段还有一种解决方法,是保留bootpg,修改其中TLB映射,将内存代码段地址映射到接近顶端4k的位置,并且修改CONFIG_SYS_TEXT_BASE。
但是由于一级bootloader的存在,已经将跳转以及TLB映射工作做完,所以uboot并不需要4k代码,并且uboot本身不算很大,平映射完全满足需求,为了移植简单快捷,我还是采用将bootpg等段删掉的方法。

因此我将arch/powerpc/cpu/ppc4xx/u-boot.lds中如下代码注掉。

#if 0 
#ifndef CONFIG_SPL
#ifdef CONFIG_440
  .bootpg RESET_VECTOR_ADDRESS - 0xffc :
  {
    arch/powerpc/cpu/pp
  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值