`
yzd
  • 浏览: 1816931 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

嵌入式Linux之我行——u-boot-2009.08在2440上的移植详解

 
阅读更多
<div id="art" style="margin: 15px;">
<div>嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便。如有错误之处,谢请指正。</div>
<ul>
<li>
<span style="font-size: x-small;">共享资源,欢迎转载:</span>
<a href="http://hbhuanggang.cublog.cn/"><span style="color: #0000ff; font-size: x-small;">http://hbhuanggang.cublog.cn</span>
</a>
</li>
</ul>
<p><strong>一、移植环境</strong>
</p>
<ul>
<li>
<span style="font-size: x-small;">主 机:VMWare--Fedora 9</span>

</li>
<li>
<span style="font-size: x-small;">开发板:Mini2440--64MB Nand,</span>
<a href="http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.30.4.tar.gz" target="_blank"><span style="color: #0000ff; font-size: x-small;">Kernel:2.6.30.4</span>
</a>

</li>
<li>
<span style="font-size: x-small;">编译器:</span>
<a href="http://www.arm123.com.cn/linux/arm-linux-gcc-4.3.2.tgz" target="_blank"><span style="color: #0000ff; font-size: x-small;">arm-linux-gcc-4.3.2.tgz</span>
</a>

</li>
<li>
<span style="font-size: x-small;">u-boot:</span>
<a href="http://ftp.denx.de/pub/u-boot/u-boot-2009.08.tar.bz2" target="_blank"><span style="color: #0000ff; font-size: x-small;">u-boot-2009.08.tar.bz2</span>
</a>
</li>
</ul>
<p><strong>二、移植步骤</strong>
</p>
<p>本次移植的功能特点包括:</p>
<ul>
<li>支持Nand Flash读写
</li>
<li>支持从Nor/Nand Flash启动
</li>
<li>支持CS8900或者DM9000网卡
</li>
<li>支持Yaffs文件系统
</li>
<li>支持USB下载(还未实现) </li>
</ul>
<p><span style="font-size: xx-small;"><span style="color: #660099;"><strong><span style="font-size: small;"><span style="font-size: x-small;">1</span>
.</span>
<span style="font-size: x-small;">了解u-boot主要的目录结构和启动流程,如下图。</span>
</strong>
</span>
</span>
</p>
<div><img src="http://blog.chinaunix.net/photo/101649_091127212720.png" alt=""></div>
<div></div>
<div> u-boot<span style="font-family: DejaVu Sans;">的</span>
stage1<span style="font-family: DejaVu Sans;">代码通常放在cpu/xxxx/</span>
start.S<span style="font-family: DejaVu Sans;">文件中,他用汇编语言写成;</span>
<div> u-boot<span style="font-family: DejaVu Sans;">的</span>
stage2代码通常放在lib_xxxx/board.c<span style="font-family: DejaVu Sans;">文件中,他用C语言写成。</span>
</div>
<div>
<span style="font-family: DejaVu Sans;"> 各个部分的流程图如下:</span>
</div>
<div></div>
</div>
<div><img src="http://blog.chinaunix.net/photo/101649_091127230537.png" alt=""></div>
<div></div>
<div></div>
<div>
<strong><span style="color: #660099; font-size: x-small;">2. 建立自己的开发板项目并测试编译。</span>
</strong>
</div>
<div>
<strong><span style="font-size: xx-small;"></span>
</strong>
目前u-boot对很多CPU直接支持,可以查看board目录的一些子目录,如:board/samsung/目录下就是对三星一些ARM处理器的支持,有smdk2400、smdk2410和smdk6400,但没有2440,所以我们就在这里建立自己的开发板项目。</div>
<div></div>
<div>1)因2440和2410的资源差不多,主频和外设有点差别,所以我们就在board/samsung/下建立自己开发板的项目,取名叫my2440
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#tar -jxvf u-boot-2009.08.tar.bz2 </span>
<span style="font-family: NSimsun; color: #ff9900;">//解压源码</span>
<span style="background-color: #ffffff;"><br></span>
<span style="font-family: NSimsun;">#cd u-boot-2009.08/board/samsung/ </span>
<span style="font-family: NSimsun; color: #ff9900;">//进入目录</span>
<br><span style="font-family: NSimsun;">#mkdir my2440 </span>
<span style="font-family: NSimsun; color: #ff9900;">//创建my2440文件夹</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
</div>
<div></div>
<div>2)因2440和2410的资源差不多,所以就以2410项目的代码作为模板,以后再修改</div>
<div>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#cp -rf smdk2410/* my2440/</span>
<span style="font-family: NSimsun; color: #ff9900;">//将2410下所有的代码复制到2440下</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style=""><span style="color: #000000;">#cd my2440 </span>
<span style="color: #ff9900;">//进入my2440目录</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="">#mv smdk2410.c my2440.c <span style="color: #ff9900;">//将my2440下的smdk2410.c改名为my2440.c</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style=""><span style="color: #000000;">#cd ../../../</span>
<span style="color: #ff9900;">//回到u-boot根目录</span>
</span>
</span>
</code>
<code><span style="color: #000000;"><span style="background-color: #ffffff;"><br></span>
<span style="font-family: NSimsun;">#<span style="">cp include/configs/smdk2410.h include/configs/my2440.h</span>
</span>
<span style="font-family: NSimsun; color: #ff9900;">//建立2440头文件</span>
<br><span style="font-family: NSimsun;">#gedit board/samsung/my2440/Makefile</span>
<span style="font-family: NSimsun; color: #ff9900;">//修改my2440下Makefile的编译项,如下:</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
</div>
<div>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">COBJS:<span style="color: #0000cc;">=</span>
my2440.o flash.o <span style="color: #ff9900;">//因在my2440下我们将smdk2410.c改名为my2440.c</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
</div>
<p>3)修改u-boot跟目录下的Makefile文件。查找到smdk2410_config的地方,在他下面按照smdk2410_config的格式建立my2440_config的编译选项,另外还要指定交叉编译器
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit Makefile</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">CROSS_COMPILE ?= arm-linux- <span style="color: #000000;"><span style="font-family: NSimsun; color: #ff9900;">//指定交叉编译器为arm-linux-gcc</span>
</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;">
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">smdk2410_config:unconfig <span style="color: #ff9900;"><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff9900;">//2410编译选项格式</span>
</span>
<br></span>
@$(MKCONFIG) $(@:_config<span style="color: #000000;"><span style="color: #0000cc;"><span style="color: #000000;">=</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #000000;">)</span>
</span>
arm arm920t smdk2410 samsung s3c24x0</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<code><span style="color: #000000;">
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">my2440_config:unconfig <span style="color: #ff9900;"><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff9900;">//2440编译选项格式</span>
</span>
<br></span>
@$(MKCONFIG) $(@:_config<span style="color: #000000;"><span style="color: #0000cc;"><span style="color: #000000;">=</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #000000;">)</span>
</span>
arm arm920tmy2440 samsung s3c24x0</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="">*说明:arm :CPU的架构(ARCH)</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style=""> arm920t:CPU的类型</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style=""> my2440 :对应在board目录下建立新的开发板项目的目录</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style=""> samsung:新开发板项目目录的上级目录,如直接在board下建立新的开发板项目的目录,则这里就为NULL</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style=""> s3c24x0:CPU型号</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="">*注意:编译选项格式的第二行要用Tab键开始,否则编译会出错</span>
</span>
</code>
</p>
</span>
</code>
</td>
</tr></tbody></table>
<p>4)测试编译新建的my2440开发板项目
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#make my2440_config</span>
<span style="font-family: NSimsun; color: #ff9900;">//如果出现Configuring for my2440 board...则表示设置正确</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="">#make <span style="color: #ff9900;">//编译后在根目录下会出现u-boot.bin文件,则u-boot移植的第一步就算完成了</span>
</span>
<span style="background-color: #ffffff;"><br></span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<p>到此为止,u-boot对自己的my2440开发板还没有任何用处,以上的移植只是搭建了一个my2440开发板u-boot的框架,要使其功能实现,还要根据my2440开发板的具体资源情况来对u-boot源码进行修改。</p>
<span style="color: #660099; font-size: xx-small;"><strong></strong>
</span>
<p><span style="color: #660099;"><strong>3. 根据u-boot启动流程图的步骤来分析或者修改添加u-boot源码,使之适合my2440开发板(<span style="color: #ff0000;">注:修改或添加的地方都用红色表示</span>
)。</strong>
</span>
</p>
<p><strong>1)my2440开发板u-boot的stage1入口点分析。</strong>
<br><span style="">一般
在嵌入式系统软件开发中,在所有源码文件编译完成之后,链接器要读取一个链接分配文件,在该文件中定义了程序的入口点,代码段、数据段等分配情况等。那么
我们的my2440开发板u-boot的这个链接文件就是cpu/arm920t/u-boot.lds,打开该文件部分代码如下:
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit </span>
<span style="">cpu/arm920t/u-boot.lds</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">OUTPUT_FORMAT<span style="color: #0000cc;">(</span>
<span style="color: #ff00ff;">"elf32-littlearm"</span>
<span style="color: #0000cc;">,</span>
<span style="color: #ff00ff;">"elf32-littlearm"</span>
<span style="color: #0000cc;">,</span>
<span style="color: #ff00ff;">"elf32-littlearm"</span>
<span style="color: #0000cc;">)</span>
<br>
OUTPUT_ARCH<span style="color: #0000cc;">(</span>
arm<span style="color: #0000cc;">)</span>
</span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//定义生成文件的目标平台是arm</span>
<br>
ENTRY<span style="color: #0000cc;">(</span>
_start<span style="color: #0000cc;">)</span>
</span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//定义程序的入口点是_start<br></span>
<br>
SECTIONS<br><span style="color: #0000cc;">{</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//其他一些代码段、数据段等分配</span>
<br><span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">=</span>
0x00000000<span style="color: #0000cc;">;</span>
<br><br><span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">=</span>
ALIGN<span style="color: #0000cc;">(</span>
4<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000cc;">.</span>
text <span style="color: #0000cc;">:</span>
<br><span style="color: #0000cc;">{</span>
<br>
cpu<span style="color: #0000cc;">/</span>
arm920t<span style="color: #0000cc;">/</span>
start<span style="color: #0000cc;">.</span>
o<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">.</span>
text<span style="color: #0000cc;">)</span>
<br><span style="color: #0000cc;">*</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">.</span>
text<span style="color: #0000cc;">)</span>
<br><span style="color: #0000cc;">}</span>
<br><span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<br><span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<br><span style="color: #0000cc;">}</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table></span>
</p>
<p>知道了程序的入口点是_start,那么我们就打开my2440开发板u-boot第一个要运行的程序<span style="">cpu/arm920t/start.S(即u-boot的<span style="font-family: Courier New;">stage1部分)</span>
,查找到_start的位置如下:
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit </span>
<span style="">cpu/arm920t/start.S</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #0000cc;">.</span>
globl _start<br>
_start<span style="color: #0000cc;">:</span>
b start_code<span style="color: #ff9900;">//将程序的执行跳转到start_code处</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table></span>
</p>
<p>从这个汇编代码可以看到程序又跳转到start_code处开始执行,那么再查找到start_code处的代码如下:
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff9900;">/*<br>
* the actual start code<br>
*/</span>
<br><br>
start_code<span style="color: #0000cc;">:</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">/*<br>
* set the cpu to SVC32 mode<br>
*/</span>
<br>
mrsr0<span style="color: #0000cc;">,</span>
cpsr<br>
bicr0<span style="color: #0000cc;">,</span>
r0<span style="color: #0000cc;">,</span>
<span style="color: #0000cc;">#</span>
0x1f<br>
orrr0<span style="color: #0000cc;">,</span>
r0<span style="color: #0000cc;">,</span>
<span style="color: #0000cc;">#</span>
0xd3<br>
msrcpsr<span style="color: #0000cc;">,</span>
r0<br><br>
bl coloured_LED_init <span style="color: #ff9900;">//此处两行是对AT91RM9200DK开发板上的LED进行初始化的</span>
<br>
bl red_LED_on</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<p>由此可以看到,start_code处才是u-boot启动代码的真正开始处。以上就是u-boot的stage1入口的过程。<br><br><strong>2)my2440开发板u-boot的stage1阶段的硬件设备初始化。</strong>
<br>

于在u-boot启动代码处有两行是AT91RM9200DK的LED初始代码,但我们my2440上的LED资源与该开发板的不一致,所以我们要删除或
屏蔽该处代码,再加上my2440的LED驱动代码(注:添加my2440
LED功能只是用于表示u-boot运行的状态,给调试带来方便,可将该段代码放到任何你想调试的地方),代码如下:
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff9900;"><span style="color: #ff0000;"><span style="color: #000000;"> <span style="color: #ff0000;">/*bl coloured_LED_init</span>
</span>
<span style="color: #ff9900;">//这两行是AT91RM9200DK开发板的LED初始化,注释掉</span>
<br></span>
<span style="color: #000000;"></span>
<span style="color: #ff0000;">bl red_LED_on*/</span>
</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;">
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff9900;"><span style="color: #ff0000;">#ifdefined(CONFIG_S3C2440)</span>
//区别与其他开发板</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff9900;">//根据mini2440原理图可知LED分别由S3C2440的PB5、6、7、8口来控制,以下是<span style="color: #ff9900;">PB端口寄存器基地址(查2440的DataSheet得知)</span>
</span>
<br><span style="color: #ff0000;"><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
<span style="color: #ff0000;">define</span>
GPBCON 0x56000010</span>
</span>
</span>
</code>
<code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff0000;"><br><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
<span style="color: #ff0000;">define</span>
GPBDAT 0x56000014<br><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
<span style="color: #ff0000;">define</span>
GPBUP 0x56000018 </span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff0000;"> <span style="color: #ff9900;">//以下对寄存器的操作参照S3C2440的DataSheet进行操作</span>
<br>
ldr r0<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">,</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
GPBUP<br>
ldr r1<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">,</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
0x7FF <span style="color: #ff9900;">//即:二进制11111111111,关闭PB口上拉</span>
<br>
str r1<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">,</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">[</span>
</span>
</span>
r0<span style="color: #0000cc;"><span style="color: #ff0000;">]</span>
</span>
<br><br>
ldr r0<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">,</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
GPBCON<span style="color: #ff9900;">//配置PB5、6、7、8为输出口,对应PBCON寄存器的第10-17位</span>
<br>
ldr r1<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">,</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
0x154FD <span style="color: #ff9900;">//即:二进制010101010011111101</span>
<br>
str r1<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">,</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">[</span>
</span>
</span>
r0<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">]</span>
</span>
</span>
<br><br>
ldr r0<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">,</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
GPBDAT<br>
ldr r1<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">,</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
0x1C0 <span style="color: #ff9900;">//即:二进制111000000,PB5设为低电平,6、7、8为高电平</span>
<br>
str r1<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">,</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">[</span>
</span>
r0<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">]</span>
</span>
</span>
</span>
<br></span>
</span>
</code>
<code><span style="color: #000000;"><span style="font-family: NSimsun;"><br><span style="color: #ff0000;">#endif</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff0000;"><span style="color: #ff9900;">//此段代码使u-boot启动后,点亮开发板上的LED1,LED2、LED3、LED4不亮</span>
</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<p><span style="font-size: x-small;">在<span style="">include/configs/my2440.h头文件中添加CONFIG_S3C2440宏
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit </span>
<span style="">include/configs/my2440.h</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">define</span>
</span>
CONFIG_ARM920T1<span style="color: #ff9900;">/* This is an ARM920T Core*/</span>
<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">define</span>
</span>
CONFIG_S3C24101<span style="color: #ff9900;">/* in a SAMSUNG S3C2410 SoC */</span>
<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">define</span>
</span>
CONFIG_SMDK24101<span style="color: #ff9900;">/* on a SAMSUNG SMDK2410 Board */</span>
<br><span style="color: #ff0000;"><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
<span style="color: #ff0000;">define</span>
CONFIG_S3C24401</span>
<span style="color: #ff9900;">/* in a SAMSUNG S3C2440 SoC*/</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table></span>
</span>
</p>
<span style="font-size: x-small;"><span style="">
<p>现在编译u-boot,在根目录下会生成一个u-boot.bin文件。然后我们利用mini2440原有的supervivi把u-
boot.bin下载到RAM中运行测试(注意:我们使用supervivi进行下载时已经对CPU、RAM进行了初始化,所以我们在u-boot中要屏
蔽掉对CPU、RAM的初始化),如下:
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<code><span style="color: #000000;"><span style="font-family: NSimsun;">
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff0000;"><span style="color: #ff0000;"><span style="color: #ff9900;"><span style="color: #ff0000;">/</span>
<span style="color: #ff0000;">*#ifndef CONFIG_SKIP_LOWLEVEL_INIT <span style="color: #ff9900;">//在start.S文件中屏蔽u-boot对CPU、RAM的初始化</span>
</span>
<br><span style="color: #ff0000;">blcpu_init_crit<br></span>
<span style="color: #ff0000;">#endif*/</span>
</span>
</span>
</span>
</span>
</code>
</p>
</span>
</span>
</code>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#make my2440_config</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="">#make</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<p>下载运行后可以看到开发板上的LED灯第一了亮了,其他三个熄灭,测试结果符合上面的要求。终端运行结果如下:<br><img src="http://blog.chinaunix.net/photo/101649_091209125537.png" alt=""></p>
</span>
<p><strong>3)在u-boot中添加对</strong>
<span style=""><strong>S3C2440一些寄存器的支持、添加中断禁止部分和时钟设置部分<span style="font-family: Courier New;">。<br></span>
</strong>
</span>
<span style="font-family: Courier New;">由于2410和2440的寄存器及地址大部分是一致的,所以这里就直接在2410的基础上再加上对2440的支持即可,代码如下:
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit </span>
<span style="">cpu/arm920t/start.S</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#<span style="color: #0000ff;">if</span>
defined<span style="color: #0000cc;">(</span>
CONFIG_S3C2400<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">|</span>
<span style="color: #0000cc;">|</span>
defined<span style="color: #0000cc;">(</span>
CONFIG_S3C2410<span style="color: #0000cc;">) <span style="color: #ff0000;">|| defined(CONFIG_S3C2440)</span>
</span>
<br>
/<span style="color: #0000cc;">*</span>
turn off the watchdog <span style="color: #0000cc;">*</span>
<span style="color: #0000cc;">/</span>
<br><br>
# <span style="color: #0000ff;">if</span>
defined<span style="color: #0000cc;">(</span>
CONFIG_S3C2400<span style="color: #0000cc;">)</span>
<br>
# define pWTCON0x15300000<br>
# define INTMSK0x14400008/<span style="color: #0000cc;">*</span>
Interupt<span style="color: #0000cc;">-</span>
Controller base addresses <span style="color: #0000cc;">*</span>
<span style="color: #0000cc;">/</span>
<br>
# define CLKDIVN0x14800014/<span style="color: #0000cc;">*</span>
clock divisor register <span style="color: #0000cc;">*</span>
<span style="color: #0000cc;">/</span>
<br>
#<span style="color: #0000ff;">else <span style="color: #ff9933;">//下面2410和2440的寄存器地址是一致的</span>
</span>
<br>
# define pWTCON0x53000000<br>
# define INTMSK0x4A000008/<span style="color: #0000cc;">*</span>
Interupt<span style="color: #0000cc;">-</span>
Controller base addresses <span style="color: #0000cc;">*</span>
<span style="color: #0000cc;">/</span>
<br>
# define INTSUBMSK0x4A00001C<br>
# define CLKDIVN0x4C000014/<span style="color: #0000cc;">*</span>
clock divisor register <span style="color: #0000cc;">*</span>
<span style="color: #0000cc;">/</span>
<br>
# <span style="color: #0000ff;">endif</span>
<br><br>
ldr r0<span style="color: #0000cc;">,</span>
<span style="color: #0000cc;">=</span>
pWTCON<br><span style="color: #0000ff;">mov</span>
r1<span style="color: #0000cc;">,</span>
#0x0<br><span style="color: #0000ff;">str</span>
r1<span style="color: #0000cc;">,</span>
<span style="color: #0000cc;">[</span>
r0<span style="color: #0000cc;">]</span>
<br><br>
/<span style="color: #0000cc;">*</span>
<br><span style="color: #0000cc;">*</span>
<span style="color: #0000ff;">mask</span>
all IRQs by setting all bits <span style="color: #0000ff;">in</span>
the INTMR <span style="color: #0000cc;">-</span>
default<br><span style="color: #0000cc;">*</span>
<span style="color: #0000cc;">/</span>
<br><span style="color: #0000ff;">mov</span>
r1<span style="color: #0000cc;">,</span>
#0xffffffff<br>
ldr r0<span style="color: #0000cc;">,</span>
<span style="color: #0000cc;">=</span>
INTMSK<br><span style="color: #0000ff;">str </span>
r1<span style="color: #0000cc;">,</span>
<span style="color: #0000cc;">[</span>
r0<span style="color: #0000cc;">]</span>
<br>
# <span style="color: #0000ff;">if</span>
defined<span style="color: #0000cc;">(</span>
CONFIG_S3C2410<span style="color: #0000cc;">)</span>
<br>
ldr r1<span style="color: #0000cc;">,</span>
<span style="color: #0000cc;">=</span>
0x3ff<br>
ldr r0<span style="color: #0000cc;">,</span>
<span style="color: #0000cc;">=</span>
INTSUBMSK<br><span style="color: #0000ff;">str</span>
r1<span style="color: #0000cc;">,</span>
<span style="color: #0000cc;">[</span>
r0<span style="color: #0000cc;">]</span>
<br>
# <span style="color: #0000ff;">endif</span>
<br><span style="color: #ff0000;"># <span style="color: #0000ff;"><span style="color: #ff0000;">if</span>
</span>
defined<span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
CONFIG_S3C2440<span style="color: #ff0000;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
<span style="color: #ff9933;">//添加s3c2440的中断禁止部分</span>
</span>
<br></span>
ldr r1<span style="color: #0000cc;"><span style="color: #ff0000;">,</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
0x7fff <span style="color: #ff9933;">//</span>
<span style="color: #ff9900;">根据2440芯片手册,INTSUBMSK寄存器有15位可用</span>
</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff0000;"> ldr r0<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">,</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
INTSUBMSK<br><span style="color: #0000ff;"><span style="color: #ff0000;">str</span>
</span>
r1<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">,</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">[</span>
</span>
r0<span style="color: #0000cc;"><span style="color: #ff0000;">]</span>
</span>
<br>
# </span>
<span style="color: #0000ff;"><span style="color: #ff0000;">endif</span>
</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;">
</span>
</code>
<code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff0000;"># <span style="color: #0000ff;"><span style="color: #ff0000;">if</span>
</span>
defined<span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
CONFIG_S3C2440</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
<span style="color: #ff0000;"><span style="color: #ff9933;">//添加s3c2440的时钟部分</span>
</span>
</span>
</span>
</span>
</code>
</p>
<code><span style="font-family: NSimsun;">
<p style="margin: 5px; line-height: 150%;"><span style="color: #0000cc;"><span style=""><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
<span style="color: #ff0000;">define</span>
<span style="color: #ff0000;">MPLLCON0x4C000004</span>
<span style="color: #ff9933;">//系统主频配置寄存器基地址</span>
</span>
</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style="color: #0000cc;"><span style="">#define UPLLCON0x4C000008<span style="color: #ff9933;">//USB时钟频率配置寄存器基地址</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff9933;"><br><span style=""><span style="color: #ff0000;">ldr r0</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">,</span>
</span>
</span>
</span>
<span style="color: #ff0000;"> </span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
</span>
<span style=""><span style="color: #ff0000;">CLKDIVN <span style="color: #ff9900;">//设置分频系数FCLK:HCLK:PCLK = 1:4:8</span>
<br>
mov r1</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">,</span>
</span>
</span>
</span>
<span style="color: #ff0000;"> </span>
<span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
</span>
<span style=""><span style="color: #ff0000;">5<br>
str r1</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">,</span>
</span>
</span>
</span>
<span style="color: #ff0000;"> </span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">[</span>
</span>
</span>
<span style="color: #ff0000;">r0</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">]</span>
</span>
</span>
</span>
</span>
</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style="color: #0000cc;"><span style="">
</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff9933;"><span style="color: #ff0000;"></span>
</span>
</span>
</p>
<span style="color: #ff9933;"><span style="color: #ff0000;">
<p style="margin: 5px; line-height: 150%;"><span style=""> ldr r0, =MPLLCON<span style="color: #ff9933;">//设置系统主频为405MHz</span>
</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style=""> ldr r1, =0x7F021<span style="color: #ff9933;">//这个值参考</span>
<span style="color: #ff9900;">芯片手册“PLL VALUE SELECTION TABLE”部分</span>
</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style=""> str r1, [r0]</span>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><span style=""> ldr r0, =UPLLCON <span style="color: #ff9933;">//设置USB时钟频率为48MHz</span>
</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style=""> ldr r1, =0x38022 <span style="color: #ff9933;">//这个值参考</span>
<span style="color: #ff9900;">芯片手册“PLL VALUE SELECTION TABLE”部分</span>
</span>
</p>
</span>
</span>
<p style="margin: 5px; line-height: 150%;"><span style="color: #ff9933;"><span style="color: #ff0000;"><span style=""> str r1, [r0]</span>
</span>
</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style=""><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
<span style="color: #ff0000;">else</span>
<span style="color: #ff9933;">//其他开发板的时钟部分,这里就不用管了,我们现在是做2440的</span>
</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style=""><span style="color: #ff0000;"> <span style="color: #000000;">/</span>
<span style="color: #0000cc;">*</span>
<span style="color: #000000;"> FCLK</span>
<span style="color: #0000cc;">:</span>
<span style="color: #000000;">HCLK</span>
<span style="color: #0000cc;">:</span>
<span style="color: #000000;">PCLK </span>
<span style="color: #0000cc;">=</span>
<span style="color: #000000;"> 1</span>
<span style="color: #0000cc;">:</span>
<span style="color: #000000;">2</span>
<span style="color: #0000cc;">:</span>
<span style="color: #000000;">4 </span>
<span style="color: #0000cc;">*</span>
<span style="color: #0000cc;">/</span>
<br><span style="color: #000000;">/</span>
<span style="color: #0000cc;">*</span>
<span style="color: #000000;"> default FCLK is 120 MHz </span>
<span style="color: #0000cc;">!</span>
<span style="color: #000000;"> </span>
<span style="color: #0000cc;">*</span>
<span style="color: #0000cc;">/</span>
</span>
</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style=""> ldrr0<span style="color: #0000cc;">,</span>
<span style="color: #0000cc;">=</span>
CLKDIVN<br><span style="color: #0000ff;">mov</span>
r1<span style="color: #0000cc;">,</span>
#3<br><span style="color: #0000ff;">str</span>
r1<span style="color: #0000cc;">,</span>
<span style="color: #0000cc;">[</span>
r0<span style="color: #0000cc;">]</span>
</span>
</p>
</span>
</code>
<p style="margin: 5px; line-height: 150%;"><code><span style=""><span style="color: #0000cc;"><span style="color: #ff0000;"># endif</span>
</span>
<br>
#<span style="color: #0000ff;">endif</span>
/<span style="color: #0000cc;">*</span>
CONFIG_S3C2400 <span style="color: #0000cc;">|</span>
<span style="color: #0000cc;">|</span>
CONFIG_S3C2410 <span style="color: #0000cc;">|</span>
<span style="color: #0000cc;">|</span>
CONFIG_S3C2440 <span style="color: #0000cc;">*</span>
<span style="color: #0000cc;">/</span>
</span>
</code>
</p>
</td>
</tr></tbody></table></span>
</p>
<span style="">
</span>
</span>
<p><span style="font-size: x-small;"><span style="">S3C2440的时钟部分除了在start.S中添加外,还要分别在board/samsung/my2440/my2440.c和cpu/arm920t/s3c24x0/speed.c中修改或添加部分代码,如下:
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit </span>
<span style="">board/samsung/my2440/my2440.c </span>
<span style=""><span style="color: #ff9900;">//设置<span style="">主频和USB时钟频率参数与start.S中的一致</span>
</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">define </span>
</span>
FCLK_SPEED <span style="color: #ff0000;">2 <span style="color: #ff9900;">//设置默认等于2,即下面红色代码部分有效</span>
</span>
<br><br><span style="color: #0000cc;">#</span>
<span style="color: #0000ff;">if</span>
FCLK_SPEED<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
0 <span style="color: #ff9900;">/* Fout = 203MHz, Fin = 12MHz for Audio */</span>
<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">define </span>
</span>
M_MDIV0xC3<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">define </span>
</span>
M_PDIV0x4<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">define </span>
</span>
M_SDIV0x1<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #0000ff;">elif</span>
</span>
FCLK_SPEED<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
1<span style="color: #ff9900;">/* Fout = 202.8MHz */</span>
<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">define </span>
</span>
M_MDIV0xA1<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">define </span>
</span>
M_PDIV0x3<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">define </span>
</span>
M_SDIV0x1<br><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
<span style="color: #ff0000;">elif</span>
<span style="color: #ff0000;">FCLK_SPEED<span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
2</span>
<span style="color: #ff9900;">/* Fout = 405MHz */</span>
<br><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
</span>
<span style="color: #ff0000;">define</span>
<span style="color: #ff0000;">M_MDIV0x7F <span style="color: #ff9900;">//这三个值根据S3C2440</span>
<span style="">芯片手册“PLL VALUE SELECTION TABLE”部分进行设置</span>
<br><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
</span>
<span style="color: #ff0000;">define</span>
M_PDIV0x2<br><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
</span>
<span style="color: #ff0000;">define</span>
M_SDIV0x1</span>
<br><span style="color: #0000cc;">#</span>
<span style="color: #0000ff;"><span style="color: #ff0000;"><span style="color: #0000ff;">endif</span>
</span>
<br></span>
<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">define </span>
</span>
USB_CLOCK <span style="color: #ff0000;">2 <span style="color: #ff9900;">//设置默认等于2,即下面红色代码部分有效</span>
</span>
<br><br><span style="color: #0000cc;">#</span>
<span style="color: #0000ff;">if</span>
USB_CLOCK<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
0<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">define </span>
</span>
U_M_MDIV0xA1<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">define </span>
</span>
U_M_PDIV0x3<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">define </span>
</span>
U_M_SDIV0x1<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #ff0000;"><span style="color: #0000ff;">elif</span>
</span>
<span style="color: #000000;"> </span>
</span>
USB_CLOCK<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
1<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">define </span>
</span>
U_M_MDIV0x48<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">define </span>
</span>
U_M_PDIV0x3<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">define </span>
</span>
U_M_SDIV0x2<br><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
</span>
<span style="color: #ff0000;">elif</span>
<span style="color: #ff0000;">USB_CLOCK</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
</span>
<span style="color: #ff0000;">2</span>
<span style="color: #ff9900;">/* Fout = 48MHz */</span>
<br><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
</span>
<span style="color: #ff0000;">define</span>
<span style="color: #ff0000;">U_M_MDIV0x38 <span style="color: #ff9900;">//这三个值根据S3C2440</span>
<span style="">芯片手册“PLL VALUE SELECTION TABLE”部分进行设置</span>
<br><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
</span>
</span>
</span>
<span style="color: #ff0000;">define</span>
U_M_PDIV0x2<br><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
</span>
</span>
</span>
<span style="color: #ff0000;">define</span>
U_M_SDIV0x2</span>
<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #ff0000;"><span style="color: #0000ff;">endif</span>
</span>
</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table></span>
</span>
</p>
<p>
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit </span>
<span style="">cpu/arm920t/s3c24x0/speed.c </span>
<span style=""><span style="color: #ff9900;">//根据<span style="">设置的分频系数FCLK:HCLK:PCLK = 1:4:8修改获取时钟频率的函数</span>
</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #0000ff;">static</span>
ulong get_PLLCLK<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">int</span>
pllreg<span style="color: #0000cc;">)</span>
<br><span style="color: #0000cc;">{</span>
<br>
S3C24X0_CLOCK_POWER <span style="color: #0000cc;">*</span>
<span style="color: #0000ff;">const</span>
clk_power <span style="color: #0000cc;">=</span>
S3C24X0_GetBase_CLOCK_POWER<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br>
ulong r<span style="color: #0000cc;">,</span>
m<span style="color: #0000cc;">,</span>
p<span style="color: #0000cc;">,</span>
s<span style="color: #0000cc;">;</span>
<br><br><span style="color: #0000ff;">if</span>
<span style="color: #0000cc;">(</span>
pllreg <span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
MPLL<span style="color: #0000cc;">)</span>
<br>
r <span style="color: #0000cc;">=</span>
clk_power<span style="color: #0000cc;">-</span>
<span style="color: #0000cc;">&gt;</span>
MPLLCON<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">else</span>
<span style="color: #0000ff;">if</span>
<span style="color: #0000cc;">(</span>
pllreg <span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
UPLL<span style="color: #0000cc;">)</span>
<br>
r <span style="color: #0000cc;">=</span>
clk_power<span style="color: #0000cc;">-</span>
<span style="color: #0000cc;">&gt;</span>
UPLLCON<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">else</span>
<br>
hang<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><br>
m <span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">(</span>
r <span style="color: #0000cc;">&amp;</span>
0xFF000<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">&gt;</span>
<span style="color: #0000cc;">&gt;</span>
12<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">+</span>
8<span style="color: #0000cc;">;</span>
<br>
p <span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">(</span>
r <span style="color: #0000cc;">&amp;</span>
0x003F0<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">&gt;</span>
<span style="color: #0000cc;">&gt;</span>
4<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">+</span>
2<span style="color: #0000cc;">;</span>
<br>
s <span style="color: #0000cc;">=</span>
r <span style="color: #0000cc;">&amp;</span>
0x3<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff0000;"><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
<span style="color: #0000ff;"><span style="color: #ff0000;">if</span>
</span>
defined<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
CONFIG_S3C2440<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
<br><span style="color: #0000ff;"><span style="color: #0000ff;"><span style="color: #ff0000;">if</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
pllreg <span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
MPLL<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
<br><span style="color: #0000cc;"><span style="color: #ff0000;">{ <span style="color: #ff9900;">//参考S3C2440<span style="">芯片手册上的公式:PLL=(2 * m * Fin)/(p * 2<sup>s</sup>
)</span>
</span>
</span>
</span>
<br><span style="color: #0000ff;"><span style="color: #0000ff;"><span style="color: #ff0000;">return</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
CONFIG_SYS_CLK_FREQ <span style="color: #0000cc;"><span style="color: #ff0000;">*</span>
</span>
m <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">*</span>
</span>
</span>
2<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">/</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
</span>
p <span style="color: #0000cc;"><span style="color: #ff0000;">&lt;</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">&lt;</span>
</span>
</span>
s<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
<br><span style="color: #0000cc;"><span style="color: #ff0000;">}</span>
</span>
<br><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
</span>
<span style="color: #ff0000;">endif</span>
<br></span>
<br><span style="color: #0000ff;">return</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">(</span>
CONFIG_SYS_CLK_FREQ <span style="color: #0000cc;">*</span>
m<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">/</span>
<span style="color: #0000cc;">(</span>
p <span style="color: #0000cc;">&lt;</span>
<span style="color: #0000cc;">&lt;</span>
s<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000cc;">}</span>
<br><br><span style="color: #ff9900;">/* return HCLK frequency */</span>
<br>
ulong get_HCLK<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">void</span>
<span style="color: #0000cc;">)</span>
<br><span style="color: #0000cc;">{</span>
<br>
S3C24X0_CLOCK_POWER <span style="color: #0000cc;">*</span>
<span style="color: #0000ff;">const</span>
clk_power <span style="color: #0000cc;">=</span>
S3C24X0_GetBase_CLOCK_POWER<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff0000;"><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
<span style="color: #0000ff;"><span style="color: #ff0000;">if</span>
</span>
defined<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
CONFIG_S3C2440<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
</span>
</span>
<span style="font-family: NSimsun;"><br><span style="color: #ff0000;"><span style="color: #0000ff;"><span style="color: #ff0000;">return</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
get_FCLK<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">/</span>
</span>
4<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
<br><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
</span>
<span style="color: #ff0000;">endif</span>
<br></span>
<br><span style="color: #0000ff;">return</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">(</span>
clk_power<span style="color: #0000cc;">-</span>
<span style="color: #0000cc;">&gt;</span>
CLKDIVN <span style="color: #0000cc;">&amp;</span>
0x2<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">?</span>
get_FCLK<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">/</span>
2 <span style="color: #0000cc;">:</span>
get_FCLK<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000cc;">}</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<p>好了!修改完毕后我们再重新编译u-boot,然后再下载到RAM中运行测试。结果终端有输出信息并且出现类似Shell的命令行,这说明这一部分移植完成。示意图如下: <br><img src="http://blog.chinaunix.net/photo/101649_091209125547.png" alt=""></p>
<p><br><strong><span style="">下接:</span>
</strong>
<a href="http://blog.chinaunix.net/u3/101649/showart.php?id=2117210" target="_blank"><strong><span style="">u-boot-2009.08在2440上的移植详解(二)</span>
</strong>
</a>
</p>
</div>
<p style="line-height: 150%; margin: 5px;">

<a href="http://blogold.chinaunix.net/u3/101649/showart.php?id=2276917" target="_blank">回目录 嵌入式Linux之我行——Bootloader移植篇 </a>
</p>
<p style="line-height: 150%; margin: 5px;"></p>
<p style="line-height: 150%; margin: 5px;"></p>
<table style="width: 100%;" border="0" cellspacing="0" cellpadding="0"><tbody>
<tr>
<td height="25" align="center">
<span style="font-size: 14pt; color: #02368d;"><strong>嵌入式Linux之我行——u-boot-2009.08在2440上的移植详解(二)</strong>
</span>
<br>
</td>
</tr>
<tr>
<td height="1"></td>
</tr>
<tr>
<td height="1"></td>
</tr>
<tr>
<td align="center">
<table style="border-collapse: collapse; width: 100%;" border="0" cellspacing="0" cellpadding="0"><tbody><tr>
<td width="100%">
<div id="art" style="margin: 15px;">
<div>
<div>嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便。如有错误之处,谢请指正。</div>
<ul>
<li>
<span style="font-size: x-small;">共享资源,欢迎转载:</span>
<a href="http://hbhuanggang.cublog.cn/"><span style="color: #0000ff; font-size: x-small;">http://hbhuanggang.cublog.cn</span>
</a>
</li>
</ul>
<p><strong>一、移植环境</strong>
</p>
<ul>
<li>
<span style="font-size: x-small;">主 机:VMWare--Fedora 9</span>

</li>
<li>
<span style="font-size: x-small;">开发板:Mini2440--64MB Nand,</span>
<a href="http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.30.4.tar.gz" target="_blank"><span style="color: #0000ff; font-size: x-small;">Kernel:2.6.30.4</span>
</a>

</li>
<li>
<span style="font-size: x-small;">编译器:</span>
<a href="http://www.arm123.com.cn/linux/arm-linux-gcc-4.3.2.tgz" target="_blank"><span style="color: #0000ff; font-size: x-small;">arm-linux-gcc-4.3.2.tgz</span>
</a>

</li>
<li>
<span style="font-size: x-small;">u-boot:</span>
<a href="http://ftp.denx.de/pub/u-boot/u-boot-2009.08.tar.bz2" target="_blank"><span style="color: #0000ff; font-size: x-small;">u-boot-2009.08.tar.bz2</span>
</a>
</li>
</ul>
<p><strong>二、移植步骤</strong>
</p>
<p><span style=""><strong>上接</strong>
:</span>
<a href="http://blog.chinaunix.net/u3/101649/showart_2105215.html" target="_blank"><strong><span style="">u-boot-2009.08在2440上的移植详解(一)</span>
</strong>
</a>
</p>
<p><strong>4)准备进入u-boot的第二阶段(在u-boot中添加对我们开发板上Nor Flash的支持)</strong>
<span style=""><span style="font-family: Courier New;"><strong>。<br></strong>
</span>
</span>

常,在嵌入式bootloader中,有两种方式来引导启动内核:从Nor Flash启动和从Nand Flash启动。u-boot中默认是从Nor
Flash启动,再从上一节这个运行结果图中看,还发现几个问题:第一,我开发板的Nor
Flash是2M的,而这里显示的是512kB;第二,出现Warning - bad CRC, using default
environment的警告信息。不是u-boot默认是从Nor
Flash启动的吗?为什么会有这些错误信息呢?这是因为我们还没有添加对我们自己的Nor Flash的支持,u-boot默认的是其他型号的Nor
Flash,而我们的Nor Flash的型号是SST39VF1601。另外怎样将命令行提示符前面的SMDK2410变成我自己定义的呢?</p>
<p>下面我们一一来解决这些问题,让u-boot完全对我们Nor Flash的支持。首先我们修改头文件代码如下:
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit </span>
<span style="">include/configs/my2440.h </span>
<span style=""><span style="color: #ff9900;">//修改命令行前的名字和Nor Flash参数部分的定义</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff9900;"><span style="color: #ff0000;">#defineCONFIG_SYS_PROMPT"[MY2440]#"</span>
//将命令行前的名字改成[MY2440]</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;">
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff9900;">/*-----------------------------------------------------------------------<br>
* FLASH and environment organization<br>
*/</span>
<br><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
<span style="color: #ff0000;"><span style="color: #0000ff;"><span style="color: #ff0000;">if</span>
</span>
0</span>
</span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//注释掉下面两个类型的Nor Flash设置,因为不是我们所使用的型号</span>
<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">define</span>
</span>
CONFIG_AMD_LV4001<span style="color: #ff9900;">/* uncomment this if you have a LV400 flash */</span>
<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #ff0000;"><span style="color: #000000;">define </span>
</span>
</span>
CONFIG_AMD_LV8001<span style="color: #ff9900;">/* uncomment this if you have a LV800 flash */</span>
<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">endif</span>
</span>
<br><br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #ff0000;"><span style="color: #000000;"><span style="color: #ff0000;"><span style="color: #000000;">define</span>
</span>
</span>
</span>
</span>
CONFIG_SYS_MAX_FLASH_BANKS1<span style="color: #ff9900;">/* max number of memory banks */</span>
<br><br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">ifdef</span>
</span>
CONFIG_AMD_LV800<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;"><span style="color: #ff0000;"><span style="color: #000000;">define</span>
</span>
</span>
</span>
PHYS_FLASH_SIZE0x00100000<span style="color: #ff9900;">/* 1MB */</span>
<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;"><span style="color: #ff0000;"><span style="color: #000000;">define</span>
</span>
</span>
</span>
CONFIG_SYS_MAX_FLASH_SECT <span style="color: #0000cc;">(</span>
19<span style="color: #0000cc;">) </span>
<span style="color: #ff9900;">/* max number of sectors on one chip */</span>
<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">define</span>
</span>
CONFIG_ENV_ADDR <span style="color: #0000cc;">(</span>
CONFIG_SYS_FLASH_BASE <span style="color: #0000cc;">+</span>
0x0F0000<span style="color: #0000cc;">)</span>
<span style="color: #ff9900;">/* addr of environment */</span>
<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">endif</span>
</span>
<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">ifdef</span>
</span>
CONFIG_AMD_LV400<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">define</span>
</span>
PHYS_FLASH_SIZE0x00080000<span style="color: #ff9900;">/* 512KB */</span>
<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">define</span>
</span>
CONFIG_SYS_MAX_FLASH_SECT<span style="color: #0000cc;">(</span>
11<span style="color: #0000cc;">)</span>
<span style="color: #ff9900;">/* max number of sectors on one chip */</span>
<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">define</span>
</span>
CONFIG_ENV_ADDR<span style="color: #0000cc;">(</span>
CONFIG_SYS_FLASH_BASE <span style="color: #0000cc;">+</span>
0x070000<span style="color: #0000cc;">)</span>
<span style="color: #ff9900;">/* addr of environment */</span>
<br><span style="color: #000000;"><span style="color: #0000cc;">#</span>
</span>
<span style="color: #ff0000;"><span style="color: #000000;">endif</span>
</span>
<br><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
<span style="color: #ff0000;">define</span>
<span style="color: #ff0000;">CONFIG_SST_39VF16011</span>
</span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//添加mini2440开发板Nor Flash设置</span>
<br><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
</span>
<span style="color: #ff0000;">define</span>
<span style="color: #ff0000;">PHYS_FLASH_SIZE0x200000</span>
<span style="color: #ff9900;">//我们开发板的Nor Flash是2M</span>
<br><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
</span>
<span style="color: #ff0000;">define</span>
<span style="color: #ff0000;">CONFIG_SYS_MAX_FLASH_SECT<span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
512</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
<span style="color: #ff9900;">//根据SST39VF1601的芯片手册描述,对其进行操作有两种方式:块方式和扇区方式。现采用扇区方式(sector),1 sector = 2Kword = 4Kbyte,所以2M的Nor Flash共有512个sector</span>
<br><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
</span>
<span style="color: #ff0000;">define</span>
<span style="color: #ff0000;">CONFIG_ENV_ADDR<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
CONFIG_SYS_FLASH_BASE <span style="color: #0000cc;"><span style="color: #ff0000;">+</span>
</span>
0x040000<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
</span>
<span style="color: #ff9900;">//暂设置环境变量的首地址为0x040000(即:256Kb)</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<p>然后添加对我们mini2440开发板上2M的Nor Flash(型号为SST39VF1601)的支持。在u-boot中对Nor
Flash的操作分别有初始化、擦除和写入,所以我们主要修改与硬件密切相关的三个函数flash_init、flash_erase、
write_hword,修改代码如下:
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit </span>
<span style="">board/samsung/my2440/flash.c</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff0000;"><span style="color: #ff9900;"><span style="color: #ff9900;"><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff9900;">//修改定义部分如下:</span>
</span>
</span>
</span>
</span>
</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff0000;"><span style="color: #ff9900;"><span style="color: #ff9900;">//#define MAIN_SECT_SIZE0x10000</span>
</span>
<br><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
<span style="color: #ff0000;">define</span>
MAIN_SECT_SIZE0x1000</span>
<span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff9900;">//定义为4k,刚好是一个扇区的大小</span>
</span>
</span>
<br><br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//#define MEM_FLASH_ADDR1 (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x00000555 &lt;&lt; 1)))</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//#define MEM_FLASH_ADDR2(*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x000002AA &lt;&lt; 1)))</span>
<br><span style="color: #ff0000;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
</span>
<span style="color: #ff0000;">define</span>
MEM_FLASH_ADDR1<span style="color: #ff0000;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">*</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
</span>
<span style="color: #0000ff;"><span style="color: #ff0000;">volatile</span>
</span>
u16 <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">*</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
CONFIG_SYS_FLASH_BASE <span style="color: #0000cc;"><span style="color: #ff0000;">+</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
0x00005555 <span style="color: #0000cc;"><span style="color: #ff0000;">&lt;</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">&lt;</span>
</span>
</span>
1<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
<span style="color: #ff9900;">//这两个参数看SST39VF1601手册</span>
</span>
</span>
<span style="font-family: NSimsun;"><br><span style="color: #ff0000;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
</span>
<span style="color: #ff0000;">define</span>
MEM_FLASH_ADDR2<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">*</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
<span style="color: #0000ff;"><span style="color: #0000ff;"><span style="color: #ff0000;"><span style="color: #0000ff;"><span style="color: #ff0000;">volatile</span>
</span>
</span>
</span>
</span>
u16 <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">*</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
CONFIG_SYS_FLASH_BASE <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">+</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
</span>
0x00002AAA <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">&lt;<span style="color: #0000cc;"><span style="color: #ff0000;">&lt;</span>
</span>
</span>
</span>
</span>
1<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)<span style="color: #0000cc;"><span style="color: #ff0000;">)<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
</span>
</span>
</span>
</span>
</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff0000;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;"><span style="color: #0000cc;">
</span>
</span>
</span>
</span>
</span>
</span>
</span>
</code>
<code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff0000;"></span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff9900;">//修改flash_init函数如下:</span>
</span>
</span>
<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;"><span style="color: #000000;">elif</span>
</span>
defined<span style="color: #0000cc;">(</span>
CONFIG_AMD_LV800<span style="color: #0000cc;">)</span>
<br><span style="color: #0000cc;">(</span>
AMD_MANUFACT <span style="color: #0000cc;">&amp;</span>
FLASH_VENDMASK<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">|</span>
<br><span style="color: #0000cc;">(</span>
AMD_ID_LV800B <span style="color: #0000cc;">&amp;</span>
FLASH_TYPEMASK<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
</span>
<span style="color: #ff0000;">elif</span>
<span style="color: #ff0000;">defined<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
</span>
</span>
CONFIG_SST_39VF1601<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
</span>
<span style="color: #ff9900;">//在CONFIG_AMD_LV800后面添加CONFIG_SST_39VF1601</span>
</span>
</span>
<span style="font-family: NSimsun;"><br><span style="color: #ff0000;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
</span>
</span>
SST_MANUFACT <span style="color: #0000cc;"><span style="color: #ff0000;">&amp;</span>
</span>
FLASH_VENDMASK<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">|</span>
</span>
<br><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
</span>
</span>
SST_ID_xF1601 <span style="color: #0000cc;"><span style="color: #ff0000;">&amp;</span>
</span>
FLASH_TYPEMASK<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
<br></span>
</span>
</code>
<code><span style="color: #000000;"><span style="font-family: NSimsun;"><br><span style="color: #0000ff;">for</span>
<span style="color: #0000cc;">(</span>
j <span style="color: #0000cc;">=</span>
0<span style="color: #0000cc;">;</span>
j <span style="color: #0000cc;">&lt;</span>
flash_info<span style="color: #0000cc;">[</span>
i<span style="color: #0000cc;">]</span>
<span style="color: #0000cc;">.</span>
sector_count<span style="color: #0000cc;">;</span>
j<span style="color: #0000cc;">+</span>
<span style="color: #0000cc;">+</span>
<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">{</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//if (j &lt;= 3) {</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">// /* 1st one is 16 KB */</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//if (j == 0) {</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//flash_info[i].start[j] = </span>
</span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">flashbase + 0;</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//}</span>
<br><br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">///* 2nd and 3rd are both 8 KB */</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//if ((j == 1) || (j == 2)) {</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//flash_info[i].start[j] = </span>
</span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">flashbase + 0x4000 + (j - </span>
</span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">1) * </span>
</span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">0x2000;</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//}</span>
<br><br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">///* 4th 32 KB */</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//if (j == 3) {</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//flash_info[i].start[j] = </span>
</span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">flashbase + 0x8000;</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//}</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//} else {</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//flash_info[i].start[j] =</span>
</span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">flashbase + (j - 3) * MAIN_SECT_SIZE;</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//}</span>
<br><br><span style="color: #ff0000;">flash_info<span style="color: #0000cc;"><span style="color: #ff0000;">[</span>
</span>
i<span style="color: #0000cc;"><span style="color: #ff0000;">]</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">.</span>
</span>
start<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">[</span>
</span>
</span>
j<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">]</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
flashbase <span style="color: #0000cc;"><span style="color: #ff0000;">+</span>
</span>
j <span style="color: #0000cc;"><span style="color: #ff0000;">*</span>
</span>
MAIN_SECT_SIZE</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
</span>
<span style="font-family: NSimsun;"><br><span style="color: #0000cc;">}</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;">
</span>
</code>
<code><span style="color: #000000;"><span style="font-family: NSimsun;"></span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff9900;">//修改flash_print_info函数如下:</span>
</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #0000ff;">case</span>
<span style="color: #0000cc;">(</span>
AMD_MANUFACT <span style="color: #0000cc;">&amp;</span>
FLASH_VENDMASK<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">:</span>
<br><span style="color: #ff0000;"><span style="color: #0000ff;">printf</span>
</span>
<span style="color: #0000cc;">(</span>
<span style="color: #ff00ff;">"AMD: "</span>
<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">break</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #ff0000;"><span style="color: #0000ff;"><span style="color: #ff0000;">case</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
SST_MANUFACT <span style="color: #0000cc;"><span style="color: #ff0000;">&amp;</span>
</span>
FLASH_VENDMASK<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">:</span>
</span>
</span>
</span>
</span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//添加SST39VF1601的</span>
<br><span style="color: #ff0000;"><span style="color: #ff0000;">printf</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
<span style="color: #ff0000;"><span style="color: #ff00ff;"><span style="color: #ff0000;">"SST:</span>
<span style="color: #ff0000;">"</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
<br><span style="color: #ff0000;"><span style="color: #0000ff;"><span style="color: #ff0000;">break</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
</span>
</span>
<br></span>
<br><span style="color: #0000ff;">case</span>
<span style="color: #0000cc;">(</span>
AMD_ID_LV800B <span style="color: #0000cc;">&amp;</span>
FLASH_TYPEMASK<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">:</span>
<br><span style="color: #ff0000;"><span style="color: #0000ff;">printf</span>
</span>
<span style="color: #0000cc;">(</span>
<span style="color: #ff00ff;">"1x Amd29LV800BB (8Mbit)/n"</span>
<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">break</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;"><span style="color: #0000ff;"><span style="color: #ff0000;">case</span>
</span>
</span>
<span style="color: #ff0000;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
SST_ID_xF1601 <span style="color: #0000cc;"><span style="color: #ff0000;">&amp;</span>
</span>
FLASH_TYPEMASK<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">:</span>
</span>
</span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//添加SST39VF1601的</span>
<br><span style="color: #ff0000;">printf</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
<span style="color: #ff00ff;"><span style="color: #ff0000;">"</span>
<span style="color: #ff0000;">1x SST39VF1610 (16Mbit)/n"</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
</span>
<br><span style="color: #0000ff;"><span style="color: #0000ff;"><span style="color: #ff0000;">break</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;">
</span>
</code>
<code><span style="color: #000000;"><span style="font-family: NSimsun;"></span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff0000;"><span style="color: #ff9900;">//修改flash_erase函数如下:</span>
<br></span>
</span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//if ((info-&gt;flash_id &amp; FLASH_VENDMASK) !=</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">// (AMD_MANUFACT &amp; FLASH_VENDMASK)) {</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//return ERR_UNKNOWN_FLASH_VENDOR;</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//}</span>
<br><span style="color: #ff0000;"><span style="color: #0000ff;"><span style="color: #ff0000;">if</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
info<span style="color: #0000cc;"><span style="color: #ff0000;">-</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">&gt;</span>
</span>
flash_id <span style="color: #0000cc;"><span style="color: #ff0000;">&amp;</span>
</span>
FLASH_VENDMASK<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">!</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
</span>
</span>
<span style="font-family: NSimsun;"><br><span style="color: #ff0000;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
SST_MANUFACT <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">&amp;</span>
</span>
</span>
FLASH_VENDMASK<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">{</span>
</span>
<br><span style="color: #0000ff;"><span style="color: #ff0000;">return</span>
</span>
ERR_UNKNOWN_FLASH_VENDOR<span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
<br><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">}</span>
</span>
</span>
<br></span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">///* wait until flash is ready */</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//chip = 0;<br></span>
</span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//do {</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//result = *addr;</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">///* check timeout */</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//if (get_timer_masked () &gt;</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">// CONFIG_SYS_FLASH_ERASE_TOUT) {</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//MEM_FLASH_ADDR1 = CMD_READ_ARRAY;</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//chip = TMO;</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//break;</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//}</span>
<br><br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//if (!chip</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">// &amp;&amp; (result &amp; 0xFFFF) &amp; BIT_ERASE_DONE)</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//chip = READY;</span>
<br><br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//if (!chip</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">// &amp;&amp; (result &amp; 0xFFFF) &amp; BIT_PROGRAM_ERROR)</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//chip = ERR;</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//} while (!chip);<br></span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//MEM_FLASH_ADDR1 = CMD_READ_ARRAY;</span>
<br><br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//if (chip == ERR) {</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//rc = ERR_PROG_ERROR;</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//goto outahere;</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//}<br></span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//if (chip == TMO) {</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//rc = ERR_TIMOUT;</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//goto outahere;</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//}</span>
<br><span style="color: #ff0000;"><span style="color: #0000ff;"><span style="color: #ff0000;">while</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
1<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
</span>
</span>
<span style="font-family: NSimsun;"><br><span style="color: #ff0000;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">{</span>
</span>
</span>
<br><span style="color: #0000ff;"><span style="color: #0000ff;"><span style="color: #ff0000;">if</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">*</span>
</span>
</span>
addr <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">&amp;</span>
</span>
</span>
0x40<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">!</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">*</span>
</span>
</span>
addr <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">&amp;</span>
</span>
</span>
0x40<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
</span>
</span>
<br><span style="color: #0000ff;"><span style="color: #0000ff;"><span style="color: #ff0000;">continue</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
</span>
<br><br><span style="color: #0000ff;"><span style="color: #0000ff;"><span style="color: #ff0000;">if</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">*</span>
</span>
</span>
addr <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">&amp;</span>
</span>
</span>
0x80<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
<br><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">{</span>
</span>
</span>
<br>
rc <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
ERR_OK<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
</span>
<br><span style="color: #0000ff;"><span style="color: #0000ff;"><span style="color: #ff0000;">break</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
</span>
<br><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">}</span>
</span>
</span>
<br><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">}</span>
</span>
</span>
</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff0000;">
</span>
</span>
</span>
</code>
<code><span style="color: #000000;"><span style="font-family: NSimsun;"></span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff9900;">//修改write_hword函数如下:</span>
<br>
MEM_FLASH_ADDR1 <span style="color: #0000cc;">=</span>
CMD_UNLOCK1<span style="color: #0000cc;">;</span>
<br>
MEM_FLASH_ADDR2 <span style="color: #0000cc;">=</span>
CMD_UNLOCK2<span style="color: #0000cc;">;</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//MEM_FLASH_ADDR1 = CMD_UNLOCK_BYPASS;</span>
<br><span style="color: #ff0000;">MEM_FLASH_ADDR1 <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
CMD_PROGRAM<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
</span>
</span>
</span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;"></span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//*addr = CMD_PROGRAM;</span>
<br><span style="color: #0000cc;">*</span>
addr <span style="color: #0000cc;">=</span>
data<span style="color: #0000cc;">;</span>
<br><br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">///* wait until flash is ready */</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//chip = 0;</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//do {</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//result = *addr;</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">///* check timeout */</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//if (get_timer_masked () &gt; CONFIG_SYS_FLASH_ERASE_TOUT) {</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//chip = ERR | TMO;</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//break;</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//}<br></span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//if (!chip &amp;&amp; ((result &amp; 0x80) == (data &amp; 0x80)))</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//chip = READY;</span>
<br><br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//if (!chip &amp;&amp; ((result &amp; 0xFFFF) &amp; BIT_PROGRAM_ERROR)) {</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//result = *addr;<br></span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//if ((result &amp; 0x80) == (data &amp; 0x80))</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//chip = READY;</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//else</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//chip = ERR;</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//}</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//} while (!chip);</span>
<br><br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//*addr = CMD_READ_ARRAY;</span>
<br><br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//if (chip == ERR || *addr != data)</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//rc = ERR_PROG_ERROR;</span>
<br><span style="color: #ff0000;"><span style="color: #0000ff;"><span style="color: #0000ff;"><span style="color: #ff0000;">while</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
1<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
</span>
</span>
<span style="font-family: NSimsun;"><br><span style="color: #ff0000;"><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">{</span>
</span>
</span>
<br><span style="color: #0000ff;"><span style="color: #0000ff;"><span style="color: #ff0000;">if</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(<span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">*</span>
</span>
</span>
addr <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">&amp;</span>
</span>
</span>
0x40<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">!</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">*</span>
</span>
</span>
addr <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">&amp;</span>
</span>
</span>
0x40<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
</span>
</span>
<br><span style="color: #0000ff;"><span style="color: #ff0000;">continue</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
</span>
<br><br><span style="color: #0000ff;"><span style="color: #ff0000;">if</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(<span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">*</span>
</span>
addr <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">&amp;</span>
</span>
</span>
0x80<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=<span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
data <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">&amp;</span>
</span>
</span>
0x80<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
</span>
</span>
<br><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">{</span>
</span>
</span>
<br>
rc <span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
ERR_OK<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
</span>
<br><span style="color: #0000ff;"><span style="color: #ff0000;">break</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
</span>
<br><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">}</span>
</span>
</span>
<br></span>
<span style="color: #0000cc;"><span style="color: #ff0000;">}</span>
</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<p>修改完后重新编译u-boot,下载到RAM中运行结果如下图:<br><img src="http://blog.chinaunix.net/photo/101649_091211132712.png" alt=""></p>
</div>
<p>从运行结果图看,Nor
Flash的大小可以正确检测到了,命令行前面的名字也由原来的SMDK2410改成我自己定义的[MY2440]了,但是还会出现bad
CRC的警告信息,其实这并不是什么问题,只是还没有将环境变量设置到Nor
Flash中,我们执行一下u-boot的:saveenv命令就可以了。如下图:<br><img src="http://blog.chinaunix.net/photo/101649_091211132738.png" alt=""></p>
<p>再重新下载u-boot.bin文件到RAM中运行,可以观察到不会出现警告信息了,这时候u-boot已经对我们开发板上的Nor Flash完全支持了。如下:<br><img src="http://blog.chinaunix.net/photo/101649_091211132754.png" alt=""></p>
<p></p>
<div>
<strong><span style="">下接:</span>
</strong>
<a href="http://blog.chinaunix.net/u3/101649/showart_2119943.html" target="_blank"><strong><span style="">u-boot-2009.08在2440上的移植详解(三)</span>
</strong>
</a>
</div>
<div></div>
</div>
</td>
</tr></tbody></table>
<p style="line-height: 150%; margin: 5px;">

<a href="http://blogold.chinaunix.net/u3/101649/showart.php?id=2276917" target="_blank">回目录 嵌入式Linux之我行——Bootloader移植篇</a>
</p>
<table style="width: 100%;" border="0" cellspacing="0" cellpadding="0"><tbody>
<tr>
<td height="25" align="center">
<span style="font-size: 14pt; color: #02368d;"><strong>嵌入式Linux之我行——u-boot-2009.08在2440上的移植详解(三)</strong>
</span>
<br>
</td>
</tr>
<tr>
<td height="1"></td>
</tr>
<tr>
<td height="1"></td>
</tr>
<tr>
<td align="center">
<table style="border-collapse: collapse; width: 100%;" border="0" cellspacing="0" cellpadding="0"><tbody><tr>
<td width="100%">
<div id="art" style="margin: 15px;">
<div>
<div>嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便。如有错误之处,谢请指正。</div>
<ul>
<li>
<span style="font-size: x-small;">共享资源,欢迎转载:</span>
<a href="http://hbhuanggang.cublog.cn/"><span style="color: #0000ff; font-size: x-small;">http://hbhuanggang.cublog.cn</span>
</a>
</li>
</ul>
<p><strong>一、移植环境</strong>
</p>
<ul>
<li>
<span style="font-size: x-small;">主 机:VMWare--Fedora 9</span>

</li>
<li>
<span style="font-size: x-small;">开发板:Mini2440--64MB Nand,</span>
<a href="http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.30.4.tar.gz" target="_blank"><span style="color: #0000ff; font-size: x-small;">Kernel:2.6.30.4</span>
</a>

</li>
<li>
<span style="font-size: x-small;">编译器:</span>
<a href="http://www.arm123.com.cn/linux/arm-linux-gcc-4.3.2.tgz" target="_blank"><span style="color: #0000ff; font-size: x-small;">arm-linux-gcc-4.3.2.tgz</span>
</a>

</li>
<li>
<span style="font-size: x-small;">u-boot:</span>
<a href="http://ftp.denx.de/pub/u-boot/u-boot-2009.08.tar.bz2" target="_blank"><span style="color: #0000ff; font-size: x-small;">u-boot-2009.08.tar.bz2</span>
</a>
</li>
</ul>
<p><strong>二、移植步骤</strong>
</p>
<p><span style=""><strong>上接</strong>
:</span>
<a href="http://blog.chinaunix.net/u3/101649/showart.php?id=2117210" target="_blank"><strong><span style="">u-boot-2009.08在2440上的移植详解(二)</span>
</strong>
</a>
</p>
<p><strong>5)准备进入u-boot的第二阶段(在u-boot中添加对我们开发板上Nand Flash的支持)<span style=""><span style="font-family: Courier New;"><strong>。</strong>
</span>
</span>
</strong>
<span style=""><span style="font-family: Courier New;"><strong><br></strong>
</span>
</span>
目前u-boot中还没有对2440上Nand Flash的支持,也就是说要想u-boot从Nand Flash上启动得自己去实现了。</p>
<p>首先,在include/configs/my2440.h头文件中定义Nand要用到的宏和寄存器,如下:
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit include/configs/my2440.h <span style="color: #ff9900;">//在文件末尾加入以下Nand Flash相关定义</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style=""><span style="color: #ff9900;">/<span style="color: #0000cc;"><span style="color: #ff9900;">*</span>
</span>
<br><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff9900;">*</span>
</span>
</span>
Nand flash register <span style="color: #0000ff;"><span style="color: #ff9900;">and</span>
</span>
envionment variables<br><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff9900;">*</span>
</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff9900;">/</span>
</span>
<br></span>
<span style="color: #ff0000;"><span style="">#define CONFIG_S3C2440_NAND_BOOT 1<br><br>
#define NAND_CTL_BASE0x4E000000 </span>
<span style=""><span style="color: #ff9900;">//Nand Flash配置寄存器基地址,查2440手册可得知<br></span>
<br>
#define STACK_BASE0x33F00000 <span style="color: #ff9900;">//定义堆栈的地址</span>
<br>
#define STACK_SIZE0x8000 <span style="color: #ff9900;">//堆栈的长度大小</span>
<br><br>
#define oNFCONF0x00<span style="color: #ff9900;">//相对Nand配置寄存器基地址的偏移量,还是配置寄存器的基地址</span>
<br>
#define oNFCONT0x04<span style="color: #ff9900;">//相对Nand配置寄存器基地址的偏移量,可得到控制寄存器的基地址(0x4E000004)</span>
</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style=""><span style="color: #ff0000;">#define oNFADDR0x0c <span style="color: #ff9900;">//相对Nand配置寄存器基地址的偏移量,可得到地址寄存器的基地址(0x4E00000c)</span>
<br>
#define oNFDATA0x10 <span style="color: #ff9900;">//相对Nand配置寄存器基地址的偏移量,可得到数据寄存器的基地址(0x4E000010)</span>
<br>
#define oNFCMD0x08<span style="color: #ff9900;">//相对Nand配置寄存器基地址的偏移量,可得到指令寄存器的基地址(0x4E000008)</span>
<br>
#define oNFSTAT0x20</span>
<span style="color: #ff9900;">//相对Nand配置寄存器基地址的偏移量,可得到状态寄存器的基地址(0x4E000020)</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style=""><span style="color: #ff0000;">#define oNFECC 0x2c </span>
<span style="color: #ff9900;">//相对Nand配置寄存器基地址的偏移量,可得到ECC寄存器的基地址(0x4E00002c)</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<p>其次,修改cpu/arm920t/start.S这个文件,使u-boot从Nand Flash启动,在上一节中提过,u-boot默认是从Nor Flash启动的。修改部分如下:
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit </span>
<span style="font-family: Courier New;">cpu/arm920t/start.S</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff9900;">//注意:在上一篇Nor Flash启动中,我们为了把u-boot用supervivi下载到内存中运行而屏蔽掉这段有关CPU初始化的代码。而现在我们要把u-boot下载到Nand Flash中,从Nand Flash启动,所以现在要恢复这段代码。</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff0000;">#ifndef CONFIG_SKIP_LOWLEVEL_INIT <br>
blcpu_init_crit<br>
#endif</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff0000;">#if 0</span>
<span style="color: #ff9900;">//屏蔽掉u-boot中的从Nor Flash启动部分</span>
<br>
#ifndef CONFIG_SKIP_RELOCATE_UBOOT<br>
relocate: <span style="color: #ff9900;">/* relocate U-Boot to RAM*/<br></span>
adrr0, _start <span style="color: #ff9900;">/* r0 &lt;- current position of code*/</span>
<br>
ldrr1, _TEXT_BASE<span style="color: #ff9900;">/* test if we run from flash or RAM */</span>
<br>
cmpr0, r1 <span style="color: #ff9900;">/* don't reloc during debug*/</span>
<br>
beqstack_setup</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"> ldrr2, _armboot_start<br>
ldrr3, _bss_start<br>
subr2, r3, r2 <span style="color: #ff9900;">/* r2 &lt;- size of armboot */<br></span>
addr2, r0, r2 <span style="color: #ff9900;">/* r2 &lt;- source end address*/</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">copy_loop:<br>
ldmiar0!, {r3-r10}<span style="color: #ff9900;">/* copy from source address [r0] */<br></span>
stmiar1!, {r3-r10}<span style="color: #ff9900;">/* copy to target address [r1]*/</span>
<br>
cmpr0, r2 <span style="color: #ff9900;">/* until source end addreee [r2]*/</span>
<br>
blecopy_loop<br>
#endif<span style="color: #ff9900;">/* CONFIG_SKIP_RELOCATE_UBOOT */</span>
<br><span style="color: #ff0000;">#endif</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="">//下面添加2440中u-boot从Nand Flash启动</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff0000;">#ifdef CONFIG_S3C2440_NAND_BOOT<br>
mov r1, #NAND_CTL_BASE<span style="color: #ff9900;">//复位Nand Flash</span>
<br>
ldr r2, =( (7&lt;&lt;12)|(7&lt;&lt;8)|(7&lt;&lt;4)|(0&lt;&lt;0) )<br>
str r2, [r1, #oNFCONF] <span style="color: #ff9900;">//设置配置寄存器的初始值,参考s3c2440手册</span>
<br>
ldr r2, [r1, #oNFCONF]</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff0000;"> ldr r2, =( (1&lt;&lt;4)|(0&lt;&lt;1)|(1&lt;&lt;0) )<br>
str r2, [r1, #oNFCONT] <span style="color: #ff9900;">//设置控制寄存器</span>
<br>
ldr r2, [r1, #oNFCONT]</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff0000;"> ldr r2, =(0x6)<span style="color: #ff9900;">//RnB Clear</span>
<br>
str r2, [r1, #oNFSTAT]<br>
ldr r2, [r1, #oNFSTAT]<br>
mov r2, #0xff<span style="color: #ff9900;">//复位command</span>
<br>
strb r2, [r1, #oNFCMD]</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff0000;"> mov r3, #0 <span style="color: #ff9900;">//等待</span>
</span>
</span>
</code>
<code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff0000;"><br>
nand1: <br>
add r3, r3, #0x1<br>
cmp r3, #0xa<br>
blt nand1</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff0000;">nand2:<br>
ldr r2, [r1, #oNFSTAT] <span style="color: #ff9900;">//等待就绪</span>
<br>
tst r2, #0x4<br>
beq nand2</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff0000;"> ldr r2, [r1, #oNFCONT]<br>
orr r2, r2, #0x2 <span style="color: #ff9900;">//取消片选</span>
<br>
str r2, [r1, #oNFCONT]</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff0000;"> <span style="color: #ff9900;">//get read to call C functions (for nand_read())</span>
<br>
ldr sp, DW_STACK_START <span style="">//为C代码准备堆栈,DW_STACK_START定义在下面</span>
<span style="color: #ff9900;"><br></span>
mov fp, #0</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff0000;"> <span style="color: #ff9900;">//copy U-Boot to RAM<br></span>
ldr r0, =TEXT_BASE<span style="color: #ff9900;">//传递给C代码的第一个参数:u-boot在RAM中的起始地址<br></span>
mov r1, #0x0<span style="color: #ff9900;">//传递给C代码的第二个参数:Nand Flash的起始地址</span>
<br>
mov r2, #0x30000<span style="color: #ff9900;">//传递给C代码的第三个参数:u-boot的长度大小(128k)<br></span>
bl nand_read_ll<span style="color: #ff9900;">//此处调用C代码中读Nand的函数,现在还没有要自己编写实现</span>
<br>
tst r0, #0x0<br>
beq ok_nand_read</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff0000;">bad_nand_read:<br>
loop2: b loop2<span style="color: #ff9900;">//infinite loop</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff0000;">ok_nand_read:<br><span style="color: #ff9900;">//</span>
<span style="color: #ff9900;">检查搬移后的数据,如果前4k完全相同,表示搬移成功</span>
<br>
mov r0, #0<br>
ldr r1, =TEXT_BASE<br>
mov r2, #0x400 <span style="color: #ff9900;">//4 bytes * 1024 = 4K-bytes<br></span>
go_next:<br>
ldr r3, [r0], #4<br>
ldr r4, [r1], #4<br>
teq r3, r4<br>
bne notmatch<br>
subs r2, r2, #4<br>
beq stack_setup<br>
bne go_next</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff0000;">notmatch:<br>
loop3: b loop3 <span style="color: #ff9900;">//infinite loop</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff0000;">#endif <span style="color: #ff9900;">//CONFIG_S3C2440_NAND_BOOT</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;">_start_armboot:.word start_armboot <span style="color: #ff9900;">//在这一句的下面加上<span style="">DW_STACK_START的定义</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="color: #ff0000;">.align 2<br>
DW_STACK_START: .word STACK_BASE+STACK_SIZE-4 </span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<p>再次,在board/samsung/my2440/目录下新建一个nand_read.c文件,在该文件中来实现上面汇编中要调用的<span style="">nand_read_ll函数,代码如下:
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit board/samsung/my2440/nand_read.c <span style="color: #ff9900;">//新建一个nand_read.c文件,记得保存</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff0000;">#<span style="color: #ff0000;">include</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">&lt;</span>
</span>
config<span style="color: #0000cc;"><span style="color: #ff0000;">.</span>
</span>
h<span style="color: #0000cc;"><span style="color: #ff0000;">&gt;</span>
</span>
</span>
</span>
</span>
</code>
</p>
<code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff0000;">
<p style="margin: 5px; line-height: 150%;"><br><span style="">#define NF_BASE 0x4E000000 <span style="color: #ff9900;">//</span>
<span style="color: #ff9900;">Nand Flash配置寄存器基地址</span>
<br><br>
#define __REGb<span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
x<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">*</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
volatile unsigned char <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">*</span>
</span>
<span style="color: #ff0000;">)(</span>
</span>
</span>
<span style=""><span style="color: #ff0000;">x<span style="color: #0000cc;"><span style="color: #ff0000;">)<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
</span>
<br>
#define __REGi(</span>
x<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">*</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
volatile unsigned <span style="color: #0000ff;"><span style="color: #ff0000;">int</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">*</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
x<span style="color: #0000cc;"><span style="color: #ff0000;">)<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
</span>
<br><br>
#define NFCONF __REGi<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
NF_BASE <span style="color: #0000cc;"><span style="color: #ff0000;">+</span>
</span>
0x0 <span style="color: #0000cc;"><span style="color: #ff0000;">) </span>
<span style="color: #ff9900;">//通过偏移量还是得到配置寄存器基地址</span>
</span>
<br>
#define NFCONT __REGi<span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
NF_BASE <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">+</span>
</span>
</span>
0x4 <span style="color: #0000cc;"><span style="color: #ff0000;">) </span>
<span style="color: #ff9900;">//通过偏移量得到控制寄存器基地址</span>
</span>
<br>
#define NFCMD __REGb<span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
NF_BASE <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">+</span>
</span>
</span>
0x8 <span style="color: #0000cc;"><span style="color: #ff0000;">) </span>
<span style="color: #ff9900;">//通过偏移量得到指令寄存器基地址</span>
</span>
<br>
#define NFADDR __REGb<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
NF_BASE <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">+</span>
</span>
</span>
0xC <span style="color: #0000cc;"><span style="color: #ff0000;">) </span>
<span style="color: #ff9900;">//通过偏移量得到地址寄存器基地址</span>
</span>
<br>
#define NFDATA __REGb<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
NF_BASE <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">+</span>
</span>
</span>
0x10<span style="color: #0000cc;"><span style="color: #ff0000;">) </span>
<span style="color: #ff9900;">//通过偏移量得到数据寄存器基地址</span>
</span>
<br>
#define NFSTAT __REGb<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
NF_BASE <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">+</span>
</span>
</span>
0x20<span style="color: #0000cc;"><span style="color: #ff0000;">) </span>
<span style="color: #ff9900;">//通过偏移量得到状态寄存器基地址</span>
</span>
<br><br>
#define NAND_CHIP_ENABLE <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
NFCONT &amp;<span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
~<span style="color: #ff0000;">(</span>
1<span style="color: #0000cc;"><span style="color: #ff0000;">&lt;</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">&lt;</span>
</span>
</span>
1<span style="color: #0000cc;"><span style="color: #ff0000;">)<span style="color: #0000cc;"><span style="color: #ff0000;">) </span>
<span style="color: #ff9900;">//Nand片选使能</span>
</span>
</span>
</span>
<br>
#define NAND_CHIP_DISABLE <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
NFCONT <span style="color: #0000cc;"><span style="color: #ff0000;">|</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
(1<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">&lt;</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">&lt;</span>
</span>
</span>
</span>
1<span style="color: #0000cc;"><span style="color: #ff0000;">)<span style="color: #0000cc;"><span style="color: #ff0000;">) </span>
<span style="color: #ff9900;">//取消Nand片选</span>
</span>
</span>
</span>
<br><span style="color: #ff0000;">#define NAND_CLEAR_RB (NFSTAT |= (1&lt;&lt;2))<br>
#define NAND_DETECT_RB { while(! (NFSTAT&amp;(1&lt;&lt;2)) );}</span>
</span>
</p>
<p style="margin: 5px; line-height: 150%;"><br><span style="">#define NAND_SECTOR_SIZE 512<br>
#define NAND_BLOCK_MASK <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
NAND_SECTOR_SIZE <span style="color: #0000cc;"><span style="color: #ff0000;">-</span>
</span>
1<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
<br><br>
/<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">*</span>
</span>
</span>
<span style="color: #0000ff;"><span style="color: #ff0000;">low</span>
</span>
level nand read function <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">*</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">/</span>
</span>
<br><span style="color: #0000ff;"><span style="color: #ff0000;">int</span>
</span>
nand_read_ll<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
unsigned char <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">*</span>
</span>
</span>
buf<span style="color: #0000cc;"><span style="color: #ff0000;">,</span>
</span>
unsigned long start_addr<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">,</span>
</span>
</span>
<span style="color: #ff0000;"><span style="color: #0000ff;"><span style="color: #ff0000;">int</span>
</span>
</span>
<span style="color: #0000ff;"><span style="color: #ff0000;">size</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
<br>
{<br><span style="color: #0000ff;"><span style="color: #ff0000;">int</span>
</span>
i<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">,</span>
</span>
</span>
j<span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
<br><br><span style="color: #0000ff;"><span style="color: #ff0000;">if</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(<span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
</span>
</span>
start_addr &amp; NAND_BLOCK_MASK<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">|<span style="color: #0000cc;"><span style="color: #ff0000;">|</span>
</span>
</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
<span style="color: #0000ff;"><span style="color: #ff0000;">size</span>
</span>
&amp; NAND_BLOCK_MASK<span style="color: #0000cc;"><span style="color: #ff0000;">)<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
</span>
<br>
{<br>
return <span style="color: #0000cc;"><span style="color: #ff0000;">-</span>
</span>
1<span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
<span style="color: #ff9900;">//地址或长度不对齐</span>
<br>
}<br><br>
NAND_CHIP_ENABLE<span style="color: #0000cc;"><span style="color: #ff0000;">; </span>
<span style="color: #ff9900;">//选中Nand片选</span>
</span>
<br><br><span style="color: #0000ff;"><span style="color: #ff0000;">for</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
i<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
start_addr<span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
i<span style="color: #0000cc;"><span style="color: #ff0000;">&lt;</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
start_addr <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">+</span>
</span>
</span>
<span style="color: #0000ff;"><span style="color: #ff0000;">size</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">)<span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
<br>
{<br><span style="color: #ff9900;">//发出READ0指令</span>
</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style=""><span style="color: #ff9900;"> </span>
<span style="color: #ff0000;">NAND_CLEAR_RB;<br>
NFCMD <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
0</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
<br><br><span style="color: #ff9900;">//对Nand进行寻址</span>
<br>
NFADDR <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
i &amp; 0xFF<span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
</span>
</p>
</span>
</span>
</span>
</code>
<p style="margin: 5px; line-height: 150%;"><code><span style="font-family: NSimsun;"><span style="">NFADDR <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
i <span style="color: #0000cc;"><span style="color: #ff0000;">&gt;</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">&gt;</span>
</span>
</span>
9<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
&amp; 0xFF<span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
</span>
<span style=""><br>
NFADDR <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
i<span style="color: #0000cc;"><span style="color: #ff0000;">&gt;</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">&gt;</span>
</span>
</span>
17<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
&amp; 0xFF<span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
</span>
<span style=""><br>
NFADDR <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
i<span style="color: #0000cc;"><span style="color: #ff0000;">&gt;</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">&gt;</span>
</span>
</span>
25<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
&amp; 0xFF<span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
</span>
<span style=""><br><br><span style="color: #0000cc;"><span style="color: #ff0000;">NAND_DETECT_RB;</span>
</span>
<br><br><span style="color: #0000ff;"><span style="color: #ff0000;">for</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
j<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
0<span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
j<span style="color: #0000cc;"><span style="color: #ff0000;">&lt;</span>
</span>
NAND_SECTOR_SIZE<span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
j<span style="color: #0000cc;"><span style="color: #ff0000;">+<span style="color: #0000cc;"><span style="color: #ff0000;">+</span>
</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">,</span>
</span>
</span>
i<span style="color: #0000cc;"><span style="color: #ff0000;">+<span style="color: #0000cc;"><span style="color: #ff0000;">+</span>
</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
<br>
{<br><span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">*</span>
</span>
</span>
buf <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">=</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
NFDATA &amp; 0xFF<span style="color: #0000cc;"><span style="color: #ff0000;">)<span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
</span>
</span>
<br>
buf<span style="color: #0000cc;"><span style="color: #ff0000;">+<span style="color: #0000cc;"><span style="color: #ff0000;">+<span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
</span>
</span>
</span>
</span>
<br>
}<br>
}<br><br>
NAND_CHIP_DISABLE<span style="color: #0000cc;"><span style="color: #ff0000;">; </span>
<span style="color: #ff9900;">//取消片选信号</span>
</span>
<br><br>
return 0<span style="color: #0000cc;"><span style="color: #ff0000;">;</span>
</span>
<br>
} </span>
</span>
</code>
</p>
</td>
</tr></tbody></table></span>
</p>
<span style="">
<p><span style="">注意:上面这段代码中对Nand进行寻址的部分,这跟具体的Nand
Flash的寻址方式有关。根据我们开发板上的Nand
Flash(K9F1208U0C)数据手册得知,片内寻址是采用26位地址形式。从第0位开始分四次通过I/O0-I/O7进行传送,并进行片内寻址。
具体含义和结构图如下(相关概念参考Nand数据手册):
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">0 - 7位:字节在上半部、下半部及OOB内的偏移地址<br>
8位:值为0代表对一页内前256个字节进行寻址,值为1代表对一页内后256个字节进行寻址<br>
9-13位:对页进行寻址<br>
14-25位:对块进行寻址<br></span>
</span>
</code>
</p>
</td>
</tr></tbody></table></span>
</p>
<p><span style=""><img src="http://blog.chinaunix.net/photo/101649_091217144330.png" alt=""></span>
</p>
</span>
<p>然后,在board/samsung/my2440/Makefile中添加nand_read.c的编译选项,使他编译到u-boot中,如下:
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">COBJS:<span style="color: #0000cc;">=</span>
my2440.o flash.o <span style="color: #ff0000;">nand_read.o</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<p>还有一个重要的地方要修改,在cpu/arm920t/u-boot.lds中,这个u-boot启动连接脚本文件决定了u-boot运行的入口地
址,以及各个段的存储位置,这也是链接定位的作用。添加下面两行代码的主要目的是防止编译器把我们自己添加的用于nandboot的子函数放到4K之后,
否则是无法启动的。如下:
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #0000cc;">.</span>
text <span style="color: #0000cc;">:</span>
<br><span style="color: #0000cc;">{</span>
<br>
cpu<span style="color: #0000cc;">/</span>
arm920t<span style="color: #0000cc;">/</span>
start<span style="color: #0000cc;">.</span>
o<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">.</span>
text<span style="color: #0000cc;">)</span>
<br><span style="color: #ff0000;">board<span style="color: #0000cc;"><span style="color: #ff0000;">/</span>
</span>
samsung<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">/</span>
</span>
</span>
my2440<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">/</span>
</span>
</span>
lowlevel_init<span style="color: #0000cc;"><span style="color: #ff0000;">.</span>
</span>
o <span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">.</span>
</span>
</span>
text<span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
<br>
board<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">/</span>
</span>
</span>
samsung<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">/</span>
</span>
</span>
my2440<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">/</span>
</span>
</span>
nand_read<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">.</span>
</span>
</span>
o <span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">(</span>
</span>
</span>
<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">.</span>
</span>
</span>
text<span style="color: #0000cc;"><span style="color: #0000cc;"><span style="color: #ff0000;">)</span>
</span>
</span>
<br></span>
<span style="color: #0000cc;">*</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">.</span>
text<span style="color: #0000cc;">)</span>
<br><span style="color: #0000cc;">}</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<p>最后编译u-boot,生成u-boot.bin文件。然后先将mini2440开发板调到Nor启动档,利用supervivi的a命令将u-
boot.bin下载到开发板的Nand Flash中,再把开发板调到Nand启动档,打开电源就从Nand Flash启动了,启动结果图如下:<br><img src="http://blog.chinaunix.net/photo/101649_091217132317.png" alt=""></p>
<p>从上面的运行图看,显然现在的Nand还不能做任何事情,而且也没有显示有关Nand的任何信息,所以只能说明上面的这些步骤只是完成了Nand移
植的Stage1部分。下面我们来添加我们开发板上的Nand Flash(K9F1208U0C)的Stage2部分的有关操作支持。</p>
<p><strong>6)现在进入u-boot的第二阶段(添加Nand Flash(K9F1208U0C)的有关操作支持)<span style=""><span style="font-family: Courier New;">。</span>
</span>
</strong>
<span style=""><span style="font-family: Courier New;"><br></span>
</span>
在上一节中我们说过,通常在嵌入式bootloader中,有两种方式来引导启动内核:从Nor Flash启动和从Nand Flash启动,<span style="">但不管是从Nor启动或者从Nand启动,进入第二阶段以后,两者的执行流程是相同的。</span>
</p>
<p><span style="">当u-boot的start.S运行到“_start_armboot:.word start_armboot”时,就会调用lib_arm/board.c中的start_armboot函数,至此u-boot正式进入第二阶段。<span style="color: #990099;">此
时注意:以前较早的u-boot版本进入第二阶段后,对Nand
Flash的支持有新旧两套代码,新代码在drivers/nand目录下,旧代码在drivers/nand_legacy目录
下,CFG_NAND_LEGACY宏决定了使用哪套代码,如果定义了该宏就使用旧代码,否则使用新代码。但是现在的u-boot-2009.08版本对
Nand的初始化、读写实现是基于最近的Linux内核的MTD架构,删除了以前传统的执行方法,使移植没有以前那样复杂了,实现Nand的操作和基本命
令都直接在drivers/mtd/nand目录下(在doc/README.nand中讲得很清楚</span>
<span style="color: #990099;">)</span>
。下面我们结合代码来分析一下u-boot在第二阶段的执行流程:
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">1.lib_arm/board.c文件中的start_armboot函数调用了drivers/mtd/nand/nand.c文件中的nand_init函数,如下:<br>
#if defined(CONFIG_CMD_NAND) <span style="color: #ff9900;">//可以看到CONFIG_CMD_NAND宏决定了Nand的初始化</span>
<br>
puts (<span style="color: #ff00ff;">"NAND: "</span>
<span style="color: #ff00ff;">)</span>
<span style="color: #ff00ff;">;</span>
<br>
nand_init();<br>
#endif<br><br>
2.nand_init调用了同文件下的nand_init_chip函数;<br>
3.nand_init_chip函数调用drivers/mtd/nand/s3c2410_nand.c文件下的board_nand_init函数,然后再调用drivers/mtd/nand/nand_base.c函数中的nand_scan函数;<br>
4.nand_scan函数调用了同文件下的nand_scan_ident函数等。</span>
</span>
</code>
</p>
</td>
</tr></tbody></table></span>
</p>
</div>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="">因
为2440和2410对nand控制器的操作有很大的不同,所以s3c2410_nand.c下对nand操作的函数就是我们做移植需要实现的部分了,他
与具体的Nand
Flash硬件密切相关。为了区别与2410,这里我们就重新建立一个s3c2440_nand.c文件,在这里面来实现对nand的操作,代码如下: </span>
</span>
</code>
</p>
<code><span style="">
<p style="margin: 5px; line-height: 150%;">
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit drivers/mtd/nand/s3c2440_nand.c <span style="color: #ff9900;">//新建s3c2440_nand.c文件</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><span style="">#include &lt;common.h&gt;</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style="">#if 0<br>
#define DEBUGN printf<br>
#else<br>
#define DEBUGN(x, args ...) {}<br>
#endif</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style="">#include &lt;nand.h&gt;<br>
#include &lt;s3c2410.h&gt;<br>
#include &lt;asm/io.h&gt;</span>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><span style="">#define __REGb(x) (*(volatile unsigned char *)(x))<br>
#define __REGi(x) (*(volatile unsigned int *)(x))</span>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><span style=""><span style="color: #ff0000;">#define NF_BASE 0x4e000000 <span style="color: #ff9900;">//Nand配置寄存器基地址</span>
<br>
#define NFCONF __REGi(NF_BASE + 0x0) <span style="color: #ff9900;">//偏移后还是得到配置寄存器基地址</span>
<br>
#define NFCONT __REGi(NF_BASE + 0x4) <span style="color: #ff9900;">//偏移后得到Nand控制寄存器基地址</span>
<br>
#define NFCMD __REGb(NF_BASE + 0x8) <span style="color: #ff9900;">//偏移后得到Nand指令寄存器基地址</span>
<br>
#define NFADDR __REGb(NF_BASE + 0xc) <span style="color: #ff9900;">//偏移后得到Nand地址寄存器基地址</span>
<br>
#define NFDATA __REGb(NF_BASE + 0x10) <span style="color: #ff9900;">//偏移后得到Nand数据寄存器基地址</span>
<br>
#define NFMECCD0 __REGi(NF_BASE + 0x14) <span style="color: #ff9900;">//偏移后得到Nand主数据区域ECC0寄存器基地址</span>
<br>
#define NFMECCD1 __REGi(NF_BASE + 0x18) <span style="color: #ff9900;">//偏移后得到Nand主数据区域ECC1寄存器基地址</span>
<br>
#define NFSECCD __REGi(NF_BASE + 0x1C) <span style="color: #ff9900;">//偏移后得到Nand空闲区域ECC寄存器基地址</span>
<br>
#define NFSTAT __REGb(NF_BASE + 0x20) <span style="color: #ff9900;">//偏移后得到Nand状态寄存器基地址</span>
<br>
#define NFSTAT0 __REGi(NF_BASE + 0x24) <span style="color: #ff9900;">//偏移后得到Nand ECC0状态寄存器基地址</span>
<br>
#define NFSTAT1 __REGi(NF_BASE + 0x28) <span style="color: #ff9900;">//偏移后得到Nand ECC1状态寄存器基地址</span>
<br>
#define NFMECC0 __REGi(NF_BASE + 0x2C) <span style="color: #ff9900;">//偏移后得到Nand主数据区域ECC0状态寄存器基地址</span>
<br>
#define NFMECC1 __REGi(NF_BASE + 0x30) <span style="color: #ff9900;">//偏移后得到Nand主数据区域ECC1状态寄存器基地址</span>
<br>
#define NFSECC __REGi(NF_BASE + 0x34) <span style="color: #ff9900;">//偏移后得到Nand空闲区域ECC状态寄存器基地址</span>
<br>
#define NFSBLK __REGi(NF_BASE + 0x38) <span style="color: #ff9900;">//偏移后得到Nand块开始地址</span>
<br>
#define NFEBLK __REGi(NF_BASE + 0x3c) </span>
<span style="color: #ff9900;">//偏移后得到Nand块结束地址</span>
</span>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><span style="">#define S3C2440_NFCONT_nCE (1&lt;&lt;1)<br>
#define S3C2440_ADDR_NALE 0x0c<br>
#define S3C2440_ADDR_NCLE 0x08</span>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><span style="">ulong IO_ADDR_W = NF_BASE;</span>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><span style="">static void s3c2440_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)<br>
{<br>
struct nand_chip *chip = mtd-&gt;priv;</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style=""> DEBUGN("hwcontrol(): 0x%02x 0x%02x/n", cmd, ctrl);</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style=""> if (ctrl &amp; NAND_CTRL_CHANGE) {<br>
IO_ADDR_W = NF_BASE;</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style=""> if (!(ctrl &amp; NAND_CLE)) <span style="color: #ff9900;">//要写的是地址</span>
<br>
IO_ADDR_W |= S3C2440_ADDR_NALE;<br>
if (!(ctrl &amp; NAND_ALE)) <span style="color: #ff9900;">//要写的是命令</span>
<br>
IO_ADDR_W |= S3C2440_ADDR_NCLE;</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style=""> if (ctrl &amp; NAND_NCE) <br>
NFCONT &amp;= ~S3C2440_NFCONT_nCE; <span style="color: #ff9900;">//使能nand flash</span>
<br>
else<br>
NFCONT |= S3C2440_NFCONT_nCE; <span style="color: #ff9900;">//禁止nand flash</span>
<br>
}</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style=""> if (cmd != NAND_CMD_NONE)<br>
writeb(cmd,(void *)IO_ADDR_W);<br>
}</span>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><span style="">static int s3c2440_dev_ready(struct mtd_info *mtd)<br>
{<br>
DEBUGN("dev_ready/n");<br>
return (NFSTAT &amp; 0x01);<br>
}</span>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><span style="">int board_nand_init(struct nand_chip *nand)<br>
{<br>
u_int32_t cfg;<br>
u_int8_t tacls, twrph0, twrph1;<br>
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();</span>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><span style=""> DEBUGN("board_nand_init()/n");</span>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><span style=""> clk_power-&gt;CLKCON |= (1 &lt;&lt; 4);</span>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><span style=""> twrph0 = 4; twrph1 = 2; tacls = 0;</span>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><span style=""> cfg = (tacls&lt;&lt;12)|(twrph0&lt;&lt;8)|(twrph1&lt;&lt;4);<br>
NFCONF = cfg;</span>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><span style=""> cfg = (1&lt;&lt;6)|(1&lt;&lt;4)|(0&lt;&lt;1)|(1&lt;&lt;0);<br>
NFCONT = cfg;</span>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><span style=""> <span style="color: #ff9900;">/* initialize nand_chip data structure */</span>
<br>
nand-&gt;IO_ADDR_R = nand-&gt;IO_ADDR_W = (void *)0x4e000010;</span>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><span style=""> </span>
<span style="">/* read_buf and write_buf are default */<br>
/* read_byte and write_byte are default */</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style="color: #ff0000;"><span style=""><span style="color: #ff9900;"> /* hwcontrol always must be implemented */</span>
<br>
nand-&gt;cmd_ctrl = s3c2440_hwcontrol;</span>
</span>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><span style=""> nand-&gt;dev_ready = s3c2440_dev_ready;</span>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><span style=""> return 0;<br>
}</span>
</p>
</td>
</tr></tbody></table>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;">其次,在开发板配置文件include/configs/my2440.h文件中定义支持Nand操作的相关宏,如下:
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit include/configs/my2440.h</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><span style="color: #ff0000;"><span style=""><span style="color: #ff9900;">/* Command line configuration. */<br></span>
#define CONFIG_CMD_NAND<br>
#define CONFIG_CMDLINE_EDITING</span>
</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style="">#ifdef CONFIG_CMDLINE_EDITING<br>
#undef CONFIG_AUTO_COMPLETE<br>
#else<br>
#define CONFIG_AUTO_COMPLETE<br>
#endif</span>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><span style="color: #ff0000;"><span style=""><span style="color: #ff9900;">/* NAND flash settings */<br></span>
#if defined(CONFIG_CMD_NAND)<br>
#define CONFIG_SYS_NAND_BASE0x4E000000 <span style="color: #ff9900;">//Nand配置寄存器基地址</span>
<br>
#define CONFIG_SYS_MAX_NAND_DEVICE1 <br>
#define CONFIG_MTD_NAND_VERIFY_WRITE 1 <br>
//#define NAND_SAMSUNG_LP_OPTIONS1 <span style="color: #ff9900;">//注意:我们这里是64M的Nand Flash,所以不用,如果是128M的大块Nand Flash,则需加上<br></span>
#endif</span>
</span>
</p>
</td>
</tr></tbody></table>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;">然后,在drivers/mtd/nand/Makefile文件中添加s3c2440_nand.c的编译项,如下:
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"># gedit drivers/mtd/nand/Makefile</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">COBJS<span style="color: #0000cc;">-</span>
y <span style="color: #0000cc;">+</span>
<span style="color: #0000cc;">=</span>
s3c2440_nand<span style="color: #0000cc;">.</span>
o<br>
COBJS<span style="color: #0000cc;">-</span>
<span style="color: #0000cc;">$</span>
<span style="color: #0000cc;">(</span>
CONFIG_NAND_S3C2440<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">+</span>
<span style="color: #0000cc;">=</span>
s3c2440_nand<span style="color: #0000cc;">.</span>
o</span>
</span>
</code>
</p>
</td>
</tr></tbody></table></span>
</code>
<p><br>
最后,重新编译u-boot并使用supervivi的a命令下载到Nand Flash中,把开发板调到Nand档从Nand启动,启动结果图如下:<br><img src="http://blog.chinaunix.net/photo/101649_091218171325.png" alt=""></p>
<p>从上图可以看出,现在u-boot已经对我们开发板上64M的Nand Flash完全支持了。Nand相关的基本命令也都可以正常使用了。</p>
<p><strong><span style="color: #990033;">补充内容:</span>
</strong>
</p>
<p><span style="color: #000000;">从以上的启动信息看,有一个警告信息“*** Warning - bad CRC or
NAND, using default
environment”,我们知道,这是因为我们还没有将u-boot的环境变量保存nand中的缘故,那现在我们就用u-boot的saveenv命
令来保存环境变量,如下:<br><img src="http://blog.chinaunix.net/photo/101649_091224122913.png" alt=""></span>
</p>
<p>从上图可以看到保存环境变量并没有成功,而且从信息看他将把环境变量保存到Flash中,显然这不正确,我们是要保存到Nand中。原来,u-boot在默认的情况下把环境变量都是保存到Nor Flash中的,所以我们要修改代码,让他保存到Nand中,如下:
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit include/configs/my2440.h</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff9900;"><span style="color: #ff9900;">//注释掉环境变量保存到Flash的宏(注意:如果你要使用上一篇中的从Nor启动的saveenv命令,则要恢复这些Flash宏定义)</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff9900;"><span style="color: #ff0000;">//#define CONFIG_ENV_IS_IN_FLASH 1<br>
//#define CONFIG_ENV_SIZE 0x10000</span>
/* Total Size of Environment Sector */</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;">
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff9900;"><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff9900;"><span style="color: #ff9900;">//添加环境变量保存到Nand的宏(注意:如果你要使用上一篇中的从Nor启动的saveenv命令,则不要这些Nand宏定义)</span>
</span>
</span>
</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff9900;"><span style="color: #ff0000;">#define CONFIG_ENV_IS_IN_NAND 1<br>
#define CONFIG_ENV_OFFSET 0x30000 <span style="color: #ff9900;">//将环境变量保存到nand中的0x30000位置</span>
<br>
#define CONFIG_ENV_SIZE 0x10000</span>
/* Total Size of Environment Sector */</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<p>重新编译u-boot,下载到nand中,启动开发板再来保存环境变量,如下:<br><img src="http://blog.chinaunix.net/photo/101649_091224122923.png" alt=""></p>
<p>可以看到,现在成功保存到Nand中了,为了验证,我们重新启动开发板,那条警告信息现在没有了,如下:<br><img src="http://blog.chinaunix.net/photo/101649_091224122932.png" alt=""></p>
<p></p>
<p><strong><span style="">下接:</span>
</strong>
<a href="http://blog.chinaunix.net/u3/101649/showart_2126764.html" target="_blank"><strong><span style="">u-boot-2009.08在2440上的移植详解(四)</span>
</strong>
</a>
</p>
<br><br>
</div>
</td>
</tr></tbody></table>
<p style="line-height: 150%; margin: 5px;">

<a href="http://blogold.chinaunix.net/u3/101649/showart.php?id=2276917" target="_blank">回目录 嵌入式Linux之我行——Bootloader移植篇 </a>

</p>
</td>
</tr>
<tr>
<td height="25">
<span style="color: #000099;"><strong>TAG</strong>
</span>

<a style="color: #ff0000;" href="http://blog.chinaunix.net/tag.php?q=arm" target="_blank">arm</a>
<a style="color: #ff0000;" href="http://blog.chinaunix.net/tag.php?q=u-boot%D2%C6%D6%B2" target="_blank">u-boot移植</a>

<a style="color: #ff0000;" href="http://blog.chinaunix.net/tag.php?q=2440" target="_blank">2440</a>
</td>
</tr>
</tbody></table>
<table style="width: 100%;" border="0" cellspacing="0" cellpadding="0"><tbody>
<tr>
<td height="25" align="center">
<span style="font-size: 14pt; color: #02368d;"><strong>嵌入式Linux之我行——u-boot-2009.08在2440上的移植详解(四)</strong>
</span>
<br>
</td>
</tr>
<tr>
<td height="1"></td>
</tr>
<tr>
<td height="1"></td>
</tr>
<tr>
<td align="center">
<table style="border-collapse: collapse; width: 100%;" border="0" cellspacing="0" cellpadding="0"><tbody><tr>
<td width="100%">
<div id="art" style="margin: 15px;">
<div>
<div>嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便。如有错误之处,谢请指正。</div>
<ul>
<li>
<span style="font-size: x-small;">共享资源,欢迎转载:</span>
<a href="http://hbhuanggang.cublog.cn/"><span style="color: #0000ff; font-size: x-small;">http://hbhuanggang.cublog.cn</span>
</a>
</li>
</ul>
<p><strong>一、移植环境</strong>
</p>
<ul>
<li>
<span style="font-size: x-small;">主 机:VMWare--Fedora 9</span>

</li>
<li>
<span style="font-size: x-small;">开发板:Mini2440--64MB Nand,</span>
<a href="http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.30.4.tar.gz" target="_blank"><span style="color: #0000ff; font-size: x-small;">Kernel:2.6.30.4</span>
</a>

</li>
<li>
<span style="font-size: x-small;">编译器:</span>
<a href="http://www.arm123.com.cn/linux/arm-linux-gcc-4.3.2.tgz" target="_blank"><span style="color: #0000ff; font-size: x-small;">arm-linux-gcc-4.3.2.tgz</span>
</a>

</li>
<li>
<span style="font-size: x-small;">u-boot:</span>
<a href="http://ftp.denx.de/pub/u-boot/u-boot-2009.08.tar.bz2" target="_blank"><span style="color: #0000ff; font-size: x-small;">u-boot-2009.08.tar.bz2</span>
</a>
</li>
</ul>
<p><strong>二、移植步骤</strong>
</p>
<p><strong>上接</strong>
:<a href="http://blog.chinaunix.net/u3/101649/showart_2119943.html" target="_blank"><strong><span style="">u-boot-2009.08在2440上的移植详解(三)</span>
</strong>
</a>
</p>
<p>在这一篇中,我们首先让开发板对CS8900或者DM9000X网卡的支持,然后再分析实现u-boot怎样来引导Linux内核启动。因为测试u-boot引导内核我们要用到网络下载功能。</p>
<p><span style=""><strong>7)u-boot对CS8900或者DM9000X网卡的支持。</strong>
<br>
u-
boot-2009.08版本已经对CS8900和DM9000X网卡有比较完善的代码支持(代码在drivers/net/目录下),而且在
S3C24XX系列中默认对CS8900网卡进行配置使用。只是在个别地方要根据开发板的具体网卡片选进行设置,就可以对S3C24XX系列中
CS8900网卡的支持使用。代码如下:
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit include/configs/my2440.h</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style=""><span style="color: #ff9900;">/*<br>
* Hardware drivers<br>
*/</span>
<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;">define</span>
CONFIG_DRIVER_CS89001<span style="color: #ff9900;">/* we have a CS8900 on-board */</span>
<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;">define</span>
CS8900_BASE0x19000300 <span style="color: #ff9900;">//注意:对不同的开发板就是要修改这个片选地址参数,这个参数值就看开发板上网卡的片选引脚是接到ARM芯片存储控制器的哪个Bank上</span>
<br><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;">define</span>
CS8900_BUS161<span style="color: #ff9900;">/* the Linux driver does accesses as shorts */</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table></span>
</p>
</div>
现在修改对我们开发板上DM9000X网卡的支持。<br>
首先,我们看看drivers/net/目录下有关DM9000的代
码,发现dm9000x.h中对CONFIG_DRIVER_DM9000宏的依赖,dm9000x.c中对CONFIG_DM9000_BASE宏、
DM9000_IO宏、DM9000_DATA等宏的依赖,所以我们修改代码如下:
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit include/configs/my2440.h</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><span style="">/* * Hardware drivers */ 屏蔽掉u-boot默认对CS8900网卡的支持<br>
//#define CONFIG_DRIVER_CS8900 1 /* we have a CS8900 on-board */<br>
//#define CS8900_BASE 0x19000300<br>
//#define CS8900_BUS16 1 /* the Linux driver does accesses as shorts */</span>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><span style="">//添加u-boot对DM9000X网卡的支持</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style="color: #ff0000;"><span style="">#define CONFIG_DRIVER_DM9000 1 <br>
#define CONFIG_NET_MULTI 1<br>
#define CONFIG_DM9000_NO_SROM 1<br>
#define CONFIG_DM9000_BASE 0x20000300 <span style="color: #ff9900;">//网卡片选地址</span>
<br>
#define DM9000_IO CONFIG_DM9000_BASE<br>
#define DM9000_DATA (CONFIG_DM9000_BASE + 4) <span style="color: #ff9900;">//网卡数据地址</span>
</span>
</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style="">//#define CONFIG_DM9000_USE_16BIT 1</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style="">注意:<br>
u-boot-2009.08
可以自动检测DM9000网卡的位数,根据开发板原理图可知网卡的数据位为16位,并且网卡位于CPU的BANK4上,所以只需在
board/samsung/my2440/lowlevel_init.S中设置 #define
B4_BWSCON(DW16)即可,不需要此处的#define CONFIG_DM9000_USE_16BIT 1</span>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><span style="">//给u-boot加上ping命令,用来测试网络通不通</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style="">#define CONFIG_CMD_PING </span>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><span style="">//恢复被注释掉的网卡MAC地址和修改你合适的开发板IP地址</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style="color: #ff0000;"><span style="">#define CONFIG_ETHADDR08:00:3e:26:0a:5b </span>
<span style=""><span style="color: #ff9900;">//开发板MAC地址<br></span>
#define CONFIG_NETMASK255.255.255.0<br>
#define CONFIG_IPADDR 192.168.1.105 <span style="color: #ff9900;">//开发板IP地址</span>
</span>
</span>
</p>
<p style="margin: 5px; line-height: 150%;"><span style="">#define CONFIG_SERVERIP192.168.1.103 <span style="color: #ff9900;">//Linux主机IP地址</span>
</span>
</p>
</td>
</tr></tbody></table>
<p>添加板载DM9000网卡初始化代码,如下:
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit board/samsung/my2440/my2440<span style="color: #0000cc;">.</span>
c</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><span style="">#include &lt;net.h&gt;<br>
#include &lt;netdev.h&gt;</span>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><span style="">#ifdef CONFIG_DRIVER_DM9000<br>
int board_eth_init(bd_t *bis)<br>
{<br>
return dm9000_initialize(bis);<br>
}<br>
#endif</span>
</p>
</td>
</tr></tbody></table>
<p>修改MD9000网卡驱动代码,如下:
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit drivers/net/dm9000x.c</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="color: #ff0000;"><span style=""><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
<span style="color: #0000ff;"><span style="color: #ff0000;">if</span>
</span>
0 </span>
</span>
<span style=""><span style="color: #ff9900;">//屏蔽掉dm9000_init函数中的这一部分,不然使用网卡的时候会</span>
<span style="color: #ff9900;">报“could not establish link”的错误<br></span>
i <span style="color: #0000cc;">=</span>
0<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">while</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">!</span>
<span style="color: #0000cc;">(</span>
phy_read<span style="color: #0000cc;">(</span>
1<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">&amp;</span>
0x20<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">{</span>
<span style="color: #ff9900;">/* autonegation complete bit */</span>
<br>
udelay<span style="color: #0000cc;">(</span>
1000<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br>
i<span style="color: #0000cc;">+</span>
<span style="color: #0000cc;">+</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">if</span>
<span style="color: #0000cc;">(</span>
i <span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
10000<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">{</span>
<br><span style="color: #ff0000;">printf</span>
<span style="color: #0000cc;">(</span>
<span style="color: #ff00ff;">"could not establish link "</span>
<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">return</span>
0<span style="color: #0000cc;">;</span>
<br><span style="color: #0000cc;">}</span>
<br><span style="color: #0000cc;">}</span>
<br><span style="color: #0000cc;"><span style="color: #ff0000;">#</span>
</span>
<span style="color: #ff0000;">endif</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<br>
然后重新编译u-boot,下载到Nand中从Nand启动,查看启动信息和环境变量并使用ping命令测试网卡,操作如下:<br><img src="http://blog.chinaunix.net/photo/101649_091228090441.png" alt=""><div>可以看到,启动信息里面显示了Net:dm9000,printenv查看的环境变量也和<span style="">include/configs/my2440.h中设置的一致。但是现在有个问题就是ping不能通过。</span>
</div>
<div></div>
<div>
<span style="">经过一段时间在网上搜索,原来有很多人都碰到了这种情况。出现问题的地方可能是DM9000网卡驱动中关闭网卡的地方,如是就试着修改代码如下:</span>
</div>
<span style="">
<div>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit drivers/net/dm9000x.c <span style="color: #ff9900;">//屏蔽掉dm9000_halt函数中的内容</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
</div>
<div>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff9900;">/*<br>
Stop the interface.<br>
The interface is stopped when it is brought.<br>
*/</span>
<br><span style="color: #0000ff;">static</span>
<span style="color: #0000ff;">void</span>
dm9000_halt<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
eth_device <span style="color: #0000cc;">*</span>
netdev<span style="color: #0000cc;">)</span>
<br><span style="color: #0000cc;">{</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//DM9000_DBG("%sn", __func__);<br></span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">///* RESET devie */</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//phy_write(0, 0x8000);/* PHY RESET */</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//DM9000_iow(DM9000_GPR, 0x01);/* Power-Down PHY */</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//DM9000_iow(DM9000_IMR, 0x80);/* Disable all interrupt */</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//DM9000_iow(DM9000_RCR, 0x00);/* Disable RX */</span>
<br><span style="color: #0000cc;">}</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
</div>
<div></div>
</span>
<div>结果,只是第一次ping不通,以后都是可以ping通的(据网友们说这是正常的),如下图:</div>
<div><img src="http://blog.chinaunix.net/photo/101649_091228130903.png" alt=""></div>
<div></div>
<div>好了,现在只剩下一个问题了,就是使用tftp进行下载。关于tftp服务器在Linux中的安装和配置,这里我就不讲了,在网上搜一下很多的。然而,在tftp下载时又遇到了问题,总是出现传送不完整又重新传送的现象,不断的循环,如下图:</div>
<div><img src="http://blog.chinaunix.net/photo/101649_091228132343.png" alt=""></div>
<div></div>
<div>困惑好久的tftp问题现在终于搞定啦,心情真是爽啊!!首先分析上面图中的现象,在下载过程中断断续续就说明是可以下载的,只是由于某种原因
使网络出现超时从而重新下载,那我想出现这种情况的可能性有两种:1、u-boot中对网络的延时设置;2、就是我的物理网络结构。首先针对第一种,我修
改了net/net.c中对网络延时的设置,结果还是不行。接着就试试第二种情况,因为之前我的网络是通过路由器来管理的,主机和开发板也是通过路由器来
连接的,所以现在我就改用一条交叉网线直接把主机和开发板连接起来,一试,果然可以啦,哈哈哈哈....。至此,网络部分的移植总算完成了。</div>
<div><img src="http://blog.chinaunix.net/photo/101649_091229123512.png" alt=""></div>
<div></div>
<div></div>
<div>
<strong><span style="">8)实现u-boot引导Linux内核启动。</span>
</strong>
</div>
<div></div>
<div>在前面几节中,我们讲了u-boot对Nor Flash和Nand Flash的启动支持,那现在我们就再来探讨一下u-boot怎样来引导Linux内核的启动。</div>
<div></div>
<div>
<span style=""><strong>①、</strong>
<span style="font-size: x-small;">机器码的确定</span>
</span>
</div>
<div>
<span style=""><span style=""><span style="font-size: x-small;">通常,在u-boot和kernel中都会有一个机器码(即:MACH_TYPE),只有这两个机器码一致时才能引导内核,否则就会出现如下mach的错误信息:</span>
</span>
</span>
</div>
<div>
<span style=""><span style=""><img src="http://blog.chinaunix.net/photo/101649_091230170552.png" alt=""></span>
</span>
</div>
<div>
</div>
<div>
<span style=""><span style=""><span style="font-size: x-small;">首先,确定u-boot中的MACH_TYPE。在u-boot的include/asm-arm/mach-types.h文件中针对不同的CPU定义了非常多的MACH_TYPE,可以找到下面这个定义:</span>
</span>
</span>
</div>
<span style="font-size: x-small;">
<div>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #0000cc;">#</span>
<span style="color: #ff0000;">define</span>
MACH_TYPE_SMDK2440 1008 <span style="color: #ff9900;">//针对2440的</span>
</span>
<span style="">MACH_TYPE码的值定义为1008</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
</div>
<div></div>
<div>那么我们就修改u-boot的MACH_TYPE代码引用部分,确定u-boot的MACH_TYPE。如下:</div>
<div>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #000000;"><span style="color: #0000cc;"><span style="color: #000000;">#gedit board/samsung/my2440/my2440.c</span>
<span style="color: #ff9900;">//修改board_init函数</span>
</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
</div>
<div>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff9900;">/* arch number of SMDK2410-Board */</span>
<br></span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;"><span style="color: #ff0000;">//gd-&gt;bd-&gt;bi_arch_number = MACH_TYPE_SMDK2410;<br></span>
</span>
改为:<br><span style="color: #ff0000;">gd-&gt;bd-&gt;bi_arch_number = MACH_TYPE_SMDK2440;</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
</div>
<div></div>
<div>其次,确定kernel中的MACH_TYPE。在kernel的arch/arm/tools/mach-types文件中也针对不同的CPU定义了非常多的MACH_TYPE,也可以找到下面这个定义:</div>
<div>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">smdk2440MACH_SMDK2440SMDK24401008</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
</div>
<div></div>
<div>那么我们就修改kernel的MACH_TYPE代码引用部分,确定kernel的MACH_TYPE。如下:</div>
<div>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #000000;"><span style="color: #0000cc;"><span style="color: #000000;">#gedit </span>
<span style="color: #000000;">arch/arm/mach-s3c2440/mach-smdk2440.c</span>
<span style="color: #ff9900;">//修改文件最后面</span>
</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
</div>
<div>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff0000;">//MACHINE_START(S3C2440, <span style="color: #ff00ff;">"SMDK2440"</span>
<span style="color: #ff00ff;">)</span>
<br></span>
改为:<br><span style="color: #ff0000;">MACHINE_START(SMDK2440, <span style="color: #ff00ff;">"SMDK2440"</span>
<span style="color: #ff00ff;">)</span>
</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
</div>
<div></div>
<div>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit arch/arm/kernel/head.S <span style="color: #ff9900;">//在ENTRY(stext)下添加如下代码(红色部分)</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
</div>
<div>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #000000;">ENTRY(stext)</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff0000;"> mov r0, #0<br>
mov r1, #0x3f0 <span style="color: #ff9900;">//上面的MACH_TYPE值1008换成十六进制就是0x3f0</span>
<br>
ldr r2, =0x30000100<br><br></span>
<span style="color: #000000;">msrcpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style=""> .......</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
</div>
<div></div>
<div>分别重新编译u-boot和kernel。u-boot下载后,记得要saveenv;kernel用tftp下载到内存后使用go命令来测试引导内核,结果可以引导了,如下:</div>
<div><img src="http://blog.chinaunix.net/photo/101649_091230170606.png" alt=""></div>
</span>
<div></div>
<div>
<span style=""><strong><span style="">②</span>
、</strong>
<span style="font-size: x-small;">准备能被u-boot直接引导的内核uImage</span>
</span>
</div>
<div>
<span style=""><span style="font-size: x-small;">通
常,kernel的启动需要u-boot提供一些参数信息,比如ramdisk在RAM中的地址。经过编译后的u-boot在根目录下的tools目录
中,会有个叫做mkimage的工具,他可以给zImage添加一个header,也就是说使得通常我们编译的内核zImage添加一个数据头信息部分,
我们把添加头后的image通常叫uImage,uImage是可以被u-boot直接引导的内核镜像。</span>
</span>
</div>
<div></div>
<div>
<span style=""><span style="font-size: x-small;">mkimage工具的使用介绍如下:</span>
</span>
</div>
<span style="">
<div>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">使用: 中括号括起来的是可选的</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="">mkimage [-x] -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image<br></span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="">选项:<br>
-A:set architecture to 'arch' <span style="color: #ff9900;">//用于指定CPU类型,比如ARM<br></span>
-O:set operating system to 'os' <span style="color: #ff9900;">//用于指定操作系统,比如Linux<br></span>
-T:set image type to 'type' <span style="color: #ff9900;">//用于指定image类型,比如Kernel</span>
<br>
-C:set compression type 'comp' <span style="color: #ff9900;">//指定压缩类型</span>
<br>
-a:set load address to 'addr' (hex) <span style="color: #ff9900;">//指定image的载入地址</span>
<br>
-e:set entry point to 'ep' (hex) <span style="color: #ff9900;">//内核的入口地址,一般为image的载入地址+0x40(信息头的大小)</span>
<br>
-n:set image name to 'name' <span style="color: #ff9900;">//image在头结构中的命名</span>
<br>
-d:use image data from 'datafile' <span style="color: #ff9900;">//无头信息的image文件名</span>
<br>
-x:set XIP (execute in place) <span style="color: #ff9900;">//设置执行位置</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
</div>
<div></div>
<div>
<span style="font-size: x-small;">先将u-boot下的tools中的mkimage复制到主机的/usr/local/bin目录下,这样就可
以在主机的任何目录下使用该工具了。现在我们进入kernel生成目录(一般是arch/arm/boot目录),然后执行如下命令,就会在该目录下生成
一个uImage.img的镜像文件,把他复制到tftp目录下,这就是我们所说的uImage。</span>
</div>
<div>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">mkimage <span style="color: #0000cc;">-</span>
n <span style="color: #ff00ff;">'linux-2.6.30.4'</span>
<span style="color: #0000cc;">-</span>
A arm <span style="color: #0000cc;">-</span>
O linux <span style="color: #0000cc;">-</span>
T kernel <span style="color: #0000cc;">-</span>
C none <span style="color: #0000cc;">-</span>
a 0x30008000 <span style="color: #0000cc;">-</span>
e 0x30008000 <span style="color: #0000cc;">-</span>
d zImage uImage<span style="color: #0000cc;">.</span>
img</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
</div>
<div></div>
<div>
<span style=""><strong>③、</strong>
<span style="font-size: x-small;">Nand Flash的分区。我们查看内核在<span style="font-family: NSimsun;">arch<span style="color: #0000cc;">/</span>
arm<span style="color: #0000cc;">/</span>
plat<span style="color: #0000cc;">-</span>
s3c24xx<span style="color: #0000cc;">/</span>
common<span style="color: #0000cc;">-</span>
smdk<span style="color: #0000cc;">.</span>
c中的分区情况如下</span>
:</span>
</span>
</div>
<div>
<span style="">
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"> 起始地址结束地址</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">uboot : 0x00000000 0x00030000 <br>
param : 0x00030000 0x00040000 <span style="color: #ff9900;">//注意这个环境变量的地址范围要与上一节补充内容中配置的<span style="color: #ff0000;">CONFIG_ENV_OFFSET</span>
<span style="color: #ff9900;">一致</span>
<br></span>
kernel: 0x00050000 0x00200000 <br>
root : 0x00250000 0x03dac000</span>
</span>
</code>
</p>
</td>
</tr></tbody></table></span>
</div>
<div></div>
<div></div>
<div>
<span style=""><span style=""><span style=""><strong>④、</strong>
<span style="font-size: x-small;">设置修改u-boot的启动参数,在u-boot命令行下输入:</span>
</span>
</span>
</span>
</div>
<div>
<span style="">
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff9900;">//设置启动参数,意思是将nand中0x50000-0x00200000(和kernel分区一致)的内容读到内存0x31000000中,然后用bootm命令来执行</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">set bootcmd 'nand read 0x31000000 0x50000 0x00200000;bootm 0x31000000'</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="">saveenv <span style="color: #ff9900;">//保存设置</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table></span>
</div>
<div></div>
<div>
<span style=""><span style=""><span style=""><strong>⑤、</strong>
</span>
<span style="font-size: x-small;">把uImage.img用tftp下载到内存中,然后再固化到Nand Flash中,操作和执行图如下:</span>
</span>
</span>
</div>
<span style=""><span style="">
<div>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">tftp 0x30000000 uImage.img <span style="color: #ff9900;">//将uImage.img下载到内存0x30000000处<br></span>
<br>
nand erase 0x50000 0x200000 <span style="color: #ff9900;">//擦除nand的0x50000-0x200000的内容</span>
<br><br>
nand write 0x30000000 0x50000 0x200000 <span style="color: #ff9900;">//将内存0x30000000处的内容写入到nand的0x50000处</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
</div>
<div></div>
</span>
</span>
<div>
<span style=""><span style=""><img src="http://blog.chinaunix.net/photo/101649_091231110531.png" alt=""></span>
</span>
</div>
<div>
</div>
<div>
<span style=""><span style=""><span style="font-size: x-small;">最后,我们重新启动开发板,可以看到,内核被u-boot成功引导起来了,如图:</span>
</span>
</span>
</div>
<div>
<span style=""><span style=""><img src="http://blog.chinaunix.net/photo/101649_091231110548.png" alt=""></span>
</span>
</div>
<div></div>
</span>
<div></div>
<div></div>
<div>
<strong><span style="">下接:</span>
</strong>
<a href="http://blog.chinaunix.net/u3/101649/showart_2134240.html" target="_blank"><span style=""><strong>u-boot-2009.08在2440上的移植详解(五)</strong>
</span>
</a>
</div>
<div>
<br><br>
</div>
</div>
</td>
</tr></tbody></table>
<p style="line-height: 150%; margin: 5px;">

<a href="http://blogold.chinaunix.net/u3/101649/showart.php?id=2276917" target="_blank">回目录 嵌入式Linux之我行——Bootloader移植篇 </a>

</p>
</td>
</tr>
</tbody></table>
<p style="line-height: 150%; margin: 5px;"></p>
<table style="width: 100%;" border="0" cellspacing="0" cellpadding="0"><tbody>
<tr>
<td height="25" align="center">
<span style="font-size: 14pt; color: #02368d;"><strong>嵌入式Linux之我行——u-boot-2009.08在2440上的移植详解(五)</strong>
</span>
<br>
</td>
</tr>
<tr>
<td height="1"></td>
</tr>
<tr>
<td height="1"></td>
</tr>
<tr>
<td align="center">
<table style="border-collapse: collapse; width: 100%;" border="0" cellspacing="0" cellpadding="0"><tbody><tr>
<td width="100%">
<div id="art" style="margin: 15px;">
<div>
<div>嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便。如有错误之处,谢请指正。</div>
<ul>
<li>
<span style="font-size: x-small;">共享资源,欢迎转载:</span>
<a href="http://hbhuanggang.cublog.cn/"><span style="color: #0000ff; font-size: x-small;">http://hbhuanggang.cublog.cn</span>
</a>
</li>
</ul>
<p><strong>一、移植环境</strong>
</p>
<ul>
<li>
<span style="font-size: x-small;">主 机:VMWare--Fedora 9</span>

</li>
<li>
<span style="font-size: x-small;">开发板:Mini2440--64MB Nand,</span>
<a href="http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.30.4.tar.gz" target="_blank"><span style="color: #0000ff; font-size: x-small;">Kernel:2.6.30.4</span>
</a>

</li>
<li>
<span style="font-size: x-small;">编译器:</span>
<a href="http://www.arm123.com.cn/linux/arm-linux-gcc-4.3.2.tgz" target="_blank"><span style="color: #0000ff; font-size: x-small;">arm-linux-gcc-4.3.2.tgz</span>
</a>

</li>
<li>
<span style="font-size: x-small;">u-boot:</span>
<a href="http://ftp.denx.de/pub/u-boot/u-boot-2009.08.tar.bz2" target="_blank"><span style="color: #0000ff; font-size: x-small;">u-boot-2009.08.tar.bz2</span>
</a>
</li>
</ul>
<p><strong>二、移植步骤</strong>
</p>
<p><strong>上接</strong>
:<a href="http://blog.chinaunix.net/u3/101649/showart_2126764.html" target="_blank"><strong>u-boot-2009.08在2440上的移植详解(四)</strong>
</a>
</p>
</div>
<div>
<strong><span style="">9)实现u-boot对yaffs/yaffs2文件系统下载的支持。</span>
</strong>
</div>
<div></div>
<div> <span style=""><span style="font-size: x-small;">注意:此篇对Nand的操作是基于MTD架构方式,在“<span style="color: #000000;">u-boot-2009.08在2440上的移植详解(三)”中讲到过。</span>
</span>
</span>
</div>
<div></div>
<div>
<span style=""> 通常一个Nnad
Flash存储设备由若干块组成,1个块由若干页组成。一般128MB以下容量的Nand
Flash芯片,一页大小为528B,被依次分为2个256B的主数据区和16B的额外空间;128MB以上容量的Nand
Flash芯片,一页大小通常为2KB。由于Nand Flash出现位反转的概率较大,一般在读写时需要使用ECC进行错误检验和恢复。</span>
</div>
<div></div>
<div>
<span style=""> Yaffs/yaffs2文件系统的设计充分考虑到Nand
Flash以页为存取单位等的特点,将文件组织成固定大小的段(Chunk)。以528B的页为例,Yaffs/yaffs2文件系统使用前512B存储
数据和16B的额外空间存放数据的ECC和文件系统的组织信息等(称为OOB数据)。通过OOB数据,不但能实现错误检测和坏块处理,同时还可以避免加载
时对整个存储介质的扫描,加快了文件系统的加载速度。以下是Yaffs/yaffs2文件系统页的结构说明:</span>

<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"> Yaffs页结构说明<br><span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">====</span>
<br>
字节 用途<br><span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">====</span>
<br>
0 - 511 存储数据(分为两个半部)<br>
512 - 515 系统信息<br>
516 数据状态字<br>
517 块状态字<br>
518 - 519 系统信息<br>
520 - 522 后半部256字节的ECC<br>
523 - 524 系统信息<br>
525 - 527 前半部256字节的ECC<br><span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">====</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
</div>
<div>
<br><span style="">好了,在了解Nand
Flash组成和Yaffs/yaffs2文件系统结构后,我们再回到u-boot中。目前,在u-boot中已经有对Cramfs、Jffs2等文件系
统的读写支持,但与带有数据校验等功能的OOB区的Yaffs/Yaffs2文件系统相比,他们是将所有文件数据简单的以线性表形式组织的。所以,我们只
要在此基础上通过修改u-boot的Nand
Flash读写命令,增加处理00B区域数据的功能,即可以实现对Yaffs/Yaffs2文件系统的读写支持。</span>
</div>
<br><div>实现对Yaffs或者Yaffs2文件系统的读写支持步骤如下:</div>
<div>
<span style=""><strong>①、</strong>
<span style="font-size: x-small;">在include/configs/my2440.h头文件中定义一个管理对Yaffs2支持的宏和开启u-boot中对Nand Flash默认分区的宏,如下:</span>
</span>
</div>
<div>
<span style=""><span style="font-size: x-small;">
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit include/configs/my2440.h <span style="color: #ff9900;">//添加到文件末尾即可</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table></span>
</span>
</div>
<span style="font-size: x-small;">
</span>
<div>
<span style="font-size: x-small;">
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style=""><span style="color: #ff0000;">#define CONFIG_MTD_NAND_YAFFS21</span>
<span style="color: #ff9900;">//</span>
<span style="color: #ff9900;">定义一个管理对Yaffs2支持的宏</span>
<br></span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style=""><span style="color: #ff9900;">//开启Nand Flash默认分区,注意此处的分区要和你的内核中的分区保持一致</span>
<br></span>
<span style=""><span style="color: #ff0000;">#define MTDIDS_DEFAULT <span style="color: #ff00ff;"><span style="color: #ff0000;">"</span>
<span style="color: #ff0000;">nand0=nandflash0</span>
<span style="color: #ff0000;">"</span>
</span>
<br>
#define MTDPARTS_DEFAULT <span style="color: #ff00ff;"><span style="color: #ff0000;">"mtdparts=nandflash0:192k(bootloader),"</span>
</span>
/<br><span style="color: #ff00ff;"><span style="color: #ff0000;">"64k(params),"</span>
</span>
/<br><span style="color: #ff00ff;"><span style="color: #ff0000;">"2m(kernel),"</span>
</span>
/<br></span>
<span style="color: #ff00ff;"><span style="color: #ff0000;">"-(root)"</span>
</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table></span>
</div>
<p><span style=""><strong><span style="">②</span>
、</strong>
<span style="font-size: x-small;">在原来对Nand操作的命令集列表中添加Yaffs2对Nand的写命令,如下:
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit common/cmd_nand.c <span style="color: #ff9900;">//在U_BOOT_CMD中添加</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p>U_BOOT_CMD(nand, CONFIG_SYS_MAXARGS, 1, do_nand,<br>
"NAND sub-system",<br>
"info - show available NAND devices/n"<br>
"nand device [dev] - show or set current device/n"<br>
"nand read - addr off|partition size/n"<br>
"nand write - addr off|partition size/n"<br>
" read/write 'size' bytes starting at offset 'off'/n"<br>
" to/from memory address 'addr', skipping bad blocks./n"</p>
<p><span style="color: #ff9900;">//注意:这里只添加了yaffs2的写命令,因为我们只用u-boot下载(即写)功能,所以我们没有添加yaffs2读的命令<br></span>
<span style="color: #ff0000;">#if defined(CONFIG_MTD_NAND_YAFFS2)<br>
"nand write[.yaffs2] - addr off|partition size - write `size' byte yaffs image/n"<br>
"starting at offset off' from memory address addr' (.yaffs2 for 512+16 NAND)/n"<br>
#endif</span>
</p>
<p><span style="color: #ff0000;"><br></span>
"nand erase [clean] [off size] - erase 'size' bytes from/n"<br>
" offset 'off' (entire device if not specified)/n"<br>
"nand bad - show bad blocks/n"<br>
"nand dump[.oob] off - dump page/n"<br>
"nand scrub - really clean NAND erasing bad blocks (UNSAFE)/n"<br>
"nand markbad off [...] - mark bad block(s) at offset (UNSAFE)/n"<br>
"nand biterr off - make a bit error at offset (UNSAFE)"<br>
#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK<br>
"/n"<br>
"nand lock [tight] [status]/n"<br>
" bring nand to lock state or display locked pages/n"<br>
"nand unlock [offset] [size] - unlock section"<br>
#endif<br>
);</p>
</td>
</tr></tbody></table>
<br></span>
</span>
</p>
<p>接着,在该文件中对nand操作的do_nand函数中添加yaffs2对nand的操作,如下:
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p><span style=""> if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) <br>
{<br>
int read;</span>
</p>
<p><span style=""> if (argc &lt; 4)<br>
goto usage;</span>
</p>
<p><span style=""> addr = (ulong)simple_strtoul(argv[2], NULL, 16);</span>
</p>
<p><span style=""> read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */<br>
printf("/nNAND %s: ", read ? "read" : "write");<br>
if (arg_off_size(argc - 3, argv + 3, nand, &amp;off, &amp;size) != 0)<br>
return 1;</span>
</p>
<p><span style=""> s = strchr(cmd, '.');<br>
if (!s || !strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i")) <br>
{<br>
if (read)<br>
ret = nand_read_skip_bad(nand, off, &amp;size, (u_char *)addr);<br>
else<br>
ret = nand_write_skip_bad(nand, off, &amp;size, (u_char *)addr);<br>
}</span>
</p>
<p><span style="">//添加yaffs2相关操作,注意该处又关联到nand_write_skip_bad函数</span>
</p>
<p><span style="">#if defined(CONFIG_MTD_NAND_YAFFS2)<br>
else if (s != NULL &amp;&amp; (!strcmp(s, ".yaffs2")))<br>
{<br>
nand-&gt;rw_oob = 1;<br>
nand-&gt;skipfirstblk = 1;<br>
ret = nand_write_skip_bad(nand,off,&amp;size,(u_char *)addr);<br>
nand-&gt;skipfirstblk = 0;<br>
nand-&gt;rw_oob = 0;<br>
}<br>
#endif</span>
</p>
<p><span style=""> else if (!strcmp(s, ".oob")) <br>
{<br>
/* out-of-band data */<br>
mtd_oob_ops_t ops = <br>
{<br>
.oobbuf = (u8 *)addr,<br>
.ooblen = size,<br>
.mode = MTD_OOB_RAW<br>
};</span>
</p>
<p><span style=""> if (read)<br>
ret = nand-&gt;read_oob(nand, off, &amp;ops);<br>
else<br>
ret = nand-&gt;write_oob(nand, off, &amp;ops);<br>
} <br>
else <br>
{<br>
printf("Unknown nand command suffix '%s'./n", s);<br>
return 1;<br>
}</span>
</p>
<p><span style=""> printf(" %zu bytes %s: %s/n", size, read ? "read" : "written", ret ? "ERROR" : "OK");</span>
</p>
<p><span style=""> return ret == 0 ? 0 : 1;<br>
}</span>
</p>
</td>
</tr></tbody></table>
<br><span style=""><strong>③、</strong>
<span style="font-size: x-small;">在include/linux/mtd/mtd.h头文件的mtd_info结构体中添加上面用到rw_oob和skipfirstblk数据成员,如下:
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit include/linux/mtd/mtd.h <span style="color: #ff9900;">//在mtd_info结构体中添加</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="">#if defined(CONFIG_MTD_NAND_YAFFS2)<br>
u_char rw_oob;<br>
u_char skipfirstblk;<br>
#endif</span>
</span>
</code>
</p>
</td>
</tr></tbody></table></span>
</span>
<br><span style=""><span style=""><span style=""><strong>④、</strong>
<span style="font-size: x-small;">在第二步关联的<span style="color: #000000;">nand_write_skip_bad函数中添加对Nand OOB的相关操作,如下:
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit drivers/mtd/nand/nand_util.c <span style="color: #ff9900;">//在</span>
</span>
<span style="">nand_write_skip_bad函数中添加</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p>int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, u_char *buffer)<br>
{<br>
int rval;<br>
size_t left_to_write = *length;<br>
size_t len_incl_bad;<br>
u_char *p_buffer = buffer;</p>
<p><span style="color: #ff0000;">#if defined(CONFIG_MTD_NAND_YAFFS2) <span style="color: #ff9900;">//add yaffs2 file system support<br></span>
if(nand-&gt;rw_oob==1) <br>
{<br>
size_t oobsize = nand-&gt;oobsize;<br>
size_t datasize = nand-&gt;writesize;<br>
int datapages = 0;</span>
</p>
<p><span style="color: #ff0000;"> if (((*length)%(nand-&gt;oobsize+nand-&gt;writesize)) != 0) <br>
{<br>
printf ("Attempt to write error length data!/n");<br>
return -EINVAL;<br>
}</span>
</p>
<p><span style="color: #ff0000;"> datapages = *length/(datasize+oobsize);<br>
*length = datapages*datasize;<br>
left_to_write = *length;<br>
}<br>
#endif</span>
</p>
<p> /* Reject writes, which are not page aligned */<br>
if ((offset &amp; (nand-&gt;writesize - 1)) != 0 ||<br>
(*length &amp; (nand-&gt;writesize - 1)) != 0) {<br>
printf ("Attempt to write non page aligned data/n");<br>
return -EINVAL;<br>
}</p>
<p> len_incl_bad = get_len_incl_bad (nand, offset, *length);</p>
<p> if ((offset + len_incl_bad) &gt;= nand-&gt;size) {<br>
printf ("Attempt to write outside the flash area/n");<br>
return -EINVAL;<br>
}</p>
<p><span style="color: #ff0000;">#if !defined(CONFIG_MTD_NAND_YAFFS2) <span style="color: #ff9900;">//add yaffs2 file system support</span>
<br>
if (len_incl_bad == *length) {<br>
rval = nand_write (nand, offset, length, buffer);<br>
if (rval != 0)<br>
printf ("NAND write to offset %llx failed %d/n",<br>
offset, rval);</span>
</p>
<p><span style="color: #ff0000;"> return rval;<br>
}<br>
#endif</span>
</p>
<p> while (left_to_write &gt; 0) {<br>
size_t block_offset = offset &amp; (nand-&gt;erasesize - 1);<br>
size_t write_size;</p>
<p> WATCHDOG_RESET ();</p>
<p> if (nand_block_isbad (nand, offset &amp; ~(nand-&gt;erasesize - 1))) {<br>
printf ("Skip bad block 0x%08llx/n",<br>
offset &amp; ~(nand-&gt;erasesize - 1));<br>
offset += nand-&gt;erasesize - block_offset;<br>
continue;<br>
}</p>
<p><span style="color: #ff0000;">#if defined(CONFIG_MTD_NAND_YAFFS2) <span style="color: #ff9900;">//add yaffs2 file system support</span>
<br>
if(nand-&gt;skipfirstblk==1) <br>
{<br>
nand-&gt;skipfirstblk=0;<br>
printf ("Skip the first good block %llx/n", offset &amp; ~(nand-&gt;erasesize - 1));<br>
offset += nand-&gt;erasesize - block_offset;<br>
continue;<br>
}<br>
#endif</span>
</p>
<p> if (left_to_write &lt; (nand-&gt;erasesize - block_offset))<br>
write_size = left_to_write;<br>
else<br>
write_size = nand-&gt;erasesize - block_offset;</p>
<p> <span style="color: #ff0000;">printf("/rWriting at 0x%llx -- ",offset);</span>
<span style="color: #ff9900;">//add yaffs2 file system support</span>
</p>
<p><br>
rval = nand_write (nand, offset, &amp;write_size, p_buffer);<br>
if (rval != 0) {<br>
printf ("NAND write to offset %llx failed %d/n",<br>
offset, rval);<br>
*length -= left_to_write;<br>
return rval;<br>
}</p>
<p> left_to_write -= write_size;<br>
printf("%d%% is complete.",100-(left_to_write/(*length/100)));<br>
offset += write_size;</p>
<p><span style="color: #ff0000;">#if defined(CONFIG_MTD_NAND_YAFFS2) <span style="color: #ff9900;">//add yaffs2 file system support</span>
<br>
if(nand-&gt;rw_oob==1) <br>
{<br>
p_buffer += write_size+(write_size/nand-&gt;writesize*nand-&gt;oobsize);<br>
} <br>
else <br>
{<br>
p_buffer += write_size;<br>
}<br>
#else<br>
p_buffer += write_size;<br>
#endif</span>
</p>
<p> }</p>
<p> return 0;<br>
}</p>
</td>
</tr></tbody></table></span>
</span>
</span>
</span>
</span>
<br><span style=""><span style=""><span style=""><strong>⑤、</strong>
<span style="font-size: x-small;">在第四步nand_write_skip_bad函数中我们看到又对nand_write函数进行了访问,所以这一步是到nand_write函数中添加对yaffs2的支持,如下:
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">#gedit drivers/mtd/nand/nand_base.c <span style="color: #ff9900;">//在</span>
</span>
<span style="">nand_write函数中添加</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">static int nand_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const uint8_t *buf)<br>
{<br>
struct nand_chip *chip = mtd-&gt;priv;<br>
int ret;</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff0000;">#if defined(CONFIG_MTD_NAND_YAFFS2) <span style="color: #ff9900;">//add yaffs2 file system support</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff0000;"> int oldopsmode = 0;</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff0000;"> if(mtd-&gt;rw_oob==1) <br>
{<br>
int i = 0;<br>
int datapages = 0;</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff0000;"> size_t oobsize = mtd-&gt;oobsize;<br>
size_t datasize = mtd-&gt;writesize;</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff0000;"> uint8_t oobtemp[oobsize];<br>
datapages = len / (datasize);</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff0000;"> for(i = 0; i &lt; (datapages); i++) <br>
{<br>
memcpy((void *)oobtemp, (void *)(buf + datasize * (i + 1)), oobsize);<br>

memmove((void *)(buf + datasize * (i + 1)), (void *)(buf + datasize *
(i + 1) + oobsize), (datapages - (i + 1)) * (datasize) + (datapages - 1)
* oobsize);<br>
memcpy((void *)(buf+(datapages) * (datasize + oobsize) - oobsize), (void *)(oobtemp), oobsize);<br>
}<br>
}<br>
#endif</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"> /* Do not allow reads past end of device */<br>
if ((to + len) &gt; mtd-&gt;size)<br>
return -EINVAL;<br>
if (!len)<br>
return 0;</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"> nand_get_device(chip, mtd, FL_WRITING);</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"> chip-&gt;ops.len = len;<br>
chip-&gt;ops.datbuf = (uint8_t *)buf;</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff0000;">#if defined(CONFIG_MTD_NAND_YAFFS2) <span style="color: #ff9900;">//add yaffs2 file system support</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff0000;"> if(mtd-&gt;rw_oob!=1) <br>
{<br>
chip-&gt;ops.oobbuf = NULL;<br>
} <br>
else <br>
{<br>
chip-&gt;ops.oobbuf = (uint8_t *)(buf + len);<br>
chip-&gt;ops.ooblen = mtd-&gt;oobsize;<br>
oldopsmode = chip-&gt;ops.mode;<br>
chip-&gt;ops.mode = MTD_OOB_RAW;<br>
}<br>
#else<br>
chip-&gt;ops.oobbuf = NULL;<br>
#endif</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"> ret = nand_do_write_ops(mtd, to, &amp;chip-&gt;ops);</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"> *retlen = chip-&gt;ops.retlen;</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"> nand_release_device(mtd);</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff0000;">#if defined(CONFIG_MTD_NAND_YAFFS2) <span style="color: #ff9900;">//add yaffs2 file system support</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun; color: #ff0000;"> chip-&gt;ops.mode = oldopsmode;<br>
#endif</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"></p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"> return ret;<br>
}</span>
</span>
</code>
</p>
</td>
</tr></tbody></table></span>
</span>
</span>
</span>
<br>
OK,对yaffs2支持的代码已修改完毕,重新编译u-boot并下载到nand中,启动开发板,在u-boot的命令行输入:nand help查看nand的命令,可以看到多了一个<span style="color: #000000;"><span style="">nand write[.yaffs2]的命令,这个就是用来下载yaffs2文件系统到nand中的命令了。</span>
</span>

