4.分析Makefile第一个文件start.S

引言:start.S是Makefile编译运行的第一个文件,它做了如下工作:

1.首先跳到reset 

2.设置为管理模式

3.关看门狗

4.关中断

5.如果SDRAM没有初始化,就cpu初始化,这里跳到cpu_init_crit

6.设置存储器

7.初始化栈(为了使用c库)Set up the stack

8._TEXT_BASE=0x33F80000  设置链接地址

9.初始化时钟

10.重定位(把flash的代码重定位到SDRAM的链接地址上去)relocate U-Boot to RAM

11.清bss,所谓bss,就是初始值为0或没有赋值的静态变量或全局变量,清除,免得浪费空间,,在u-boot.lds有bss   第1-11点为u-boot的硬件初始化,为第一阶段

12.调用c函数start_armboot,这里实现u-boot更复杂的功能,为第二阶段,实现如串口,flash读写擦除,网卡,启动内核等功能

代码如下:(按1-12顺序跳读)

  1. include

  2. #include

  3.  

  4. .globl _start   

  5. _start:    b       reset         //1.首先跳到reset  --85行

  6.     ldr    pc, _undefined_instruction

  7.     ldr    pc, _software_interrupt

  8.     ldr    pc, _prefetch_abort

  9.     ldr    pc, _data_abort

  10.     ldr    pc, _not_used

  11.     ldr    pc, _irq

  12.     ldr    pc, _fiq

  13.  

  14. _undefined_instruction:    .word undefined_instruction

  15. _software_interrupt:    .word software_interrupt

  16. _prefetch_abort:    .word prefetch_abort

  17. _data_abort:        .word data_abort

  18. _not_used:        .word not_used

  19. _irq:            .word irq

  20. _fiq:            .word fiq

  21.  

  22.     .balignl 16,0xdeadbeef

  23.  

  24.  

  25. /*

  26. *************************************************************************

  27. *

  28. * Startup Code (reset vector)

  29. *

  30. * do important init only if we don't start from memory!

  31. * relocate armboot to ram

  32. * setup stack

  33. * jump to second stage

  34. *

  35. *************************************************************************

  36. */

  37.  

  38. _TEXT_BASE:

  39.     .word    TEXT_BASE

  40.  

  41. .globl _armboot_start

  42. _armboot_start:

  43.     .word _start

  44.  

  45. /*

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

  47. */

  48. .globl _bss_start

  49. _bss_start:

  50.     .word __bss_start

  51.  

  52. .globl _bss_end

  53. _bss_end:

  54.     .word _end

  55.  

  56. .globl FREE_RAM_END

  57. FREE_RAM_END:

  58.     .word    0x0badc0de

  59.  

  60. .globl FREE_RAM_SIZE

  61. FREE_RAM_SIZE:

  62.     .word    0x0badc0de

  63.  

  64. .globl PreLoadedONRAM

  65. PreLoadedONRAM:

  66.     .word    0

  67.  

  68. #ifdef CONFIG_USE_IRQ

  69. /* IRQ stack memory (calculated at run-time) */

  70. .globl IRQ_STACK_START

  71. IRQ_STACK_START:

  72.     .word    0x0badc0de

  73.  

  74. /* IRQ stack memory (calculated at run-time) */

  75. .globl FIQ_STACK_START

  76. FIQ_STACK_START:

  77.     .word 0x0badc0de

  78. #endif

  79.  

  80.  

  81. /*

  82. * the actual reset code

  83. */

  84.  

  85. reset:

  86.     /*

  87.      * set the cpu to SVC32 mode    //2.设置为管理模式

  88.      */

  89.     mrs    r0,cpsr

  90.     bic    r0,r0,#0x1f

  91.     orr    r0,r0,#0xd3

  92.     msr    cpsr,r0

  93.  

  94. /* turn off the watchdog */

  95. #if defined(CONFIG_S3C2400)

  96. # define pWTCON        0x15300000

  97. # define INTMSK        0x14400008    /* Interupt-Controller base addresses */

  98. # define CLKDIVN    0x14800014    /* clock divisor register */

  99. #elif defined(CONFIG_S3C2410)

  100. # define pWTCON        0x53000000

  101. # define INTMOD     0X4A000004

  102. # define INTMSK        0x4A000008    /* Interupt-Controller base addresses */

  103. # define INTSUBMSK    0x4A00001C

  104. # define CLKDIVN    0x4C000014    /* clock divisor register */

  105. #endif

  106.  

  107. #if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)     //3.关看门狗

  108.     ldr     r0, =pWTCON

  109.     mov     r1, #0x0

  110.     str     r1, [r0]

  111.  

  112.     /*

  113.      * mask all IRQs by setting all bits in the INTMR - default      //4.关中断

  114.      */

  115.     mov    r1, #0xffffffff

  116.     ldr    r0, =INTMSK

  117.     str    r1, [r0]

  118. # if defined(CONFIG_S3C2410)

  119.     ldr    r1, =0x3ff

  120.     ldr    r0, =INTSUBMSK

  121.     str    r1, [r0]

  122. # endif

  123.  

  124. #if 0

  125.     /* FCLK:HCLK:PCLK = 1:2:4 */

  126.     /* default FCLK is 120 MHz ! */

  127.     ldr    r0, =CLKDIVN

  128.     mov    r1, #3

  129.     str    r1, [r0]

  130. #endif

  131. #endif    /* CONFIG_S3C2400 || CONFIG_S3C2410 */

  132.  

  133.     /*

  134.      * we do sys-critical inits only at reboot,

  135.      * not when booting from ram!

  136.      */

  137. #ifndef CONFIG_SKIP_LOWLEVEL_INIT

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

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

  140.     cmp     r0, r1                  /* don't reloc during debug         */

  141.     blne    cpu_init_crit //5.如果SDRAM没有初始化,就cpu初始化,这里跳到cpu_init_crit

  142. #endif

  143.  

  144.     /* 7.初始化栈(为了使用c库)Set up the stack     8._TEXT_BASE=0x33F80000                             */4.分析Makefile第一个文件start.S_第1张图片

  145. stack_setup:

  146.     ldr    r0, _TEXT_BASE        /* upper 128 KiB: relocated uboot   */

  147.     sub    r0, r0, #CFG_MALLOC_LEN    /* malloc area                      */

  148.     sub    r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo                        */

  149.  

  150. #ifdef CONFIG_USE_IRQ

  151.     sub    r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)

  152. #endif

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

  154.  

  155. #ifndef CONFIG_SKIP_LOWLEVEL_INIT

  156.     bl clock_init       //9.初始化时钟

  157. #endif    

  158.  

  159. #ifndef CONFIG_SKIP_RELOCATE_UBOOT

  160. relocate:                /* 10.重定位(把flash的代码重定位到SDRAM的链接地址上去)relocate U-Boot to RAM        */

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

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

  163.     cmp     r0, r1                  /* don't reloc during debug         */

  164.     beq     clear_bss

  165.     

  166.     ldr    r2, _armboot_start

  167.     ldr    r3, _bss_start

  168.     sub    r2, r3, r2        /* r2 <- size of armboot            */

  169. #if 1

  170.     bl  CopyCode2Ram    /* r0: source, r1: dest, r2: size */

  171. #else

  172.     add    r2, r0, r2        /* r2 <- source end address         */

  173.  

  174. copy_loop:

  175.     ldmia    r0!, {r3-r10}        /* copy from source address [r0]    */

  176.     stmia    r1!, {r3-r10}        /* copy to   target address [r1]    */

  177.     cmp    r0, r2            /* until source end addreee [r2]    */

  178.     ble    copy_loop

  179. #endif

  180. #endif    /* CONFIG_SKIP_RELOCATE_UBOOT */

  181.  

  182. clear_bss://11.清bss,所谓bss,就是初始值为0或没有赋值的静态变量或全局变量,清除,免得浪费空间,,在u-boot.lds有bss   第1-11点为u-boot的硬件初始化,为第一阶段

  183.     ldr    r0, _bss_start        /* find start of bss segment        */

  184.     ldr    r1, _bss_end        /* stop here                        */

  185.     mov     r2, #0x00000000        /* clear                            */

  186.  

  187. clbss_l:str    r2, [r0]        /* clear loop...                    */

  188.     add    r0, r0, #4

  189.     cmp    r0, r1

  190.     ble    clbss_l

  191.  

  192. SetLoadFlag:

  193.     /* Set a global flag, PreLoadedONRAM */

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

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

  196.     cmp     r0, r1                  /* don't reloc during debug         */

  197.     ldr r2, =PreLoadedONRAM

  198.     mov r3, #1

  199.     streq r3, [r2]

  200.  

  201. #if 0

  202.     /* try doing this stuff after the relocation */

  203.     ldr     r0, =pWTCON

  204.     mov     r1, #0x0

  205.     str     r1, [r0]

  206.  

  207.     /*

  208.      * mask all IRQs by setting all bits in the INTMR - default

  209.      */

  210.     mov    r1, #0xffffffff

  211.     ldr    r0, =INTMR

  212.     str    r1, [r0]

  213.  

  214.     /* FCLK:HCLK:PCLK = 1:2:4 */

  215.     /* default FCLK is 120 MHz ! */

  216.     ldr    r0, =CLKDIVN

  217.     mov    r1, #3

  218.     str    r1, [r0]

  219.     /* END stuff after relocation */

  220. #endif

  221.  

  222.     ldr    pc, _start_armboot

  223.  

  224. _start_armboot:    .word start_armboot //12.调用c函数start_armboot,这里实现u-boot更复杂的功能,为第二阶段,实现如串口,flash读写擦除,网卡,启动内核等功能

  225.  

  226.  

  227. /*

  228. *************************************************************************

  229. *

  230. * CPU_init_critical registers

  231. *

  232. * setup important registers

  233. * setup memory timing

  234. *

  235. *************************************************************************

  236. */

  237.  

  238.  

  239. #ifndef CONFIG_SKIP_LOWLEVEL_INIT

  240. cpu_init_crit:

  241.     /*

  242.      * flush v4 I/D caches

  243.      */

  244.     mov    r0, #0

  245.     mcr    p15, 0, r0, c7, c7, 0    /* flush v3/v4 cache */

  246.     mcr    p15, 0, r0, c8, c7, 0    /* flush v4 TLB */

  247.  

  248.     /*

  249.      * disable MMU stuff and caches

  250.      */

  251.     mrc    p15, 0, r0, c1, c0, 0

  252.     bic    r0, r0, #0x00002300    @ clear bits 13, 9:8 (--V- --RS)

  253.     bic    r0, r0, #0x00000087    @ clear bits 7, 2:0 (B--- -CAM)

  254.     orr    r0, r0, #0x00000002    @ set bit 2 (A) Align

  255.     orr    r0, r0, #0x00001000    @ set bit 12 (I) I-Cache

  256.     mcr    p15, 0, r0, c1, c0, 0

  257.  

  258.     /*

  259.      * before relocating, we have to setup RAM timing

  260.      * because memory timing is board-dependend, you will

  261.      * find a lowlevel_init.S in your board directory.

  262.      */

  263.     mov    ip, lr

  264.     bl    lowlevel_init     //6.设置存储器

  265.     mov    lr, ip

  266.     mov    pc, lr

  267. #endif /* CONFIG_SKIP_LOWLEVEL_INIT */

  268.  

  269. /*

  270. *************************************************************************

  271. *

  272. * Interrupt handling

  273. *

  274. *************************************************************************

  275. */

  276.  

  277. @

  278. @ IRQ stack frame.

  279. @

  280. #define S_FRAME_SIZE    72

  281.  

  282. #define S_OLD_R0    68

  283. #define S_PSR        64

  284. #define S_PC        60

  285. #define S_LR        56

  286. #define S_SP        52

  287.  

  288. #define S_IP        48

  289. #define S_FP        44

  290. #define S_R10        40

  291. #define S_R9        36

  292. #define S_R8        32

  293. #define S_R7        28

  294. #define S_R6        24

  295. #define S_R5        20

  296. #define S_R4        16

  297. #define S_R3        12

  298. #define S_R2        8

  299. #define S_R1        4

  300. #define S_R0        0

  301.  

  302. #define MODE_SVC 0x13

  303. #define I_BIT     0x80

  304.  

  305. /*

  306. * use bad_save_user_regs for abort/prefetch/undef/swi ...

  307. * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling

  308. */

  309.  

  310.     .macro    bad_save_user_regs

  311.     sub    sp, sp, #S_FRAME_SIZE

  312.     stmia    sp, {r0 - r12}            @ Calling r0-r12

  313.     ldr    r2, _armboot_start

  314.     sub    r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)

  315.     sub    r2, r2, #(CFG_GBL_DATA_SIZE+8)  @ set base 2 words into abort stack

  316.     ldmia    r2, {r2 - r3}            @ get pc, cpsr

  317.     add    r0, sp, #S_FRAME_SIZE        @ restore sp_SVC

  318.  

  319.     add    r5, sp, #S_SP

  320.     mov    r1, lr

  321.     stmia    r5, {r0 - r3}            @ save sp_SVC, lr_SVC, pc, cpsr

  322.     mov    r0, sp

  323.     .endm

  324.  

  325.     .macro    irq_save_user_regs

  326.     sub    sp, sp, #S_FRAME_SIZE

  327.     stmia    sp, {r0 - r12}            @ Calling r0-r12

  328.     add     r8, sp, #S_PC

  329.     stmdb   r8, {sp, lr}^                   @ Calling SP, LR

  330.     str     lr, [r8, #0]                    @ Save calling PC

  331.     mrs     r6, spsr

  332.     str     r6, [r8, #4]                    @ Save CPSR

  333.     str     r0, [r8, #8]                    @ Save OLD_R0

  334.     mov    r0, sp

  335.     .endm

  336.  

  337.     .macro    irq_restore_user_regs

  338.     ldmia    sp, {r0 - lr}^            @ Calling r0 - lr

  339.     mov    r0, r0

  340.     ldr    lr, [sp, #S_PC]            @ Get PC

  341.     add    sp, sp, #S_FRAME_SIZE

  342.     subs    pc, lr, #4            @ return & move spsr_svc into cpsr

  343.     .endm

  344.  

  345.     .macro get_bad_stack

  346.     ldr    r13, _armboot_start        @ setup our mode stack

  347.     sub    r13, r13, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)

  348.     sub    r13, r13, #(CFG_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack

  349.  

  350.     str    lr, [r13]            @ save caller lr / spsr

  351.     mrs    lr, spsr

  352.     str     lr, [r13, #4]

  353.  

  354.     mov    r13, #MODE_SVC            @ prepare SVC-Mode

  355.     @ msr    spsr_c, r13

  356.     msr    spsr, r13

  357.     mov    lr, pc

  358.     movs    pc, lr

  359.     .endm

  360.  

  361.     .macro get_irq_stack            @ setup IRQ stack

  362.     ldr    sp, IRQ_STACK_START

  363.     .endm

  364.  

  365.     .macro get_fiq_stack            @ setup FIQ stack

  366.     ldr    sp, FIQ_STACK_START

  367.     .endm

  368.  

  369. /*

  370. * exception handlers

  371. */

  372.     .align  5

  373. undefined_instruction:

  374.     get_bad_stack

  375.     bad_save_user_regs

  376.     bl     do_undefined_instruction

  377.  

  378.     .align    5

  379. software_interrupt:

  380.     get_bad_stack

  381.     bad_save_user_regs

  382.     bl     do_software_interrupt

  383.  

  384.     .align    5

  385. prefetch_abort:

  386.     get_bad_stack

  387.     bad_save_user_regs

  388.     bl     do_prefetch_abort

  389.  

  390.     .align    5

  391. data_abort:

  392.     get_bad_stack

  393.     bad_save_user_regs

  394.     bl     do_data_abort

  395.  

  396.     .align    5

  397. not_used:

  398.     get_bad_stack

  399.     bad_save_user_regs

  400.     bl     do_not_used

  401.  

  402. @ thisway.diy, 2006.06.24

  403. .globl Launch

  404.     .align    4

  405. Launch:    

  406.     mov r7, r0

  407.     @ diable interrupt

  408.     @ disable watch dog timer

  409.     mov    r1, #0x53000000

  410.     mov    r2, #0x0

  411.     str    r2, [r1]

  412.  

  413.     ldr r1,=INTMSK

  414.     ldr r2,=0xffffffff  @ all interrupt disable

  415.     str r2,[r1]

  416.  

  417.     ldr r1,=INTSUBMSK

  418.     ldr r2,=0x7ff       @ all sub interrupt disable

  419.     str r2,[r1]

  420.  

  421.     ldr     r1, = INTMOD

  422.     mov r2, #0x0        @ set all interrupt as IRQ (not FIQ)

  423.     str     r2, [r1]

  424.  

  425.     @

  426.     mov    ip, #0

  427.     mcr    p15, 0, ip, c13, c0, 0      @    /* zero PID */

  428.     mcr    p15, 0, ip, c7, c7, 0       @    /* invalidate I,D caches */

  429.     mcr    p15, 0, ip, c7, c10, 4      @    /* drain write buffer */

  430.     mcr    p15, 0, ip, c8, c7, 0       @    /* invalidate I,D TLBs */

  431.     mrc    p15, 0, ip, c1, c0, 0       @    /* get control register */

  432.     bic    ip, ip, #0x0001             @    /* disable MMU */

  433.     mcr    p15, 0, ip, c1, c0, 0       @    /* write control register */

  434.  

  435.     @ MMU_EnableICache

  436.     @mrc p15,0,r1,c1,c0,0

  437.     @orr r1,r1,#(1<<12)

  438.     @mcr p15,0,r1,c1,c0,0

  439.  

  440.     @ clear SDRAM: the end of free mem(has wince on it now) to the end of SDRAM

  441.     ldr     r3, FREE_RAM_END

  442.     ldr     r4, =PHYS_SDRAM_1+PHYS_SDRAM_1_SIZE    @ must clear all the memory unused to zero

  443.     mov     r5, #0

  444.  

  445.     ldr     r1, _armboot_start

  446.     ldr     r2, =On_Steppingstone

  447.     sub     r2, r2, r1

  448.     mov     pc, r2

  449. On_Steppingstone:

  450. 2:  stmia   r3!, {r5}

  451.     cmp     r3, r4

  452.     bne     2b

  453.  

  454.     @ set sp = 0 on sys mode

  455.     mov sp, #0

  456.  

  457.     @ add by thisway.diy 2006.06.26, switch to SVC mode

  458.     msr    cpsr_c,    #0xdf    @ set the I-bit = 1, diable the IRQ interrupt

  459.     msr    cpsr_c,    #0xd3    @ set the I-bit = 1, diable the IRQ interrupt

  460.     ldr sp, =0x31ff5800    

  461.     

  462.     nop

  463.     nop

  464.     nop

  465.     nop

  466.  

  467.     mov     pc, r7  @ Jump to PhysicalAddress

  468.     nop

  469.     mov pc, lr

  470.  

  471. #ifdef CONFIG_USE_IRQ

  472.  

  473.     .align    5

  474. irq:

  475. /* add by www.100ask.net to use IRQ for USB and DMA */

  476.     sub    lr, lr, #4                    @ the return address

  477.     ldr    sp, IRQ_STACK_START            @ the stack for irq

  478.     stmdb    sp!,     { r0-r12,lr }    @ save registers

  479.     

  480.     ldr    lr,    =int_return                @ set the return addr

  481.     ldr    pc, =IRQ_Handle                @ call the isr

  482. int_return:

  483.     ldmia    sp!,     { r0-r12,pc }^    @ return from interrupt

  484.  

  485.     .align    5

  486. fiq:

  487.     get_fiq_stack

  488.     /* someone ought to write a more effiction fiq_save_user_regs */

  489.     irq_save_user_regs

  490.     bl     do_fiq

  491.     irq_restore_user_regs

  492.  

  493. #else

  494.  

  495.     .align    5

  496. irq:

  497.     get_bad_stack

  498.     bad_save_user_regs

  499.     bl     do_irq

  500.  

  501.     .align    5

  502. fiq:

  503.     get_bad_stack

  504.     bad_save_user_regs

  505.     bl     do_fiq

  506.  

  507. #endif

 

 

你可能感兴趣的:(u-boot)