青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 60, 文章 - 0, 評(píng)論 - 197, 引用 - 0
數(shù)據(jù)加載中……

學(xué)習(xí) ARM 系列 -- FS2410 開發(fā)板上 Nand Flash 到內(nèi)存的代碼搬移

一、目的
   前面做過一個(gè)實(shí)驗(yàn),搬移 Nand Flash 里的前 4k 代碼到內(nèi)存指定位置,這其實(shí)是把
SRAM 從 0x40000000 開始的 4K 代碼復(fù)制到 SDRAM 的指定位置,并沒有涉及到對(duì) Nand
Flash 的操作。究其原因,開發(fā)板上電后,Nand Flash 開始的前 4K 數(shù)據(jù)會(huì)被自動(dòng)復(fù)制到
SRAM 0x40000000 開始的 4K 區(qū)域里,這個(gè)區(qū)域被稱為 "Steppingstone"。那我們這次就來
操作 Nand Flash,讀取它 4K 后的代碼到 SDRAM 指定位置,并執(zhí)行 SDRAM 中的代碼。

二、代碼
   通過前面做的幾個(gè)實(shí)驗(yàn),我們已經(jīng)熟悉了 ARM 開發(fā)的基本流程,這可以讓我們更關(guān)注于
代碼的邏輯。好,先來分析文件 head.s:

   @ 文件 head.s
   @ 作用:關(guān)閉看門狗、SDRAM 的初始化設(shè)置、搬移 Nand Flash 4K 以后
   @ 的代碼到 SDRAM 的指定位置、執(zhí)行 SDRAM 中的代碼
   .text
   .global _start
   _start:
    ldr r0, =0x53000000 @ Close Watch Dog Timer
    mov r1, #0x0
    str r1, [r0]
  
    bl  memory_setup  @ Initialize memory setting
    bl  flash_to_sdram @ Copy code to sdram
    
    ldr sp, =0x34000000 @ Set stack pointer
    ldr pc, =main              @ execute the code in SDRAM
  

   @ 文件 mem.s
   @ 作用:SDRAM 的初始化設(shè)置
   @ 關(guān)于初始化的更多細(xì)節(jié),請(qǐng)參考我的前一篇隨筆
   .global memory_setup         @ 導(dǎo)出 memory_setup, 使其對(duì)鏈接器可見
   memory_setup:
    mov  r1, #0x48000000
    adrl r2, mem_cfg_val
    add  r3, r1, #13*4
   1: 
    @ write initial values to registers
    ldr  r4, [r2], #4
    str  r4, [r1], #4
    cmp  r1, r3
    bne  1b
    mov  pc, lr
    
    .align 4
   mem_cfg_val:
    .long 0x22111110 @ BWSCON
    .long 0x00000700 @ BANKCON0
    .long 0x00000700 @ BANKCON1
    .long 0x00000700 @ BANKCON2
    .long 0x00000700 @ BANKCON3
    .long 0x00000700 @ BANKCON4
    .long 0x00000700 @ BANKCON5
    .long 0x00018005 @ BANKCON6
    .long 0x00018005 @ BANKCON7 9bit
    .long 0x008e07a3 @ REFRESH
    .long 0x000000b2 @ BANKSIZE
    .long 0x00000030 @ MRSRB6
    .long 0x00000030 @ MRSRB7


   @ 文件 flash.s
   @ 作用:設(shè)置 Nand Flash 的控制寄存器、讀取 Nand Flash
   @ 中的代碼到 SDRAM 的指定位置
   .equ NFCONF, 0x4e000000
   .equ NFCMD,  0x4e000004
   .equ NFADDR, 0x4e000008
   .equ NFDATA, 0x4e00000c
   .equ NFSTAT, 0x4e000010
   .equ NFECC,  0x4e000014
   .global flash_to_sdram
   flash_to_sdram:
        @ Save return addr
        mov r10,lr
    
        @ Initialize Nand Flash
        mov r0,#NFCONF
        ldr r1,=0xf830
        str r1,[r0]
   
        @ First reset and enable Nand Flash
        ldr r1,[r0]
        bic r1, r1, #0x800
        str r1,[r0]
   
        ldr r2,=NFCMD
        mov r3,#0xff
        str r3,[r2]
    
        @ for delay
        mov r3, #0x0a
   1:
        subs r3, r3, #1
        bne 1b
  
   @ Wait until Nand Flash bit0 is 1
   wait_nfstat:
        ldr r2,=NFSTAT
        ldr r3,[r2]
        tst r3,#0x01
        beq wait_nfstat
          
        @ Disable Nand Flash
        ldr r0,=NFCONF
        ldr r1,[r0]
        orr r1,r1,#0x8000
        str r1,[r0]
   
        @ Initialzie stack
        ldr sp,=4096
  
        @ Set arguments and call 
        @ function nand_read defined in nand_read.c
        ldr r0,=0x30000000
        mov r1,#4096
        mov r2,#1024
        bl nand_read
   
        @ return
        mov pc,r10


   /* 文件 nand_read.c
    * 作用:從 Nand Flash 中讀取一塊數(shù)據(jù)到 SDRAM 中的指定位置
    */
   #define NFCONF (*(volatile unsigned long *)0x4e000000)
   #define NFCMD  (*(volatile unsigned long *)0x4e000004)
   #define NFADDR (*(volatile unsigned long *)0x4e000008)
   #define NFDATA (*(volatile unsigned long *)0x4e00000c)
   #define NFSTAT (*(volatile unsigned long *)0x4e000010)
   #define NFECC  (*(volatile unsigned long *)0x4e000014)
  
   #define NAND_SECTOR_SIZE 512
   #define NAND_BLOCK_MASK  0x1ff
  
   void wait_idle() {
     int i;
     for (i = 0; i < 50000; ++i) ;
   }
  
   int nand_read(unsigned char *buf, unsigned long start_addr, int size){
     int i, j;
     /*
      * detect the argument
      */ 
     if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
       return -1;    
     }
   
     /* chip Enable */
     NFCONF &= ~0x800;
     for (i=0; i<10; i++) {
       ;
     }
   
     for (i=start_addr; i < (start_addr + size); i+=NAND_SECTOR_SIZE) {
       NFCMD = 0;
   
       /* Write Address */
       NFADDR = i & 0xff;
       NFADDR = (i >> 9)  & 0xff;
       NFADDR = (i >> 17) & 0xff;
       NFADDR = (i >> 25) & 0xff;
   
       wait_idle();
   
       for(j=0; j < NAND_SECTOR_SIZE; j++) {
         *buf++ = (NFDATA & 0xff);
       }
     }
   
     NFCONF |= 0x800;    /* chip disable */
     return 0;
   }

