arm9200開發文檔

2007.8.13

u-boot1.1.6初步調試成功。

1.在網上找了幾個u-boot的移植文檔,之前一直沒有成功,後來,設置好u-boot的程序運行地址後,make clean && make at91rm9200dk_config && make ,生成u-boot.bin文件。

2.在調試好arm9200的仿真器後,選擇File->Load memory from file ,選擇u-boot.bin 文件。

3.文件Load 成功以後,將PC指針設置爲u-boot程序的運行地址。

4.執行程序,即可在串口終端看到u-boot的提示符。

2007.8.14

1.發現在文件Start.S中調用了LowLevelInit函數,初始化SDRAM,終端,DEBUG串口,NAND等,根據需要添加。在u-boot中沒有進行LowLevelInit,所以會出現初始化不正確的時候會有問題。

2.經常會出現IIC不能寫的狀況,原因不明。

3.AXD調試的時候,經常要重啓纔可以。有時候要進行斷電。

4.u-boot的程序啓動地址在board/at91rm9200dk/config.mk中修改TEXT_BASE的值

2007.8.15

1.研究PMC時鐘是怎麼回事,給個時鐘是如何產生的,看數據手冊的方框圖。

  設置master clock 的寄存器,選擇使用slow clock ,main clock,plla,pllb中的一個作爲時鐘輸入,通過master clock controller後生成master clock process clock.選擇的pllapllb可以通過設置相應的寄存器來倍頻main clock.

2007-8-20

1.u-boot-1.1.6成功從nand flash 上啓動。但是還有很多問題沒有搞清楚。board/at91rm9200dk/config.mk,這個TEXT_BASE的值所起的作用,沒有搞清楚。U-boot.bin

文件從flash中讀取到sdram中的內存的位置不是這個地址,也還是可以啓動的。所以,之前的bios9200的代碼完全不用作任何的改變,就可以將u-boot燒寫到nand flash上,並且讀入內存,啓動u-boot。之前雖然也進行過直接燒寫的工作,但是可能是u-boot中的代碼,初始化的串口有問題,造成沒有什麼輸出,顯示的。現在代碼中寫死了。

2.閱讀了一下bios9200的代碼,關鍵的部分在於,不同的板子,要進行不同的LowLevelInit工作的,所以之前的at91rm9200_for_Uboot,不能夠使用,也是因爲LowLevelInit初始化的可能有些問題,在u-boot 啓動的時候,按照網上的修改方法,並沒有進行LowLevelInit,所以出現問題。

3.u-boot的移植配置,參看以下文章

開發板H9200M簡介

FLSH: 4M (2M×16)  ->固化Linux內核      0x1000_0000-0x103_FFFF
SDRAM: 32M (2×8M×16
)           0x2000_0000-0x21FF_FFFF
NAND Flash: 64M ->
存放數據

JP100: 1
2短接,從flash啓動,啓動Flash中固化的程序。
       2
3短接,從片內ROM啓動,啓動片內ROM中的程序。

[編輯]

主要地址資源分配

[編輯]

使用廠商提供的低級初始化模塊的資源分配

資源名字

接口方式

內存分佈

備註

SDRAM

NCS1

20000000-21FFFFFF

32M

FLASH

NCS0

10000000-103FFFFF

4M

 

 

10000000-10005FFF

boot.bin

 

 

10010000-1001FFFF

Uboot.gz

 

 

10020000-1015FFFF

uImage

 

 

10160000-102FFFFF

ramdisk

 

 

103F0000-103FFFFF

環境變量的存放地點

[編輯]

完全使用Uboot來做bootloader的資源分配

資源名字

接口方式

內存分佈

備註

SDRAM

NCS1

20000000-21FFFFFF

32M

FLASH

NCS0

10000000-103FFFFF

4M

 

 

10000000-1001FFFF

u-boot.bin

 

 

10020000-1015FFFF

uImage

 

 

10160000-102FFFFF

ramdisk

 

 

103F0000-103FFFFF

環境變量的存放地點

[編輯]

移植u-boot到目標板

[編輯]

U-Boot主要目錄結構

board 目標板相關文件,比如Makefileu-boot.lds等都和具體的開發板的硬件和地址分配有關;
common
獨立於處理器體系結構的通用代碼,與體系結構無關的文件。實現各種命令的C文件,如內存大小探測與故障檢測;
cpu
與處理器相關的文件。如mpc8xx子目錄下含串口、網口、LCD驅動及中斷初始化等文件;
disk disk
驅動的分區處理代碼
driver
通用設備驅動,如CFI FLASH驅動(目前對INTEL FLASH支持較好)
doc U-Boot
的說明文檔;
examples
可在U-Boot下運行的示例程序;如hello_world.c,timer.c
include U-Boot
頭文件;尤其configs子目錄下與目標板相關的配置頭文件是移植過程中經常要修改的文件;
lib_xxx
處理器體系相關的文件,如lib_ppc, lib_arm目錄分別包含與PowerPCARM體系結構相關的文件;
net
與網絡功能相關的文件目錄,如bootp,nfs,tftp
post
上電自檢文件目錄。尚有待於進一步完善;
rtc RTC
驅動程序;
tools
用於創建U-Boot S-RECORDBIN鏡像文件的工具;

[編輯]

u-boot1.1.6boot.bin移植方法

1、增加目標平臺到./board/下(此步驟可選,主要爲了不影響源碼)

    因爲我們當前平臺h9200m用的是at91rm9200 CPU,因此我們找最接近的已有平臺來簡化移植過程,進入board目錄下,以原有at91rm9200dk爲模板,拷貝at91rm9200dk爲我們 h9200m目錄,進入目錄h9200m,將at91rm9200dk.c更名爲h9200m.c,再編輯當前目錄下的Makefile,編輯並搜索 at91rm9200,在28行會找到at91rm9200dk.o,將其改爲h9200m.o;目錄中config.mk是用來記錄U-boot複製到 內存的基址,flash.c用來配置Flashu-boot.lds是內核鏈接器的腳本文件。 命令:

cd u-boot-1.1.6/board
cp at91rm9200dk/ h9200m –R
cd h9200m
mv at91rm9200dk.c h9200m.c
vi Makefile
       /at91rm9200  
u-boot 1.1.6版本中在第28行)
      
修改at91rm9200dkh9200m

2、進入./include/configs

    at91rm9200dk.h爲模板,生成h9200m.h;在這裏的文件都是和硬件系統配置息息相關,它需記錄新平臺的所有配置參數。 命令:

cd u-boot-1.1.6/include/configs
cp at91rm9200dk.h h9200m.h

3、修改Makefile以及

    編輯源碼根目錄下的Makefile,搜索at91rm92001.1.6版本在1766行,在1768行插入配置代碼,編輯源碼目錄下 MAKEALL,搜索at91rm92001.1.6版本在190行,在at91rm9200dk後加入h9200m即可。
命令:

vi u-boot-1.1.6/Makefile
       /at91rm9200
      
輸入:
       h9200m_config   :        unconfig
                @$(MKCONFIG) $(@:_config=) arm arm920t h9200m NULL at91rm9200
vi u-boot-1.1.6/MAKEALL
       /AT91RM9200      (1.1.6
版本是在第190)
     
