Chinaunix首页 | 论坛 | 博客
  • 博客访问: 204610
  • 博文数量: 56
  • 博客积分: 1085
  • 博客等级: 少尉
  • 技术积分: 652
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-29 13:50
文章分类
文章存档

2014年(4)

2012年(25)

2011年(27)

我的朋友

分类: Delphi

2011-10-06 19:17:31

/*

参考了别人的一些笔记,看完了启动代码。

本文档记录在看代码时碰到的困难,将这些曾经困扰的问题记录下来,以备今后之用。分析时不重要的代码被删除了。

*/

.globl _start

_start: b       reset

    ldr  pc, _undefined_instruction

    ldr  pc, _software_interrupt

    ldr  pc, _prefetch_abort

    ldr  pc, _data_abort

    ldr  pc, _not_used

    ldr  pc, _irq

    ldr  pc, _fiq

 

_undefined_instruction:    .word undefined_instruction

_software_interrupt:  .word software_interrupt

_prefetch_abort:  .word prefetch_abort

_data_abort:      .word data_abort

_not_used:        .word not_used

_irq:             .word irq

_fiq:             .word fiq

 

.balignl 16,0xdeadbeef

/*

_start是整个u-boot程序的入口点,即链接后,该处是整个程序的第一条指令。程序的入口点是由链接脚本所指定,比如对于smdk2410的板子(下面都以smdk241为例),脚本文件位于board\smdk2140\u-boot.lds。在该脚本文件中:ENTRY(_start) 即指定程序的入口地址。globl _start 定义一个外部可以引用的变量,比如说,在其它源代码文档中,就可以直指引用_start这个变量。如int entry=_start; 那此处entry值将是多少呢?因为_start相当于一个变量,entry的值就是_start处存储的值,即b reset机器码值。关于globl定义的变量得注意的地方,后面还有记录

 

这段代码处理中断向量表。

 

关于 balignal 16,0xdeadbeef的网上资料:

.align伪操作用于表示对齐方式:通过添加填充字节使当前位置满足一定的对齐方式。

.balign的作用同.align

.align {alignment} {,fill} {,max}

其中:alignment用于指定对齐方式,可能的取值为2的次幂,缺省为4fill是填充内容,

缺省用0填充。max是填充字节数最大值,如果填充字节数超过max,就不进行对齐.

例如:.align 4, 指定对齐方式为字对齐 

deadbeef一般用来表示没用的或是已经被释放掉的内存

*/

 

_TEXT_BASE:

    .word    TEXT_BASE

 

.globl _armboot_start

_armboot_start:

    .word _start

 

/*

 * These are defined in the board-specific linker script.

 */

.globl _bss_start

_bss_start:

    .word __bss_start

 

.globl _bss_end

_bss_end:

    .word _end

/*

备注这几个由.word伪操作符定义变量的作用及其取值

_TEXT_BASE:

    .word   TEXT_BASE

 

_TEXT_BASE:此处定义一汇编语言标签,更好的理解就是:告诉编译器,为_TEXT_BASE分配存储空间,该空间的名字就叫_TEXT_BASE,该空间中存储的值就是由.word后面确定的TEXT_BASEC(0x33F80000),相当于C语言中long _TEXT_BASE=TEXT_BASE; TEXT_BASE定义在board\smdk2410\config.mk文件中。该值的作用是告诉链接器,本程序运行的基地址为TEXT_BASEU-boot编译后,烧在FLASH的第一个块中,CPU复位上电后,PC寄存器为0x0000。怎么会跑到TEXT_BASE处执行呢?

事实上,CPU上电后,从地址0x0000处执行,而U-BOOT的最起始代码,即本文件中从_start开始的代码是与地址不相关的,这段代码放在任何空间执行的结果都是一样(当然不是绝对,假设u-boot代码段是100K,则放在TEXT_BASE-80K处,搬运时就会把u-boot代码后面20K部分覆盖为最前面的20K)。

.globl _armboot_start

_armboot_start:

    .word _start

定义外部可以引用的变量_armboot_start,。即相当于C long _armboot_start=&_start; _armboot_start值是多少?是TEXT_BASE,即0x33F80000!等价的那条C语句,取的是_start变量地址,而不是_start本身。在C语言中,定义一变量 int x=100;就是告诉编译器。给我一个int大小的存储空间,该空间存储的值就是100,这个空间在哪呢?即空间地址是多少呢?我们可以通过&x知道。

在汇编语言中,理解上有点不一样。上面三行语句,

第一句,告诉编译器,向外面输出变量_armboot_start

第二句,_armboot_start变量在此处,到底在哪,要到链接时才能确定,凡正现在知道有这么一个变量了。

第三句,_armboot_start变量空间放的数据为_start标签的值。这点与C语言的理解有点不一样了。此处引用的是_start标签对应处的地址。在汇编语言中,标签代表的就是那行所在的地址。

图1是从u-boot编译后生成的u-boot.map截图的。从此文件中知道,_armboot_start这个变量地址为0x33f80044,

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