免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1050 | 回复: 0
打印 上一主题 下一主题

Arm linux启动分析(5) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-11-30 22:16 |只看该作者 |倒序浏览
二、U-boot链接脚本的介绍
1 uboot的链接脚本的内容及分析如下
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)  //指定启动时的函数入口地址,_start在每个CPU的start.S中定义
                 //真正的启动运行地址段由TEXT_BASE宏定义在编译时由config.mk中定义
SECTIONS
{
  . = 0;                             //指定系统启动从偏移地址 0开始
  . = ALIGN(4);                     //地址进行4字节对其调整,确保低 2bit地址线为 0
  .text      :                       //定义.text段空间
        {
    cpu/sep4020/start.o  (.text)   //指定 start.o目标文件首先从.text段分配
     *(.text)                         //后续.text段内容的分配
  }

  . = ALIGN(4);   //.text段处理后,进行4字节地址对其调整,然后分配.rodata段空间
  .rodata : { *(.rodata) }

  . = ALIGN(4);    //4字节地址调整,然后分配.data段空间
  .data : { *(.data) }

  . = ALIGN(4);    //4字节地址调整,然后分配.got段空间
  .got : { *(.got) }
__u_boot_cmd_start = .;             //定义.u_boot_cmd的段空间,
  .u_boot_cmd : { *(.u_boot_cmd) }  //并且__u_boot_cmd_start符号指向段空间开始
  __u_boot_cmd_end = .;               //__u_boot_cmd_end符号指向该段空间结束

  armboot_end_data = .;             // armboot_end_data符号指向之前所有分配完段的结束,  
//后续将开始.bss段的分配

  . = ALIGN(4);                       //地址 4字节调整,开始分配.bss段空间
  __bss_start = .;                   //.bss段空间开始地址
  .bss : { *(.bss) }
  _end = .;                            //.bss段空间结束地址
}
说明1:标准应用程序包括 3 类标准段空间:.text 运行代段;.data 全局变量等具有初始值的数据空间;.bss暂态变量,堆栈等数据空间;
说明 2:.rodata,.got,.u_boot_cmd 等段空间由程序员设计需要而自行定义的段空间;
说明 3:本PPT采用 ARM720T CPU 进行分析,其指令字长为 4字节,所以地址调整为 4 字节;
2 U-boot起始地址的指定
(1)在配置文件config.mk中154定义了CPPFLAGS 变量,其中指定了程序的链接基址为       TEXT_BASE
       CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS)  -D__KERNEL__
       ifneq ($(TEXT_BASE),)
       CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE)
       Endif
(2)在其后又在172行CFLAGS 包含了CPPFLAGS变量
       CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes
(3)然后在主Makefile中将config.mk进来了,这样其中的大部分变量都在编译过程中有固定的值了
       # load other configuration
       include $(TOPDIR)/config.mk
(4)在生成elf可执行文件u-boot的命令中就指定了链接标志LDFLAGS
$(obj)u-boot:    depend $(SUBDIRS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT)
        cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
               --start-group $(__LIBS) --end-group $(PLATFORM_LIBS)
               -Map u-boot.map -o u-boot

三、U-boot的相关代码分析
1、cpu/sep4020/start.S启动分析
.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   //快速中断向量

_TEXT_BASE: //程序在SDRAM中运行的起始地址,即链接的起始地址
.word      TEXT_BASE  // TEXT_BASE是链接时候的起始地址,在/board/prochip/UB4020/config.mk中定义的

.globl _armboot_start
_armboot_start:       //程序运行起始地址,实际上是FLASH中程序的起始运行地址
.word _start

.globl _bss_start
_bss_start:       //bss段的起始链接地址
.word __bss_start

.globl _bss_end
_bss_end: //bss段的链接结束地址
.word _end
/*
* 实际的启动复位代码
*/
reset://复位启动子程序
/*stack setup for each mode*/
/* SVC32 mode*/   
mrs  r0,cpsr    //设置 CPU为 SVC32模式
bic   r0,r0,#0x1f
orr   r0,r0,#0x13
msr  cpsr,r0
ldr   r0, _TEXT_BASE//配置SVC模式的堆栈空间(在sdram中)
sub  r0, r0, #CFG_MALLOC_LEN
sub  r0, r0, #CFG_GBL_DATA_SIZE
#ifdef CONFIG_USE_IRQ
sub  r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub  sp, r0, #12      


#ifdef CONFIG_USE_IRQ
/* IRQ mode*/
mov R4, #0xD2             //切换 CPU为 IRQ模式
    msr  cpsr, R4   
ldr   r0, _TEXT_BASE //配置IRQ模式的堆栈空间(在sdram中)
sub  r0, r0, #CFG_MALLOC_LEN
sub  r0, r0, #CFG_GBL_DATA_SIZE
sub  r0, r0, #(CONFIG_STACKSIZE_FIQ)
sub  sp, r0, #12
。。。。。。。。。。其他模式配置堆栈省略。。。。。。。。。。。。。
/*返回 SVC 模式*/      
mov R4, #0xD3             //关闭系统的中断
    msr  cpsr, R4        