(插入h9200m,插入後如下:)

             At91rm9200dk     h9200m      cmc_pu2                    /

4、根據具體的硬件配置,修改參數

    因爲在at91rm9200引導時,廠商提供了前期初始化的boot.bin,它主要作了部分的硬件初始化,替代U-boot stage1部分,所以在U-boot中就應該去掉這部分功能,不然會導致重複配置,使U-boot在初始配置時當掉,因此我們要修改. /include/configs/h9200m.h,添加#define CONFIG_SKIP_LOWLEVEL_INIT 1(我們默認添在第40行),使U-boot跳過低級初始化過程;我們使用的開發板的nor flash4M的,因此我們搜索PHYS_FLASH_SIZE,複製這行,並將上面的原始一行註釋掉,將下面的0x200000改爲 0x400000,在163行。 命令:

vi u-boot-1.1.6/include/configs/h9200m.h
       :40
      
添加#define CONFIG_SKIP_LOWLEVEL_INIT 1
       :161
/PHYS_FLASH_SIZE
      
修改0x200000改爲
0x400000
       :164
/CFG_MAX_FLASH_SECT
      
修改256改爲
71
       :200
/CFG_PROMPT
      
修改Uboot>改爲
H9200M>
      
註釋掉188192行、
196
       /* #ifdef CONFIG_SKIP_LOWLEVEL_INIT
       ... ...
       #else */
       ... ...
       /*#endif*/      /* CONFIG_SKIP_LOWLEVEL_INIT */
      
註釋掉176179行、182

       /*  #ifdef CONFIG_SKIP_LOWLEVEL_INIT
       ... ...
       /*#endif*/      /* CONFIG_SKIP_LOWLEVEL_INIT */
       ... ...
      
修改180181兩行爲
       #define CFG_ENV_ADDR     (PHYS_FLASH_1 + 0x103f000)  /* end flash */
       #define CFG_ENV_SIZE     0x10000  /* 64K */

5、下面我們要進行鍼對板子的具體化設置

編輯./board/h9200m/h9200m.c,跳轉到第50行,

gd->bd->bi_arch_number = MACH_TYPE_AT91RM9200;
修改爲gd->bd->bi_arch_number = MACH_TYPE_H9200M;

再編輯./include/asm-arm/mach-types.h,跳轉到第740行,添加硬件設備的ID號,我們在這裏使用1888作爲h9200m的設備號

#define MACH_TYPE_H9200M                1888

這樣我們的開發板就有自己的設備號了,不過kernel是不成認的,如果你想讓全世界人都承認,你還要到www.kernel.com去申請你的設備,這樣一來所有內核源碼中都會有這一段代碼了;上面的做法僅用來測試使用。 (至此一個可以啓動的Uboot就已經完成了)

[編輯]

從裸板開始,假設flash中沒有內容,從新載入uboot

a.PC宿主機設置

windows下,打開超級終端,設置串口爲115200 8N1 無流控

b.JP100設置爲23短接,從片內rom啓動,啓動片內ROM中的程序。上電,復位,超級終端下出現”CCCCCCC”

c.Xmodem協議發送loader.bin,發完繼續出現”CCCCCC”

d.再用Xmodem協議發送u-boot.bin,發完顯示>U-Boot>提示符

e.擦除FLASH:

>protect off all
>erase all

上述兩步擦除FLASH中所有內容,若只擦除uboot所佔部分,則

>protect off 10000000 1001FFFF
>erasse 10000000 1001FFFF
>protect on 10000000 1001FFFF

(待證實)

>protect off 1:0-1
>erase 1:0-1
>protect on 1:0-1

f.裝入boot.bin

>loadb 20000000  (能過串口線(Kermit mode)來裝載二進制文件)

在超級終端下,用kermit模式發送boot.bin

>cp.b 20000000 10000000 5ffff

g.裝入u-boot.gz

>loadb 20000000

kermit模式發送u-boot.gz

>cp.b 20000000 10010000 ffff
>protect on 10000000 1001ffff   (FLASH
區域保護)

h.JP100設置爲12短接,從flash啓動,啓動Flash中固化的程序。

[編輯]

環境變量設置

a.網絡參數設置

>setenv ethaddr 12:34:56:78:99:aa      ;MAC地址
>setenv ipaddr IP
地址(192.168.0.139)             ;目標板IP
>setenv serverip
服務器地址(192.168.0.123)       ;服務器
IP
>setenv bootdelay 5                 ;
延時

>saveenv                            ;
保存

b.系統自動運行

注意:這裏設置爲絡服務器啓動模式,用網線從主機上下載內核和文件系統到SDRAM中,每次掉電後都要重新開始。

>setenv bootargs root=/dev/ram rw initrd=0x21100000,6000000 ramdisk_size=15360
 consloe=ttyS0,115200 mem=32M
>saveenv

initrd指定根文件系統的位置

>setenv bootcmd tftp 21000000 uimage/; tftp 21100000 ramdisk.gz/; bootm 21000000
>saveenv

    設定自動啓動腳本,先用tftp下載內核鏡象到21000000 ,然後下載文件系統到21100000,再從內核鏡象地址21000000啓動

注意:必須確保主機上啓動了tftp服務,在根目錄上有tftpboot目錄。可用rpm –q tftp查看是否安裝了tftp,若沒有的話,則需要安裝。在服務配置裏選定tftp服務,開始。設置開機時自動啓動tftp服務。執行ntsysv 令,然後選擇需要開機自動啓動的服務,nfs,tftp等,以空格選擇。

linux下的終端執行minicom,則啓動串口終端,可以用minicom –s設置。

 

 

2007-8-21 NAND 移植成功

       主要參看了網上的幾篇文章,http://bbs2.chinaunix.net/viewthread.php?tid=855860

       http://www.lupaworld.com/23340/viewspace_4343.html

重點內容如下部分:

對於uboot的移植請參考我之前寫的《U-Boot的編譯與移植到QT-S3C44B0X開發板上》http://bbs.chinaunix.net/viewthr ... p;highlight=pywj777

非常感謝dozec的《基於S3C2410Linux全線移植文檔》http://bbs.chinaunix.net/viewthr ... Linux全線移植文檔我的nand flash移植大部分是參考這個文檔移植成功的。

下面對nand flash的初始化代碼nand_init()進行分析:
1.
如果定義(CONFIG_COMMANDS & CFG_CMD_NAND)沒定義(CFG_NAND_LEGACY) start_armboot()調用driver/nand/nand.c中的nand_init(),否則如果定義(CONFIG_COMMANDS & CFG_CMD_NAND)並且有定義了CFG_NAND_LEGACY,則調用自己定義的nand_init()。在我當前的情景中是使用driver/nand/nand.c中的nand_init()
2.nand_init()
調用本文件中的nand_init_chip()nand進行初始化。
3.nand_init_chip()
首先調用board_nand_init()
4.board_nand_init()
是需要自己添加的函數,這個函數的主要功能是對struct nand_chip結構體的函數指針賦值,讓它們指向自己爲nand驅動編寫的一些函數,對未賦值的指針,uboot會在後面爲其賦上通用nand驅動函數指針。
5.nand_init_chip()
接着調用nand_scan().
6.nand_scan()
定義在drivers/nand/nand_base.c文件中。它首先對struct nand_chip結構體中在board_nand_init()函數中未賦值的指針賦上通用nand驅動函數指針。