注:Nand Flash 的設(shè)置和讀取數(shù)據(jù)的主要流程簡單介紹如下:
   1. NFCONF = 0xf830
   2. 在第一次操作NAND Flash前,通常復(fù)位一下:
      NFCONF &= ~0x800 (使能NAND Flash)
      NFCMD = 0xff (reset命令)
      循環(huán)查詢NFSTAT位0,直到它等于1
   3. NFCMD = 0 (讀命令)
   4. 這步得稍微注意一下,請(qǐng)打開K9F1208U0M數(shù)據(jù)手冊(cè)第7頁,那個(gè)表格列出了在地址操
      作的4個(gè)步驟對(duì)應(yīng)的地址線,A8沒用到:
      NFADDR = addr & 0xff
      NFADDR = (addr>>9) & 0xff (注意了,左移9位,不是8位)
      NFADDR = (addr>>17) & 0xff (左移17位,不是16位)
      NFADDR = (addr>>25) & 0xff (左移25位,不是24位)
   5. 循環(huán)查詢NFSTAT位0,直到它等于1
   6. 連續(xù)讀NFDATA寄存器512次,得到一頁數(shù)據(jù)(512字節(jié))
   7. NFCONF |= 0x800 (禁止NAND Flash)


   /* 文件 sdram.c
    * 作用:循環(huán)點(diǎn) FS2410 開發(fā)板上的 D9、D10、D11、D12
    * 四個(gè)發(fā)光二極管。
    */
   #define GPFCON (*(volatile unsigned long *)0x56000050)
   #define GPFDAT (*(volatile unsigned long *)0x56000054)
  
   int main()
   {
     int i,j;
     while(1) {
       for (i = 0; i <4; ++i) {
         GPFCON = 0x1<<(8+i*2);
         GPFDAT = 0x0;
  
         // for delay
         for(j=0;j<50000;++j) ;
       }
     }
   }


   /*
    * 文件 nand.lds (lds 文件是連接腳本)
    */
   SECTIONS {
       first  0x00000000 : { head.o mem.o flash.o nand_read.o }
       second 0x30000000 : AT(4096) { sdram.o }
   }
  
