Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6478721
  • 博文数量: 579
  • 博客积分: 1548
  • 博客等级: 上尉
  • 技术积分: 16635
  • 用 户 组: 普通用户
  • 注册时间: 2012-12-12 15:29
个人简介

http://www.csdn.net/ http://www.arm.com/zh/ https://www.kernel.org/ http://www.linuxpk.com/ http://www.51develop.net/ http://linux.chinaitlab.com/ http://www.embeddedlinux.org.cn http://bbs.pediy.com/

文章分类

全部博文(579)

文章存档

2018年(18)

2015年(91)

2014年(159)

2013年(231)

2012年(80)

分类: 嵌入式

2014-01-19 16:21:25

操作系统:ubuntu10.04


前言:
    在上一章节中,详细分析了uboot中的顶级makefile,了解了uboot的编译流程,在本章节中,将要详细分析的是uboot 的执行流程。
而uboot的第一条执行,是在 start.S 的。


一,start.S的详细分析。
点击(此处)折叠或打开
  1. /*
  2.  * armboot - Startup Code for ARM920 CPU-core
  3.  *
  4.  * Copyright (c) 2001    Marius Gr鰃er
  5.  * Copyright (c) 2002    Alex Z黳ke
  6.  * Copyright (c) 2002    Gary Jennejohn
  7.  *
  8.  * See file CREDITS for list of people who contributed to this
  9.  * project.
  10.  *
  11.  * This program is free software; you can redistribute it and/or
  12.  * modify it under the terms of the GNU General Public License as
  13.  * published by the Free Software Foundation; either version 2 of
  14.  * the License, or (at your option) any later version.
  15.  *
  16.  * This program is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19.  * GNU General Public License for more details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with this program; if not, write to the Free Software
  23.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  24.  * MA 02111-1307 USA
  25.  */


  26. #include <config.h>            /* ./include/config.h    */
  27. #include <version.h>        /* ./include/version.h     */


  28. /*
  29.  *************************************************************************
  30.  *
  31.  * Jump vector table as in table 3.1 in [1]
  32.  *
  33.  *************************************************************************
  34.  */

  35. /*
  36. global声明一个符号可被其他文档引用,相当于声明了一个全局变量,.globl和.global相同。
  37. 详情请看:http://blog.chinaunix.net/uid-28458801-id-3554759.html

  38.  _start就是整个start.S的最开始,即整个uboot的代码的开始。
  39.  _start后面加上一个冎号’:’,表示其是一个标号Label,类似亍C诧言goto后面的标号。
  40. 而同时,_start的值,也就是返个代码的位置了,此处即为代码的最开始,相对的0的位置。

  41. b reset :表示跳转到 reset 执行,并且不返回

  42. ldr: LDR伪指令-----大范围的地址读取
  43. 详情请看:1,http://blog.chinaunix.net/uid-28458801-id-3753775.html
  44.         2,http://blog.chinaunix.net/uid-28458801-id-3753657.html
  45.         
  46. .word .word expr {,expr}… 分配一段字内存单元,幵用expr初始化字内存单元(32bit)
  47. 以_undefined_instruction为例,就是,此处分配了一个word=32bit=4字节
  48. 的地址空间,里面存放的值是undefined_instruction。
  49. 而此处_undefined_instruction也就是该地址空间的地址了。用C诧言来表达就是:
  50. _undefined_instruction = &undefined_instruction。
  51. 在后面的代码,我们可以看到,undefined_instruction也是一个标号,即一个地址值,对应着
  52. 就是在发生“未定义指令”的时候,系统所要去执行的代码。
  53. 所以:
  54. ldr pc, 标号1
  55. 。。。
  56. 标号1:.word 标号2
  57. 标号2:
  58.     。。。(具体要执行的代码)
  59. 的意思就是,将地址为标号1中内容载入到pc,而地址为标号1中的内容,正好装的是标号2。
  60. 用C诧言表达其实很简单:
  61. PC = *(标号1) = 标号2
  62. 对PC赋值,即是实现代码跳转,所以整个返段汇编代码的意思就是:
  63. 跳转到标号2的位置,执行对应的代码。

  64. .balignl 16,0xdeadbeef 意思就是,接下来的代码,都要16字节对齐,不足之处,用0xdeadbeef填充。
  65. */
  66. .globl _start
  67. _start:    b reset
  68.     ldr    pc, _undefined_instruction
  69.     ldr    pc, _software_interrupt
  70.     ldr    pc, _prefetch_abort
  71.     ldr    pc, _data_abort
  72.     ldr    pc, _not_used
  73.     ldr    pc, _irq
  74.     ldr    pc, _fiq

  75. _undefined_instruction:    .word undefined_instruction
  76. _software_interrupt:    .word software_interrupt
  77. _prefetch_abort:    .word prefetch_abort
  78. _data_abort:        .word data_abort
  79. _not_used:        .word not_used
  80. _irq:            .word irq
  81. _fiq:            .word fiq

  82.     .balignl 16,0xdeadbeef


  83. /*
  84.  *************************************************************************
  85.  *
  86.  * Startup Code (reset vector)
  87.  *
  88.  * do important init only if we don't start from memory!
  89.  * relocate armboot to ram
  90.  * setup stack
  91.  * jump to second stage
  92.  *
  93.  *************************************************************************
  94.  */
  95. /*
  96. _TEXT_BASE是一个标号地址,此地址中是一个word类型的变量,变量名是TEXT_BASE,代码的基地址.
  97. TEXT_BASE 定义在 \board\xx\config.mk,假设为 TEXT_BASE = 0x33D00000

  98. *(_armboot_start) = _start
  99. */
  100. _TEXT_BASE:
  101.     .word    TEXT_BASE

  102. .globl _armboot_start
  103. _armboot_start:
  104.     .word _start

  105. /*
  106.  * These are defined in the board-specific linker script.
  107.  */
  108.  /*
  109.  _bss_start和_bss_end都叧是两个标号,对应着此处的地址。
  110. 而两个地址里面分别存放的值是__bss_start和_end,这两个的值,定义在 \board\xx\u-boot.lds 中。
  111. 而关亍_bss_start和_bss_end定义为.glogl即全局变量,是因为uboot的其他源码中要用到这两个变量。

  112. FREE_RAM_END和FREE_RAM_SIZE,PreLoadedONRAM,IRQ_STACK_START,FIQ_STACK_START,之所以也是声明为全局变量,
  113. 是因为uboot的源码中会用到这些变量。
  114.  */
  115. .globl _bss_start
  116. _bss_start:
  117.     .word __bss_start

  118. .globl _bss_end
  119. _bss_end:
  120.     .word _end

  121. .globl FREE_RAM_END
  122. FREE_RAM_END:
  123.     .word    0x0badc0de

  124. .globl FREE_RAM_SIZE
  125. FREE_RAM_SIZE:
  126.     .word    0x0badc0de

  127. .globl PreLoadedONRAM
  128. PreLoadedONRAM:
  129.     .word    0

  130. #ifdef CONFIG_USE_IRQ
  131. /* IRQ stack memory (calculated at run-time) */
  132. .globl IRQ_STACK_START
  133. IRQ_STACK_START:
  134.     .word    0x0badc0de

  135. /* IRQ stack memory (calculated at run-time) */
  136. .globl FIQ_STACK_START
  137. FIQ_STACK_START:
  138.     .word 0x0badc0de
  139. #endif


  140. /*
  141.  * the actual reset code
  142.  */
  143. /*
  144. 对 mrs 和msr 有疑问的请看:http://blog.chinaunix.net/uid-28458801-id-4083956.html
  145. */
  146. reset:
  147.     /*
  148.      * set the cpu to SVC32 mode.设置cpu为 SVC模式。
  149.      * 如果对arm的个模式有疑问的请看:1,http://blog.chinaunix.net/uid-28458801-id-3788554.html
  150.      *     2,http://blog.chinaunix.net/uid-28458801-id-3494646.html
  151.      */

  152.     mrs    r0,cpsr                    /* 传送CPSR的内容到R0 */
  153.     bic    r0,r0,#0x1f                /* 清除r0的bit[4:0]位 */
  154.     orr    r0,r0,#0xd3                /* 把r0的bit[7:6]和bit[4]和bit[2:0]置为1 */
  155.     msr    cpsr,r0                    /* 将r0的值赋给CPSR */

  156. /* turn off the watchdog */
  157. #if defined(CONFIG_S3C2400)
  158. # define pWTCON        0x15300000
  159. # define INTMSK        0x14400008    /* Interupt-Controller base addresses */
  160. # define CLKDIVN    0x14800014    /* clock divisor register */
  161. #elif defined(CONFIG_S3C2410)
  162. # define pWTCON        0x53000000
  163. # define INTMOD 0X4A000004
  164. # define INTMSK        0x4A000008    /* Interupt-Controller base addresses */
  165. # define INTSUBMSK    0x4A00001C
  166. # define CLKDIVN    0x4C000014    /* clock divisor register */
  167. #endif


  168. /*
  169. 以上是看门狗的相关寄存器的地址。

  170. 对 ldr伪指令 有疑惑的请看:http://blog.chinaunix.net/uid-28458801-id-4084264.html

  171. 先是用r0寄存器存pWTCON的值,然后r1=0,再将r1中的0写入到pWTCON寄存器中,其实就是
  172. *((int *)pWTCON) = 0;
  173. */
  174. #if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
  175.     ldr r0, =pWTCON            /* 宏pWTCON的值赋值给r0寄存器 */
  176.     mov r1, #0x0
  177.     str r1, [r0]

  178.     /*
  179.      * mask all IRQs by setting all bits in the INTMR - default
  180.      * 关闭所有中断。
  181.      * INTMSK寄存器设置为0xffffffff
  182.      */
  183.     mov    r1, #0xffffffff
  184.     ldr    r0, =INTMSK
  185.     str    r1, [r0]
  186. /* 将INTSUBMSK寄存器的值设置为0x3ff。*/
  187. # if defined(CONFIG_S3C2410)
  188.     ldr    r1, =0x3ff
  189.     ldr    r0, =INTSUBMSK
  190.     str    r1, [r0]
  191. # endif

  192. #if 0        /* 不编译*/
  193.     /* FCLK:HCLK:PCLK = 1:2:4 */
  194.     /* default FCLK is 120 MHz ! */
  195.     ldr    r0, =CLKDIVN
  196.     mov    r1, #3
  197.     str    r1, [r0]
  198. #endif
  199. #endif    /* CONFIG_S3C2400 || CONFIG_S3C2410 */

  200.     /*
  201.      * we do sys-critical inits only at reboot,
  202.      * not when booting from ram!
  203.      */
  204.      /*
  205.      ADR伪指令--- 小范围的地址读取
  206.      */
  207.     
  208. #ifndef CONFIG_SKIP_LOWLEVEL_INIT
  209.     adr    r0, _start        /* r0 <- current position of code ,将_start的地址赋值给r0 */
  210.     ldr    r1, _TEXT_BASE    /* test if we run from flash or RAM*/
  211.     cmp r0, r1     /* don't reloc during debug , 比较r0和r1是否相等 */
  212.     blne    cpu_init_crit    /* 如果r0和r1不相等,则执行 cpu_init_crit*/
  213. #endif

  214.     /* Set up the stack                        
  215.     CFG_MALLOC_LEN,CFG_GBL_DATA_SIZE 定义在\include\configs\xx.h
  216.     
  217.     #define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024)
  218.     #define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */

  219.     #define CFG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
  220.     
  221.     #define CONFIG_STACKSIZE_IRQ    (4*1024)    /* IRQ stack */
  222.     #define CONFIG_STACKSIZE_FIQ    (4*1024)    /* FIQ stack */
  223.     
  224.     */
  225. stack_setup:
  226.     ldr    r0, _TEXT_BASE        /* upper 128 KiB: relocated uboot ,地址为_TEXT_BASE的内存中的内容给r0 */
  227.     sub    r0, r0, #CFG_MALLOC_LEN    /* malloc area ,256 kb */
  228.     sub    r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo ,128 byte */
  229.     
  230. /* cpu/arm920t/cpu.c 中的 cpu_init 中真正的为 IRQ,FIQ模式划分了栈*/
  231. #ifdef CONFIG_USE_IRQ
  232.     sub    r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)        /* 4kb + 4kb*/
  233. #endif
  234.     sub    sp, r0, #12        /* leave 3 words for abort-stack ,12 byte */

  235. #ifndef CONFIG_SKIP_LOWLEVEL_INIT
  236.     bl clock_init        /* 初始化系统时钟*/
  237. #endif

  238. #ifndef CONFIG_SKIP_RELOCATE_UBOOT
  239. relocate:                /* relocate U-Boot to RAM     */
  240.     adr    r0, _start        /* r0 <- current position of code */
  241.     ldr    r1, _TEXT_BASE        /* test if we run from flash or RAM */
  242.     cmp r0, r1 /* don't reloc during debug */
  243.     beq clear_bss
  244.     
  245.     ldr    r2, _armboot_start    /* _start */
  246.     ldr    r3, _bss_start
  247.     sub    r2, r3, r2        /* r2 <- size of armboot */
  248. #if 1
  249.     bl CopyCode2Ram    /* r0: source, r1: dest, r2: size */
  250. #else
  251.     add    r2, r0, r2        /* r2 <- source end address */

  252. copy_loop:
  253.     ldmia     {r3-r10}        /* copy from source address [r0] */
  254.     stmia     {r3-r10}        /* copy to target address [r1] */
  255.     cmp    r0, r2            /* until source end addreee [r2] */
  256.     ble    copy_loop
  257. #endif
  258. #endif    /* CONFIG_SKIP_RELOCATE_UBOOT */

  259. /* 清除 bss 段*/
  260. clear_bss:
  261.     ldr    r0, _bss_start        /* find start of bss segment */
  262.     ldr    r1, _bss_end        /* stop here */
  263.     mov     r2, #0x00000000        /* clear */

  264. clbss_l:str    r2, [r0]        /* clear loop... */
  265.     add    r0, r0, #4
  266.     cmp    r0, r1
  267.     ble    clbss_l

  268. SetLoadFlag:
  269.     /* Set a global flag, PreLoadedONRAM */
  270.     adr    r0, _start        /* r0 <- current position of code */
  271.     ldr    r1, _TEXT_BASE        /* test if we run from flash or RAM */
  272.     cmp r0, r1 /* don't reloc during debug */
  273.     ldr r2, =PreLoadedONRAM
  274.     mov r3, #1
  275.     streq r3, [r2]

  276. #if 0    /* 不编译*/
  277.     /* try doing this stuff after the relocation */
  278.     ldr r0, =pWTCON
  279.     mov r1, #0x0
  280.     str r1, [r0]

  281.     /*
  282.      * mask all IRQs by setting all bits in the INTMR - default
  283.      */
  284.     mov    r1, #0xffffffff
  285.     ldr    r0, =INTMR
  286.     str    r1, [r0]

  287.     /* FCLK:HCLK:PCLK = 1:2:4 */
  288.     /* default FCLK is 120 MHz ! */
  289.     ldr    r0, =CLKDIVN
  290.     mov    r1, #3
  291.     str    r1, [r0]
  292.     /* END stuff after relocation */
  293. #endif

  294.     ldr    pc, _start_armboot

  295. _start_armboot:    .word start_armboot        /* 进入c函数阶段 ./lib_arm/board.c */


  296. /*
  297.  *************************************************************************
  298.  *
  299.  * CPU_init_critical registers
  300.  *
  301.  * setup important registers
  302.  * setup memory timing
  303.  *
  304.  *************************************************************************
  305.  */


  306. #ifndef CONFIG_SKIP_LOWLEVEL_INIT
  307. cpu_init_crit:
  308.     /*
  309.      * flush v4 I/D caches
  310.      */
  311.     mov    r0, #0
  312.     mcr    p15, 0, r0, c7, c7, 0    /* flush v3/v4 cache */
  313.     mcr    p15, 0, r0, c8, c7, 0    /* flush v4 TLB */

  314.     /*
  315.      * disable MMU stuff and caches
  316.      */
  317.     mrc    p15, 0, r0, c1, c0, 0
  318.     bic    r0, r0, #0x00002300    @ clear bits 13, 9:8 (--V- --RS)
  319.     bic    r0, r0, #0x00000087    @ clear bits 7, 2:0 (B--- -CAM)
  320.     orr    r0, r0, #0x00000002    @ set bit 2 (A) Align
  321.     orr    r0, r0, #0x00001000    @ set bit 12 (I) I-Cache
  322.     mcr    p15, 0, r0, c1, c0, 0

  323.     /*
  324.      * before relocating, we have to setup RAM timing
  325.      * because memory timing is board-dependend, you will
  326.      * find a lowlevel_init.S in your board directory.
  327.      */
  328.     mov    ip, lr
  329.     bl    lowlevel_init        /* 设置存储控制器,使得外接的sdram可用*/
  330.     mov    lr, ip
  331.     mov    pc, lr
  332. #endif /* CONFIG_SKIP_LOWLEVEL_INIT */

  333. /*
  334.  *************************************************************************
  335.  *
  336.  * Interrupt handling
  337.  *
  338.  *************************************************************************
  339.  */

  340. @
  341. @ IRQ stack frame.
  342. @
  343. #define S_FRAME_SIZE    72

  344. #define S_OLD_R0    68
  345. #define S_PSR        64
  346. #define S_PC        60
  347. #define S_LR        56
  348. #define S_SP        52

  349. #define S_IP        48
  350. #define S_FP        44
  351. #define S_R10        40
  352. #define S_R9        36
  353. #define S_R8        32
  354. #define S_R7        28
  355. #define S_R6        24
  356. #define S_R5        20
  357. #define S_R4        16
  358. #define S_R3        12
  359. #define S_R2        8
  360. #define S_R1        4
  361. #define S_R0        0

  362. #define MODE_SVC 0x13
  363. #define I_BIT     0x80

  364. /*
  365.  * use bad_save_user_regs for abort/prefetch/undef/swi ...
  366.  * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
  367.  */

  368.     .macro    bad_save_user_regs
  369.     sub    sp, sp, #S_FRAME_SIZE
  370.     stmia    sp, {r0 - r12}            @ Calling r0-r12
  371.     ldr    r2, _armboot_start
  372.     sub    r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
  373.     sub    r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
  374.     ldmia    r2, {r2 - r3}            @ get pc, cpsr
  375.     add    r0, sp, #S_FRAME_SIZE        @ restore sp_SVC

  376.     add    r5, sp, #S_SP
  377.     mov    r1, lr
  378.     stmia    r5, {r0 - r3}            @ save sp_SVC, lr_SVC, pc, cpsr
  379.     mov    r0, sp
  380.     .endm

  381.     .macro    irq_save_user_regs
  382.     sub    sp, sp, #S_FRAME_SIZE
  383.     stmia    sp, {r0 - r12}            @ Calling r0-r12
  384.     add r8, sp, #S_PC
  385.     stmdb r8, {sp, lr}^ @ Calling SP, LR
  386.     str lr, [r8, #0] @ Save calling PC
  387.     mrs r6, spsr
  388.     str r6, [r8, #4] @ Save CPSR
  389.     str r0, [r8, #8] @ Save OLD_R0
  390.     mov    r0, sp
  391.     .endm

  392.     .macro    irq_restore_user_regs
  393.     ldmia    sp, {r0 - lr}^            @ Calling r0 - lr
  394.     mov    r0, r0
  395.     ldr    lr, [sp, #S_PC]            @ Get PC
  396.     add    sp, sp, #S_FRAME_SIZE
  397.     subs    pc, lr, #4            @ return & move spsr_svc into cpsr
  398.     .endm

  399.     .macro get_bad_stack
  400.     ldr    r13, _armboot_start        @ setup our mode stack
  401.     sub    r13, r13, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
  402.     sub    r13, r13, #(CFG_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack

  403.     str    lr, [r13]            @ save caller lr / spsr
  404.     mrs    lr, spsr
  405.     str lr, [r13, #4]

  406.     mov    r13, #MODE_SVC            @ prepare SVC-Mode
  407.     @ msr    spsr_c, r13
  408.     msr    spsr, r13
  409.     mov    lr, pc
  410.     movs    pc, lr
  411.     .endm

  412.     .macro get_irq_stack            @ setup IRQ stack
  413.     ldr    sp, IRQ_STACK_START
  414.     .endm

  415.     .macro get_fiq_stack            @ setup FIQ stack
  416.     ldr    sp, FIQ_STACK_START
  417.     .endm

  418. /*
  419.  * exception handlers
  420.  */
  421.     .align 5
  422. undefined_instruction:
  423.     get_bad_stack
  424.     bad_save_user_regs
  425.     bl     do_undefined_instruction

  426.     .align    5
  427. software_interrupt:
  428.     get_bad_stack
  429.     bad_save_user_regs
  430.     bl     do_software_interrupt

  431.     .align    5
  432. prefetch_abort:
  433.     get_bad_stack
  434.     bad_save_user_regs
  435.     bl     do_prefetch_abort

  436.     .align    5
  437. data_abort:
  438.     get_bad_stack
  439.     bad_save_user_regs
  440.     bl     do_data_abort

  441.     .align    5
  442. not_used:
  443.     get_bad_stack
  444.     bad_save_user_regs
  445.     bl     do_not_used

  446. @ thisway.diy, 2006.06.24
  447. .globl Launch
  448.     .align    4
  449. Launch:
  450.     mov r7, r0
  451.     @ diable interrupt
  452.     @ disable watch dog timer
  453.     mov    r1, #0x53000000
  454.     mov    r2, #0x0
  455.     str    r2, [r1]

  456.     ldr r1,=INTMSK
  457.     ldr r2,=0xffffffff @ all interrupt disable
  458.     str r2,[r1]

  459.     ldr r1,=INTSUBMSK
  460.     ldr r2,=0x7ff @ all sub interrupt disable
  461.     str r2,[r1]

  462.     ldr r1, = INTMOD
  463.     mov r2, #0x0 @ set all interrupt as IRQ (not FIQ)
  464.     str r2, [r1]

  465.     @
  466.     mov    ip, #0
  467.     mcr    p15, 0, ip, c13, c0, 0 @    /* zero PID */
  468.     mcr    p15, 0, ip, c7, c7, 0 @    /* invalidate I,D caches */
  469.     mcr    p15, 0, ip, c7, c10, 4 @    /* drain write buffer */
  470.     mcr    p15, 0, ip, c8, c7, 0 @    /* invalidate I,D TLBs */
  471.     mrc    p15, 0, ip, c1, c0, 0 @    /* get control register */
  472.     bic    ip, ip, #0x0001 @    /* disable MMU */
  473.     mcr    p15, 0, ip, c1, c0, 0 @    /* write control register */

  474.     @ MMU_EnableICache
  475.     @mrc p15,0,r1,c1,c0,0
  476.     @orr r1,r1,#(1<<12)
  477.     @mcr p15,0,r1,c1,c0,0

  478.     @ clear SDRAM: the end of free mem(has wince on it now) to the end of SDRAM
  479.     ldr r3, FREE_RAM_END
  480.     ldr r4, =PHYS_SDRAM_1+PHYS_SDRAM_1_SIZE @ must clear all the memory unused to zero
  481.     mov r5, #0

  482.     ldr r1, _armboot_start
  483.     ldr r2, =On_Steppingstone
  484.     sub r2, r2, r1
  485.     mov pc, r2
  486. On_Steppingstone:
  487. 2: stmia {r5}
  488.     cmp r3, r4
  489.     bne 2b

  490.     @ set sp = 0 on sys mode
  491.     mov sp, #0

  492.     @ add by thisway.diy 2006.06.26, switch to SVC mode
  493.     msr    cpsr_c,    #0xdf    @ set the I-bit = 1, diable the IRQ interrupt
  494.     msr    cpsr_c,    #0xd3    @ set the I-bit = 1, diable the IRQ interrupt
  495.     ldr sp, =0x31ff5800    
  496.     
  497.     nop
  498.     nop
  499.     nop
  500.     nop

  501.     mov pc, r7 @ Jump to PhysicalAddress
  502.     nop
  503.     mov pc, lr

  504. #ifdef CONFIG_USE_IRQ

  505.     .align    5
  506. irq:
  507. /* add by to use IRQ for USB and DMA */
  508.     sub    lr, lr, #4             @ the return address
  509.     ldr    sp, IRQ_STACK_START     @ the stack for irq
  510.     stmdb         { r0-r12,lr }    @ save registers
  511.     
  512.     ldr    lr,    =int_return         @ set the return addr
  513.     ldr    pc, =IRQ_Handle         @ call the isr
  514. int_return:
  515.     ldmia         { r0-r12,pc }^    @ return from interrupt

  516.     .align    5
  517. fiq:
  518.     get_fiq_stack
  519.     /* someone ought to write a more effiction fiq_save_user_regs */
  520.     irq_save_user_regs
  521.     bl     do_fiq
  522.     irq_restore_user_regs

  523. #else

  524.     .align    5
  525. irq:
  526.     get_bad_stack
  527.     bad_save_user_regs
  528.     bl     do_irq

  529.     .align    5
  530. fiq:
  531.     get_bad_stack
  532.     bad_save_user_regs
  533.     bl     do_fiq

  534. #endif
最后得到的内存分别如下:





二,my_uboot的实现思路
    根据以上分析,总结了my_uboot的实现思路:
(1)设置 CPU 模式
(2)关闭看门狗
(3)关闭中断
(4)设置堆栈 sp 指针
(5)清除 bss 段
(6)异常中断处理
(7)跳转到 start_armboot 函数中执行。

(1)设置 CPU 模式
总的来说,就是将 CPU 设置为 SVC 模式。

(2)关闭看门狗
就是去设置对应的寄存器,将看门狗关闭。

(3)关闭中断
关闭中断,也是去设置对应的寄存器,即可。

(4)设置堆栈 sp 指针
设置堆栈以便 C 程序执行。

(5)清除 bss 段
此处很简单,就是将对应 bss 段,都设置为,0,即清零。
其对应的地址空间,就是那些未初始化的全局变量的地址。

(6)异常中断处理
异常中断处理,就是实现对应的常见的那些处理中断的部分内容。
说白了就是实现一个个中断凼数。 uboot在初始化的时候,主要目的叧是为了初始化系统,及引
导系统,所以,此处的中断处理部分的代码,往往相对比较简单,丌是很复杂

(7)跳转到 start_armboot 函数中执行
前面的6个操作都是汇编语言实现的,开发难度高,移植性低,
因此在实现uboot的真正的引导linux内核的实现,还是由C语言来实现。
在此,初步的思路是:1,初始化。2,串口,以便调试。3,实现linux内核的引导。




三,疑问
在这实现中,有个很重要的疑问:通过什么方式来烧写uboot,linux内核,文件系统程序。
初步设想:通过 SEGGER的 J-Flash ARM 程序,把编译好的需要的3个文件烧写到Flash中对于的位置。
如果这个设想不通过,则需要在my_uboot中添加uboot的一下命令的实现。





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