7.
通用nand驅動函數nand_select_chip()賦值給struct nand_chip結構體的函數指針用於打開或關閉nand芯片,0爲打開,1爲關閉。在這個函數中會調用nand_chip結構體中的hwcontrol函數指針,這個指針指向的函數是需要自己編寫的。這個函數指針在board_nand_init()函數中被賦值。主要作用是向nand flash發送一些nand flash開啓與關閉命令。
8.nand_scan()
剩餘部分初始化nand_chipmtd_info結構體。
9.nand_scan()
最後在返回時調用drivers/nand/nand_bbt.c文件中的nand_default_bbt()
10.nand_default_bby()
選擇一個壞塊描述表,返回時調用本文件中的nand_scan_bbt()
11.nand_scan_bbt()
尋找建立一個壞塊描述表。
12.
最後返回到nand_init(),這樣nand驅動的初始化完成了。

下面對命令nand read addr ofs size的執行流程進行分析:
1.nand read addr ofs size
命令的作用是從nand flash地址的偏移量ofs處讀取長度爲size字節的數據存儲到內存地址addr處。
2.common/main.c
文件中的main_loop()主要執行read_line()讀取命令行。
3.read_line()
讀取到命令行後會調用common/main.c文件中的run_command()
4.run_command()
調用common/command.c文件中的find_cmd().u_boot_cmd段中尋找該命令的cmd_tbl_t結構,找到後返回該結構。該命令的結構是通過定義在include/command.h中的宏定義U_BOOT_CMD登記進.u_boot_cmd段中的。
5.run_command()
找到該命令的cmd_tbl_t結構後則執行該命令對應的函數。對於本情景是nand命令對應的函數do_nand()
6.do_nand()
有兩個版本,一個是定義了CFG_NAND_LEGACY。另一個是未定義CFG_NAND_LEGACY。這兩個版本都定義在common/cmd_nand.c文件中。對於本情景使用未定義CFG_NAND_LEGACYdo_nand()函數。要使用do_nand()還必須定義宏CONFIG_COMMANDS&CFG_CMD_NAND。(若未定義CFG_NAND_LEGACY則在這個情景中的do_nand()函數調用的函數都定義在drivers/nand_legacy/nand_legacy.c文件中)。
7.
對於我們的情景do_nand()會調用定義在include/nand.h文件中的nand_read()
8.nand_read()
則調用本nand芯片對應的nand_info_t結構的read指針。而read指針在nand_scan()中被指向了同文件(drivers/nand/nand_base.c)中的nand_read()函數。
9.nand_read()
函數最終會調用nand_chip結構中的cmdfunc指針,通過這個指針指向的函數向nand flash芯片發送命令。最終完成整個命令的執行。

爲了讓uboot支持自己QT板子的nand flash而進行修改的部分
1.
前面的移植請參考我寫的一篇《U-Boot的編譯與移植到QT-S3C44B0X開發板上》,現在在board/51EDA/QT/目錄下建立nand.c文件。
2.
nand.c中添加自己的board_nand_init()函數。設定nand_chip結構中的hwcontroldev_ready指針指向自己的函數QT_hwcontrolQT_device_ready。並建立自己的QT_hwcontrolQT_device_ready函數。
3.
由於自己板子的nand flash的命令發送方式與uboot提供的通用nand flash命令發送方式不同,所以在nand.c文件中建立自己的命令發送函數QT_nand_command(),並在board_nand_init()函數中將nand_chip結構中的cmdfunc指針指向QT_nand_command()函數,使其使用自己定義的發送命令函數。
4.
include/configs/QT.h中定義CFG_NAND_BASE用於指定自己板子nand flashI/O地址。
5.
CONFIG_COMMANDS中打開CFG_CMD_NAND選項。
6.
include/configs/QT.h中定義NAND_MAX_CHIPS指定自己板子的nand flash芯片數。
7.
include/configs/QT.h中定義CFG_MAX_NAND_DEVICE指定想要支持的nand flash設備數。

dozec
的《基於S3C2410Linux全線移植文檔》在U-BOOTNand Flash的支持中的移植方法是在定義了CFG_NAND_LEGACY情況下移植的。而我的是在未定義CFG_NAND_LEGACY的情況下移植的。


       基於以上的分析,仔細閱讀u-boot的代碼主要修改board/at91rm9200dk/at91rm9200dk.c

/*

 * Disk On Chip (NAND) Millenium initialization.

 * The NAND lives in the CS2* space

 */

#if (CONFIG_COMMANDS & CFG_CMD_NAND)

extern ulong nand_probe (ulong physadr);

 

#define AT91_SMARTMEDIA_BASE 0x40000000    /* physical address to access memory on NCS3 */

void nand_init (void)

{

       /* Setup Smart Media, fitst enable the address range of CS3 */

       *AT91C_EBI_CSA |= AT91C_EBI_CS3A_SMC_SmartMedia;

       //CFGR

#define AT91C_EBI_DBPUC       ((unsigned int) 0x1 <<0)

#define AT91C_EBI_EBSEN ((unsigned int) 0x1 <<1)

       AT91C_BASE_EBI->EBI_CFGR =(AT91C_EBI_DBPUC & 0x00 ) | (AT91C_EBI_EBSEN & 0x00);

 

//根據不同的flash 對寄存器進行相應的設置

/*    AT91C_BASE_SMC2->SMC2_CSR[3] = (SM_RWH | SM_RWS |

              AT91C_SMC2_ACSS_STANDARD | AT91C_SMC2_DBW_8 |

              SM_TDF | AT91C_SMC2_WSEN | SM_NWS);*/

       AT91C_BASE_SMC2->SMC2_CSR[3] = (AT91C_SMC2_NWS & 0x04) |

                                   AT91C_SMC2_WSEN |

                                   (AT91C_SMC2_TDF & 0X200) |

                                   (AT91C_SMC2_BAT) |

                                   AT91C_SMC2_DBW_8;

 

       /* enable the SMOE line PC0=SMCE, A21=CLE, A22=ALE */

       *AT91C_PIOC_ASR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE |

              AT91C_PC3_BFBAA_SMWE;

       *AT91C_PIOC_PDR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE |

              AT91C_PC3_BFBAA_SMWE;

 

//flash CEPC15 REPC14,所以進行以下配置,根據不同的板子來

       *AT91C_PMC_PCER = 1 << AT91C_ID_PIOC;

       //enable PC14 bid output

       *AT91C_PIOC_ODR = AT91C_PIO_PC14;

       *AT91C_PIOC_PER = AT91C_PIO_PC14;

       //pull-up 14

       AT91C_BASE_PIOC->PIO_PPUDR = ~AT91C_PIO_PC14;

       AT91C_BASE_PIOC->PIO_PPUER = AT91C_PIO_PC14;

             

       //enable pc15 for output

       *AT91C_PIOC_PER = AT91C_PIO_PC15;

       AT91C_BASE_PIOC->PIO_OER = AT91C_PIO_PC15;

 

//進行短暫的延時

       int j;

       for(j=0;j<50000;j++);

 

       printf ("%4lu MB/n", nand_probe(AT91_SMARTMEDIA_BASE) >> 20);

}

 

 

