﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-嵌入式-文章分类-U-Boot相关方面的资料</title><link>http://www.cnitblog.com/zouzheng/category/6841.html</link><description>要像阿甘一直向前奔跑！</description><language>zh-cn</language><lastBuildDate>Mon, 26 Sep 2011 13:30:09 GMT</lastBuildDate><pubDate>Mon, 26 Sep 2011 13:30:09 GMT</pubDate><ttl>60</ttl><item><title>uboot patch for QT2410 and GTA01/02</title><link>http://www.cnitblog.com/zouzheng/articles/41560.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Thu, 27 Mar 2008 07:41:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/41560.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/41560.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/41560.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/41560.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/41560.html</trackback:ping><description><![CDATA[<h1 class=firstHeading>Bootloader/zh cn <a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn">http://wiki.openmoko.org/wiki/Bootloader/zh_cn</a></h1>
<div id=bodyContent>
<h3 id=siteSub>From OpenMoko</h3>
<div id=contentSub></div>
<div id=jump-to-nav>Jump to: <a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#column-one"><u><font color=#0000ff>navigation</font></u></a>, <a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#searchInput"><u><font color=#0000ff>search</font></u></a></div>
<!-- start content -->
<div class="thumb tright">
<div style="WIDTH: 302px"><a class=internal title=Neo1973控制台上的u-boot href="http://wiki.openmoko.org/wiki/Image:Uboot-s3c2410fb.jpg"><u><font color=#0000ff><img height=450 alt=Neo1973控制台上的u-boot src="http://wiki.openmoko.org/images/thumb/4/47/Uboot-s3c2410fb.jpg/300px-Uboot-s3c2410fb.jpg" width=300 longDesc=/wiki/Image:Uboot-s3c2410fb.jpg></font></u></a>
<div class=thumbcaption>
<div class=magnify style="FLOAT: right"><a class=internal title=Enlarge href="http://wiki.openmoko.org/wiki/Image:Uboot-s3c2410fb.jpg"><img height=11 alt=Enlarge src="http://wiki.openmoko.org/skins/common/images/magnify-clip.png" width=15></a></div>
Neo1973控制台上的u-boot</div>
</div>
</div>
<div class="thumb tright">
<div style="WIDTH: 302px"><a class=internal title=Neo1973上的u-boot引导菜单 href="http://wiki.openmoko.org/wiki/Image:Neo1973_uboot_splash_closeup.jpg"><img height=385 alt=Neo1973上的u-boot引导菜单 src="http://wiki.openmoko.org/images/thumb/e/e5/Neo1973_uboot_splash_closeup.jpg/300px-Neo1973_uboot_splash_closeup.jpg" width=300 longDesc=/wiki/Image:Neo1973_uboot_splash_closeup.jpg></a>
<div class=thumbcaption>
<div class=magnify style="FLOAT: right"><a class=internal title=Enlarge href="http://wiki.openmoko.org/wiki/Image:Neo1973_uboot_splash_closeup.jpg"><img height=11 alt=Enlarge src="http://wiki.openmoko.org/skins/common/images/magnify-clip.png" width=15></a></div>
Neo1973上的u-boot引导菜单</div>
</div>
</div>
<table class=toc id=toc summary=Contents>
    <tbody>
        <tr>
            <td>
            <div id=toctitle>
            <h2>Contents</h2>
            <span class=toctoggle>[<a class=internal id=togglelink href="javascript:toggleToc()"><u><font color=#0000ff>hide</font></u></a>]</span></div>
            <ul lastCheckbox="null">
                <li class=toclevel-1><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E6.A6.82.E8.BF.B0"><u><font color=#0000ff><span class=tocnumber>1</span> <span class=toctext>概述</span></font></u></a>
                <li class=toclevel-1><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E5.BC.95.E5.AF.BC.E8.A3.85.E8.BD.BD.E7.A8.8B.E5.BA.8F.E6.BA.90.E4.BB.A3.E7.A0.81"><u><font color=#0000ff><span class=tocnumber>2</span> <span class=toctext>引导装载程序源代码</span></font></u></a>
                <li class=toclevel-1><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E5.BC.95.E5.AF.BC.E8.A3.85.E8.BD.BD.E7.A8.8B.E5.BA.8F.E4.BA.8C.E8.BF.9B.E5.88.B6.E6.96.87.E4.BB.B6"><u><font color=#0000ff><span class=tocnumber>3</span> <span class=toctext>引导装载程序二进制文件</span></font></u></a>
                <li class=toclevel-1><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E5.BC.95.E5.AF.BC.E8.A3.85.E8.BD.BD.E7.A8.8B.E5.BA.8F.E5.BC.80.E5.8F.91"><u><font color=#0000ff><span class=tocnumber>4</span> <span class=toctext>引导装载程序开发</span></font></u></a>
                <ul lastCheckbox="null">
                    <li class=toclevel-2><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#QT2410"><u><font color=#0000ff><span class=tocnumber>4.1</span> <span class=toctext>QT2410</span></font></u></a>
                    <li class=toclevel-2><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#GTA01"><u><font color=#0000ff><span class=tocnumber>4.2</span> <span class=toctext>GTA01</span></font></u></a>
                    <ul>
                        <li class=toclevel-3><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E4.BD.BF.E7.94.A8JTAG.E4.BB.8ERAM.E5.90.AF.E5.8A.A8"><u><font color=#0000ff><span class=tocnumber>4.2.1</span> <span class=toctext>使用JTAG从RAM启动</span></font></u></a> </li>
                    </ul>
                    </li>
                </ul>
                <li class=toclevel-1><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E5.BB.BA.E7.AB.8B.E5.8F.AF.E5.BC.95.E5.AF.BC.E7.9A.84.E6.98.A0.E5.83.8F.E6.96.87.E4.BB.B6"><u><font color=#0000ff><span class=tocnumber>5</span> <span class=toctext>建立可引导的映像文件</span></font></u></a>
                <li class=toclevel-1><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E5.BC.95.E5.AF.BC.E8.8F.9C.E5.8D.95"><u><font color=#0000ff><span class=tocnumber>6</span> <span class=toctext>引导菜单</span></font></u></a>
                <ul lastCheckbox="null">
                    <li class=toclevel-2><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E8.BF.9B.E5.85.A5.E5.BC.95.E5.AF.BC.E8.8F.9C.E5.8D.95"><u><font color=#0000ff><span class=tocnumber>6.1</span> <span class=toctext>进入引导菜单</span></font></u></a>
                    <li class=toclevel-2><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E4.BD.BF.E7.94.A8.E5.BC.95.E5.AF.BC.E8.8F.9C.E5.8D.95"><u><font color=#0000ff><span class=tocnumber>6.2</span> <span class=toctext>使用引导菜单</span></font></u></a>
                    <li class=toclevel-2><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E7.BB.99.E5.BC.95.E5.AF.BC.E8.8F.9C.E5.8D.95.E5.A2.9E.E5.8A.A0.E9.A1.B9.E7.9B.AE"><u><font color=#0000ff><span class=tocnumber>6.3</span> <span class=toctext>给引导菜单增加项目</span></font></u></a> </li>
                </ul>
                <li class=toclevel-1><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E5.BC.95.E5.AF.BC.E8.A3.85.E8.BD.BD.E7.A8.8B.E5.BA.8F.E5.91.BD.E4.BB.A4.E6.8F.90.E7.A4.BA.E8.A1.8C"><u><font color=#0000ff><span class=tocnumber>7</span> <span class=toctext>引导装载程序命令提示行</span></font></u></a>
                <ul lastCheckbox="null">
                    <li class=toclevel-2><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#Accessing_the_bootloader_prompt"><u><font color=#0000ff><span class=tocnumber>7.1</span> <span class=toctext>Accessing the bootloader prompt</span></font></u></a>
                    <ul lastCheckbox="null">
                        <li class=toclevel-3><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#Using_usbtty_from_Linux"><u><font color=#0000ff><span class=tocnumber>7.1.1</span> <span class=toctext>Using usbtty from Linux</span></font></u></a>
                        <li class=toclevel-3><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#Typical_u-boot_prompt"><u><font color=#0000ff><span class=tocnumber>7.1.2</span> <span class=toctext>Typical u-boot prompt</span></font></u></a> </li>
                    </ul>
                    <li class=toclevel-2><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#Commands_on_the_bootloader_prompt"><u><font color=#0000ff><span class=tocnumber>7.2</span> <span class=toctext>Commands on the bootloader prompt</span></font></u></a>
                    <ul lastCheckbox="null">
                        <li class=toclevel-3><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E8.87.AA.E5.8A.A8.E5.BC.95.E5.AF.BC"><u><font color=#0000ff><span class=tocnumber>7.2.1</span> <span class=toctext>自动引导</span></font></u></a>
                        <li class=toclevel-3><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E7.8E.AF.E5.A2.83.E5.8F.98.E9.87.8F"><u><font color=#0000ff><span class=tocnumber>7.2.2</span> <span class=toctext>环境变量</span></font></u></a>
                        <li class=toclevel-3><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#MMC.2FSD.E5.8D.A1"><u><font color=#0000ff><span class=tocnumber>7.2.3</span> <span class=toctext>MMC/SD卡</span></font></u></a>
                        <li class=toclevel-3><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#NAND"><u><font color=#0000ff><span class=tocnumber>7.2.4</span> <span class=toctext>NAND</span></font></u></a>
                        <ul lastCheckbox="null">
                            <li class=toclevel-4><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E4.BB.8E_NAND_.E5.8A.A0.E8.BD.BD.E5.86.85.E6.A0.B8"><u><font color=#0000ff><span class=tocnumber>7.2.4.1</span> <span class=toctext>从 NAND 加载内核</span></font></u></a>
                            <li class=toclevel-4><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E5.90.91_NAND_.E5.86.99.E6.96.B0.E7.9A.84.E5.BC.95.E5.AF.BC.E8.A3.85.E8.BD.BD.E7.A8.8B.E5.BA.8F"><u><font color=#0000ff><span class=tocnumber>7.2.4.2</span> <span class=toctext>向 NAND 写新的引导装载程序</span></font></u></a>
                            <li class=toclevel-4><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E5.90.91_NAND_.E5.86.99.E5.86.85.E6.A0.B8"><u><font color=#0000ff><span class=tocnumber>7.2.4.3</span> <span class=toctext>向 NAND 写内核</span></font></u></a>
                            <li class=toclevel-4><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E5.90.91_NAND_.E5.86.99.E6.A0.B9.E6.96.87.E4.BB.B6.E7.B3.BB.E7.BB.9F"><u><font color=#0000ff><span class=tocnumber>7.2.4.4</span> <span class=toctext>向 NAND 写根文件系统</span></font></u></a> </li>
                        </ul>
                        <li class=toclevel-3><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#Neo1973_.E7.9B.B8.E5.85.B3.E7.9A.84.E5.91.BD.E4.BB.A4"><u><font color=#0000ff><span class=tocnumber>7.2.5</span> <span class=toctext>Neo1973 相关的命令</span></font></u></a>
                        <ul lastCheckbox="null">
                            <li class=toclevel-4><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E5.85.B3.E6.9C.BA"><u><font color=#0000ff><span class=tocnumber>7.2.5.1</span> <span class=toctext>关机</span></font></u></a>
                            <li class=toclevel-4><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E5.85.85.E7.94.B5.E5.99.A8.E7.9B.B8.E5.85.B3"><u><font color=#0000ff><span class=tocnumber>7.2.5.2</span> <span class=toctext>充电器相关</span></font></u></a>
                            <ul lastCheckbox="null">
                                <li class=toclevel-5><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E6.9F.A5.E8.AF.A2.E5.85.85.E7.94.B5.E5.99.A8.E7.8A.B6.E6.80.81"><u><font color=#0000ff><span class=tocnumber>7.2.5.2.1</span> <span class=toctext>查询充电器状态</span></font></u></a>
                                <li class=toclevel-5><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E7.A6.81.E7.94.A8.E5.85.85.E7.94.B5.E5.99.A8"><u><font color=#0000ff><span class=tocnumber>7.2.5.2.2</span> <span class=toctext>禁用充电器</span></font></u></a>
                                <li class=toclevel-5><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E5.BC.BA.E5.88.B6.E5.BF.AB.E9.80.9F.E5.85.85.E7.94.B5"><u><font color=#0000ff><span class=tocnumber>7.2.5.2.3</span> <span class=toctext>强制快速充电</span></font></u></a>
                                <li class=toclevel-5><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E4.BD.BF.E8.83.BD.2F.E7.A6.81.E7.94.A8.E8.87.AA.E5.8A.A8.E5.BF.AB.E9.80.9F.E5.85.85.E7.94.B5"><u><font color=#0000ff><span class=tocnumber>7.2.5.2.4</span> <span class=toctext>使能/禁用自动快速充电</span></font></u></a> </li>
                            </ul>
                            <li class=toclevel-4><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E8.83.8C.E5.85.89.E7.81.AF"><u><font color=#0000ff><span class=tocnumber>7.2.5.3</span> <span class=toctext>背光灯</span></font></u></a>
                            <li class=toclevel-4><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E6.8C.AF.E5.8A.A8"><u><font color=#0000ff><span class=tocnumber>7.2.5.4</span> <span class=toctext>振动</span></font></u></a> </li>
                        </ul>
                        <li class=toclevel-3><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#S3C2410_.E4.B8.93.E7.94.A8.E5.91.BD.E4.BB.A4"><u><font color=#0000ff><span class=tocnumber>7.2.6</span> <span class=toctext>S3C2410 专用命令</span></font></u></a>
                        <ul>
                            <li class=toclevel-4><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#266MHz.E6.97.B6.E9.92.9F"><u><font color=#0000ff><span class=tocnumber>7.2.6.1</span> <span class=toctext>266MHz时钟</span></font></u></a> </li>
                        </ul>
                        <li class=toclevel-3><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#QT2410.E4.B8.8A.E7.9A.84TFTP"><u><font color=#0000ff><span class=tocnumber>7.2.7</span> <span class=toctext>QT2410上的TFTP</span></font></u></a>
                        <ul>
                            <li class=toclevel-4><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#TFTP_kernel_download"><u><font color=#0000ff><span class=tocnumber>7.2.7.1</span> <span class=toctext>TFTP kernel download</span></font></u></a> </li>
                        </ul>
                        </li>
                    </ul>
                    </li>
                </ul>
                <li class=toclevel-1><a href="http://wiki.openmoko.org/wiki/Bootloader/zh_cn#.E8.AE.BE.E5.A4.87.E5.9B.BA.E4.BB.B6.E5.8D.87.E7.BA.A7"><u><font color=#0000ff><span class=tocnumber>8</span> <span class=toctext>设备固件升级</span></font></u></a> </li>
            </ul>
            </td>
        </tr>
    </tbody>
</table>
<script type=text/javascript> if (window.showTocToggle) { var tocShowText = "show"; var tocHideText = "hide"; showTocToggle(); } </script>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 概述" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=1"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E6.A6.82.E8.BF.B0></a>
<h2>概述 </h2>
<p>GTA01使用了<a class="external text" title=http://u-boot.sourceforge.net/ href="http://u-boot.sourceforge.net/" rel=nofollow><u><font color=#810081>u-boot</font></u></a>引导装载程序。 </p>
<p>关于u-boot的更多信息可以在下列地方找到 </p>
<ul lastCheckbox="null">
    <li><a class="external free" title=http://www.denx.de/wiki/DULG href="http://www.denx.de/wiki/DULG" rel=nofollow><u><font color=#0000ff>http://www.denx.de/wiki/DULG</font></u></a>
    <li><a class="external free" title=http://www.gumstix.org/tikiwiki/tiki-index.php?page=U-Boot href="http://www.gumstix.org/tikiwiki/tiki-index.php?page=U-Boot" rel=nofollow><u><font color=#0000ff>http://www.gumstix.org/tikiwiki/tiki-index.php?page=U-Boot</font></u></a>
    <li><a class="external free" title=http://linuxdevices.com/articles/AT5085702347.html href="http://linuxdevices.com/articles/AT5085702347.html" rel=nofollow><u><font color=#810081>http://linuxdevices.com/articles/AT5085702347.html</font></u></a> </li>
</ul>
<p>但是，未经修改的u-boot不支持GTA01所需要的许多特性，比如 </p>
<ul lastCheckbox="null">
    <li>利用<a title="S3C2410 Steppingstone/zh cn" href="http://wiki.openmoko.org/wiki/S3C2410_Steppingstone/zh_cn"><u><font color=#810081>S3C2410 Steppingstone</font></u></a>从NAND闪存启动
    <li>从SD/Transflash读取内核/initrd
    <li>S3C2410 NAND闪存
    <li>通过S3C2410 USB Device控制器下载程序
    <li>S3C2410 Framebuffer启动logo/状态显示 </li>
</ul>
<p><a title=User:HaraldWelte href="http://wiki.openmoko.org/wiki/User:HaraldWelte"><u><font color=#0000ff>Harald Welte</font></u></a>正在为这些解决问题而工作，并且实际上它们中的大多数已经得到了实现。 </p>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 引导装载程序源代码" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=2"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E5.BC.95.E5.AF.BC.E8.A3.85.E8.BD.BD.E7.A8.8B.E5.BA.8F.E6.BA.90.E4.BB.A3.E7.A0.81></a>
<h2>引导装载程序源代码 </h2>
<p>从 <a class="external free" title=http://svn.openmoko.org/trunk/src/target/u-boot/patches/ href="http://svn.openmoko.org/trunk/src/target/u-boot/patches/" rel=nofollow><u><font color=#0000ff>http://svn.openmoko.org/trunk/src/target/u-boot/patches/</font></u></a> 可以获得当前的引导装载程序的补丁。 </p>
<p>Untar the sources, apply the patch. run "make gta01bv3_config" (or gta01bv2_config, or whatever hardware revision you have), run "make". You will get a resulting "u-boot.bin" image, which you can directly flash (either using existing bootloader or <a title=Sjf2410-linux href="http://wiki.openmoko.org/wiki/Sjf2410-linux"><u><font color=#0000ff>sjf2410-linux</font></u></a>) into NAND. </p>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 引导装载程序二进制文件" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=3"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E5.BC.95.E5.AF.BC.E8.A3.85.E8.BD.BD.E7.A8.8B.E5.BA.8F.E4.BA.8C.E8.BF.9B.E5.88.B6.E6.96.87.E4.BB.B6></a>
<h2>引导装载程序二进制文件 </h2>
<p>最新的引导装载程序二进制文件可以从 <a class="external free" title=http://buildhost.openmoko.org/tmp/gta01/deploy/images/ href="http://buildhost.openmoko.org/tmp/gta01/deploy/images/" rel=nofollow><u><font color=#0000ff>http://buildhost.openmoko.org/tmp/gta01/deploy/images/</font></u></a> 网站找到。它应该写到 NAND flash 0x00000000 (size 0x30000) 地址处。 </p>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 引导装载程序开发" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=4"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E5.BC.95.E5.AF.BC.E8.A3.85.E8.BD.BD.E7.A8.8B.E5.BA.8F.E5.BC.80.E5.8F.91></a>
<h2>引导装载程序开发 </h2>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: QT2410" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=5"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=QT2410></a>
<h3>QT2410 </h3>
<p>If you want to do bootloader development on the QT2410, it's easier to work with a bootloader image that can be downloaded via USB into RAM instead of flashing. </p>
<p>为了做到这一点，你需要编辑 u-boot/include/configs/qt2410.h 文件，将32行的 "if 0" 改为 "if 1"，然后用 "make" 重新编译。 </p>
<p>The resulting "u-boot.bin" is _NOT SUITABLE_ for NAND flash, but only for direct execution from within ram, e.g. by using the <a title="S3c2410 boot usb" href="http://wiki.openmoko.org/wiki/S3c2410_boot_usb"><u><font color=#0000ff>s3c2410_boot_usb</font></u></a> program. </p>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: GTA01" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=6"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=GTA01></a>
<h3>GTA01 </h3>
<p>Doing bootloader development on the GTA01 is a bit more tricky. first, we don't have any NOR flash. Second, there is no other way to boot _but_ from NAND. Therefore, we also don't have a USB downloader like the QT2410. </p>
<p>The main problem is: The <a title="S3C2410 Steppingstone" href="http://wiki.openmoko.org/wiki/S3C2410_Steppingstone"><u><font color=#0000ff>S3C2410 Steppingstone</font></u></a> unconditionally copies the first 4k of flash into its internal SRAM. That SRAM segment stays unconditionally mapped at physical address zero. How do we get around this </p>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 使用JTAG从RAM启动" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=7"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E4.BD.BF.E7.94.A8JTAG.E4.BB.8ERAM.E5.90.AF.E5.8A.A8></a>
<h4>使用JTAG从RAM启动 </h4>
<p>So how can we boot from RAM? We use JTAG / OpenOCD to </p>
<ul>
    <li>reset and halt the cpu at PC=0 </li>
</ul>
<pre>&gt; reset halt
target halted in ARM state due to debug request, current mode: Supervisor
cpsr: 0x400000d3 pc: 0x00000000
MMU: disabled, D-Cache: disabled, I-Cache: disabled
</pre>
<ul>
    <li>download a small piece of code for low-level SDRAM timing initialization (overwrite 4k SRAM of steppingstone) </li>
</ul>
<pre>&gt; load_binary /space/misc/gta01/u-boot.git/foo.bin 0
downloaded 332 byte in 0s 21899us
</pre>
<ul>
    <li>assert a break point at address 0x33f80000 (which indicates that the low-level code has finished) </li>
</ul>
<pre>&gt; bp 0x33f80000 4 hw
breakpoint added at address 0x33f80000
</pre>
<ul>
    <li>run the code up to the break point </li>
</ul>
<pre>&gt; resume
Target 0 resumed
&gt; Target 0 halted
target halted in ARM state due to breakpoint, current mode: Supervisor
cpsr: 0x600000d3 pc: 0x33f80000
MMU: disabled, D-Cache: disabled, I-Cache: enabled
</pre>
<ul>
    <li>download the u-boot RAM image to 0x33f80000 </li>
</ul>
<pre>&gt; load_binary /space/misc/gta01/u-boot.git/u-boot.bin 0x33f80000
downloaded 135692 byte in 6s 567264us
</pre>
<ul>
    <li>resume processing </li>
</ul>
<pre>&gt; resume
Target 0 resumed
</pre>
<p>At this point, the display backlight gets bright and we see the following familiar prompt on the serial console: </p>
<pre>U-Boot 1.1.6 (Jan 13 2007 - 23:44:23)
DRAM:  128 MB
NAND:  64 MiB
*** Warning - bad CRC or NAND, using default environment
In:    serial
Out:   serial
Err:   serial
Hit any key to stop autoboot:  0
GTA01Bv2 #
</pre>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 建立可引导的映像文件" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=8"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E5.BB.BA.E7.AB.8B.E5.8F.AF.E5.BC.95.E5.AF.BC.E7.9A.84.E6.98.A0.E5.83.8F.E6.96.87.E4.BB.B6></a>
<h2>建立可引导的映像文件 </h2>
<p>u-boot needs bootable images (such as kernels, but also initrd and others) in form of a so-called <em>uImage</em>. In order to create a <em>uImage</em> from e.g. a <em>vmlinux</em> kernel image, you can proceed as follows: </p>
<pre>objcopy -O binary -R .note -R .comment -S vmlinux linux.bin
gzip -9 linux.bin
u-boot/tools/mkimage -A arm -O linux -T kernel -C gzip -a 30008000 -e 30008000 -n "Kernel Image QT2410" -d linux.bin.gz uImage
</pre>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 引导菜单" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=9"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E5.BC.95.E5.AF.BC.E8.8F.9C.E5.8D.95></a>
<h2>引导菜单 </h2>
<div class="thumb tright">
<div style="WIDTH: 402px"><a class=internal title="u-boot boot menu on Neo1973" href="http://wiki.openmoko.org/wiki/Image:Neo1973_uboot_menu.jpg"><img height=267 alt="u-boot boot menu on Neo1973" src="http://wiki.openmoko.org/images/thumb/2/22/Neo1973_uboot_menu.jpg/400px-Neo1973_uboot_menu.jpg" width=400 longDesc=/wiki/Image:Neo1973_uboot_menu.jpg></a>
<div class=thumbcaption>
<div class=magnify style="FLOAT: right"><a class=internal title=Enlarge href="http://wiki.openmoko.org/wiki/Image:Neo1973_uboot_menu.jpg"><img height=11 alt=Enlarge src="http://wiki.openmoko.org/skins/common/images/magnify-clip.png" width=15></a></div>
u-boot boot menu on Neo1973</div>
</div>
</div>
<p>As of the Phase-0 release, our u-boot version now features an on-screen boot menu. </p>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 进入引导菜单" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=10"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E8.BF.9B.E5.85.A5.E5.BC.95.E5.AF.BC.E8.8F.9C.E5.8D.95></a>
<h3>进入引导菜单 </h3>
<p>You can access the boot meny by pressing and holding the <a title="Neo1973 AUX Button" href="http://wiki.openmoko.org/wiki/Neo1973_AUX_Button"><u><font color=#0000ff>Neo1973 AUX Button</font></u></a> together with the power button while switching the phone on. </p>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 使用引导菜单" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=11"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E4.BD.BF.E7.94.A8.E5.BC.95.E5.AF.BC.E8.8F.9C.E5.8D.95></a>
<h3>使用引导菜单 </h3>
<p>By pressing the <a title="Neo1973 AUX Button" href="http://wiki.openmoko.org/wiki/Neo1973_AUX_Button"><u><font color=#0000ff>Neo1973 AUX Button</font></u></a> you can cycle through the menu items. Use the <em>POWER</em> button to select one item. </p>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 给引导菜单增加项目" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=12"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E7.BB.99.E5.BC.95.E5.AF.BC.E8.8F.9C.E5.8D.95.E5.A2.9E.E5.8A.A0.E9.A1.B9.E7.9B.AE></a>
<h3>给引导菜单增加项目 </h3>
<p>You can add items to the boot menu by setting environment variables. FIXME. </p>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 引导装载程序命令提示行" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=13"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E5.BC.95.E5.AF.BC.E8.A3.85.E8.BD.BD.E7.A8.8B.E5.BA.8F.E5.91.BD.E4.BB.A4.E6.8F.90.E7.A4.BA.E8.A1.8C></a>
<h2>引导装载程序命令提示行 </h2>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: Accessing the bootloader prompt" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=14"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=Accessing_the_bootloader_prompt></a>
<h3>Accessing the bootloader prompt </h3>
<p>The bootloader prompt is available either on the serial console (via <a title="Debug Board" href="http://wiki.openmoko.org/wiki/Debug_Board"><u><font color=#0000ff>Debug Board</font></u></a>), or as virtual USB Serial device (USB CDC_ACM). Whether the serial port or usb i used depends on the u-boot environment variables <strong>stdin</strong>, <strong>stdout</strong> and <strong>stderr</strong>. </p>
<p>Whether or not you use usbtty, the first couple of messages will always be displayed on the serial console. </p>
<p>The bootloader is currently configured to waid for three seconds. If a key press on the <strong>stdin</strong> is received within those three seconds, auto-boot is aborted. </p>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: Using usbtty from Linux" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=15"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=Using_usbtty_from_Linux></a>
<h4>Using usbtty from Linux </h4>
<p>Just by connecting the phone in u-boot mode to your Linux pc should make it detect a <a title="CDC ACM" href="http://wiki.openmoko.org/wiki/CDC_ACM"><u><font color=#0000ff>CDC ACM</font></u></a> device, and you should get a new tty device called /dev/ttySAC0. Use your favourite terminal emulator (minicom, cu, zc, ...) to access it like any other serial port. </p>
<p>First, you should try to check whether the USB device shows up in 'lsusb' while you're running in u-boot mode: </p>
<pre># lsusb -d 1457:5119
Bus 005 Device 079: ID 1457:5119
</pre>
<pre># lsusb -v -d 1457:5119
Bus 005 Device 079: ID 1457:5119
Device Descriptor:
bLength                18
bDescriptorType         1
bcdUSB               1.10
bDeviceClass            2 Communications
bDeviceSubClass         0
bDeviceProtocol         0
bMaxPacketSize0        16
idVendor           0x1457
idProduct          0x5119
bcdDevice            0.00
iManufacturer           1 OpenMoko, Inc
iProduct                2 Neo1973 Bootloader U-Boot 1.2.0-g6c7cac8c-dirty-moko3
iSerial                 3 0000000
bNumConfigurations      1
Configuration Descriptor:
bLength                 9
bDescriptorType         2
wTotalLength           85
bNumInterfaces          3
bConfigurationValue     1
iConfiguration          4 TTY via USB
bmAttributes         0xc0
Self Powered
MaxPower                0mA
Interface Descriptor:
bLength                 9
bDescriptorType         4
bInterfaceNumber        0
bAlternateSetting       0
bNumEndpoints           1
bInterfaceClass         2 Communications
bInterfaceSubClass      2 Abstract (modem)
bInterfaceProtocol      1 AT-commands (v.25ter)
iInterface              6 Control Interface
CDC Header:
bcdCDC               0.6e
CDC Call Management:
bmCapabilities       0x00
bDataInterface          1
CDC ACM:
bmCapabilities       0x00
CDC Union:
bMasterInterface        0
bSlaveInterface         1
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0x81  EP 1 IN
bmAttributes            3
Transfer Type            Interrupt
Synch Type               None
Usage Type               Data
wMaxPacketSize     0x0010  1x 16 bytes
bInterval             255
Interface Descriptor:
bLength                 9
bDescriptorType         4
bInterfaceNumber        1
bAlternateSetting       0
bNumEndpoints           2
bInterfaceClass        10 CDC Data
bInterfaceSubClass      0 Unused
bInterfaceProtocol      0
iInterface              5 Bulk Data Interface
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0x02  EP 2 OUT
bmAttributes            2
Transfer Type            Bulk
Synch Type               None
Usage Type               Data
wMaxPacketSize     0x0010  1x 16 bytes
bInterval             255
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0x83  EP 3 IN
bmAttributes            2
Transfer Type            Bulk
Synch Type               None
Usage Type               Data
wMaxPacketSize     0x0010  1x 16 bytes
bInterval             255
Interface Descriptor:
bLength                 9
bDescriptorType         4
bInterfaceNumber        2
bAlternateSetting       0
bNumEndpoints           0
bInterfaceClass       254 Application Specific Interface
bInterfaceSubClass      1 Device Firmware Update
bInterfaceProtocol      1
iInterface              7 USB Device Firmware Upgrade
Device Status:     0x0001
Self Powered
</pre>
<p>Next, you can access it using your favourite terminal program. </p>
<p>Then, if the environment is not set correctly, you will need to use the current console (e.g. serial console) to set </p>
<pre>GTA01Bv2 # setenv stderr usbtty
GTA01Bv2 # setenv stdout usbtty
GTA01Bv2 # setenv stdin usbtty
</pre>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: Typical u-boot prompt" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=16"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=Typical_u-boot_prompt></a>
<h4>Typical u-boot prompt </h4>
<pre>U-Boot 1.2.0-moko1 (Feb 16 2007 - 00:36:13)
DRAM:  128 MB
NAND:  64 MiB
Found Environment offset in OOB..
Video: 640x480x8 31kHz 59Hz
USB:   S3C2410 USB Deviced
In:    serial
Out:   serial
Err:   serial
Hit any key to stop autoboot:  0
GTA01Bv3 #
</pre>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: Commands on the bootloader prompt" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=17"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=Commands_on_the_bootloader_prompt></a>
<h3>Commands on the bootloader prompt </h3>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 自动引导" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=18"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E8.87.AA.E5.8A.A8.E5.BC.95.E5.AF.BC></a>
<h4>自动引导 </h4>
<p>Auto-boot executes the command[s] specified in the <em>bootcmd</em> environment variable. The default configuration is: </p>
<pre>GTA01Bv3 # printenv
bootcmd=setenv bootargs ${bootargs_base} ${mtdparts}; nand read.e 0x32000000 kernel; bootm 0x32000000
</pre>
<p>This basically tells us that it will load the content of the NAND partition <strong>kernel</strong> to memory address 0x32000000 and then try to boot it. </p>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 环境变量" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=19"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E7.8E.AF.E5.A2.83.E5.8F.98.E9.87.8F></a>
<h4>环境变量 </h4>
<p>u-boot is configured to manage a non-volatile environment that is stored in NAND flash. You can use the commands to read/alter/store the environment in the following example: </p>
<pre>GTA01Bv2 # printenv
baudrate=115200
bootargs=rootfstype=jffs2 root=/dev/mtdblock4 console=ttySAC0,115200 console=tty0 loglevel=8 dyntick=enable lpj=252416
usbtty=cdc_acm
bootdelay=10
stdout=serial
stderr=serial
stdin=serial
mtdparts=mtdparts=neo1973-nand:0x00030000(u-boot),0x0000c000(u-boot_env),0x00200000(kernel),0x00130000(splash),0x03c94000(rootfs)
mtdids=nand0=neo1973-nand
bootargs_base=rootfstype=jffs2 root=/dev/mtdblock4 console=ttySAC0,115200 console=tty0 loglevel=8 dyntick=enable lpj=252416
bootcmd=setenv bootargs ${bootargs_base} ${mtdparts}; nand read.e 0x32000000 kernel; bootm 0x32000000
pcf50606_int1=0x40
filesize=160C000
partition=nand0,0
mtddevnum=0
mtddevname=u-boot
Environment size: 670/16380 bytes
GTA01Bv3 # setenv bootdelay 10
GTA01Bv3 # printenv bootdelay
bootdelay=10
GTA01Bv3 # saveenv
Saving Environment to NAND...
Erasing Nand...Writing to Nand... done
GTA01Bv3 #
</pre>
<p>Note: When setting multiple commands, e.g. for bootcmd, you need to escape the ';', for instance </p>
<pre>GTA01Bv3 # setenv bootcmd mmcinit\; ext2load mmc 0 0x32000000 uImage\; bootm 0x32000000
</pre>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: MMC/SD卡" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=20"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=MMC.2FSD.E5.8D.A1></a>
<h4>MMC/SD卡 </h4>
<p>in order to initialize a MMC/SD card, you have to use the ``mmcinit<em> command.</em> </p>
<pre>GTA01Bv3 # mmcinit
trying to detect SD Card...
MMC found. Card desciption is:
Manufacturer ID = 58d564
HW/FW Revision = 3 8
Product Name = 21DN!@X�
Serial Number = 445303
Month = 5
Year = 2000
READ_BL_LEN=15, C_SIZE_MULT=7, C_SIZE=3197
size = 4208984064
GTA01Bv3 #
</pre>
<p>afterwards, you can read ext2 filesystems like: </p>
<pre>GTA01Bv3 # ext2ls mmc 0
&lt;DIR&gt;       1024 .
&lt;DIR&gt;       1024 ..
&lt;DIR&gt;      12288 lost+found
1544788 uImage
</pre>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: NAND" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=21"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=NAND></a>
<h4>NAND </h4>
<pre>GTA01Bv3 # help nand
nand info                  - show available NAND devices
nand device [dev]     - show or set current device
nand read[.jffs2]     - addr off size
nand write[.jffs2]    - addr off size - read/write `size' bytes starting
at offset `off' to/from memory address `addr'
nand erase [clean] [off size] - erase `size' bytes from
offset `off' (entire device if not specified)
nand bad - show bad blocks
nand dump[.oob] off - dump page
nand scrub - really clean NAND erasing bad blocks (UNSAFE)
nand markbad off - mark bad block at offset (UNSAFE)
nand biterr off - make a bit error at offset (UNSAFE)
</pre>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 从 NAND 加载内核" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=22"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E4.BB.8E_NAND_.E5.8A.A0.E8.BD.BD.E5.86.85.E6.A0.B8></a>
<h5>从 NAND 加载内核 </h5>
<pre>GTA01Bv3 # nand read 0x32000000 kernel
NAND read: device 0 offset 212992, size 2097152 ...  2097152 bytes read: OK
GTA01Bv3 # bootm 0x32000000
## Booting image at 32000000 ...
Image Name:   OpenMoko Kernel Image Neo1973
Created:      2007-02-15  23:54:18 UTC
Image Type:   ARM Linux Kernel Image (gzip compressed)
Data Size:    1546258 Bytes =  1.5 MB
Load Address: 30008000
Entry Point:  30008000
Verifying Checksum ... OK
Uncompressing Kernel Image ... OK
Starting kernel ...
</pre>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 向 NAND 写新的引导装载程序" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=23"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E5.90.91_NAND_.E5.86.99.E6.96.B0.E7.9A.84.E5.BC.95.E5.AF.BC.E8.A3.85.E8.BD.BD.E7.A8.8B.E5.BA.8F></a>
<h5>向 NAND 写新的引导装载程序 </h5>
<p>The following set of commands loads the file u-boot.bin from ext2/mmc and flashes it into the bootloader flash partition: </p>
<pre>GTA01Bv3 # ext2load mmc 0 0x32000000 u-boot.bin
GTA01Bv3 # nand erase u-boot
GTA01Bv3 # nand write 0x32000000 u-boot ${filesize}
</pre>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 向 NAND 写内核" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=24"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E5.90.91_NAND_.E5.86.99.E5.86.85.E6.A0.B8></a>
<h5>向 NAND 写内核 </h5>
<p>The following set of commands loads the file uImage from ext2/mmc and flashes it into the kernel flash partition: </p>
<pre>GTA01Bv3 # ext2load mmc 0 0x32000000 uImage
GTA01Bv3 # nand erase kernel
GTA01Bv3 # nand write.e 0x32000000 kernel ${filesize}
</pre>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 向 NAND 写根文件系统" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=25"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E5.90.91_NAND_.E5.86.99.E6.A0.B9.E6.96.87.E4.BB.B6.E7.B3.BB.E7.BB.9F></a>
<h5>向 NAND 写根文件系统 </h5>
<p>The following set of commands loads the file rootfs.jffs2 from ext2/mmc and flashes it into the rootfs flash partition: </p>
<pre>GTA01Bv3 # ext2load mmc 0 0x32000000 rootfs.jffs2
GTA01Bv3 # nand erase rootfs
GTA01Bv3 # nand write.e 0x32000000 rootfs ${filesize}
</pre>
<p>Please note that this will only work with root file system sizes that are smaller than the amount of memory above 0x32000000, which in the case of 64MB SDRAM is something like 32MB. </p>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: Neo1973 相关的命令" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=26"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=Neo1973_.E7.9B.B8.E5.85.B3.E7.9A.84.E5.91.BD.E4.BB.A4></a>
<h4>Neo1973 相关的命令 </h4>
<p>我们的 u-boot 支持几个 Neo1973 专用命令： </p>
<pre>GTA01Bv2 # help neo1973
neo1973 neo1973 info - display phone informantion
neo1973 power-off - switch off the phone
neo1973 charger status - display charger status
neo1973 charger autofast - enable automatic fast (500mA) charging
neo1973 charger&nbsp;!autofast - disable automatic fast (500mA) charging
neo1973 charger fast - enable fast (500mA) charging
neo1973 charger off - disable charging
neo1973 backlight (on|off) - switch backlight on or off
neo1973 vibrator (on|off) - switch vibrator on or off
</pre>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 关机" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=27"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E5.85.B3.E6.9C.BA></a>
<h5>关机 </h5>
<p>使用 </p>
<pre>neo1973 power-off
</pre>
<p>you can switch the device off from the bootloader prompt. </p>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 充电器相关" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=28"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E5.85.85.E7.94.B5.E5.99.A8.E7.9B.B8.E5.85.B3></a>
<h5>充电器相关 </h5>
<p>For a detailed description of the charger basics, see <a title="Neo1973 Battery Charger" href="http://wiki.openmoko.org/wiki/Neo1973_Battery_Charger"><u><font color=#0000ff>Neo1973 Battery Charger</font></u></a>. </p>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 查询充电器状态" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=29"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E6.9F.A5.E8.AF.A2.E5.85.85.E7.94.B5.E5.99.A8.E7.8A.B6.E6.80.81></a>
<h6>查询充电器状态 </h6>
<p>You can get the current charger status by issuing </p>
<pre>neo1973 charger status
</pre>
<p>The following modes are possible: </p>
<ul lastCheckbox="null">
    <li>idle - no charging
    <li>trickle - FIXME
    <li>pre - Slow (100mA) charging, works in hardware.
    <li>fast_cccv - Fast (500mA) charging, using Constant-Current followed by Constant Voltage (Li-Ion) </li>
</ul>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 禁用充电器" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=30"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E7.A6.81.E7.94.A8.E5.85.85.E7.94.B5.E5.99.A8></a>
<h6>禁用充电器 </h6>
<p>You can disable battery charging (until the next reboot) by issuing </p>
<pre>neo1973 charger off
</pre>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 强制快速充电" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=31"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E5.BC.BA.E5.88.B6.E5.BF.AB.E9.80.9F.E5.85.85.E7.94.B5></a>
<h6>强制快速充电 </h6>
<p>使用 </p>
<pre>neo1973 charger fast
</pre>
<p>you can force the PMU to try to do a fast (500mA) charge of the battery. It will abort if the battery is in over temperature or some other error condition occurs. </p>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 使能/禁用自动快速充电" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=32"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E4.BD.BF.E8.83.BD.2F.E7.A6.81.E7.94.A8.E8.87.AA.E5.8A.A8.E5.BF.AB.E9.80.9F.E5.85.85.E7.94.B5></a>
<h6>使能/禁用自动快速充电 </h6>
<p>Autofast is a feature of the PCF50606 PMU. It means that the fast_cccv mode will be automatically selected if a charger with suitable voltage is plugged in, and the battery not in over temperature condition. </p>
<table style="BORDER-RIGHT: #606060 1px solid; BORDER-TOP: #606060 1px solid; MARGIN: 1em 5%; BORDER-LEFT: #606060 1px solid; COLOR: #ff0000; BORDER-BOTTOM: #606060 1px solid; BACKGROUND-COLOR: #ddddee">
    <tbody>
        <tr>
            <td style="PADDING-RIGHT: 0.5em; PADDING-LEFT: 0.5em; PADDING-BOTTOM: 0.5em; PADDING-TOP: 0.5em"></td>
            <td style="PADDING-RIGHT: 0.5em; PADDING-LEFT: 0.5em; PADDING-BOTTOM: 0.5em; PADDING-TOP: 0.5em"><strong>WARNING:</strong> This is potentially dangerous. Only enable autofast if you ARE SURE that you can draw 500mA from the USB connector. This is the case with a wall outlet charger, or if you are attached to a self-powered hub or a desktop PC root hub. Bus powered hubs and some laptops only provide 100mA on their USB ports and can thus not support fast charging </td>
        </tr>
    </tbody>
</table>
<p>You can enable or disable autofast by </p>
<pre>neo1973 charger autofast
</pre>
<p>and </p>
<pre>neo1973 charger&nbsp;!autofast
</pre>
<p>respectively. </p>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 背光灯" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=33"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E8.83.8C.E5.85.89.E7.81.AF></a>
<h5>背光灯 </h5>
<p>You can switch the backlight on and off by using </p>
<pre>neo1973 backlight on
</pre>
<p>and </p>
<pre>neo1973 backlight off
</pre>
<p>respectively. </p>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 振动" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=34"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E6.8C.AF.E5.8A.A8></a>
<h5>振动 </h5>
<p>You can switch the vibrator on and off by using </p>
<pre>neo1973 vibrator on
</pre>
<p>and </p>
<pre>neo1973 vibrator off
</pre>
<p>respectively. </p>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: S3C2410 专用命令" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=35"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=S3C2410_.E4.B8.93.E7.94.A8.E5.91.BD.E4.BB.A4></a>
<h4>S3C2410 专用命令 </h4>
<pre>GTA01Bv2 # help s3c2410
s3c2410 speed get - display current PLL speed config
s3c2410 speed list - display supporte PLL speed configs
s3c2410 speed set - set PLL speed
GTA01Bv2 # s3c2410 speed list
50 MHz
101 MHz
202 MHz
266 MHz
GTA01Bv2 # s3c2410 speed get
FCLK = 202 MHz, HCLK = 101 MHz, PCLK = 50 MHz
GTA01Bv2 # s3c2410 speed set 101
GTA01Bv2 # s3c2410 speed get
FCLK = 101 MHz, HCLK = 50 MHz, PCLK = 50 MHz
</pre>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 266MHz时钟" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=36"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=266MHz.E6.97.B6.E9.92.9F></a>
<h5>266MHz时钟 </h5>
<p>You can re-configure the <a title=S3C2410 href="http://wiki.openmoko.org/wiki/S3C2410"><u><font color=#0000ff>S3C2410</font></u></a> PLL to generate a 266 MHz core cpu clock (rather than the 200MHz default) by using </p>
<pre>GTA01Bv2 # s3c2410 speed set 266
</pre>
<p>and </p>
<pre>GTA01Bv2 # s3c2410 speed set 202
</pre>
<p>respectively. </p>
<table style="BORDER-RIGHT: #606060 1px solid; BORDER-TOP: #606060 1px solid; MARGIN: 1em 5%; BORDER-LEFT: #606060 1px solid; COLOR: #ff0000; BORDER-BOTTOM: #606060 1px solid; BACKGROUND-COLOR: #ddddee">
    <tbody>
        <tr>
            <td style="PADDING-RIGHT: 0.5em; PADDING-LEFT: 0.5em; PADDING-BOTTOM: 0.5em; PADDING-TOP: 0.5em"></td>
            <td style="PADDING-RIGHT: 0.5em; PADDING-LEFT: 0.5em; PADDING-BOTTOM: 0.5em; PADDING-TOP: 0.5em"><strong>WARNING:</strong> The current hardware (as of GTA01Bv3) only runs stable at 266MHz if you do not attach aynthing (esp. the FPC / <a title="Debug Board" href="http://wiki.openmoko.org/wiki/Debug_Board"><u><font color=#0000ff>Debug Board</font></u></a> to the Debug Port </td>
        </tr>
    </tbody>
</table>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: QT2410上的TFTP" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=37"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=QT2410.E4.B8.8A.E7.9A.84TFTP></a>
<h4>QT2410上的TFTP </h4>
<p>The QT2410 cs8900a Ethernet can be used to download images via network. </p>
<p>First, you have to make sure that <em>ipaddr</em>, <em>serverip</em>, <em>ethaddr' and </em>netmaskk<em> are set correctly in the environment:</em> </p>
<pre>QT2410 # printenv
ethaddr=00:01:02:03:04:05
netmask=255.255.255.0
ipaddr=192.168.100.100
serverip=192.168.100.1
</pre>
<p><br></p>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: TFTP kernel download" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=38"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=TFTP_kernel_download></a>
<h5>TFTP kernel download </h5>
<pre>QT2410 # tftpboot 0x32000000
*** Warning: no boot file name; using 'C0A86464.img'
TFTP from server 192.168.100.1; our IP address is 192.168.100.100
Filename 'C0A86464.img'.
Load address: 0x32000000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
##########################################
done
Bytes transferred = 1544788 (179254 hex)
</pre>
<p>you can then commence booting via </p>
<pre>QT2410# bootm 0x32000000
</pre>
<div class=editsection style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: 设备固件升级" href="http://wiki.openmoko.org/index.php?title=Bootloader/zh_cn&amp;action=edit&amp;section=39"><u><font color=#0000ff>edit</font></u></a>]</div>
<a name=.E8.AE.BE.E5.A4.87.E5.9B.BA.E4.BB.B6.E5.8D.87.E7.BA.A7></a>
<h2>设备固件升级 </h2>
<p>Our version of u-boot also implements <a title="USB DFU" href="http://wiki.openmoko.org/wiki/USB_DFU"><u><font color=#0000ff>USB DFU</font></u></a>. </p>
<p>To find out whether your version of u-boot supports this, use the output of </p>
<pre>$ lsusb -v -d 1457:5119
</pre>
<p>while the phone is in u-boot mode. </p>
<p>If it supports DFU, you should see the following snippet towards the end of the output: </p>
<pre>    Interface Descriptor:
bLength                 9
bDescriptorType         4
bInterfaceNumber        2
bAlternateSetting       0
bNumEndpoints           0
bInterfaceClass       254 Application Specific Interface
bInterfaceSubClass      1 Device Firmware Update
bInterfaceProtocol      1
iInterface              0
</pre>
<p>关于如何进行固件升级的信息，请看<a title="Dfu-util/zh cn" href="http://wiki.openmoko.org/wiki/Dfu-util/zh_cn"><u><font color=#0000ff>dfu-util</font></u></a>。 </p>
</div>
<img src ="http://www.cnitblog.com/zouzheng/aggbug/41560.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/zouzheng/" target="_blank">zz</a> 2008-03-27 15:41 <a href="http://www.cnitblog.com/zouzheng/articles/41560.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>将ppcboot2.0.0移植到s3c2410平台</title><link>http://www.cnitblog.com/zouzheng/articles/41212.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Thu, 20 Mar 2008 01:21:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/41212.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/41212.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/41212.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/41212.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/41212.html</trackback:ping><description><![CDATA[<div class=content id=fontzoom>
<p>
<div><span class=post_user>思考树整理，转载注明出处。<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#121;&#117;&#101;&#116;&#105;&#97;&#110;&#116;&#105;&#97;&#110;&#64;&#49;&#54;&#51;&#46;&#99;&#111;&#109;"><u><font color=#0000ff>yuetiantian@163.com</font></u></a></span></div>
<div><span class=post_user></span><br>1.修改Makefile<br>ifeq($(ARCH),arm)<br>#CROSS-COMPILE = arm-linux-<br>CROSS-COMPILE = /opt/host/armv4l/bin/armv4l-unknown-linux-<br>即修改arm cpu的交叉编译器为你现有可用交叉编译工具链<br>2.修改vi inclue/configs/smdk2410.h<br>(1)修改网卡信息<br>#define CONFIG_DRIVER_CS8900<br>改成#define CONFIG_DRIVER_DM9000<br>#define CS8900 0x19000300<br>改成#define DM9000 0X08000300<br>#define CS8900_BUS16<br>改成#define DM9000_BUS16<br>(2)修改网络地址<br>#define CONFIG_IPADDR 192.168.2.120<br>#define CONFIG_IPSERVERIP 192.168.2.25<br>(3)修改提示符<br>#define CFG_PROMPT "zyt#"<br>(4)修改flash容量<br>vi inclue/configs/smdk2410.h<br>#ifdef CONFIG_AMD_LV400<br>#define PHYS_FLASH_SIZE 0x00080000 /* 512KB */<br>改成<br>#ifdef CONFIG_AMD_LV400<br>#define PHYS_FLASH_SIZE 0x01000000 /* 16M */<br>#define CFG_MEMTEST_END 0x33A00000 /*63M in<br>DRAM*/<br>改成#define CFG_MEMTEST_END 0x33A00000 /*58M in<br>DRAM*/<br>3.修改给u-boot 预留空间大小vi board/s3c2410/config.mk<br>调整TEXT_BASE值为0x33A00000<br>4.修改cpu第10个寄存器为0x31<br>vi board/s3c2410/memsetup.S<br>倒数第三行0x32 -&gt;0x31<br>5.添加网卡驱动<br>拷贝dm9000x.c到 drivers目录<br>拷贝net.h到drivers目录<br>vi Makefile<br>将dm9000x.o 替换掉目标文件中的cs8900.o<br>6.编译<br>#make distclean<br>#make smdk2410_config<br>#make all<br>报一个错误<br>'true' undeclared<br>进入tools/gdb/ 编辑 astest.c 修改dfdp-&gt;cacheable= true 为dfdp-&gt;cacheable= 1；<br>保存<br>再编译，通过，ok<br>烧写到flash后，启动板子，tftp 0x30008000 zImage<br>########################</div>
<div class=post_content>ok！</div>
<p>&#160;</p>
</div>
<img src ="http://www.cnitblog.com/zouzheng/aggbug/41212.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/zouzheng/" target="_blank">zz</a> 2008-03-20 09:21 <a href="http://www.cnitblog.com/zouzheng/articles/41212.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>u-boot在s3c2410开发板上移植过程</title><link>http://www.cnitblog.com/zouzheng/articles/41186.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Wed, 19 Mar 2008 11:55:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/41186.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/41186.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/41186.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/41186.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/41186.html</trackback:ping><description><![CDATA[<div class=content id=fontzoom>
<p>
<p><font size=3><strong>1）</strong>u-boot版本1.1.3，gcc version 3.3.3 (DENX ELDK 3.1.1 3.3.3-9)</font></p>
<p><font size=3><strong>2）</strong>在Makefile中加入<br>bks2410_config&nbsp;:&nbsp;unconfig<br>&nbsp;@./mkconfig $(@:_config=) arm arm920t bks2410 NULL s3c24x0<br>我把我的板子起名叫bks2410，可以依自己的喜好修改</font></p>
<p><font size=3><strong>3）</strong>建立board/bks2410目录，拷贝board/smdk2410下的文件到board/bks2410目录，将smdk2410.c更名为bks2410.c</font></p>
<p><font size=3><strong>4）</strong>cp include/configs/smdk2410.h include/configs/bks2410.h</font></p>
<p><font size=3><strong>5）</strong>将arm-linux-gcc的目录加入到PATH环境变量中，我的是目录/opt/eldk/usr/bin:/opt/eldk/bin</font></p>
<p><font size=3><strong>6）</strong>测试编译能否成功：<br>make bks2410_config<br>make all ARCH=arm<br>生成u-boot.bin就OK了</font></p>
<p><font size=3><strong>7）</strong>依照你自己开发板的内存地址分配情况修改board/bks2410/memsetup.S文件，我的程序：<br>#include &lt;config.h&gt;<br>#include &lt;version.h&gt;</font></p>
<p><font size=3>#define BWSCON&nbsp;0x48000000</font></p>
<p><font size=3>/* BWSCON */<br>#define DW8&nbsp;&nbsp; &nbsp;(0x0)<br>#define DW16&nbsp;&nbsp; &nbsp;(0x1)<br>#define DW32&nbsp;&nbsp; &nbsp;(0x2)<br>#define WAIT&nbsp;&nbsp; &nbsp;(0x1&lt;&lt;2)<br>#define UBLB&nbsp;&nbsp; &nbsp;(0x1&lt;&lt;3)</font></p>
<p><font size=3>#define B1_BWSCON&nbsp;&nbsp; &nbsp;(DW32)<br>#define B2_BWSCON&nbsp;&nbsp; &nbsp;(DW16)<br>#define B3_BWSCON&nbsp;&nbsp; &nbsp;(DW16 + WAIT + UBLB)<br>#define B4_BWSCON&nbsp;&nbsp; &nbsp;(DW16)<br>#define B5_BWSCON&nbsp;&nbsp; &nbsp;(DW16)<br>#define B6_BWSCON&nbsp;&nbsp; &nbsp;(DW32)<br>#define B7_BWSCON&nbsp;&nbsp; &nbsp;(DW32)</font></p>
<p><font size=3>/* BANK0CON */<br>#if 0<br>#define B0_Tacs&nbsp;&nbsp; &nbsp;0x0&nbsp;/*&nbsp; 0clk */<br>#define B0_Tcos&nbsp;&nbsp; &nbsp;0x0&nbsp;/*&nbsp; 0clk */<br>#define B0_Tacc&nbsp;&nbsp; &nbsp;0x7&nbsp;/* 14clk */<br>#define B0_Tcoh&nbsp;&nbsp; &nbsp;0x0&nbsp;/*&nbsp; 0clk */<br>#define B0_Tah&nbsp;&nbsp; &nbsp;0x0&nbsp;/*&nbsp; 0clk */<br>#define B0_Tacp&nbsp;&nbsp; &nbsp;0x0<br>#define B0_PMC&nbsp;&nbsp; &nbsp;0x0&nbsp;/* normal */<br>#endif</font></p>
<p><font size=3>#define B0_Tacs&nbsp;&nbsp; &nbsp;0x3&nbsp;/*&nbsp; 0clk */<br>#define B0_Tcos&nbsp;&nbsp; &nbsp;0x3&nbsp;/*&nbsp; 0clk */<br>#define B0_Tacc&nbsp;&nbsp; &nbsp;0x7&nbsp;/* 14clk */<br>#define B0_Tcoh&nbsp;&nbsp; &nbsp;0x3&nbsp;/*&nbsp; 0clk */<br>#define B0_Tah&nbsp;&nbsp; &nbsp;0x3&nbsp;/*&nbsp; 0clk */<br>#define B0_Tacp&nbsp;&nbsp; &nbsp;0x1<br>#define B0_PMC&nbsp;&nbsp; &nbsp;0x0&nbsp;/* normal */</font></p>
<p><font size=3>/* BANK1CON */<br>#if 0<br>#define B1_Tacs&nbsp;&nbsp; &nbsp;0x0&nbsp;/*&nbsp; 0clk */<br>#define B1_Tcos&nbsp;&nbsp; &nbsp;0x0&nbsp;/*&nbsp; 0clk */<br>#define B1_Tacc&nbsp;&nbsp; &nbsp;0x7&nbsp;/* 14clk */<br>#define B1_Tcoh&nbsp;&nbsp; &nbsp;0x0&nbsp;/*&nbsp; 0clk */<br>#define B1_Tah&nbsp;&nbsp; &nbsp;0x0&nbsp;/*&nbsp; 0clk */<br>#define B1_Tacp&nbsp;&nbsp; &nbsp;0x0<br>#define B1_PMC&nbsp;&nbsp; &nbsp;0x0<br>#endif</font></p>
<p><font size=3>#define B1_Tacs&nbsp;&nbsp; &nbsp;0x3&nbsp;/*&nbsp; 0clk */<br>#define B1_Tcos&nbsp;&nbsp; &nbsp;0x3&nbsp;/*&nbsp; 0clk */<br>#define B1_Tacc&nbsp;&nbsp; &nbsp;0x7&nbsp;/* 14clk */<br>#define B1_Tcoh&nbsp;&nbsp; &nbsp;0x3&nbsp;/*&nbsp; 0clk */<br>#define B1_Tah&nbsp;&nbsp; &nbsp;0x3&nbsp;/*&nbsp; 0clk */<br>#define B1_Tacp&nbsp;&nbsp; &nbsp;0x3<br>#define B1_PMC&nbsp;&nbsp; &nbsp;0x0</font></p>
<p><font size=3>#define B2_Tacs&nbsp;&nbsp; &nbsp;0x0<br>#define B2_Tcos&nbsp;&nbsp; &nbsp;0x0<br>#define B2_Tacc&nbsp;&nbsp; &nbsp;0x7<br>#define B2_Tcoh&nbsp;&nbsp; &nbsp;0x0<br>#define B2_Tah&nbsp;&nbsp; &nbsp;0x0<br>#define B2_Tacp&nbsp;&nbsp; &nbsp;0x0<br>#define B2_PMC&nbsp;&nbsp; &nbsp;0x0</font></p>
<p><font size=3>#if 0<br>#define B3_Tacs&nbsp;&nbsp; &nbsp;0x0&nbsp;/*&nbsp; 0clk */<br>#define B3_Tcos&nbsp;&nbsp; &nbsp;0x3&nbsp;/*&nbsp; 4clk */<br>#define B3_Tacc&nbsp;&nbsp; &nbsp;0x7&nbsp;/* 14clk */<br>#define B3_Tcoh&nbsp;&nbsp; &nbsp;0x1&nbsp;/*&nbsp; 1clk */<br>#define B3_Tah&nbsp;&nbsp; &nbsp;0x0&nbsp;/*&nbsp; 0clk */<br>#define B3_Tacp&nbsp;&nbsp; &nbsp;0x3&nbsp;&nbsp;&nbsp;&nbsp; /*&nbsp; 6clk */<br>#define B3_PMC&nbsp;&nbsp; &nbsp;0x0&nbsp;/* normal */<br>#endif</font></p>
<p><font size=3>#define B3_Tacs&nbsp;&nbsp; &nbsp;0x0&nbsp;/*&nbsp; 0clk */<br>#define B3_Tcos&nbsp;&nbsp; &nbsp;0x0&nbsp;/*&nbsp; 4clk */<br>#define B3_Tacc&nbsp;&nbsp; &nbsp;0x7&nbsp;/* 14clk */<br>#define B3_Tcoh&nbsp;&nbsp; &nbsp;0x0&nbsp;/*&nbsp; 1clk */<br>#define B3_Tah&nbsp;&nbsp; &nbsp;0x0&nbsp;/*&nbsp; 0clk */<br>#define B3_Tacp&nbsp;&nbsp; &nbsp;0x0&nbsp;&nbsp;&nbsp;&nbsp; /*&nbsp; 6clk */<br>#define B3_PMC&nbsp;&nbsp; &nbsp;0x0&nbsp;/* normal */</font></p>
<p><font size=3>#define B4_Tacs&nbsp;&nbsp; &nbsp;0x0&nbsp;/*&nbsp; 0clk */<br>#define B4_Tcos&nbsp;&nbsp; &nbsp;0x0&nbsp;/*&nbsp; 0clk */<br>#define B4_Tacc&nbsp;&nbsp; &nbsp;0x7&nbsp;/* 14clk */<br>#define B4_Tcoh&nbsp;&nbsp; &nbsp;0x0&nbsp;/*&nbsp; 0clk */<br>#define B4_Tah&nbsp;&nbsp; &nbsp;0x0&nbsp;/*&nbsp; 0clk */<br>#define B4_Tacp&nbsp;&nbsp; &nbsp;0x0<br>#define B4_PMC&nbsp;&nbsp; &nbsp;0x0&nbsp;/* normal */</font></p>
<p><font size=3>#define B5_Tacs&nbsp;&nbsp; &nbsp;0x0&nbsp;/*&nbsp; 0clk */<br>#define B5_Tcos&nbsp;&nbsp; &nbsp;0x0&nbsp;/*&nbsp; 0clk */<br>#define B5_Tacc&nbsp;&nbsp; &nbsp;0x7&nbsp;/* 14clk */<br>#define B5_Tcoh&nbsp;&nbsp; &nbsp;0x0&nbsp;/*&nbsp; 0clk */<br>#define B5_Tah&nbsp;&nbsp; &nbsp;0x0&nbsp;/*&nbsp; 0clk */<br>#define B5_Tacp&nbsp;&nbsp; &nbsp;0x0<br>#define B5_PMC&nbsp;&nbsp; &nbsp;0x0&nbsp;/* normal */</font></p>
<p><font size=3>#define B6_MT&nbsp;&nbsp; &nbsp;0x3&nbsp;/* SDRAM */<br>#define B6_Trcd&nbsp; &nbsp; &nbsp;0x1<br>#define B6_SCAN&nbsp;&nbsp; &nbsp;0x1&nbsp;/* 9bit */</font></p>
<p><font size=3>#define B7_MT&nbsp;&nbsp; &nbsp;0x3&nbsp;/* SDRAM */<br>#define B7_Trcd&nbsp;&nbsp; &nbsp;0x1&nbsp;/* 3clk */<br>#define B7_SCAN&nbsp;&nbsp; &nbsp;0x1&nbsp;/* 9bit */</font></p>
<p><font size=3>/* REFRESH parameter */<br>#define REFEN&nbsp;&nbsp; &nbsp;0x1&nbsp;/* Refresh enable */<br>#define TREFMD&nbsp;&nbsp; &nbsp;0x0&nbsp;/* CBR(CAS before RAS)/Auto refresh */<br>#define Trp&nbsp;&nbsp; &nbsp;0x0&nbsp;/* 2clk */<br>#define Trc&nbsp;&nbsp; &nbsp;0x3&nbsp;/* 7clk */<br>#define Tchr&nbsp;&nbsp; &nbsp;0x2&nbsp;/* 3clk */<br>#define REFCNT&nbsp;&nbsp; &nbsp;1113&nbsp;/* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */<br>/**************************************/</font></p>
<p><font size=3>_TEXT_BASE:<br>&nbsp;.word&nbsp;TEXT_BASE</font></p>
<p><font size=3>.globl memsetup<br>memsetup:<br>&nbsp;/* memory control configuration */<br>&nbsp;/* make r0 relative the current location so that it */<br>&nbsp;/* reads SMRDATA out of FLASH rather than memory ! */<br>&nbsp;adr&nbsp;&nbsp;&nbsp;&nbsp; r0, SMRDATA<br>&nbsp;/*ldr&nbsp;r1, _TEXT_BASE*/<br>&nbsp;/*sub&nbsp;r0, r0, r1*/<br>&nbsp;ldr&nbsp;r1, =BWSCON&nbsp;/* Bus Width Status Controller */<br>&nbsp;add&nbsp;&nbsp;&nbsp;&nbsp; r2, r0, #13*4<br>0:<br>&nbsp;ldr&nbsp;&nbsp;&nbsp;&nbsp; r3, [r0], #4<br>&nbsp;str&nbsp;&nbsp;&nbsp;&nbsp; r3, [r1], #4<br>&nbsp;cmp&nbsp;&nbsp;&nbsp;&nbsp; r2, r0<br>&nbsp;bne&nbsp;&nbsp;&nbsp;&nbsp; 0b</font></p>
<p><font size=3>&nbsp;/* everything is fine now */<br>&nbsp;mov&nbsp;pc, lr</font></p>
<p><font size=3>&nbsp;.ltorg<br>/* the literal pools origin */</font></p>
<p><font size=3>SMRDATA:<br>&nbsp;&nbsp;&nbsp; .word (0+(B1_BWSCON&lt;&lt;4)+(B2_BWSCON&lt;&lt;8)+(B3_BWSCON&lt;&lt;12)+(B4_BWSCON&lt;&lt;16)+(B5_BWSCON&lt;&lt;20)+(B6_BWSCON&lt;&lt;24)+(B7_BWSCON&lt;&lt;28))<br>&nbsp;&nbsp;&nbsp; .word ((B0_Tacs&lt;&lt;13)+(B0_Tcos&lt;&lt;11)+(B0_Tacc&lt;&lt;8)+(B0_Tcoh&lt;&lt;6)+(B0_Tah&lt;&lt;4)+(B0_Tacp&lt;&lt;2)+(B0_PMC))<br>&nbsp;&nbsp;&nbsp; .word ((B1_Tacs&lt;&lt;13)+(B1_Tcos&lt;&lt;11)+(B1_Tacc&lt;&lt;8)+(B1_Tcoh&lt;&lt;6)+(B1_Tah&lt;&lt;4)+(B1_Tacp&lt;&lt;2)+(B1_PMC))<br>&nbsp;&nbsp;&nbsp; .word ((B2_Tacs&lt;&lt;13)+(B2_Tcos&lt;&lt;11)+(B2_Tacc&lt;&lt;8)+(B2_Tcoh&lt;&lt;6)+(B2_Tah&lt;&lt;4)+(B2_Tacp&lt;&lt;2)+(B2_PMC))<br>&nbsp;&nbsp;&nbsp; .word 0x1f7c/*((B3_Tacs&lt;&lt;13)+(B3_Tcos&lt;&lt;11)+(B3_Tacc&lt;&lt;8)+(B3_Tcoh&lt;&lt;6)+(B3_Tah&lt;&lt;4)+(B3_Tacp&lt;&lt;2)+(B3_PMC))*/<br>&nbsp;&nbsp;&nbsp; .word ((B4_Tacs&lt;&lt;13)+(B4_Tcos&lt;&lt;11)+(B4_Tacc&lt;&lt;8)+(B4_Tcoh&lt;&lt;6)+(B4_Tah&lt;&lt;4)+(B4_Tacp&lt;&lt;2)+(B4_PMC))<br>&nbsp;&nbsp;&nbsp; .word ((B5_Tacs&lt;&lt;13)+(B5_Tcos&lt;&lt;11)+(B5_Tacc&lt;&lt;8)+(B5_Tcoh&lt;&lt;6)+(B5_Tah&lt;&lt;4)+(B5_Tacp&lt;&lt;2)+(B5_PMC))<br>&nbsp;&nbsp;&nbsp; .word ((B6_MT&lt;&lt;15)+(B6_Trcd&lt;&lt;2)+(B6_SCAN))<br>&nbsp;&nbsp;&nbsp; .word ((B7_MT&lt;&lt;15)+(B7_Trcd&lt;&lt;2)+(B7_SCAN))<br>&nbsp;&nbsp;&nbsp; .word ((REFEN&lt;&lt;23)+(TREFMD&lt;&lt;22)+(Trp&lt;&lt;20)+(Trc&lt;&lt;18)+(Tchr&lt;&lt;16)+REFCNT)<br>&nbsp;&nbsp;&nbsp; .word 0x31<br>&nbsp;&nbsp;&nbsp; .word 0x30<br>&nbsp;&nbsp;&nbsp; .word 0x30<br>&nbsp;&nbsp;&nbsp; <br><strong>8）</strong>在board/bks2410加入NAND Flash读函数，建立nand_read.c，加入如下内容(copy from vivi)：<br>#include &lt;config.h&gt;</font></p>
<p><font size=3>#define __REGb(x)&nbsp;(*(volatile unsigned char *)(x))<br>#define __REGi(x)&nbsp;(*(volatile unsigned int *)(x))<br>#define NF_BASE&nbsp;&nbsp;0x4e000000<br>#define NFCONF&nbsp;&nbsp;__REGi(NF_BASE + 0x0)<br>#define NFCMD&nbsp;&nbsp;__REGb(NF_BASE + 0x4)<br>#define NFADDR&nbsp;&nbsp;__REGb(NF_BASE + 0x8)<br>#define NFDATA&nbsp;&nbsp;__REGb(NF_BASE + 0xc)<br>#define NFSTAT&nbsp;&nbsp;__REGb(NF_BASE + 0x10)</font></p>
<p><font size=3>#define BUSY 1<br>inline void wait_idle(void) {<br>&nbsp;&nbsp;&nbsp; int i;</font></p>
<p><font size=3>&nbsp;&nbsp;&nbsp; while(!(NFSTAT &amp; BUSY))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i=0; i&lt;10; i++);<br>}</font></p>
<p><font size=3>#define NAND_SECTOR_SIZE&nbsp;512<br>#define NAND_BLOCK_MASK&nbsp;&nbsp;(NAND_SECTOR_SIZE - 1)</font></p>
<p><font size=3>/* low level nand read function */<br>int<br>nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)<br>{<br>&nbsp;&nbsp;&nbsp; int i, j;</font></p>
<p><font size=3>&nbsp;&nbsp;&nbsp; if ((start_addr &amp; NAND_BLOCK_MASK) || (size &amp; NAND_BLOCK_MASK)) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;&nbsp;/* invalid alignment */<br>&nbsp;&nbsp;&nbsp; }</font></p>
<p><font size=3>&nbsp;&nbsp;&nbsp; /* chip Enable */<br>&nbsp;&nbsp;&nbsp; NFCONF &amp;= ~0x800;<br>&nbsp;&nbsp;&nbsp; for(i=0; i&lt;10; i++);</font></p>
<p><font size=3>&nbsp;&nbsp;&nbsp; for(i=start_addr; i &lt; (start_addr + size);) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* READ0 */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NFCMD = 0;</font></p>
<p><font size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Write Address */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NFADDR = i &amp; 0xff;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NFADDR = (i &gt;&gt; 9) &amp; 0xff;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NFADDR = (i &gt;&gt; 17) &amp; 0xff;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NFADDR = (i &gt;&gt; 25) &amp; 0xff;</font></p>
<p><font size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wait_idle();</font></p>
<p><font size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(j=0; j &lt; NAND_SECTOR_SIZE; j++, i++) {<br>&nbsp;*buf = (NFDATA &amp; 0xff);<br>&nbsp;buf++;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }</font></p>
<p><font size=3>&nbsp;&nbsp;&nbsp; /* chip Disable */<br>&nbsp;&nbsp;&nbsp; NFCONF |= 0x800;&nbsp;/* chip disable */</font></p>
<p><font size=3>&nbsp;&nbsp;&nbsp; return 0;<br>}</font></p>
<p><font size=3><strong>9）</strong>修改board/bks2410/Makefile为<br>OBJS&nbsp;:= bks2410.o flash.o nand_read.o</font></p>
<p><font size=3><strong>10）</strong>修改cpu/arm920t/start.S文件<br>在ldr&nbsp;pc, _start_armboot之前加入：<br>#ifdef CONFIG_S3C2410_NAND_BOOT<br>&nbsp; bl&nbsp;&nbsp;&nbsp; copy_myself<br>&nbsp; <br>&nbsp; @ jump to ram<br>&nbsp; ldr&nbsp;&nbsp; r1, =on_the_ram<br>&nbsp; add&nbsp; pc, r1, #0<br>&nbsp; nop<br>&nbsp; nop<br>&nbsp; 1:&nbsp;&nbsp;&nbsp; b&nbsp;&nbsp;&nbsp;&nbsp; 1b&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @ infinite loop<br>&nbsp; <br>on_the_ram:<br>#endif</font></p>
<p><font size=3>在_start_armboot:&nbsp;.word start_armboot之后加入：<br>#ifdef CONFIG_S3C2410_NAND_BOOT<br>copy_myself:<br>&nbsp; mov r10, lr<br>@ reset NAND<br>&nbsp; mov r1, #NAND_CTL_BASE<br>&nbsp; ldr&nbsp;&nbsp; r2, =0xf830&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @ initial value<br>&nbsp; str&nbsp;&nbsp; r2, [r1, #oNFCONF]<br>&nbsp; ldr&nbsp;&nbsp; r2, [r1, #oNFCONF]<br>&nbsp; bic&nbsp; r2, r2, #0x800&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @ enable chip<br>&nbsp; str&nbsp;&nbsp; r2, [r1, #oNFCONF]<br>&nbsp; mov r2, #0xff&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @ RESET command<br>&nbsp; strb r2, [r1, #oNFCMD]<br>&nbsp; mov r3, #0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @ wait</font></p>
<p><font size=3>1:add&nbsp; r3, r3, #0x1<br>&nbsp; cmp r3, #0xa<br>&nbsp; blt&nbsp;&nbsp; 1b<br>2:ldr&nbsp;&nbsp; r2, [r1, #oNFSTAT]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @ wait ready<br>&nbsp; tst&nbsp;&nbsp;&nbsp; r2, #0x1<br>&nbsp; beq&nbsp; 2b<br>&nbsp; ldr&nbsp;&nbsp; r2, [r1, #oNFCONF]<br>&nbsp; orr&nbsp; r2, r2, #0x800&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @ disable chip<br>&nbsp; str&nbsp;&nbsp; r2, [r1, #oNFCONF]</font></p>
<p><font size=3>@ get read to call C functions (for nand_read())<br>&nbsp; ldr&nbsp;&nbsp; sp, DW_STACK_START&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @ setup stack pointer<br>&nbsp; mov fp, #0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @ no previous frame, so fp=0</font></p>
<p><font size=3>@ copy vivi to RAM<br>&nbsp; ldr&nbsp;&nbsp; r0, =UBOOT_RAM_BASE<br>&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp; r1, #0x0<br>&nbsp; mov r2, #0x20000<br>&nbsp; bl&nbsp;&nbsp;&nbsp; nand_read_ll<br>&nbsp; tst&nbsp;&nbsp;&nbsp; r0, #0x0<br>&nbsp; beq&nbsp; ok_nand_read</font></p>
<p><font size=3>#ifdef CONFIG_DEBUG_LL<br>&nbsp; bad_nand_read:<br>&nbsp; ldr&nbsp;&nbsp; r0, STR_FAIL<br>&nbsp; ldr&nbsp;&nbsp; r1, SerBase<br>&nbsp; bl&nbsp;&nbsp;&nbsp; PrintWord<br>1:b&nbsp;&nbsp;&nbsp;&nbsp; 1b&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @ infinite loop<br>&nbsp; #endif</font></p>
<p><font size=3>ok_nand_read:<br>#ifdef CONFIG_DEBUG_LL<br>&nbsp; ldr&nbsp;&nbsp; r0, STR_OK<br>&nbsp; ldr&nbsp;&nbsp; r1, SerBase<br>&nbsp; bl&nbsp;&nbsp;&nbsp; PrintWord<br>#endif</font></p>
<p><font size=3>@ verify<br>&nbsp; mov r0, #0<br>&nbsp; ldr&nbsp;&nbsp; r1, =UBOOT_RAM_BASE<br>&nbsp; mov r2, #0x400&nbsp;&nbsp;&nbsp;&nbsp; @ 4 bytes * 1024 = 4K-bytes<br>go_next:<br>&nbsp; ldr&nbsp;&nbsp; r3, [r0], #4<br>&nbsp; ldr&nbsp;&nbsp; r4, [r1], #4<br>&nbsp; teq&nbsp;&nbsp; r3, r4<br>&nbsp; bne&nbsp; notmatch<br>&nbsp; subs r2, r2, #4<br>&nbsp; beq&nbsp; done_nand_read<br>&nbsp; bne&nbsp; go_next</font></p>
<p><font size=3>notmatch:<br>#ifdef CONFIG_DEBUG_LL<br>&nbsp; sub&nbsp; r0, r0, #4<br>&nbsp; ldr&nbsp;&nbsp; r1, SerBase<br>&nbsp; bl&nbsp;&nbsp;&nbsp; PrintHexWord<br>&nbsp; ldr&nbsp;&nbsp; r0, STR_FAIL<br>&nbsp; ldr&nbsp;&nbsp; r1, SerBase<br>&nbsp; bl&nbsp;&nbsp;&nbsp; PrintWord<br>#endif<br>1:b&nbsp;&nbsp;&nbsp;&nbsp; 1b<br>done_nand_read:<br>#ifdef CONFIG_DEBUG_LL<br>&nbsp; ldr&nbsp;&nbsp; r0, STR_OK<br>&nbsp; ldr&nbsp;&nbsp; r1, SerBase<br>&nbsp; bl&nbsp;&nbsp;&nbsp; PrintWord<br>#endif<br>&nbsp; mov pc, r10<br>@ clear memory<br>@ r0: start address<br>@ r1: length<br>&nbsp; mem_clear:<br>&nbsp; mov r2, #0<br>&nbsp; mov r3, r2<br>&nbsp; mov r4, r2<br>&nbsp; mov r5, r2<br>&nbsp; mov r6, r2<br>&nbsp; mov r7, r2<br>&nbsp; mov r8, r2<br>&nbsp; mov r9, r2</font></p>
<p><font size=3>clear_loop:<br>&nbsp; stmia&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r0!, {r2-r9}<br>&nbsp; subs r1, r1, #(8 * 4)<br>&nbsp; bne&nbsp; clear_loop<br>&nbsp; mov pc, lr</font></p>
<p><font size=3>#endif @ CONFIG_S3C2410_NAND_BOOT</font></p>
<p><font size=3>在文件的最后加入：<br>&nbsp; &nbsp;.align&nbsp;&nbsp;&nbsp;&nbsp; 2<br>DW_STACK_START:<br>&nbsp;.word&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STACK_BASE+STACK_SIZE-4</font></p>
<p><font size=3><strong>11）</strong>修改include/configs/bks2410.h文件，添加如下内容：<br>/*<br>&nbsp;* Nandflash Boot<br>&nbsp;*/<br>#define CONFIG_S3C2410_NAND_BOOT 1<br>#define STACK_BASE &nbsp;&nbsp; 0x33f00000<br>#define STACK_SIZE &nbsp;&nbsp; 0x8000<br>#define UBOOT_RAM_BASE &nbsp;&nbsp; 0x33f80000<br>/* NAND Flash Controller */<br>#define NAND_CTL_BASE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x4E000000<br>#define bINT_CTL(Nb)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __REG(INT_CTL_BASE + (Nb))<br>/* Offset */<br>#define oNFCONF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x00<br>#define oNFCMD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x04<br>#define oNFADDR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x08<br>#define oNFDATA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x0c<br>#define oNFSTAT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x10<br>#define oNFECC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x14</font></p>
<p><font size=3><strong>12）</strong>重新编译u-boot<br>make all ARCH=arm</font></p>
<p><font size=3><strong>13）</strong>通过jtag将u-boot烧写到flash中就可以从NAND flash启动了<br></font></p>
<p><font size=3><strong>我的u-boot启动信息：</strong></font></p>
<p><font size=3>U-Boot 1.1.3 (May&nbsp; 6 2006 - 18:13:59)</font></p>
<p><font size=3>U-Boot code: 33F80000 -&gt; 33F967C4&nbsp; BSS: -&gt; 33F9AAAC<br>RAM Configuration:<br>Bank #0: 30000000 64 MB<br>Flash: 512 kB<br>*** Warning - bad CRC, using default environment</font></p>
<p><font size=3>In:&nbsp;&nbsp;&nbsp; serial<br>Out:&nbsp;&nbsp; serial<br>Err:&nbsp;&nbsp; serial<br>BKS2410 # </font></p>
<p>&nbsp;</p>
</div>
<img src ="http://www.cnitblog.com/zouzheng/aggbug/41186.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/zouzheng/" target="_blank">zz</a> 2008-03-19 19:55 <a href="http://www.cnitblog.com/zouzheng/articles/41186.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>U-Boot的移植U-Boot Practically Porting Guide（转）</title><link>http://www.cnitblog.com/zouzheng/articles/40300.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Fri, 29 Feb 2008 07:56:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/40300.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/40300.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/40300.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/40300.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/40300.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: U-Boot的移植之(一)基础篇：添加新的目标板定义本文使用最新的U-Boot-1.3.0-rc2。U-Boot本身支持很多开发板，在其源代码中，每个板子都对应一个board/目录下的文件夹(笔者注：这并不确切，因为有的文件夹是供应商名称，下面可以有多个目标板目录，这里只考虑最简单的情况)，以及include/configs/目录下的目标板配置头文件。因此，要添加U-Boot对我们的目标板的支...&nbsp;&nbsp;<a href='http://www.cnitblog.com/zouzheng/articles/40300.html'>阅读全文</a><img src ="http://www.cnitblog.com/zouzheng/aggbug/40300.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/zouzheng/" target="_blank">zz</a> 2008-02-29 15:56 <a href="http://www.cnitblog.com/zouzheng/articles/40300.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Blackfin上移植u-boot</title><link>http://www.cnitblog.com/zouzheng/articles/40217.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Wed, 27 Feb 2008 09:05:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/40217.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/40217.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/40217.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/40217.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/40217.html</trackback:ping><description><![CDATA[<p>本文介绍的移植过程基于华恒科技提供的软件包（用于HHBF531-StartKIT-R1开发板）。我<br>们的硬件平台是：<br>CPU：BF533<br>FLASH：S29AL004D-512KB<br>SDRAM：HY57V281620-16MB<br>下面我们分成以下几个步骤进行介绍：<br>一， 建立交叉编译开发环境：<br>1， 安装（虚拟）linux系统：<br>&nbsp;&nbsp;&nbsp; 移植uclinux要在linux系统环境下交叉编译，所以需要一个linux系统。可以安装一个<br>完整的linux操作系统，也可以在windows系统下利用虚拟软件运行linux系统。本人不习惯<br>使用linux操作系统，所以在windows环境下安装了一个虚拟linux——colinux。本人下载<br>的colinux安装包是colinux_installer_v0.95.zip ，安装包内包含blackfin交叉编译工具<br>链，利用此工具包安装的虚拟linux系统内已经带有blackfin交叉编译工具链，下载地址为<br>：<a href="http://blackfin.uclinux.org/gf/project/bfin-colinux/frs/。" target=_blank><u><font color=#0000ff>http://blackfin.uclinux.org/gf/project/bfin-colinux/frs/。</font></u></a><br>安装colinux的方法很简单，和一般的windows软件安装相同，全部采用默认值即可。唯一<br>要注意的是，要保证安装盘（比如说c盘）有足够的空间（大约需要3.5GB）。<br>安装成功后，点击你桌面上的blackfin-colinux图标就可以运行colinux了。Colinux默认<br>已经建立两个用户：root和uclinux，密码均为bf533。查看linux根目录下有没有/opt/uC<br>linux/bfin-elf、/opt/uClinux/bfin-linux-uclibc、/opt/uClinux/bfin-uclinux三个目<br>录，有的话blackfin交叉工具链已经安装成功，但不一定适用于本文的源码编译；因为某<br>些变量定义不一致可能导致华恒提供的源码编译错误，所以要使用华恒提供的软件包附带<br>的交叉编译工具链。<br>更多资料参见：<a href="http://blackfin.uclinux.org/。" target=_blank><u><font color=#0000ff>http://blackfin.uclinux.org/。</font></u></a><br><br>2， 安装blackfin交叉编译工具链：<br>解压华恒软件包HHBF531-R1-v1.0.0-070327.tgz：<br>#tar jxvf HHBF531-R1-v1.0.0-070327.tgz<br>生成HHBF531-R1文件夹，内包含交叉编译工具链、uboot源码包、uclinux源码包、jtag工<br>具和源码镜像。<br>进入交叉编译工具链目录：<br>#cd HHBF531-R1/toolchains<br>交叉编译工具链是一个tgz压缩包gcc-bfin-3.4.tgz，包含的用于交叉编译的可执行文件，<br>直接解压到相应目录即可以使用，无需安装。<br>#tar jxvf gcc-bfin-3.4.tgz /usr/local/<br>设置编译工具目录：<br>#PATH=&#8221;/usr/local/gcc-bfin-3.4-uclinux/bin:$PATH&#8221;<br>这样，交叉编译环境就建立好了。开始华恒提供的源码吧，看看你的环境是否建立正确！<br>如果出现错误，仔细检查以上过程。<br><br>二， 移植u-boot：<br>uclinux启动离不开引导程序，这个引导程序叫作bootloader。Bootloader是在操作系统运<br>行之前执行的一段小程序。通过这段小程序，我们可以初始化硬件设备、建立内存空间的<br>映射表，从而建立适当的系统软硬件环境，为最终调用操作系统内核做好准备。<br>U-Boot是一种通用的Bootloader，可以方便地移植到各种硬件平台上。<br>华恒提供的u-boot在HHBF531-R1/u-boot目录下，支持blackfin系列DSP和常用开发板。<br><br>我们这里把U-Boot的移植分成两个部分。第一部分是为我们的新开发板在目录/board/下建<br>立一个新目录，并拷贝最类似的开发板源码到该目录，做一些配置修改，对我们的新开发<br>板进行配置并编译通过；第二部分是针对我们的新开发板的特点修改相关源码文件的内容<br>，使其能在我们的新开发板上运行。<br>1， 第一部分：<br>我们的新开发板基于BF533，与U-Boot中的hhbf开发板最类似，我们以hhbf开发板为模板修<br>改得到我们新开发板的移植代码。<br>进入u-boot目录：<br>#cd HHBF531-R1/u-boot<br>注意要让uclinux用户用于读写操作的权限，否则下面操作时报&#8220;Permition denied.&#8221;错<br>误。简单点，我们直接用root用户登陆。<br>进入开发板目录，建立对应于我们开发板的文件目录，这里命名为naribf533。<br>#cd board<br>#cp &#8211;R hhbf naribf533<br>#cd naribf533<br>#mv hhbf.c naribf533.c（修改文件名）<br>删除不需要的文件：<br>#mv &#8211;r hhbf*<br>#mv psd4256.h<br>这样我们新开发板的文件目录和文件都有了（现在还不能在我们开发板上运行）。然后修<br>改naribf533目录下的Makefile和u-boot.lds，把其中的hhbf全部修改为naribf533，后面<br>编译过程中如果报找不到hhbf的错误也把相应的hhbf改为naribf533。<br>再加入一个头文件：<br>#cd include/configs<br>#cp hhbf.h naribf533.h<br>这个头文件中有很多内容要修改，我们将在第二部分中予以修改。<br>修改顶层目录下的Makefile，找到以下内容：<br>hhbf533_config : unconfig<br>@ &gt; include/config.h<br>@echo &#8220;#define CONFIG_HHBF&nbsp; 1&#8221; &gt;&gt; include/config.h<br>@echo &#8220;#define CONFIG_BF533 1&#8221; &gt;&gt; include/config.h<br>@./mkconfig &#8211;a $(@:_config=) blackfin bf533 hhbf533 #hhtech<br>模仿上述语句，在下面增加以下内容：<br>naribf533_config : unconfig<br>@ &gt; include/config.h<br>@echo &#8220;#define CONFIG_HHBF&nbsp; 1&#8221; &gt;&gt; include/config.h<br>@echo &#8220;#define CONFIG_BF533 1&#8221; &gt;&gt; include/config.h<br>@./mkconfig &#8211;a $(@:_config=) blackfin bf533 naribf533<br>切记在&#8220;@./mkconfig &#8211;a $(@:_config=) blackfin bf533 naribf533&#8221;前面的是Tab来的<br>，万万不能用空格代替，因为它是靠这个来识别命令的！<br>最后编译u-boot，<br>#make distclean<br>#make naribf533_config（就是在Makefile里添加的config）<br>#make<br>看看有没有错，有错的话按着提示来改，如果没错的话应该就能生成u-boot.bin这个文件<br>。现在还不能使用，因为这只是hhbf的一个仿制品而已。<br>编译正确生成u-boot.bin文件，这一部分就算完成了。下面我们尝试修改相应的源代码。<br><br><br>2， 第二部分：<br>&nbsp;&nbsp;&nbsp; 该部分主要是修改开发板配置文件以及flash驱动。<br>我们先来修改开发板配置文件，让u-boot能运行起来。修改的主要内容包括：串口设置、<br>时钟设置、flash设置和SDRAM设置。我们的开发板上目前还没有网络功能，先不设置该内<br>容。<br>将以下设置替换原开发板配置文件相应部分即可。<br>串口设置，将波特率设置为115200。<br>#define CONFIG_BAUDRATE 115200<br>时钟设置，根据开发板晶振频率和系统需要的工作频率设置，我们开发板的晶振为27MHz，<br>内核时钟为输入时钟的22倍频，系统时钟为内核时钟的5分频，所以如下设置。<br>#ifdef CONFIG_BF533<br>&nbsp;&nbsp;&nbsp; #define CONFIG_CLKIN_HZ 27000000<br>#endif//CONFIG_BF533<br>#ifdef CONFIG_BF561<br>&nbsp;&nbsp;&nbsp; #define CONFIG_CLKIN_HZ 33000000<br>#endif//CONFIG_BF561<br><br>/* CONFIG_CLKIN_HALF controls what is passed to PLL 0=CLKIN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>/*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1=CLKIN/2&nbsp;&nbsp;&nbsp; */<br>#define CONFIG_CLKIN_HALF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0<br><br>/* CONFIG_PLL_BYPASS controls if the PLL is used 0=don't bypass&nbsp; */<br>/*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1=bypass PLL&nbsp;&nbsp;&nbsp; */<br>#define CONFIG_PLL_BYPASS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0<br><br>/* CONFIG_VCO_MULT controls what the multiplier of the PLL is.&nbsp;&nbsp; */<br>/* Values can range from 1-64&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>#ifdef CONFIG_BF533<br>&nbsp;&nbsp;&nbsp; #define CONFIG_VCO_MULT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 12<br>#endif//CONFIG_BF533<br>#ifdef CONFIG_BF561<br>&nbsp;&nbsp;&nbsp; #define CONFIG_VCO_MULT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10<br>#endif//CONFIG_BF561<br><br>/* CONFIG_CCLK_DIV controls what the core clock divider is&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>/* Values can be 1, 2, 4, or 8 ONLY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>#define CONFIG_CCLK_DIV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<br><br>/* CONFIG_SPI_BAUD controls the SPI peripheral clock divider&nbsp;&nbsp;&nbsp;&nbsp; */<br>/* Values can range from 2-65535&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>/* SCK Frequency = SCLK / (2 * CONFIG_SPI_BAUD)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>#define CONFIG_SPI_BAUD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2<br><br><br>/* CONFIG_SCLK_DIV controls what the peripheral clock divider is */<br>/* Values can range from 1-15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>#define CONFIG_SCLK_DIV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4<br>flash设置，根据你的开发板flash容量和起始地址定制，我们的开发板flash容量为512KB<br>，起始地址为0x20000000。<br>#ifdef CONFIG_BF533<br>#define CFG_MAX_FLASH_BANKS 1 //flash只有一段<br>#define CFG_MAX_FLASH_SECT 11 //flash一共有11个sector<br>#endif//CONFIG_BF533<br><br>#ifdef CONFIG_BF533<br>#define CFG_ENV_ADDR 0x20020000<br>#define CFG_ENV_SECT_SIZE 0x10000<br>#endif//CONFIG_BF533<br><br>#ifdef CONFIG_BF533<br>#define FLASH_SIZE 0x80000<br>#define CFG_FLASH_SIZE 0x80000 //容量为512KB<br>#endif//CONFIG_BF533<br>SDRAM设置，根据你的开发板SDRAM容量和起始地址定制，我们的开发板SDRAM容量为16MB，<br>列地址宽度为9，起始地址为0x00000000。<br>#define CFG_LARGE_IMAGE_LEN 0x1000000&nbsp;&nbsp; /* Large Image Length */<br><br>#ifdef CONFIG_BF533<br>#define CONFIG_MEM_SIZE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 128, 64, 32, 16 */<br><br>#endif//CONFIG_BF533<br><br>#define CONFIG_MEM_ADD_WDTH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 8, 9, 10, 11&nbsp;&nbsp;&nbsp; */<br><br>#define CFG_MEMTEST_START 0x00100000 /* memtest works on */<br>#define CFG_MEMTEST_END 0x00f00000 /* 1..15 MB in DRAM */<br><br>#define CFG_SDRAM_BASE 0x00000000<br>#ifdef CONFIG_BF533<br>#define CFG_MAX_RAM_SIZE 0x01000000<br>#endif//CONFIG_BF533<br>如上设置后，重新编译u-boot，发现出现错误#error "CFG_MONITOR_BASE != TEXT_BASE"<br>，原因是TEXT_BASE设置值与配置文件不一致，主要是由于我们修改了SDRAM的容量。到b<br>oard/naribf533目录下修改config.mk文件，将TEXT_BASE的地址修改为0x0fc0000。接下来<br>编译应该没有任何错误了。<br>编译生成的u-boot.bin下载到开发板即可以运行了，应该能看到串口返回的u-boot成功运<br>行的信息。这样第一步修改就完成了。<br>在上面看到的u-boot运行信息里，你会发现有很多关于华恒的信息，可能你很不愿意显示<br>这些内容。这是因为你还没有修改flash驱动，里面显示的还是华恒提供的flash驱动显示<br>的内容。而且此时还不能下载uclinux镜像，因为华恒提供的flash驱动不一定适合你的开<br>发板，不能对你的开发板flash进行写操作。所以，我们接下来修改flash驱动。<br>flash驱动对应的文件是board/naribf533/flash.c，它主要包括以下几个函数：<br>unsigned long flash_init (void )，Flash初始化； <br>&nbsp;&nbsp;&nbsp; void flash_print_info (flash_info_t *info)，打印Flash信息； <br>&nbsp;&nbsp;&nbsp; int flash_erase (flash_info_t *info， int s_first， int s_last)，Flash擦除<br>； <br>&nbsp;&nbsp;&nbsp; volatile static int write_dword (flash_info_t *info， ulong dest， ulong d<br>ata)，Flash写入； <br>&nbsp;&nbsp;&nbsp; int write_buff (flash_info_t *info， uchar *src， ulong addr， ulong cnt)，<br>从内存复制数据。<br>Flash驱动修改要根据你使用的flash特性进行，参考flash的文档。主要修改内容包括：f<br>lash操作命令、flash扇区分配和一些打印信息。<br>另外，还有SDRAM的配置。除了再(board).h文件中的配置以外，如果你使用的SDRAM的刷新<br>频率不同于hhbf531学习板上使用的，还必须到include/asm-blackfin/mem_init.h文件中<br>去修改SDRAM_Tref和SDRAM_NRA两个参数。<br><br>3， 测试U-boot：<br>如果以上修改内容都做到了，编译得到的u-boot应该没有什么问题了，但测试还是必要的<br>。<br>u-boot能正确打印启动信息，不代表u-boot完全正确了，比如说flash不能正确擦写、SDR<br>AM不能正确操作等问题都可能存在。这里分一下几项内容测试u-boot。<br>1）测试u-boot所有命令：<br>在u-boot的monitor下，键入help，会显示u-boot支持的所有命令。依次测试各命令，检查<br>是否正确。<br>2）测试flash驱动：<br>通过u-boot的loadb和go命令，下载一个可执行程序到某个未使用的地址空间，检查是否正<br>确运行，以测试flash能否正确读写。<br>3）测试SDRAM：<br>SDRAM的测试往往被人忽略，其实该部分是很重要的，一旦错误可能给后面的内核移植带来<br>很多问题，本人就遇到这样的问题。<br>测试SDRAM主要包括空间的连续性和是否有空间重叠现象。<br>连续性测试可以通过md命令，从低地址到高地址依次打印内存信息，检查打印的地址是否<br>连续。<br>内存空间是否重叠可以通过对每MB空间写入特定数，检查各MB空间的数据是否重复，重复<br>则可能因为空间重叠。<br>除以上测试内容外，可能还有其他小问题，视情况另做测试。<br>通过以上测试后，你的u-boot基本就没有问题了，可以放心地利用它下载运行linux了。</p>
<p>&nbsp;</p>
<p>U-Boot在基于ADSP BF533的嵌入式Linux系统上的移植<br><br></p>
<p><strong>1 引言</strong></p>
<p>Boot Loader(内核引导程序)是在操作系统内核运行之前运行的一段自举程序，用于初始化硬件设备、改变处理器运行模式、重组中断向量和建立内存空间映射图，从而将系统的软硬件带到一个合适的状态或者用户定制的特定状态，以便为最终加载操作系统内核准备好正确的环境[1]。</p>
<p>嵌入式Linux系统常用的Boot Loader有arm-boot、redboot、U-Boot等。U-Boot (全称Universal Boot Loader)是当前比较流行的遵循GPL条件的开放源码项目。U-Boot具有源码公开的特点，开发人员可根据自身需要进行裁减；支持多种处理器和嵌入式操作系统内核；具有多种设备驱动源码：支持种引导方式；具有功能强大且成熟、稳定等诸多优点，故在嵌入式系统开发过程中广泛采用。U-Boot严重依赖于底层硬件，不同的CPU或嵌入式板极设备需要不同的U-Boot，因此，在嵌入式系统中建立通用的U-Boot是非常困难的，故U-Boot需针对开发板量身定做。</p>
<p><strong>2 开发平台</strong></p>
<p>2.1 BF533简介</p>
<p>Blackfin系列DSP是ADI公司与Intel联合开发推出的第一款高性能、低功耗第四代定点DSP产品，融合了Analog Devices/Intel公司的微信号结构(MSA)。它将一个32位RISC型指令集和双16位乘法累加(MAC)信号处理功能与通用型微控制器所具有的易用性组合在一起。这种组合使Blackfin处理器能够在信号处理和控制处理应用中发挥最佳的性能。且Blackfin处理器通过将工业标准接口与高性能的信号处理内核相结合在一起,用户可以快速设计出节省成本的解决方案，而且无需昂贵的外部组件。</p>
<p>本开发系统采用BF533，BF533是主频高达600 MHz、峰值处理能力为1.2 GMI/s的高性能Blackfin处理器。BF533内核包含2个16位MAC、2个40位ALU、4个8位视频ALU以及1个40位移位器。另外，BF533还包括1个UART口、1个SPI口、2个串行口(SPORT)、4个通用定时器(其中3个具有PWM功能)、1个实时时钟、看门狗定时器以及1个并行外设接口。外部存储器控制器可与SDRAM、SRAM、Flash和ROM实现无缝连接[2]。</p>
<p>2.2 系统硬件平台简介</p>
<p>本系统的开发板硬件系统如图1所示。<br><br></p>
<p align=center><img height=225 src="http://news.eeworld.com.cn/pic/20070913/20070913112424.bmp" width=420></p>
<p>目标板以Blackfin嵌入式处理器为核心，数据地址线复用到SDRAM、Flash、USB、Ethernet，并通过FPGA实现逻辑控制。此外，将UART端口转换为RS232端口引出。其中SDRAM的地址为0x00000000～0x02000000，Flash的地址为0x20000000～0x20300000。</p>
<p>宿主机采用Window和Suse10.0双操作系统，采用串行接口和以太网连接宿主机和目标板，程序先在宿主机上编译，然后下载至目标板上运行，目标板的终端被重定向到串行接口，由宿主机输出。</p>
<p>2.3 开发环境的建立</p>
<p>2.3.1 在宿主机上设置终端</p>
<p>大部分嵌入式系统在宿主机大多都采用kermit或minaicom实现与目标板的通信，本系统采用inicom。minicom是Linux下一个类似于Windows超级终端的友好串口通信程序。在终端输入bash#minicom-s进入minicom设置画面，设置串口波特率、有效数据位、停止位以及奇偶校验位分别为57 600、8 bit、1位停止位以及无奇偶校验位等。</p>
<p>2.3.2安装交叉编译器</p>
<p>交叉编译是在一个架构下编译另外一个架构的目标文件。要从http：//blackfin.uclinux.org网站上下载Blackfin ToolChain，然后安装并修改环境变量PATH，使其包含ToolChain的安装目录。<br><br><img src="http://news.eeworld.com.cn/pic/20070913/20070913112445.jpg"></p>
<p><strong>3 U-Boot启动两阶段</strong></p>
<p>U-Boot代码一般分为stage1和stage2两大部分。stage1依赖于cpu体系结构如设备初始化代码，常用汇编语言编写以达到短小精悍,提高系统运行效率的目的。它主要包括cpu/bf533目录下的start.s。stage2一般采用C语言编写实现复杂功能，这样代码则具有更好的可读性和可移植性，主要包括lib blackfin/board.c文件和common/main．c文件中main_loop函数。</p>
<p>stagel从cpu入口函数cpu/bf533/start.s开始,通常包含以下步骤：</p>
<p>(1)基本硬件的初始化，为随后执行kernel准备好基本的硬件环境。包括：屏蔽所有中断，引导装载程序的执行过程中不必执行任何中断，中断屏蔽可通过写cpu的中断屏蔽寄存器或状态寄存器实现；设置cpu的速度和时钟频率，初始化pll；RAM初始化，初始化内存控制器的各个寄存器；初始化UART，向串口打印U-Boot的字符信息；关闭cpu内部指令，数据cache。</p>
<p>(2) 为加载U-Boot的stage2准备RAM空间，通常将stage2置于整个RAM空间的最顶层1 MB空间。</p>
<p>(3)拷贝U-Boot的stage2到RAM。判断是否是Flash运行,如果是就将stage2的代码拷贝到TEXT BASE处。将stage2安排到RAM空间的最顶层1 MB是较推荐的方法。</p>
<p>(4)设置堆栈指针sp为C语言代码执行做好准备。</p>
<p>(5)跳转到stage2的C语言代码入口点。</p>
<p>stage2主要包括lib-blackfin/board.c中board_init_f、board_init_r函数以及common/main.C中main_loop函数。通常包含以下步骤：</p>
<p>(1)初始化此阶段需用的硬件设备，由board_init_f和board_init_r函数实现。 <br><br><img src="http://news.eeworld.com.cn/pic/20070913/20070913112503.jpg"></p>
<p>(2)内存映射检测。</p>
<p>(3)加载内核并为内核设置启动参数。</p>
<p>(4)调用内核。</p>
<p><strong>4 U-BOOt的移植</strong></p>
<p>4.1 U-Boot方法与要点</p>
<p>移植U-Boot简便的方法是从U-Boot支持的开发板中选择一个与其目标板接近的开发板进行修改。需修改的是与硬件相关的部分,涉及到两个层面：针对CPU的移植，由于U-Boot_1.1.3支持BF533，故只需做第二层面的移植：针对目标板硬件的移植。在移植前，需仔细阅读U-Boot/readme文件，该文件对目录结构和如何移植作了简要介绍。从移植U-Boot的最小要求、U-Boot能够正常启动的角度出发,选择BF533的STAMP板为模板,相关源代码在/board/stamp目录下，结合U-Boot的启动流程，主要修改文件如下：</p>
<p>(1)与目标板相关的代码部分：在board下创建mybf533目录，无需从头开始，参考与目标板相似的STAMP板在mybf533目录下创建mybf533.c、mybf533.h、flash.c、config.mk、Makefie等文件。需要修改/board/mybf533/config.mk：<br><br><img src="http://news.eeworld.com.cn/pic/20070913/20070913112520.jpg"></p>
<p>TFEXT_BASE用于设置程序编译链接的起始地址即将U-Boot的stage2拷贝到SDRAM的TEXT_BASE处，即SDRAM最顶层一段存储区。修改board/mybf533/Makefile： <br><br><img src="http://news.eeworld.com.cn/pic/20070913/20070913112536.jpg"><br><br>(2)与CPU相关的代码部分：U-Boot_1.1.3/epu文件中含有BF533的目录，其中包含start.s、cpu.c、cpu.h、interrupt.c、init_sdram.s等。故不需要建立与cpu相关的文件目录。</p>
<p>(3)与头文件相关的代码：在include/configs创建mybf533.h，参考include/configs/stamp.h，如下：<br><br><img src="http://news.eeworld.com.cn/pic/20070913/20070913112557.jpg"><br><br>Flash的修改与具体型号和容量有关，修改过程中参考Flash擦除数据命令、特定寄存器的写入地址以及扇区的大小和位置。</p>
<p>与SDRAM相关设置：<br><br><img src="http://news.eeworld.com.cn/pic/20070913/20070913112615.jpg"><br><img height=245 src="http://news.eeworld.com.cn/pic/20070913/20070913112714.jpg" width=400><br><br>注意：最后一行要用Tab键开头表示命令。其中blackfin表示CPU的种类.bf533是cpu bf533对应的代码目录，mybf533是目标板对应的目录。这样可使用make mybf533_config配置自身的开发板。</p>
<p>其他修改视情况而定。如根据SDRAM大小修改cplb表，根据需要修改堆栈大小。如drivers/cfi_flash.c中flash_init()函数,cpu/bf533/ints.c中init_IRQ()函数等。</p>
<p>修改完毕后就可以采用如以下命令编译U-Boot：bash＄&gt;make clean，bash＄&gt;make mrproper，bash＄&gt;make mybf533_config，bash＄&gt;make。</p>
<p>编译完后U-Boot_1.1.3生成U-Boot的二进制文件U-Boot.bin(U-Boot.bin只能用于更新)。执行bash＄&gt;bfin-uclinux-objcopy-I binary-Oihex U-Boot.bin,生成可在Windows下首次烧写到Flash的十六进制文件U-Boot.hex。 <br><br>4.2 U-Boot的烧写</p>
<p>第一次下载U-Boot到目标板或者当U-Boot不能正常启动时。必须通过JTAG或者ADI ICE将U-Boot下载到目标板。在此可将ADI公司的仿真器与Visual DSP++环境相连,通过Visual DSP++,在TOOLS--&gt;Flash Programmer下执行Flash驱动程序M25P64.dxe，选择"Erase all"--&gt;Load Flie烧写U-Boot.hex文件到Flash中。</p>
<p>移植成功后，打开终端minicom复位开发板，若串口能输出正确的启动信息．则表明移植基本成功。启动后，如果在设定的时间内，串口没有接收到按键。U-Boot将自动加载操作系统内核和文件系统。若设定时间内串口接收到按键，则U-Boot停止自动加载,进入命令行，可看到U-Boot的提示符"mybf533&gt;"，查看Flash信息，调试或手动加载内核。</p>
<p>生成新的U-Boot.bin文件后。可通过Ethernet或者串口更新U-Boot。因为网络的传输速度远比串口快，故一般选择网络传输。将新生成的U-Boot.bin拷贝到宿主机根目录下的tftpboot目录(前提是已经创建tftp sever),在目标板出现U-Boot提示符后。按任意键进入下载模式：<br>mybf533&gt;tftp 0x1000000 U-Boot.bin</p>
<p>0x1000000为SDRAM默认的下载地址空间,用于U-Boot的升级、调试。当需要升级或者修改U-Boot,可将新的U-Boot从SDRAM烧写到。Flash,覆盖原来的U-Boot，以减少烧写Flash的次数。在烧写以前最好测试一下所下载的U-Boot能否正常运行：<br><br><img height=215 src="http://news.eeworld.com.cn/pic/20070913/20070913112738.jpg" width=400></p>
<p>如果不正确，应重复执行Erase all和Copy命令，直到正确为止。至此，U-Boot移植的步骤已基本完成。</p>
<p><strong>5 结束语</strong></p>
<p>U-Boot是一个功能强大的Boot loader。前期移植工作是嵌入式系统开发的首要环节。但其移植不可避免的存在一些难以预料的问题。嵌入式开发人员应该在了解U-Boot的工作机理、移植条件后,根据目标板和具体情况灵活裁减U-Boot以提高操作系统移植的稳定性，缩短移植周期，降低产品成本。</p>
<p>本文结合U-Boot的运行机理以及U-Boot移植的基本要求，研究了U-Boot在基于BF533的嵌入式系统上的移植。本文的移植是在不改变U-Boot框架前提下，对嵌入式目标板和CPU相关代码进行修改，实现了成功移植且移植后的U-Boot能够在目标板上稳定运行，为后续开发奠定了良好的基础。</p>
<p><br>基于Blackfin嵌入式系统的U-boot分析与调试<br></p>
<p><strong>引言</strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>Boot loader代码是CPU芯片复位后进入操作系统之前执行的一段代码，主要用于完成硬件启动到操作系统启动的过渡，从而为操作系统提供基本的运行环境。Boot loader代码与CPU的内核结构、具体型号、应用系统配置及操作系统有关，其功能类似于PC机的BIOS程序。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>Blackfin DSP是美国模拟器件公司与Intel联合开发的第4代DSP产品，是专为通信和互联网应用而设计的通用DSP芯片，适合处理互联网中的大量图像、声音、文本和数据流，以及汽车电子中的可视系统、宽带无线系统、消费类多媒体电子、数字摄像机、多通道VoIP、安全和监督、机顶盒和视频电话会议等。 本文对基于Blackfin 561微处理器构建的嵌入式开发板EZKIT561的U-boot第一和第二阶段的具体工作流程进行了分析，画出了各阶段的流程图，同时在U-boot第一阶段代码中加入LED指示程序来跟踪第一阶段的执行情况；而在U-boot第二阶段，则在代码的相应位置添加了向串口的打印信息，以跟踪U-boot在此阶段的执行情况。</p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 Blackfin DSP简介</strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>ADI公司推出的Blackfin处理器是专为嵌人式音频、视频、通信计算要求和功耗约束条件而设计的新型16～32位嵌入式处理器。Blackfin处理器由ADI和Intel联合开发，主要基于微信号架构(MSA)。它将一个32位RISC型指令集和双16位乘法累加(MAC)信号处理功能与通用型微控制器所具有的易用性组合在一起。这种处理特征使得Blackfin处理器在信号处理和控制处理应用中均能发挥上佳作用，因而在许多场合可免除增设单独异类处理器。</p>
<p>&nbsp;&nbsp;<strong>&nbsp;&nbsp;&nbsp;&nbsp; 2 Boot loader及U-boot简介</strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>2．1 Boot loader简介</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>Boot loader是用于初始化目标板硬件，可给嵌入式操作系统提供板上硬件资源信息，并进行装载、引导嵌人式操作系统运行的固件。最终，Boot Loader会把操作系统内核映像加载到RAM中，并将系统控制权传递给它。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>大多数Boot Loader都包含两种不同的操作模式： "启动加载"模式和"下载模式"。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>启动加载(Boot loading)模式也称"自主"(Autonomous)模式。即Boot Loader从目标机上的某个固态存储设备上将操作系统加载到RAM中运行。这种模式是Boot Loader的正常工作模式，因此在嵌入式产品发布的时侯，Boot Loader显然必须工作在这种模式下。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>在下载(Downloading)模式下，目标机上的Boot Loader将通过串口连接或网络连接等手段从主机(Host)下载内核映像和根文件系统映像等。从主机下载的文件通常先被Boot Loader保存到目标机的RAM，然后再被Boot Loader写到目标机的FLASH等固态存储设备中。Boot Loader的这种模式通常在第一次安装内核与根文件系统时使用；此外，以后的系统更新也会使用Boot Loader的这种模式。工作于这种模式下的Boot Loader通常都会向它的终端用户提供一个简单的命令行接口。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>2．2 U-boot简介<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>U-Boot(全称U niversal Boot Loader)是遵循GPL条款的开放源码项目。其源码目录和编译形式与Linux内核相似。事实上，不少U-Boot源码就是相应的Linux内核源程序的简化，尤其是一些设备的驱动程序，这一点从U-Boot源码的注释中就能体现。目前支持的目标操作系统有OpenBSD，NetBSD，FreeBSD，4．4BSD，Linux，SVR4，Esix，Solaris，Irix，VxWorks，LynxOS，pSOS，QNX，RTEMS，ARTOS；这是U-Boot中Universal的一层含义，另外一层含义是U-Boot除了支持PowerPC系列处理器外，还能支持Black-fin、MIPS、x86、ARM、NIOS、XScale等诸多处理器。上述两个特点正是U-Boot项目的开发目标，即支持尽可能多的嵌入式处理器和嵌人式操作系统。U-Boot的主要目录结构如表1所列。</p>
<p>&nbsp;&nbsp;<strong>&nbsp;&nbsp;&nbsp;&nbsp; 3 基于Blackfin DSP的U-boot运行分析</strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>大多数Boot loader都分为stagel和stage2两大部分，U-boot也是如此。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>3．1 U-boot的stagel阶段</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>依赖于CPU体系结构的代码(比如设备初始化代码等)，通常都放在stage1中，该代码可用blackfin DSP汇编语言来实现，以达到短小精悍的目的。实际操作可在位于U-boot 1．1．3＼cpu＼bf533中的Start．S和Startl．S文件中实现，而且是从Start．S开始运行，此阶段的程序流程图如图1所示。<br></p>
<p>
<table cellSpacing=0 cellPadding=0 width=675 border=0>
    <tbody>
        <tr>
            <td>
            <p align=center><img height=362 src="http://image.mcuol.com/News/070927152338460.jpg" width=300></p>
            <div align=center><br><img height=491 src="http://image.mcuol.com/News/070927152338821.jpg" width=320> </div>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>stage1的步骤以执行的先后主要包括硬件设备初始化、为加载Boot Loader的stage2准备RAM空间、拷贝Boot Loader的stage2到RAM空间、设置堆栈、跳转到stag2的C入口等。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>3．2 U-boot的stage2阶段</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>通常stage2可用C语言来实现更复杂的功能，该代码具有更好的可读性和可移植性。Stage2实现的主要功能包括初始化本阶段要使用到的硬件设备，检测系统内存映射(memory map)，将ker-nel映像和根文件系统映像从flash上读到RAM空间中，为内核设置启动参数，以及调用内核等。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>而基于ADSP-BF561 EZKIT-Lite评估板的U-boot在该阶段的启动时，首先在第一阶段结束后，调用＼U-boot 1．1．3＼1ib_blackfin＼board．c文件中的board_init_f()函数并执行。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>然后再调用board．c文件中的board_init_r()函数并按先后顺序执行，其流程图如图2所示。<br></p>