<p><span style="color: #000000;"><span style=""><strong>⑥、</strong>
<span style="font-size: x-small;">使用nand write[.yaffs2]命令把事前制作好的yaffs2文件系统下载到Nand Flash中(yaffs2文件系统的制作请参考:<a href="http://blog.chinaunix.net/u3/101649/showart_2075312.html" target="_blank"><span style="font-family: Courier New; color: #810081;">Linux-2.6.30.4在2440上的移植之文件系统</span>
</a>
),下载操作步骤和效果图如下:
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">tftp 0x30000000 root-2.6.30.4.bin <span style="color: #ff9900;">//用tftp将yaffs2文件系统下载到内存的0x30000000位置</span>
<br><br>
nand erase 0x250000 0x3dac000 <span style="color: #ff9900;">//擦除Nand的文件系统分区</span>
<br><br>
nand write.yaffs2 0x30000000 0x250000 0x658170 <span style="color: #ff9900;">//将内存中的yaffs2文件系统写入Nand的文件系统分区,注意这里的0x658170是yaffs2文件系统的实际大小(可以在tftp传送完后可以看到),要写正确,否则会形成假坏块</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table></span>
</span>
<br></span>
<img src="http://blog.chinaunix.net/photo/101649_100103193104.png" alt=""></p>
<p><br><span style=""><strong>⑦、</strong>
<span style="font-size: x-small;">结合u-boot和内核来测试启动下载的yaffs2文件系统<br>

