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

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

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

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

二、代碼
   通過前面做的幾個實驗,我們已經(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)于初始化的更多細節(jié),請參考我的前一篇隨筆
   .global memory_setup         @ 導(dǎo)出 memory_setup, 使其對鏈接器可見
   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. 這步得稍微注意一下,請打開K9F1208U0M數(shù)據(jù)手冊第7頁,那個表格列出了在地址操
      作的4個步驟對應(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)點 FS2410 開發(fā)板上的 D9、D10、D11、D12
    * 四個發(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 }
   }
  
注:這個鏈接腳本是用來傳給鏈接器的,其作用如下:
  1. 將 head.o 放在 0x00000000 開始的地址處, mem.o、flash.o、and_read.o
     依次放在 head.o 后面, 它們的運行地址是 0x00000000
  2. 將 sdram.o 放在地址 4096 開始處, 但它的運行地址是 0x30000000, 運行前需要
     從 4096 處復(fù)制到 SDRAM 的 0x300000000 處

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

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


   # 文件 Makefile
   # 由代碼文件生成目標文件,并依據(jù)連接腳本 nand.lds 連接目標文件,
   # 最后將連接生成的目標文件轉(zhuǎ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

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

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

評論

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

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

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

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

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

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

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

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

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ù)  更多評論   

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

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

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

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

