uboot连接器脚本

来源:互联网 发布:软件与软件教育现代化 编辑:程序博客网 时间:2024/06/05 17:48
1、uboot.lds
  1. OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
  2. ;指定输出的格式,elf小端,32位
  3. OUTPUT_ARCH(arm)
  4. ;指定输出文件是arm平台
  5. ENTRY(_start)
  6. ;指定启始代码段为_start
  7. ;下面写的是链接,表示最终生成的elf格式,如何进行链接
  8. SECTIONS
  9. {
  10. . = 0x00000000;开始地址
  11. . = ALIGN(4);//4字节对齐
  12. .text ://正文段,即指令代码,放在当前位置,即0x00000000位置
  13. {
  14. cpu/arm920t/start.o (.text)//从目标文件start.o开始,即从汇编程序start.S开始
  15. *(.text)//其他代码部分都放在此处,如board.o cpu.o等等,在他们中有相应的跳转指令,只要指定开始就可以了
  16. //其他放在其后面,自己实现自动跳转。比如再编译c程序的时候,a.o b.o c.o最后生成a.out,只要指定开始就可以了
  17. //就是默认的main开始,其他的自己实现跳转,不用管放在什么位置了。
  18. }
  19. . = ALIGN(4);//继续4字节对齐
  20. .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }只读代码段
  21. . = ALIGN(4);//继续4字节对齐
  22. .data : { *(.data) }//数据段,RW可读写
  23. . = ALIGN(4);//继续4字节对齐
  24. .got : { *(.got) }//自定义got段
  25. . = .;
  26. __u_boot_cmd_start = .;//定义变量__u_boot_cmd_start为当前位置
  27. .u_boot_cmd : { *(.u_boot_cmd) }//放置cmd
  28. __u_boot_cmd_end = .;定义变量__u_boot_cmd_end
  29. . = ALIGN(4);//继续4字节
  30. __bss_start = .;//定义__bss_start变量,为当前位置,定义为当前位置是因为不知道编译出来到有多大放
  31. //放到了那里,那么就等链接的时候自动生成并定义变量
  32. .bss (NOLOAD) : { *(.bss) . = ALIGN(4); }//bss段,即未初始化变量段如数组,参数等
  33. _end = .;//定义变量_end
  34. }