置u-boot启动参数bootargs,注意:这一长串参数要与内核配置里面的Boot options--&gt;Default kernel
command
string的设置要一致。特别是mtdblock3要根据内核具体的分区来设,在上一篇中讲到了内核中Nand的分区情况,u-boot属于
mtdblock0,param属于mtdblock1,kernel属于mtdblock2,root就属于mtdblock3,所以这里要设置成
root=/dev/mtdblock3,否则文件系统无法启动成功,会出现一些什么I/O之类的错误<br><img src="http://blog.chinaunix.net/photo/101649_100103195908.png" alt=""></span>
</span>
</p>
<p><span style=""><span style="font-size: x-small;">好了,最后重启开发板,内核引导成功,yaffs2文件系统也挂载成功,效果图如下:<br><img src="http://blog.chinaunix.net/photo/101649_100103195933.png" alt=""></span>
</span>
</p>
<div>
<strong><span style="">下接:</span>
</strong>
<a href="http://blog.chinaunix.net/u3/101649/showart.php?id=2397082" target="_blank"><span style=""><strong>u-boot-2009.08在2440上的移植详解(六)</strong>
</span>
</a>
</div>
</div>
</td>
</tr></tbody></table>
<p style="line-height: 150%; margin: 5px;">

<a href="http://blogold.chinaunix.net/u3/101649/showart.php?id=2276917" target="_blank">回目录 嵌入式Linux之我行——Bootloader移植篇 </a>