修改配置文件include/configs/at91rm9200dk.h中關於nand flash的宏定義

//增加nand的命令支持

#define CONFIG_COMMANDS          /

                     ((CONFIG_CMD_DFL | CFG_CMD_MII |/

                     CFG_CMD_DHCP | CFG_CMD_NAND ) & /

                    ~(CFG_CMD_BDI | /

                     CFG_CMD_IMI | /

                     CFG_CMD_AUTOSCRIPT | /

                     CFG_CMD_FPGA | /

                     CFG_CMD_MISC | /

                     CFG_CMD_LOADS ))

 

/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */

#include <cmd_confdefs.h>

//#include <asm/arch/AT91RM9200.h>

 

#define CFG_NAND_LEGACY   1     //使用board/at91rm9200dk/at91rm9200dk.c中的nand_init()函數和driver/nand_legacy/nand_legacy.c中的函數,如果不定義,使用driver/nand/nand.c中的nand_init()

#define CFG_MAX_NAND_DEVICE  1     /* Max number of NAND devices        */

 

#define SECTORSIZE 512

 

#define ADDR_COLUMN 1

#define ADDR_PAGE 2

#define ADDR_COLUMN_PAGE 3

 

#define NAND_ChipID_UNKNOWN  0x00

#define NAND_MAX_FLOORS 1

#define NAND_MAX_CHIPS 1

 

//my ale cle 這個不是很明白,應該根據你的板子上的連接來設置,看你的flash 上的cleale分別接的是那一根地址線

#define AT91_SMART_MEDIA_ALE (1 << 21)  /* our ALE is AD21 */

#define AT91_SMART_MEDIA_CLE (1 << 22)  /* our CLE is AD22 */

 

//PC15接的是CEPC14接的是RE

#define NAND_DISABLE_CE(nand) do { *AT91C_PIOC_SODR = AT91C_PIO_PC15;} while(0)

#define NAND_ENABLE_CE(nand) do { *AT91C_PIOC_CODR = AT91C_PIO_PC15;} while(0)

 

#define NAND_WAIT_READY(nand) while (!(*AT91C_PIOC_PDSR & AT91C_PIO_PC14))

 

#define WRITE_NAND_COMMAND(d, adr) do{ *(volatile __u8 *)((unsigned long)adr | AT91_SMART_MEDIA_CLE) = (__u8)(d); } while(0)

#define WRITE_NAND_ADDRESS(d, adr) do{ *(volatile __u8 *)((unsigned long)adr | AT91_SMART_MEDIA_ALE) = (__u8)(d); } while(0)

#define WRITE_NAND(d, adr) do{ *(volatile __u8 *)((unsigned long)adr) = (__u8)d; } while(0)

#define READ_NAND(adr) ((volatile unsigned char)(*(volatile __u8 *)(unsigned long)adr))

/* the following are NOP's in our implementation */

//要進行修改,按以下定義

#define NAND_CTL_CLRALE(nandptr)     (nandptr & ~(AT91_SMART_MEDIA_ALE))

#define NAND_CTL_SETALE(nandptr)      (nandptr|AT91_SMART_MEDIA_ALE)

#define NAND_CTL_CLRCLE(nandptr)      (nandptr & ~(AT91_SMART_MEDIA_CLE))

#define NAND_CTL_SETCLE(nandptr)      (nandptr|AT91_SMART_MEDIA_CLE)

 

2007-8-22

1.解決環境變量env的存儲問題。

描述:在cmd_nvedit.c中,檢查環境變量存儲在那裏。可選的有 CFG_ENV_IS_IN_NVRAM

    CFG_ENV_IS_IN_EEPROM

    CFG_ENV_IS_IN_FLASH

    CFG_ENV_IS_IN_DATAFLASH

    CFG_ENV_IS_IN_NAND

CFG_ENV_IS_NOWHERE

include/configs/at91rm9200.h中定義其中的一種就可以,因爲還沒有搞好I2C,所以目前先使用NAND flash。在該文件中添加:

#define CFG_ENV_IS_IN_NAND

#define CFG_ENV_OFFSET                                   0x40000                //環境變量存儲位置偏移

#define CFG_ENV_SIZE                                 0x20000                //環境變量存儲大小

#define CFG_ENV_ADDR                               0x40040000          

並且註釋掉其他的ENV的設置。

 

由於nand的驅動使用了nand_legacy.c中的nand接口函數。所以要修改common/env_nand.c中的saveenv 函數和env_relocate_spec函數。

 

int saveenv(void)

{

       ulong total;

       int ret = 0;

 

       puts ("Erasing Nand...");

       /*

       if (nand_erase(&nand_info[0], CFG_ENV_OFFSET, CFG_ENV_SIZE))

              return 1;

       */

       if (nand_legacy_erase(&nand_dev_desc[0], CFG_ENV_OFFSET, CFG_ENV_SIZE,1))

              return 1;

 

       puts ("Writing to Nand... ");

       total = CFG_ENV_SIZE;

       /*

       ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr);

       if (ret || total != CFG_ENV_SIZE)

              return 1;

       */

       ret = nand_legacy_rw(&nand_dev_desc[0] , 0x00 ,CFG_ENV_OFFSET,CFG_ENV_SIZE, (size_t *)&total, (u_char*)env_ptr);

 

       puts ("done/n");

       return ret;

}

 

/*

 * The legacy NAND code saved the environment in the first NAND device i.e.,

 * nand_dev_desc + 0. This is also the behaviour using the new NAND code.

 */

void env_relocate_spec (void)

{

#if !defined(ENV_IS_EMBEDDED)

       ulong total;

       int ret;

 

       total = CFG_ENV_SIZE;

//     ret = nand_read(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr);

       ret = nand_legacy_rw(&nand_dev_desc[0], 0x01 ,CFG_ENV_OFFSET,CFG_ENV_SIZE, (size_t *)&total, (u_char*)env_ptr);

 

     if (ret || total != CFG_ENV_SIZE)

              return use_default();

 

       if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc)

              return use_default();

#endif /* ! ENV_IS_EMBEDDED */

}

 

2007-8-27

內核與文件系統移植成功。其中經歷了不少的問題。主要是這麼幾個方面:

1.       uboot中的bootargs的設置,init=/linuxrc  console=/dev/ttyS0,115200 root=/dev/mtdblock2

2.       自動啓動內核的時候,bootcmd的設置在內核中要給nand flash 分好區的,在第三個分區燒寫上文件系統。

3.       編譯busybox,寫好rcS文件。

 

2007-8-28

1.明確的幾個問題。

       1)在當前的啓動方式下,uboot僅僅相當於提供了方便的方式下載內核,文件系統的任務,如何能夠讓uboot自己完成啓動的全部任務。目前爲eeprom中的bios程序,調用燒寫在nand flash上的uboot,完成啓動。但是bios要是從nand flash上讀出uboot,就必須移植nand flash的驅動纔可以,這樣相當於bios也可以完成燒寫nand flash的任務。那麼是不是有辦法讓uboot燒寫在eeprom中,自己啓動的。

 

2.出現不能初始化console的錯誤的時候,可能是/dev沒有加載,在編譯內核的時候,要選中自動加載/devboot的時候,這個選項。不然程序會因爲找不到/dev/console出錯。

 

 

 