注:這個(gè)鏈接腳本是用來傳給鏈接器的,其作用如下:
  1. 將 head.o 放在 0x00000000 開始的地址處, mem.o、flash.o、and_read.o
     依次放在 head.o 后面, 它們的運(yùn)行地址是 0x00000000
  2. 將 sdram.o 放在地址 4096 開始處, 但它的運(yùn)行地址是 0x30000000, 運(yùn)行前需要
     從 4096 處復(fù)制到 SDRAM 的 0x300000000 處

完整的連接腳本文件形式如下:
SECTIONS {
...
secname start BLOCK(align) (NOLOAD) : AT(ldadr) {contents} >region :phdr =fill
...
}

并非每個(gè)選項(xiàng)都是必須的,僅從 nand.lds 用到的來看:
(1) secname: 段名,對(duì)于 nand.lds, 段名為 first 和 second
(2) start: 本段的運(yùn)行時(shí)地址,如果沒有 AT(xxx),則本段的存儲(chǔ)地址也是 start
(3) AT(ldadr): 定義本段存儲(chǔ)(加載)的地址
(4) {contents}: 決定哪些內(nèi)容放在本段,可以是整個(gè)目標(biāo)文件,也可是目標(biāo)文件中的某段


   # 文件 Makefile
   # 由代碼文件生成目標(biāo)文件,并依據(jù)連接腳本 nand.lds 連接目標(biāo)文件,
   # 最后將連接生成的目標(biāo)文件轉(zhuǎn)換成二進(jìn)制格式
   sdram:head.s flash.s mem.s sdram.c
        arm-linux-gcc -c -o head.o head.s
        arm-linux-gcc -c -o mem.o mem.s
        arm-linux-gcc -c -o flash.o flash.s
        arm-linux-gcc -c -o nand_read.o nand_read.c
        arm-linux-gcc -c -o sdram.o sdram.c
        arm-linux-ld  -Tnand.lds head.o mem.o flash.o nand_read.o sdram.o -o sdram_tmp.o
        arm-linux-objcopy -O binary -S sdram_tmp.o sdram
   clean:
        rm -f *.o
        rm -f sdram

三、編譯、燒寫、測(cè)試
Make 一下就會(huì)生成我們要的文件 sdram, 將其通過 JTAG 燒入 Nand Flash ,Reset
一下開發(fā)板, 呵呵,欣賞我們的成果吧!

posted on 2008-01-06 21:43 Normandy 閱讀(4688) 評(píng)論(7)  編輯 收藏 引用 所屬分類: Embeded Area

評(píng)論

# re: 學(xué)習(xí) ARM 系列 -- FS2410 開發(fā)板上 Nand Flash 到內(nèi)存的代碼搬移  回復(fù)  更多評(píng)論   

好東西,支持。最好在介紹一下abc.c文件及其作用。
2008-01-06 22:02 | hukq

# re: 學(xué)習(xí) ARM 系列 -- FS2410 開發(fā)板上 Nand Flash 到內(nèi)存的代碼搬移  回復(fù)  更多評(píng)論   

LZ 強(qiáng)人呀!學(xué)習(xí)......
2008-01-07 11:11 | kyle

# re: 學(xué)習(xí) ARM 系列 -- FS2410 開發(fā)板上 Nand Flash 到內(nèi)存的代碼搬移  回復(fù)  更多評(píng)論   

請(qǐng)教摟住:
在用SJF2410燒寫程序的時(shí)候,如果我想把BOOT程序燒寫在0000H,MAIN程序燒寫在1000H處,而APPLY程序燒寫在2000H處,應(yīng)該如何操作??
一定要燒寫三次才可以嗎?
謝謝摟主
2008-03-09 14:23 | 葫蘆瓜

# re: 學(xué)習(xí) ARM 系列 -- FS2410 開發(fā)板上 Nand Flash 到內(nèi)存的代碼搬移  回復(fù)  更多評(píng)論   