</p>
</td>
</tr>
<tr>
<td height="25">
<span style="color: #000099;"><strong>TAG</strong>
</span>

<a style="color: #ff0000;" href="http://blog.chinaunix.net/tag.php?q=u-boot-2009.08%D2%C6%D6%B2" target="_blank">u-boot-2009.08移植</a>
<a style="color: #ff0000;" href="http://blog.chinaunix.net/tag.php?q=yaffs2" target="_blank">yaffs2</a>

<a style="color: #ff0000;" href="http://blog.chinaunix.net/tag.php?q=2440" target="_blank">2440</a>
</td>
</tr>
</tbody></table>
<table style="width: 100%;" border="0" cellspacing="0" cellpadding="0"><tbody>
<tr>
<td height="25" align="center">
<span style="font-size: 14pt; color: #02368d;"><strong>嵌入式Linux之我行——u-boot-2009.08在2440上的移植详解(六)</strong>
</span>
<br>
</td>
</tr>
<tr>
<td height="1"></td>
</tr>
<tr>
<td height="1"></td>
</tr>
<tr>
<td align="center">
<table style="border-collapse: collapse; width: 100%;" border="0" cellspacing="0" cellpadding="0"><tbody><tr>
<td width="100%">
<div id="art" style="margin: 15px;">
<div>
<div>嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便。如有错误之处,谢请指正。</div>
<ul>
<li>
<span style="font-size: x-small;">共享资源,欢迎转载:</span>
<a href="http://hbhuanggang.cublog.cn/"><span style="color: #0000ff; font-size: x-small;">http://hbhuanggang.cublog.cn</span>
</a>
</li>
</ul>
<p><strong>一、移植环境</strong>
</p>
<ul>
<li>
<span style="font-size: x-small;">主 机:VMWare--Fedora 9</span>