2007.8.13

u-boot1.1.6初步調試成功。

1.在網上找了幾個u-boot的移植文檔,之前一直沒有成功,後來,設置好u-boot的程序運行地址後,make clean && make at91rm9200dk_config && make ,生成u-boot.bin文件。

2.在調試好arm9200的仿真器後,選擇File->Load memory from file ,選擇u-boot.bin 文件。

3.文件Load 成功以後,將PC指針設置爲u-boot程序的運行地址。

4.執行程序,即可在串口終端看到u-boot的提示符。

2007.8.14

1.發現在文件Start.S中調用了LowLevelInit函數,初始化SDRAM,終端,DEBUG串口,NAND等,根據需要添加。在u-boot中沒有進行LowLevelInit,所以會出現初始化不正確的時候會有問題。

2.經常會出現IIC不能寫的狀況,原因不明。

3.AXD調試的時候,經常要重啓纔可以。有時候要進行斷電。

4.u-boot的程序啓動地址在board/at91rm9200dk/config.mk中修改TEXT_BASE的值

2007.8.15

1.研究PMC時鐘是怎麼回事,給個時鐘是如何產生的,看數據手冊的方框圖。

  設置master clock 的寄存器,選擇使用slow clock ,main clock,plla,pllb中的一個作爲時鐘輸入,通過master clock controller後生成master clock process clock.選擇的pllapllb可以通過設置相應的寄存器來倍頻main clock.

2007-8-20

1.u-boot-1.1.6成功從nand flash 上啓動。但是還有很多問題沒有搞清楚。board/at91rm9200dk/config.mk,這個TEXT_BASE的值所起的作用,沒有搞清楚。U-boot.bin

文件從flash中讀取到sdram中的內存的位置不是這個地址,也還是可以啓動的。所以,之前的bios9200的代碼完全不用作任何的改變,就可以將u-boot燒寫到nand flash上,並且讀入內存,啓動u-boot。之前雖然也進行過直接燒寫的工作,但是可能是u-boot中的代碼,初始化的串口有問題,造成沒有什麼輸出,顯示的。現在代碼中寫死了。

2.閱讀了一下bios9200的代碼,關鍵的部分在於,不同的板子,要進行不同的LowLevelInit工作的,所以之前的at91rm9200_for_Uboot,不能夠使用,也是因爲LowLevelInit初始化的可能有些問題,在u-boot 啓動的時候,按照網上的修改方法,並沒有進行LowLevelInit,所以出現問題。

3.u-boot的移植配置,參看以下文章

開發板H9200M簡介

FLSH: 4M (2M×16)  ->固化Linux內核      0x1000_0000-0x103_FFFF
SDRAM: 32M (2×8M×16
)           0x2000_0000-0x21FF_FFFF
NAND Flash: 64M ->
存放數據

JP100: 1
2短接,從flash啓動,啓動Flash中固化的程序。
       2
3短接,從片內ROM啓動,啓動片內ROM中的程序。

[編輯]

主要地址資源分配

[編輯]

使用廠商提供的低級初始化模塊的資源分配

資源名字

接口方式

內存分佈

備註

SDRAM

NCS1

20000000-21FFFFFF

32M

FLASH

NCS0

10000000-103FFFFF

4M

 

 

10000000-10005FFF

boot.bin

 

 

10010000-1001FFFF

Uboot.gz

 

 

10020000-1015FFFF

uImage

 

 

10160000-102FFFFF

ramdisk

 

 

103F0000-103FFFFF

環境變量的存放地點

[編輯]

完全使用Uboot來做bootloader的資源分配

資源名字

接口方式

內存分佈

備註

SDRAM

NCS1

20000000-21FFFFFF

32M

FLASH

NCS0

10000000-103FFFFF

4M

 

 

10000000-1001FFFF

u-boot.bin

 

 

10020000-1015FFFF

uImage

 

 

10160000-102FFFFF

ramdisk

 

 

103F0000-103FFFFF

環境變量的存放地點

[編輯]

移植u-boot到目標板

[編輯]

U-Boot主要目錄結構

board 目標板相關文件,比如Makefileu-boot.lds等都和具體的開發板的硬件和地址分配有關;
common
獨立於處理器體系結構的通用代碼,與體系結構無關的文件。實現各種命令的C文件,如內存大小探測與故障檢測;
cpu
與處理器相關的文件。如mpc8xx子目錄下含串口、網口、LCD驅動及中斷初始化等文件;
disk disk
驅動的分區處理代碼
driver
通用設備驅動,如CFI FLASH驅動(目前對INTEL FLASH支持較好)
doc U-Boot
的說明文檔;
examples
可在U-Boot下運行的示例程序;如hello_world.c,timer.c
include U-Boot
頭文件;尤其configs子目錄下與目標板相關的配置頭文件是移植過程中經常要修改的文件;
lib_xxx
處理器體系相關的文件,如lib_ppc, lib_arm目錄分別包含與PowerPCARM體系結構相關的文件;
net
與網絡功能相關的文件目錄,如bootp,nfs,tftp
post
上電自檢文件目錄。尚有待於進一步完善;
rtc RTC
驅動程序;
tools
用於創建U-Boot S-RECORDBIN鏡像文件的工具;

[編輯]

u-boot1.1.6boot.bin移植方法

1、增加目標平臺到./board/下(此步驟可選,主要爲了不影響源碼)

    因爲我們當前平臺h9200m用的是at91rm9200 CPU,因此我們找最接近的已有平臺來簡化移植過程,進入board目錄下,以原有at91rm9200dk爲模板,拷貝at91rm9200dk爲我們 h9200m目錄,進入目錄h9200m,將at91rm9200dk.c更名爲h9200m.c,再編輯當前目錄下的Makefile,編輯並搜索 at91rm9200,在28行會找到at91rm9200dk.o,將其改爲h9200m.o;目錄中config.mk是用來記錄U-boot複製到 內存的基址,flash.c用來配置Flashu-boot.lds是內核鏈接器的腳本文件。 命令:

cd u-boot-1.1.6/board
cp at91rm9200dk/ h9200m –R
cd h9200m
mv at91rm9200dk.c h9200m.c
vi Makefile
       /at91rm9200  
u-boot 1.1.6版本中在第28行)
      
修改at91rm9200dkh9200m

2、進入./include/configs

    at91rm9200dk.h爲模板,生成h9200m.h;在這裏的文件都是和硬件系統配置息息相關,它需記錄新平臺的所有配置參數。 命令:

cd u-boot-1.1.6/include/configs
cp at91rm9200dk.h h9200m.h

3、修改Makefile以及

    編輯源碼根目錄下的Makefile,搜索at91rm92001.1.6版本在1766行,在1768行插入配置代碼,編輯源碼目錄下 MAKEALL,搜索at91rm92001.1.6版本在190行,在at91rm9200dk後加入h9200m即可。
命令:

vi u-boot-1.1.6/Makefile
       /at91rm9200
      
輸入:
       h9200m_config   :        unconfig
                @$(MKCONFIG) $(@:_config=) arm arm920t h9200m NULL at91rm9200
vi u-boot-1.1.6/MAKEALL
       /AT91RM9200      (1.1.6
版本是在第190)
     