@葫蘆瓜
有兩種思路:
(1) 如果你編譯后生成三個(gè)二進(jìn)制程序, 可通過sjf2410 分三次將三個(gè)文件燒入 Nand Flash的不同位置, 具體請(qǐng)看 sjf2410.exe 的用法。
(2) 如果你編譯后只生成一個(gè)二進(jìn)制文件, 即把 boot 、main 、apply 三個(gè)目標(biāo)文件連接成一個(gè)文件,可通過sjf2410 一次燒寫即可。要點(diǎn)是在連接時(shí)指定連接腳本。 連接腳本如下:

SECTIONS {
first 0x00000000 : { boot.o}
second 0x00000000 : AT(4096) { main.o }
third 0x00000000 : AT(8192) { apply.o }
}

然后在連接程序中這樣調(diào)用連接腳本:
arm-linux-ld -Tnand.lds boot.o main.o apply.o -o prog_tmp.o
arm-linux-objcopy -O binary -S prog_tmp.o prog


2008-03-10 09:47 | Normandy

# re: 學(xué)習(xí) ARM 系列 -- FS2410 開發(fā)板上 Nand Flash 到內(nèi)存的代碼搬移  回復(fù)  更多評(píng)論   

如果從nand boot的話
SRAM是從0-4096
不是從0x40000000開始吧
2008-08-08 01:00 |

# re: 學(xué)習(xí) ARM 系列 -- FS2410 開發(fā)板上 Nand Flash 到內(nèi)存的代碼搬移[未登錄]  回復(fù)  更多評(píng)論   

@毛
實(shí)際上板子加電啟動(dòng)時(shí),SRAM 從 0x40000000 開始的 4096 字節(jié)區(qū)域被映射成 從 0x00000000 開始的 4096 字節(jié)區(qū)域, 手冊(cè)上有說明
2008-08-11 13:06 | Normandy

# re: 學(xué)習(xí) ARM 系列 -- FS2410 開發(fā)板上 Nand Flash 到內(nèi)存的代碼搬移  回復(fù)  更多評(píng)論   