</li>
<li>
<span style="font-size: x-small;">开发板:Mini2440--64MB Nand,</span>
<a href="http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.30.4.tar.gz" target="_blank"><span style="color: #0000ff; font-size: x-small;">Kernel:2.6.30.4</span>
</a>

</li>
<li>
<span style="font-size: x-small;">编译器:</span>
<a href="http://www.arm123.com.cn/linux/arm-linux-gcc-4.3.2.tgz" target="_blank"><span style="color: #0000ff; font-size: x-small;">arm-linux-gcc-4.3.2.tgz</span>
</a>

</li>
<li>
<span style="font-size: x-small;">u-boot:</span>
<a href="http://ftp.denx.de/pub/u-boot/u-boot-2009.08.tar.bz2" target="_blank"><span style="color: #0000ff; font-size: x-small;">u-boot-2009.08.tar.bz2</span>
</a>
</li>
</ul>
<p><strong>二、移植步骤</strong>
</p>
<p><strong>上接</strong>
:<a href="http://blog.chinaunix.net/u3/101649/showart.php?id=2134240" target="_blank"><strong>u-boot-2009.08在2440上的移植详解(五)</strong>
</a>
</p>
</div>
<div>
<strong><span style="">10)u-boot利用tftp服务下载内核和利用nfs服务挂载nfs文件系统。</span>
</strong>
</div>
<div>
<strong></strong>
</div>
<div>
<span style="">知识点:</span>
</div>
<ol>
<li>
<span style="">tftp服务的安装与配置及测试;</span>