(插入h9200m,插入後如下:)

             At91rm9200dk     h9200m      cmc_pu2                    /

4、根據具體的硬件配置,修改參數

    因爲在at91rm9200引導時,廠商提供了前期初始化的boot.bin,它主要作了部分的硬件初始化,替代U-boot stage1部分,所以在U-boot中就應該去掉這部分功能,不然會導致重複配置,使U-boot在初始配置時當掉,因此我們要修改. /include/configs/h9200m.h,添加#define CONFIG_SKIP_LOWLEVEL_INIT 1(我們默認添在第40行),使U-boot跳過低級初始化過程;我們使用的開發板的nor flash4M的,因此我們搜索PHYS_FLASH_SIZE,複製這行,並將上面的原始一行註釋掉,將下面的0x200000改爲 0x400000,在163行。 命令:

vi u-boot-1.1.6/include/configs/h9200m.h
       :40
      
添加#define CONFIG_SKIP_LOWLEVEL_INIT 1
       :161
/PHYS_FLASH_SIZE
      
修改0x200000改爲
0x400000
       :164
/CFG_MAX_FLASH_SECT
      
修改256改爲
71
       :200
/CFG_PROMPT
      
修改Uboot>改爲
H9200M>
      
註釋掉188192行、
196
       /* #ifdef CONFIG_SKIP_LOWLEVEL_INIT
       ... ...
       #else */
       ... ...
       /*#endif*/      /* CONFIG_SKIP_LOWLEVEL_INIT */
      
註釋掉176179行、182

       /*  #ifdef CONFIG_SKIP_LOWLEVEL_INIT
       ... ...
       /*#endif*/      /* CONFIG_SKIP_LOWLEVEL_INIT */
       ... ...
      
修改180181兩行爲
       #define CFG_ENV_ADDR     (PHYS_FLASH_1 + 0x103f000)  /* end flash */
       #define CFG_ENV_SIZE     0x10000  /* 64K */

5、下面我們要進行鍼對板子的具體化設置

編輯./board/h9200m/h9200m.c,跳轉到第50行,

gd->bd->bi_arch_number = MACH_TYPE_AT91RM9200;
修改爲gd->bd->bi_arch_number = MACH_TYPE_H9200M;

再編輯./include/asm-arm/mach-types.h,跳轉到第740行,添加硬件設備的ID號,我們在這裏使用1888作爲h9200m的設備號

#define MACH_TYPE_H9200M                1888

這樣我們的開發板就有自己的設備號了,不過kernel是不成認的,如果你想讓全世界人都承認,你還要到www.kernel.com去申請你的設備,這樣一來所有內核源碼中都會有這一段代碼了;上面的做法僅用來測試使用。 (至此一個可以啓動的Uboot就已經完成了)

[編輯]

從裸板開始,假設flash中沒有內容,從新載入uboot

a.PC宿主機設置

windows下,打開超級終端,設置串口爲115200 8N1 無流控

b.JP100設置爲23短接,從片內rom啓動,啓動片內ROM中的程序。上電,復位,超級終端下出現”CCCCCCC”

c.Xmodem協議發送loader.bin,發完繼續出現”CCCCCC”

d.再用Xmodem協議發送u-boot.bin,發完顯示>U-Boot>提示符

e.擦除FLASH:

>protect off all
>erase all

上述兩步擦除FLASH中所有內容,若只擦除uboot所佔部分,則

>protect off 10000000 1001FFFF
>erasse 10000000 1001FFFF
>protect on 10000000 1001FFFF

(待證實)

>protect off 1:0-1
>erase 1:0-1
>protect on 1:0-1

f.裝入boot.bin

>loadb 20000000  (能過串口線(Kermit mode)來裝載二進制文件)

在超級終端下,用kermit模式發送boot.bin

>cp.b 20000000 10000000 5ffff

g.裝入u-boot.gz

>loadb 20000000

kermit模式發送u-boot.gz

>cp.b 20000000 10010000 ffff
>protect on 10000000 1001ffff   (FLASH
區域保護)

h.JP100設置爲12短接,從flash啓動,啓動Flash中固化的程序。

[編輯]

環境變量設置

a.網絡參數設置

>setenv ethaddr 12:34:56:78:99:aa      ;MAC地址
>setenv ipaddr IP
地址(192.168.0.139)             ;目標板IP
>setenv serverip
服務器地址(192.168.0.123)       ;服務器
IP
>setenv bootdelay 5                 ;
延時

>saveenv                            ;
保存

b.系統自動運行

注意:這裏設置爲絡服務器啓動模式,用網線從主機上下載內核和文件系統到SDRAM中,每次掉電後都要重新開始。

>setenv bootargs root=/dev/ram rw initrd=0x21100000,6000000 ramdisk_size=15360
 consloe=ttyS0,115200 mem=32M
>saveenv

initrd指定根文件系統的位置

>setenv bootcmd tftp 21000000 uimage/; tftp 21100000 ramdisk.gz/; bootm 21000000
>saveenv

    設定自動啓動腳本,先用tftp下載內核鏡象到21000000 ,然後下載文件系統到21100000,再從內核鏡象地址21000000啓動

注意:必須確保主機上啓動了tftp服務,在根目錄上有tftpboot目錄。可用rpm –q tftp查看是否安裝了tftp,若沒有的話,則需要安裝。在服務配置裏選定tftp服務,開始。設置開機時自動啓動tftp服務。執行ntsysv 令,然後選擇需要開機自動啓動的服務,nfs,tftp等,以空格選擇。

linux下的終端執行minicom,則啓動串口終端,可以用minicom –s設置。

 

 

2007-8-21 NAND 移植成功

       主要參看了網上的幾篇文章,http://bbs2.chinaunix.net/viewthread.php?tid=855860

       http://www.lupaworld.com/23340/viewspace_4343.html

重點內容如下部分:

對於uboot的移植請參考我之前寫的《U-Boot的編譯與移植到QT-S3C44B0X開發板上》http://bbs.chinaunix.net/viewthr ... p;highlight=pywj777

非常感謝dozec的《基於S3C2410Linux全線移植文檔》http://bbs.chinaunix.net/viewthr ... Linux全線移植文檔我的nand flash移植大部分是參考這個文檔移植成功的。

下面對nand flash的初始化代碼nand_init()進行分析:
1.
如果定義(CONFIG_COMMANDS & CFG_CMD_NAND)沒定義(CFG_NAND_LEGACY) start_armboot()調用driver/nand/nand.c中的nand_init(),否則如果定義(CONFIG_COMMANDS & CFG_CMD_NAND)並且有定義了CFG_NAND_LEGACY,則調用自己定義的nand_init()。在我當前的情景中是使用driver/nand/nand.c中的nand_init()
2.nand_init()
調用本文件中的nand_init_chip()nand進行初始化。
3.nand_init_chip()
首先調用board_nand_init()
4.board_nand_init()
是需要自己添加的函數,這個函數的主要功能是對struct nand_chip結構體的函數指針賦值,讓它們指向自己爲nand驅動編寫的一些函數,對未賦值的指針,uboot會在後面爲其賦上通用nand驅動函數指針。
5.nand_init_chip()
接着調用nand_scan().
6.nand_scan()
定義在drivers/nand/nand_base.c文件中。它首先對struct nand_chip結構體中在board_nand_init()函數中未賦值的指針賦上通用nand驅動函數指針。

