Chinaunix首页 | 论坛 | 博客
  • 博客访问: 328600
  • 博文数量: 67
  • 博客积分: 668
  • 博客等级: 上士
  • 技术积分: 1591
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-16 22:08
文章分类

全部博文(67)

文章存档

2015年(1)

2014年(13)

2013年(28)

2012年(23)

2011年(2)

分类: 嵌入式

2012-02-06 13:39:35

本文只对其中实现过程做简单记录的学习笔记。本节主要参考资料

1.uboot工作流程(网上找到资料,具体出处不明)

2.mini2440uboot移植详细手册


首先从cpu/arm920t/start.S文件运行。对此文件进行分析。

Include的文件包括common.h config.h. makefile文件中的编译选项中已经指定了,搜索的默认目录,即顶层的include目录。

 common.h文件包含的头文件如下:

  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include

等等

其他根据CONFIG项还会包含其他头文件.并且声明了许多.c文件的函数。config.h文件中的数据是由脚本生成。本例中包含如下两行

  1. #include
  2. #include

configs/$(board ),asm/config.h arm文件夹是连接文件夹,它已经连接到了asm-arm

mini2440.h文件包含了所有板级CONFIG配置选项。注意这个文件是复制2410的所以将一些相应的选项改为2440的。asm/config.h文件 仅包含了一个配置项  #define CONFIG_RELOC_FIXUP_WORKS

接着看start.S文件,首先是一个中断向量表。然后在跳转到start_code,在set cup to svc mode这一段后面注视掉bl coloured_LED_init bl red_LED_on这两行(点亮LED操作)。在接着注释语句turn off watch dog上面一行添加||defined(CONFIG_S3C2440),CONFIG_S3C2440项在configs/mini2440.h文件中定义出来。然后是中断掩码和CPU初始频率的设置,这个根据移植手册和芯片手册。代码正常启动(即不定义CONFIG_SKIP_LOWLEVEL_INIT)接着会跳转到cpu_init_crit。此函数完成,关闭cacha,关闭MMU相关,跳转到lowlevel_init

lowlevel_initboard目录的lowlevel_init.S中,它主要将所有存储器控制寄存器的值初始化。这里找到SMRDATA标识的存储寄存器的数据表格,是用了SMRDATATEXT_BASE的差值,可以表示SMRDATA的偏移地址,因为差值是偏移地址,所以无论是在哪里运行,只要保证连接代码时这些代码是被连续连接在开始地址的就可以,代码:

  1. ldr r0, =SMRDATA
  2. ldr r1, _TEXT_BASE
  3. sub r0, r0, r1 @r0中就是SMRDATA的相对于0x0地址的偏移地址

本例lsd有如下部分:

  1. . = 0x00000000;
  2. . = ALIGN(4);
  3. .text :
  4. {
  5. cpu/arm920t/start.o (.text)
  6. board/gc5084/mini2440/lowlevel_init.o (.text)

详细看参考资料1。另外在移植手册中提到Jtag调试时会有bug,这是因为调试时是运行在内存中的,而上面的是相对于0x0地址的偏移地址,所以会错误,可以修改成如下代码:

  1. ldr r0, =SMRDATA
  2. ldr r1, =lowlevel_init 
  3.  @保存lowlevel_init地址,这个地址是连接位置相关的,即是内存中的地址
  4. sub r0, r0, r1 
  5.  @lowlevel_init到SMRDATA代码之间的长度
  6. adr r3, lowlevel_init 
  7.  @adr指令是伪指令,它是基于当前PC值加上或减去一个偏移值,而得到地址。所以无论运行于哪里他都会加载上当前运行地址的程序标号的地址。
  8. add r0, r0, r3 
  9.  @当前运行地址的lowlevel_init地址 + lowlevel_init到SMRDATA代码之间的长度 = SMRDATA数据表的地址。

而后relocate这段,查看开始开始地址是否和RAM加载地址TEXT_BASE相同。决定是否需要跳转过搬运代码到RAM这一段。

接着可以添加代码同时支持NOR FLASHNAND FLASH,移植手册上是通过想0x4开始的地址写数据来判度,而似乎也可以使用这种方法 ”直接读BWSCON[21]的值是最简单快捷的方式,它们是由OM[1:0]决定的。而OM[1:0]的状态也就决定NANDNOR“,资料1中又可以通过给0地址写入数据,nand flash是内部4k,所以可写,而nor flash不可以。因而有多种方法。 这部分稍后在分析。(但是有一个疑问,现在没有为C全局变量清BSS段,而直接跳到读nand flashC语言函数中会不会有问题)

在这里首先使用了移植手册上的方法,手册中的代码设置了sp的值,BSS段的设置没有,但因为没有全局变量所以也没事。

nor flash中搬运代码则相对简单。norboot:标号处, _armboot_start定义为开始的向量表,它与bss_start的差值就是uboot代码的长度。

然后执行到stack_setup,设置堆栈指针sp,从TEXT_BASE开始减去#CONFIG_SYS_MALLOC_LEN区域和CONFIG_SYS_GBL_DATA_SIZE区域等,将sp指向所得到的地址。然后清除BSS段,再跳转到start_armboot,lib_arm/board.c,进入第二阶段。内存地址图如下:

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