</li>
<li>
<span style="">nfs服务的安装与配置及测试;</span>

</li>
<li>
<span style="">u-boot到kernel的参数传递(<span style="color: #ff0000;">重点</span>
)。</span>
</li>
</ol>
<p><span style="">
我们知道使用tftp下载内核和使用nfs挂载文件系统的好处是,当我们重新编译内核或文件系统后不用重新把这些镜像文件再烧录到flash上,而是把这
些镜像文件放到开发主机的tftp或nfs服务的主目录下,通过网络来加载他们,不用频繁的往flash上烧,这样一可以保护flash的使用寿命,二可
以方便的调试内核或文件系统,提高开发效率。可见,让u-boot实现这个功能是一件很有意义的事情。</span>
</p>
<p><span style=""> 实现这样的功能很简单,网上也有很多资料。但有很多细节的东西如果稍不注意就导致失败,这里就结合本人实现的过程进行讲述和一些问题的分析。</span>
</p>
<ul>
<li>
<strong><span style="">tftp服务的安装与配置及测试</span>
</strong>
</li>
</ul>
<p><span style=""><strong></strong>
要使用tftp服务及测试它要安装两个软件包,一个就是tftp服务
器,另外一个就是tftp客户端,这里安装客户端只是用于在主机本地测试tftp服务器是否正常运行的,来确保u-boot能够访问tftp服务(u-
boot中已有tftp客户端的功能,其实在前面几篇中都已经使用了tftp下载内核或文件系统到开发板上,如果那里都做到了,这里就可以直接跳过)。</span>
</p>
<p><span style="">
首先使用rpm命令查看你的主机上是否已经安装了tftp服务器和客户端,如果没有安装就去下载这两个软件包进行安装或者可以使用yum命令进行在线安
装,yum会自动的去搜索适合你主机平台的最新软件包进行下载安装,如果主机已经安装了,则会提示软件包已经安装了最新的版本。如下图所示:<br><img src="http://blog.chinaunix.net/photo/101649_101117094209.png" alt=""></span>
</p>
<p><span style="">配置tftp服务器,主要是配置tftp的主目录及访问权限。因tftp服务依赖于xinetd服务,所以一般tftp服务安装好后其配置文件一般会在/etc/xinetd.d/目录下:
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #0000cc;">[</span>
root<span style="color: #0000ff;">@</span>
<span style="color: #808000;">localhost</span>
home<span style="color: #0000cc;">]</span>
</span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;"># vi /etc/xinetd.d/tftp <br></span>
<br>
service tftp<br><span style="color: #0000cc;">{</span>
<br>
disable <span style="color: #0000cc;">=</span>
<span style="color: #ff0000;">no</span>
<br>
socket_type <span style="color: #0000cc;">=</span>
dgram<br>
protocol <span style="color: #0000cc;">=</span>
udp<br><span style="color: #ff0000;">wait</span>
<span style="color: #0000cc;">=</span>
yes<br>
user <span style="color: #0000cc;">=</span>
root<br>
server <span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">/</span>
usr<span style="color: #0000cc;">/</span>
sbin<span style="color: #0000cc;">/</span>
in<span style="color: #0000cc;">.</span>
tftpd<br>
server_args <span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">-</span>
s <span style="color: #0000cc;">/</span>
home<span style="color: #0000cc;">/</span>
tftp<span style="color: #0000cc;">-</span>
root <span style="color: #0000cc;">-</span>
c<span style="color: #ff9900;">//主要是修改这里,指定tftp服务器的主目录,-c选项是指可以创建文件<br></span>
per_source <span style="color: #0000cc;">=</span>
11<br>
cps <span style="color: #0000cc;">=</span>
100 2<br>
flags <span style="color: #0000cc;">=</span>
IPv4<br><span style="color: #0000cc;">}</span>
</span>
<br></span>
</code>
</p>
</td>
</tr></tbody></table></span>
</p>
<span style="">
<p> 创建刚才指定的tftp服务器主目录,也要注意主目录的可读可写的权限:
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #0000cc;">[</span>
root<span style="color: #0000ff;">@</span>
<span style="color: #808000;">localhost</span>
home<span style="color: #0000cc;">]</span>
<span style="color: #ff9900;">#mkdir /home/tftp-root</span>
<br><span style="color: #0000cc;">[</span>
root<span style="color: #0000ff;">@</span>
<span style="color: #808000;">localhost</span>
home<span style="color: #0000cc;">]#<span style="color: #ff9900;">chmod 777 /home/tftp-root</span>
</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table></span>
<p><span style=""> 启动和测试tftp服务:
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #0000cc;">[</span>
root<span style="color: #0000ff;">@</span>
<span style="color: #808000;">localhost</span>
home<span style="color: #0000cc;">]</span>
<span style="color: #ff9900;">#service xinetd restart //重启xinetd服务就会启动其下的所有服务,也包括tftp服务</span>
<br><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #0000cc;">[</span>
root<span style="color: #0000ff;">@</span>
<span style="color: #808000;">localhost</span>
home<span style="color: #0000cc;">]</span>
<span style="color: #ff9900;">#service iptables stop //关闭防火墙</span>
</span>
</span>
<br><span style="color: #0000cc;">[</span>
root<span style="color: #0000ff;">@</span>
<span style="color: #808000;">localhost</span>
home<span style="color: #0000cc;">]</span>
<span style="color: #ff9900;">#tftp 主机IP地址</span>
<br>
tftp<span style="color: #0000cc;">&gt;</span>
get<span style="color: #0000cc;">要下载的文件</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">tftp<span style="color: #0000cc;">&gt;</span>
put<span style="color: #0000cc;">要上传的文件</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">tftp<span style="color: #0000cc;">&gt;</span>
<span style="color: #0000ff;">q</span>
<br><span style="color: #0000cc;">[</span>
root<span style="color: #0000ff;">@</span>
<span style="color: #808000;">localhost</span>
home<span style="color: #0000cc;">]#</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table></span>
</p>
<ul>
<li>
<strong><span style="">nfs服务的安装与配置及测试</span>
</strong>
</li>
</ul>
<p><span style=""><strong> </strong>
以root的身份在控制台输入setup,在系统服务选项中选中nfs服务,如下图:<br><img src="http://blog.chinaunix.net/photo/101649_101117103720.png" alt=""><img src="http://blog.chinaunix.net/photo/101649_101117103744.png" alt=""></span>
</p>
<p><span style=""> 配置NFS服务器的共享主目录,也要注意权限问题:
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="color: #0000cc;"><span style="font-family: NSimsun;"><span style="color: #000000;">[root@localhost home]#</span>
vi /etc/exports <span style="color: #ff9900;">//如果没有这个文件就创建它,添加下面一行配置信息,注意格式一定要正确,否则导致服务不正常</span>
</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="color: #0000cc;"><span style="font-family: NSimsun;">/home/filesystem *(rw,no_root_squash,sync)</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="color: #0000cc;"><span style="color: #000000;"><span style="font-family: NSimsun;">注释:“</span>
<span style="color: #000000;"><span style="color: #0000cc;"><span style="font-family: NSimsun;">/home/filesystem</span>
</span>
</span>
<span style="font-family: NSimsun;">”是NFS服务器的主目录,注意目录的权限</span>
</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="color: #0000cc;"><span style="color: #000000;"><span style="font-family: NSimsun;">“</span>
<span style="font-family: NSimsun; color: #0000cc;">*</span>
<span style="font-family: NSimsun;">”表示所有的IP都可以访问NFS主目录</span>
</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="color: #0000cc;"><span style="color: #000000;"><span style="font-family: NSimsun;">“</span>
<span style="font-family: NSimsun; color: #0000cc;">rw</span>
<span style="font-family: NSimsun;">”表示可读可写</span>
</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="color: #0000cc;"><span style="color: #000000;"><span style="font-family: NSimsun;">”</span>
<span style="font-family: NSimsun; color: #0000cc;">no_root_squash</span>
<span style="font-family: NSimsun;">“表示</span>
<span style="">登入到NFS主机的用户如果是ROOT用户,他就拥有ROOT的权限</span>
</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="color: #0000cc;"><span style=""> “<span style="font-family: NSimsun; color: #0000cc;">sync</span>
”表示同步</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="color: #0000cc;"><span style="font-family: NSimsun;"><span style="color: #000000;">[root@localhost home]#</span>
service nfs restart <span style="color: #ff9900;">//重新启动NFS服务,使配置文件生效</span>
</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table></span>
</p>
<span style="">
<p> 测试NFS服务是否正常。将事先准备好的文件系统放到NFS主目录下,如下:
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">[root@localhost home]# ls /home/filesystem/<br>
bin dev home lib mnt root sum100 tmp var<br>
debug etc hostname linuxrc proc sbin sys usr<br>
[root@localhost home]# </span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="">//在主机本地测试NFS服务,将NFS主目录下的文件系统挂载到/mnt目录下,192.168.1.101是主机的IP</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">[root@localhost home]#mount -o nolock -t nfs 192.168.1.101:/home/filesystem /mnt</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<p> 可以看到/mnt目录下的内容和NFS主目录/home/filesystem下的内容完全一致,说明NFS服务正常:<br><img src="http://blog.chinaunix.net/photo/101649_101117111101.png" alt=""></p>
</span>