<p>
<table cellSpacing=0 cellPadding=0 width=675 border=0>
    <tbody>
        <tr>
            <td>
            <div align=center><img height=393 src="http://image.mcuol.com/News/070927152338982.jpg" width=320></div>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>之后，再在board_init_r函数的最后调用＼U-boot 1．1．3＼common＼main．c中的main_loop()函数。在执行过程中，系统会首先对自动启动内核进行倒计时，倒计时的时间由环境变量bootdelay的设定值决定。由于先前已经对串口进行了初始化，所以会在windows超级终端打印"ezkit：&gt;"，这样，mainloop()函数的执行将产生两条分支：一是等待u-boot的自启动命令执行，即执行bootcmd环境变量所设定的自动运行的命令(比如setenvbootcmd bootm 0x2000 0000)，引导flash特定地址中的嵌入式操作系统；二是在u-boot的自启动命令执行前按下任意键，以进入u-boot的命令行。在此状态下可以查看和修改环境变量、下载更新U-boot和内核镜像文件、对flash进行擦写操作或通过命令启动操作系统(如bootm 0x2000 0000)；</p>
<p>&nbsp;<strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4 基于评估板的U-boot启动跟踪调试</strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>4．1 第一阶段跟踪调试</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>由于U-boot的启动过程分为两个阶段，第一阶段在串口初始化之前无法获得字符串提示信息。这样，第一阶段的运行过程似乎就没办法掌握．但是，EZKIT561开发板提供16个用户可编程的LED，所以就可以通过这16个LED来了解u-boot在第一阶段的具体执行过程，即在U-boot第一阶段的几个不同的代码处添加LED指示程序。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>ADSP-BF561有48个双向通用可编程I／O引脚。这些可编程引脚具有实现SPI接口的特殊功能。每一个可编程引脚均能通过操作一系列的标志控制寄存器、标志状态寄存器和标志中断寄存器来进行独立控制。由于一共有48个通用可编程I／O引脚，所以可将以上寄存器分成三组，每组可对16个通用可编程I／O引脚进行操作。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>通过参考EZKIT56 1原理图可知，LED 5～20与PF 32～47 pins相连，可以跟踪堆栈配置。设计时可使用以下寄存器进行控制。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>(1)FIO2_DIR寄存器</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>这是一个16位寄存器，若将其中的某一位设置为1，那么相应的PF引脚就可作为输出；反之，则为输入。其相关设置代码如下：<br></p>
<p><img height=128 src="http://image.mcuol.com/News/070927152339093.jpg" width=293> </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>(2)FIO2_FLAG_D</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>这也是一个16位寄存器，对其写操作时，可指定相应的PF引脚状态；而当进行读操作时，则返回相应的PF引脚的值。它的每一位都控制着一个LED灯。其相关设置代码如下：<br></p>
<p><img height=57 src="http://image.mcuol.com/News/070927152339154.jpg" width=250> </p>
<p>w [p0]=r0；<br>ssync；</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>添加的跟踪堆栈配置程序的流程图如图3所示。修改代码后即可在U-boot文件夹路径下依次输入以下命令：make clean、make mrproper、make ezkit561 config和make，然后再利用bfin-u．clinux-objcopy将生成的U-boot．bin转换为U-boot．hex，最后通过VDSP＋＋开发环境中TOOL下的flashprogrammer将u-boot．hex烧写到flash中，同时进行复位操作以观察LED的变化。</p>
<p>&nbsp;</p>
<p>
<table cellSpacing=0 cellPadding=0 width=675 border=0>
    <tbody>
        <tr>
            <td>
            <p align=center><img height=272 src="http://image.mcuol.com/News/070927152339215.jpg" width=220></p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>本设计希望在堆栈配置前使LED 13、LED 14亮，其它LED灭，持续时间为1 s；而在堆栈分配之后使LED 11、LED 12亮，其它LED灭，持续时间为1 s。其实际的观察结果是，在复位之后，LED 13、LED 14持续亮1 s，接着LED 11、LED 12持续亮1秒，可见其完全达到了预期目标。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>4．2 第二阶段跟踪调试</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>第二阶段是在进人C函数之后，就进行串口的初始化。之后，便可通过向串口打印信息来实时跟踪所启动的执行流程，以了解程序目前执行的具体部分或运行到哪一个阶段出现了问题。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>下面以打印串口初始化完成信息为例。首先在U-boot第二阶段找到串口初始化的代码，即U-boot／lib-blackfin／board．c文件的serial．init()函数，然后在此函数之后添加printf("serial initializationis ok!＼n")以实现打印。其程序代码如下：<br></p>
