zoukankan      html  css  js  c++  java
  • 嵌入式Linux引导过程之1.3——Xloader的sys_init 分类: arm-linux-Ubuntu 2013-07-22 16:28 288人阅读 评论(0) 收藏


    上一篇文章对XLOADER_ENTRY进行了分析,看到其中调用的第一个标号就是sys_init,本文就对这个标号对应的代码段进行粗略的分析,这里我也还有好多没有搞明白的,就先留着,日后慢慢明白,先把自己目前能够看明白的东西记下来。

    另外,需要说明的是,像sys_init以及后续还要讲的ddr_init之类的代码是与体系结构高度相关的,由于我的文章针对的是SPEArPlus开发板的,因此,上面提到的所有寄存器的地址以及功能说明要需要参考相应的user manual文档。
    与本文代码对应的文档是SPEArPlus 600 PRELIMINARY USER MANUAL。

    好, 下面就开始看代码。sys_init代码段位于Xloader目录下的pll/spear_pll.S代码中,该代码段的主要功能是对系统的时钟频率以及 工作方式进行初始化,并初始化外设时钟等,主要对GMAC Ethernet、UART1、UART2以及SMI(Serial Flash Controller)等外设进行了初始化。

    对代码的整个说明以注释的方式跟源文件一起贴在这里,其中还有很多不明白的地方,希望以后能够慢慢明白:

      1 /*      PRESERVE8 */
      2
      3
      4
      5 /*;----------------------------------------------------------------------------------- */
      6 /*
      7     INCLUDE include/mmu946T.s
      8     INCLUDE include/arm.equ
      9 */
     10      #include "splus_pll.h"
     11
     12
     13 #define MISC_BASE              0xFCA80000
     14 #define PHY_CTR_REG            0xA4
     15 #define PERIPHCLK_CFG           0x28
     16 #define PERIPH1_CLKEN           0x2C
     17 #define PERIPH1_RST             0x38
     18 #define AMBA_CLK_CFG            0x24
     19 #define GMAC_SYNTH_CLK          0x68
     20 #define GMAC_CTR_REG            0xA8
     21 #define PLL1_FREQ               0xa600010f
     22 #define PLL1_CNTL_REG           0x00000008
     23 #define PLL1_FRQ_REG            0x0000000C
     24
     25 #define TXCLK_SYNTH             0x00000008 /*enable synth. clock */
     26 #define PLL2_FREQ               0x8500010f 
     27 #define PLL2_CNTL_REG           0x00000014
     28 #define PLL2_FRQ_REG            0x00000018
     29
     30
     31 #define SYSCTL_BASE             0xFCA00000
     32 #define SCCTRL                  0x00000000
     33 #define SCPLLCTRL               0x00000014
     34 #define PLLTIM                  0x1FFFFFF
     35
     36 #define SMI_BASE                0xFC000000
     37 #define SMI_CR1                 0x00
     38
     39 /* CONTROL REG 1 */
     40 #define BANK_EN                 0x0000000F /* enables all banks */
     41 #define DSEL_TIME               0x00000050 /* Deselect time 5+1 SMI_CK periods */
     42 #define PRESCAL3                0x00000300 /* AHB_CK prescaling value */
     43 #define PRESCAL5                0x00000500 /* AHB_CK prescaling value */
     44 #define PRESCALA                0x00000A00 /* AHB_CK prescaling value */
     45 #define PRESCALF                0x00000F00 /* AHB_CK prescaling value */
     46 #define PRESCAL9                0x00000900 /* AHB_CK prescaling value */
     47 #define SW_MODE                 0x10000000 /* enables SW Mode */
     48 #define WB_MODE                 0x20000000 /* Write Burst Mode */
     49 #define FAST_MODE               0x00008000 /* Fast Mode */
     50
     51
     52 #define ARM1_WE                     0x00000001
     53 #define ARM1                        0x00000002
     54 #define ARM2                        0x00000004
     55 #define UART1                       0x00000008
     56 #define UART2                       0x00000010
     57 #define SSP1                        0x00000020
     58 #define SSP2                        0x00000040
     59 #define I2C                         0x00000080
     60 #define JPEG                        0x00000100
     61 #define FSMC                        0x00000200
     62 #define FIRDA                       0x00000400
     63 #define GPT4                        0x00000800
     64 #define GPT5                        0x00001000
     65 #define GPIO4                       0x00002000
     66 #define SSP3                        0x00004000
     67 #define AD                          0x00008000
     68 #define GPT3                        0x00010000
     69 #define RTC                         0x00020000
     70 #define GPIO3                       0x00040000
     71 #define DMA                         0x00080000
     72 #define ROM                         0x00100000
     73 #define SMI                         0x00200000
     74 #define CLCD                        0x00400000
     75 #define GMAC    0x00800000
     76 #define USBDEV                      0x01000000
     77 #define USBHOST1                    0x02000000
     78 #define USBHOST2                    0x04000000
     79 #define DDR_CTRL                    0x08000000
     80 #define RAM_WRAPPER                 0x10000000
     81 #define DDR_CORE                    0x20000000
     82
     83 #define PLL_MODE_NON_DITHERED_M_MASK   0xFF000000
     84 #define PLL_MODE_NON_DITHERED_M_SHIFT  24
     85 #define PLL_VALUE_M_MASK               0xFFFF0000
     86 #define PLL_VALUE_M_SHIFT              16
     87 #define PLL_VALUE_P_MASK               0x00000700
     88 #define PLL_VALUE_P_SHIFT              8
     89 #define PLL_VALUE_N_MASK               0x0000000F
     90 #define PLL_VALUE_N_SHIFT              0
     91 #define SYNTH_XMASK  0XFFFF0000
     92 #define SYNTH_YMASK  0X0000FFFF
     93
     94    
     95 /*   AREA   INIT, CODE, READONLY
     96
     97 ;-----------------------------------------------------------------------------------
     98   
     99 ; ************************************************
    100 ; *  Routine to initialize the system controller.
    101 ; ************************************************
    102 */
    103
    104
    105 .global sys_init
    106 sys_init:
    107
    108  /* SYSTEM PLL INIT */
    109
        /* 0xFC880010是WdogRIS寄存器的地址。
         * 该寄存器是一个只读的寄存器,当读出来的内容最低位为1时,
         * 表示由于看门狗计数器到达了0而引发了一次中断,否则该位为0。
         * 此处一直到114行代码断的作用是判断是否是由于看门狗引发的
         * 中断而导致了sys_init的调用,如果是,则直接跳转到
         * normal_mode标号处执行代码,而不需要对时钟进行初始化了。
         */
    110    LDR     R1, =0xFC880010
    111    LDR    R3,[R1, #0x0 ]    /* 读取WdogRIS寄存器的内容 */
    112         AND     R3,R3,#0x1    /* 只取读取内容的最低位,该位就表明了当前看门狗的状态 */
    113         CMP     R3,#0x1    /* 看看最低位是否为1,如果是,则表明此时是由看门狗引发的中断
    114         BEQ     normal_mode     * 不需要重新进行时钟初始化,直接跳转到normal_mode就行。
                     */
    115
        /* 对系统工作模式进行设定,将系统设置为SLOW模式
         * 其中,SYSCTL_BASE==0xFCA00000
         * SCCTRL==0x00000000
         */
    116 /* setting SYSCTL to SLOW mode */
    117         LDR     R1, =SYSCTL_BASE    /* System Controler registers的基地址 */
    118    LDR   R3,[R1, #SCCTRL ]    /* 读入SCCTRL寄存器的内容 */
    119    ORR   R2,R3,#0x00000002    /* 将SCCTRL寄存器的低三位设置成'b01x(x表示任意值),
                     * 当系统reset后,初始时SCCTRL的低三位为'b001。
                     * 当SCCTRL低三位的值为'b01x时,系统将被设置成SLOW模式。
                     */
    120    STR   R2,[R1, #SCCTRL]    /* 保存设置之后的值到SCCTRL寄存器 */
    121
    122 /* setting 100us pll timer */
    123    LDR    R4, =PLLTIM    /* PLLTIM==0x01FFFFFF */
    124         MOVS   R2,R4,LSL #0x3    /* 由于SCPLLCTRL寄存器的[27:3]位是保存PllTime的,
                         * 因此这里将PLLTIM左移三位,用来设置SCPLLCTRL中的PllTime。
                         */
    125         STR      R2,[R1, #SCPLLCTRL]    /* 将移位之后的PLLTIM的值保存到SCPLLCTRL寄存器 */
    126
    127 /*
    128 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    129 ; programming PLL1
    130 ;        LDR     R1,=MISC_BASE
    131 ;        LDR     R2,=PLL1_FREQ
    132 ;        STR     R2,[R1, #PLL1_FRQ_REG]
    133
    134
    135 /*      ; programming PLL1 */
    136         LDR     R1,=MISC_BASE    /* MISC_BASE==0xFCA80000,是各种寄存器的基地址 */
    137
    138 /*        ; program M value */
    139         LDR     R2,[R1, #PLL1_FRQ_REG] /* ; read the PLL1_Frequency register*/
                            /* 距MISC_BASE偏移PLL1_FRQ_REG==0x0000000C处
                             * 是PLL1_FRQ寄存器。此处,首先加载PLL1_FRQ寄存器的值
                             */
    140         LDR     R7,=PLL_MODE_NON_DITHERED_M_MASK    /* PLL_MODE_NON_DITHERED_M_MASK==0xFF000000 */
    141         MVN     R7,R7    /* 将R7的值按位反转,也就是R7==0x00FFFFFF */
    142         AND     R2,R2,R7 /*; Mask the M value */    /* 将从PLL1_FRQ寄存器中读出的值的高8位清零,
                                 * 这高8位要替换成自己定义的值
                                 */
    143         LDR     R4,=CONFIG_SYS_PLL1_M_VALUE    /* CONFIG_SYS_PLL1_M_VALUE==166==0xA6,
                             * 这个值定义在spear_pll.h文件中,当我们修改该头文件中的
                             * CONFIG_SYS_PLL1_M_VALUE的时候,
                             * 就会在初始化的时候改变PLL1_FRQ寄存器中的高8位的值。
                             */
    144         MOV     R4,R4, lsl #PLL_MODE_NON_DITHERED_M_SHIFT /* ; Shift and set the M value */
                            /* PLL_MODE_NON_DITHERED_M_SHIFT==24
                             * 这里是将CONFIG_SYS_PLL1_M_VALUE的值左移24位,
                             * 使其有效位位于32位字中的高8位。
                             */
    145         ORR     R2,R2,R4    /* 将PLL1_FRQ寄存器中读出的值的高8位设置成spear_pll.h中定义的值 */
    146         STR     R2,[R1, #PLL1_FRQ_REG] /* ; load the M value*/    /* 将设置保存到PLL1_FRQ寄存器中 */
    147
        /* 148-155行所做的事情与139-146行所做的事情类似
         * 只不过此处设置的是P值,而不是M值
         */
    148         LDR     R2,[R1, #PLL1_FRQ_REG]
    149         LDR     R7,=PLL_VALUE_P_MASK
    150         MVN     R7,R7
    151         AND     R2,R2,R7
    152         LDR     R4,=CONFIG_SYS_PLL1_P_VALUE
    153         MOV     R4,R4, lsl #PLL_VALUE_P_SHIFT
    154         ORR     R2,R2,R4
    155         STR     R2,[R1, #PLL1_FRQ_REG]
    156
        /* 157-164行所做的事情与139-146行所做的事情类似
         * 只不过此处设置的是N值,而不是M值
         */
    157         LDR     R2,[R1, #PLL1_FRQ_REG]
    158         LDR     R7,=PLL_VALUE_N_MASK
    159         MVN     R7,R7
    160         AND     R2,R2,R7
    161         LDR     R4,=CONFIG_SYS_PLL1_N_VALUE
    162         MOV     R4,R4, lsl #PLL_VALUE_N_SHIFT
    163         ORR     R2,R2,R4
    164         STR     R2,[R1, #PLL1_FRQ_REG]
    165
    166
        /* 从这里开始设置PLL1_CTR寄存器, PLL1_CNTL_REG==0x00000008
         * 我猜应该是先diable再enable使得之前对pll的设置生效。
         */
    167 /*; power down : pll1 ctrl programming */
    168         LDR     R2,=0x1c0a    /* PLL1_CTR寄存器的第2位清零,disable pll */
    169         STR     R2,[R1, #PLL1_CNTL_REG]
    170 /*;enable pll1 */
    171         LDR     R2,=0x1c0e    /* PLL1_CTR寄存器的第2位置位,enable pll */
    172         STR     R2,[R1, #PLL1_CNTL_REG]
    173 /* ;strobe */    /* 这一段没明白什么意思... */
    174         LDR     R2,=0x1c06
    175         STR     R2,[R1, #PLL1_CNTL_REG]
    176         LDR     R2,=0x1c0e
    177         STR     R2,[R1, #PLL1_CNTL_REG]
    178 /*;wait for lock   */
        /* PLL1_CTR寄存器的最低位是一个只读位,当它为0的时候
         * 表示pll处于unlock状态,当它为1的时候表示pll处于lock状态
         * 此处,是在等待,知道pll处于lock状态。
         */
    179 pll1_lock_1:
    180         LDR     R2,[R1,#PLL1_CNTL_REG]    /* 读取PLL1_CTR寄存器的值 */
    181         AND     R2,R2,#0x1        /* 屏蔽除最低位之外的所有位 */
    182         CMP     R2,#0x1        /* 看看最低位是否为1,为1则表明已经处于lock状态了 */
    183         BNE     pll1_lock_1        /* 否则继续等待,知道最低位为1 */

        /* 以下代码所做的工作类似与上面的代码
         * 只不过上面的代码是对PLL1进行初始化,
         * 而下面的代码是对PLL2进行初始化。原因可能是SPEArPlus这个开发板具有双ARM核。
         */
    184 /*
    185 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    186 ; programming PLL2
    187 */
    188         LDR     R1,=MISC_BASE
    189         LDR     R2,=PLL2_FREQ
    190         STR     R2,[R1, #PLL2_FRQ_REG]
    191
    192 /*
    193 ; power down : PLL2 ctrl programming
    194 */
    195         LDR     R2,=0x1c0a
    196         STR     R2,[R1, #PLL2_CNTL_REG]
    197 /* ;enable pll1*/
    198         LDR     R2,=0x1c0e
    199         STR     R2,[R1, #PLL2_CNTL_REG]
    200 /*;strobe */
    201         LDR     R2,=0x1c06
    202         STR     R2,[R1, #PLL2_CNTL_REG]
    203         LDR     R2,=0x1c0e
    204         STR     R2,[R1, #PLL2_CNTL_REG]
    205 /*;turn from int to ext. div  */
    206 /*;     LDR     R2,=0x1d0f */
    207 /*;     STR     R2,[R1, #PLL2_CNTL_REG]*/
    208
    209 /*;wait for lock */
    210 pll2_lock_1:
    211         LDR     R2,[R1,#PLL2_CNTL_REG]
    212         AND     R2,R2,#0x1
    213         CMP     R2,#0x1
    214         BNE     pll2_lock_1
    215 /*
    216 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    217 ;GMAC Tx Clock programming
    218 ;MISCCntl->PERIPH1_CLKEN  &= ~ PERIPH_GMAC;
    219
    220 ;MISCCntl->GMAC_SYNTH_CLK = (SYNTH_XMASK & (0x2<<16)) | (SYNTH_YMASK & 0x3); //375*(X/Y)=125
    221 ;MISCCntl->GMAC_CTR_REG = TXCLK_SYNTH;
    222
    223 ;MISCCntl->PERIPH1_CLKEN  |=  PERIPH_GMAC;
    224 ;MISCCntl->PERIPH1_RST    |= PERIPH_GMAC;
    225 ;MISCCntl->PERIPH1_RST    &= ~PERIPH_GMAC;
    226
    227
    228
    229 ;MISCCntl->PERIPH1_CLKEN  &= ~ PERIPH_GMAC;
    230 */
        /* PERIPH1_CLKEN==0x2C,此偏移对应的寄存器是PERIP1_CLK_ENB
         * 该寄存器的功能是设置外设时钟的使能
         * 这里先关闭gmac的时钟,然后对gmac进行相关设置之后再打开gmac的时钟
         */
    231         LDR  R1, =MISC_BASE
    232         LDR  R2, [R1, #PERIPH1_CLKEN] /*;// read the peripheral-1 clock enable register */
    233         BIC  R2,  R2, #GMAC        /* GMAC==0x00800000,也就是将PERIP1_CLK_ENB寄存器中的gmac_clken位清零
                         * disable gmac ethernet的时钟
                         */
    234         STR  R2, [R1, #PERIPH1_CLKEN] /*;// set the enable value */    /* 保存设置到寄存器 */
    235        
    236 /*;MISCCntl->GMAC_SYNTH_CLK = (SYNTH_XMASK & (0x2<<16)) | (SYNTH_YMASK & 0x3); //375*(X/Y)=125 */
        /* GMAC_SYNTH_CLK==0x68,R1+GMAC_SYNTH_CLK的地址对应与GMAC_CLK_SYNT寄存器。
         * 对GMAC_CLK_SYNT寄存器进行设置,将其设置为0x00020003
         */
    237        LDR  R2, =SYNTH_XMASK    /* SYNTH_XMASK==0xFFFF0000 */
    238         MOV  R3, #0x02
    239         MOV  R3, R3, lsl #16
    240         AND  R2, R2, R3        /* R2 = 0xFFFF0000 & 0x00020000 */
    241         LDR  R3, =SYNTH_YMASK    /* SYNTH_YMASK==0x0000FFFF */
    242         AND  R3, R3, #0x03
    243         ORR  R2, R2, R3        /* R2 = 0x00020000 | 0x00000003 */
    244         STR  R2, [R1, #GMAC_SYNTH_CLK] /* ;// read the peripheral-1 clock enable register */
    245
    246 /*;MISCCntl->GMAC_CTR_REG = TXCLK_SYNTH;   */
        /* GMAC_CTR_REG==0xA8,对应于GMAC_CFG_CTR寄存器 */
    247         LDR  R2, =0x00
    248         STR  R2, [R1, #GMAC_CTR_REG] /*;// read the peripheral-1 clock enable register */
    249
    250 /*;MISCCntl->PERIPH1_CLKEN  |=  PERIPH_GMAC; */
        /* 重新将gmac对应的外设时钟使能 */
    251         LDR  R2, [R1, #PERIPH1_CLKEN] /* ;// read the peripheral-1 clock enable register*/
    252         ORR  R2,  R2, #GMAC
    253         STR  R2, [R1, #PERIPH1_CLKEN] /* ;// set the enable value*/
    254
    255 /*;MISCCntl->PERIPH1_RST    |= PERIPH_GMAC; */
        /* PERIPH1_RST==0x38,对应于PERIP1_SOF_RST寄存器
         * 此处将PERIPH1_RST寄存器中的GMAC位置1是令gmac ethernet执行reset
         * 使得以上对gmac的设置生效
         */
    256         LDR  R2, [R1, #PERIPH1_RST] /* ;// read the peripheral-1 clock enable register*/
    257         ORR  R2,  R2, #GMAC
    258         STR  R2, [R1, #PERIPH1_RST] /* ;// set the enable value */
    259
    260 /* ;MISCCntl->PERIPH1_RST    &= ~PERIPH_GMAC;*/
        /* 将PERIP1_SOF_RST寄存器中的GMAC复位,即reset完之后关闭reset功能 */
    261         LDR  R2, [R1, #PERIPH1_RST] /*;// read the peripheral-1 clock enable register */
    262         BIC  R2,  R2, #GMAC
    263         STR  R2, [R1, #PERIPH1_RST] /*;// set the enable value */
    264
    265
    266
    267
    268
    269                 
    270
    271 /* ; enable plltimeen */
        /* 设置PERIP_CLK_CFG寄存器的值为0x82,很奇怪手册里面没有对该寄存器的具体说明 */
    272         LDR     R2,=0x82
    273         STR     R2,[R1, #PERIPHCLK_CFG]    /* PERIPHCLK_CFG==0x28 */
    274
    275 /* ; set pclkdiv & hclkdiv */
        /* 设置CORE_CLK_CFG寄存器的值为0x555 */
    276         LDR     R1, =MISC_BASE
    277         LDR     R2,=0x555
    278         STR     R2,[R1, #AMBA_CLK_CFG]    /* AMBA_CLK_CFG==0x24 */
    279
    280 /* ; SMI init */
    281         LDR R1, =SMI_BASE    /* SMI_BASE==0xFC000000 */
    282         LDR R2, =BANK_EN    /* BANK_EN==0x0000000F,低4位每一位代表一个bank
                     * 系统初始化的时候只有bank0是enable的,以支持
                     * 从外部memory来引导系统
                     */
    283         ORR R2, R2, #DSEL_TIME    /* DSEL_TIME==0x00000050 Deselect time 5+1 SMI_CK periods */
    284         ORR R2, R2, #PRESCALF    /* PRESCALF==0x00000F00 AHB_CK prescaling value */
    285         STR R2, [R1, #SMI_CR1]    /* 保存设置到寄存器SMI_CR1 */
    286
        /* 又来一遍一样的?不明白。。。 */
    287         LDR R2, =BANK_EN
    288         ORR R2, R2, #DSEL_TIME
    289         ORR R2, R2, #PRESCALF
    290         STR R2, [R1, #SMI_CR1]
    291
    292
    293 /*; setting SYSCTL to NORMAL mode */
    294         LDR     R1, =SYSCTL_BASE    /* SYSCTL_BASE==0xFCA00000,是所有系统控制寄存器的基地址 */
    295         LDR     R3,[R1, #SCCTRL ]    /* 读取SCCTRL寄存器的值保存在R3中 */
    296         MOV     R2,#0x00000004
    297         STR     R2,[R1, #SCCTRL]    /* 将SCCTRL寄存器的值设置成0x00000004
                         * SCCTRL寄存器中最低3位为'b1xx(x表示任意值)时为NORMAL模式
                         */
    298
    299 /* ; wait for normal mode */
    300         LDR     R1, =SYSCTL_BASE
        /* SCCTRL寄存器的[6:3]位为ModeStatus位,当ModeStatus为'b0100时,
         * 表示系统处于NORMAL模式。
         * 下面的代码中,0x20=='b0(0100)000,括号中的4位即与ModeStatus对应。
         * 当从SCCTRL寄存器读出的内容经过掩码后与0x20相同,则说明已经为NORMAL模式了
         * 否则说明还没有切换到NORMAL模式,继续等待,知道成功切换到NORMAL模式。
         */
    301 loop_normal:
    302         LDR     R2,[R1, #SCCTRL]
    303         AND     R2,R2,#0x20
    304         CMP     R2,#0x20
    305          BNE     loop_normal
    306
        /* 下面的代码块看似想要使能UART1、UART2和SMI的时钟
         * 可是,感觉又好像没有必要,因为315行这一句就使能了所有外设的时钟了
         * 有点诡异。。。没搞明白为什么要这么做
         */
    307 /*; enable UART1, UART2, SMI clocks */
    308         LDR  R1, =MISC_BASE
    309         LDR  R2, [R1, #PERIPH1_CLKEN] /*;// read the peripheral-1 clock enable register */
    310 /* ; enable UART1, UART2 & SMI clocks */
    311         ORR  R2, R2, #UART1        /* PERIP1_CLK_ENB第3位置1,使能UART1 clock */
    312         ORR  R2, R2, #UART2        /* PERIP1_CLK_ENB第4位置1,使能UART2 clock */
    313         ORR  R2, R2, #SMI        /* PERIP1_CLK_ENB第21位置1,使能Serial Flash clock */
    314         LDR  R3, =0xFFFFFFF8   
    315         ORR  R2,R2,R3        /* ???这个比较诡异,看着好像是使能所有的外设时钟??? */
    316         STR  R2, [R1, #PERIPH1_CLKEN] /*;// set the enable value */
    317
        /* 这部分跟上面那部分代码有的一拼,感觉是想要disable UART1、UART1和SMI的reset,
         * 可是323这一句就清除了所有外设的reset了
         * 所以还是看不明白为什么要这么做。。。
         */
    318 /* ; remove reset of UART1, UART2, SMI peripherals */
    319         LDR R2, [R1, #PERIPH1_RST]
    320         BIC R2, R2, #UART1
    321         BIC R2, R2, #UART2
    322         BIC R2, R2, #SMI
    323         MOV R2,#0x00
    324         STR  R2, [R1, #PERIPH1_RST]
    325
    326 /*; remove reset on all IPs */
    327 /*;        LDR     R1,=MISC_BASE */
    328 /*@;    LDR     R2,=0x0 */
    329 /*;     STR     R2,[R1, #PERIPH1_RST_REG] */
    330
        /* 这个标号是在Watchdog引发中断以后,用于直接返回的,在整个sys_init的开头就进行了判断
         * 另外,当不是由Watchdog引发中断时,程序走到这里也将返回,在我们上下文里,将返回XLOADER_ENTRY           
         */
    331 normal_mode:
    332    MOV     PC, R14
    333

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    phpcms后台进入地址(包含No permission resources错误)
    phpmyadmin上传大sql文件办法
    ubuntu彻底卸载mysql
    Hdoj 2602.Bone Collector 题解
    一篇看懂词向量
    Hdoj 1905.Pseudoprime numbers 题解
    The Python Challenge 谜题全解(持续更新)
    Hdoj 2289.Cup 题解
    Hdoj 2899.Strange fuction 题解
    Hdoj 2199.Can you solve this equation? 题解
  • 原文地址:https://www.cnblogs.com/mao0504/p/4706944.html
Copyright © 2011-2022 走看看