我是新手,想問個(gè)問題,就是你的這幾篇文章的程序可以使用串口或者USB下載到開發(fā)板嗎?如果行怎么下載,地址是多少,迫切的想知道,其他熱心的朋友也可以幫忙回答一下,謝謝!
2008-10-28 16:20 | 李強(qiáng)
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲午夜视频在线| 久久九九电影| 国产在线观看一区| 黄色在线一区| 国语精品中文字幕| 亚洲国产成人91精品| 亚洲美女免费视频| 亚洲欧美制服中文字幕| 久久久精品国产一区二区三区| 久久精品人人爽| 欧美不卡在线视频| 亚洲每日更新| 午夜国产精品影院在线观看| 久久精品99国产精品酒店日本| 老司机免费视频一区二区| 欧美精品v日韩精品v韩国精品v | 最新69国产成人精品视频免费| 亚洲成人资源| 99精品国产热久久91蜜凸| 午夜国产精品影院在线观看| 乱人伦精品视频在线观看| 亚洲人成毛片在线播放| 中文亚洲欧美| 久久一区国产| 国产精品久久久久久一区二区三区 | 亚洲午夜久久久久久久久电影院| 欧美在线视频免费| 美女精品视频一区| 亚洲一区二区三区视频播放| 玖玖综合伊人| 国产欧美欧美| 一区二区免费在线观看| 久久久久久久精| 亚洲美女诱惑| 欧美电影资源| 伊人精品视频| 久久国产精品99精品国产| 欧美国产一区在线| 欧美一区二区三区四区在线| 欧美日韩精品综合| 伊人久久婷婷色综合98网| 久久久久久有精品国产| 欧美理论在线播放| 依依成人综合视频| 久久国产99| 一本高清dvd不卡在线观看| 噜噜噜在线观看免费视频日韩| 国产精品乱看| 亚洲视频免费在线| 亚洲精品1区2区| 免费一级欧美在线大片| 精品成人国产| 久久精品成人一区二区三区| 一区二区日本视频| 欧美日韩mv| 亚洲美洲欧洲综合国产一区| 欧美不卡视频一区发布| 久久狠狠一本精品综合网| 国产精品五月天| 欧美一区二区三区的| 洋洋av久久久久久久一区| 欧美日韩精品一区二区三区四区 | 久久午夜精品| 欧美伊人精品成人久久综合97| 国产精品黄色在线观看| 亚洲中字黄色| 亚洲免费视频在线观看| 国产精品久久国产精品99gif | 欧美激情精品久久久久久变态| 久久九九国产精品| 狠狠狠色丁香婷婷综合久久五月| 久久久久九九九九| 久久久久88色偷偷免费| 精品不卡一区| 亚洲国产日韩综合一区| 欧美精品亚洲精品| 亚洲婷婷综合久久一本伊一区| 日韩写真在线| 国产欧美日韩另类一区| 久久综合九色综合久99| 免费成人高清| 亚洲影音一区| 午夜国产精品影院在线观看| 国产免费一区二区三区香蕉精| 欧美一区二区三区四区视频| 久久久久久久久久看片| 亚洲国产精品久久| 一区二区三区欧美激情| 国产在线精品一区二区中文| 亚洲国产精品黑人久久久| 欧美少妇一区二区| 久久久视频精品| 欧美日本乱大交xxxxx| 欧美亚洲免费高清在线观看| 麻豆精品网站| 性伦欧美刺激片在线观看| 欧美国产第二页| 欧美三级韩国三级日本三斤| 久久国产综合精品| 欧美激情视频给我| 久久精品一二三区| 欧美日韩另类综合| 久久亚洲精品伦理| 欧美午夜理伦三级在线观看| 麻豆国产精品777777在线| 国产精品看片资源| 最新国产の精品合集bt伙计| 国产欧美日韩综合| 999亚洲国产精| 亚洲精品黄网在线观看| 欧美一区二区三区四区夜夜大片| 日韩网站免费观看| 麻豆成人在线播放| 欧美在线观看日本一区| 欧美色精品在线视频| 亚洲第一中文字幕| 精品91在线| 午夜日韩视频| 亚洲欧美久久久久一区二区三区| 麻豆成人在线观看| 麻豆国产精品一区二区三区| 国产欧美精品日韩| 亚洲免费婷婷| 午夜一区在线| 国产精品久久久久9999| 亚洲高清资源| 91久久黄色| 毛片精品免费在线观看| 葵司免费一区二区三区四区五区| 国产精品自在在线| 亚洲欧美日韩一区二区在线 | 久久全球大尺度高清视频| 午夜激情亚洲| 国产精品麻豆成人av电影艾秋 | 久久精品欧美日韩精品| 国产精品美女www爽爽爽视频| 日韩视频中文字幕| 亚洲五月婷婷| 欧美日韩亚洲综合| 一区二区三区波多野结衣在线观看| 亚洲精品欧美在线| 欧美成人精品| 亚洲国产99精品国自产| 亚洲精品美女久久7777777| 久久人人爽人人爽| 免费欧美视频| 亚洲人成久久| 欧美日韩另类综合| 亚洲午夜精品久久| 欧美一区午夜视频在线观看| 国产婷婷色一区二区三区| 午夜伦欧美伦电影理论片| 欧美一区网站| 激情五月婷婷综合| 欧美电影专区| 在线一区二区三区四区五区| 午夜亚洲福利| 久久精品亚洲一区二区| 久久久青草婷婷精品综合日韩 | 欧美一级在线亚洲天堂| 国产精品自在线| 久久九九精品99国产精品| 欧美成年人网| 亚洲网站啪啪| 伊人激情综合| 国产精品福利网站| 久久久久久久综合| 亚洲精品女av网站| 亚洲欧美成人综合| 亚洲第一页在线| 欧美午夜免费| 久久先锋影音av| 99精品黄色片免费大全| 久久精品免费看| 日韩午夜一区| 国产一区二区三区av电影| 欧美精品一区二区视频| 亚洲欧美日韩在线不卡| 欧美黑人一区二区三区| 亚洲一区黄色| 亚洲国产成人精品久久久国产成人一区 | 国内精品久久久久影院优| 欧美激情小视频| 香蕉久久夜色精品国产使用方法| 亚洲电影免费观看高清| 性一交一乱一区二区洋洋av| 亚洲激情影视| 国内精品久久久久久久影视蜜臀| 欧美日韩ab片| 欧美高清在线一区| 久久成年人视频| 夜夜爽www精品| 亚洲高清中文字幕| 久久频这里精品99香蕉| 亚洲欧美一区二区三区久久| 亚洲精品乱码久久久久久黑人| 国产一区二区三区高清播放| 国产精品成人观看视频国产奇米| 免费成人美女女| 久久久久久久一区|