2、start.s
  1. #include <common.h>
  2. #include <config.h>

  3. /*
  4.  *************************************************************************
  5.  *
  6.  * Jump vector table as in table 3.in [1]
  7.  *
  8.  *************************************************************************
  9.  */


  10. .globl _start//这里定义了一个符号,_start 其中.globl指示告诉编译器,_start这个符号要被链接器用到,
  11.              //_start就像C语言的main函数一样,告诉链接器程序从这里入口
  12.              //每个汇编都要提供一个_start符号并且用.globl声明,如果使用默认到链接器。
  13.              //如果一个符号没有被.globl声明,就表示这个符号不会被连接器用到。即使int a;声明没有赋值
  14. _start: b    reset //符号具体含义的定义相当于对符号赋值 即a=....
  15.     ldr    pc, _undefined_instruction
  16.     ldr    pc, _software_interrupt
  17.     ldr    pc, _prefetch_abort
  18.     ldr    pc, _data_abort
  19.     ldr    pc, _not_used
  20.     ldr    pc, _irq
  21.     ldr    pc, _fiq

  22. _undefined_instruction:    .word undefined_instruction//前面的_undefined_instruction也是一个符号,没有
  23.                                                  //globl声明不会被编译器用到。
  24.                                                  //把undefined_instruction值按照16bit赋值给
  25.                                                  //标号_undefined_instruction 即使int a=22;
  26. _software_interrupt:    .word software_interrupt
  27. _prefetch_abort:    .word prefetch_abort
  28. _data_abort:        .word data_abort
  29. _not_used:        .word not_used
  30. _irq:            .word irq
  31. _fiq:            .word fiq

  32.     .balignl 16,0xdeadbeef


  33. /*
  34.  *************************************************************************
  35.  *
  36.  * Startup Code (called from the ARM reset exception vector)
  37.  *
  38.  * do important init only if we don't start from 
  39.  * relocate armboot to ram
  40.  * setup stack
  41.  * jump to second stage
  42.  *
  43.  *************************************************************************
  44.  */

  45. _TEXT_BASE:
  46.     .word    TEXT_BASE//定义符号_TEXT_BASE值为TEXT_BASE

  47.     .word _start

  48. /*
  49.  * These are defined in the board-specific linker script.
  50.  */
  51. .globl _bss_start
  52. _bss_start:
  53.     .word __bss_start//在lds中定义的开始赋值为_bss_start

  54. .globl _bss_end//同上//定义_bss_end为lds中的_end
  55. _bss_end:
  56.     .word _end


  57. //下面这里没有define
  58. #ifdef CONFIG_USE_IRQ
  59. /* IRQ stack memory (calculated at run-time) */
  60. .globl IRQ_STACK_START
  61. IRQ_STACK_START:
  62.     .word    0x0badc0de

  63. /* IRQ stack memory (calculated at run-time) */
  64. .globl FIQ_STACK_START
  65. FIQ_STACK_START:
  66.     .word 0x0badc0de
  67. #endif
  68. //没有define


  69. /*
  70.  * the actual start code
  71.  */

  72. start_code:
  73.     /*
  74.      * set the cpu to SVC32 mode
  75.      */
  76.     mrs    r0, cpsr//cpsr到r0
  77.     bic    r0, r0, #0x1f//
  78.     orr    r0, r0, #0xd3//上面把r0的32位赋值成SVC32模式然后下面再赋值给cpsr,改变状态寄存器从而进入svc32
  79.     msr    cpsr,r0

  80.     bl coloured_LED_init//跳转到LED程序,这里可以删除,也可以进行点灯调试
  81.     bl red_LED_on

  82. #if    defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK)
  83.     /*
  84.      * relocate exception table
  85.      */
  86.      //重新拷贝异常向量表,从_start开始的16个32位数据拷贝到0地址
  87.     ldr    r0, =_start
  88.     ldr    r1, =0x0
  89.     mov    r2, #16
  90. copyex:
  91.     subs    r2, r2, #1
  92.     ldr    r3, [r0], #4
  93.     str    r3, [r1], #4// 拷贝然后地址+4 每个地址1个字节,4*8=32
  94.     bne    copyex
  95. #endif

  96. #if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
  97.     /* turn off the watchdog */

  98. if defined(CONFIG_S3C2400)//定义寄存器地址
  99. # define pWTCON        0x15300000
  100. # define INTMSK        0x14400008    /* Interupt-Controller base addresses */
  101. # define CLKDIVN    0x14800014    /* clock divisor register */
  102. #else
  103. # define pWTCON        0x53000000
  104. # define INTMSK        0x4A000008    /* Interupt-Controller base addresses */
  105. # define INTSUBMSK    0x4A00001C
  106. # define CLKDIVN    0x4C000014    /* clock divisor register */
  107. # endif

  108.     ldr r0, =pWTCON 关闭看门狗
  109.     mov r1, #0x0
  110.     str r1, [r0]

  111.     /*
  112.      * mask all IRQs by setting all bits in the INTMR - default
  113.      */
  114.     mov    r1, #0xffffffff//这里关闭中断
  115.     ldr    r0, =INTMSK
  116.     str    r1, [r0]
  117. if defined(CONFIG_S3C2410)
  118.     ldr    r1, =0x3ff
  119.     ldr    r0, =INTSUBMSK
  120.     str    r1, [r0]
  121. # endif

  122.     /* FCLK:HCLK:PCLK = 1:2:*/
  123.     /* default FCLK is 120 MHz ! */
  124.     ldr    r0, =CLKDIVN
  125.     mov    r1, #3
  126.     str    r1, [r0]
  127. #endif    /* CONFIG_S3C2400 || CONFIG_S3C2410 */

  128.     /*
  129.      * we do sys-critical inits only at reboot,
  130.      * not when booting from 
  131.      */
  132. #ifndef CONFIG_SKIP_LOWLEVEL_INIT//这里没有定义skip,跳转到cpu_init_crit
  133.     bl    cpu_init_crit
  134. #endif


  135. //在lowlevel_init.S执行完后继续执行下面的代码





  136. #ifndef CONFIG_SKIP_RELOCATE_UBOOT //进行代码搬运
  137. relocate:                /* relocate U-Boot to RAM     */
  138.     adr    r0, _start        /* r0 <- current position of code */ //adr取变脸地址,取_start地址。
  139.     ldr    r1, _TEXT_BASE        /* test if we run from flash or RAM */
  140.     cmp r0, r1 /* don't reloc during debug */
  141.     beq stack_setup

  142.     ldr    r2, _armboot_start            //计算代码段大小 从_bss_start - _armboot_start即_start 都在lds中定义            
  143.     ldr    r3, _bss_start
  144.     sub    r2, r3, r2        /* r2 <- size of armboot */ //然后从0地址拷贝这么大小的内容到_TEXT_BASE地址开始的空间中即内存
  145.     add    r2, r0, r2        /* r2 <- source end address */

  146. copy_loop:
  147.     ldmia     {r3-r10}        /* copy from source address [r0] */
  148.     stmia     {r3-r10}        /* copy to target address [r1] */
  149.     cmp    r0, r2            /* until source end addreee [r2] */
  150.     ble    copy_loop
  151. #endif    /* CONFIG_SKIP_RELOCATE_UBOOT */

  152.     /* Set up the stack                         */
  153. stack_setup: //这里初始化堆栈,搬运代码完成后,初始化堆栈
  154.     ldr    r0, _TEXT_BASE        /* upper 128 KiB: relocated uboot */ //下面两个变量在Includes/config/smdk2410.h中有定义
  155.     sub    r0, r0, #CONFIG_SYS_MALLOC_LEN    /* malloc area */ //堆空间定义的大小 malloc可分配空间大小
  156.     sub    r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ //给内核传递参数的大小空间,初始化
  157. #ifdef CONFIG_USE_IRQ//这里不使用快速中断 下面不用
  158.     sub    r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
  159. #endif
  160.     sub    sp, r0, #12        /* leave 3 words for abort-stack */ //从这里看出初始化堆栈时间上就是给定sp寄存器的值

  161. clear_bss:
  162.     ldr    r0, _bss_start        /* find start of bss segment */ //清楚_bss_start段为0
  163.     ldr    r1, _bss_end        /* stop here */
  164.     mov    r2, #0x00000000        /* clear */

  165. clbss_l:str    r2, [r0]        /* clear loop... */
  166.     add    r0, r0, #4
  167.     cmp    r0, r1
  168.     ble    clbss_l

  169.     ldr    pc, _start_armboot //然后跳转到_start_armboot

  170. _start_armboot:    .word start_armboot //lib_arm中board.c 程序中开始执行start_armboot函数 即传说中的stage2


  171. /*
  172.  *************************************************************************
  173.  *
  174.  * CPU_init_critical registers
  175.  *
  176.  * setup important registers
  177.  * setup memory timing
  178.  *
  179.  *************************************************************************
  180.  */


  181. #ifndef CONFIG_SKIP_LOWLEVEL_INIT //初始化关键寄存器
  182. cpu_init_crit:
  183.     /*
  184.      * flush v4 I/D caches
  185.      */
  186.     mov    r0, #0
  187.     mcr    p15, 0, r0, c7, c7, 0    /* flush v3/v4 cache */
  188.     mcr    p15, 0, r0, c8, c7, 0    /* flush v4 TLB */ //初始化cache和快表

  189.     /*
  190.      * disable MMU stuff and caches
  191.      */ //关闭MMU全部使用物理地址
  192.     mrc    p15, 0, r0, c1, c0, 0
  193.     bic    r0, r0, #0x00002300    @ clear bits 13, 9:(--V- --RS)
  194.     bic    r0, r0, #0x00000087    @ clear bits 7, 2:(B--- -CAM)
  195.     orr    r0, r0, #0x00000002    @ set bit 2 (A) Align
  196.     orr    r0, r0, #0x00001000    @ set bit 12 (I) I-Cache
  197.     mcr    p15, 0, r0, c1, c0, 0

  198.     /*
  199.      * before relocating, we have to setup RAM timing
  200.      * because memory timing is board-dependend, you will
  201.      * find a lowlevel_init.in your board directory.
  202.      */
  203.     mov    ip, lr

  204.     bl    lowlevel_init //跳转到board中的lowlevel_init.S中执行,进行SDARM的配置

  205.     mov    lr, ip
  206.     mov    pc, lr
  207. #endif /* CONFIG_SKIP_LOWLEVEL_INIT */

  208. /*
  209.  *************************************************************************
  210.  *
  211.  * Interrupt handling
  212.  *
  213.  *************************************************************************
  214.  */

  215. @
  216. @ IRQ stack frame.
  217. @
  218. #define S_FRAME_SIZE    72

  219. #define S_OLD_R0    68
  220. #define S_PSR        64
  221. #define S_PC        60
  222. #define S_LR        56
  223. #define S_SP        52

  224. #define S_IP        48
  225. #define S_FP        44
  226. #define S_R10        40
  227. #define S_R9        36
  228. #define S_R8        32
  229. #define S_R7        28
  230. #define S_R6        24
  231. #define S_R5        20
  232. #define S_R4        16
  233. #define S_R3        12
  234. #define S_R2        8
  235. #define S_R1        4
  236. #define S_R0        0

  237. #define MODE_SVC 0x13
  238. #define I_BIT     0x80

  239. /*
  240.  * use bad_save_user_regs for abort/prefetch/undef/swi ...
  241.  * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
  242.  */

  243.     .macro    bad_save_user_regs
  244.     sub    sp, sp, #S_FRAME_SIZE
  245.     stmia    sp, {r0 - r12}            @ Calling r0-r12
  246.     ldr    r2, _armboot_start
  247.     sub    r2, r2, #(CONFIG_STACKSIZE)
  248.     sub    r2, r2, #(CONFIG_SYS_MALLOC_LEN)
  249.     sub    r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
  250.     ldmia    r2, {r2 - r3}            @ get pc, cpsr
  251.     add    r0, sp, #S_FRAME_SIZE        @ restore sp_SVC

  252.     add    r5, sp, #S_SP
  253.     mov    r1, lr
  254.     stmia    r5, {r0 - r3}            @ save sp_SVC, lr_SVC, pc, cpsr
  255.     mov    r0, sp
  256.     .endm

  257.     .macro    irq_save_user_regs
  258.     sub    sp, sp, #S_FRAME_SIZE
  259.     stmia    sp, {r0 - r12}            @ Calling r0-r12
  260.     add r7, sp, #S_PC
  261.     stmdb r7, {sp, lr}^ @ Calling SP, LR
  262.     str lr, [r7, #0] @ Save calling PC
  263.     mrs r6, spsr
  264.     str r6, [r7, #4] @ Save CPSR
  265.     str r0, [r7, #8] @ Save OLD_R0
  266.     mov    r0, sp
  267.     .endm

  268.     .macro    irq_restore_user_regs
  269.     ldmia    sp, {r0 - lr}^            @ Calling r0 - lr
  270.     mov    r0, r0
  271.     ldr    lr, [sp, #S_PC]            @ Get PC
  272.     add    sp, sp, #S_FRAME_SIZE
  273.     subs    pc, lr, #4            @ return & move spsr_svc into cpsr
  274.     .endm

  275.     .macro get_bad_stack
  276.     ldr    r13, _armboot_start        @ setup our mode stack
  277.     sub    r13, r13, #(CONFIG_STACKSIZE)
  278.     sub    r13, r13, #(CONFIG_SYS_MALLOC_LEN)
  279.     sub    r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack

  280.     str    lr, [r13]            @ save caller lr / spsr
  281.     mrs    lr, spsr
  282.     str lr, [r13, #4]

  283.     mov    r13, #MODE_SVC            @ prepare SVC-Mode
  284.     @ msr    spsr_c, r13
  285.     msr    spsr, r13
  286.     mov    lr, pc
  287.     movs    pc, lr
  288.     .endm

  289.     .macro get_irq_stack            @ setup IRQ stack
  290.     ldr    sp, IRQ_STACK_START
  291.     .endm

  292.     .macro get_fiq_stack            @ setup FIQ stack
  293.     ldr    sp, FIQ_STACK_START
  294.     .endm

  295. /*
  296.  * exception handlers
  297.  */
  298.     .align 5
  299. undefined_instruction:
  300.     get_bad_stack
  301.     bad_save_user_regs
  302.     bl    do_undefined_instruction

  303.     .align    5
  304. software_interrupt:
  305.     get_bad_stack
  306.     bad_save_user_regs
  307.     bl    do_software_interrupt

  308.     .align    5
  309. prefetch_abort:
  310.     get_bad_stack
  311.     bad_save_user_regs
  312.     bl    do_prefetch_abort

  313.     .align    5
  314. data_abort:
  315.     get_bad_stack
  316.     bad_save_user_regs
  317.     bl    do_data_abort

  318.     .align    5
  319. not_used:
  320.     get_bad_stack
  321.     bad_save_user_regs
  322.     bl    do_not_used

  323. #ifdef CONFIG_USE_IRQ

  324.     .align    5
  325. irq:
  326.     get_irq_stack
  327.     irq_save_user_regs
  328.     bl    do_irq
  329.     irq_restore_user_regs

  330.     .align    5
  331. fiq:
  332.     get_fiq_stack
  333.     /* someone ought to write a more effiction fiq_save_user_regs */
  334.     irq_save_user_regs
  335.     bl    do_fiq
  336.     irq_restore_user_regs

  337. #else

  338.     .align    5
  339. irq:
  340.     get_bad_stack
  341.     bad_save_user_regs
  342.     bl    do_irq

  343.     .align    5
  344. fiq:
  345.     get_bad_stack
  346.     bad_save_user_regs
  347.     bl    do_fiq

  348. #endif
0 0
原创粉丝点击