<p><img height=107 src="http://image.mcuol.com/News/070927152339316.jpg" width=300> </p>
<p><img height=114 src="http://image.mcuol.com/News/070927152339397.jpg" width=330> </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>修改代码后的编译和下载步骤如前所示，调试时使用的串行通信软件是windows自带的"超级终端"程序，所选择的"每秒位数" (即波特率)为57600，传输文件使用的通信协议为Kermit协议。配置好超级终端后，按下开发板上的复位键．终端便可显示出系统启动过程的相关信息。系统复位后，第一行显示的是"serial initializa-tion is ok!"。这便是自行添加的打印语句，其主要功能是提示串口初始化已完成。 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>由于第二阶段可以通过串口打印信息，且在相关的每一阶段均可添加相关的printf句来实现打印提示信息，所以跟踪及调试都比较容易。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>&nbsp; 5 结束语</strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> </strong>通过分析基于Blackfin 561微处理器构建的嵌入式开发板EZKIT561的U-boot代码，以期对Boot Loader的启动过程有一个比较深入的理解，文章还通过一些调试方法对其运行阶段进行跟踪，以便对将来在开发板上的ucLinux移植和进一步的视频编解码工作进行准备。<br></p>
<img src ="http://www.cnitblog.com/zouzheng/aggbug/40217.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/zouzheng/" target="_blank">zz</a> 2008-02-27 17:05 <a href="http://www.cnitblog.com/zouzheng/articles/40217.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DENX U-Boot及Linux使用手册</title><link>http://www.cnitblog.com/zouzheng/articles/40215.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Wed, 27 Feb 2008 08:45:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/40215.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/40215.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/40215.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/40215.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/40215.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;1. 概要这是嵌入式PowerPC, ARM和MIPS系统中使用DENX U-Boot和Linux的指导手册。文档中描述了如何在嵌入式PowerPC, ARM和MIPS系统上配置、编译、使用Das U-Boot（常常缩写为&#8220;U-Boot&#8221;）和Linux操作系统。本文档写于2005年一月至四月四日十四点十五分。2. 绪论本文档描述了如何在嵌...&nbsp;&nbsp;<a href='http://www.cnitblog.com/zouzheng/articles/40215.html'>阅读全文</a><img src ="http://www.cnitblog.com/zouzheng/aggbug/40215.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/zouzheng/" target="_blank">zz</a> 2008-02-27 16:45 <a href="http://www.cnitblog.com/zouzheng/articles/40215.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>u-boot启动过程分析——基于lpc2210的移植代码</title><link>http://www.cnitblog.com/zouzheng/articles/40174.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Tue, 26 Feb 2008 06:51:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/40174.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/40174.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/40174.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/40174.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/40174.html</trackback:ping><description><![CDATA[<p><em>作者：华清远见嵌入式培训中心（</em><em>转载请注明出处）</em>
<p>&nbsp;</p>
<div>u-boot是一种普遍用于嵌入式系统中的Bootloader。 </div>
<p>&nbsp;</p>
<div><strong><font color=#0938f7>Bootloader介绍</font></strong> </div>
<p>&nbsp;</p>
<div>Bootloader的定义：<u>Bootloader是在操作系统运行之前执行的一小段程序，通过这一小段程序，我们可以初始化硬件设备、建立内存空间的映射表，从而建立适当的系统软硬件环境，为最终调用操作系统内核做好准备</u>。意思就是说如果我们要想让一个操作系统在我们的板子上运转起来，我们就必须首先对我们的板子进行一些基本配置和初始化，然后才可以将操作系统引导进来运行。具体在Bootloader中完成了哪些操作我们会在后面分析到，这里我们先来回忆一下PC的体系结构：<u>PC机中的引导加载程序是由BIOS和位于硬盘MBR中的OS Boot Loader（比如LILO和GRUB等）一起组成的，BIOS在完成硬件检测和资源分配后，将硬盘MBR中的Boot Loader读到系统的RAM中，然后将控制权交给OS Boot Loader。Boot Loader的主要运行任务就是将内核映象从硬盘上读到RAM中，然后跳转到内核的入口点去运行，即开始启动操作系统</u>。在嵌入式系统中，通常并没有像BIOS那样的固件程序（注：有的嵌入式cpu也会内嵌一段短小的启动程序），因此整个系统的加载启动任务就完全由Boot Loader来完成。比如在一个基于ARM7TDMI core的嵌入式系统中，系统在上电或复位时通常都从地址0x00000000处开始执行，而在这个地址处安排的通常就是系统的Boot Loader程序。（<em>先想一下，通用PC和嵌入式系统为何会在此处存在如此的差异呢</em>？） </div>
<p>&nbsp;</p>
<div>Bootloader是基于特定硬件平台来实现的，因此几乎不可能为所有的嵌入式系统建立一个通用的Bootloader，不同的处理器架构都有不同的Bootloader，Bootloader不但依赖于cpu的体系结构，还依赖于嵌入式系统板级设备的配置。对于2块不同的板子而言，即使他们使用的是相同的处理器，要想让运行在一块板子上的Bootloader程序也能运行在另一块板子上，一般也需要修改Bootloader的源程序。 </div>
<p>&nbsp;</p>
<div><strong><font color=#0000ff>Bootloader的启动方式</font></strong> </div>
<p>&nbsp;</p>
<div>Bootloader的启动方式主要有网络启动方式、磁盘启动方式和Flash启动方式。 </div>
<p>&nbsp;</p>
<div><strong>1、网络启动方式</strong> </div>
<p align=center><a id=ImgSpan href="http://www.farsight.com.cn/FarsightBBS/UploadFile/2007-12/20071271619932958.gif" target=_blank><img alt=按此在新窗口浏览图片 src="http://www.farsight.com.cn/FarsightBBS/UploadFile/2007-12/20071271619932958.gif" onload="return imgzoom(this,550)" border=0></a></p>
<div><br></div>
<p align=center>图1&nbsp;&nbsp;Bootloader网络启动方式示意图
<p>&nbsp;</p>
<div>如图1所示，里面主机和目标板，他们中间通过网络来连接，首先目标板的DHCP/BIOS通过BOOTP服务来为Bootloader分配IP地址，配置网络参数，这样才能支持网络传输功能。我们使用的u-boot可以直接设置网络参数，因此这里就不用使用DHCP的方式动态分配IP了。接下来目标板的Bootloader通过TFTP服务将内核映像下载到目标板上，然后通过网络文件系统来建立主机与目标板之间的文件通信过程，之后的系统更新通常也是使用Boot Loader的这种工作模式。工作于这种模式下的Boot Loader通常都会向它的终端用户提供一个简单的命令行接口。 </div>
<p>&nbsp;</p>
<div><strong>2、磁盘启动方式</strong> </div>
<p>&nbsp;</p>
<div>这种方式主要是用在台式机和服务器上的，这些计算机都使用BIOS引导，并且使用磁盘作为存储介质，这里面两个重要的用来启动linux的有LILO和GRUB，这里就不再具体说明了。 </div>
<p>&nbsp;</p>
<div><strong>3、Flash启动方式</strong> </div>
<p>&nbsp;</p>
<div>这是我们最常用的方式。Flash有NOR Flash和NAND Flash两种。NOR Flash可以支持随机访问，所以代码可以直接在Flash上执行，Bootloader一般是存储在Flash芯片上的。另外Flash上还存储着参数、内核映像和文件系统。这种启动方式与网络启动方式之间的不同之处就在于，在网络启动方式中，内核映像和文件系统首先是放在主机上的，然后经过网络传输下载进目标板的，而这种启动方式中内核映像和文件系统则直接是放在Flash中的，这两点在我们u-boot的使用过程中都用到了。 </div>
<p>&nbsp;</p>
<div><strong><font color=#0000ff>U-boot的定义</font></strong> </div>
<p>&nbsp;</p>
<div>U-boot，全称Universal Boot Loader，是由DENX小组的开发的遵循GPL条款的开放源码项目，它的主要功能是完成硬件设备初始化、操作系统代码搬运，并提供一个控制台及一个指令集在操作系统运行前操控硬件设备。U-boot之所以这么通用，原因是他具有很多特点：开放源代码、支持多种嵌入式操作系统内核、支持多种处理器系列、较高的稳定性、高度灵活的功能设置、丰富的设备驱动源码以及较为丰富的开发调试文档与强大的网络技术支持。另外u-boot对操作系统和产品研发提供了灵活丰富的支持，主要表现在：可以引导压缩或非压缩系统内核，可以灵活设置/传递多个关键参数给操作系统，适合系统在不同开发阶段的调试要求与产品发布，支持多种文件系统，支持多种目标板环境参数存储介质，采用CRC32校验，可校验内核及镜像文件是否完好，提供多种控制台接口，使用户可以在不需要ICE的情况下通过串口/以太网/USB等接口下载数据并烧录到存储设备中去（这个功能在实际的产品中是很实用的，尤其是在软件现场升级的时候），以及提供丰富的设备驱动等。 </div>
<p>&nbsp;</p>
<div><strong><font color=#0000ff>u-boot源代码的目录结构</font></strong> </div>
<p>&nbsp;</p>
<div>1、board中存放于开发板相关的配置文件，每一个开发板都以子文件夹的形式出现。<br>2、Commom文件夹实现u-boot行下支持的命令，每一个命令对应一个文件。<br>3、cpu中存放特定cpu架构相关的目录，每一款cpu架构都对应了一个子目录。<br>4、Doc是文档目录，有u-boot非常完善的文档。<br>5、Drivers中是u-boot支持的各种设备的驱动程序。<br>6、Fs是支持的文件系统，其中最常用的是JFFS2文件系统。<br>7、Include文件夹是u-boot使用的头文件，还有各种硬件平台支持的汇编文件，系统配置文件和文件系统支持的文件。<br>8、Net是与网络协议相关的代码，bootp协议、TFTP协议、NFS文件系统得实现。<br>9、Tooles是生成U-boot的工具。 </div>
<p>&nbsp;</p>
<div>对u-boot的目录有了一些了解后，分析启动代码的过程就方便多了，其中比较重要的目录就是/board、/cpu、/drivers和/include目录，如果想实现u-boot在一个平台上的移植，就要对这些目录进行深入的分析。 </div>
<p>&nbsp;</p>
<div><strong><font color=#0000ff>u-boot的启动过程</font></strong> </div>
<p>&nbsp;</p>
<div>系统启动的入口点。既然我们现在要分析u-boot的启动过程，就必须先找到u-boot最先实现的是哪些代码，最先完成的是哪些任务。另一方面一个可执行的image必须有一个入口点，并且只能有一个全局入口点，所以要通知编译器这个入口在哪里。由此我们可以找到程序的入口点是在/board/lpc2210/u-boot.lds中指定的，其中ENTRY(_start)说明程序从_start开始运行，而他指向的是cpu/arm7tdmi/start.o文件。因为我们用的是ARM7TDMI的cpu架构，在复位后从地址0x00000000取它的第一条指令，所以我们将Flash映射到这个地址上，这样在系统加电后，cpu将首先执行u-boot程序。 </div>
<p>&nbsp;</p>
<div>u-boot的启动过程是多阶段实现的，分了两个阶段。依赖于cpu体系结构的代码（如设备初始化代码等）通常都放在stage1中，而且通常都是用汇编语言来实现，以达到短小精悍的目的。而stage2则通常是用C语言来实现的，这样可以实现复杂的功能，而且代码具有更好的可读性和可移植性。 </div>
<p>&nbsp;</p>
<div>下面我们先详细分析下stage1中的代码，如图2所示：</div>
<p align=center><a id=ImgSpan href="http://www.farsight.com.cn/FarsightBBS/UploadFile/2007-12/200712716213266446.gif" target=_blank><img alt=按此在新窗口浏览图片 src="http://www.farsight.com.cn/FarsightBBS/UploadFile/2007-12/200712716213266446.gif" onload="return imgzoom(this,550)" border=0></a></p>
<div align=center>图2&nbsp;&nbsp;Start.s程序流程 </div>
<p>&nbsp;</p>
<div align=center>代码真正开始是在_start，设置异常向量表，这样在cpu发生异常时就跳转到/cpu/arm7tdmi/interrupts中去执行相应得中断代码。在interrupts文件中大部分的异常代码都没有实现具体的功能，只是打印一些异常消息，其中关键的是reset中断代码，跳到reset入口地址。 </div>
<p>&nbsp;</p>
<div>reset复位入口之前有一些段的声明。在reset中，首先是将cpu设置为svc32模式下，并屏蔽所有irq和fiq。在u-boot中除了定时器使用了中断外，其他的基本上都不需要使用中断，比如串口通信和网络等通信等，在u-boot中只要完成一些简单的通信就可以了，所以在这里屏蔽掉了所有的中断响应。 </div>
<p>&nbsp;</p>
<div>初始化外部总线。这部分首先设置了I/O口功能，包括串口、网络接口等的设置，其他I/O口都设置为GPIO。然后设置BCFG0~BCFG3，即外部总线控制器。这里bank0对应Flash，设置为16位宽度，总线速度设为最慢，以实现稳定的操作；Bank1对应DRAM，设置和Flash相同；Bank2对应RTL8019。 </div>
<p>&nbsp;</p>
<div>接下来是cpu关键设置，包括系统重映射（告诉处理器在系统发生中断的时候到外部存储器中去读取中断向量表）和系统频率。 </div>
<p>&nbsp;</p>
<div>lowlevel_init，设定RAM的时序，并将中断控制器清零。这些部分和特定的平台有关，但大致的流程都是一样的。 </div>
<p>&nbsp;</p>
<div>下面就是代码的搬移阶段了。为了获得更快的执行速度，通常把stage2加载到RAM空间中来执行，因此必须为加载Boot Loader的stage2准备好一段可用的RAM空间范围。空间大小最好是memory page大小(通常是4KB)的倍数，一般而言，1M的RAM空间已经足够了。flash中存储的u-boot可执行文件中，代码段、数据段以及BSS段都是首尾相连存储的，所以在计算搬移大小的时候就是利用了用BSS段的首地址减去代码的首地址，这样算出来的就是实际使用的空间。程序用一个循环将代码搬移到0x81180000，即RAM底端1M空间用来存储代码。然后程序继续将中断向量表搬到RAM的顶端。由于stage2通常是C语言执行代码，所以还要建立堆栈去。在堆栈区之前还要将malloc分配的空间以及全局数据所需的空间空下来，他们的大小是由宏定义给出的，可以在相应位置修改。基本内存分布图：<br></div>
<p align=center><a id=ImgSpan href="http://www.farsight.com.cn/FarsightBBS/UploadFile/2007-12/20071271622022868.gif" target=_blank><img alt=按此在新窗口浏览图片 src="http://www.farsight.com.cn/FarsightBBS/UploadFile/2007-12/20071271622022868.gif" onload="return imgzoom(this,550)" border=0></a></p>
<div align=center><br><br>图3&nbsp;&nbsp;搬移后内存分布情况图 </div>
<p>&nbsp;</p>
<div>接下来是u-boot启动的第二个阶段，是用c代码写的，这部分是一些相对变化不大的部分，我们针对不同的板子改变它调用的一些初始化函数，并且通过设置一些宏定义来改变初始化的流程，所以这些代码在移植的过程中并不需要修改，也是错误相对较少出现的文件。在文件的开始先是定义了一个函数指针数组，通过这个数组，程序通过一个循环来按顺序进行常规的初始化，并在其后通过一些宏定义来初始化一些特定的设备。在最后程序进入一个循环，main_loop。这个循环接收用户输入的命令，以设置参数或者进行启动引导。 </div>
<p>&nbsp;</p>
<div>本篇文章将分析重点放在了前面的start.s上，是因为这部分无论在移植还是在调试过程中都是最容易出问题的地方，要解决问题就需要程序员对代码进行修改，所以在这里简单介绍了一下start.s的基本流程，希望能对大家有所帮助。</div>
<img src ="http://www.cnitblog.com/zouzheng/aggbug/40174.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/zouzheng/" target="_blank">zz</a> 2008-02-26 14:51 <a href="http://www.cnitblog.com/zouzheng/articles/40174.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>U-BOOT分析</title><link>http://www.cnitblog.com/zouzheng/articles/40173.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Tue, 26 Feb 2008 06:49:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/40173.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/40173.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/40173.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/40173.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/40173.html</trackback:ping><description><![CDATA[我之前发在 linuxforum上面， 不过讨论的人比较少 ， 就贴在这里了。 <br>具体可见：
<p style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; LINE-HEIGHT: 150%">http://www.linuxforum.net/forum/showflat.php?Cat=&amp;Board=embedded&amp;Number=651003&amp;page=0&amp;view=collapsed&amp;sb=5&amp;o=0&amp;fpart=1#Post651082 <br><br>再读bootm源码，现象正常！ <br><br>呵呵 ， 原来 tftp download到是否是 hdr-&gt;ih_load(0x30008000) 确实是有说道的。 <br>原来对bootm源码有个地方理解错了， bootm 会根据 hdr-&gt;ih_comp 判断是否需要解压， 对于<br>mkimage -C none 的是不需要解压的。 <br><br>1&gt; mkimage -A arm -O linux -T kernel -C none -a 30008000 -e <br>30008040 -n linux-2.6.18.8 -d zImage uImage2.6.18.8-8040 <br>这种情况 ，只能把 uImage download到 30008000的位置上 ，否则 从 30008040<br>是启动不了的。 <br>2&gt; mkimage -A arm -O linux -T kernel -C none -a 30008000 -e <br>30008000 -n linux-2.6.18.8 -d zImage uImage2.6.18.8-8000 <br>这种情况download地址随便。 <br>如果 tftp 下载地址==0x30008000 ， 就从 0x30008040 启动就肯定OK 。 <br>详细的请看代码。 <br>研究了一下 u-boot-1.2.0 里面的 bootm的实现代码： do_bootm_linux() 函数 ，<br>原来由于我用mkimage的的时候的选项是 -C none ， 所以下面的判断中 hdr-&gt;ih_comp ＝ <br>IH_COMP_NONE <br>通过再读一遍代码， 也弄明白了上次问的问题， 就是 u－boot里面的解压和<br>内核自解压的区别： u-boot 里面的解压实际上是bootm 实现的 ， 把 mkimage -C bzip2<br>或者gzip 生成的 uImage进行解压 ； 而kernel的自解压是对zImage进行解压，<br>发生在bootm解压之后。 <br><br>呵呵 ， 原来 tftp download到是否是 hdr-&gt;ih_load(0x30008000) 确实是有说道的。 <br>原来对bootm源码有个地方理解错了， bootm 会根据 hdr-&gt;ih_comp 判断是否需要解压， 对于<br>mkimage -C none 的是不需要解压的。 <br><br>1&gt; mkimage -A arm -O linux -T kernel -C none -a 30008000 -e <br>30008040 -n linux-2.6.18.8 -d zImage uImage2.6.18.8-8040 <br>这种情况 ，只能把 uImage download到 30008000的位置上 ，否则 从 30008040<br>是启动不了的。 <br>2&gt; mkimage -A arm -O linux -T kernel -C none -a 30008000 -e <br>30008000 -n linux-2.6.18.8 -d zImage uImage2.6.18.8-8000 <br>这种情况download地址随便。 <br>如果 tftp 下载地址==0x30008000 ， 就从 0x30008040 启动就肯定OK 。 <br>详细的请看代码。 <br>研究了一下 u-boot-1.2.0 里面的 bootm的实现代码： do_bootm_linux() 函数 ，<br>原来由于我用mkimage的的时候的选项是 -C none ， 所以下面的判断中 hdr-&gt;ih_comp ＝ <br>IH_COMP_NONE <br>通过再读一遍代码， 也弄明白了上次问的问题， 就是 u－boot里面的解压和<br>内核自解压的区别： u-boot 里面的解压实际上是bootm 实现的 ， 把 mkimage -C bzip2<br>或者gzip 生成的 uImage进行解压 ； 而kernel的自解压是对zImage进行解压，<br>发生在bootm解压之后。 <br><br>switch (hdr-&gt;ih_comp) {<br>case IH_COMP_NONE:<br>if(ntohl(hdr-&gt;ih_load) == addr) { //如果你是tftp 到 0x30008000那么这里就命中了。 <br>printf (" XIP %s ... ", name); //tftp download 这里， 确实打印出来了。 <br>} else { //否则随便download到一个地址， 流程就进入这里了。 <br>#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) //这个条件编译不成立<br>size_t l = len;<br>void *to = (void *)ntohl(hdr-&gt;ih_load); <br>void *from = (void *)data; <br>printf (" Loading %s ... ", name); <br>while (l &gt; 0) {<br>size_t tail = (l &gt; CHUNKSZ) ? CHUNKSZ : l;<br>WATCHDOG_RESET();<br>memmove (to, from, tail);<br>to += tail;<br>from += tail;<br>l -= tail;<br>}<br>#else/* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */<br>------------------------实际执行的是这里---------------------------------<br>memmove ((void *) ntohl(hdr-&gt;ih_load), (uchar *)data, len); <br>//从这里就可以看出一旦 tftpdownload到一个任意地址， bootm 都会把<br>//它（去掉header后的kernel搬运到0x30008000 的位置上，因此entry <br>//point 肯定要是 0x30008000 ，但是对于tftp 恰好download到 <br>//0x30008000 的位置上的时候， 你会发现上面的代码中，就donothing <br>//了，因此就必须从 0x30008040 <br><br>#endif/* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */<br>}<br>break;<br>case IH_COMP_GZIP:<br>printf (" Uncompressing %s ... ", name);<br>if (gunzip ((void *)ntohl(hdr-&gt;ih_load), unc_len, // 把它解压到ih_load的位置上去<br>(uchar *)data, &amp;len) != 0) {<br>puts ("GUNZIP ERROR - must RESET board to recover\n");<br>SHOW_BOOT_PROGRESS (-6);<br>do_reset (cmdtp, flag, argc, argv);<br>}<br>break;<br>.....<br>省略了 gzip和 bzip2的处理 ， // 这里也说明 和 zImage的自解压是不一样的。 <br>gzip : mkimage -C gzip ; <br>bzip2 mkimage -C bzip2 . <br>他是只uImage 本身被压缩了 <br>default:<br>if (iflag)<br>enable_interrupts();<br>printf ("Unimplemented compression type %d\n", hdr-&gt;ih_comp);<br>SHOW_BOOT_PROGRESS (-7);<br>return 1;<br>}<br>//解压完毕，对于我得板子来说，是解压到 0x8000的位置上去了，这是个物理地址<br>puts ("OK\n");<br>SHOW_BOOT_PROGRESS (7);</p>
<img src ="http://www.cnitblog.com/zouzheng/aggbug/40173.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/zouzheng/" target="_blank">zz</a> 2008-02-26 14:49 <a href="http://www.cnitblog.com/zouzheng/articles/40173.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>u-boot 分析 - &lt;节选&gt; [嵌入式Linux系统开发技术详解-基于ARM]</title><link>http://www.cnitblog.com/zouzheng/articles/40172.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Tue, 26 Feb 2008 06:45:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/40172.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/40172.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/40172.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/40172.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/40172.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 6.1 &nbsp;Bootloader对于计算机系统来说，从开机上电到操作系统启动需要一个引导过程。嵌入式Linux系统同样离不开引导程序，这个引导程序就叫作Bootloader。6.1.1&nbsp; Bootloader介绍Bootloader是在操作系统运行之前执行的一段小程序。通过这段小程序，我们可以初始化硬件设备、建立内存空间的映射表，从而建立适当的系统软硬件环境，为最终调...&nbsp;&nbsp;<a href='http://www.cnitblog.com/zouzheng/articles/40172.html'>阅读全文</a><img src ="http://www.cnitblog.com/zouzheng/aggbug/40172.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/zouzheng/" target="_blank">zz</a> 2008-02-26 14:45 <a href="http://www.cnitblog.com/zouzheng/articles/40172.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>U-boot启动分析</title><link>http://www.cnitblog.com/zouzheng/articles/40118.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Mon, 25 Feb 2008 06:50:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/40118.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/40118.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/40118.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/40118.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/40118.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 收藏和记录些U-Boot启动分析方面的资料&nbsp;&nbsp;<a href='http://www.cnitblog.com/zouzheng/articles/40118.html'>阅读全文</a><img src ="http://www.cnitblog.com/zouzheng/aggbug/40118.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/zouzheng/" target="_blank">zz</a> 2008-02-25 14:50 <a href="http://www.cnitblog.com/zouzheng/articles/40118.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ArmLinux BOOTLOADER全程详解</title><link>http://www.cnitblog.com/zouzheng/articles/13880.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Thu, 20 Jul 2006 03:31:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/13880.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/13880.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/13880.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/13880.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/13880.html</trackback:ping><description><![CDATA[<table cellSpacing=2 cellPadding=2 width="100%" border=0>
    <tbody>
        <tr>
            <td>
            <div class=post_content>ArmLinux BOOTLOADER全程详解<br><br>网上关于<strong class=b>Linux</strong>的<strong class=b>BOOTLOADER</strong>文章不少了,但是大都是vivi,blob等比较庞大的程序,读起来不太方便,编译出的文件也比较大,而且更多的是面向开发用的引导代码,做成产品时还要裁减,这一定程度影响了开发速度,对初学者学习开销也比较大,在此分析一种简单的<strong class=b>BOOTLOADER</strong>,是在三星公司提供的2410 <strong class=b>BOOTLOADER</strong>上稍微修改后的结果,编译出来的文件大小不超过4k,希望对大家有所帮助. <br><strong>1.几个重要的概念 <br></strong>COMPRESSED KERNEL and DECOMPRESSED KERNEL <br>压缩后的KERNEL,按照文档资料,现在不提倡使用DECOMPRESSED KERNEL,而要使用COMPRESSED KERNEL,它包括了解压器.因此要在ram分配时给压缩和解压的KERNEL提供足够空间,这样它们不会相互覆盖.当执行指令跳转到 COMPRESSED KERNEL后,解压器就开始工作,如果解压器探测到解压的代码会覆盖掉COMPRESSED KERNEL,那它会直接跳到COMPRESSED KERNEL后存放数据,并且重新定位KERNEL,所以如果没有足够空间,就会出错. <br><br>Jffs2 File System <br>可以使armlinux应用中产生的数据保存在FLASH上,我的板子还没用到这个. <br><br>RAMDISK <br>使用RAMDISK可以使ROOT FILE SYSTEM在没有其他设备的情况下启动.一般有两种加载方式,我就介绍最常用的吧,把COMPRESSED RAMDISK IMAGE放到指定地址,然后由<strong class=b>BOOTLOADER</strong>把这个地址通过启动参数的方式ATAG_INITRD2传递给KERNEL.具体看代码分析. <br><br>启动参数(摘自IBM developer) <br>在调用内核之前，应该作一步准备工作，即：设置 <strong class=b>Linux</strong> 内核的启动参数。<strong class=b>Linux</strong> 2.4.x 以后的内核都期望以标记列表(tagged list)的形式来传递启动参数。启动参数标记列表以标记 ATAG_CORE 开始，以标记 ATAG_NONE 结束。每个标记由标识被传递参数的 tag_header 结构以及随后的参数值数据结构来组成。数据结构 tag 和 tag_header 定义在 <strong class=b>Linux</strong> 内核源码的include/asm/setup.h 头文件中. <br>在嵌入式 <strong class=b>Linux</strong> 系统中，通常需要由 <strong class=b>BOOTLOADER</strong> 设置的常见启动参数有：ATAG_CORE、ATAG_MEM、ATAG_CMDLINE、ATAG_RAMDISK、ATAG_INITRD等。 <br>(注)参数也可以用COMMANDLINE来设定,在我的<strong class=b>BOOTLOADER</strong>里,我两种都用了. <br><br><strong>2.开发环境和开发板配置:</strong><br>CPU:S3C2410,BANK6上有64M的SDRAM(两块),BANK0上有32M NOR FLASH,串口当然是逃不掉的.这样,按照数据手册,地址分配如下: <br>0x4000_0000开始是4k的片内DRAM. <br>0x0000_0000开始是32M FLASH 16bit宽度 <br>0x3000_0000开始是64M SDRAM 32bit宽度 <br>注意:控制寄存器中的BANK6和BANK7部分必须相同. <br>0x4000_0000(片内DRAM)存放4k以内的<strong class=b>BOOTLOADER</strong> IMAGE <br>0x3000_0100开始存放启动参数 <br>0x3120_0000 存放COMPRESSED KERNEL IMAGE <br>0x3200_0000 存放COMPRESSED RAMDISK <br>0x3000_8000 指定为DECOMPRESSED KERNEL IMAGE ADDRESS <br>0x3040_0000 指定为DECOMPRESSED RAMDISK IMAGE ADDRESS <br>开发环境:Redhat <strong class=b>Linux</strong>,armgcc toolchain, armlinux KERNEL <br>如何建立armgcc的编译环境:建议使用toolchain,而不要自己去编译armgcc,偶试过好多次,都以失败告终. <br>先下载arm-gcc 3.3.2 toolchain <br>将arm-linux-gcc-3.3.2.tar.bz2 解压到 /toolchain <br># tar jxvf arm-linux-gcc-3.3.2.tar.bz2 <br># mv /usr/local/arm/3.3.2 /toolchain <br>在makefile 中在把arch=arm CROSS_COMPILE设置成toolchain的路径还有就是INCLUDE = -I ../include -I /root/my/usr/local/arm/3.3.2/include.,否则库函数就不能用了 <br><strong>3.启动方式: <br></strong>可以放在FLASH里启动,或者用Jtag仿真器.由于使用NOR FLASH,根据2410的手册,片内的4K DRAM在不需要设置便可以直接使用,而其他存储器必须先初始化,比如告诉memory controller,BANK6里有两块SDRAM,数据宽度是32bit,= =.否则memory control会按照复位后的默认值来处理存储器.这样读写就会产生错误. <br>所以第一步,通过仿真器把执行代码放到0x4000_0000,(在编译的时候,设定TEXT_BASE=0x40000000) <br>第二步,通过 AxD把linux KERNEL IMAGE放到目标地址(SDRAM)中,等待调用 <br>第三步,执行<strong class=b>BOOTLOADER</strong>代码,从串口得到调试数据,引导armlinux <br><br><strong>4.代码分析</strong><br>讲了那么多执行的步骤,是想让大家对启动有个大概印象,接着就是<strong class=b>BOOTLOADER</strong>内部的代码分析了,<strong class=b>BOOTLOADER</strong>文章内容网上很多,我这里精简了下,删除了不必要的功能. <br><strong class=b>BOOTLOADER</strong>一般分为2部分,汇编部分和c语言部分,汇编部分执行简单的硬件初始化,C部分负责复制数据,设置启动参数,串口通信等功能. <br><strong class=b>BOOTLOADER</strong>的生命周期: <br>1. 初始化硬件,比如设置UART(至少设置一个),检测存储器= =. <br>2. 设置启动参数,这是为了告诉内核硬件的信息,比如用哪个启动界面,波特率 = =. <br>3. 跳转到<strong class=b>Linux</strong> KERNEL的首地址. <br>4. 消亡 <br>当然,在引导阶段,象vivi等,都用虚地址,如果你嫌烦的话,就用实地址,都一样. <br>我们来看代码: <br>2410init.s <br>.global _start//开始执行处 <br>_start: <br>//下面是中断向量 <br>b reset @ Supervisor Mode//重新启动后的跳转 <br>⋯⋯ <br>⋯⋯ <br>reset: <br>ldr r0,=WTCON /WTCON地址为53000000,watchdog的控制寄存器 */ <br>ldr r1,=0x0 /*关watchdog*/ <br>str r1,[r0] <br>ldr r0,=INTMSK <br>ldr r1,=0xffffffff /*屏蔽所有中断*/ <br>str r1,[r0] <br>ldr r0,=INTSUBMSK <br>ldr r1,=0x3ff /*子中断也一样*/ <br>str r1,[r0] <br>/*Initialize Ports...for display LED.*/ <br>ldr r0, =GPFCON <br>ldr r1, =0x55aa <br>str r1, [r0] <br>ldr r0, =GPFUP <br>ldr r1, =0xff <br>str r1, [r0] <br>ldr r0,=GPFDAT <br>ldr r1,=POWEROFFLED1 <br>str r1,[r0] <br>/* Setup clock Divider control register <br>* you must configure CLKDIVN before LOCKTIME or MPLL UPLL <br>* because default CLKDIVN 1,1,1 set the SDMRAM Timing Conflictnop <br>* FCLK:HCLK:PCLK = 1:2:4 in this case <br>*/ <br>ldr r0,=CLKDIVN <br>ldr r1,=0x3 <br>str r1,[r0] <br>/*To reduce PLL lock time, adjust the LOCKTIME register. */ <br>ldr r0,=LOCKTIME <br>ldr r1,=0xffffff <br>str r1,[r0] <br>/*Configure MPLL */ <br>ldr r0,=MPLLCON <br>ldr r1,=((M_MDIV&lt;&lt;12)+(M_PDIV&lt;&lt;4)+M_SDIV) //Fin=12MHz,Fout=203MHz <br>str r1,[r0] <br>ldr r1,=GSTATUS2 <br>ldr r10,[r1] <br>tst r10,#OFFRST <br>bne 1000f <br>//以上这段,我没动,就用三星写的了,下面是主要要改的地方 <br>/* MEMORY C0NTROLLER(MC)设置*/ <br>add r0,pc,#MCDATA - (.+8)// r0指向MCDATA地址,那里存放着MC初始化要用到的数据 <br>ldr r1,=BWSCON // r1指向MC控制器寄存器的首地址 <br>add r2,r0,#52 // 复制次数,偏移52字 <br>1: //按照偏移量进行循环复制 <br>ldr r3,[r0],#4 <br>str r3,[r1],#4 <br>cmp r2,r0 <br>bne 1b <br>.align 2 <br>MCDATA: <br>.word (0+(B1_BWSCON&lt;&lt;4)+(B2_BWSCON&lt;&lt;8)+(B3_BWSCON&lt;&lt;12)+(B4_BWSCON&lt;&lt;16)+(B5_BWSCON&lt;&lt;20)+(B6_BWSCON&lt;&lt;24)+(B7_BWSCON&lt;&lt;28)) <br>上面这行就是BWSCON的数据,具体参数意义如下: <br>需要更改设置DW6 和DW7都设置成10,即32bit,DW0 设置成01,即16bit <br>下面都是每个BANK的控制器数据,大都是时钟相关,可以用默认值,设置完MC后,就跳到调用main函数的部分
            <pre><br>.word ((B0_Tacs&lt;&lt;13)+(B0_Tcos&lt;&lt;11)+(B0_Tacc&lt;&lt;8)+(B0_Tcoh&lt;&lt;6)+(B0_Tah&lt;&lt;4)+(B0_Tacp&lt;&lt;2)+(B0_PMC)) <br>.word ((B1_Tacs&lt;&lt;13)+(B1_Tcos&lt;&lt;11)+(B1_Tacc&lt;&lt;8)+(B1_Tcoh&lt;&lt;6)+(B1_Tah&lt;&lt;4)+(B1_Tacp&lt;&lt;2)+(B1_PMC)) <br>.word ((B2_Tacs&lt;&lt;13)+(B2_Tcos&lt;&lt;11)+(B2_Tacc&lt;&lt;8)+(B2_Tcoh&lt;&lt;6)+(B2_Tah&lt;&lt;4)+(B2_Tacp&lt;&lt;2)+(B2_PMC)) <br>.word ((B3_Tacs&lt;&lt;13)+(B3_Tcos&lt;&lt;11)+(B3_Tacc&lt;&lt;8)+(B3_Tcoh&lt;&lt;6)+(B3_Tah&lt;&lt;4)+(B3_Tacp&lt;&lt;2)+(B3_PMC)) <br>.word ((B4_Tacs&lt;&lt;13)+(B4_Tcos&lt;&lt;11)+(B4_Tacc&lt;&lt;8)+(B4_Tcoh&lt;&lt;6)+(B4_Tah&lt;&lt;4)+(B4_Tacp&lt;&lt;2)+(B4_PMC)) <br>.word ((B5_Tacs&lt;&lt;13)+(B5_Tcos&lt;&lt;11)+(B5_Tacc&lt;&lt;8)+(B5_Tcoh&lt;&lt;6)+(B5_Tah&lt;&lt;4)+(B5_Tacp&lt;&lt;2)+(B5_PMC)) <br>.word ((B6_MT&lt;&lt;15)+(B6_Trcd&lt;&lt;2)+(B6_SCAN)) <br>.word ((B7_MT&lt;&lt;15)+(B7_Trcd&lt;&lt;2)+(B7_SCAN)) <br>.word ((REFEN&lt;&lt;23)+(TREFMD&lt;&lt;22)+(Trp&lt;&lt;20)+(Trc&lt;&lt;18)+(Tchr&lt;&lt;16)+REFCNT) <br>.word 0xB2 /* REFRESH Control Register */ <br>.word 0x30 /* BANKSIZE Register : Burst Mode */ <br>.word 0x30 /* SDRAM Mode Register */ <br>.align 2 <br>.global call_main //调用main函数,函数参数都为0 <br>call_main: <br>ldr sp,STACK_START <br>mov fp,#0 /* no previous frame, so fp=0*/ <br>mov a1, #0 /* set argc to 0*/ <br>mov a2, #0 /* set argv to NUL*/ <br>bl main /* call main*/ <br>STACK_START: <br>.word STACK_BASE <br>undefined_instruction: <br>software_interrupt: <br>prefetch_abort: <br>data_abort: <br>not_used: <br>irq: <br>fiq: </pre>
            <br>/*以上是主要的汇编部分,实现了时钟设置,串口设置watchdog关闭,中断关闭功能(如果有需要还可以降频使用),然后转入main*/
            <pre><br>2410init.c file <br>int main(int argc,char **argv) <br>{ <br>u32 test = 0; <br>void (*theKERNEL)(int zero, int arch, unsigned long params_addr) = (void (*)(int, int, unsigned long))RAM_COMPRESSED_KERNEL <br>_BASE; //压缩后的IMAGE地址 <br>int i,k=0; <br>// downPt=(RAM_COMPRESSED_KERNEL_BASE); <br>chkBs=(_RAM_STARTADDRESS);//SDRAM开始的地方 <br>// fromPt=(FLASH_LINUXKERNEL); <br>MMU_EnableICache(); <br>ChangeClockDivider(1,1); // 1:2:4 <br>ChangeMPllValue(M_MDIV,M_PDIV,M_SDIV); //Fin=12MHz FCLK=200MHz <br>Port_Init();//设置I/O端口,在使用com口前,必须调用这个函数,否则通信芯片根本得不到数据 <br>Uart_Init(PCLK, 115200);//PCLK使用默认的200000,拨特率115200 <br>/*******************(检查ram空间)*******************/ <br>Uart_SendString("nt<strong class=b>Linux</strong> S3C2410 Nor <strong class=b>BOOTLOADER</strong>n"); <br>Uart_SendString("ntChecking SDRAM 2410loader.c...n"); <br>for(;chkBs&lt;0x33FA0140;chkBs=chkBs+0x4,test++)// </pre>
            <br>//根据我的经验,最好以一个字节为递增,我们的板子,在256byte递增检测的时候是没问题的,但是 <br>//以1byte递增就出错了,第13跟数据线随几的会冒&#8221;1&#8221;,检测出来是硬件问题,现象如下 <br>//用仿真器下代码测试SDRAM，开始没贴28F128A3J FLASH片子，测试结果很好，但在上了FLASH片子//之后，测试数据（data）为0x00000400 <br>连续成批写入读出时，操作大约1k左右内存空间就会出错，//而且随机。那个出错数据总是变为0x00002400，数据总线10位和13位又没短路 <br>发生。用其他数据//测试比如0x00000200；0x00000800没这问题。dx帮忙。 <br>//至今没有解决,所以我用不了Flash. <br>{ <br>chkPt1 = chkBs; <br>*(u32 *)chkPt1 = test;//写数据 <br>if(*(u32 *)chkPt1==1024))//读数据和写入的是否一样? <br>{ <br>chkPt1 += 4; <br>Led_Display(1); <br>Led_Display(2); <br>Led_Display(3); <br>Led_Display(4); <br>} <br>else <br>goto error; <br>} <br>Uart_SendString("ntSDRAM Check Successful!ntMemory Maping..."); <br>get_memory_map(); <br>//获得可用memory 信息,做成列表,后面会作为启动参数传给KERNEL <br>//所谓内存映射就是指在4GB 物理地址空间中有哪些地址范围被分配用来寻址系统的 RAM 单元。 <br>Uart_SendString("ntMemory Map Successful!n"); <br>//我用仿真器把KERNEL,RAMDISK直接放在SDRAM上,所以下面这段是不需要的,但是如果KERNEL,RAMDISK在FLASH里,那就需要.
            <pre><br>/*******************(copy linux KERNEL)*******************/ <br>Uart_SendString("tLoading KERNEL IMAGE from FLASH... n "); <br>Uart_SendString("tand copy KERNEL IMAGE to SDRAM at 0x31000000n"); <br>Uart_SendString("ttby LEIJUN DONG dongleijun4000@hotmail.com n"); <br>for(k = 0;k &lt; 196608;k++,downPt += 1,fromPt += 1)//3*1024*1024/32linux KERNEL des,src,length=3M <br>* (u32 *)downPt = * (u32 *)fromPt; <br>/*******************(load RAMDISK)*******************/ <br>Uart_SendString("ttloading COMPRESSED RAMDISK...n"); <br>downPt=(RAM_COMPRESSED_RAMDISK_BASE); <br>fromPt=(FLASH_RAMDISK_BASE); <br>for(k = 0;k &lt; 196608;k++,downPt += 1,fromPt += 1)//3*1024*1024/32linux KERNEL des,src,length=3M <br>* (u32 *)downPt = * (u32 *)fromPt; <br>/******jffs2文件系统,在开发中如果用不到FLASH,这段也可以不要********/ <br>Uart_SendString("ttloading jffs2...n"); <br>downPt=(RAM_JFFS2); <br>fromPt=(FLASH_JFFS2); <br>for(k = 0;k &lt; (1024*1024/32);k++,downPt += 1,fromPt += 1) <br>* (u32 *)downPt = * (u32 *)fromPt; <br>Uart_SendString( "Load Success...Run...n "); <br>/*******************(setup param)*******************/ <br>setup_start_tag();//开始设置启动参数 <br>setup_memory_tags();//内存印象 <br>setup_commandline_tag("console=ttyS0,115200n8");//启动命令行 <br>setup_initrd2_tag();//root device <br>setup_RAMDISK_tag();//ramdisk image <br>setup_end_tag(); <br>/*关I-cache */ <br>asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i)); <br>i &amp;= ~0x1000; <br>asm ("mcr p15, 0, %0, c1, c0, 0": : "r" (i)); <br>/* flush I-cache */ <br>asm ("mcr p15, 0, %0, c7, c5, 0": : "r" (i)); </pre>
            <br>//下面这行就跳到了COMPRESSED KERNEL的首地址 <br>theKERNEL(0, ARCH_NUMBER, (unsigned long *)(RAM_BOOT_PARAMS)); <br>//启动kernel时候,I-cache可以开也可以关,r0必须是0,r1必须是CPU型号 <br>(可以从linux/arch/arm/tools/mach-types中找到),r2必须是参数的物理开始地址
            <pre><br>/*******************END*******************/ <br>error: <br>Uart_SendString("nnPanic SDRAM check error!n"); <br>return 0; <br>} <br>static void setup_start_tag(void) <br>{ <br>params = (struct tag *)RAM_BOOT_PARAMS;//启动参数开始的地址 <br>params-&gt;hdr.tag = ATAG_CORE; <br>params-&gt;hdr.size = tag_size(tag_core); <br>params-&gt;u.core.flags = 0; <br>params-&gt;u.core.pagesize = 0; <br>params-&gt;u.core.rootdev = 0; <br>params = tag_next(params); <br>} <br>static void setup_memory_tags(void) <br>{ <br>int i; <br>for(i = 0; i &lt; NUM_MEM_AREAS; i++) { <br>if(memory_map[i].used) { <br>params-&gt;hdr.tag = ATAG_MEM; <br>params-&gt;hdr.size = tag_size(tag_mem32); <br>params-&gt;u.mem.start = memory_map[i].start; <br>params-&gt;u.mem.size = memory_map[i].len; <br>params = tag_next(params); <br>} <br>} <br>} <br>static void setup_commandline_tag(char *commandline) <br>{ <br>int i = 0; <br>/* skip non-existent command lines so the kernel will still <br>* use its default command line. <br>*/ <br>params-&gt;hdr.tag = ATAG_CMDLINE; <br>params-&gt;hdr.size = 8; <br>//console=ttyS0,115200n8 <br>strcpy(params-&gt;u.cmdline.cmdline, p); <br>params = tag_next(params); <br>} <br>static void setup_initrd2_tag(void) <br>{ <br>/* an ATAG_INITRD node tells the kernel where the compressed <br>* ramdisk can be found. ATAG_RDIMG is a better name, actually. <br>*/ <br>params-&gt;hdr.tag = ATAG_INITRD2; <br>params-&gt;hdr.size = tag_size(tag_initrd); <br>params-&gt;u.initrd.start = RAM_COMPRESSED_RAMDISK_BASE; <br>params-&gt;u.initrd.size = 2047;//k byte <br>params = tag_next(params); <br>} <br>static void setup_ramdisk_tag(void) <br>{ <br>/* an ATAG_RAMDISK node tells the kernel how large the <br>* decompressed ramdisk will become. <br>*/ <br>params-&gt;hdr.tag = ATAG_RAMDISK; <br>params-&gt;hdr.size = tag_size(tag_ramdisk); <br>params-&gt;u.ramdisk.start = RAM_DECOMPRESSED_RAMDISK_BASE; <br>params-&gt;u.ramdisk.size = 7.8*1024; //k byte <br>params-&gt;u.ramdisk.flags = 1; // automatically load ramdisk <br>params = tag_next(params); <br>} <br>static void setup_end_tag(void) <br>{ <br>params-&gt;hdr.tag = ATAG_NONE; <br>params-&gt;hdr.size = 0; <br>} void Uart_Init(int pclk,int baud)//串口是很重要的 <br>{ <br>int i; <br>if(pclk == 0) <br>pclk = PCLK; <br>rUFCON0 = 0x0; //UART channel 0 FIFO control register, FIFO d<a class=keyurl title=ISA href="http://www.dz863.com/interface-circuits/ISA.htm" target=_blank><font color=#5f9ea0>ISA</font></a>ble <br>rUMCON0 = 0x0; //UART chaneel 0 MODEM control register, AFC d<a class=keyurl title=ISA href="http://www.dz863.com/interface-circuits/ISA.htm" target=_blank><font color=#5f9ea0>ISA</font></a>ble <br>//UART0 <br>rULCON0 = 0x3; //Line control register : Normal,No parity,1 stop,8 bits <br>下面这段samsung好象写的不太对,但是我按照Normal,No parity,1 stop,8 bits算出来的确是0x245 <br>// [10] [9] [8] [7] [6] [5] [4] [3:2] [1:0] <br>// Clock Sel, Tx Int, Rx Int, Rx Time Out, Rx err, Loop-back, Send break, Transmit Mode, Receive Mode <br>// 0 1 0 , 0 1 0 0 , 01 01 <br>// PCLK Level Pulse D<a class=keyurl title=ISA href="http://www.dz863.com/interface-circuits/ISA.htm" target=_blank><font color=#5f9ea0>ISA</font></a>ble Generate Normal Normal Interrupt or Polling <br>rUCON0 = 0x245; // Control register <br>rUBRDIV0=( (int)(PCLK/16./ baud) -1 ); //Baud rate divisior register 0 <br>delay(10); <br>} </pre>
            <br>经过以上的折腾,接下来就是kernel的活了.能不能启动kernel,得看你编译kernel的水平了.&nbsp;<br><br>摘自：<a href="http://www.dz863.com/Embedded-Systems-Design/ARM-Microcontroller/ArmLinux-BOOTLOADER.htm"><font color=#5f9ea0>http://www.dz863.com/Embedded-Systems-Design/ARM-Microcontroller/ArmLinux-BOOTLOADER.htm</font></a><br></div>
            <br>
            <div class=post_footer><a class=post_permalink href="http://deven.yculblog.com/post.1083361.html" rel=follow><font color=#5f9ea0>阅读全文</font> </a>/ <a class=post_comments href="http://deven.yculblog.com/post.1083361.html#followups" rel=follow><font color=#5f9ea0>评论</font></a><span class=post_pm>/ <a class=post_pm href="http://www.ycul.com/pm.php?act=edit&amp;u_id=1036269" rel=follow><font color=#5f9ea0>丢小纸条</font></a></span><span class=post_folder>/ 文件夹: <a class=post_folder href="http://deven.yculblog.com/archive.72442.html" rel=follow><font color=#5f9ea0>嵌入开发——Linux系统构建学习笔记</font></a></span></div>
            <br>&nbsp; </td>
        </tr>
        <tr>
            <td>
            <div><a class=post_title href="http://deven.yculblog.com/post.1083352.html" rel=follow><strong><font color=#000080>【摘】Kernel Memory Layout on ARM Linux</font> </strong></a></div>
            <div><span class=post_user><font color=#778899>棉花糖糖主</font> </span><span class=post_time><font color=#999999>@ 2006-02-02 10:25</font> </span></div>
            <br>
            <div class=post_content><br>
            <pre>		Kernel Memory Layout on ARM Linux
            Russell King &lt;rmk@arm.linux.org.uk&gt;
            November 17, 2005 (2.6.15)
            This document describes the virtual memory layout which the Linux
            kernel uses for ARM processors.  It indicates which regions are
            free for platforms to use, and which are used by generic code.
            The ARM CPU is capable of addressing a maximum of 4GB virtual memory
            space, and this must be shared between user space processes, the
            kernel, and hardware devices.
            As the ARM architecture matures, it becomes necessary to reserve
            certain regions of VM space for use for new facilities; therefore
            this document may reserve more VM space over time.
            Start		End		Use
            --------------------------------------------------------------------------
            ffff8000	ffffffff	copy_user_page / clear_user_page use.
            For SA11xx and Xscale, this is used to
            setup a minicache mapping.
            ffff1000	ffff7fff	Reserved.
            Platforms must not use this address range.
            ffff0000	ffff0fff	CPU vector page.
            The CPU vectors are mapped here if the
            CPU supports vector relocation (control
            register V bit.)
            ffc00000	fffeffff	DMA memory mapping region.  Memory returned
            by the dma_alloc_xxx functions will be
            dynamically mapped here.
            ff000000	ffbfffff	Reserved for future expansion of DMA
            mapping region.
            VMALLOC_END	feffffff	Free for platform use, recommended.
            VMALLOC_END must be aligned to a 2MB
            boundary.
            VMALLOC_START	VMALLOC_END-1	vmalloc() / ioremap() space.
            Memory returned by vmalloc/ioremap will
            be dynamically placed in this region.
            VMALLOC_START may be based upon the value
            of the high_memory variable.
            PAGE_OFFSET	high_memory-1	Kernel direct-mapped RAM region.
            This maps the platforms RAM, and typically
            maps all platform RAM in a 1:1 relationship.
            TASK_SIZE	PAGE_OFFSET-1	Kernel module space
            Kernel modules inserted via insmod are
            placed here using dynamic mappings.
            00001000	TASK_SIZE-1	User space mappings
            Per-thread mappings are placed here via
            the mmap() system call.
            00000000	00000fff	CPU vector page / null pointer trap
            CPUs which do not support vector remapping
            place their vector page here.  NULL pointer
            dereferences by both the kernel and user
            space are also caught via this mapping.
            Please note that mappings which collide with the above areas may result
            in a non-bootable kernel, or may cause the kernel to (eventually) panic
            at run time.
            Since future CPUs may impact the kernel mapping layout, user programs
            must not access any memory which is not mapped inside their 0x0001000
            to TASK_SIZE address range.  If they wish to access these areas, they
            must set up their own mappings using open() and mmap().
            </pre>
            <br><br>摘自：<a href="http://www.arm.linux.org.uk/developer/memory.txt"><font color=#5f9ea0>http://www.arm.linux.org.uk/developer/memory.txt</font></a><br></div>
            <br>
            <div class=post_footer><a class=post_permalink href="http://deven.yculblog.com/post.1083352.html" rel=follow><font color=#5f9ea0>阅读全文</font> </a>/ <a class=post_comments href="http://deven.yculblog.com/post.1083352.html#followups" rel=follow><font color=#5f9ea0>评论</font></a><span class=post_pm>/ <a class=post_pm href="http://www.ycul.com/pm.php?act=edit&amp;u_id=1036269" rel=follow><font color=#5f9ea0>丢小纸条</font></a></span><span class=post_folder>/ 文件夹: <a class=post_folder href="http://deven.yculblog.com/archive.72443.html" rel=follow><font color=#5f9ea0>嵌入开发——Linux内核分析学习笔记</font></a></span></div>
            <br>&nbsp; </td>
        </tr>
        <tr>
            <td>
            <div><a class=post_title href="http://deven.yculblog.com/post.1083334.html" rel=follow><strong><font color=#000080>【摘】Booting ARM Linux</font> </strong></a></div>
            <div><span class=post_user><font color=#778899>棉花糖糖主</font> </span><span class=post_time><font color=#999999>@ 2006-02-02 10:11</font> </span></div>
            <br>
            <div class=post_content>
            <center>
            <h3>Booting ARM Linux</h3>
            </center><ins>Author: Russell King<br>Initial date: May 18, 2002<br>Revision: <font color=#0000ff>1 - 17 September 2004</font><font color=#ff0000>2 - 30 September 2004</font></ins>
            <p>In order to boot ARM Linux, you require a boot loader, which is a small program that runs before the main kernel. The boot loader is expected to initialise various devices, and eventually call the Linux kernel, passing information to the kernel. </p>
            <p>Essentially, the boot loader should provide (as a minimum) the following: </p>
            <ol>
                <li><a href="http://www.arm.linux.org.uk/developer/booting.php#1"><font color=#5f9ea0>Setup and initialise the RAM.</font> </a>
                <li><a href="http://www.arm.linux.org.uk/developer/booting.php#2"><font color=#5f9ea0>Initialise one serial port.</font> </a>
                <li><a href="http://www.arm.linux.org.uk/developer/booting.php#3"><font color=#5f9ea0>Detect the machine type.</font> </a>
                <li><a href="http://www.arm.linux.org.uk/developer/booting.php#4"><font color=#5f9ea0>Setup the kernel tagged list.</font> </a>
                <li><a href="http://www.arm.linux.org.uk/developer/booting.php#5"><font color=#5f9ea0>Call the kernel image.</font> </a></li>
            </ol>
            <a name=1></a><u>1. Setup and initialise RAM</u>
            <p>Existing boot loaders: MANDATORY<br>New boot loaders: MANDATORY </p>
            <p>The boot loader is expected to find and initialise all RAM that the kernel will use for volatile data storage in the system. It performs this in a machine dependent manner. (It may use internal algorithms to automatically locate and size all RAM, or it may use knowledge of the RAM in the machine, or any other method the boot loader designer sees fit.) </p>
            <p><a name=2></a><u>2. Initialise one serial port</u> </p>
            <p>Existing boot loaders: OPTIONAL, RECOMMENDED<br>New boot loaders: OPTIONAL, RECOMMENDED </p>
            <p>The boot loader should initialise and enable one serial port on the target. This allows the kernel serial driver to automatically detect which serial port it should use for the kernel console (generally used for debugging purposes, or communication with the target.) </p>
            <p>As an alternative, the boot loader can pass the relevant 'console=' option to the kernel via the tagged lists specifing the port, and serial format options as described in </p>
            <p>linux/Documentation/kernel-parameters.txt. </p>
            <p><a name=3></a><u>3. Detect the machine type</u> </p>
            <p>Existing boot loaders: OPTIONAL<br>New boot loaders: MANDATORY </p>
            <p>The boot loader should detect the machine type its running on by some method. Whether this is a hard coded value or some algorithm that looks at the connected hardware is beyond the scope of this document. The boot loader must ultimately be able to provide a MACH_TYPE_xxx value to the kernel. (see linux/arch/arm/tools/mach-types). </p>
            <p><a name=4></a><u>4. Setup the kernel tagged list</u> </p>
            <p>Existing boot loaders: OPTIONAL, HIGHLY RECOMMENDED<br>New boot loaders: MANDATORY </p>
            <p>The boot loader must create and initialise the kernel tagged list. A valid tagged list starts with ATAG_CORE and ends with ATAG_NONE. The ATAG_CORE tag may or may not be empty. An empty ATAG_CORE tag has the size field set to '2' (0x00000002). The ATAG_NONE must set the size field to zero. </p>
            <p>Any number of tags can be placed in the list. It is undefined whether a repeated tag appends to the information carried by the previous tag, or whether it replaces the information in its entirety; some tags behave as the former, others the latter. </p>
            <p>The boot loader must pass at a minimum the size and location of the system memory, and root filesystem location. Therefore, the minimum tagged list should look: </p>
            <p>&nbsp;</p>
            <pre>	+-----------+
            base -&gt;	| ATAG_CORE |  |
            +-----------+  |
            | ATAG_MEM  |  | increasing address
            +-----------+  |
            | ATAG_NONE |  |
            +-----------+  v
            </pre>
            The tagged list should be stored in system RAM.
            <p>The tagged list must be placed in a region of memory where neither the kernel decompressor nor initrd 'bootp' program will overwrite it. The recommended placement is in the first 16KiB of RAM. </p>
            <p><a name=5></a><u>5. Calling the kernel image</u></p>
            <p>Existing boot loaders: MANDATORY<br>New boot loaders: MANDATORY </p>
            <p>There are two options for calling the kernel zImage. If the zImage is stored in flash, and is linked correctly to be run from flash, then it is legal for the boot loader to call the zImage in flash directly. </p>
            <p>The zImage may also be placed in system RAM (at any location) and called there. Note that the kernel uses 16K of RAM below the image to store page tables. The recommended placement is 32KiB into RAM. </p>
            <p>In either case, the following conditions must be met: </p>
            <ul>
                <li>CPU register settings
                <ul>
                    <li>r0 = 0.
                    <li>r1 = machine type number discovered in (3) above.
                    <li>r2 = physical address of tagged list in system RAM. </li>
                </ul>
                <li>CPU mode
                <ul>
                    <li>All forms of interrupts must be disabled (IRQs and FIQs.)
                    <li>The CPU must be in SVC mode. (A special exception exists for Angel.) </li>
                </ul>
                <li>Caches, MMUs
                <ul>
                    <li>The MMU must be off.
                    <li>Instruction cache may be on or off.
                    <li>Data cache must be off <ins class=rev1>and must not contain any stale data.</ins></li>
                </ul>
                </li>
            </ul>
            <li><ins class=rev2>Devices</ins>
            <ul>
                <li><ins class=rev2>DMA to/from devices should be quiesced.</ins></li>
            </ul>
            <li>The boot loader is expected to call the kernel image by jumping directly to the first instruction of the kernel image. </li>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.cnitblog.com/zouzheng/aggbug/13880.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/zouzheng/" target="_blank">zz</a> 2006-07-20 11:31 <a href="http://www.cnitblog.com/zouzheng/articles/13880.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>U-Boot移植文档之三(用U-BOOT构建嵌入式系统的引导装载程序)</title><link>http://www.cnitblog.com/zouzheng/articles/5821.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Tue, 27 Dec 2005 07:10:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/5821.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/5821.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/5821.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/5821.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/5821.html</trackback:ping><description><![CDATA[<strong>作 者：</strong>■ 北京理工大学 曾宏安 齐 尧 　　　　中国科技大学 焦振强 殷洪军<br><br><strong><br></strong><strong>摘 要：</strong>BootLoader (引导装载程序)是嵌入式系统软件开发的第一个环节，它把操作系统和硬件平台衔接在一起，对于嵌入式系统的后续软件开发十分重要，在整个开发中也占有相当大的比例。U-BOOT是当前比较流行、功能强大的BootLoader，可以支持多种体系结构。LH7A400是Sharp公司生产的一款基于 ARM922T内核的32位RISC芯片，本文详细介绍U-BOOT的功能、特点以及在LH7A400处理器上的移植过程。<br><br><br><strong>关键词：</strong>BootLoader U-BOOT移植 LH7A400 ARM922T<br><br><br><strong>引 言</strong>：<br><br>　　本文以U-BOOT为例，介绍了如何在ARM9开发板上移植BootLoader的过程。LH7A400学习板是旋极公司推出的一款高性能嵌入式开发板，其采用的处理器LH7A400是Sharp公司生产的一款基于ARM922T内核的32位RISC芯片。该芯片集成了高性能的32位RISC处理器核 ARM922T(运算速度200MHz，总线速度100MHz) ，能使处理速度达到每秒220百万条指令(MIPS)，能耗为1.33mW/MIPS，可以在低电压状态下工作(核心1.8V，输入/输出3.3 V)，片内带有锁相回路(PLL)和低能耗核心。此外该芯片还包括: 16KB 高速缓存(Cache)， 存储器管理单元(MMU)， 80KB 静态存储器(SRAM)， 彩色液晶显示控制器(LCD)， 直接存储控制器(10通道DMA)， 异步串行口控制器(UART)，同步串行口控制器(SSP)， PCMCIA控制器， AC97声音控制器， 智能卡控制器， 多媒体卡控制器， 电池控制器， USB控制器和时钟/供电管理器。值得一提的是，LH7A400是一款宽温芯片，其工作温度范围为-40℃～+85℃(降低时钟频率)，可广泛应用于无线手持设备、智能电话、PDA、家庭娱乐控制器、PocketPC及各种工控设备。<br>该学习板还包括如下硬件：由2片16位Flash (32MB)和2片16位的SDRAM(64M)构成32位宽的高速存储器结构；10/100M自适应网络芯片DM9000；Sharp 3.5&#8217;TFT LCD彩屏；触摸屏；USB Host/Device；CF卡插槽；全功能JTAG接口等。<br><br><strong>1 U-BOOT简介</strong><br><br>　　U-BOOT是由德国的工程师Wolfgang Denk从8XXROM代码发展而来的，它支持很多处理器，比如PowerPC、ARM、MIPS和x86。目前，U-BOOT源代码在 sourceforge网站的社区服务器中，Internet上有一群自由开发人员对其进行维护和开发，它的项目主页是http: //sourceforge.net/projects/U-BOOT。U-BOOT的最新版本源代码可以在Sourceforge的CVS服务器中匿名获得。<br>#cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/U-BOOT login<br>#cvs -z6 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/U-BOOT \ co -P modulename<br><br>1.1 U-BOOT源代码目录结构<br><br>◆ board：和一些已有开发板有关的文件，比如Makefile和u-boot.lds等都和具体开发板的硬件和地址分配有关。<br>◆ common：与体系结构无关的文件，实现各种命令的C文件。<br>◆ cpu：CPU相关文件，其中的子目录都是以U-BOOT所支持的CPU为名，比如有子目录arm926ejs、mips、mpc8260和nios等，每个特定的子目录中都包括cpu.c和interrupt.c，start.S。其中cpu.c初始化CPU、设置指令Cache和数据Cache等； interrupt.c设置系统的各种中断和异常，比如快速中断、开关中断、时钟中断、软件中断、预取中止和未定义指令等；start.S是U-BOOT 启动时执行的第一个文件，它主要是设置系统堆栈和工作方式，为进入C程序奠定基础。<br>◆ disk：disk驱动的分区处理代码。<br>◆ doc：文档。<br>◆ drivers：通用设备驱动程序，比如各种网卡、支持CFI的Flash、串口和USB总线等。<br>◆fs:支持文件系统的文件，U-BOOT现在支持cramfs、fat、fdos、jffs2和registerfs。<br>◆ include：头文件，还有对各种硬件平台支持的汇编文件，系统的配置文件和对文件系统支持的文件。<br>◆ net：与网络有关的代码，BOOTP协议、TFTP协议、RARP协议和NFS文件系统的实现。<br>◆ lib_arm：与ARM体系结构相关的代码。<br>◆ tools：创建S-Record格式文件 和U-BOOT images的工具。<br><br>1.2 U-BOOT的特点<br><br>　　U-BOOT支持SCC/FEC以太网、OOTP/TFTP引导、IP和MAC的预置功能，这一点和其它BootLoader(如BLOB和RedBoot等)类似。但U-BOOT还具有一些特有的功能。<br><br>◆ 在线读写Flash、DOC、IDE、IIC、EEROM、RTC，其它的BootLoader根本不支持IDE和DOC的在线读写。<br>◆ 支持串行口kermit和S-record下载代码，U-BOOT本身的工具可以把ELF32格式的可执行文件转换成为 S-record格式，直接从串口下载并执行。<br>◆ 识别二进制、ELF32、uImage格式的Image，对Linux引导有特别的支持。U-BOOT对Linux 内核进一步封装为uImage。封装如下：<br>#{CROSS_COMPILE}-objcopy -O binary -R.note -R.comment -S vmlinux \ linux.bin <br>#gzip -9 linux.bin<br>#tools/mkimage -A arm -O linux -T kernel -C gzip -a 0xc0008000 -e\<br>0xc0008000 -n &#8220;Linux-2.4.20&#8221; -d linux.bin.gz /tftpboot/uImage<br>即在Linux内核镜像vmLinux前添加了一个特殊的头，这个头在include/image.h中定义，包括目标操作系统的种类(比如Linux， VxWorks等)、目标CPU的体系机构(比如ARM、PowerPC等)、映像文件压缩类型(比如gzip、bzip2等)、加载地址、入口地址、映像名称和映像的生成时间。当系统引导时，U-BOOT会对这个文件头进行CRC校验，如果正确，才会跳到内核执行。如下所示：<br>WT-ARM9# bootm 0xc1000000<br>## Checking Image at 0xc100000 ...<br>Image Name: Linux-2.4.20<br>Created: 2004-07-02 22:10:11 UTC<br>Image Type: ARM Linux Kernel Image (gzip compressed)<br>Data Size: 550196 Bytes = 537 kB = 0 MB<br>Load Address: 0xc0008000<br>Entry Point: 0xc0008000<br>Verifying Checksum ... OK<br>Uncompressing Kernel Image &#8230;&#8230;&#8230; OK<br>◆ 单任务软件运行环境。U-BOOT可以动态加载和运行独立的应用程序，这些独立的应用程序可以利用U-BOOT控制台的I/O函数、内存申请和中断服务等。这些应用程序还可以在没有操作系统的情况下运行，是测试硬件系统很好的工具。<br>◆ 监控(minitor)命令集：读写I/O，内存，寄存器、内存、外设测试功能等 <br>◆ 脚本语言支持(类似BASH脚本)。利用U-BOOT中的autoscr命令，可以在U-BOOT中运行&#8220;脚本&#8221;。首先在文本文件中输入需要执行的命令，然后用tools/mkimage封装，然后下载到开发板上，用autoscr执行就可以了。<br>① 编辑如下的脚本example.script。<br>echo<br>echo Network Configuration:<br>echo ----------------------<br>echo Target:<br>printenv ipaddr hostname<br>echo<br>echo Server:<br>printenv serverip rootpath<br>echo<br>② 用tools/mkimage对脚本进行封装。<br># mkimage -A ARM -O linux -T script -C none -a 0 -e 0 -n "autoscr example script" -d example.script /tftpboot/example.img<br>Image Name: autoscr example script<br>Created: Wes Sep 8 01:15:02 2004<br>Image Type: ARM Linux Script (uncompressed)<br>Data Size: 157 Bytes = 0.15 kB = 0.00 MB<br>Load Address: 0x00000000<br>Entry Point: 0x00000000<br>Contents:<br>Image 0: 149 Bytes = 0 kB = 0 MB<br>③ 在U-BOOT中加载并执行这个脚本。<br>WT-ARM9# tftp 100000 /tftpboot/example.img<br>ARP broadcast 1<br>TFTP from server 10.0.0.2; our IP address is 10.0.0.99<br>Filename '/tftpboot/TQM860L/example.img'.<br>Load address: 0x100000<br>Loading: #<br>done<br>Bytes transferred = 221 (dd hex)<br>WT-ARM9# autoscr 100000<br>## Executing script at 00100000<br>Network Configuration:<br>----------------------<br>Target:<br>ipaddr=10.0.0.99<br>hostname=arm<br>Server:<br>serverip=10.0.0.2<br>rootpath=/nfsroot<br>WT-ARM9#<br>◆ 支持WatchDog、LCD logo和状态指示功能等。如果系统支持splash screen，U-BOOT启动时，会把这个图像显示到LCD上，给用户更友好的感觉。<br>◆ 支持MTD和文件系统。U-BOOT作为一种强大的BootLoader，它不仅支持MTD，而且可以在MTD基础上实现多种文件系统，比如cramfs、fat和jffs2等。<br>◆ 支持中断。由于传统的BootLoader都分为stage1和stage2，所以在stage2中添加中断处理服务十分困难，比如BLOB；而U- BOOT是把两个部分放到了一起，所以添加中断服务程序就很方便。<br>◆ 详细的开发文档。由于大多数BootLoader都是开源项目，所以文档都不是很充分。U-BOOT的维护人员意识到了这个问题，充分记录了开发文档，所以它的移植要比BLOB等缺少文档的BootLoader方便。<br><br><strong>2 对U-BOOT-1.1.0的修改</strong><br><br>　　为了使U-BOOT-1.1.0支持新的开发板，一种简便的做法是在U-BOOT已经支持的开发板中选择一种接近的进行修改。由于U-BOOT- 1.10不支持ARM-922T内核，所以选择基于ARM-920T内核的smdk2400为模板。相关的源代码在board/smdk2400/下。<br><br>2.1 支持ARM-922T内核的代码修改<br><br>修改以下代码，使U-BOOT支持arm-922t内核。<br>① 在include/目录下新建文件arm922t.h，内容如下：<br>#ifndef __ARM922T_H__<br>#define __ARM922T_H__<br>#endif<br>② 在include/目录下新建文件wt-arm9.h，该文件描述了ARM922T中Timer、UART等寄存器的结构及若干宏定义。具体内容要参考相关处理器手册。<br>③ 在cpu/目录下新建目录arm922t，将目录arm920t下的内容复制后，参考手册分别修改cpu.c、interrupts.c和serial.c，其它文件不修改。<br><br>2.2 开发板的支持<br><br>　　建立自己开发板的目录和相关文件。<br>① 在include/configs目录中添加头文件lh7a400.h。这个文件是lh7a400开发板的配置文件，它包括开发板的CPU、系统时钟、 RAM、Flash系统及其它相关的配置信息。其格式可参考include/configs/smdk2400.h。<br>② 在board/目录下新建wt-arm9目录，创建如下文件：flash.c、lhmemsetup.c、wt- arm9.c、Makefile和u-boot.lds。<br>◆ flash.c。U-BOOT 读、写和删除Flash设备的源代码文件。由于不同开发板中Flash存储器的种类各不相同，所以，修改flash.c时需参考相应的Flash芯片手册。它包括如下几个函数：<br>unsigned long flash_init (void )，Flash初始化；<br>void flash_print_info (flash_info_t *info)，打印Flash信息；<br>int flash_erase (flash_info_t *info， int s_first， int s_last)，Flash擦除；<br>volatile static int write_dword (flash_info_t *info， ulong dest， ulong data)，Flash写入；<br>int write_buff (flash_info_t *info， uchar *src， ulong addr， ulong cnt)，从内存复制数据。<br>◆ lhmemsetup.c。初始化时钟、SMC控制器和SDRAM控制器。<br>◆ wt-arm9.c。设置各种总线时钟，打开数据Cache和指令Cache，并设置相关内存参数。<br>◆ Makefile。直接拷贝board/smdk2400/Makefile，作如下修改：<br>OBJS ：= wt-arm9.o flash.o lhmemsetup.o<br>◆ u-boot.lds。设置U-BOOT中各个目标文件的连接地址，直接拷贝 board/smdk2400/u-boot.lds，作如下修改：<br>.text<br>{<br>cpu/arm922t/start.o (.text)<br>*(.text)<br>}<br><br>2.3 添加网口设备控制程序<br><br>　　在drivers/目录中添加网口设备控制程序dm9000.c 和dm9000.h，其中dm9000.c 主要包括以下函数：<br>int eth_init (bd_t *bd)，初始化网络设备；<br>void eth_halt (void)，关闭网络设备；<br>int eth_send (volatile void *packet，int len)，发送数据包；<br>int eth_rx (void) 接收数据包。<br>用中断方式处理数据包的收发，因此还定义了另外两个函数：<br>void InitInterrupt (void) ，中断初始化；<br>void dm9000_irq (void) ，中断处理。<br>以上两个函数在cpu/arm922t/interrupts.c中被调用，最后在drivers/Makefile中加入dm9000.o。<br><br>2.4 修改Makefile<br><br>　　在u-boot-1.1.0/Makefile中加入<br>lh7a400_config : unconfig<br>@./mkconfig $(@:_config=) arm arm922t wt-arm9<br>其中&#8220;arm&#8221;是CPU的种类， arm922t 是ARM CPU对应的代码目录，wt-arm9是自己开发板对应的目录。<br>交叉编译器安装在/opt/arm/3.3/bin/目录下，所以把CROSS_COMPILE设置成相应的路径：<br>export CROSS_COMPILE = /opt/arm/3.3/bin/arm-elf-<br><br>2.5 生成目标文件<br><br>　　 先运行make clean，<br>[zeng@localhost u-boot-1.1.0]$make clean<br>然后运行make lh7a400_config，<br>[zeng@localhost u-boot-1.1.0]$ make lh7a400_config<br>Configuring for lh7a400 board...<br>再运行make，<br>[zeng@localhost u-boot-1.1.0]$make<br>之后会生成三个文件：<br>u-boot——ELF格式的文件，可以被大多数Debug程序识别；<br>u-boot.bin——二进制bin文件，纯粹的U-BOOT二进制执行代码，不保存ELF格式和调试信息。这个文件一般用于烧录到用户开发板中；<br>u-boot.srec——Motorola S-Record格式，可以通过串行口下载到开发板中。<br><br>2.6 测 试<br><br>　　通过JTAG口将u-boot.bin烧写到Flash的零地址，复位后执行u-boot。若运行正常，会从串口返回如下信息：<br>U-Boot 1.1.0 (Aug 21 2004 ?18:44:37)<br>U-BooT code: C3F80000 -&gt; C3FA51A0 BSS: -&gt; C3FA96EC<br>IRQ Stack: c3f1ff7c<br>FIQ Stack: c3f1ef7c<br>RAM Configuration:<br>Bank #0: c0000000 8 MB<br>Bank #1: c1000000 8 MB<br>&#8230;&#8230;<br>Flash: 32 MB<br>In: serial<br>Out: serial<br>Err: serial<br>WT-ARM9 #<br><br>　　输入help得到所有命令列表，help command 列出该命令的功能。紧接着测试Flash和网卡，如果都正常工作的话，表明移植U-BOOT的工作基本完成，可以接着调试内核和文件系统。<br><br><strong>结 语</strong><br><br>　　BootLoader是操作系统和硬件的枢纽，它为操作系统内核的启动提供了必要的条件和参数。在移植过程中，开发人员除了要掌握 BootLoader的结构和工作流程外，还要对相关硬件有一定的了解。目前，笔者移植的U-BOOT已经能够稳定地运行在开发板上，而且可以通过 Flash和网络加载内核和文件系统，为后续开发，特别是驱动程序的开发奠定了良好的基础。<br><br><strong>　　　　　　　　　　　　　　　　　　　参考文献</strong><br>1 杜春雷. ARM体系结构与编程. 北京:清华大学出版社，2003<br>2 LH7A400 Universal SOC Advance User&#8217;s Guide: SHARP Inc，2002<br>3 Karim Yaghmour. Building Embedded Linux System. O&#8217;Reilly， 2004<br>　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　 
<img src ="http://www.cnitblog.com/zouzheng/aggbug/5821.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/zouzheng/" target="_blank">zz</a> 2005-12-27 15:10 <a href="http://www.cnitblog.com/zouzheng/articles/5821.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>U-Boot移植之二 </title><link>http://www.cnitblog.com/zouzheng/articles/5810.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Mon, 26 Dec 2005 14:39:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/5810.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/5810.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/5810.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/5810.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/5810.html</trackback:ping><description><![CDATA[<div>uboot是一个通用的免费开放源码的boot程序，支持很多的处理器。<br>以下是现在网上下载一个u-boot-1.1.1版本，用于at91rm9200系统的修改的例子。最后在redhat8.0上，用gcc2.95编译通过。</div>
<div>在网上下载了uboot-1.1.1版本。要用于自己的at91rm9200的系统，这个系统的情况是：<br>SDRAM: 32Mbytes NCS1<br>FLASH: 8Mbytes NCS0</div>
<div>涉及到的文件有四个：<br>common.h<br>flash.c<br>flash.h<br>&#8221;./board/at91rm9200dk/config.mk&#8221;<br>以下简单的说说。</div>
<div>一、首先读读uboot自带的readme文件，了解了一个大概。</div>
<div>二、看看common.h，这个文件定义了一些基本的东西，并包含了一些必要的头文件。再看看flash.h，这个文件里面定义了flash_info_t为一个struct。包含了flash的一些属性定义。并且定义了所有的flash的属性，其中，AMD的有：AMD_ID_LV320B，定义为 &#8220;#define AMD_ID_LV320B 0x22F922F9&#8221;。</div>
<div>三、对于&#8220;./borad/at91rm9200dk/flash.c&#8221;的修改，有以下的方面：<br>&#8220;void flash_identification(flash_info_t *info)&#8221;这个函数的目的是确认flash的型号。注意的是，这个函数里面有一些宏定义，直接读写了flash。并获得ID号。</div>
<div>四、修改：&#8221;./board/at91rm9200dk/config.mk&#8221;为<br>TEXT_BASE=0x21f80000 为TEXT_BASE=0x21f00000 （当然，你应该根据自己的板子来修改，和一级boot的定义的一致即可）。</div>
<div>五、再修改&#8221;./include/configs/at91rm9200dk.h&#8221;为<br>修改flash和SDRAM的大小。</div>
<div>六、另外一个要修改的文件是：<br>./borad/at91rm9200dk/flash.c。这个文件修改的部分比较的多。<br>1． 首先是OrgDef的定义，加上目前的flash。<br>2． 接下来，修改&#8221;#define FLASH_BANK_SIZE 0x200000&#8221;为自己flash的容量<br>3． 在修改函数flash_identification(flash_info_t * info)里面的打印信息，这部分将在u-boot启动的时候显示。<br>4． 然后修改函数flash_init(void)里面对一些变量的赋值。<br>5． 最后修改的是函数flash_print_info(flash_info_t * info)里面实际打印的函数信息。<br>6． 还有一个函数需要修改，就是：&#8220;flash_erase&#8221;，这个函数要检测先前知道的flash类型是否匹配，否则，直接就返回了。把这里给注释掉。</div>
<div><br>七、接下来看看SDRAM的修改。<br>这个里面对于&#8220;SIZE&#8221;的定义都是基于字节计算的。<br>只要修改&#8221;./include/configs/at91rm9200dk.h&#8221;里面的<br>&#8220;#define PHYS_SDRAM_SIZE 0X200000&#8221;就可以了。注意，SIZE是以字节为单位的。</div>
<div>八、还有一个地方要注意<br>就是按照目前的设定，一级boot把u_boot加载到了SDRAM的空间为：21F00000 -&gt; 21F16B10，这恰好是SDRAM的高端部分。另外，BSS为21F1AE34。</div>
<div><br>九、编译后，可以写入flash了。<br>1． 压缩这个u-boot.bin<br>&#8220;gzip &#8211;c u-boot.bin &gt; u-boot.gz&#8221;<br>压缩后的文件大小为：<br>43Kbytes<br>2． 接着把boot.bin和u-boot.gz烧到flash里面去。<br>Boot.bin大约11kBytes，在flash的0x1000 0000 ~ 0x1000 3fff </div>
<div>免费参加，名额有限!2005DVTF;MP3 U盘礼物...</div>
<div>zlei 发表于 2005-1-16 12:31 ARM 论坛 &#8592;返回版面 </div>
<div>U-Boot 在44B0X 开发板上的移植以及代码分析（ZT） </div>
<div>armboot的原理</div>
<div>1、BIOS的源码，其作用是初始化硬件，并COPY Boot到SDRAM中<br>2、在SDRAM中运行BOOT达到在线升级的目的。<br>3、此源代码与硬件无关，在44b0x上测试通过</div>
<div>4、串口通讯协议自己制定，很好理解。在线升级很快<br>5、目前只支持SST39LVF160，可以自己修改成相信的NOR FLASH</div>
<div>U-Boot 在44B0X 开发板上的移植以及代码分析</div>
<div>1. u-boot 介绍<br>u-boot 是一个open source 的bootloader，目前版本是0.4.0。u-boot 是在ppcboot 以及armboot 的基础上发展而来，虽然宣称是0.4.0 版本，却相当的成熟和稳定，已经在许多嵌入式系统开发过程中被采用。由于其开发源代码，其支持的开发板众多。唯一遗憾的是并不支持我们现在学习所用 samsung 44B0X 的开发板。<br>为什么我们需要u-boot？显然可以将ucLinux 直接烧入flash，从而不需要额外的<br>引导装载程序（bootloader）。但是从软件升级的角度以及程序修补的来说，软件的自<br>动更新非常重要。事实上，引导装载程序（bootloader）的用途不仅如此，但仅从软件的自动更新的需要就说明我们的开发是必要的。同时，u-boot 移植的过程也是一个对嵌入式系统包括软硬件以及操作系统加深理解的一个过程。</div>
<div><br>2. u-boot 移植的框架<br>移植u-boot 到新的开发板上仅需要修改和硬件相关的部分。在代码结构上：<br>1) 在board 目录下创建ev44b0ii 目录，创建ev44b0ii.c 以及flash.c,memsetup.S,u-boot.lds等。不需要从零开始，可选择一个相似的目录，直接复制过来，修改文件名以及内容。我在移植u-boot 过程中，选择的是ep7312 目录。由于u-boot 已经包含基于s3c24b0 的开发板目录，作为参考，也可以复制相应的目录。<br>2) 在cpu 目录下创建arm7tdmi 目录,主要包含start.S，interrupts.c 以及cpu.c,serial.c几个文件。同样不需要从零开始建立文件，直接从arm720t 复制，然后修改相应内容。<br>3) 在include/configs 目录下添加ev44b0ii.h，在这里放上全局的宏定义等。<br>4) 找到u-boot 根目录下Makefile 修改加入<br>ev44b0ii_config : unconfig<br>@./mkconfig $(@:_config=) arm arm7tdmi ev44b0ii<br>5) 运行make ev44bii_config,如果没有错误就可以开始硬件相关代码移植的工作</div>
<div><br>3. u-boot 的体系结构<br>1) 总体结构<br>u-boot 是一个层次式结构。从上图也可以看出，做移植工作的软件人员应当提供串口驱动（UART Driver）,以太网驱动(Ethernet Driver),Flash 驱动（Flash 驱动）,USB 驱动（USB Driver）。目前，通过USB 口下载程序显得不是十分必要，所以暂时没有移植USB 驱动。驱动层之上是u-boot 的应用，command 通过串口提供人机界面。我们可以使用一些命令做一些常用的工作，比如内存查看命令md。<br>Kermit 应用主要用来支持使用串口通过超级终端下载应用程序。TFTP 则是通过网络方式来下载应用程序，例如uclinux 操作系统。<br>2) 内存分布<br>在 flash rom 中内存分布图ev44b0ii 的flash 大小2M(8bits),现在将0-40000 共256k 作为u-boot 的存储空间。由于u-boot 中有一些环境变量，例如ip 地址，引导文件名等，可在命令行通过setenv 配置好,通过saveenv 保存在40000-50000（共64k）这段空间里。如果存在保存好的环境变量，u-boot 引导将直接使用这些环境变量。正如从代码分析中可以看到，我们会把flash 引导代码搬移到DRAM 中运行。下图给出u-boot 的代码在DRAM中的位置。引导代码u-boot 将从0x0000 0000 处搬移到0x0C700000 处。特别注意的由于ev44b0ii uclinux 中断向量程序地址在0x0c00 0000 处，所以不能将程序下载到0x0c00 0000 出，通常下载到0x0c08 0000 处。</div>
<div><br>4. start.S 代码结构<br>1) 定义入口<br>一个可执行的Image 必须有一个入口点并且只能有一个唯一的全局入口，通常这个入口放在Rom(flash)的0x0 地址。例如start.S 中的<br>.globl _start<br>_start:<br>值得注意的是你必须告诉编译器知道这个入口，这个工作主要是修改连接器脚本文件（lds）。<br>2) 设置异常向量(Exception Vector)<br>异常向量表，也可称为中断向量表，必须是从0 地址开始，连续的存放。如下面的就包括了复位(reset),未定义处理（undef）,软件中断(SWI),预去指令错误(Pabort),数据错误 (Dabort),保留，以及IRQ,FIQ 等。注意这里的值必须与uclinux 的vector_base 一致。这就是说如果uclinux 中vector_base(include/armnommu/proc-armv/system.h)定义为0x0c00 0000,则HandleUndef 应该在<br>0x0c00 0004。<br>b reset //for debug<br>ldr pc,=HandleUndef<br>ldr pc,=HandleSWI<br>ldr pc,=HandlePabort<br>ldr pc,=HandleDabort<br>b .<br>ldr pc,=HandleIRQ<br>ldr pc,=HandleFIQ<br>ldr pc,=HandleEINT0 /*mGA H/W interrupt vector table*/<br>ldr pc,=HandleEINT1<br>ldr pc,=HandleEINT2<br>ldr pc,=HandleEINT3<br>ldr pc,=HandleEINT4567<br>ldr pc,=HandleTICK /*mGA*/<br>b .<br>b .<br>ldr pc,=HandleZDMA0 /*mGB*/<br>ldr pc,=HandleZDMA1<br>ldr pc,=HandleBDMA0<br>ldr pc,=HandleBDMA1<br>ldr pc,=HandleWDT<br>ldr pc,=HandleUERR01 /*mGB*/<br>b .<br>b .<br>ldr pc,=HandleTIMER0 /*mGC*/<br>ldr pc,=HandleTIMER1<br>ldr pc,=HandleTIMER2<br>ldr pc,=HandleTIMER3<br>ldr pc,=HandleTIMER4<br>ldr pc,=HandleTIMER5 /*mGC*/<br>b .<br>b .<br>ldr pc,=HandleURXD0 /*mGD*/<br>ldr pc,=HandleURXD1<br>ldr pc,=HandleIIC<br>ldr pc,=HandleSIO<br>ldr pc,=HandleUTXD0<br>ldr pc,=HandleUTXD1 /*mGD*/<br>b .<br>b .<br>ldr pc,=HandleRTC /*mGKA*/<br>b .<br>b .<br>b .<br>b .<br>b . /*mGKA*/<br>b .<br>b .<br>ldr pc,=HandleADC /*mGKB*/<br>b .<br>b .<br>b .<br>b .<br>b . /*mGKB*/<br>b .<br>b .<br>ldr pc,=EnterPWDN<br>作为对照：请看以上标记的值：<br>.equ HandleReset, 0xc000000<br>.equ HandleUndef,0xc000004<br>.equ HandleSWI, 0xc000008<br>.equ HandlePabort, 0xc00000c<br>.equ HandleDabort, 0xc000010<br>.equ HandleReserved, 0xc000014<br>.equ HandleIRQ, 0xc000018<br>.equ HandleFIQ, 0xc00001c<br>/*the value is different with an address you think it may be.<br>*IntVectorTable */<br>.equ HandleADC, 0xc000020<br>.equ HandleRTC, 0xc000024<br>.equ HandleUTXD1, 0xc000028<br>.equ HandleUTXD0, 0xc00002c<br>.equ HandleSIO, 0xc000030<br>.equ HandleIIC, 0xc000034<br>.equ HandleURXD1, 0xc000038<br>.equ HandleURXD0, 0xc00003c<br>.equ HandleTIMER5, 0xc000040<br>.equ HandleTIMER4, 0xc000044<br>.equ HandleTIMER3, 0xc000048<br>.equ HandleTIMER2, 0xc00004c<br>.equ HandleTIMER1, 0xc000050<br>.equ HandleTIMER0, 0xc000054<br>.equ HandleUERR01, 0xc000058<br>.equ HandleWDT, 0xc00005c<br>.equ HandleBDMA1, 0xc000060<br>.equ HandleBDMA0, 0xc000064<br>.equ HandleZDMA1, 0xc000068<br>.equ HandleZDMA0, 0xc00006c<br>.equ HandleTICK, 0xc000070<br>.equ HandleEINT4567, 0xc000074<br>.equ HandleEINT3, 0xc000078<br>.equ HandleEINT2, 0xc00007c<br>.equ HandleEINT1, 0xc000080<br>.equ HandleEINT0, 0xc000084<br>3) 初始化CPU 相关的pll,clock,中断控制寄存器<br>依次为关闭watch dog timer,关闭中断，设置LockTime，PLL(phase lock loop),以及时钟。<br>这些值（除了LOCKTIME）都可从Samsung 44b0 的手册中查到。<br>ldr r0,WTCON //watch dog disable<br>ldr r1,=0x0<br>str r1,[r0]<br>ldr r0,INTMSK<br>ldr r1,MASKALL //all interrupt disable<br>str r1,[r0]<br>/*****************************************************<br>* Set clock control registers *<br>*****************************************************/<br>ldr r0,LOCKTIME<br>ldr r1,=800 // count = t_lock * Fin (t_lock=200us, Fin=4MHz) = 800<br>str r1,[r0]<br>ldr r0,PLLCON /*temporary setting of PLL*/<br>ldr r1,PLLCON_DAT /*Fin=10MHz,Fout=40MHz or 60MHz*/<br>str r1,[r0]<br>ldr r0,CLKCON<br>ldr r1,=0x7ff8 //All unit block CLK enable<br>str r1,[r0]<br>4) 初始化内存控制器<br>内存控制器，主要通过设置13 个从1c80000 开始的寄存器来设置，包括总线宽度，<br>8 个内存bank，bank 大小，sclk,以及两个bank mode。<br>/*****************************************************<br>* Set memory control registers *<br>*****************************************************/<br>memsetup:<br>adr r0,SMRDATA<br>ldmia r0,{r1-r13}<br>ldr r0,=0x01c80000 //BWSCON Address<br>stmia r0,{r1-r13}<br>5) 将rom 中的程序复制到RAM 中<br>首先利用PC 取得bootloader 在flash 的起始地址，再通过标号之差计算出这个程序代<br>码的大小。这些标号，编译器会在连接（link）的时候生成正确的分布的值。取得正<br>确信息后，通过寄存器(r3 到r10)做为复制的中间媒介，将代码复制到RAM 中。<br>relocate:<br>/*<br>* relocate armboot to RAM<br>*/<br>adr r0, _start /* r0 &lt;- current position of code */<br>ldr r2, _armboot_start<br>ldr r3, _armboot_end<br>sub r2, r3, r2 /* r2 &lt;- size of armboot */<br>ldr r1, _TEXT_BASE /* r1 &lt;- destination address */<br>add r2, r0, r2 /* r2 &lt;- source end address */<br>/*<br>* r0 = source address<br>* r1 = target address<br>* r2 = source end address<br>*/<br>copy_loop:<br>ldmia r0!, {r3-r10}<br>stmia r1!, {r3-r10}<br>cmp r0, r2<br>ble copy_loop<br>6) 初始化堆栈<br>进入各种模式设置相应模式的堆栈。<br>InitStacks:<br>/*Don't use DRAM,such as stmfd,ldmfd......<br>SVCstack is initialized before*/<br>mrs r0,cpsr<br>bic r0,r0,#0X1F<br>orr r1,r0,#0xDB /*UNDEFMODE|NOINT*/<br>msr cpsr,r1 /*UndefMode*/<br>ldr sp,UndefStack<br>orr r1,r0,#0XD7 /*ABORTMODE|NOINT*/<br>msr cpsr,r1 /*AbortMode*/<br>ldr sp,AbortStack<br>orr r1,r0,#0XD2 /*IRQMODE|NOINT*/<br>msr cpsr,r1 /*IRQMode*/<br>ldr sp,IRQStack<br>orr r1,r0,#0XD1 /*FIQMODE|NOINT*/<br>msr cpsr,r1 /*FIQMode*/<br>ldr sp,FIQStack<br>bic r0,r0,#0XDF /*MODEMASK|NOINT*/<br>orr r1,r0,#0X13<br>msr cpsr,r1 /*SVCMode*/<br>ldr sp,SVCStack<br>7) 转到RAM 中执行<br>使用指令ldr,pc,RAM 中C 函数地址就可以转到RAM 中去执行。<br>5. 系统初始化部分<br>1. 串口部分<br>串口的设置主要包括初始化串口部分，值得注意的串口的Baudrate 与时钟MCLK 有很大关系，是通过：rUBRDIV0=( (int)(MCLK/16./(gd -&gt;baudrate) + 0.5) -1 )计算得出。这可以在手册中查到。其他的函数包括发送，接收。这个时候没有中断，是通过循环等待来判断是否动作完成。<br>例如，接收函数：<br>while(!(rUTRSTAT0 &amp; 0x1)); //Receive data read<br>return RdURXH0();<br>2. 时钟部分<br>实现了延时函数udelay。<br>这里的get_timer 由于没有使用中断，是使用全局变量来累加的。<br>3. flash 部分<br>flash 作为内存的一部分，读肯定没有问题，关键是flash 的写部分。<br>Flash 的写必须先擦除，然后再写。<br>unsigned long flash_init (void)<br>{<br>int i;<br>u16 manId,devId;<br>//first we init it as unknown,even if you forget assign it below,it's not a problem<br>for (i=0; i &lt; CFG_MAX_FLASH_BANKS; ++i){<br>flash_info[i].flash_id = FLASH_UNKNOWN;<br>flash_info[i].sector_count=CFG_MAX_FLASH_SECT;<br>}<br>/*check manId,devId*/<br>_RESET();<br>_WR(0x555,0xaa);<br>_WR(0x2aa,0x55);<br>_WR(0x555,0x90);<br>manId=_RD(0x0);<br>_WR(0x555,0xaa);<br>_WR(0x2aa,0x55);<br>_WR(0x555,0x90);<br>devId=_RD(0x1);<br>_RESET();<br>printf("flashn");<br>printf("Manufacture ID=%4x(0x0004), Device ID(0x22c4)=%4xn",manId,devId);<br>if(manId!=0x0004 &amp;&amp; devId!=0x22c4){<br>printf("flash check faliluren");<br>return 0;<br>}else{<br>for (i=0; i &lt; CFG_MAX_FLASH_BANKS; ++i){<br>flash_info[i].flash_id=FLASH_AM160T;/*In fact it is fujitu,I only don't want to<br>modify common files*/<br>}<br>}<br>/* Setup offsets */<br>flash_get_offsets (CFG_FLASH_BASE, &amp;flash_info[0]);<br>/* zhangyy comment<br>#if CFG_MONITOR_BASE &gt;= CFG_FLASH_BASE<br>//onitor protection ON by default<br>flash_protect(FLAG_PROTECT_SET,<br>CFG_MONITOR_BASE,<br>CFG_MONITOR_BASE+monitor_flash_len-1,<br>&amp;flash_info[0]);<br>#endif<br>*/<br>flash_info[0].size =PHYS_FLASH_SIZE;<br>return (PHYS_FLASH_SIZE);<br>}<br>flash_init 完成初始化部分，这里的主要目的是检验flash 的型号是否正确。<br>int flash_erase (flash_info_t *info, int s_first, int s_last)<br>{<br>volatile unsigned char *addr = (volatile unsigned char *)(info-&gt;start[0]);<br>int flag, prot, sect, l_sect;<br>//ulong start, now, last;<br>u32 targetAddr;<br>u32 targetSize;<br>/*zyy note:It is required and can't be omitted*/<br>rNCACHBE0=( (0x2000000&gt;&gt;12)&lt;&lt;16 )|(0&gt;&gt;12); //flash area(Bank0) must be non-cachable<br>area.<br>rSYSCFG=rSYSCFG &amp; (~0x8); //write buffer has to be off for proper timing.<br>if ((s_first &lt; 0) || (s_first &gt; s_last)) {<br>if (info-&gt;flash_id == FLASH_UNKNOWN) {<br>printf ("- missingn");<br>} else {<br>printf ("- no sectors to erasen");<br>}<br>return 1;<br>}<br>if ((info-&gt;flash_id == FLASH_UNKNOWN) ||<br>(info-&gt;flash_id &gt; FLASH_AMD_COMP)) {<br>printf ("Can't erase unknown flash type - abortedn");<br>return 1;<br>}<br>prot = 0;<br>for (sect=s_first; sect&lt;=s_last; ++sect) {<br>if (info-&gt;protect[sect]) {<br>prot++;<br>}<br>}<br>if (prot) {<br>printf ("- Warning: %d protected sectors will not be erased!n",<br>prot);<br>} else {<br>printf ("n");<br>}<br>l_sect = -1;<br>/* Disable interrupts which might cause a timeout here */<br>flag = disable_interrupts();<br>/* Start erase on unprotected sectors */<br>for (sect = s_first; sect&lt;=s_last; sect++) {<br>if (info-&gt;protect[sect] == 0) {/* not protected */<br>targetAddr=0x10000*sect;<br>if(targetAddr&lt;0x1F0000)<br>targetSize=0x10000;<br>else if(targetAddr&lt;0x1F8000)<br>targetSize=0x8000;<br>else if(targetAddr&lt;0x1FC000)<br>targetSize=0x2000;<br>else<br>targetSize=0x4000;<br>F29LV160_EraseSector(targetAddr);<br>l_sect = sect;<br>if(!BlankCheck(targetAddr, targetSize))<br>printf("BlankCheck Errorn");<br>}<br>}<br>/* re-enable interrupts if necessary */<br>if (flag)<br>enable_interrupts();<br>/* wait at least 80us - let's wait 1 ms */<br>udelay (1000);<br>/*<br>*We wait for the last triggered sector<br>*/<br>if (l_sect &lt; 0)<br>goto DONE;<br>DONE:<br>printf (" donen");<br>return 0;<br>}<br>int BlankCheck(int targetAddr,int targetSize)<br>{<br>int i,j;<br>for(i=0;i<targetsize>{<br>j=*((u16 *)(i+targetAddr));<br>if( j!=0xffff)<br>{<br>printf("E:%x=%xn",(i+targetAddr),j);<br>return 0;<br>}<br>}<br>return 1;<br>}<br>flash_erase 擦除flash,BlankCheck 则检查该部分内容是否擦除成功。<br>/*-----------------------------------------------------------------------<br>*Write a word to Flash, returns:<br>* 0 - OK<br>* 1 - write timeout<br>* 2 - Flash not erased<br>*/<br>static int write_word (flash_info_t *info, ulong dest, ulong data)<br>{<br>volatile u16 *tempPt;<br>/*zhangyy note:because of compatiblity of function,I use low &amp; hi*/<br>u16 low = data &amp; 0xffff;<br>u16 high = (data &gt;&gt; 16) &amp; 0xffff;<br>low=swap_16(low);<br>high=swap_16(high);<br>tempPt=(volatile u16 *)dest;<br>_WR(0x555,0xaa);<br>_WR(0x2aa,0x55);<br>_WR(0x555,0xa0);<br>*tempPt=high;<br>_WAIT();<br>_WR(0x555,0xaa);<br>_WR(0x2aa,0x55);<br>_WR(0x555,0xa0);<br>*(tempPt+1)=low;<br>_WAIT();<br>return 0;<br>}<br>wirte_word 则想flash 里面写入unsigned long 类型的data，因为flash 一次只能写入16bits，所以这里分两次写入。</targetsize></div>
<img src ="http://www.cnitblog.com/zouzheng/aggbug/5810.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/zouzheng/" target="_blank">zz</a> 2005-12-26 22:39 <a href="http://www.cnitblog.com/zouzheng/articles/5810.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>U-Boot移植 </title><link>http://www.cnitblog.com/zouzheng/articles/5803.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Mon, 26 Dec 2005 11:59:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/5803.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/5803.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/5803.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/5803.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/5803.html</trackback:ping><description><![CDATA[<font color=#333333>
<div>BOOT LOADER（引导装载器），是用于初始化目标板硬件，给嵌入式操作系统提供板上硬件资源信息，并进一步装载、引导嵌入式操作系统运行的固件。在嵌入式系统开发过程中，很多情况都会涉及底层BOOT LOADER的移植问题，即使在有些已有BOOT LOADER的参考开发板上也存在这种可能。概括来说，如下情况会考虑进行BOOT LOADER的移植工作：<br>A. 在自主设计的目标板上，用于引导嵌入式操作系统及其应用；<br>B. 在厂家未提供BOOT LOADER源码的参考板上，遇有如下情形之一：<br>a. 在实际应用中需要添加或修改一些功能；<br>b. 为了给自行设计主板移植BOOT LOADER提供参考，先在参考板上进行移植以积累经验；<br>另外，从嵌入式系统实际开发角度讲，嵌入式操作系统的引导、配置甚至应用程序的运行状况都和BOOT LOADER有一定的关联，可以说，掌握BOOT LOADER移植是顺利进行嵌入式系统开发的重要利器。<br>与常见的嵌入式操作系统板级支持包BSP相比，BOOT LOADER与底层硬件更为相关，即每个不同配置的目标板基本都有不同的BOOT LOADER。因为BOOT LOADER往往更依据量体裁衣、定身制作的原则，以满足要求的最小化代码存放在启动ROM或FLASH中。<br>诚然，自行编写BOOT LOADER未尝不可，但从可利用的资源和实际项目开发考虑，采用移植已有的BOOT LOADER源码来解决这一问题更符合大多数项目开发的要求。<br>1 U-Boot简介<br>U- Boot，全称Universal Boot Loader，是遵循GPL条款的开放源码项目。从FADSROM、8xxROM、PPCBOOT逐步发展演化而来。其源码目录、编译形式与Linux内核很相似，事实上，不少U-Boot源码就是相应的Linux内核源程序的简化，尤其是一些设备的驱动程序，这从U-Boot源码的注释中能体现这一点。但是U-Boot不仅仅支持嵌入式Linux系统的引导，当前，它还支持NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS嵌入式操作系统。其目前要支持的目标操作系统是OpenBSD, NetBSD, FreeBSD,4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks, LynxOS, pSOS, QNX, RTEMS, ARTOS。这是U-Boot中Universal的一层含义，另外一层含义则是U-Boot除了支持PowerPC系列的处理器外，还能支持MIPS、 x86、ARM、NIOS、XScale等诸多常用系列的处理器。这两个特点正是U-Boot项目的开发目标，即支持尽可能多的嵌入式处理器和嵌入式操作系统。就目前来看，U-Boot对PowerPC系列处理器支持最为丰富，对Linux的支持最完善。其它系列的处理器和操作系统基本是在2002年11 月PPCBOOT改名为U-Boot后逐步扩充的。从PPCBOOT向U-Boot的顺利过渡，很大程度上归功于U-Boot的维护人德国DENX软件工程中心Wolfgang Denk[以下简称W.D]本人精湛专业水平和持着不懈的努力。当前，U-Boot项目正在他的领军之下，众多有志于开放源码BOOT LOADER移植工作的嵌入式开发人员正如火如荼地将各个不同系列嵌入式处理器的移植工作不断展开和深入，以支持更多的嵌入式操作系统的装载与引导。<br>选择U-Boot的理由：<br>① 开放源码；<br>② 支持多种嵌入式操作系统内核，如Linux、NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS；<br>③ 支持多个处理器系列，如PowerPC、ARM、x86、MIPS、XScale；<br>④ 较高的可靠性和稳定性；<br>④ 较高的可靠性和稳定性；<br>⑤ 高度灵活的功能设置，适合U-Boot调试、操作系统不同引导要求、产品发布等；<br>⑥ 丰富的设备驱动源码，如串口、以太网、SDRAM、FLASH、LCD、NVRAM、EEPROM、RTC、键盘等；<br>⑦ 较为丰富的开发调试文档与强大的网络技术支持；<br>2 U-Boot主要目录结构<br>- board 目标板相关文件，主要包含SDRAM、FLASH驱动；<br>- common 独立于处理器体系结构的通用代码，如内存大小探测与故障检测；<br>- cpu 与处理器相关的文件。如mpc8xx子目录下含串口、网口、LCD驱动及中断初始化等文件；<br>- driver 通用设备驱动，如CFI FLASH驱动（目前对INTEL FLASH支持较好）<br>- doc U-Boot的说明文档；<br>- examples可在U-Boot下运行的示例程序；如hello_world.c,timer.c；<br>- include U-Boot头文件；尤其configs子目录下与目标板相关的配置头文件是移植过程中经常要修改的文件；<br>- lib_xxx 处理器体系相关的文件，如lib_ppc, lib_arm目录分别包含与PowerPC、ARM体系结构相关的文件；<br>- net 与网络功能相关的文件目录，如bootp,nfs,tftp；<br>- post 上电自检文件目录。尚有待于进一步完善；<br>- rtc RTC驱动程序；<br>- tools 用于创建U-Boot S-RECORD和BIN镜像文件的工具； <br>3 U-Boot支持的主要功能<br>U-Boot可支持的主要功能列表<br>系统引导 支持NFS挂载、RAMDISK（压缩或非压缩）形式的根文件系统<br>支持NFS挂载、从FLASH中引导压缩或非压缩系统内核；<br>基本辅助功能 强大的操作系统接口功能；可灵活设置、传递多个关键参数给操作系统，适合系统在不同开发阶段的调试要求与产品发布，尤对Linux支持最为强劲；<br>支持目标板环境参数多种存储方式，如FLASH、NVRAM、EEPROM；<br>CRC32校验，可校验FLASH中内核、RAMDISK镜像文件是否完好；<br>设备驱动 串口、SDRAM、FLASH、以太网、LCD、NVRAM、EEPROM、键盘、USB、PCMCIA、PCI、RTC等驱动支持；<br>上电自检功能 SDRAM、FLASH大小自动检测；SDRAM故障检测；CPU型号；<br>特殊功能 XIP内核引导；<br>4 U-Boot移植过程<br>① 获得发布的最新版本U-Boot源码，与Linux内核源码类似，也是 bzip2的压缩格式。可从U-Boot的官方网站<a href="http://sourceforge.net/projects/U-Boot"><strong><font color=#00143c>http://sourceforge.net/projects/U-Boot</font></strong></a>上获得；<br>② 阅读相关文档，主要是U-Boot源码根目录下的README文档和U-Boot官方网站的DULG（The DENX U-Boot and Linux Guide）文档<a href="http://www.denx.de/twiki/bin/view/DULG/Manual"><strong><font color=#00143c>http://www.denx.de/twiki/bin/view/DULG/Manual</font></strong></a>。尤其是DULG文档，从如何安装建立交叉开发环境和解决U-Boot移植中常见问题都一一给出详尽的说明；<br>③ 订阅U-Boot用户邮件列表<a href="http://lists.sourceforge.net/lists/listinfo/u-boot-users"><strong><font color=#00143c>http://lists.sourceforge.net/lists/listinfo/u-boot-users</font></strong></a>。在移植U-Boot过程中遇有问题，在参考相关文档和搜索U-Boot-User邮件档案库<a href="http://sourceforge.net/mailarchive/forum.php?forum_id=12898"><strong><font color=#00143c>http://sourceforge.net/mailarchive/forum.php?forum_id=12898</font></strong></a>仍不能解决的情况下，第一时间提交所遇到的这些问题，众多热心的U-Boot开发人员会乐于迅速排查问题，而且很有可能，W.D本人会直接参与指导；<br>④ 在建立的开发环境下进行移植工作。绝大多数的开发环境是交叉开发环境。在这方面，DENX 和MontaVista均提供了完整的开发工具集；<br>⑤ 在目标板与开发主机间接入硬件调试器。这是进行U-Boot移植应当具备且非常关键的调试工具。因为在整个U-Boot的移植工作中,尤其是初始阶段，硬件调试器是我们了解目标板真实运行状态的唯一途径。在这方面，W.D本人和众多嵌入式开发人员倾向于使用BDI2000。一方面，其价格不如ICE调试器昂贵，同时其可靠性高，功能强大，完全能胜任移植和调试U-Boot。另外，网上也有不少关于BDI2000调试方面的参考文档。<br>⑥ 如果在参考开发板上移植U-Boot，可能需要移除目标板上已有的BOOT LOADER。可以根据板上BOOT LOADER的说明文档，先着手解决在移除当前BOOT LOADER的情况下，如何进行恢复。以便今后在需要场合能重新装入原先的BOOT LOADER。<br>5 U-Boot移植方法<br>当前，对于U-Boot的移植方法，大致分为两种。一种是先用BDI2000创建目标板初始运行环境，将U-Boot镜像文件u-boot.bin下载到目标板RAM中的指定位置，然后，用BDI2000进行跟踪调试。其好处是不用将U-Boot镜像文件烧写到FLASH中去。但弊端在于对移植开发人员的移植调试技能要求较高，BDI2000的配置文件较为复杂。另外一种方法是用BDI2000先将 U-Boot镜像文件烧写到FLASH中去，然后利用GDB和BDI2000进行调试。这种方法所用BDI2000的配置文件较为简单，调试过程与U- Boot移植后运行过程相吻合，即U-Boot先从FLASH中运行，再重载至RAM中相应位置，并从那里正式投入运行。唯一感到有些麻烦的就是需要不断烧写FLASH。但考虑到FLASH常规擦写次数基本为10万次左右，作为移植U-Boot，不会占用太多的次数，应该不会为FLASH烧写有什么担忧。同时，W. D本人也极力推荐使用后一种方法。笔者建议，除非U-Boot移植资深人士或有强有力的技术支持，建议采用第二种移植方法。<br>6 U-Boot移植主要修改的文件<br>从移植U-Boot最小要求－U-Boot能正常启动的角度出发，主要考虑修改如下文件：<br>① &lt;目标板&gt;.h头文件，如include/configs/RPXlite.h。可以是U-Boot源码中已有的目标板头文件，也可以是新命名的配置头文件；大多数的寄存器参数都是在这一文件中设置完成的；<br>② &lt;目标板&gt;.c文件，如board/RPXlite/RPXlite.c。它是SDRAM的驱动程序，主要完成SDRAM的UPM表设置，上电初始化。<br>③ FLASH的驱动程序，如board/RPXlite/flash.c，或common/cfi_flash.c。可在参考已有FLASH驱动的基础上，结合目标板FLASH数据手册，进行适当修改； <br>④ 串口驱动，如修改cpu/mpc8xx/serial.c串口收发器芯片使能部分。<br>7 U-Boot移植要点<br>① BDI2000的配置文件。如果采用第二种移植方法，即先烧入FLASH的方法，配置项只需很少几个，就可以进行U-Boot的烧写与调试了。对PPC 8xx系列的主板，可参考DULG文档中TQM8xx的配置文件进行相应的修改。下面，笔者以美国Embedded Planet公司的RPXlite DW板为例，给出在嵌入式Linux交叉开发环境下的BDI2000参考配置文件以作参考：<br>; bdiGDB configuration file for RPXlite DW or LITE_DW<br>; --------------------------------------------<br>[INIT]<br>; init core register<br>WSPR 149 0x2002000F ;DER : set debug enable register<br>; WSPR 149 0x2006000F ;DER : enable SYSIE for BDI flash program<br>WSPR 638 0xFA200000 ;IMMR : internal memory at 0xFA200000<br>WM32 0xFA200004 0xFFFFFF89 ;SYPCR<br>[TARGET]<br>CPUCLOCK 40000000 ;the CPU clock rate after processing the init list<br>BDIMODE AGENT ;the BDI working mode (LOADONLY | AGENT)<br>BREAKMODE HARD ;SOFT or HARD, HARD uses PPC hardware breakpoints<br>[HOST]<br>IP 173.60.120.5<br>FILE uImage.litedw <br>FORMAT BIN<br>LOAD MANUAL ;load code MANUAL or AUTO after reset<br>DEBUGPORT 2001<br>START 0x0100<br>[FLASH]<br>CHIPTYPE AM29BX8 ;;Flash type (AM29F | AM29BX8 | AM29BX16 | I28BX8 | I28BX16)<br>CHIPSIZE 0x400000 ;;The size of one flash chip in bytes<br>BUSWIDTH 32 ;The width of the flash memory bus in bits (8 | 16 | 32)<br>WORKSPACE 0xFA202000 ; RAM buffer for fast flash programming<br>FILE u-boot.bin ;The file to program<br>FORMAT BIN 0x00000000<br>ERASE 0x00000000 BLOCK<br>ERASE 0x00008000 BLOCK<br>ERASE 0x00010000 BLOCK<br>ERASE 0x00018000 BLOCK<br>[REGS]<br>DMM1 0xFA200000<br>FILE reg823.def<br>② U-Boot移植参考板。这是进行U-Boot移植首先要明确的。可以根据目标板上CPU、FLASH、SDRAM的情况，以尽可能相一致为原则，先找出一个与所移植目标板为同一个或同一系列处理器的U-Boot支持板为移植参考板。如RPXlite DW板可选择U-Boot源码中RPXlite板作为U-Boot移植参考板。对U-Boot移植新手，建议依照循序渐进的原则，目标板文件名暂时先用移植参考板的名称，在逐步熟悉U-Boot移植基础上，再考虑给目标板重新命名。在实际移植过程中，可用Linux命令查找移植参考板的特定代码，如 grep &#8211;r RPXlite ./ 可确定出在U-Boot中与RPXlite板有关的代码，依此对照目标板实际进行屏蔽或修改。同时应不局限于移植参考板中的代码，要广泛借鉴U-Boot 中已有的代码更好地实现一些具体的功能。<br>③ U-Boot烧写地址。不同目标板，对U-Boot在FLASH中存放地址要求不尽相同。事实上，这是由处理器中断复位向量来决定的，与主板硬件相关，对 MPC8xx主板来讲，就是由硬件配置字(HRCW)决定的。也就是说，U-Boot烧写具体位置是由硬件决定的，而不是程序设计来选择的。程序中相应U -Boot起始地址必须与硬件所确定的硬件复位向量相吻合；如RPXlite DW板的中断复位向量设置为0x00000100。因此， U-Boot 的BIN镜像文件必须烧写到FLASH的起始位置。事实上，大多数的PPC系列的处理器中断复位向量是0x00000100和0xfff00100。这也是一般所说的高位启动和低位启动的BOOT LOADER所在位置。可通过修改U-Boot源码&lt;目标板&gt;.h头文件中CFG_MONITOR_BASE 和board/&lt;目标板&gt;/config.mk中的TEXT_BASE的设置来与硬件配置相对应。<br>④ CPU寄存器参数设置。根据处理器系列、类型不同，寄存器名称与作用有一定差别。必须根据目标板的实际，进行合理配置。一个较为可行和有效的方法，就是借鉴参考移植板的配置，再根据目标板实际，进行合理修改。这是一个较费功夫和考验耐力的过程，需要仔细对照处理器各寄存器定义、参考设置、目标板实际作出选择并不断测试。MPC8xx处理器较为关键的寄存器设置为SIUMCR、PLPRCR、SCCR、BRx、ORx。<br>⑤ 串口调试。能从串口输出信息，即使是乱码，也可以说U-Boot移植取得了实质性突破。依据笔者调试经历，串口是否有输出，除了与串口驱动相关外，还与 FLASH相关的寄存器设置有关。因为U-Boot是从FLASH中被引导启动的，如果FLASH设置不正确，U-Boot代码读取和执行就会出现一些问题。因此，还需要就FLASH的相关寄存器设置进行一些参数调试。同时，要注意串口收发芯片相关引脚工作波形。依据笔者调试情况，如果串口无输出或出现乱码，一种可能就是该芯片损坏或工作不正常。<br>⑥ 与启动 FLASH相关的寄存器BR0、OR0的参数设置。应根据目标板FLASH的数据手册与BR0和OR0的相关位含义进行合理设置。这不仅关系到FLASH能否正常工作，而且与串口调试有直接的关联。<br>⑦ 关于CPLD电路。目标板上是否有CPLD电路丝毫不会影响U-Boot的移植与嵌入式操作系统的正常运行。事实上，CPLD电路是一个集中将板上电路的一些逻辑关系可编程设置的一种实现方法。其本身所起的作用就是实现一些目标板所需的脉冲信号和电路逻辑，其功能完全可以用一些逻辑电路与CPU口线来实现。<br>⑧ SDRAM的驱动。串口能输出以后，U-Boot移植是否顺利基本取决于SDRAM的驱动是否正确。与串口调试相比，这部分工作更为核心，难度更大。 MPC8xx目标板SDRAM驱动涉及三部分。一是相关寄存器的设置；二是UPM表；三是SDRAM上电初始化过程。任何一部分有问题，都会影响U- Boot、嵌入式操作系统甚至应用程序的稳定、可靠运行。所以说，SDRAM的驱动不仅关系到U-Boot本身能否正常运行，而且还与后续部分相关，是相当关键的部分。<br>⑨ 补充功能的添加。在获得一个能工作的U-Boot后，就可以根据目标板和实际开发需要，添加一些其它功能支持。如以太网、LCD、NVRAM等。与串口和 SDRAM调试相比，在已有基础之上，这些功能添加还是较为容易的。大多只是在参考现有源码的基础上，进行一些修改和配置。<br>另外，如果在自主设计的主板上移植U-Boot，那么除了考虑上述软件因素以外，还需要排查目标板硬件可能存在的问题。如原理设计、PCB布线、元件好坏。在移植过程中，敏锐判断出故障态是硬件还是软件问题，往往是关系到项目进度甚至移植成败的关键，相应难度会增加许多。<br>完成一个目标板的移植工作后，可考虑将移植结果以补丁的形式发送到U-Boot用户邮件列表，尤其是一些参考板的移植结果。这是使用GPL代码并遵循GPL 条款的体现。可在阅读README相关补丁说明的基础上，添加适当的注释，将自己列入光荣榜(CREDITS)。如果愿意承担所移植板的后续更新工作，可以考虑加入维护人员(MAINTAINERS)开发队伍行列。<br>诚然，在实际的U-Boot移植中无法避免地会遇到一些难以预料的问题，甚至出现倒退，尤其U-Boot移植新手，更会平添诸多难度。但笔者相信，在逐步熟悉U-Boot移植方法、过程中，随着自身经验的不断积累，加之有众多热衷于开放源码人士的鼎立相助，坚冰终会消融</div>
</font>
<p align=left><br><br>armlinux的bootloader启动代码分析<br><br>Author : balancesli<br>mail : balancesli@thizlinux.com.cn<br><br>前阶段做了一次基于at91rm9200引导部分的技术分析，主要采用了u-boot，这里只面向使用at91rm9200板子的<br>的朋友做个简单的推敲，希望起到抛砖引玉的作用.<br><br>关键词 : <br>u-boot: 一个开源的面向多个目标平台(ppc, mips, arm, x86)的bootloader.<br>at91rm9200 : Atmel 公司生产的基于arm9核的Soc处理器.<br><br>以下先给出at91rm9200引导流程图<br><br>Boot program Flow Diagram <br><br>Device Setup<br>|<br>|<br>Boot SPI DataFlash Boot --&gt; Download from DataFlash --&gt; run<br>|<br>| <br>TWI EEPROM Boot --&gt; Download from EEPROM --&gt; run<br>|<br>|<br>Parallel Boot --&gt; Download from 8-bit Device --&gt; <br>| <br>| Xmodem protocol <br>| |---DBGU Serial Download ---------------------&gt; run<br>|____|<br>| DFU protocol<br>|-----USB download -----------------------&gt; run <br><br>在这里我主要介绍通过片内引导和片外引导, 片内引导主要采用串口下载并引导u-boot，并完成程序被烧写到Flash上, <br>然后就可以通过跳线的方式从片外引导执行已经烧写到片外Flash上的引导程序(bootloader).<br><br>这里要提及的是at91rm9200内部本身有128k的片内rom,其固化了一个bootloader和uploader, 用来支持程序的<br>下载和引导,而且其内部固化的程序提供了很多内部服务接口(Internel Service)供我们来使用，例如Xmodem，Tempo<br>DataFlash, CRC, Sine服务接口，这样我们就可以利用它所提供的Service interface API完成程序的下载。<br>这里主要介绍Xmodem接口服务。<br><br>at91rm9200内部固化的代码在设计上采用了面向对象的设计方法，如下:<br><br><br>typedef struct _AT91S_Service <br>{<br>char data;<br>char (*MainMethod)();<br>char (*ChildMethod)();<br>}AT91S_Service, *AT91PS_Service;<br><br>char AT91F_MainMethod()<br>{<br><br>}<br>char AT91F_ChildMethod()<br>{<br><br>}<br><br>/*init the Service */<br>AT91PS_Service AT91F_OpenDevice(AT91PS_Service pService)<br>{<br>pService-&gt;data = 0;<br>pService-&gt;MainMethod = AT91F_MainMethod;<br>pService-&gt;ChildMethod = AT91F_ChildMethod;<br>}<br><br>//使用方法如下<br>AT91S_Service service;<br>AT91PS_Service pService = AT91F_OpenDevice(&amp;service);<br>pService-&gt;AT91F_MainMethmod();<br>.....<br><br>通过如上代码片断可以看出它采用了类似面向对象的设计方法。<br>其实如果各位朋友接触过的话或者看过这本书的话，应该很容易便接受它。<br>下面以Xmodem服务为例子介绍:<br><br>at91rm9200内部提供的服务包含了几个服务对象, 这些对象在片内启动xmodem协议Host端和Targe端通讯时会用到.<br><br>typedef struct _AT91S_RomBoot <br>{<br>const unsigned int version;<br>// Peripheral descriptors<br>const AT91S_MEMCDesc MEMC_DESC;<br>const AT91S_STDesc SYSTIMER_DESC;<br>const AT91S_Pio2Desc PIOA_DESC;<br>const AT91S_Pio2Desc PIOB_DESC;<br>const AT91S_USART2Desc DBGU_DESC;<br>const AT91S_USART2Desc USART0_DESC;<br>const AT91S_USART2Desc USART1_DESC;<br>const AT91S_USART2Desc USART2_DESC;<br>const AT91S_USART2Desc USART3_DESC;<br>const AT91S_TWIDesc TWI_DESC;<br>const AT91S_SPIDesc SPI_DESC;<br><br>// Objects entry<br>const AT91PF_OpenPipe OpenPipe;<br>const AT91PF_OpenSBuffer OpenSBuffer;<br>const AT91PF_OpenSvcUdp OpenSvcUdp;<br>const AT91PF_OpenSvcXmodem OpenSvcXmodem;<br>const AT91PF_OpenCtlTempo OpenCtlTempo;<br>const AT91PF_OpenDfuDesc OpenDfuDesc;<br>const AT91PF_OpenUsbDesc OpenUsbDesc;<br>const AT91PF_OpenSvcDataFlash OpenSvcDataFlash;<br>const AT91PF_SVC_CRC16 CRC16;<br>const AT91PF_SVC_CRCCCITT CRCCCITT;<br>const AT91PF_SVC_CRCHDLC CRCHDLC;<br>const AT91PF_SVC_CRC32 CRC32;<br>// Array<br>const AT91PS_SVC_CRC_BIT_REV Bit_Reverse_Array;<br>const AT91PS_SINE_TAB SineTab;<br>const AT91PF_Sinus Sine;<br>} AT91S_RomBoot;<br><br>//AT91S_Pipe<br>typedef struct _AT91S_Pipe<br>{<br>// A pipe is linked with a peripheral and a buffer<br>AT91PS_SvcComm pSvcComm;<br>AT91PS_Buffer pBuffer;<br><br>// Callback functions with their arguments<br>void (*WriteCallback) (AT91S_PipeStatus, void *);<br>void (*ReadCallback) (AT91S_PipeStatus, void *);<br>void *pPrivateReadData;<br>void *pPrivateWriteData;<br><br>// Pipe methods<br>AT91S_PipeStatus (*Write) (<br>struct _AT91S_Pipe *pPipe,<br>char const * pData,<br>unsigned int size,<br>void (*callback) (AT91S_PipeStatus, void *),<br>void *privateData<br>);<br><br>AT91S_PipeStatus (*Read) (<br>struct _AT91S_Pipe *pPipe,<br>char *pData,<br>unsigned int size,<br>void (*callback) (AT91S_PipeStatus, void *),<br>void *privateData<br>);<br><br>AT91S_PipeStatus (*AbortWrite)(struct _AT91S_Pipe *pPipe);<br>AT91S_PipeStatus (*AbortRead)(struct _AT91S_Pipe *pPipe);<br>AT91S_PipeStatus (*AbortRead)(struct _AT91S_Pipe *pPipe);<br>AT91S_PipeStatus (*Reset)(struct _AT91S_Pipe *pPipe);<br>char (*IsWritten)(struct _AT91S_Pipe *pPipe, char const *pVoid);<br>char (*IsReceived) (struct _AT91S_Pipe *pPipe, char const *pVoid);<br>} AT91S_Pipe;<br><br>//AT91S_Buff<br>typedef struct _AT91S_SBuffer<br>{<br>AT91S_Buffer parent;<br>char *pRdBuffer;<br>char const *pWrBuffer;<br>unsigned int szRdBuffer;<br>unsigned int szWrBuffer;<br>unsigned int stRdBuffer;<br>unsigned int stWrBuffer;<br>} AT91S_SBuffer;<br><br>// AT91S_SvcTempo<br>typedef struct _AT91S_SvcTempo<br>{<br><br>// Methods:<br>AT91S_TempoStatus (*Start) (<br>struct _AT91S_SvcTempo *pSvc,<br>unsigned int timeout,<br>unsigned int reload,<br>void (*callback) (AT91S_TempoStatus, void *),<br>void *pData);<br>AT91S_TempoStatus (*Stop) (struct _AT91S_SvcTempo *pSvc);<br><br>struct _AT91S_SvcTempo *pPreviousTempo;<br>struct _AT91S_SvcTempo *pNextTempo;<br><br>// Data<br>unsigned int TickTempo; //* timeout value<br>unsigned int ReloadTempo;//* Reload value for periodic execution<br>void (*TempoCallback)(AT91S_TempoStatus, void *);<br>void *pPrivateData;<br>AT91E_SvcTempo flag;<br>} AT91S_SvcTempo;<br><br>// AT91S_CtrlTempo<br>typedef struct _AT91S_CtlTempo<br>{<br>// Members:<br><br>// Start and stop for Timer hardware<br>AT91S_TempoStatus (*CtlTempoStart) (void *pTimer);<br>AT91S_TempoStatus (*CtlTempoStop) (void *pTimer);<br><br>// Start and stop for Tempo service<br>AT91S_TempoStatus (*SvcTempoStart) (<br>struct _AT91S_SvcTempo *pSvc,<br>unsigned int timeout,<br>unsigned int reload,<br>void (*callback) (AT91S_TempoStatus, void *),<br>void *pData);<br>AT91S_TempoStatus (*SvcTempoStop) (struct _AT91S_SvcTempo *pSvc);<br>AT91S_TempoStatus (*CtlTempoSetTime)(struct _AT91S_CtlTempo *pCtrl, unsigned int NewTime);<br>AT91S_TempoStatus (*CtlTempoGetTime)(struct _AT91S_CtlTempo *pCtrl);<br>AT91S_TempoStatus (*CtlTempoIsStart)(struct _AT91S_CtlTempo *pCtrl);<br>AT91S_TempoStatus (*CtlTempoCreate) (struct _AT91S_CtlTempo *pCtrl,struct _AT91S_SvcTempo *pTempo);<br>AT91S_TempoStatus (*CtlTempoRemove) (struct _AT91S_CtlTempo *pCtrl,struct _AT91S_SvcTempo *pTempo);<br>AT91S_TempoStatus (*CtlTempoTick) (struct _AT91S_CtlTempo *pCtrl);<br><br>// Data:<br><br>void *pPrivateData; // Pointer to devived class<br>void const *pTimer; // hardware<br>AT91PS_SvcTempo pFirstTempo;<br>AT91PS_SvcTempo pNewTempo;<br>} AT91S_CtlTempo;<br><br><br><br>//以下代码是上面几个对象的使用范例，通过这样就可以完成Host端和Targe端之间的xmodem通讯,并可以下载代码了。<br><br>AT91S_RomBoot const *pAT91;<br>AT91S_SBuffer sXmBuffer;<br>AT91S_SvcXmodem svcXmodem;<br>AT91S_Pipe xmodemPipe;<br>AT91S_CtlTempo ctlTempo;<br><br>AT91PS_Buffer pXmBuffer;<br>AT91PS_SvcComm pSvcXmodem;<br>unsigned int SizeDownloaded; <br><br>/* Init of ROM services structure */<br>pAT91 = AT91C_ROM_BOOT_ADDRESS;//这里取得内部ROM服务的入口地址<br><br>/* Tempo Initialization */<br>pAT91-&gt;OpenCtlTempo(&amp;ctlTempo, (void *) &amp;(pAT91-&gt;SYSTIMER_DESC));<br>ctlTempo.CtlTempoStart((void *) &amp;(pAT91-&gt;SYSTIMER_DESC));<br><br>/* Xmodem Initialization */<br>pXmBuffer = pAT91-&gt;OpenSBuffer(&amp;sXmBuffer);<br>pSvcXmodem = pAT91-&gt;OpenSvcXmodem(&amp;svcXmodem, (AT91PS_USART)AT91C_BASE_DBGU, &amp;ctlTempo);<br>pAT91-&gt;OpenPipe(&amp;xmodemPipe, pSvcXmodem, pXmBuffer);<br>xmodemPipe.Read(&amp;xmodemPipe, (char *)AT91C_UBOOT_BASE_ADDRESS, AT91C_UBOOT_MAXSIZE, <br>AT91F_XmodemProtocol, 0); <br>while(XmodemComplete !=1);<br><br><br><br>//上面部分主要针对at91rm9200片内启动时我们可以使用的片内接口服务介绍，玩H9200的朋友可以参考一下便知道缘由。<br><br>下面主要介绍at91rm9200片外启动时所使用的bootloader--&gt;u-boot.<br><br>一. bootloader <br>BootLoader(引导装载程序)是嵌入式系统软件开发的非常重要的环节，它把操作系统和硬件平台衔接在一起，<br>是跟硬件体系密切相关的。<br><br><br><br>1.1 典型的嵌入式系统软件部分Image memory layout : bootloader , bootloader param, kernel, rootfs.<br><br>1.2 引导模式 : 1. bootstrap或download<br>2. autoboot<br>1.3 u-boot简介 :<br>u-boot是由Wolfgang Denk开发，它支持(mips, ppc, arm, x86)等目标体系，<br>可以在http://sourceforge.net 上下载获得源码，<br><br>1.4 u-boot源代码目录结构<br><br>board：开发板相关的源码，不同的板子对应一个子目录，内部放着主板相关代码。<br><br>at91rm9200dk/at91rm9200.c, config.mk, Makefile, flash.c ,u-boot.lds等都和具体开发板的硬件和地址分配有关。<br><br>common：与体系结构无关的代码文件，实现了u-boot所有命令，<br>其中内置了一个shell脚本解释器(hush.c, a prototype Bourne shell grammar parser), busybox中也使用了它.<br><br>cpu：与cpu相关代码文件，其中的所有子目录都是以u-boot所支持的cpu命名.<br><br>at91rm9200/at45.c, at91rm9200_ether.c, cpu.c, interrupts.c serial.c, start.S, config.mk, Makefile等.<br>其中cpu.c负责初始化CPU、设置指令Cache和数据Cache等；<br><br>interrupt.c负责设置系统的各种中断和异常，比如快速中断、开关中断、时钟中断、软件中断、<br>预取中止和未定义指令等；<br><br>start.S负责u-boot启动时执行的第一个文件，它主要是设置系统堆栈和工作方式，为跳转到C程序入口点.<br><br>disk：设备分区处理代码。<br><br>doc：u-boot相关文档。<br><br><br>drivers：u-boot所支持的设备驱动代码, 网卡、支持CFI的Flash、串口和USB总线等。<br><br>fs: u-boot所支持支持文件系统访问存取代码， 如jffs2.<br><br>include：u-boot head文件，主要是与各种硬件平台相关的头文件，<br>如include/asm-arm/arch-at91rm9200/, include/asm-arm/proc-armv<br><br>net：与网络有关的代码，BOOTP协议、TFTP协议、RARP协议代码实现.<br><br>lib_arm：与arm体系相关的代码。(这里我们主要面向的是ARM体系，所以该目录是我们主要研究对象)<br><br>tools：编译后会生成mkimage工具，用来对生成的raw bin文件加入u-boot特定的image_header.<br><br>1.5 u-boot的功能介绍<br><br>　u-boot支持SCC/FEC以太网、OOTP/TFTP引导、IP和MAC的功能.<br>读写Flash、DOC、IDE、IIC、EEROM、RTC<br>支持串行口kermit和S-record下载代码, 并直接从串口下载并执行。<br><br>在我们生成的内核镜像时，要做如下处理.<br>1. arm-linux-objcopy -O binary -R.note -R.comment -S vmlinux linux.bin <br>2. gzip -9 linux.bin<br>3. mkimage -A arm -O linux -T kernel -C gzip -a 0xc0008000 -e 0xc0008000 -n <br>"Linux-2.4.19-rmk7&#8221; -d linux.bin.gz uImage<br><br>即在Linux内核镜像vmLinux前添加了一个特殊的头，这个头在include/image.h中定义，<br>typedef struct image_header <br>{<br>uint32_t ih_magic; /* Image Header Magic Number */<br>uint32_t ih_hcrc; /* Image Header CRC Checksum */<br>uint32_t ih_time; /* Image Creation Timestamp */<br>uint32_t ih_size; /* Image Data Size */<br>uint32_t ih_load; /* Data Load Address */<br>uint32_t ih_ep; /* Entry Point Address */<br>uint32_t ih_dcrc; /* Image Data CRC Checksum */<br>uint8_t ih_os; /* Operating System */<br>uint8_t ih_arch; /* CPU architecture */<br>uint8_t ih_type; /* Image Type */<br>uint8_t ih_comp; /* Compression Type */<br>uint8_t ih_name[IH_NMLEN]; /* Image Name */<br>} image_header_t;<br><br>当u-boot引导时会对这个文件头进行CRC校验，如果正确，才会跳到内核执行.<br><br>如果u-boot启动以后会出现<br>u-boot&gt;<br>敲入help, 会出现大量的命令提示，Monitor command<br>go - start application at address 'addr'<br>run - run commands in an environment variable<br>bootm - boot application image from memory<br>bootp - boot image via network using BootP/TFTP protocol<br>tftpboot- boot image via network using TFTP protocol<br>and env variables "ipaddr" and "serverip"<br>(and eventually "gatewayip")<br>rarpboot- boot image via network using RARP/TFTP protocol<br>diskboot- boot from IDE devicebootd - boot default, i.e., run 'bootcmd'<br>loads - load S-Record file over serial line<br>loadb - load binary file over serial line (kermit mode)<br>md - memory display<br>mm - memory modify (auto-incrementing)<br>nm - memory modify (constant address)<br>mw - memory write (fill) <br>cp - memory copy<br>cmp - memory compare<br>crc32 - checksum calculation<br>imd - i2c memory display<br>imm - i2c memory modify (auto-incrementing)<br>inm - i2c memory modify (constant address)<br>imw - i2c memory write (fill)<br>icrc32 - i2c checksum calculation<br>iprobe - probe to discover valid I2C chip addresses<br>iloop - infinite loop on address range<br>isdram - print SDRAM configuration information<br>sspi - SPI utility commands<br>base - print or set address offset<br>printenv- print environment variables<br>setenv - set environment variables<br>saveenv - save environment variables to persistent storage<br>protect - enable or disable FLASH write protection<br>erase - erase FLASH memory<br>flinfo - print FLASH memory information<br>bdinfo - print Board Info structure<br>iminfo - print header information for application image<br>coninfo - print console devices and informations<br>ide - IDE sub-system<br>loop - infinite loop on address range<br>mtest - simple RAM test<br>icache - enable or disable instruction cache<br>dcache - enable or disable data cache<br>reset - Perform RESET of the CPU<br>echo - echo args to console<br>version - print monitor version<br>help - print online help<br>? - alias for 'help'<br><br>u-boot支持大量的命令可用, 这里就不作介绍，大家有兴趣可以看看u-boot 的README文档<br>3.3 对u-boot-1.0.0的修改和移植<br><br>1.6 关于u-boot的移植如下，由于u-boot的软件设计体系非常清晰，它的移植工作并不复杂，<br>相信各位的代码阅读功力不错的话，参照如下就可以完成。<br><br>If the system board that you have is not listed, then you will need<br>to port U-Boot to your hardware platform. To do this, follow these<br>steps:<br><br>1. Add a new configuration option for your board to the toplevel<br>"Makefile" and to the "MAKEALL" script, using the existing<br>entries as examples. Note that here and at many other places<br>boards and other names are listed in alphabetical sort order. Please<br>keep this order.<br><br>2. Create a new directory to hold your board specific code. Add any<br>files you need. In your board directory, you will need at least<br>the "Makefile", a ".c", "flash.c" and "u-boot.lds".<br><br>3. Create a new configuration file "include/configs/.h" for<br>your board<br><br>4. If you're porting U-Boot to a new CPU, then also create a new<br>directory to hold your CPU specific code. Add any files you need.<br><br>5. Run "make _config" with your new name.<br><br>6. Type "make", and you should get a working "u-boot.srec" file<br><br>7. Debug and solve any problems that might arise.<br>[Of course, this last step is much harder than it sounds.]<br><br>为了使u-boot-1.0.0支持新的开发板，一种简便的做法是在u-boot已经支持的开发板中参考选择一种较接近板的进行修改,<br>幸运的是在u-boot-1.0.0中已经有了at91rm9200的支持。<br><br>1.7 与at91rm9200相关的u-boot代码<br><br>在include/configs/at91rm9200dk.h 它包括开发板的CPU、系统时钟、RAM、Flash系统及其它相关的配置信息。<br>在include/asm-arm/AT91RM9200.h, 该文件描述了H9200寄存器的结构及若干宏定义。<br>具体内容要参考相关处理器手册。<br>在cpu/at91rm9200/目录下别为cpu.c、interrupts.c和serial.c等文件.<br>在board/at91rm9200dk/目录下分别为flash.c、at91rm9200dk.c, config.mk, Makefile,u-boot.lds<br><br>flash.c : u-boot读、写和删除Flash设备的源代码文件。由于不同开发板中Flash存储器的种类各不相同，<br>所以，修改flash.c时需参考相应的Flash芯片手册。它包括如下几个函数：<br>unsigned long flash_init (void )，Flash初始化；<br>void flash_print_info (flash_info_t *info)，打印Flash信息；<br>int flash_erase (flash_info_t *info， int s_first， int s_last)，Flash擦除；<br>volatile static int write_dword (flash_info_t *info， ulong dest， ulong data)，Flash写入；<br>int write_buff (flash_info_t *info， uchar *src， ulong addr， ulong cnt)，从内存复制数据。<br><br>u-boot.lds :linker scripte, 设置u-boot中各个目标文件的连接地址.<br><br>网口设备控制程序<br><br>　　在drivers/目录中网口设备控制程序cs8900, bcm570x等, 还可以添加其他网卡驱动<br>int eth_init (bd_t *bd) : 初始化网络设备；<br>void eth_halt (void) : 关闭网络设备；<br>int eth_send (volatile void *packet，int len) : 发送数据包；<br>int eth_rx (void) : 接收数据包。<br><br>Makefile<br><br>　　在u-boot-1.0.0/Makefile中 <br>at91rm9200dk_config : unconfig<br>./mkconfig $(@:_config=) arm at91rm9200 at91rm9200dk<br><br>1.8 编译u-boot<br><br>　 make at91rm9200_config<br>Configuring for at91rm9200 board...<br>make all<br>生成三个文件：u-boot.bin, u-boot, u-boot.srec<br><br>u-boot.bin is a raw binary image<br>u-boot is an image in ELF binary format<br>u-boot.srec is in Motorola S-Record format (objcopy -O srec -R.note -R.comment -S [inputfile] [outfile]<br><br><br>以上工作完成我们可以通过串口将u-boot.bin下载到主板的SDRAM中，它会自动执行， 并出现uboot&gt;<br>这里我们可以通过串口把boot.bin, u-boot.bin.gz下载到主板，再用u-boot的提供的写flash功能分别<br>把boot.bin, u-boot.bin.gz写入到flash中，完成以上工作后，对主板跳线选择片外启动，<br>板子复位后会自动启动u-boot.<br><br><br><br><br>二.loader.bin, boot.bin, u-boot.bin代码执行流分析.<br><br>以上三个文件时at91rm9200启动所需要的三个bin,他们的实现代码并不难。<br>如果是你是采用at91rm9200的评估版，应该能得到其源码。<br><br>2.1 loader.bin 执行流程,这个文件主要在片内启动从串口下载代码时会用到<br>loader/entry.S init cpu<br>b main ---&gt; crt0.S<br>--&gt; copydata --&gt; clearbss --&gt; b boot<br>main.c --&gt; boot --&gt;<br>/*Get internel rom service address*/<br>/* Init of ROM services structure */ <br>pAT91 = AT91C_ROM_BOOT_ADDRESS;<br><br>/* Xmodem Initialization */<br>--&gt; pAT91-&gt;OpenSBuffer<br>--&gt; pAT91-&gt;OpenSvcXmodem<br>/* System Timer initialization */<br>---&gt; AT91F_AIC_ConfigureIt<br>/* Enable ST interrupt */<br>AT91F_AIC_EnableIt<br>AT91F_DBGU_Printk("XMODEM: Download U-BOOT ");<br><br>Jump.S<br>// Jump to Uboot BaseAddr exec<br>Jump((unsigned int)AT91C_UBOOT_BASE_ADDRESS) <br><br>2.2 boot.bin执行流程 该文件会在从片内启动时被下载到板子上，以后还会被烧写到片外Flash中，以便在片外启动时<br>用它来引导并解压u-boot.gz，并跳转到u-boot来执行。<br>boot/entry.S<br>b main --&gt; crt0.S --&gt; copydata --&gt; clearbss --&gt; b boot<br><br>T91F_DBGU_Printk(" ");<br>AT91F_DBGU_Printk("************************************** ");<br>AT91F_DBGU_Printk("** Welcome to at91rm9200 ** ");<br>AT91F_DBGU_Printk("************************************** ");<br><br>boot/misc.s /* unzip uboot.bin.gz */<br>----&gt; decompress_image(SRC,DST,LEN) --&gt; gunzip <br><br>//jump to ubootBaseAddr exec 这里跳转到解压u-boot.gz的地址处直接开始执行u-boot<br>asm("mov pc,%0" : : "r" (DST));<br><br>2.3 uboot.bin执行流程<br>u-boot/cpu/at91rm9200/start.S <br>start ---&gt;reset <br>---&gt; copyex ---&gt; cpu_init_crit <br>---&gt; /* set up the stack */ --&gt; start_armboot<br>u-boot/lib_arm/board.c<br><br>init_fnc_t *init_sequence[] = {<br>cpu_init, /* basic cpu dependent setup */<br>board_init, /* basic board dependent setup */<br>interrupt_init, /* set up exceptions */<br>env_init, /* initialize environment */<br>init_baudrate, /* initialze baudrate settings */<br>serial_init, /* serial communications setup */<br>console_init_f, /* stage 1 init of console */<br>display_banner, /* say that we are here */<br>dram_init, /* configure available RAM banks */<br>display_dram_config,<br>checkboard,<br>NULL,<br>};<br><br>---&gt; start_armboot ---&gt; call init_sequence<br>---&gt; flash_init --&gt; display_flash_config <br>---&gt; nand_init ---&gt; AT91F_DataflashInit <br>---&gt; dataflash_print_info --&gt; env_relocate<br>---&gt; drv_vfd_init --&gt; devices_init --&gt; jumptable_init<br>---&gt; console_init_r --&gt; misc_init_r --&gt; enable_interrupts<br>---&gt; cs8900_get_enetaddr --&gt; board_post_init --&gt; <br><br>u-boot/common/main.c<br>for (;;) <br>{ /* shell parser */<br>main_loop () --&gt; u_boot_hush_start --&gt; readline<br>--&gt; abortboot <br>--&gt;printf("Hit any key to stop autoboot: %2d ", bootdelay);<br>}<br><br>以上是at91rm9200启动并进入u-boot的执行流分析。后面u-boot还会将uImage解压到特定的位置并开始执行内核代码。<br><br>三. 综述<br>总之, 不同厂商的出的Soc片子在启动方式大都提供片内和片外启动两种方式，一般都是在片内固化一段小程序<br>方便于程序开发而已，在其DataSheet文档中有详尽的描述。若是对at92rm9200有兴趣或玩过的朋友，可以与我共同探讨相互学习。</p>
<img src ="http://www.cnitblog.com/zouzheng/aggbug/5803.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/zouzheng/" target="_blank">zz</a> 2005-12-26 19:59 <a href="http://www.cnitblog.com/zouzheng/articles/5803.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>