7.
通用nand驅動函數nand_select_chip()賦值給struct nand_chip結構體的函數指針用於打開或關閉nand芯片,0爲打開,1爲關閉。在這個函數中會調用nand_chip結構體中的hwcontrol函數指針,這個指針指向的函數是需要自己編寫的。這個函數指針在board_nand_init()函數中被賦值。主要作用是向nand flash發送一些nand flash開啓與關閉命令。
8.nand_scan()
剩餘部分初始化nand_chipmtd_info結構體。
9.nand_scan()
最後在返回時調用drivers/nand/nand_bbt.c文件中的nand_default_bbt()
10.nand_default_bby()
選擇一個壞塊描述表,返回時調用本文件中的nand_scan_bbt()
11.nand_scan_bbt()
尋找建立一個壞塊描述表。
12.
最後返回到nand_init(),這樣nand驅動的初始化完成了。

下面對命令nand read addr ofs size的執行流程進行分析:
1.nand read addr ofs size
命令的作用是從nand flash地址的偏移量ofs處讀取長度爲size字節的數據存儲到內存地址addr處。
2.common/main.c
文件中的main_loop()主要執行read_line()讀取命令行。
3.read_line()
讀取到命令行後會調用common/main.c文件中的run_command()
4.run_command()
調用common/command.c文件中的find_cmd().u_boot_cmd段中尋找該命令的cmd_tbl_t結構,找到後返回該結構。該命令的結構是通過定義在include/command.h中的宏定義U_BOOT_CMD登記進.u_boot_cmd段中的。
5.run_command()
找到該命令的cmd_tbl_t結構後則執行該命令對應的函數。對於本情景是nand命令對應的函數do_nand()
6.do_nand()
有兩個版本,一個是定義了CFG_NAND_LEGACY。另一個是未定義CFG_NAND_LEGACY。這兩個版本都定義在common/cmd_nand.c文件中。對於本情景使用未定義CFG_NAND_LEGACYdo_nand()函數。要使用do_nand()還必須定義宏CONFIG_COMMANDS&CFG_CMD_NAND。(若未定義CFG_NAND_LEGACY則在這個情景中的do_nand()函數調用的函數都定義在drivers/nand_legacy/nand_legacy.c文件中)。
7.
對於我們的情景do_nand()會調用定義在include/nand.h文件中的nand_read()
8.nand_read()
則調用本nand芯片對應的nand_info_t結構的read指針。而read指針在nand_scan()中被指向了同文件(drivers/nand/nand_base.c)中的nand_read()函數。
9.nand_read()
函數最終會調用nand_chip結構中的cmdfunc指針,通過這個指針指向的函數向nand flash芯片發送命令。最終完成整個命令的執行。

爲了讓uboot支持自己QT板子的nand flash而進行修改的部分
1.
前面的移植請參考我寫的一篇《U-Boot的編譯與移植到QT-S3C44B0X開發板上》,現在在board/51EDA/QT/目錄下建立nand.c文件。
2.
nand.c中添加自己的board_nand_init()函數。設定nand_chip結構中的hwcontroldev_ready指針指向自己的函數QT_hwcontrolQT_device_ready。並建立自己的QT_hwcontrolQT_device_ready函數。
3.
由於自己板子的nand flash的命令發送方式與uboot提供的通用nand flash命令發送方式不同,所以在nand.c文件中建立自己的命令發送函數QT_nand_command(),並在board_nand_init()函數中將nand_chip結構中的cmdfunc指針指向QT_nand_command()函數,使其使用自己定義的發送命令函數。
4.
include/configs/QT.h中定義CFG_NAND_BASE用於指定自己板子nand flashI/O地址。
5.
CONFIG_COMMANDS中打開CFG_CMD_NAND選項。
6.
include/configs/QT.h中定義NAND_MAX_CHIPS指定自己板子的nand flash芯片數。
7.
include/configs/QT.h中定義CFG_MAX_NAND_DEVICE指定想要支持的nand flash設備數。

dozec
的《基於S3C2410Linux全線移植文檔》在U-BOOTNand Flash的支持中的移植方法是在定義了CFG_NAND_LEGACY情況下移植的。而我的是在未定義CFG_NAND_LEGACY的情況下移植的。


       基於以上的分析,仔細閱讀u-boot的代碼主要修改board/at91rm9200dk/at91rm9200dk.c

/*

 * Disk On Chip (NAND) Millenium initialization.

 * The NAND lives in the CS2* space

 */

#if (CONFIG_COMMANDS & CFG_CMD_NAND)

extern ulong nand_probe (ulong physadr);

 

#define AT91_SMARTMEDIA_BASE 0x40000000    /* physical address to access memory on NCS3 */

void nand_init (void)

{

       /* Setup Smart Media, fitst enable the address range of CS3 */

       *AT91C_EBI_CSA |= AT91C_EBI_CS3A_SMC_SmartMedia;

       //CFGR

#define AT91C_EBI_DBPUC       ((unsigned int) 0x1 <<0)

#define AT91C_EBI_EBSEN ((unsigned int) 0x1 <<1)

       AT91C_BASE_EBI->EBI_CFGR =(AT91C_EBI_DBPUC & 0x00 ) | (AT91C_EBI_EBSEN & 0x00);

 

//根據不同的flash 對寄存器進行相應的設置

/*    AT91C_BASE_SMC2->SMC2_CSR[3] = (SM_RWH | SM_RWS |

              AT91C_SMC2_ACSS_STANDARD | AT91C_SMC2_DBW_8 |

              SM_TDF | AT91C_SMC2_WSEN | SM_NWS);*/

       AT91C_BASE_SMC2->SMC2_CSR[3] = (AT91C_SMC2_NWS & 0x04) |

                                   AT91C_SMC2_WSEN |

                                   (AT91C_SMC2_TDF & 0X200) |

                                   (AT91C_SMC2_BAT) |

                                   AT91C_SMC2_DBW_8;

 

       /* enable the SMOE line PC0=SMCE, A21=CLE, A22=ALE */

       *AT91C_PIOC_ASR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE |

              AT91C_PC3_BFBAA_SMWE;

       *AT91C_PIOC_PDR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE |

              AT91C_PC3_BFBAA_SMWE;

 

//flash CEPC15 REPC14,所以進行以下配置,根據不同的板子來

       *AT91C_PMC_PCER = 1 << AT91C_ID_PIOC;

       //enable PC14 bid output

       *AT91C_PIOC_ODR = AT91C_PIO_PC14;

       *AT91C_PIOC_PER = AT91C_PIO_PC14;

       //pull-up 14

       AT91C_BASE_PIOC->PIO_PPUDR = ~AT91C_PIO_PC14;

       AT91C_BASE_PIOC->PIO_PPUER = AT91C_PIO_PC14;

             

       //enable pc15 for output

       *AT91C_PIOC_PER = AT91C_PIO_PC15;

       AT91C_BASE_PIOC->PIO_OER = AT91C_PIO_PC15;

 

//進行短暫的延時

       int j;

       for(j=0;j<50000;j++);

 

       printf ("%4lu MB/n", nand_probe(AT91_SMARTMEDIA_BASE) >> 20);

}

 

 

