<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > S3C2440 2440init.s分析第二篇(一)

          S3C2440 2440init.s分析第二篇(一)

          作者: 時(shí)間:2016-11-20 來(lái)源:網(wǎng)絡(luò) 收藏
          S3C2440 2440init.s分析第二篇(一)
          ;=========================================
          ; NAME: 2440INIT.S
          ; DESC: C start up codes
          ; Configure memory, ISR ,stacks
          ; Initialize C-variables
          ; HISTORY:
          ; 2002.02.25:kwtark: ver 0.0
          ; 2002.03.20:purnnamu: Add some functions for testing STOP,Sleep mode
          ; 2003.03.14:DonGo: Modified for 2440.
          ;=========================================

          ;首先,啟動(dòng)代碼定義了一些常量
          GET option.inc
          GET memcfg.inc
          GET 2440addr.inc

          BIT_SELFREFRESH EQU (1<<22)

          ;處理器模式常量
          USERMODE EQU 0x10
          FIQMODE EQU 0x11
          IRQMODE EQU 0x12
          SVCMODE EQU 0x13
          ABORTMODE EQU 0x17
          UNDEFMODE EQU 0x1b
          MODEMASK EQU 0x1f
          NOINT EQU 0xc0

          ;定義處理器各模式下堆棧地址常量
          UserStack EQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 ~
          SVCStack EQU (_STACK_BASEADDRESS-0x2800) ;0x33ff5800 ~
          UndefStack EQU (_STACK_BASEADDRESS-0x2400) ;0x33ff5c00 ~
          AbortStack EQU (_STACK_BASEADDRESS-0x2000) ;0x33ff6000 ~
          IRQStack EQU (_STACK_BASEADDRESS-0x1000) ;0x33ff7000 ~
          FIQStack EQU (_STACK_BASEADDRESS-0x0) ;0x33ff8000 ~

          ;檢查在tasm.exe里是否設(shè)置了采用THUMB(16位)代碼(armasm -16 ...@ADS 1.0)
          GBLL THUMBCODE ;定義THUMBCODE全局變量
          [ {CONFIG} = 16 ;如果發(fā)現(xiàn)是才用16位代碼的話
          THUMBCODE SETL {TRUE} ;把THUMBCODE設(shè)置為T(mén)URE
          CODE32 ;把處理器從新設(shè)置成為ARM模式
          | ;如果處理器現(xiàn)在就是ARM模式
          THUMBCODE SETL {FALSE} ;把THUMBCODE設(shè)置為FALSE就行了
          ]

          MACRO ;一個(gè)根據(jù)THUMBCODE把PC寄存的值保存到LR的宏
          MOV_PC_LR
          [ THUMBCODE
          bx lr ;在ARM模式中要使用BX指令轉(zhuǎn)跳到THUMB指令,并轉(zhuǎn)換模式
          |
          mov pc,lr ;如果目標(biāo)地址也是ARM指令的話就采用這種方式
          ]
          MEND

          MACRO ;和上面的宏一樣,只是多了一個(gè)相等的條件
          MOVEQ_PC_LR
          [ THUMBCODE
          bxeq lr
          |
          moveq pc,lr
          ]
          MEND

          ;=======================================================================================
          ;下面這個(gè)宏是用于第一次查表過(guò)程的實(shí)現(xiàn)中斷向量的重定向,如果你比較細(xì)心的話就是發(fā)現(xiàn)
          ;在_ISR_STARTADDRESS=0x33FF_FF00里定義的第一級(jí)中斷向量表是采用型如Handle***的方式的.
          ;而在程序的ENTRY處(程序開(kāi)始處)采用的是b Handler***的方式.
          ;在這里Handler***就是通過(guò)HANDLER這個(gè)宏和Handle***進(jìn)立聯(lián)系的.
          ;這種方式的優(yōu)點(diǎn)就是正真定義的向量數(shù)據(jù)在內(nèi)存空間里,而不是在ENTRY處的ROM(FLASH)空間里,
          ;這樣,我們就可以在程序里靈活的改動(dòng)向量的數(shù)據(jù)了.
          ;========================================================================================

          MACRO
          $HandlerLabel HANDLER $HandleLabel

          $HandlerLabel
          sub sp,sp,#4 ;減少sp(用于存放轉(zhuǎn)跳地址)
          stmfd sp!,{r0} ;把工作寄存器壓入棧(lr does not push because it return to original address)
          ldr r0,=$HandleLabel;將HandleXXX的址址放入r0
          ldr r0,[r0] ;把HandleXXX所指向的內(nèi)容(也就是中斷程序的入口)放入r0
          str r0,[sp,#4] ;把中斷服務(wù)程序(ISR)壓入棧
          ldmfd sp!,{r0,pc} ;用出棧的方式恢復(fù)r0的原值和為pc設(shè)定新值(也就完成了到ISR的轉(zhuǎn)跳)
          MEND


          ;=========================================================================================
          ;在這里用IMPORT偽指令(和c語(yǔ)言的extren一樣)引入|Image$$RO$$Base|,|Image$$RO$$Limit|...
          ;這些變量是通過(guò)ADS的工程設(shè)置里面設(shè)定的RO Base和RW Base設(shè)定的,
          ;最終由編譯腳本和連接程序?qū)氤绦?
          ;那為什么要引入這玩意呢,最簡(jiǎn)單的用處是可以根據(jù)它們拷貝自已
          ;==========================================================================================
          IMPORT |Image$$RO$$Base| ; ROM code(也就是代碼)的開(kāi)始地址
          IMPORT |Image$$RO$$Limit| ; ROM code的結(jié)束地址 (=ROM data的開(kāi)始地址)
          IMPORT |Image$$RW$$Base| ; 要初始化的RAM的開(kāi)始地址
          IMPORT |Image$$ZI$$Base| ; area(需要清零的RAM區(qū)域)的開(kāi)始地址
          IMPORT |Image$$ZI$$Limit| ; area的結(jié)束地址

          ;這里引入一些在其它文件中實(shí)現(xiàn)在函數(shù),包括為我們所熟知的main函數(shù)
          IMPORT MMU_SetAsyncBusMode
          IMPORT MMU_SetFastBusMode ;hzh

          IMPORT Main ; The main entry of mon program

          ;從這里開(kāi)始就是正真的代碼入口了!
          AREA Init,CODE,READONLY ;這表明下面的是一個(gè)名為Init的代碼段

          ENTRY ;定義程序的入口(調(diào)試用)

          EXPORT __ENTRY ;導(dǎo)出符號(hào)_ENTRY,但在那用到就還沒(méi)查明
          __ENTRY
          ResetEntry
          ;1)The code, which converts to Big-endian, should be in little endian code.
          ;2)The following little endian code will be compiled in Big-Endian mode.
          ; The code byte order should be changed as the memory bus width.
          ;3)The pseudo instruction,DCD can not be used here because the linker generates error.
          ASSERT :DEF:ENDIAN_CHANGE
          [ ENDIAN_CHANGE ;下面是大小端的一個(gè)判斷,在Option.inc里已經(jīng)設(shè)為FALSE
          ASSERT :DEF:ENTRY_BUS_WIDTH
          [ ENTRY_BUS_WIDTH=32
          b ChangeBigEndian ;DCD 0xea000007
          ]

          [ ENTRY_BUS_WIDTH=16
          andeq r14,r7,r0,lsl #20 ;DCD 0x0007ea00
          ]

          [ ENTRY_BUS_WIDTH=8
          streq r0,[r0,-r10,ror #1] ;DCD 0x070000ea
          ]
          |
          b ResetHandler ;設(shè)成FALSE的話就來(lái)到這了,轉(zhuǎn)跳到復(fù)位程序入口
          ]
          b HandlerUndef ;轉(zhuǎn)跳到Undefined mode程序入口
          b HandlerSWI ;轉(zhuǎn)跳到SWI 中斷程序入口
          b HandlerPabort ;轉(zhuǎn)跳到PAbort(指令異常)程序入口
          b HandlerDabort ;轉(zhuǎn)跳到DAbort(數(shù)據(jù)異常)程序入口
          b . ;保留
          b HandlerIRQ ;轉(zhuǎn)跳到IRQ 中斷程序入口
          b HandlerFIQ ;轉(zhuǎn)跳到FIQ 中斷程序入口

          ;@0x20
          b EnterPWDN ; Must be @0x20.

          ;==================================================================================
          ;下面是改變大小端的程序,這里采用直接定義機(jī)器碼的方式,至說(shuō)為什么這么做就得問(wèn)三星了
          ;反正我們程序里這段代碼也不會(huì)去執(zhí)行,不用去管它
          ;==================================================================================
          ChangeBigEndian
          ;@0x24
          [ ENTRY_BUS_WIDTH=32
          DCD 0xee110f10 ;0xee110f10 => mrc p15,0,r0,c1,c0,0
          DCD 0xe3800080 ;0xe3800080 => orr r0,r0,#0x80; //Big-endian
          DCD 0xee010f10 ;0xee010f10 => mcr p15,0,r0,c1,c0,0
          ]
          [ ENTRY_BUS_WIDTH=16
          DCD 0x0f10ee11
          DCD 0x0080e380
          DCD 0x0f10ee01
          ]
          [ ENTRY_BUS_WIDTH=8
          DCD 0x100f11ee
          DCD 0x800080e3
          DCD 0x100f01ee
          ]
          DCD 0xffffffff ;swinv 0xffffff is similar with NOP and run well in both endian mode.
          DCD 0xffffffff
          DCD 0xffffffff
          DCD 0xffffffff
          DCD 0xffffffff
          b ResetHandler

          ;如上所說(shuō),這里采用HANDLER宏去建立Hander***和Handle***之間的聯(lián)系
          HandlerFIQ HANDLER HandleFIQ
          HandlerIRQ HANDLER HandleIRQ
          HandlerUndef HANDLER HandleUndef
          HandlerSWI HANDLER HandleSWI
          HandlerDabort HANDLER HandleDabort
          HandlerPabort HANDLER HandlePabort

          ;===================================================================================
          ;呵呵,來(lái)了來(lái)了.好戲來(lái)了,這一段程序就是用來(lái)進(jìn)行第二次查表的過(guò)程了.
          ;如果說(shuō)第一次查表是由硬件來(lái)完成的,那這一次查表就是由軟件來(lái)實(shí)現(xiàn)的了.
          ;為什么要查兩次表??
          ;沒(méi)有辦法,ARM把所有的中斷都?xì)w納成一個(gè)IRQ中斷異常和一個(gè)FIRQ中斷異常
          ;第一次查表主要是查出是什么異常,可我們總要知道是這個(gè)中斷異常中的什么中斷呀!
          ;沒(méi)辦法了,再查一次表唄!
          ;===================================================================================
          IsrIRQ
          sub sp,sp,#4 ;給PC寄存器保留
          stmfd sp!,{r8-r9} ;把r8-r9壓入棧

          ldr r9,=INTOFFSET ;把INTOFFSET的地址裝入r9
          ldr r9,[r9] ;把INTOFFSET的值裝入r9
          ldr r8,=HandleEINT0 ;這就是我們第二個(gè)中斷向量表的入口的,先裝入r8
          ;===================================================================================
          ;哈哈,這查表方法夠好了吧,r8(入口)+index*4(別望了一條指令是4 bytes的喔),
          ;這不就是我們要找的那一項(xiàng)了嗎.找到了表項(xiàng),下一步做什么?肯定先裝入了!
          ;==================================================================================
          add r8,r8,r9,lsl #2
          ldr r8,[r8] ;裝入中斷服務(wù)程序的入口
          str r8,[sp,#8] ;把入口也入棧,準(zhǔn)備用舊招
          ldmfd sp!,{r8-r9,pc} ;施招,彈出棧,哈哈,順便把r8彈出到PC,O了,跳轉(zhuǎn)成功!


          LTORG ;聲明文字池,因?yàn)槲覀冇昧薼dr偽指令


          ;==============================================================================
          ; ENTRY(好了,我們的CPU要在這復(fù)位了.)
          ;==============================================================================
          ResetHandler
          ldr r0,=WTCON ;1.關(guān)看門(mén)狗
          ldr r1,=0x0
          str r1,[r0]

          ldr r0,=INTMSK
          ldr r1,=0xffffffff ;2.關(guān)中斷
          str r1,[r0]

          ldr r0,=INTSUBMSK
          ldr r1,=0x7fff ;3.關(guān)子中斷
          str r1,[r0]

          [ {FALSE} ;4.得有些表示了,該點(diǎn)點(diǎn)LED燈了,不過(guò)被FALSE掉了.
          ;rGPFDAT = (rGPFDAT & ~(0xf<<4)) | ((~data & 0xf)<<4);
          ; Led_Display
          ldr r0,=GPFCON
          ldr r1,=0x5500
          str r1,[r0]
          ldr r0,=GPFDAT
          ldr r1,=0x10
          str r1,[r0]
          ]

          ;5.為了減少PLL的lock time, 調(diào)整LOCKTIME寄存器.
          ldr r0,=LOCKTIME
          ldr r1,=0xffffff
          str r1,[r0]

          [ PLL_ON_START ;6.下面就來(lái)設(shè)置PLL了,你的板快不快就看這了!!
          ; Added for confirm clock divide. for 2440.
          ; 設(shè)定Fclk:Hclk:Pclk
          ldr r0,=CLKDIVN
          ldr r1,=CLKDIV_VAL ; 0=1:1:1, 1=1:1:2, 2=1:2:2, 3=1:2:4,
          str r1,[r0] ; 4=1:4:4, 5=1:4:8, 6=1:3:3, 7=1:3:6.

          ;===============================================================================
          ;MMU_SetAsyncBusMode 和 MMU_SetFastBusMode 都在4K代碼以上,
          ;如果你想你編譯出來(lái)的程序能在NAND上運(yùn)行的話,就不要在這調(diào)用這兩函數(shù)了.
          ;如果你不要求的話,你就用把.啥事沒(méi)有.
          ;為什么是4K,問(wèn)三星吧,就提供4K的內(nèi)部SRAM,要是提供400K多好呀.
          ;好了,好了,4K就4K吧,不能用這兩函數(shù),自己寫(xiě)還不行嗎,下面的代碼這這么來(lái)了,
          ;實(shí)現(xiàn)和上面兩函數(shù)一樣的功能.
          ;===============================================================================
          ; [ CLKDIV_VAL>1 ; 意思是 Fclk:Hclk 不是 1:1.
          ; bl MMU_SetAsyncBusMode
          ; |
          ; bl MMU_SetFastBusMode ; default value.
          ; ]

          [ CLKDIV_VAL>1 ; 意思是 Fclk:Hclk 不是 1:1.
          mrc p15,0,r0,c1,c0,0
          orr r0,r0,#0xc0000000;R1_nF:OR:R1_iA
          mcr p15,0,r0,c1,c0,0
          |
          mrc p15,0,r0,c1,c0,0
          bic r0,r0,#0xc0000000;R1_iA:OR:R1_nF
          mcr p15,0,r0,c1,c0,0
          ]

          ;配置 UPLL
          ldr r0,=UPLLCON
          ldr r1,=((U_MDIV<<12)+(U_PDIV<<4)+U_SDIV)
          str r1,[r0]
          nop ; Caution: After UPLL setting, at least 7-clocks
          nop ; delay must be inserted for setting hardware be completed.
          nop
          nop
          nop
          nop
          nop
          ;配置 MPLL 一定要使最后的頻率為16.9344MHz,不然你甭想用USB接口了,哈哈.
          ldr r0,=MPLLCON
          ldr r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV)
          str r1,[r0]
          ]

          ;檢查是否從SLEEP模式中恢復(fù)
          ldr r1,=GSTATUS2
          ldr r0,[r1]
          tst r0,#0x2
          ;如果是從SLEEP模式中恢復(fù), 轉(zhuǎn)跳到SLEEP_WAKEUP.
          bne WAKEUP_SLEEP

          EXPORT StartPointAfterSleepWakeUp ;導(dǎo)出符號(hào)StartPointAfterSleepWakeUp
          StartPointAfterSleepWakeUp

          ;===============================================================================
          ;設(shè)置內(nèi)存控制器等寄存器的值,因?yàn)檫@些寄存器是連續(xù)排列的,所以采用如下辦法對(duì)這些
          ;寄存器進(jìn)行連續(xù)設(shè)置.其中用到了SMRDATA的數(shù)據(jù),這在代碼后面有定義
          ;===============================================================================
          ;ldr r0,=SMRDATA
          adrl r0, SMRDATA ;be careful!, hzh
          ldr r1,=BWSCON ;BWSCON 地址
          add r2, r0, #52 ;SMRDATA數(shù)據(jù)的結(jié)束地址,共有52字節(jié)的數(shù)據(jù)

          0
          ldr r3, [r0], #4
          str r3, [r1], #4
          cmp r2, r0
          bne %B0

          ;================================================================================
          ;如果 EINT0 產(chǎn)生(這中斷就是我們按鍵產(chǎn)生的), 就清除SDRAM ,不過(guò)好像沒(méi)人會(huì)在這個(gè)時(shí)候按
          ;================================================================================
          ; check if EIN0 button is pressed

          ldr r0,=GPFCON
          ldr r1,=0x0
          str r1,[r0]
          ldr r0,=GPFUP
          ldr r1,=0xff
          str r1,[r0]

          ldr r1,=GPFDAT
          ldr r0,[r1]
          bic r0,r0,#(0x1e<<1) ; bit clear
          tst r0,#0x1
          bne %F1 ;如果沒(méi)有按,就跳到后面的1標(biāo)號(hào)處



          ; 這就是清零內(nèi)存的代碼

          ldr r0,=GPFCON
          ldr r1,=0x55aa
          str r1,[r0]
          ; ldr r0,=GPFUP
          ; ldr r1,=0xff
          ; str r1,[r0]
          ldr r0,=GPFDAT
          ldr r1,=0x0
          str r1,[r0] ;LED=****

          mov r1,#0
          mov r2,#0
          mov r3,#0
          mov r4,#0
          mov r5,#0
          mov r6,#0
          mov r7,#0
          mov r8,#0

          ldr r9,=0x4000000 ;64MB
          ldr r0,=0x30000000
          0
          stmia r0!,{r1-r8}
          subs r9,r9,#32
          bne %B0

          ;到這就結(jié)束了.

          1
          bl InitStacks ;初始化堆棧
          ;bl Led_Test ;又是LED,注掉了

          ;=======================================================================
          ; 哈哈,下面又有看頭了,這個(gè)初始化程序好像被名曰hzh的高手改過(guò)
          ; 能在NOR NAND 還有內(nèi)存中運(yùn)行,當(dāng)然了,在內(nèi)存中運(yùn)行最簡(jiǎn)單了.
          ; 在NOR NAND中運(yùn)行的話都要先把自己拷到內(nèi)存中.
          ; 此外,還記得上面提到的|Image$$RO$$Base|,|Image$$RO$$Limit|...嗎?
          ; 這就是拷貝的依據(jù)了!!!
          ;=========================================================================
          ldr r0, =BWSCON
          ldr r0, [r0]
          ands r0, r0, #6 ;OM[1:0] != 0, 從NOR FLash啟動(dòng)或直接在內(nèi)存運(yùn)行
          bne copy_proc_beg ;不讀取NAND FLASH
          adr r0, ResetEntry ;OM[1:0] == 0, 否則,為從NAND FLash啟動(dòng)
          cmp r0, #0 ;再比較入口是否為0地址處
          ;==========================================================================
          ;如果不是,則表示主板設(shè)置了從NAND啟動(dòng),但這個(gè)程序由于其它原因,
          ;并沒(méi)有從NAND從啟動(dòng),這種情況最有可能的原因就是用仿真器.
          ;==========================================================================
          bne copy_proc_beg ;這種情況也不讀取NAND FLASH.
          ;nop
          ;===========================================================
          nand_boot_beg ;這一段代碼完成從NAND讀代碼到RAM
          mov r5, #NFCONF ;首先設(shè)定NAND的一些控制寄存器
          ;set timing value
          ldr r0, =(7<<12)|(7<<8)|(7<<4)
          str r0, [r5]
          ;enable control
          ldr r0, =(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0)
          str r0, [r5, #4]

          bl ReadNandID ;按著讀取NAND的ID號(hào),結(jié)果保存在r5里
          mov r6, #0 ;r6設(shè)初值0.
          ldr r0, =0xec73 ;期望的NAND ID號(hào)
          cmp r5, r0 ;這里進(jìn)行比較
          beq %F1 ;相等的話就跳到下一個(gè)1標(biāo)號(hào)處
          ldr r0, =0xec75 ;這是另一個(gè)期望值
          cmp r5, r0
          beq %F1 ;相等的話就跳到下一個(gè)1標(biāo)號(hào)處
          mov r6, #1 ;不相等了,設(shè)置r6=1.
          1
          bl ReadNandStatus ;讀取NAND狀態(tài),結(jié)果放在r1里

          mov r8, #0 ;r8設(shè)初值0,意義為頁(yè)號(hào)
          ldr r9, =ResetEntry ;r9設(shè)初值為初始化程序入口地址
          ;=========================================================================
          ; 注意,在這里使用的是ldr偽指令,而不是上面用的adr偽指令,它加載的是ResetEntry
          ; 的決對(duì)地址,也就是我們期望的RAM中的地址,在這里,它和|Image$$RO$$Base|一樣
          ; 也就是說(shuō),我如我們編譯程序時(shí)RO BASE指定的地址在RAM里,而把生成的文件拷到
          ; NAND里運(yùn)行,由ldr加載的r9的值還是定位在內(nèi)存.
          ;=========================================================================
          2
          ands r0, r8, #0x1f ;凡r8為0x1f(32)的整數(shù)倍-1,eq有效,ne無(wú)效
          bne %F3 ;這句的意思是對(duì)每個(gè)塊(32頁(yè))進(jìn)行檢錯(cuò)
          mov r0, r8 ;r8->r0
          bl CheckBadBlk ;檢查NAND的壞區(qū)
          cmp r0, #0 ;比較r0和0
          addne r8, r8, #32 ;存在壞塊的話就跳過(guò)這個(gè)壞塊
          bne %F4 ;沒(méi)有的話就跳到標(biāo)號(hào)4處
          3
          mov r0, r8 ;當(dāng)前頁(yè)號(hào)->r0
          mov r1, r9 ;當(dāng)前目標(biāo)地址->r1
          bl ReadNandPage ;讀取該頁(yè)的NAND數(shù)據(jù)到RAM
          add r9, r9, #512 ;每一頁(yè)的大小是512Bytes
          add r8, r8, #1 ;r8指向下一頁(yè)
          4
          cmp r8, #256 ;比較是否讀完256頁(yè)即128KBytes
          bcc %B2 ;如果r8小于256(沒(méi)讀完),就返回前面的標(biāo)號(hào)2處

          mov r5, #NFCONF ;DsNandFlash
          ldr r0, [r5, #4]
          bic r0, r0, #1
          str r0, [r5, #4]
          ldr pc, =copy_proc_beg ;調(diào)用copy_proc_beg
          ;===========================================================
          copy_proc_beg
          adr r0, ResetEntry ;ResetEntry值->r0
          ldr r2, BaseOfROM ;BaseOfROM值(后面有定義)->r2
          cmp r0, r2 ;比較r0和r2
          ldreq r0, TopOfROM ;如果相等的話(在內(nèi)存運(yùn)行),TopOfROM->r0
          beq InitRam ;同時(shí)跳到InitRam

          ;=========================================================
          ;下面這個(gè)是針對(duì)代碼在NOR FLASH時(shí)的拷貝方法
          ;功能為把從ResetEntry起,TopOfROM-BaseOfROM大小的數(shù)據(jù)拷到BaseOfROM
          ;TopOfROM和BaseOfROM為|Image$$RO$$Limit|和|Image$$RO$$Base|
          ;|Image$$RO$$Limit|和|Image$$RO$$Base|由連接器生成
          ;為生成的代碼的代碼段運(yùn)行時(shí)的起啟和終止地址
          ;BaseOfBSS和BaseOfZero為|Image$$RW$$Base|和|Image$$ZI$$Base|
          ;|Image$$RW$$Base|和|Image$$ZI$$Base|也是由連接器生成
          ;兩者之間就是初始化數(shù)據(jù)的存放地放
          ;=======================================================

          ldr r3, TopOfROM
          0
          ldmia r0!, {r4-r7}
          stmia r2!, {r4-r7}
          cmp r2, r3
          bcc %B0

          sub r2, r2, r3 ;r2=BaseOfROM-TopOfROM=(-)代碼長(zhǎng)度
          sub r0, r0, r2 ;r0=ResetEntry-(-)代碼長(zhǎng)度=ResetEntry+代碼長(zhǎng)度

          InitRam
          ldr r2, BaseOfBSS ;BaseOfBSS->r2
          ldr r3, BaseOfZero ;BaseOfZero->r3
          0
          cmp r2, r3 ;比較BaseOfBSS和BaseOfZero
          ldrcc r1, [r0], #4 ;要是r21 ; means Fclk:Hclk is not 1:1.
          ; bl MMU_SetAsyncBusMode
          ; |
          ; bl MMU_SetFastBusMode ; default value.
          ; ]

          ;bl Led_Test

          ;===========================================================
          ; 進(jìn)入C語(yǔ)言前的最后一步了,就是把我們用說(shuō)查二級(jí)向量表
          ; 的中斷例程安裝到一級(jí)向量表(異常向量表)里.
          ldr r0,=HandleIRQ ;This routine is needed
          ldr r1,=IsrIRQ ;if there is not subs pc,lr,#4 at 0x18, 0x1c
          str r1,[r0]

          ; ;Copy and paste RW data/zero initialized data
          ; ldr r0, =|Image$$RO$$Limit| ; Get pointer to ROM data
          ; ldr r1, =|Image$$RW$$Base| ; and RAM copy
          ; ldr r3, =|Image$$ZI$$Base|
          ;
          ; ;Zero init base => top of initialised data
          ; cmp r0, r1 ; Check that they are different
          ; beq %F2
          ;1
          ; cmp r1, r3 ; Copy init data
          ; ldrcc r2, [r0], #4 ;--> LDRCC r2, [r0] + ADD r0, r0, #4
          ; strcc r2, [r1], #4 ;--> STRCC r2, [r1] + ADD r1, r1, #4
          ; bcc %B1
          ;2
          ; ldr r1, =|Image$$ZI$$Limit| ; Top of zero init segment
          ; mov r2, #0
          ;3
          ; cmp r3, r1 ; Zero init
          ; strcc r2, [r3], #4
          ; bcc %B3



          關(guān)鍵詞: S3C24402440init.

          評(píng)論


          技術(shù)專(zhuān)區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();