<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
 <channel>
  <title>Redboot专栏</title>
  <link>http://redboot.blogbus.com</link>
  <description><![CDATA[redboot，ecos及嵌入式开发]]></description>
  <generator> by blogbus.com </generator>
  <lastBuildDate>Tue, 22 Dec 2009 11:13:34 +0800</lastBuildDate>
  <image>
									<url>http://public.blogbus.com/profile/1/1/6/4285611/avatar_4285611_96.jpg</url>
									<title>Redboot专栏</title>
									<link>http://redboot.blogbus.com</link>
								</image>  <item>
   <title>linux netfilter 简要说明</title>
   <description><![CDATA[<p>最近，有一个任务，需要用到linux netfilter。时间很紧，只有1个星期搞这个事情。</p>
<p>以前从来没有看过netfilter的代码。只是在几年前，曾经有个同事做过一个关于iptable的ppt。</p>
<p>当时，也没有搞明白，只是觉得iptable的命令繁杂的很。</p>
<p>现在，只给我这么短的时间，让我搞这个，感觉真是叫赶鸭子上架。</p>
<p>没办法，只能硬着头皮做起来。不过，动起手来发现 其实没有想象那么困难。</p>
<p>netfilter部分的代码，结构还是蛮清晰的。</p>
<p>&nbsp;</p>
<p>一般来讲，我们用netfilter做两部分的工作，一个是 filter 一个是NAT。</p>
<p>filter 就是根据包的规则做过滤，像防火墙啦，负载或者流量控制啦。</p>
<p>NAT 就是地址转换。（实际上NAT是属于netfilter下面的 conntrack模块的一部分，但是NAT更有名一些啦）</p>
<p>&nbsp;</p>
<p>netfilter做这个工作的方法就是在 5个点加钩子函数，于是，我们会看到每次提到netfilter都会看到的一幅图：</p>
<p>
<a title="netfilter by andrew_tshi, on Flickr" href="http://www.flickr.com/photos/65753396@N00/4191752808/"><img src="http://farm3.static.flickr.com/2583/4191752808_55754aefb8.jpg" alt="netfilter" width="500" height="246" /></a></p>
<p>&nbsp;</p>
<p>5个点分别是：</p>
<p>LOCAL_IN</p>
<p>LOCAL_OUT</p>
<p>PRE_ROUTING</p>
<p>FORWARD</p>
<p>POST_ROUTING</p>
<p>&nbsp;</p>
<p>通过函数 nf_register_hook 就可以把注册一个处理函数到这5个点上的其中一个。</p>
<p>&nbsp;</p>
<p>nf_register_hook函数的参数是这样一个结构：</p>
<p>struct nf_hook_ops</p>
<p>{</p>
<p><span style="white-space: pre;">	</span>struct list_head list; &nbsp;//将该结构插入到一个双向链表中</p>
<p><span style="white-space: pre;">	</span>nf_hookfn *hook; //钩子函数</p>
<p><span style="white-space: pre;">	</span>struct module *owner;</p>
<p><span style="white-space: pre;">	</span>int pf;</p>
<p><span style="white-space: pre;">	</span>int hooknum; &nbsp; //代表插入到上述5个点的哪一个</p>
<p><span style="white-space: pre;">	</span>int priority; &nbsp;//优先级，插入到什么位置</p>
<p>};</p>
<p>&nbsp;</p>
<p>优先级是这么定义的</p>
<p>&nbsp;</p>
<p>enum nf_ip_hook_priorities {</p>
<p><span style="white-space: pre;">	</span>NF_IP_PRI_FIRST = INT_MIN,</p>
<p><span style="white-space: pre;">	</span>NF_IP_PRI_CONNTRACK_DEFRAG = -400,</p>
<p><span style="white-space: pre;">	</span>NF_IP_PRI_RAW = -300,</p>
<p><span style="white-space: pre;">	</span>NF_IP_PRI_SELINUX_FIRST = -225,</p>
<p><span style="white-space: pre;">	</span>NF_IP_PRI_CONNTRACK = -200,</p>
<p><span style="white-space: pre;">	</span>NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD = -175,</p>
<p><span style="white-space: pre;">	</span>NF_IP_PRI_MANGLE = -150,</p>
<p><span style="white-space: pre;">	</span>NF_IP_PRI_NAT_DST = -100,</p>
<p><span style="white-space: pre;">	</span>NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT = -50,</p>
<p><span style="white-space: pre;">	</span>NF_IP_PRI_FILTER = 0,</p>
<p><span style="white-space: pre;">	</span>NF_IP_PRI_NAT_SRC = 100,</p>
<p><span style="white-space: pre;">	</span>NF_IP_PRI_SELINUX_LAST = 225,</p>
<p><span style="white-space: pre;">	</span>NF_IP_PRI_CONNTRACK_HELPER = INT_MAX - 2,</p>
<p><span style="white-space: pre;">	</span>NF_IP_PRI_NAT_SEQ_ADJUST = INT_MAX - 1,</p>
<p><span style="white-space: pre;">	</span>NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX,</p>
<p><span style="white-space: pre;">	</span>NF_IP_PRI_LAST = INT_MAX,</p>
<p>};</p>
<p>&nbsp;</p>
<p>当每次调用 nf_register_hook 注册一个 nf_hook_ops 到一个点（hooknum）上，</p>
<p>每个点都是一个双向链表，nf_register_hook会把nf_hook_ops 按照优先级</p>
<p>插入到相应的位置上。所以，在iptable里面把这5个点 叫做5个chain。</p>
<p>&nbsp;</p>
<p>在filter，mangle 和nat中， nf_hook_ops里面的钩子函数, 又会去调用一个函数 ipt_do_table</p>
<p>相应的table里面包含很多规则，所以，将之称为table。</p>
<p>&nbsp;</p>
<p>chain和table这两个名词，在我看iptable的时候，一度搞晕了。</p>
<p>其实看看源码就知道怎么回事了，非常清晰。</p>
<p>&nbsp;</p>
<p>每个hook函数返回值为：</p>
<p>&nbsp;</p>
<p>NF_ACCEPT: 继续按正常的协议栈流程处理。</p>
<p>NF_DROP: 丢弃包，中止协议栈的流程。</p>
<p>NF_STOLEN: 这个包已被缓存，中止协议栈的流程。</p>
<p>NF_QUEUE: 把包放到队列中(通常会把包转发到用户空间处理)。</p>
<p>NF_REPEAT: 再此调用这个钩子函数。</p>
<p>&nbsp;</p>
<p>另外，要注意一个是 抛开mangle的部分不说，其实每条包的经过路径都是这样一个过程：</p>
<p>&nbsp;</p>
<p>CONNTRACK -&gt; DNAT -&gt; FILTER -&gt; SNAT -&gt; CONNTRACK</p>
<p>&nbsp;</p>
<p>上面是 netfilter总体结构的一个介绍，下次会重点介绍一下 conntrack部分</p>
<p>&nbsp;</p>
<p>因为时间仓促可能有的东西理解的不正确，如果高手看到请指正，谢谢。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="/logs/39116533.html">发现一个不错的东西：protothreads</a> 2009-05-09</div><div><a href="/logs/22987104.html">Redboot 设备初始化说明</a> 2008-06-15</div><div><a href="/logs/22329480.html">Redboot（i386）启动流程（四）</a> 2008-06-05</div><div><a href="/logs/21382467.html">Redboot（i386）启动流程（三）</a> 2008-05-22</div><div><a href="/logs/21317838.html">Redboot（i386）启动流程（二）</a> 2008-05-21</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fredboot.blogbus.com%2Flogs%2F54060286.html&title=linux+netfilter+%E7%AE%80%E8%A6%81%E8%AF%B4%E6%98%8E">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://pindao.blogbus.com/sejie?utm_source=blogbus&utm_medium=rss&utm_campaign=sejie" target="_blank">色界频道——这里有顶尖的摄影大师，也有摄影爱好者，他们用相机收纳大千世界。</a></b></div><br /><br />]]></description>
   <link>http://redboot.blogbus.com/logs/54060286.html</link>
   <author>redboot</author>
   <pubDate>Thu, 17 Dec 2009 10:12:33 +0800</pubDate>
  </item>
  <item>
   <title>新建menuconfig项目</title>
   <description><![CDATA[<p>最近，搞一个项目，想加入类似 linux kernel中的menuconfig的功能，进行项目配置管理。</p>
<p>于是，看了看相关代码。</p>
<p>不过，一直没有找到 独立的项目，只得从 busybox 项目中， 把menuconfig的部分分离出来。</p>
<p>形成一个独立的小项目，以便移植到其他需要类似功能的项目中去。</p>
<p>有兴趣的朋友可以从 google code 的<a href="http://code.google.com/p/menuconfig/source/checkout" target="_blank">svn</a>上 下载。</p>
<p>这是一个非常简单的menuconfig示例。</p>
<p>只需要执行 make menuconfig</p>
<p>进入菜单，选择相关项目，保存，就会输出两个项目：</p>
<p>.config 这个文件通常可以用于MAKEFILE处理用。</p>
<p>include/autoconf.h 这个可以直接在 c 代码里面使用。</p>
<p>&nbsp;</p>
<p>理论上，这个配置还支持</p>
<p>make xconfig</p>
<p>make config</p>
<p>make gconfig</p>
<p>make oldconfig</p>
<p>make defconfig</p>
<p>等等，不过，我没有测试过。</p>
<p>回头我会简单介绍一下，代码的处理过程，和脚本的语法。</p>
<p>谢谢关注</p>
<p>&nbsp;</p>
<p>&nbsp;</p><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="/logs/54060286.html">linux netfilter 简要说明</a> 2009-12-17</div><div><a href="/logs/34859828.html">u-boot 启动流程二（mips）</a> 2009-02-09</div><div><a href="/logs/23055879.html">Redboot 的链接脚本</a> 2008-06-16</div><div><a href="/logs/20234712.html">CPU学习</a> 2008-05-04</div><div><a href="/logs/19874250.html">eCos编译配置说明</a> 2008-04-27</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fredboot.blogbus.com%2Flogs%2F43629854.html&title=%E6%96%B0%E5%BB%BAmenuconfig%E9%A1%B9%E7%9B%AE">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://tuijian.blogbus.com/" target="_blank">推荐：让我们寻找最优秀的Blogger！</a></b></div><br /><br />]]></description>
   <link>http://redboot.blogbus.com/logs/43629854.html</link>
   <author>redboot</author>
   <pubDate>Thu, 06 Aug 2009 16:40:37 +0800</pubDate>
  </item>
  <item>
   <title>发现一个不错的东西：protothreads</title>
   <description><![CDATA[<p>最近在porting <a href="http://www.sics.se/~adam/uip/" target="_blank">uIP</a>，就顺便读了下uIP的代码。</p>
<p>意外发现一个比较好玩的东西 <a href="http://www.sics.se/~adam/pt/" target="_blank">Protothreads</a></p>
<p>这是个什么东西呢？</p>
<p>文档上说，这是一个极轻量级的无栈线程库。</p>
<p>简单的说，就是在一个死循环 while(1){} 里面跑多个线程，但是，又不必为每个线程都分配一个栈。</p>
<p>因为为每个线程都分配一个栈空间还要分配一个数据结构，太耗费内存了。</p>
<p>所以，它特别适合在内存受限的嵌入式系统里面用。</p>
<p>比如，一个小嵌入式系统，要支持网络协议，还要支持客户的命令，而根本就没有一个操作系统。</p>
<p>你就可以用 Protothreads 来做一个简单的线程调度。</p>
<p>就好像有了个小操作系统。而其代价又是如此之小。不单没有什么调度算法的cpu开销。</p>
<p>内存方面为每个线程也只需要多花两个字节。</p>
<p>还支持信号量操作，而且不用汇编，只用c语言和一些宏定义。</p>
<p>哇，简直太幸福啦！</p>
<p>这么酷的玩意是怎么搞的呢？</p>
<p>其实，说起来也不麻烦，他提供了一些宏，我读了一些，展开来大致就相当于下面这种形式：</p>
<p>while(1){</p>
<p>switch(s) { </p>
<p>case 0:...</p>
<p>case x:...</p>
<p>case y: ...</p>
<p>}</p>
<p>}</p>
<p>从下面几个宏的定义就能看出来了：</p>
<p>#define &nbsp;&nbsp;&nbsp; LC_INIT(s)&nbsp;&nbsp; s = 0;<br />#define &nbsp;&nbsp;&nbsp; LC_RESUME(s)&nbsp;&nbsp; switch(s) { case 0:<br />#define &nbsp;&nbsp;&nbsp; LC_SET(s)&nbsp;&nbsp; s = __LINE__; case __LINE__:<br />#define &nbsp;&nbsp;&nbsp; LC_END(s)&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; </p>
<p>&nbsp;</p>
<p>不过，这样做显然也是有一些代价的，</p>
<p>第一，使用局部变量要极为小心，（文档建议不要用）</p>
<p>很简单，没有栈啊，局部变量放哪里（这个解释不严密，具体看看实现就清楚了）？</p>
<p>第二，当调用函数时，没多调用一层就要多加一个变量，记录执行到这个函数的位置。</p>
<p>以便下次进入时，能找到合适的位置。</p>
<p>&nbsp;</p>
<p>不过，不管怎么讲，这还是很好玩的一个&ldquo;线程&rdquo;库，如果手上碰巧碰到一个内存极少的硬件可以用下。</p>
<p>&nbsp;</p><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="/logs/54060286.html">linux netfilter 简要说明</a> 2009-12-17</div><div><a href="/logs/35085538.html">u-boot命令配置</a> 2009-02-12</div><div><a href="/logs/22987104.html">Redboot 设备初始化说明</a> 2008-06-15</div><div><a href="/logs/21382467.html">Redboot（i386）启动流程（三）</a> 2008-05-22</div><div><a href="/logs/21317838.html">Redboot（i386）启动流程（二）</a> 2008-05-21</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fredboot.blogbus.com%2Flogs%2F39116533.html&title=%E5%8F%91%E7%8E%B0%E4%B8%80%E4%B8%AA%E4%B8%8D%E9%94%99%E7%9A%84%E4%B8%9C%E8%A5%BF%EF%BC%9Aprotothreads">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://icity.cn" target="_blank">《城客》：第一本中文互动杂志！</a></b></div><br /><br />]]></description>
   <link>http://redboot.blogbus.com/logs/39116533.html</link>
   <author>redboot</author>
   <pubDate>Sat, 09 May 2009 00:41:35 +0800</pubDate>
  </item>
  <item>
   <title>dlmalloc in u-boot （3） 流程</title>
   <description><![CDATA[<p><a href="http://redboot.blogbus.com/logs/38352001.html" target="_blank">接上篇</a><br />最后大致讲一下处理流程，主要讲几个函数 malloc， free 和 malloc_extend_top。<br /><br />- malloc<br />当申请内存的时候就调用 Void_t* malloc(size_t bytes)<br /><br />malloc函数首先根据申请内存的大小计算实际需要的内存，因为malloc_chunk本身需要一些内存，还有8字节对齐的pad部分。如果实际需要的内存小于512byte就直接在相应的bin中寻找是否有空余的内存，如果没有可以再到下一个bin中寻找（这个个bin分配到的内存要多8byte。）</p>
<p>如果需要内存不小于512就要根据相应算法找到所需的bin。查找空闲内存块。因为这里的内存块大小并不相同，所以要比较大小。如果大于所需内存太多（多过一个最小块的大小）就不能用了。</p>
<p><br />如果上面步骤没有找到内存，就到last_remainder里面去找，如果last_remainder里面的够大。就在上面分配。<br />如果还没有找到就全局搜索，寻找 best fitting chunk。这时还没有找到的话，就在top上面分配，如果top上面的大小不够，则调用malloc_extend_top函数向系统申请更多的内存扩充top。如果还申请不到足够的内存，就只能返回空指针了。<br /><br />- free<br />free的算法比较简单，当free一块内存时，就把这个malloc_chunk块挂到相应的bin中，不过在挂之前，要先看看邻接的内存块是否空闲，如果空闲则正好合并成大块，这样可以减少内存碎片的问题。<br />另外，如果当前释放的内存被合并到top上面，会检查一下top有多大，如果非常大了（uboot定义为128k），就通过函数malloc_trim还给系统。<br /><br />- malloc_extend_top</p>
<p>malloc本身并没有内存，所有的内存都是通过malloc_extend_top函数分配给top, 然后再给malloc函数去分配的。所以，本身malloc_extend_top函数很简单，不过要注意几个事情，一个是向内存申请通常是以一页（4k)为单位申请；另外，每次向系统申请的内存通常来说应当连续，如果不连续说明还有别的程序再想系统申请内存，这时不能把分到的内存直接扩充到top上。</p>
<p>&nbsp;</p>
<p>好了，最近看的dlmalloc的部分基本上写完了。</p>
<p>其实，代码本身比较细，很多东西一下子看不清楚，所以难免有理解错的地方。</p>
<p>写下来有个好处，回头如果需要不必重新看起。</p>
<p>读了dlmalloc后，自己在其基础上面写了个非常简单的malloc。</p>
<p>实现一个简单的malloc功能：</p>
<p>只有一个链表，所有free的内存块都挂在上面，</p>
<p>分配的时候，先从这个链表里面找 first-fit，就是只要够大就用，如果非常大就分割一下。</p>
<p>如果链表不够，就调用malloc_extend_top申请新内存。</p>
<p>跑了一下感觉还不错，其实在uboot这种简单应用场景下面这样简单的东西也够用啦。</p>
<p>&nbsp;</p><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="http://redboot.blogbus.com/logs/38352001.html">dlmalloc in u-boot （2） 数据结构</a> 2009-04-23</div><div><a href="http://redboot.blogbus.com/logs/38339807.html">dlmalloc in u-boot （1） 简介</a> 2009-04-22</div><div><a href="http://redboot.blogbus.com/logs/35092680.html">u-boot移植</a> 2009-02-12</div><div><a href="http://redboot.blogbus.com/logs/35085538.html">u-boot命令配置</a> 2009-02-12</div><div><a href="http://redboot.blogbus.com/logs/34991963.html">u-boot编译过程二</a> 2009-02-11</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fredboot.blogbus.com%2Flogs%2F38382371.html&title=dlmalloc+in+u-boot+%EF%BC%883%EF%BC%89+%E6%B5%81%E7%A8%8B">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://pindao.blogbus.com/sejie?utm_source=blogbus&utm_medium=rss&utm_campaign=sejie" target="_blank">色界频道——这里有顶尖的摄影大师，也有摄影爱好者，他们用相机收纳大千世界。</a></b></div><br /><br />]]></description>
   <link>http://redboot.blogbus.com/logs/38382371.html</link>
   <author>redboot</author>
   <pubDate>Thu, 23 Apr 2009 17:36:04 +0800</pubDate>
  </item>
  <item>
   <title>dlmalloc in u-boot （2） 数据结构</title>
   <description><![CDATA[<p><a href="http://redboot.blogbus.com/logs/38339807.html" target="_blank">接上篇</a></p>
<p>dlmalloc有两个重要的数据结构，一个是 chunk, 另一个是bin。<br /><br />chunk就是分配内存的数据块，定义如下：<br />struct malloc_chunk<br />{<br />&nbsp; INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */<br />&nbsp; INTERNAL_SIZE_T size;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Size in bytes, including overhead. */<br />&nbsp; struct malloc_chunk* fd;&nbsp;&nbsp; /* double links -- used only if free. */<br />&nbsp; struct malloc_chunk* bk;<br />};<br />这是malloc_chunk的数据结构，不过要注意，一块malloc_chunk可不是只有这么大。<br />一块malloc_chunk的大小是8byte的倍数。<br />举个例子：<br />如果申请一块4byte的内存，只是实际会分配出16byte。<br />其中，头8byte存放 prev_size和size，然后是4个byte的内存，最后还有4个byte是为了8byte对其的pad。<br />如下图：<br /><br />=================<br />&nbsp;&nbsp; prev_size [4byte]<br />&nbsp;&nbsp; size&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; [4byte]<br />&nbsp; -------------------<br />&nbsp;&nbsp; data&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [4byte]<br />&nbsp; -------------------<br />&nbsp;&nbsp; pad&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; [4byte]<br />=================<br /><br />这样我们可以看到，fd和bk在分配出去的时候并不存在，只是在空闲时可用，构成一个双向链表。<br />当malloc_chunk被free时，就会插入一个双向链表中，留作以后分配，用得就是fd和bk。<br /><br />而prev_size和size还有一个用处，就是通过这两个元素，可以找到与当前malloc_chunk块相邻的<br />的malloc_chunk块。<br />比如：有指针p指向一个malloc_chunk块： struct malloc_chunk * p = ...<br />这是通过 (struct malloc_chunk *)((char*)(p) + p-&gt;size) 和<br />(struct malloc_chunk *)((char*)(p) - p-&gt;prev_size) <br />就可以找到相邻内存。<br />这在合并内存的时候非常有用。<br /><br />另外，要注意的是 size的最低一位是标记是否被用的状态。<br />因为malloc_chunk的大小是8byte的倍数。所以，低3位都为零，于是最低一位就当作一个标记位。<br />标记是否被分配。不过，奇怪的是，这个标记是将相邻前一块是否被用 （PREV_INUSE）而不是当前块。<br />这点一直让我蛮费解的。</p>
<p>关于chunk，这里<a href="http://www.vtzone.org/discuz/viewthread.php?tid=36&amp;extra=page%3D2" target="_blank">一篇文章</a>介绍的蛮详细的，还有些配图，很不错。</p>
<p>www.vtzone.org里面还有挺多介绍dlmalloc和内存管理方面的文章，值得读读。<br /><br />chunk介绍完，就该介绍bin了。<br />所谓的bin其实就是一些双向链表，在初始化的时候，申请了128个双向链表。用以存放空闲的malloc_chunk。<br />这样，就可以快速的寻找的所需要的malloc_chunk。其中，前64个bin存放的是固定尺寸<br />（16byte-512byte以8byte递增）<br />的malloc_chunk。之后，有相应的映射算法。这是因为小于512byte的分配更频繁，这样做会有更好的效率。<br />在分配时，以最小块优先，最佳适合的顺序搜索可用的块。<br /><br />其中注意两个特殊的bin是top和last_remainder。<br />top存放的是最新从系统获得到的内存，分配时先在其他链表中寻找，如果都没有才在top上面分配，<br />如果top的内存也不够分了，就从系统申请新的内存，还是放在top上面供分配。<br /><br />last_remainder是指上次被切分的malloc_chunk，这大概是根据局部化特性，来提高分配的效率。</p>
<p>这样数据结构就大致介绍这么多，<a href="http://redboot.blogbus.com/logs/38382371.html" target="_blank">下一篇讲讲处理流程</a></p><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="http://redboot.blogbus.com/logs/38382371.html">dlmalloc in u-boot （3） 流程</a> 2009-04-23</div><div><a href="http://redboot.blogbus.com/logs/38339807.html">dlmalloc in u-boot （1） 简介</a> 2009-04-22</div><div><a href="http://redboot.blogbus.com/logs/35092680.html">u-boot移植</a> 2009-02-12</div><div><a href="http://redboot.blogbus.com/logs/35085538.html">u-boot命令配置</a> 2009-02-12</div><div><a href="http://redboot.blogbus.com/logs/34991963.html">u-boot编译过程二</a> 2009-02-11</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fredboot.blogbus.com%2Flogs%2F38352001.html&title=dlmalloc+in+u-boot+%EF%BC%882%EF%BC%89+%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://pindao.blogbus.com/sejie?utm_source=blogbus&utm_medium=rss&utm_campaign=sejie" target="_blank">色界频道——这里有顶尖的摄影大师，也有摄影爱好者，他们用相机收纳大千世界。</a></b></div><br /><br />]]></description>
   <link>http://redboot.blogbus.com/logs/38352001.html</link>
   <author>redboot</author>
   <pubDate>Thu, 23 Apr 2009 10:02:57 +0800</pubDate>
  </item>
  <item>
   <title>dlmalloc in u-boot （1） 简介</title>
   <description><![CDATA[<p>最近，又有关于uboot的项目，于是读了malloc部分的代码。uboot上的malloc是用的dl malloc，这是由Doug Lea写的一个malloc版本。据说，linux上用的就是它。看网上<a href="http://oiramario.cnblogs.com/archive/2006/01/10/314634.html" target="_blank">有人测试</a>，效率蛮不错的。</p>
<p>这是作者写的<a href="http://www.nondot.org/sabre/os/files/MemManagement/LEA.html" target="_blank">说明</a> (<a href="http://www.yeeyan.com/articles/view/25646/6380" target="_blank">中文</a>)</p>
<p>u-boot用dlmalloc的版本是 2.6.6，应该算是比较老的吧，最新的是2.8.3。不过，对于u-boot来讲已经足够了。本身没有多少内存好分配的。也用不到mmap。</p>
<p>对于u-boot来说，就是先设定一块内存空间留给malloc分配。malloc分配时，先回寻找当前空闲的块。如果找不到就通过函数malloc_extend_top调用一个宏：MORECORE(直接调用sbrk函数，sbrk函数是unix的标准函数，在uboot里面自己写了一个非常简单的sbrk)，从系统（就是uboot了）申请一块内存。这时，uboot就从前面预留的内存空间中分配一块给malloc。</p>
<p>free的部分比较简单，当一块内存free的时候，先看看能不能跟前后空闲的内存块一起合并，这样就能避免内存的碎片问题。然后，把释放的内存按照大小插入的相应的链表中，以供下次分配用。</p>
<p>代码虽然不算很多，但是却挺不容易读懂的。<br />努力读了读，大致明白了基本的流程。</p>
<p>打算分几次记录一下。</p>
<p><a href="http://redboot.blogbus.com/logs/38352001.html" target="_blank">下一篇</a></p><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="http://redboot.blogbus.com/logs/38382371.html">dlmalloc in u-boot （3） 流程</a> 2009-04-23</div><div><a href="http://redboot.blogbus.com/logs/38352001.html">dlmalloc in u-boot （2） 数据结构</a> 2009-04-23</div><div><a href="http://redboot.blogbus.com/logs/35092680.html">u-boot移植</a> 2009-02-12</div><div><a href="http://redboot.blogbus.com/logs/35085538.html">u-boot命令配置</a> 2009-02-12</div><div><a href="http://redboot.blogbus.com/logs/34991963.html">u-boot编译过程二</a> 2009-02-11</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fredboot.blogbus.com%2Flogs%2F38339807.html&title=dlmalloc+in+u-boot+%EF%BC%881%EF%BC%89+%E7%AE%80%E4%BB%8B">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://pindao.blogbus.com/shenghuo?utm_source=blogbus&utm_medium=rss&utm_campaign=shenghuo" target="_blank">生活频道——笑谈生活，坐看人生，这里有着小人物的健康生活。</a></b></div><br /><br />]]></description>
   <link>http://redboot.blogbus.com/logs/38339807.html</link>
   <author>redboot</author>
   <pubDate>Wed, 22 Apr 2009 22:37:50 +0800</pubDate>
  </item>
  <item>
   <title>u-boot移植</title>
   <description><![CDATA[<p>当我们有一个新的硬件 希望porting uboot要做哪些工作呢？<br /><br />首先，代码部分要做以下工作：<br />lowlevel_init.S 主要是配置频率，硬件间差别较大（频率值和寄存器配置方式都会不同）通常都要根据实际情况进行设置。</p>
<p>start.S， cache.S 两个文件基本可以参照现有文件，进行相应修改。<br /><br />另外，配置ddr controller, flash初始化，串口都是必要工作。<br /><br />还有就是pci和网口的驱动代码，还有环境变量的访问。<br /><br />配置方面：<br />&nbsp; 要添加相应硬件的头文件xxx.h在 include/configs目录下， 该文件内容比较多，尽量参照意义已有类似硬件的模板。<br />&nbsp; <br />Makefile中加入编译目标：<br />&nbsp; xxx_config&nbsp;&nbsp;&nbsp; :&nbsp;&nbsp;&nbsp; unconfig<br />&nbsp;&nbsp;&nbsp; @$(MKCONFIG) $(@:_config=) ARCH CPU BOARD VENDOR SOC <br /><br />目录组织与硬件配置的关系可以参考如下：<br />&nbsp;&nbsp;&nbsp; <br />header_file&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ARCH&nbsp;&nbsp;&nbsp; CPU&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; BOARD&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; VENDOR&nbsp;&nbsp;&nbsp; SOC<br />smdk2410 &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; arm &nbsp;&nbsp;&nbsp; arm920t &nbsp;&nbsp;&nbsp; smdk2410 &nbsp;&nbsp;&nbsp; NULL &nbsp;&nbsp;&nbsp; s3c24x0<br /><br />LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).a<br />board/smdk2410/libsmdk2410.a<br /><br />LIBS += cpu/$(CPU)/lib$(CPU).a<br />cpu/arm920t/libarm920t.a <br /><br />LIBS += cpu/$(CPU)/$(SOC)/lib$(SOC).a<br />cpu/arm920t/s3c24x0/libs3c24x0.a <br /><br />LIBS += lib_$(ARCH)/lib$(ARCH).a<br />lib_arm/libarm.a <br /><br /></p><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="http://redboot.blogbus.com/logs/38382371.html">dlmalloc in u-boot （3） 流程</a> 2009-04-23</div><div><a href="http://redboot.blogbus.com/logs/38352001.html">dlmalloc in u-boot （2） 数据结构</a> 2009-04-23</div><div><a href="http://redboot.blogbus.com/logs/38339807.html">dlmalloc in u-boot （1） 简介</a> 2009-04-22</div><div><a href="http://redboot.blogbus.com/logs/35085538.html">u-boot命令配置</a> 2009-02-12</div><div><a href="http://redboot.blogbus.com/logs/34991963.html">u-boot编译过程二</a> 2009-02-11</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fredboot.blogbus.com%2Flogs%2F35092680.html&title=u-boot%E7%A7%BB%E6%A4%8D">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://pindao.blogbus.com/sejie?utm_source=blogbus&utm_medium=rss&utm_campaign=sejie" target="_blank">色界频道——这里有顶尖的摄影大师，也有摄影爱好者，他们用相机收纳大千世界。</a></b></div><br /><br />]]></description>
   <link>http://redboot.blogbus.com/logs/35092680.html</link>
   <author>redboot</author>
   <pubDate>Thu, 12 Feb 2009 14:40:43 +0800</pubDate>
  </item>
  <item>
   <title>u-boot命令配置</title>
   <description><![CDATA[<p><br />u-boot启动后，进入命令模式，通过输入uboot提供的命令来进行交互操作。一些相关命令的用法已经在<a href="http://redboot.blogbus.com/logs/34921403.html">前面文章</a>介绍，这里介绍一下uboot命令内部结构，并了解如何配置uboot的命令，以及可以自己添加一些命令。<br /><br />如何实现一个命令，看下面一个简单的例子，就明白了。<br /><br />uboot命令的数据结构定义：<br /><br />struct cmd_tbl_t {<br />&nbsp;&nbsp;&nbsp; char&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; *name;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Command Name&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; */<br />&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; maxargs;&nbsp;&nbsp;&nbsp; /* maximum number of arguments&nbsp;&nbsp;&nbsp; */<br />&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; repeatable;&nbsp;&nbsp;&nbsp; /* autorepeat allowed?&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; */<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Implementation function&nbsp;&nbsp;&nbsp; */<br />&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (*cmd)(struct cmd_tbl_s *, int, int, char *[]);<br />&nbsp;&nbsp;&nbsp; char&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; *usage;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Usage message&nbsp;&nbsp;&nbsp; (short)&nbsp;&nbsp;&nbsp; */<br />&nbsp;&nbsp;&nbsp; char&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; *help;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Help&nbsp; message&nbsp;&nbsp;&nbsp; (long)&nbsp;&nbsp;&nbsp; */<br /><br />};<br /><br />声明命令的宏定义：<br /><br />#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \<br />cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}<br /><br /><br />声明一个命令：<br /><br />U_BOOT_CMD(<br />&nbsp;&nbsp;&nbsp; exit,&nbsp;&nbsp;&nbsp; 2,&nbsp;&nbsp;&nbsp; 1,&nbsp;&nbsp;&nbsp; do_exit,<br />&nbsp;&nbsp;&nbsp;&nbsp; "exit&nbsp;&nbsp;&nbsp; - exit script\n",<br />&nbsp;&nbsp;&nbsp; "&nbsp;&nbsp;&nbsp; - exit functionality\n"<br />);<br /><br />命令的具体实现：<br /><br />int<br />do_exit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])<br />{<br />&nbsp;&nbsp;&nbsp; int r;<br /><br />&nbsp;&nbsp;&nbsp; r = 0;<br />&nbsp;&nbsp;&nbsp; if (argc &gt; 1)<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; r = simple_strtoul(argv[1], NULL, 10);<br /><br />&nbsp;&nbsp;&nbsp; return -r - 2;<br />}<br /><br />这样，就实现了一个命令 &ldquo;exit&rdquo; 。</p>
<p>如果，我们需要自己添加一个新命令，只要有实现函数 do_xxx，和命令声明U_BOOT_CMD(xxx, ...) 就可以了。<br /><br />下面，我们介绍一下命令的配置方式。注意：最新的uboot命令配置方法发生变化，与以前不同。<br /><br />首先，在头文件 smdk2410.h (该文件前面文章有介绍) 包含了所需的命令头文件<br />#include &lt;config_cmd_default.h&gt;</p>
<p><br />在 config_cmd_default.h 中定义了，所需要用到的命令，如：<br />#define CONFIG_CMD_MEMORY&nbsp;&nbsp;&nbsp; /* md mm nm mw cp cmp crc base loop mtest */<br />（所以，autoconf.mk里，就会有 CONFIG_CMD_MEMORY=y ）<br /><br />而在common/Makefile 下，有这样的定义：<br />COBJS-$(CONFIG_CMD_MEMORY) += cmd_mem.o<br /><br />这样，当config_cmd_default.h里有了相应定义，就会把相应实现进行编译。<br />就可以获得相关命令的支持了。</p>
<p>&nbsp;</p>
<p>&nbsp;</p><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="http://redboot.blogbus.com/logs/34991963.html">u-boot编译过程二</a> 2009-02-11</div><div><a href="http://redboot.blogbus.com/logs/34986179.html">u-boot编译过程一</a> 2009-02-11</div><div><a href="http://redboot.blogbus.com/logs/38382371.html">dlmalloc in u-boot （3） 流程</a> 2009-04-23</div><div><a href="http://redboot.blogbus.com/logs/38352001.html">dlmalloc in u-boot （2） 数据结构</a> 2009-04-23</div><div><a href="http://redboot.blogbus.com/logs/38339807.html">dlmalloc in u-boot （1） 简介</a> 2009-04-22</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fredboot.blogbus.com%2Flogs%2F35085538.html&title=u-boot%E5%91%BD%E4%BB%A4%E9%85%8D%E7%BD%AE">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://pindao.blogbus.com/fengshang?utm_source=blogbus&utm_medium=rss&utm_campaign=fengshang" target="_blank">风尚频道——国内顶尖的时尚族群汇聚于此，未必是流行，但一定要有品位。</a></b></div><br /><br />]]></description>
   <link>http://redboot.blogbus.com/logs/35085538.html</link>
   <author>redboot</author>
   <pubDate>Thu, 12 Feb 2009 13:39:11 +0800</pubDate>
  </item>
  <item>
   <title>u-boot编译过程二</title>
   <description><![CDATA[<p>接着<a href="http://redboot.blogbus.com/logs/34986179.html">上次</a>，这次介绍make all的过程。<br />首先，介绍一下生成的config.mk 和 config.h如何使用，得到正确配置的。<br /><br />config.mk直接被include到Makefile来,并使用其定义如下：<br />&nbsp;&nbsp;&nbsp; include $(obj)include/config.mk<br />&nbsp;&nbsp;&nbsp; export&nbsp;&nbsp;&nbsp; ARCH CPU BOARD VENDOR SOC<br />这样可以直接选择需要编译的模块，例如：<br />&nbsp;&nbsp;&nbsp; LIBS += cpu/$(CPU)/$(SOC)/lib$(SOC).a<br />&nbsp;&nbsp;&nbsp; LIBS += lib_$(ARCH)/lib$(ARCH).a<br />&nbsp;&nbsp;&nbsp; LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).a<br />config.h被include/common.h所包含，而它有包含了相应硬件的头文件。<br />&nbsp;&nbsp;&nbsp; common.h &lt;--- config.h &lt;--- smdk2410.h<br />除了在源程序中，使用这些头文件的定义之外，uboot还有一个脚本通过解析common.h以及其包含的所有头文件信息，来生成配置信息如下形式：<br />&nbsp;&nbsp;&nbsp; CONFIG_BAUDRATE=115200<br />&nbsp;&nbsp;&nbsp; CONFIG_NETMASK="255.255.255.0"<br />&nbsp;&nbsp;&nbsp; CONFIG_DRIVER_CS8900=y<br />&nbsp;&nbsp;&nbsp; CONFIG_ARM920T=y<br />&nbsp;&nbsp;&nbsp; CONFIG_RTC_S3C24X0=y<br />&nbsp;&nbsp;&nbsp; CONFIG_CMD_ELF=y<br /><br />而头文件的定义的形式如下，对比可以看出脚本的工作原理。&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; #define CONFIG_BAUDRATE&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 115200<br />&nbsp;&nbsp;&nbsp; #define CONFIG_NETMASK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 255.255.255.0<br />&nbsp;&nbsp;&nbsp; #define CONFIG_DRIVER_CS8900&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp; /* we have a CS8900 on-board */<br />&nbsp;&nbsp;&nbsp; #define CONFIG_ARM920T&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp; /* This is an ARM920T Core&nbsp;&nbsp;&nbsp; */<br />&nbsp;&nbsp;&nbsp; #define&nbsp;&nbsp;&nbsp; CONFIG_RTC_S3C24X0&nbsp;&nbsp;&nbsp; 1<br />&nbsp;&nbsp;&nbsp; #define CONFIG_CMD_ELF<br /><br />通过这样，uboot可以自动得到一个模块选择的配置功能。如果我们需要添加什么定义或者功能，也可以在相应的头文件中加入定义实现。<br /><br />现在，配置已经得到，就看最后的编译流程。<br />编译分为五大部分，分别如下：<br />&nbsp;&nbsp;&nbsp; 1. $(SUBDIRS) 工具，例子等，包括目录：tools examples api_examples<br />&nbsp;&nbsp;&nbsp; 2. $(OBJS)&nbsp; 启动模块 cpu/arm920t/start.o<br />&nbsp;&nbsp;&nbsp; 3. $(LIBBOARD) 板子支持模块 board/smdk2410/libsmdk2410.a<br />&nbsp;&nbsp;&nbsp; 4. $(LIBS) &nbsp;&nbsp;&nbsp; 其他模块，有诸如以下模块：<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cpu/arm920t/libarm920t.a <br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cpu/arm920t/s3c24x0/libs3c24x0.a <br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lib_arm/libarm.a <br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fs/jffs2/libjffs2.a <br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fs/yaffs2/libyaffs2.a <br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; net/libnet.a <br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; disk/libdisk.a <br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; drivers/bios_emulator/libatibiosemu.a <br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; drivers/mtd/libmtd.a <br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; drivers/net/libnet.a <br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; drivers/net/phy/libphy.a <br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; drivers/net/sk98lin/libsk98lin.a <br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; drivers/pci/libpci.a <br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; common/libcommon.a /<br /><br />&nbsp;&nbsp;&nbsp; 5. $(LDSCRIPT) 链接脚本<br /><br />编译完成这五部分，链接成elf格式的u-boot文件，最后通过objcopy -O binary命令将elf格式转换成为raw binary格式的文件u-boot.bin就可以烧到板子上使用了。</p><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="http://redboot.blogbus.com/logs/34986179.html">u-boot编译过程一</a> 2009-02-11</div><div><a href="http://redboot.blogbus.com/logs/35085538.html">u-boot命令配置</a> 2009-02-12</div><div><a href="http://redboot.blogbus.com/logs/19874250.html">eCos编译配置说明</a> 2008-04-27</div><div><a href="http://redboot.blogbus.com/logs/38382371.html">dlmalloc in u-boot （3） 流程</a> 2009-04-23</div><div><a href="http://redboot.blogbus.com/logs/38352001.html">dlmalloc in u-boot （2） 数据结构</a> 2009-04-23</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fredboot.blogbus.com%2Flogs%2F34991963.html&title=u-boot%E7%BC%96%E8%AF%91%E8%BF%87%E7%A8%8B%E4%BA%8C">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://pindao.blogbus.com/fengshang?utm_source=blogbus&utm_medium=rss&utm_campaign=fengshang" target="_blank">风尚频道——国内顶尖的时尚族群汇聚于此，未必是流行，但一定要有品位。</a></b></div><br /><br />]]></description>
   <link>http://redboot.blogbus.com/logs/34991963.html</link>
   <author>redboot</author>
   <pubDate>Wed, 11 Feb 2009 14:00:45 +0800</pubDate>
  </item>
  <item>
   <title>u-boot编译过程一</title>
   <description><![CDATA[<p>现在介绍一下u-boot的编译过程，这里用的uboot版本是U-Boot 2008.10,硬件用smdk2410，这个板子用得比较普遍，uboot已经有对其的支持。通过我们对编译过程和代码的了解，我们也容易用uboot支持我们自己需要的硬件。<br /><br />编译命令非常简单：<br />&nbsp;&nbsp;&nbsp; make smdk2410_config （生成配置）<br />&nbsp;&nbsp;&nbsp; make all&nbsp; （生成最终文件）<br />当然，更好的做法是把编译出的文件生成到另外一个目录，并make clean如：<br />&nbsp;&nbsp;&nbsp; export BUILD_DIR=../tmp<br />&nbsp;&nbsp;&nbsp; make distclean<br />&nbsp;&nbsp;&nbsp; make smdk2410_config <br />&nbsp;&nbsp;&nbsp; make all<br /><br />现在，我们可以来看看Makefile，u-boot的Makefile文件非常大。但是，其结构却并不复杂。<br />u-boot已经支持了很多硬件，前半部分是共用部分，编译出最终的uboot可执行文件。<br />而后半部分，是为各种不同的硬件进行配置，每种硬件有一个目标，每个的做法都非常类似，我们用到的是：<br />smdk2410_config&nbsp;&nbsp;&nbsp; :&nbsp;&nbsp;&nbsp; unconfig<br />&nbsp;&nbsp;&nbsp; @$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0<br /><br />这里的 MKCONFIG&nbsp;&nbsp;&nbsp; := $(SRCTREE)/mkconfig<br />实际上是调用脚本mkconfig，而这个脚本做的工作简单如下：<br /><br />建立config.mk文件<br />&nbsp;&nbsp;&nbsp; echo "ARCH&nbsp;&nbsp; = $2" &gt;&nbsp; config.mk<br />&nbsp;&nbsp;&nbsp; echo "CPU&nbsp;&nbsp;&nbsp; = $3" &gt;&gt; config.mk<br />&nbsp;&nbsp;&nbsp; echo "BOARD&nbsp; = $4" &gt;&gt; config.mk<br />&nbsp;&nbsp;&nbsp; echo "VENDOR = $5" &gt;&gt; config.mk<br />&nbsp;&nbsp;&nbsp; echo "SOC&nbsp;&nbsp;&nbsp; = $6" &gt;&gt; config.mk<br />建立config.h<br />&nbsp;&nbsp;&nbsp; echo "#include &lt;configs/$1.h&gt;" &gt;&gt;config.h<br />&nbsp;&nbsp;&nbsp; <br />在这里$1-$6的值分别是：smdk2410 arm arm920t smdk2410 NULL s3c24x0<br /><br />而执行了 make smdk2410_config 之后，就生成了相应的config.mk，config.h两个文件。<br />在config.mk文件中，定义了相应硬件信息 ： ARCH CPU BOARD VENDOR SOC<br />在config.h文件中，包含了相应硬件的头文件smdk2410.h ，位于include\configs目录下。<br />如果新建自己的硬件项目，那么也需要建立相应的头文件在这个地方。<br />这样，uboot的配置已经生成，下一次介绍make all的过程。</p><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="http://redboot.blogbus.com/logs/34991963.html">u-boot编译过程二</a> 2009-02-11</div><div><a href="http://redboot.blogbus.com/logs/35085538.html">u-boot命令配置</a> 2009-02-12</div><div><a href="http://redboot.blogbus.com/logs/19874250.html">eCos编译配置说明</a> 2008-04-27</div><div><a href="http://redboot.blogbus.com/logs/38382371.html">dlmalloc in u-boot （3） 流程</a> 2009-04-23</div><div><a href="http://redboot.blogbus.com/logs/38352001.html">dlmalloc in u-boot （2） 数据结构</a> 2009-04-23</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fredboot.blogbus.com%2Flogs%2F34986179.html&title=u-boot%E7%BC%96%E8%AF%91%E8%BF%87%E7%A8%8B%E4%B8%80">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://pindao.blogbus.com/fengshang?utm_source=blogbus&utm_medium=rss&utm_campaign=fengshang" target="_blank">风尚频道——国内顶尖的时尚族群汇聚于此，未必是流行，但一定要有品位。</a></b></div><br /><br />]]></description>
   <link>http://redboot.blogbus.com/logs/34986179.html</link>
   <author>redboot</author>
   <pubDate>Wed, 11 Feb 2009 11:31:30 +0800</pubDate>
  </item>
 </channel>
</rss>
