Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2149414
  • 博文数量: 361
  • 博客积分: 10828
  • 博客等级: 上将
  • 技术积分: 4161
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-20 14:34
文章分类

全部博文(361)

文章存档

2011年(132)

2010年(229)

分类: LINUX

2011-02-28 20:15:14

s3c2410 u-boot stage1

前言

         本文主要是基于大家比较熟悉的 s3c2410 ,对移植 u-boot stage1 过程进行一个分析,网上关于之方面的资料很多,但是几乎都只是对代码作注解,容易让人产生知其一不知其二的感觉,在这里,我主要结合 u-boot stage1 时的内存布局和 stage1 的具体指令来做个分析,这样看起来比较直观,更容易理解一些 .

一、 全局看 u-boot

我们要深入理解 u-boot 如何工作的,以及跟硬件都有什么依赖,我们需要先对 u-boot 及硬件有一个全局的认识。

在这之前,为了更多的人不会迷糊一些问题,先澄清几个概念:

_start : 这是 u-boot 的第一条指令入口地址 , 如果从 flash 启动,就是 0x0, 如果直接下载到 SDRAM 中执行,则是 TEXT_BASE=0x33F80000.

_TEXT_BASE :本身是一个地址,但是地址处放的内容是 TEXT_BASE,

s3c2410 中我们通常设为 0x33F80000, 通过 config.mk 中的 -Ttext $(TEXT_BASE) 来指定链接选项,从而更新链接脚本中的入口地址,不明白的去查查 linker and loader.

cpu/arm920t/start.S

_TEXT_BASE:

.word TEXT_BASE

    _armboot_start : 本身也是一个地址,但是地址处放的内容是 _start ,如果 _start 0x33F80000, _artboot_start 放的内容就是 0x33F80000 ,见 cpu/arm920t/start.S

  _armboot_start:

       .word _start

知道这三个地址之后,再看两条指令:

adr r0,_start    /*r0 <- current position of code*/

这条指令网上讲得也很多,翻译过来就是 add r0,r0,[PC+#offset], 就是把通过一个地址来知道 _start 处的地址,注意是地址,即 TEXT_BASE=0x33F80000, 这步在链接的时候就已经确定了,或者你不用管那么多,你知道链接完成之后,这条指令相当于 mov r0,0x33F80000(sdram) 或者 mov r0,0x0(flash) 就行了。

ldr r1,_TEXT_BASE    /* test if we run from flash or RAM */

注意,这里的 ldr 不是伪指令,伪指令表示时, ldr r1,=_TEXT_BASE

这两个的区别在于,伪指令是直接把 _TEXT_BASE 写入到 r1 中,这里 _TEXT_BASE 就代表一个地址,而 ldr r1,_TEXT_BASE, 是把 _TEXT_BASE 中存放的内容,也就是 TEXT_BASE=0x33F80000 写入到了 r1.

ldr    r2, _armboot_start

结合上面讲的,应该知道,这条语句实际上是将 _armboot_start 中的内容,也就是 _start 的地址写入到了 r2 中,而非网上很多人问的是 _armboot_start 的地址 .

ldr    r3, _bss_start

这跟上面一样分析了,定义见 cpu/arm920t/start.S

.globl _bss_start

_bss_start:

  .word __bss_start

下面这两条语句也就好理解了:

  sub       r2, r3, r2         /* r2 <- armboot 大小   */

  add r2, r0, r2          /* r2 <- 代码结束地址   */

到底 armboot 的大小都包含了哪些东西,结合 u-boot.lds ,见下图:

 

 

   

    关于链接脚本,讲起来又很多了,不清楚的,建议看看 linker and loader ,清楚代码的编译链接及加载过程,是我们更深入的理解底层机制的根本。

 

在上面,我只是讲了几个平时可能遇到的,又不太理解的问题,关于 stage1 中代码的注释网上一搜就有一大把。看了注释,再结合,我讲的这几点,应该能弄清 stage1 中是如何拷贝代码的了。接下来,我们来看看为什么 TEXT_BASE 的值是 0x33F80000 呢?

二、 TEXT_BASE=0x33F80000 的由来?

先看一个 SDRAM 的内存映射图:同样结合上面的 uboot.lds

0x33F80000

0x30000000

0x33ffffff

映射前

映射后

 


bss 段、 u-boot cmd 段、 .data .rodata

.text 段及中断向量表

malloc 区域,见 start.S  sub r0,r0, #CFG_MALLOC_LEN

全局变量,见 start.S sub  r0, r0, #CFG_GBL_DATA_SIZE

IRQ:sub    r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)

sub   sp, r0, #12                 /* leave 3 words for abort-stack    */

.

.

 

bss

u-boot cmd

.data 数据段

.rodata 只读数据段,

入口 20 字节中断向量表 .text(start.o *(.text))

  在 S3C2410 中,查看 datasheet 64M SDRAM 地址空间即为 0x30000000 0x33ffffff ,在 bank6 中,而 flash 映射地址为 0x0 开始。

  TEXT_BASE=0x33F80000 即为程序加载起始地址,可以使用的空间大小即为 0x33F80000 0x33FFFFFF 512K ,如果你 u-boot 包含的功能太多,觉得不够用,你可以把 0x33F80000 调小一点,即和往低地址移一些,移的过程中注意 memory page 对齐就行了,一般是 4KB.

阅读(818) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~