修改配置文件include/configs/at91rm9200dk.h中關於nand flash的宏定義

//增加nand的命令支持

#define CONFIG_COMMANDS          /

                     ((CONFIG_CMD_DFL | CFG_CMD_MII |/

                     CFG_CMD_DHCP | CFG_CMD_NAND ) & /

                    ~(CFG_CMD_BDI | /

                     CFG_CMD_IMI | /

                     CFG_CMD_AUTOSCRIPT | /

                     CFG_CMD_FPGA | /

                     CFG_CMD_MISC | /

                     CFG_CMD_LOADS ))

 

/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */

#include <cmd_confdefs.h>

//#include <asm/arch/AT91RM9200.h>

 

#define CFG_NAND_LEGACY   1     //使用board/at91rm9200dk/at91rm9200dk.c中的nand_init()函數和driver/nand_legacy/nand_legacy.c中的函數,如果不定義,使用driver/nand/nand.c中的nand_init()

#define CFG_MAX_NAND_DEVICE  1     /* Max number of NAND devices        */

 

#define SECTORSIZE 512

 

#define ADDR_COLUMN 1

#define ADDR_PAGE 2

#define ADDR_COLUMN_PAGE 3

 

#define NAND_ChipID_UNKNOWN  0x00

#define NAND_MAX_FLOORS 1

#define NAND_MAX_CHIPS 1

 

//my ale cle 這個不是很明白,應該根據你的板子上的連接來設置,看你的flash 上的cleale分別接的是那一根地址線

#define AT91_SMART_MEDIA_ALE (1 << 21)  /* our ALE is AD21 */

#define AT91_SMART_MEDIA_CLE (1 << 22)  /* our CLE is AD22 */

 

//PC15接的是CEPC14接的是RE

#define NAND_DISABLE_CE(nand) do { *AT91C_PIOC_SODR = AT91C_PIO_PC15;} while(0)

#define NAND_ENABLE_CE(nand) do { *AT91C_PIOC_CODR = AT91C_PIO_PC15;} while(0)

 

#define NAND_WAIT_READY(nand) while (!(*AT91C_PIOC_PDSR & AT91C_PIO_PC14))

 

#define WRITE_NAND_COMMAND(d, adr) do{ *(volatile __u8 *)((unsigned long)adr | AT91_SMART_MEDIA_CLE) = (__u8)(d); } while(0)

#define WRITE_NAND_ADDRESS(d, adr) do{ *(volatile __u8 *)((unsigned long)adr | AT91_SMART_MEDIA_ALE) = (__u8)(d); } while(0)

#define WRITE_NAND(d, adr) do{ *(volatile __u8 *)((unsigned long)adr) = (__u8)d; } while(0)

#define READ_NAND(adr) ((volatile unsigned char)(*(volatile __u8 *)(unsigned long)adr))

/* the following are NOP's in our implementation */

//要進行修改,按以下定義

#define NAND_CTL_CLRALE(nandptr)     (nandptr & ~(AT91_SMART_MEDIA_ALE))

#define NAND_CTL_SETALE(nandptr)      (nandptr|AT91_SMART_MEDIA_ALE)

#define NAND_CTL_CLRCLE(nandptr)      (nandptr & ~(AT91_SMART_MEDIA_CLE))

#define NAND_CTL_SETCLE(nandptr)      (nandptr|AT91_SMART_MEDIA_CLE)

 

2007-8-22

1.解決環境變量env的存儲問題。

描述:在cmd_nvedit.c中,檢查環境變量存儲在那裏。可選的有 CFG_ENV_IS_IN_NVRAM

    CFG_ENV_IS_IN_EEPROM

    CFG_ENV_IS_IN_FLASH

    CFG_ENV_IS_IN_DATAFLASH

    CFG_ENV_IS_IN_NAND

CFG_ENV_IS_NOWHERE

include/configs/at91rm9200.h中定義其中的一種就可以,因爲還沒有搞好I2C,所以目前先使用NAND flash。在該文件中添加:

#define CFG_ENV_IS_IN_NAND

#define CFG_ENV_OFFSET                                   0x40000                //環境變量存儲位置偏移

#define CFG_ENV_SIZE                                 0x20000                //環境變量存儲大小

#define CFG_ENV_ADDR                               0x40040000          

並且註釋掉其他的ENV的設置。

 

由於nand的驅動使用了nand_legacy.c中的nand接口函數。所以要修改common/env_nand.c中的saveenv 函數和env_relocate_spec函數。

 

int saveenv(void)

{

       ulong total;

       int ret = 0;

 

       puts ("Erasing Nand...");

       /*

       if (nand_erase(&nand_info[0], CFG_ENV_OFFSET, CFG_ENV_SIZE))

              return 1;

       */

       if (nand_legacy_erase(&nand_dev_desc[0], CFG_ENV_OFFSET, CFG_ENV_SIZE,1))

              return 1;

 

       puts ("Writing to Nand... ");

       total = CFG_ENV_SIZE;

       /*

       ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr);

       if (ret || total != CFG_ENV_SIZE)

              return 1;

       */

       ret = nand_legacy_rw(&nand_dev_desc[0] , 0x00 ,CFG_ENV_OFFSET,CFG_ENV_SIZE, (size_t *)&total, (u_char*)env_ptr);

 

       puts ("done/n");

       return ret;

}

 

/*

 * The legacy NAND code saved the environment in the first NAND device i.e.,

 * nand_dev_desc + 0. This is also the behaviour using the new NAND code.

 */

void env_relocate_spec (void)

{

#if !defined(ENV_IS_EMBEDDED)

       ulong total;

       int ret;

 

       total = CFG_ENV_SIZE;

//     ret = nand_read(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr);

       ret = nand_legacy_rw(&nand_dev_desc[0], 0x01 ,CFG_ENV_OFFSET,CFG_ENV_SIZE, (size_t *)&total, (u_char*)env_ptr);

 

     if (ret || total != CFG_ENV_SIZE)

              return use_default();

 

       if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc)

              return use_default();

#endif /* ! ENV_IS_EMBEDDED */

}

 

2007-8-27

內核與文件系統移植成功。其中經歷了不少的問題。主要是這麼幾個方面:

1.       uboot中的bootargs的設置,init=/linuxrc  console=/dev/ttyS0,115200 root=/dev/mtdblock2

2.       自動啓動內核的時候,bootcmd的設置在內核中要給nand flash 分好區的,在第三個分區燒寫上文件系統。

3.       編譯busybox,寫好rcS文件。

 

2007-8-28

1.明確的幾個問題。

       1)在當前的啓動方式下,uboot僅僅相當於提供了方便的方式下載內核,文件系統的任務,如何能夠讓uboot自己完成啓動的全部任務。目前爲eeprom中的bios程序,調用燒寫在nand flash上的uboot,完成啓動。但是bios要是從nand flash上讀出uboot,就必須移植nand flash的驅動纔可以,這樣相當於bios也可以完成燒寫nand flash的任務。那麼是不是有辦法讓uboot燒寫在eeprom中,自己啓動的。

 

2.出現不能初始化console的錯誤的時候,可能是/dev沒有加載,在編譯內核的時候,要選中自動加載/devboot的時候,這個選項。不然程序會因爲找不到/dev/console出錯。

 

 

 

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章