我是新手,想問個問題,就是你的這幾篇文章的程序可以使用串口或者USB下載到開發(fā)板嗎?如果行怎么下載,地址是多少,迫切的想知道,其他熱心的朋友也可以幫忙回答一下,謝謝!
2008-10-28 16:20 | 李強
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美与黑人午夜性猛交久久久| 欧美黄在线观看| 亚洲一区二区免费在线| 久久久蜜桃一区二区人| 中国成人亚色综合网站| 欧美国产欧美综合 | 久久九九久久九九| 欧美视频在线观看免费网址| 亚洲第一久久影院| 久久久久免费视频| 午夜精品影院| 国产日韩一区| 久久亚洲欧洲| 久久亚洲精品欧美| 激情欧美国产欧美| 美女视频黄a大片欧美| 欧美自拍丝袜亚洲| 国内精品免费午夜毛片| 久久伊人精品天天| 久久综合国产精品台湾中文娱乐网| 激情另类综合| 亚洲激情欧美激情| 欧美电影免费观看网站| 日韩一区二区高清| 一本久道久久综合婷婷鲸鱼| 欧美午夜视频网站| 欧美一区二区视频免费观看| 欧美一级成年大片在线观看| 国语精品一区| 亚洲国产高清在线观看视频| 欧美日韩精品伦理作品在线免费观看| 亚洲图片在区色| 亚洲欧美另类中文字幕| 激情视频一区| 亚洲精品乱码久久久久久蜜桃麻豆| 欧美日韩一区二区三区在线观看免| 亚洲女人小视频在线观看| 性8sex亚洲区入口| 亚洲国产日韩综合一区| 亚洲精选一区二区| 国产视频综合在线| 亚洲高清视频的网址| 欧美涩涩网站| 另类激情亚洲| 欧美日韩国产色视频| 久久精品国产久精国产爱| 久久综合亚洲社区| 午夜视频在线观看一区二区| 老司机aⅴ在线精品导航| 亚洲伊人网站| 美女日韩欧美| 欧美伊人精品成人久久综合97| 久久婷婷久久| 亚洲在线观看| 欧美mv日韩mv国产网站| 午夜视频精品| 欧美大尺度在线观看| 欧美电影专区| 欧美中文字幕| 欧美高清免费| 美女主播一区| 国产无遮挡一区二区三区毛片日本| 亚洲福利一区| 韩国av一区| 一本色道精品久久一区二区三区 | 亚洲专区一区| 欧美高清hd18日本| 老司机午夜精品视频| 欧美亚男人的天堂| 亚洲国产婷婷| 国产日韩精品视频一区二区三区| 一区二区三区在线视频观看| 亚洲精选在线观看| 在线看国产日韩| 亚洲欧美精品中文字幕在线| 99这里只有精品| 美女在线一区二区| 久久久久综合一区二区三区| 国产精品久久久久999| 亚洲国产日韩欧美在线99| 国产亚洲第一区| 亚洲午夜精品一区二区| 日韩一级成人av| 蜜臀a∨国产成人精品| 老司机午夜免费精品视频| 国产亚洲精品aa午夜观看| 亚洲在线网站| 亚洲欧美日韩国产| 欧美亚男人的天堂| 最近看过的日韩成人| 老司机一区二区三区| 国产麻豆综合| 在线亚洲观看| 一区二区免费在线观看| 欧美连裤袜在线视频| 最新亚洲一区| 亚洲私人影院| 国产精品久久午夜| 午夜日韩在线观看| 久久九九热re6这里有精品| 国产日韩1区| 欧美一级专区免费大片| 久久成人18免费网站| 国产日韩欧美另类| 欧美一区二区三区四区在线观看地址| 久久精品二区亚洲w码| 国产一区二区三区av电影 | 奶水喷射视频一区| 亚洲国产精品久久人人爱蜜臀| 亚洲精选中文字幕| 欧美日韩一区二区三区在线看| 一区二区三区国产精华| 校园激情久久| 极品少妇一区二区| 欧美精品九九| 亚欧成人在线| 国产一二精品视频| 亚洲欧美综合精品久久成人| 久久精品国产第一区二区三区| 欧美在线观看www| 欧美在线一级视频| 在线免费精品视频| 欧美了一区在线观看| 日韩一区二区久久| 欧美一区二区日韩一区二区| 韩国av一区二区三区在线观看| 巨乳诱惑日韩免费av| 亚洲精品女人| 亚洲一区二区影院| 国产一级久久| 欧美国产日产韩国视频| 亚洲砖区区免费| 欧美电影免费观看高清| 亚洲一区二区av电影| 欧美喷水视频| 久久精品99久久香蕉国产色戒| 久久一日本道色综合久久| 亚洲国产精品福利| 久久国产福利| 亚洲国产中文字幕在线观看| 国产精品久久999| 开心色5月久久精品| 亚洲视频香蕉人妖| 亚洲国产成人91精品| 午夜视频在线观看一区二区| 亚洲国产精品成人一区二区| 国产精品人人做人人爽人人添| 欧美成人一区二区三区| 欧美一区二区黄| 日韩亚洲在线| 欧美激情在线狂野欧美精品| 午夜一区不卡| 一区二区三区免费观看| 亚洲高清成人| 国产欧美一区二区精品忘忧草| 欧美国产日产韩国视频| 欧美在线综合视频| 在线一区二区视频| 最新日韩在线视频| 欧美激情a∨在线视频播放| 久久久久综合| 欧美在线在线| 亚洲欧美偷拍卡通变态| 夜夜精品视频一区二区| 亚洲人成小说网站色在线| 伊人狠狠色j香婷婷综合| 欧美日韩精品在线| 欧美精品一区二区高清在线观看| 久久久国产精品一区| 先锋资源久久| 香蕉久久国产| 香蕉成人伊视频在线观看| 亚洲制服欧美中文字幕中文字幕| 日韩一级裸体免费视频| 亚洲免费成人| 在线一区免费观看| 亚洲综合国产| 欧美一区二区三区四区高清 | 国产精品视频一区二区三区| 欧美色网在线| 国产精品一区二区在线观看网站 | 在线观看福利一区| 一区二区三区亚洲| 国产在线欧美| 伊人久久亚洲影院| 亚洲国产99精品国自产| 亚洲精品欧美一区二区三区| 亚洲日本成人| 99精品国产在热久久婷婷| 一区二区三区你懂的| 亚洲影视九九影院在线观看| 午夜精品视频一区| 一区二区视频免费在线观看| 国内精品福利| 嫩草成人www欧美| 麻豆精品视频| 亚洲国产精品va在线看黑人| 亚洲人成网站在线播| 亚洲精品视频在线看| 一区二区三区四区五区视频|