<ul>
<li>
<strong><span style="">u-boot到kernel的参数传递</span>
</strong>
<span style=""><strong> </strong>
</span>
</li>
</ul>
<p><span style=""><strong> </strong>
我们知道,在kernel配置选项Boot
options中有一个Default kernel command
string参数项,而在u-boot参数中也有一个bootargs参数项,他们都是供内核启动用的,那他们又有什么区别呢,内核启动时到底是用哪一个
呢?两种参数项分别如下图所示(kernel中的参数指定是从开发板Flash分区上挂载文件系统,u-boot中的参数指定的是从NFS挂载文件系
统):<br><img src="http://blog.chinaunix.net/photo/101649_101117133232.png" alt=""><br><img src="http://blog.chinaunix.net/photo/101649_101117133255.png" alt=""></span>
</p>
<div></div>
<div>
<span style="">
实际上,内核中的参数项是内核默认提供的,在内核配置时去指定,而u-boot提供的则在u-boot启动时传递到内核中取代内核提供的参数。所以当u-
boot没有提供bootargs参数时,内核启动就是用内核配置时指定的参数,当u-boot提供了bootargs参数时就使用u-boot的参数。</span>
</div>
<br><p> 那么,u-boot是如果将参数信息传递到内核中的呢?而内核又是怎么接收u-boot传递过来的参数呢?这就涉及到一点点ARM寄存器的知识了。</p>
<p> 我们知道,ARM有7种工作模式和37个寄存器(31个通用寄存器和6个状态寄存器),如下图:<br><img src="http://blog.chinaunix.net/photo/101649_101117140836.png" alt=""></p>
<p>
ARM工作模式之间的转换就是利用这些寄存器进行,而u-boot参数的传递也利用了三个通用寄存器R0、R1和R2。关于ARM工作模式和寄存器在这里
就不做讲叙了,以后再讲,这里你就理解成u-boot在启动的时候把参数存放到这三个寄存器中,到内核启动时再把寄存器中的参数取出,当然,他们并不是就
这样简单的操作。下面我们看代码一一分析。</p>
<p>
首先,我们来分析一下u-boot是怎样处理和发送要传递的参数,而u-boot要传递的参数又有哪些呢?除了我们最容易知道的bootargs(即内核
commandline)参数项外,要传递的参数还有MACH_TYPE(即我们所说的机器码)、系统根设备信息(标志,页面大小)、内存信息(起始地
址,大小)、RAMDISK信息(起始地址,大小)、压缩的RAMDISK根文件系统信息(起始地址,大小)。由此可见要传递的参数很多,这时候,u-
boot就提供一种叫做参数链表(tagged
list)的方式把这些参数组织起来,链表结构体定义在:include/asm-arm/setup.h中,而实现链表的组织在lib_arm
/bootm.c中:<br><img src="http://blog.chinaunix.net/photo/101649_101119161402.png" alt=""><img src="http://blog.chinaunix.net/photo/101649_101119162600.png" alt=""></p>
<p>我们可以看到,链表的组织是由一系列函数实现,u-boot规定,链表必须以ATAG_CORE标记开始,以ATAG_NONE标记结束,中间就是
一些参数标记项,这点从代码中可以体现出来。那么在这些函数中有一个bd的参数是至关重要的,它是一个bd_info类型的结构体,定义在
include/asm-arm/u-boot.h中,而这个结构体又被一个global_data类型的结构体所引用,定义在include/asm-
arm/global_data.h中,如下:<br><img src="http://blog.chinaunix.net/photo/101649_101119164540.png" alt=""><img src="http://blog.chinaunix.net/photo/101649_101119164554.png" alt=""><br>
那么,那个bd参数到底是做什么用的呢?从定义中可以得知,bd记录了机器码、u-boot参数链表在内存中的地址等信息,那又问,它在什么地方进行记录的呢?它就在我们自己开发板初始化代码中记录的,如:board/samsung/my2440/my2440.c中<br><img src="http://blog.chinaunix.net/photo/101649_101119170625.png" alt=""></p>
<p>注意:bd_t被gd_t所引用,而在global_data.h中我们可以看到,u-boot定义了一个gd_t的全局指针变量*gd,所以在这里就可以直接使用gd来设置bd了。</p>
<p>好了,我们还是接着分析这个参数链表是如何被传递的,组织参数链表的系列函数在一个叫do_bootm_linux的函数中被调用的,还是定义在lib_arm/bootm.c中<br><img src="http://blog.chinaunix.net/photo/101649_101119172049.png" alt=""></p>
<div>从这个函数中我们可以看到,要使参数传递生效必须需要CONFIG_SETUP_MEMORY_TAGS和
CONFIG_CMDLINE_TAG这两个宏的支持,所以需要在include/configs/my2440.h中定义它们。原来我就是没定义它们,
在使用NFS挂载文件系统时就出现问题。同时,theKernel这个函数指针是u-boot参数传递的至关点,我们知道,函数在内存中执行的时候其实就
是一个地址,而在代码中首先将这个函数指针指向kernel的入口地址,最后还将0、机器码和u-boot参数项在内存中的地址带给这个入口地址,故执行
这个入口地址的时候即kernel启动的时候可以有这三个参数进行接收。那么,这个入口地址(kernel启动地址或者说kernel入口地址)是怎么来
的是谁指定的,又是多少呢?看代码,是从一个bootm_headers_t类型的结构体的成员ep取得的,而这个结构体是从调用
do_bootm_linux的地方传递过来的。bootm_headers_t定义在include/image.h中,do_bootm_linux
在common/cmd_bootm.c中被调用,如下:<br><img src="http://blog.chinaunix.net/photo/101649_101119172824.png" alt=""><img src="http://blog.chinaunix.net/photo/101649_101119172958.png" alt="">
</div>
<div></div>
<div>从代码中可以清楚的看到对bootm_headers_t的成员ep进行了赋值,但是还是不够直观这个入口地址到底是多少?只知道是使用
image_get_ep函数从bootm_headers_t中的legacy_hdr_os_copy上取得的,那它在什么地方被赋值的呢?原来在
image_set_ep函数中,定义在tools/mkimage.c中,如下:</div>
<div><img src="http://blog.chinaunix.net/photo/101649_101119172852.png" alt=""></div>
<div></div>
<div>我们再想想,这个mkimage.c是做什么用的?原来是用它来制作u-boot格式的内核——uImage,还记得怎样使用mkimage来制作uImage吧,在“<span style=""><span style="font-size: x-small;"><strong><span style="color: #02368d;">u-boot-2009.08在2440上的移植详解(四)</span>
</strong>
</span>
</span>
”中讲到,如下:</div>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;">mkimage <span style="color: #0000cc;">[</span>
<span style="color: #0000cc;">-</span>
<span style="color: #0000ff;">x</span>
<span style="color: #0000cc;">]</span>
<span style="color: #0000cc;">-</span>
A arch <span style="color: #0000cc;">-</span>
O os <span style="color: #0000cc;">-</span>
T type <span style="color: #0000cc;">-</span>
C comp <span style="color: #0000cc;">-</span>
a addr <span style="color: #0000cc;">-</span>
e ep <span style="color: #0000cc;">-</span>
n name <span style="color: #0000cc;">-</span>
d data_file<span style="color: #0000cc;">[</span>
<span style="color: #0000cc;">:</span>
data_file<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">]</span>
image<br><br>
选项:<br><span style="color: #0000cc;">-</span>
A:set architecture to <span style="color: #ff00ff;">'arch'</span>
<span style="color: #0000cc;">/</span>
<span style="color: #0000cc;">/</span>
用于指定CPU类型,比如ARM<br><span style="color: #0000cc;">-</span>
O:set operating <span style="color: #ff0000;">system</span>
to <span style="color: #ff00ff;">'os'</span>
<span style="color: #0000cc;">/</span>
<span style="color: #0000cc;">/</span>
用于指定操作系统,比如Linux<br><span style="color: #0000cc;">-</span>
T:set image type to <span style="color: #ff00ff;">'type'</span>
<span style="color: #0000cc;">/</span>
<span style="color: #0000cc;">/</span>
用于指定image类型,比如Kernel<br><span style="color: #0000cc;">-</span>
C:set compression type <span style="color: #ff00ff;">'comp'</span>
<span style="color: #0000cc;">/</span>
<span style="color: #0000cc;">/</span>
指定压缩类型<br><span style="color: #0000cc;">-</span>
a:set load address to <span style="color: #ff00ff;">'addr'</span>
<span style="color: #0000cc;">(</span>
<span style="color: #ff0000;">hex</span>
<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">/</span>
<span style="color: #0000cc;">/</span>
指定image的载入地址<br><span style="color: #0000cc;">-</span>
e:set entry point to <span style="color: #ff00ff;">'ep'</span>
<span style="color: #0000cc;">(</span>
<span style="color: #ff0000;">hex</span>
<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">/</span>
<span style="color: #0000cc;">/</span>
内核的入口地址,一般为image的载入地址<span style="color: #0000cc;">+</span>
0x40(信息头的大小)<br><span style="color: #0000cc;">-</span>
n:set image name to <span style="color: #ff00ff;">'name'</span>
<span style="color: #0000cc;">/</span>
<span style="color: #0000cc;">/</span>
image在头结构中的命名<br><span style="color: #0000cc;">-</span>
d:use image data from <span style="color: #ff00ff;">'datafile'</span>
<span style="color: #0000cc;">/</span>
<span style="color: #0000cc;">/</span>
无头信息的image文件名<br><span style="color: #0000cc;">-</span>
x:set XIP <span style="color: #0000cc;">(</span>
execute in place<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">/</span>
<span style="color: #0000cc;">/</span>
设置执行位置<br><br>
例如:<br>
mkimage <span style="color: #0000cc;">-</span>
n <span style="color: #ff00ff;">'linux-2.6.30.4'</span>
<span style="color: #0000cc;">-</span>
A arm <span style="color: #0000cc;">-</span>
O linux <span style="color: #0000cc;">-</span>
T kernel <span style="color: #0000cc;">-</span>
C none <span style="color: #0000cc;">-</span>
a 0x30008000 <span style="color: #0000cc;">-</span>
e 0x30008000 <span style="color: #0000cc;">-</span>
d zImage uImage<span style="color: #0000cc;">.</span>
img</span>
</code>
</p>
</td>
</tr></tbody></table>
<p><br>
呵呵,相信此时的你拨云见日,茅塞顿开了吧!这个入口地址就是0x30008000,这也正是为什么u-boot一定要使用uImage的格式来启动内核的原因之一。<span style="background-color: #ffffff; color: #ff0000;">注意:这里有个kernel入口地址0x30008000,在上面还提到一个u-boot参数链表在内存中的地址0x30000100,试想如果这里指定的kernel入口地址覆盖了参数链表的地址会怎么样?</span>
</p>
<p>好了,把上面每个步骤从下往上看就可以知道u-boot参数项在u-boot端的传递的整个流程了,那么,接下来再分析u-boot参数项在kernel端是怎样接收的。 </p>
<div>kernel启动的流程如下图所示:</div>
<div><img src="http://blog.chinaunix.net/photo/101649_101122123046.png" alt=""></div>
<div></div>
<div>在文件arch/arm/boot/compressed/head.S中,start是zImage的起始点,部分代码如下:</div>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;">start:<br>
......</span>
</code>
<code><span style="color: #000000;"></span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"> .word0x016f2818@ Magic numbers to help the loader<br>
.wordstart@ absolute load/run zImage address<br>
.word_edata@ zImage end address<br>
1:movr7, r1 @ save architecture ID<br>
movr8, r2 @ save atags pointer<br>
......</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;">wont_overwrite:movr0, r4<br>
movr3, r7<br>
bldecompress_kernel<br>
bcall_kernel</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;">......</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;">
<code><span style="color: #000000;">call_kernel:blcache_clean_flush<br>
blcache_off<br>
movr0, #0@ must be zero<br>
movr1, r7@ restore architecture number<br>
movr2, r8@ restore atags pointer<br>
movpc, r4@ call kernel</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;">......</span>
</code>
</p>
</td>
</tr></tbody></table>
<p>首先,将u-boot传递过来的r1(机器码)、r2(参数链表在内在中的物理地址)分别保存到ARM寄存器r7、r8中,再将r7作为参数传递给解压函数<span style="font-family: NSimsun;">decompress_kernel(),在这个解压函数中再将r7传递给全局变量__machine_arch_type,然后在跳转到vmlinux入口之前再将r7、r8还原到r1、r2中。</span>
</p>
<p><span style="">在arch/arm/kernel/head.S文件中,内核vmlinux入口的部分代码如下:</span>
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;">ENTRY<span style="color: #0000cc;">(</span>
stext<span style="color: #0000cc;">)</span>
<br>
setmodePSR_F_BIT <span style="color: #0000cc;">|</span>
PSR_I_BIT <span style="color: #0000cc;">|</span>
SVC_MODE<span style="color: #0000cc;">,</span>
r9 @ ensure svc mode @ <span style="color: #0000ff;">and</span>
irqs disabled<br>
mrcp15<span style="color: #0000cc;">,</span>
0<span style="color: #0000cc;">,</span>
r9<span style="color: #0000cc;">,</span>
c0<span style="color: #0000cc;">,</span>
c0@ get processor id<br><span style="color: #ff0000;">bl</span>
__lookup_processor_type@ r5<span style="color: #0000cc;">=</span>
procinfo r9<span style="color: #0000cc;">=</span>
cpuid<br><span style="color: #0000ff;">movs</span>
r10<span style="color: #0000cc;">,</span>
r5 @ invalid processor <span style="color: #0000cc;">(</span>
r5<span style="color: #0000cc;">=</span>
0<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">?</span>
<br>
beq__error_p @ yes<span style="color: #0000cc;">,</span>
error <span style="color: #ff00ff;">'p'</span>
<br><span style="color: #ff0000;">bl</span>
__lookup_machine_type@ r5<span style="color: #0000cc;">=</span>
machinfo<br><span style="color: #0000ff;">movs</span>
r8<span style="color: #0000cc;">,</span>
r5 @ invalid machine <span style="color: #0000cc;">(</span>
r5<span style="color: #0000cc;">=</span>
0<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">?</span>
<br>
beq__error_a @ yes<span style="color: #0000cc;">,</span>
error <span style="color: #ff00ff;">'a'</span>
<br><span style="color: #ff0000;">bl</span>
__vet_atags<br><span style="color: #ff0000;">bl</span>
__create_page_tables</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;">......</span>
</code>
</p>
</td>
</tr></tbody></table>
<br><span style="">首
先从ARM特殊寄存器(CP15)中获得ARM内核的类型,从处理器内核描述符(proc_info_list)表(__proc_info_begin
—__proc_info_end)中查询有无此ARM
内核的类型,如果无就出错退出。处理器内核描述符定义在include/asm-arm/procinfo.h中,具体的函数实现在
arch/arm/mm/proc-xxx.S中,在编译连接过程中将各种处理器内核描述符组合成表。接着从机器描述(machine_desc)表
(__mach_info_begin—__mach_info_end)中查询有无r1寄存器指定的机器码,如果没有就出错退出,<span style="color: #ff0000;">所以这也说明了为什么在u-boot中指定的机器码一定要与内核中指定的一致,否则内核就无法启动</span>

机器编号mach_type_xxx在arch/arm/tools/mach-types文件中说明,每个机器描述符中包括一个唯一的机器编号,机器描
述符的定义在
include/asm-arm/mach/arch.h中,具体实现在arch/arm/mach-xxxx文件夹中,在编译连接过程中将基于同一种处
理器的不同机器描述符组合成表。例如,S3C2440处理器的机器码为1008的机器描述符如下所示:</span>

<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;">MACHINE_START<span style="color: #0000cc;">(</span>
SMDK2440<span style="color: #0000cc;">,</span>
<span style="color: #ff00ff;">"SMDK2440"</span>
<span style="color: #0000cc;">)</span>
<br><span style="color: #ff9900;">/* Maintainer: Ben Dooks &lt;ben@fluff.org&gt; */</span>
<br><span style="color: #0000cc;">.</span>
phys_io <span style="color: #0000cc;">=</span>
S3C2410_PA_UART<span style="color: #0000cc;">,</span>
<br><span style="color: #0000cc;">.</span>
io_pg_offst<span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">(</span>
u32<span style="color: #0000cc;">)</span>
S3C24XX_VA_UART<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">&gt;</span>
<span style="color: #0000cc;">&gt;</span>
18<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">&amp;</span>
0xfffc<span style="color: #0000cc;">,</span>
<br><span style="color: #0000cc;">.</span>
boot_params<span style="color: #0000cc;">=</span>
S3C2410_SDRAM_PA <span style="color: #0000cc;">+</span>
0x100<span style="color: #0000cc;">,<span style="color: #ff9900;"><span style="font-family: NSimsun;">//注意:这个地址就是与u-boot中参数链表在内存中的物理地址相对应</span>
</span>
</span>
<br><br><span style="color: #0000cc;">.</span>
init_irq <span style="color: #0000cc;">=</span>
s3c24xx_init_irq<span style="color: #0000cc;">,</span>
<br><span style="color: #0000cc;">.</span>
map_io<span style="color: #0000cc;">=</span>
smdk2440_map_io<span style="color: #0000cc;">,</span>
<br><span style="color: #0000cc;">.</span>
init_machine<span style="color: #0000cc;">=</span>
smdk2440_machine_init<span style="color: #0000cc;">,</span>
<br><span style="color: #0000cc;">.</span>
timer <span style="color: #0000cc;">=</span>
<span style="color: #0000cc;">&amp;</span>
s3c24xx_timer<span style="color: #0000cc;">,</span>
<br>
MACHINE_END<br></span>
</code>
</p>
</td>
</tr></tbody></table>
<p>最后就打开MMU,并跳转到 init/main.c的start_kernel()初始化系统。函数start_kernel()的部分代码如下:
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">asmlinkage <span style="color: #0000ff;">void</span>
__init start_kernel<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">void</span>
<span style="color: #0000cc;">)</span>
<br><span style="color: #0000cc;">{</span>
<br><span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<br>
setup_arch<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">&amp;</span>
command_line<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<br><span style="color: #0000cc;">}</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<p>函数setup_arch在arch/arm/kernel/setup.c中实现,部分代码如下:
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #0000ff;">void</span>
__init setup_arch<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">char</span>
<span style="color: #0000cc;">*</span>
<span style="color: #0000cc;">*</span>
cmdline_p<span style="color: #0000cc;">)</span>
<br><span style="color: #0000cc;">{</span>
<br><span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<br>
setup_processor<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br>
mdesc <span style="color: #0000cc;">=</span>
setup_machine<span style="color: #0000cc;">(</span>
machine_arch_type<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<br>
parse_tags<span style="color: #0000cc;">(</span>
tags<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<span style="color: #0000cc;">.</span>
<br><span style="color: #0000cc;">}</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<br><span style="">setup_processor()函数从处理器内核描述符表中找到匹配的描述符,并初始化一些处理器<br>

量。setup_machine()用机器编号(在解压函数decompress_kernel
中被赋值)作为参数返回机器描述符。从机器描述符中获得内核参数的物理地址,赋值给tags
变量。然后调用parse_tags()函数分析内核参数链表,把各个参数值传递给全局变量。这样内核就收到了u-boot传递的参数。</span>

<ul>
<li>
<strong>tftp下载内核和nfs挂载文件系统</strong>
</li>
</ul>
<p>好了,上面tftp服务和nfs服务都已经准备好了,u-boot到kernel的参数传递也没问题了,接下来就设置一下u-boot环境变量中的
参数项和kernel的配置选项使之能使用tftp自动下载kernal和通过网络自动挂载nfs文件系统。u-boot环境变量设置如下:<br><img src="http://blog.chinaunix.net/photo/101649_101122152010.png" alt=""></p>
<p>bootcmd参数项就是使用tftp把主机tftp主目录下的uImage下载到开发板SDRAM中的0x31000000位置,接着使用bootm命令执行引导内核启动。</p>
<p>而bootargs参数项就是内核启动的命令行参数,u-boot就是把这个参数项传递给了内核,通过nfs挂载文件系统。这里一定要注意
serverip和ipaddr的设置(即服务器IP或者开发主机IP和开发板的IP)。另外要注意,内核要能使用nfs也要配置相应的选项,如下:
</p>
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;">File systems ---&gt; <br>
Network File Systems ---&gt; <br>
&lt;*&gt; NFS file system support ## 必选<br>
  • Provide NFSv3 client support ## 可选<br>
  • Root file system <span style="color: #ff0000;">on</span>
  • NFS ## 必选<br>
    Networking ---&gt; <br>
  • Networking support <br>
  • Networking options ---&gt; <br>
  • IP: kernel level autoconfiguration ## 必选</span>
  • <br></span>
    </code>
    </p>
    </td>
    </tr></tbody></table>
    <p><br>
    运行结果如下:</p>
    <p>a. tftp下载内核,并引导内核启动:<br><img src="http://blog.chinaunix.net/photo/101649_101122153429.png" alt=""></p>
    <p>b. u-boot传递的命令行参数被内核所接收:<br><img src="http://blog.chinaunix.net/photo/101649_101122153450.png" alt=""></p>
    <p>c. 内核通过nfs挂载文件系统:<br><img src="http://blog.chinaunix.net/photo/101649_101122153505.png" alt=""></p>
    <p>d.查看挂载的nfs文件系统,发现完全与主机nfs服务器主目录中的文件系统一致,说明成功!<br><img src="http://blog.chinaunix.net/photo/101649_101122153519.png" alt=""></p>
    <p></p>
    </div>
    </td>
    </tr></tbody></table>
    <p style="line-height: 150%; margin: 5px;">

    <a href="http://blogold.chinaunix.net/u3/101649/showart.php?id=2276917" target="_blank">回目录 嵌入式Linux之我行——Bootloader移植篇 </a>

    </p>
    </td>
    </tr>
    </tbody></table>
    <p style="line-height: 150%; margin: 5px;"></p>
    </td>
    </tr>
    </tbody></table>
    分享到:
    评论

    相关推荐

    Global site tag (gtag.js) - Google Analytics