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出错。

 

 

 

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