bl      cpu_init_crit
/*********************进入cpu_init_crit 函数******************************************/
cpu_init_crit://cpu的初始化
/* 配置SEP4020的主频 */
ldr   r0, =0x10001004    /*96M*/
ldr   r1, =0x400B         
str   r1, [r0]

ldr   r0, =0x10001014    /*Normal*/
ldr   r1, =0x1
str   r1, [r0]
ldr   r0, =0x10001004    /*96M*/
ldr   r1, =0xC00B         
str   r1, [r0]

ldr   r0, =0x1000100C   /*open all*/
ldr   r1, =0xFFFFFFFF
str   r1, [r0]

/*配置SEP4020的串口参数*/
#if 1
ldr   r0, =0x1000500C   /*databit:8*/
ldr   r1, =0x83
str   r1, [r0]

ldr   r0, =0x10005004    /*baud=9600*/
ldr   r1, =0x0
str   r1, [r0]

ldr   r0, =0x10005000
ldr   r1, =0x2F
str   r1, [r0]

ldr   r0, =0x1000500C
ldr   r1, =0x3
str   r1, [r0]
#endif
mov pc, lr
/*********************从cpu_init_crit 函数返回**************************************/

/*
*在U-BOOT重定位之前我们需要配置好SDRAM的相应参数,这个是在borad目录的lowlevel_init.S中完成的
*/
bl     lowlevel_init
/*******进入lowlevel_init函数*******/
/*
* lowlevel_init主要配置4020的EMI模块相应的参数
*/
.globl lowlevel_init
lowlevel_init:
    ldr    r4,    =EMI_CSECONF
    ldr    r5,    =0x8ca6a6a1                 
    str    r5,    [ r4 ]

    ldr    r4,    =EMI_SDCONF1
    ldr    r5,    =0x1E184177
    str    r5,    [ r4 ]

    ldr    r4,    =EMI_SDCONF2
    ldr    r5,    =0x80001860
    str    r5,    [ r4 ]
/*******从lowlevel_init函数返回*******/

/*将系统的0地址remap到sdram中去*/

remap:
mov r0, pc
add  r0,   r0,   #0x20000000
add  r0,   r0,   #0x08
mov pc,   r0

mov r0,   r0
mov r0,   r0
mov r0,   r0
mov r0,   r0

    ldr   r4,   =0x11000020
     ldr   r5,   =0xb    //remap到sdram中
str   r5,   [ r4 ]
/*
清系统的BSS段
*/
ldr r0, = 0
ldr r1, _bss_start
ldr r2, _bss_end
bss_init:
str r0, [r1]
add r1,r1,#4
cmp r1,r2
blt bss_init

#ifndef CONFIG_SKIP_RELOCATE_UBOOT

/*比较系统的运行地址和链接地址判断是否需要将u-boot搬运到sdram中去,在我们的SEP4020中我们是将U-BOOT重新搬运到SDRAM的0x30700000地址处*/
relocate:                        /* relocate U-Boot to RAM        */
adr   r0, _start        /* r0    */
ldr   r1, _TEXT_BASE         /* test if we run from flash or RAM */
cmp     r0, r1                  /* don't reloc during debug         */
beq    vector_copy     //如果相等则说明已经在sdram中,这时候只需要搬运中断向量表

ldr   r2, _armboot_start
ldr   r3, _bss_start
sub  r2, r3, r2        /* r2             */
add  r2, r0, r2        /* 将源码的结束地址赋值给r2 */

copy_loop:       //正真的代码搬运过程
ldmia       r0!, {r3-r10}         /* copy from source address [r0]    */
stmia       r1!, {r3-r10}         /* copy to   target address [r1]    */
cmp r0, r2                    /* until source end addreee [r2]    */
ble   copy_loop
/*
搬运中断向量表到sdram的0地址去
*/
vector_copy:
ldr   r0, _TEXT_BASE
add  r2, r0, #128
ldr   r1, =0x30000000 /*modified by shixq from 0x0c000000 to 0x30000000*/
/*     add  r1, r1, #0x08 *//*deleted by shixq*/
vector_copy_loop://搬运中断向量表的循环
ldmia       r0!, {r3-r10}
stmia       r1!, {r3-r10}
cmp r0, r2
ble   vector_copy_loop
#endif      /* CONFIG_SKIP_RELOCATE_UBOOT */

/*使能4020的中断*/
mrs  R4, cpsr
    bic   R4, R4, #0x80
    msr  cpsr, R4  

/*跳转到系统的c语言初始化函数start_armboot 中去,开始初始化系统的各种外设*/
ldr   pc, _start_armboot

_start_armboot:       .word start_armboot




本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/99507/showart_2107725.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP