<?xml version="1.0" encoding="gb2312"?>
<rss version="2.0">
<channel>
<title><![CDATA[狒狒]]></title>
        <image>
        <title>http://hi.baidu.com</title>
        <link>http://hi.baidu.com</link>
        <url>http://img.baidu.com/img/logo-hi.gif</url>
        </image>
<description><![CDATA[闲情逸事]]></description>
<link>http://hi.baidu.com/flyingfat</link>
<language>zh-cn</language>
<generator>www.baidu.com</generator>
<ttl>5</ttl>


<item>
        <title><![CDATA[绝对好笑]]></title>
        <link><![CDATA[http://hi.baidu.com/flyingfat/blog/item/93d8852bb1c409f8e7cd40e1.html]]></link>
        <description><![CDATA[
		
		太阳给草打电话 <br>
太阳：喂，草吗，我日。  <br>
草：我草，你谁啊？ <br>
太阳：我日啊 <br>
草：我草，你到底谁啊 <br>
太阳：我日啊，你草吧 <br>
草：TMD，你到底是谁啊，我草  <br>
太阳：我日，我日啊  <br>
草:我草. <br>
这时， <br>
太阳的妈妈接过电话：我日他妈呀，你是草吧，草你妈呢？ 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/flyingfat/blog/category/%CF%D0%C7%E9%D2%DD%CA%C2">闲情逸事</a>&nbsp;<a href="http://hi.baidu.com/flyingfat/blog/item/93d8852bb1c409f8e7cd40e1.html#comment">查看评论</a>]]></description>
        <pubDate>2007-07-04  00:05</pubDate>
        <category><![CDATA[闲情逸事]]></category>
        <author><![CDATA[flyingfat]]></author>
		<guid>http://hi.baidu.com/flyingfat/blog/item/93d8852bb1c409f8e7cd40e1.html</guid>
</item>

<item>
        <title><![CDATA[《施氏食獅史》]]></title>
        <link><![CDATA[http://hi.baidu.com/flyingfat/blog/item/93d8852bbfec03f8e7cd40c9.html]]></link>
        <description><![CDATA[
		
		《施氏食獅史》是一篇由趙元任所寫的設限文章。全文共九十一字（連標題九十六字），每字的普通話發音都是shi。這篇短文都能看懂，可是如果你用普通話（以及任何官話方言）讀給別人聽，他是無論如何也聽不懂的！  <br>
<br>
《施氏食獅史》  <br>
石室詩士施氏，嗜獅，誓食十獅。施氏時時適市視獅。十時，適十獅適市。是時，適施氏適市。氏視是十獅，恃矢勢，使是十獅逝世。氏拾是十獅屍，適石室。石室濕，氏使侍拭石室。石室拭，氏始試食是十獅。食時，始識是十獅，實十石獅屍。試釋是事。 <br>
<br>
译文&mdash;&mdash;  <br>
有一位姓施的诗人，住在一间以石头盖成的房屋里，对狮子特别爱好，并且爱吃狮子，他发誓要吃掉十头狮子。他时常都到市上察看有无狮子出现，某日十 时，正好有十头狮子出现市上，当时施君也来到市上，他看到这十头狮子，于是取下弓箭，将这十头狮子予以射杀，施君随之拾起十头射杀死掉的狮子的尸体，准备 搬运到他住的地方石室，不凑巧，这间石室很潮湿，施君叫他的仆人将石室擦干净，等到把石室擦干净，他开始尝试吃掉这十头死尸的狮子，正要吃的时候，才识破 这十头狮尸，并非真的狮尸，而是十头用石头做的狮子，现在请你试将这件事情解释一下。 <a href="http://hi.baidu.com/flyingfat/blog/item/93d8852bbfec03f8e7cd40c9.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/flyingfat/blog/category/%CF%D0%C7%E9%D2%DD%CA%C2">闲情逸事</a>&nbsp;<a href="http://hi.baidu.com/flyingfat/blog/item/93d8852bbfec03f8e7cd40c9.html#comment">查看评论</a>]]></description>
        <pubDate>2007-07-02  12:18</pubDate>
        <category><![CDATA[闲情逸事]]></category>
        <author><![CDATA[flyingfat]]></author>
		<guid>http://hi.baidu.com/flyingfat/blog/item/93d8852bbfec03f8e7cd40c9.html</guid>
</item>

<item>
        <title><![CDATA[内核级进程通信]]></title>
        <link><![CDATA[http://hi.baidu.com/flyingfat/blog/item/946f3cdd989081d88c10297a.html]]></link>
        <description><![CDATA[
		
		最近有项目需要多个进程间共享内存数据，而DirectFB的fusion基本上可以满足要求，空闲时间对此进行分析。 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/flyingfat/blog/category/Linux">Linux</a>&nbsp;<a href="http://hi.baidu.com/flyingfat/blog/item/946f3cdd989081d88c10297a.html#comment">查看评论</a>]]></description>
        <pubDate>2007-06-15  09:55</pubDate>
        <category><![CDATA[Linux]]></category>
        <author><![CDATA[flyingfat]]></author>
		<guid>http://hi.baidu.com/flyingfat/blog/item/946f3cdd989081d88c10297a.html</guid>
</item>

<item>
        <title><![CDATA[GCC中在C语言中嵌入汇编]]></title>
        <link><![CDATA[http://hi.baidu.com/flyingfat/blog/item/9013ef1f6f74d10b314e1565.html]]></link>
        <description><![CDATA[
		
		<div>最开始，人们都是用汇编语言来写程序，甚至连操作系统也是用汇编语言写的。但是，当程序的复杂性非常高的时候用汇编就会很难控制了。因为汇编语言没有提供任何<font style="background-color: rgb(255, 255, 0);">类型检查机制</font>，因此，很容易会很基本的犯错误，比如，把指针作为整数来用而不是当作指针来引用内存。更糟糕的是，用汇编写的程序被<font style="background-color: rgb(255, 255, 0);">限定在只能在特定的平台上运行</font>，移植一个汇编程序到别的平台，甚至和重新写程序的难度差不多。但是，现在也有人热衷写汇编，比如：comp.lang.asm.x86，他们多数是写DOS下的游戏程序。</div>
<div>&nbsp;&nbsp;&nbsp;  早<font style="background-color: rgb(255, 255, 0);">期的高级语言编译器通常不能产生效率很高的代码也不能提供对底层硬件的访问</font>， 因此不能满足编写系统程序的需要。那时候，人们为了写高效率的代码或者访问底层硬件需要写汇编代码，但是，现在，人们不是为了提高效率而需要汇编，因为现 代编译器产生的代码的效率和一个熟练的汇编程序员写的代码差不了多少。C语言提供了对各种硬件的操作，几乎所有的Linux代码都是C语言的。</div>
<div>&nbsp;&nbsp;&nbsp;  但是，有的时候汇编是唯一的选择，nonehteless,there are times when writting assembly code is the only option.尤其是编写操作系统的时候。<font style="background-color: rgb(255, 255, 0);">比如，有写CPU的寄存器保存着机器的状态信息，操作系统必须访问。还有一些特殊的指令需要汇编。甚至一些应用程序也需要汇编，比如访问状态字，C就不能直接做到。</font></div>
<div><font style="background-color: rgb(255, 255, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font style="background-color: rgb(255, 255, 0);">面 临的挑战就是如何在大量的C代码中嵌入少量的汇编代码。一种方法是用汇编编写关键的功能，遵循C编译器的参数传递和寄存器使用规则。把汇编代码存入另外一 个文件，把C代码和汇编代码编译后利用链接器链接。例如，p1.c包含C语言代码，p2.s包含汇编语言代码，下面的编译命令:</font></div>
<div><font style="background-color: rgb(255, 255, 0);">gcc -o p p1.c p2.s</font></div>
<div><font style="background-color: rgb(255, 255, 0);">可以把p1.c编译，p2.s汇编，然后两个目标文件会被链接成一个可执行文件p.</font></div>
<div><font style="background-color: rgb(0, 255, 0);">在linux0.11内核中，setup.s就是利用这种类似的方法来调用main.c函数的。同时，中断处理函数也是用C写的而在汇编中进行调用。</font></div>
<div> </div>
<div><font style="background-color: rgb(255, 255, 0);">&nbsp;&nbsp;&nbsp;&nbsp;  另外一种方法就是把汇编和C代码混和来写。嵌入汇编允许用户直接向编译器编译产生的代码序列中插入汇编代码。With GCC,it is also possible to mix assembly with C code. Inline assembly </font><font style="background-color: rgb(255, 255, 0);">allows the user insert assembly code directly into the code sequence generated by the complier. Features provided to specify instruction operands and to indicate to the compiler which are being overwritten by the assembly instructions. The resulting code is,of course,highly machine-dependent,since different types of machines do not have compatible machine insturctions. The asm directive is also specific to GCC, creating an incompatibility with many other compilers. Noneheless, this can be useful way to keep the amount of machine-dependent code to an absolute minimum.</font></div>
<div>  GCC的帮助文档中有关于inline assembly的说明。可惜不是很完整和精确。</div>
<div>&nbsp;&nbsp;  基本的inline assembly形式如下，有点类似函数调用：</div>
<div>&nbsp;&nbsp;  asm(code-string)</div>
<div>&nbsp;&nbsp;  code-string是要嵌入的汇编指令。编译器会把这段代码插入编译产生的汇编代码中。the compiler will insert this string verbatim into the assembly code being generated,and hence the compiler and the user-supplied assembly will be combined.因此，编译器产生的汇编代码和用户提供的汇编代码就结合到一起了。编译器不对嵌入的汇编代码进行语法检查，因此，第一个报错的通常是汇 编器。</div>
<div>&nbsp;&nbsp;&nbsp;  <font style="background-color: rgb(0, 255, 0);">下面通过一个例子来说明这种用法。</font></div>
<div><font style="background-color: rgb(0, 255, 0);">&nbsp;&nbsp;&nbsp;  下面这段代码需要访问程序状态字，利用inline assembly来实现。</font></div>
<div><font style="background-color: rgb(0, 255, 0);">考虑下面两个函数原型：</font></div>
<div><font style="background-color: rgb(0, 255, 0);">int ok_smul( int x ,int y, int *dest)</font></div>
<div><font style="background-color: rgb(0, 255, 0);">int ok_umul(unsigned x, unsigned y, unsigned *dest)</font></div>
<div><font style="background-color: rgb(0, 255, 0);">每个函数的功能都是计算x和y的乘积然后把结果存入dest所指向的内存中。</font></div>
<div><font style="background-color: rgb(0, 255, 0);">返回值代表的是乘法结果是否溢出。返回0时代表溢出，返回1时代表没有溢出。我们用两个函数来实现乘法因为它们在不同的情况下溢出。</font></div>
<div><font style="background-color: rgb(0, 255, 0);">查一下IA32的指令mul和imul，可以发现当产生溢出时都会设置CF标志位。setae指令可以对寄存器的低字节清零当CF标志置位的时候，否则置1。我们期望利用如下代码实现上述功能;</font></div>
<div><font style="background-color: rgb(0, 255, 0);">/*frist attempt. doesnot work, why??*/</font></div>
<div><font style="background-color: rgb(0, 255, 0);">int ok_smull(int x, int y,int *dest)</font></div>
<div><font style="background-color: rgb(0, 255, 0);">{</font></div>
<div><font style="background-color: rgb(0, 255, 0);">&nbsp;&nbsp;  int result=0;</font></div>
<div><font style="background-color: rgb(0, 255, 0);">&nbsp;&nbsp;  *dest =x*y;</font></div>
<div><font style="background-color: rgb(0, 255, 0);">&nbsp;&nbsp;  asm(&quot;setae %al&quot;);</font></div>
<div><font style="background-color: rgb(0, 255, 0);">&nbsp;&nbsp;  return result;</font></div>
<div><font style="background-color: rgb(0, 255, 0);">}</font></div>
<div> </div>
<div><font style="background-color: rgb(0, 255, 0);">这段代码不能达到我们的目的，因为我们是 期望%eax寄存器作为函数的返回值，期望编译器会把变量result的值放入%eax中作为返回值。不幸的是，GCC有它自己的规则。GCC产生的代码 会在最后初始化result的值，即GCC调换了result＝0这指令的顺序，因为我们没有用到result。问题的关键是GCC不知道我们插入的汇编 代码和其余C代码想怎么样相互作用。</font></div>
<div><font style="background-color: rgb(0, 255, 0);">下面这种方法可以解决这个问题，但不是在任何情况下都工作。</font></div>
<div><font style="background-color: rgb(0, 255, 0);">/*second attempt, works with limited contexts*/</font></div>
<div><font style="background-color: rgb(0, 255, 0);">int dummy = 0;</font></div>
<div><font style="background-color: rgb(0, 255, 0);">int ok_smul2(int x,int y,int * dest)</font></div>
<div><font style="background-color: rgb(0, 255, 0);">{</font></div>
<div><font style="background-color: rgb(0, 255, 0);">  int result;</font></div>
<div> </div>
<div><font style="background-color: rgb(0, 255, 0);"> *dest =x*y;</font></div>
<div><font style="background-color: rgb(0, 255, 0);"> result=dummy;</font></div>
<div><font style="background-color: rgb(0, 255, 0);">asm(&quot;setae %al&quot;);</font></div>
<div><font style="background-color: rgb(0, 255, 0);">return result;</font></div>
<div><font style="background-color: rgb(0, 255, 0);">}</font></div>
<div> </div>
<div><font style="background-color: rgb(0, 255, 0);">因为我们用全局变量来初始化result，编译器通常会比较&ldquo;保守&rdquo;当涉及到全局变量的问题，因为不会自做主张的改变代码顺序。</font></div>
<div><font style="background-color: rgb(0, 255, 0);">这程序只在编译的时候打开优化选项-O的时候才能正常工作。<a href="http://search.msn.com/results.aspx?q=%E5%9B%A0%E4%B8%BA%E5%A6%82%E6%9E%9C%E4%B8%8D%E4%BC%98%E5%8C%96%EF%BC%8C%E7%BC%96%E8%AF%91%E5%99%A8%E4%BC%9A%E6%8A%8Aresult%E4%BF%9D%E5%AD%98%E5%88%B0%E5%A0%86%E6%A0%88%E4%B8%8A%EF%BC%8C%E5%B9%B6%E5%9C%A8%E8%BF%94%E5%9B%9E%E4%B9%8B%E5%89%8D%E8%AF%BB%E5%8F%96%E5%AE%83%E7%9A%84%E5%80%BC%EF%BC%8C%E8%BF%99%E6%A0%B7%E4%BC%9A%E8%A6%86%E7%9B%96%E4%BA%86setae%E6%8C%87%E4%BB%A4%E8%AE%BE%E7%BD%AE%E7%9A%84%E5%80%BC%E3%80%82"><font style="background-color: rgb(0, 204, 255);">因为如果不优化，编译器会把result保存到堆栈上，并在返回之前读取它的值，这样会覆盖了setae指令设置的值。</font></a>编译器不知道插入的汇编代码和剩余的代码的关系，因为我们没有提供这种信息。</font></div>
<div> </div>
<div><font style="background-color: rgb(255, 153, 204);">为了解决这个问题，提供了扩展的嵌入式汇编。Extended form of asm</font></div>
<div><font style="background-color: rgb(255, 153, 204);">Gcc提供了一种扩展的asm，允许用户指定C语言中的变量值作为嵌入汇编语句的操作数和指定那些寄存器会被覆盖。有了这些信息，编译器就会正确地色互知要求的初始值，执行指令，并利用计算的结果。</font></div>
<div><font style="background-color: rgb(255, 153, 204);">一般形式的嵌入汇编语句如下：</font></div>
<div><font style="background-color: rgb(255, 153, 204);">asm(code-string [:output-list[:input-list [:overwrite-list]] ]);</font></div>
<div><font style="background-color: rgb(255, 153, 204);">register names such as &quot;%eax&quot; must be written with an extra &lsquo;％&rsquo;symbol,such as &quot;%%eax&quot;.</font></div>
<div><font style="background-color: rgb(255, 153, 204);">下面的代码是采用这种方式的实现：</font></div>
<div><font style="background-color: rgb(255, 153, 204);">/*uses extended asm to get reliable code*/</font></div>
<div><font style="background-color: rgb(255, 153, 204);">int ok_suml3(int x,int y, int *dest)</font></div>
<div><font style="background-color: rgb(255, 153, 204);">{</font></div>
<div><font style="background-color: rgb(255, 153, 204);"> int result;</font></div>
<div><font style="background-color: rgb(255, 153, 204);">*dest =x*y;</font></div>
<div> </div>
<div><font style="background-color: rgb(255, 153, 204);">asm(&quot;setae %%bl; movzbl %%bl,%0&quot;</font></div>
<div><font style="background-color: rgb(255, 153, 204);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  : &quot;=r&quot; (result) /*output*/</font></div>
<div><font style="background-color: rgb(255, 153, 204);">&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; /*no input*/ </font></div>
<div><font style="background-color: rgb(255, 153, 204);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  : &quot;%ebx&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /*overwrite*/</font></div>
<div><font style="background-color: rgb(255, 153, 204);">&nbsp;&nbsp;&nbsp;&nbsp;  );</font></div>
<div><font style="background-color: rgb(255, 153, 204);">return result;</font></div>
<div><font style="background-color: rgb(255, 153, 204);">}</font></div>
<div> </div>
<div> </div> <a href="http://hi.baidu.com/flyingfat/blog/item/9013ef1f6f74d10b314e1565.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/flyingfat/blog/category/linux%BB%E3%B1%E0%D3%EF%D1%D4">linux汇编语言</a>&nbsp;<a href="http://hi.baidu.com/flyingfat/blog/item/9013ef1f6f74d10b314e1565.html#comment">查看评论</a>]]></description>
        <pubDate>2007-04-10  22:45</pubDate>
        <category><![CDATA[linux汇编语言]]></category>
        <author><![CDATA[flyingfat]]></author>
		<guid>http://hi.baidu.com/flyingfat/blog/item/9013ef1f6f74d10b314e1565.html</guid>
</item>

<item>
        <title><![CDATA[linux gcc常用参数]]></title>
        <link><![CDATA[http://hi.baidu.com/flyingfat/blog/item/69cfcbf91e132658252df29f.html]]></link>
        <description><![CDATA[
		
		格&nbsp;&nbsp;&nbsp;  式（选项 &amp;&amp; 解释 ）<br>
linux gcc常用命令集合：<br>
-o FILE   <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  指定输出文件名，在编译为目标代码时，这一选项不是必须的。如果FILE没有指定，缺省文件名是a.out.<br>
-c        <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  只编译生成目标文件,不链接<br>
-m486     <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  针对 486 进行代码优化。 <br>
-O0       <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  不进行优化处理。<br>
-O 或 -O1 <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  优化生成代码。<br>
-O2       <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  进一步优化。<br>
-O3 比 -O2 <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  更进一步优化，包括 inline 函数。<br>
-w        <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  关闭所有警告,建议不要使用此项<br>
-Wall     <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  允许发出gcc能提供的所有有用的警告,也可以用-W(warning)来标记指定的警告<br>
-werror   <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  把所有警告转换为错误,以在警告发生时中止编译过程                             <br>
-MM       <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  输出一个make兼容的相关列表<br>
-v        <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  显示在编译过程的每一步中用到的命令 <br>
-E        <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  只运行 C 预编译器。<br>
-shared   <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  生成共享目标文件。通常用在建立共享库时。<br>
-static   <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  链接静态库，即执行静态链接<br>
-lFOO     <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  链接名为libFOO的函数库<br>
-g        <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  在可执行程序中包含标准调试信息<br>
-ggdb     <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  在可执行程序中包含只有GNU debugger才能使别的达两条是信息<br>
-O        <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  优化编译过的代码<br>
-ON       <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  指定代码优化的级别为N,o&lt;=N&lt;=3<br>
-ansi     <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  支持ANSI/ISO C的标准语法，取消GNU的语法扩展中与该标准有冲突的部分(但这一选项并不能保证生成ANSI兼容的代码) 这一选项将禁止 GNU C 的某些特色， 例如 asm 或 typeof 关键词。<br>
<br>
-pedantic <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  允许发出ANSI/ISO C标准所列出的所有警告<br>
-pedantic -errors   <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  允许发出ANSI/ISO C标准所列出的所有错误<br>
-traditional        <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  支持Kernighan &amp; Ritchie C语法(如用旧式语法定义函数);如果不知道这个选项的含义,也没有关系<br>
<br>
-IDIRECTORY   <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  指定额外的头文件搜索路径DIRECTORY。<br>
-LDIRECTORY   <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  指定额外的函数库搜索路径DIRECTORY。<br>
-DFOO=BAR <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  在命令行定义预处理宏FOO,其值为BAR<br>
-IDIRNAME <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  将DIRNAME加入到头文件的搜索目录列表中<br>
-LDIRNAME <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  将DIRNAME加入到库文件的搜索目录列表中，缺省情况下gcc 只链接共享库<br>
-DMACRO   <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  以字符串&ldquo;1&rdquo;定义 MACRO 宏。<br>
-DMACRO=DEFN  <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  以字符串&ldquo;DEFN&rdquo;定义 MACRO 宏。<br>
-UMACRO   <br>
&nbsp;&nbsp;&nbsp;  &amp;&amp;  取消对 MACRO 宏的定义。 <a href="http://hi.baidu.com/flyingfat/blog/item/69cfcbf91e132658252df29f.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/flyingfat/blog/category/%B1%E0%D2%EB%C6%F7">编译器</a>&nbsp;<a href="http://hi.baidu.com/flyingfat/blog/item/69cfcbf91e132658252df29f.html#comment">查看评论</a>]]></description>
        <pubDate>2007-04-10  22:36</pubDate>
        <category><![CDATA[编译器]]></category>
        <author><![CDATA[flyingfat]]></author>
		<guid>http://hi.baidu.com/flyingfat/blog/item/69cfcbf91e132658252df29f.html</guid>
</item>

<item>
        <title><![CDATA[Linux 汇编语言开发指南]]></title>
        <link><![CDATA[http://hi.baidu.com/flyingfat/blog/item/3b8f6af085d5eac27831aac1.html]]></link>
        <description><![CDATA[
		
		<span class="atitle"><span style="font-weight: bold;">转载自：<a href="http://www-900.ibm.com/developerWorks/cn/linux/l-assembly/index.shtml">IBM developerWorks 中国网站</a></span><br>
<br>
</span>肖文鹏(<a href="mailto:xiaowp@263.net">xiaowp@263.net</a>)<br>
北京理工大学计算机系硕士研究生<br>
2003 年 7 月  <blockquote>汇 编语言的优点是速度快，可以直接对硬件进行操作，这对诸如图形处理等关键应用是非常重要的。Linux 是一个用 C 语言开发的操作系统，这使得很多程序员开始忘记在 Linux 中还可以直接使用汇编这一底层语言来优化程序的性能。本文为那些在Linux 平台上编写汇编代码的程序员提供指南，介绍 Linux 汇编语言的语法格式和开发工具，并辅以具体的例子讲述如何开发实用的Linux 汇编程序。</blockquote>
<p><a name="0"><span class="atitle2">一、简介</span></a></p>
<p>作 为最基本的编程语言之一，汇编语言虽然应用的范围不算很广，但重要性却勿庸置疑，因为它能够完成许多其它语言所无法完成的功能。就拿 Linux 内核来讲，虽然绝大部分代码是用 C 语言编写的，但仍然不可避免地在某些关键地方使用了汇编代码，其中主要是在 Linux 的启动部分。由于这部分代码与硬件的关系非常密切，即使是 C 语言也会有些力不从心，而汇编语言则能够很好扬长避短，最大限度地发挥硬件的性能。</p>
<p>大 多数情况下 Linux 程序员不需要使用汇编语言，因为即便是硬件驱动这样的底层程序在 Linux 操作系统中也可以用完全用 C 语言来实现，再加上 GCC 这一优秀的编译器目前已经能够对最终生成的代码进行很好的优化，的确有足够的理由让我们可以暂时将汇编语言抛在一边了。但实现情况是 Linux 程序员有时还是需要使用汇编，或者不得不使用汇编，理由很简单：精简、高效和 libc 无关性。假设要移植 Linux 到某一特定的嵌入式硬件环境下，首先必然面临如何减少系统大小、提高执行效率等问题，此时或许只有汇编语言能帮上忙了。</p>
<p>汇编语言直接同计算机的底层软件甚至硬件进行交互，它具有如下一些优点：<br>
</p>
<ul>
    <li>能够直接访问与硬件相关的存储器或 I/O 端口；  </li>
    <li>能够不受编译器的限制，对生成的二进制代码进行完全的控制；  </li>
    <li>能够对关键代码进行更准确的控制，避免因线程共同访问或者硬件设备共享引起的死锁；  </li>
    <li>能够根据特定的应用对代码做最佳的优化，提高运行速度；  </li>
    <li>能够最大限度地发挥硬件的功能。 </li>
</ul>
<p> </p>
<p>同时还应该认识到，汇编语言是一种层次非常低的语言，它仅仅高于直接手工编写二进制的机器指令码，因此不可避免地存在一些缺点：<br>
</p>
<ul>
    <li>编写的代码非常难懂，不好维护；  </li>
    <li>很容易产生 bug，难于调试；  </li>
    <li>只能针对特定的体系结构和处理器进行优化；  </li>
    <li>开发效率很低，时间长且单调。 </li>
</ul>
<p> </p>
<p>Linux 下用汇编语言编写的代码具有两种不同的形式。第一种是完全的汇编代码，指的是整个程序全部用汇编语言编写。尽管是完全的汇编代码，Linux 平台下的汇编工具也吸收了 C 语言的长处，使得程序员可以使用 #include、#ifdef 等预处理指令，并能够通过宏定义来简化代码。第二种是内嵌的汇编代码，指的是可以嵌入到C语言程序中的汇编代码片段。虽然 ANSI 的 C 语言标准中没有关于内嵌汇编代码的相应规定，但各种实际使用的 C 编译器都做了这方面的扩充，这其中当然就包括 Linux 平台下的 GCC。</p>
<p><a name="1"><span class="atitle2">二、Linux 汇编语法格式</span></a></p>
<p>绝大多数 Linux 程序员以前只接触过DOS/Windows 下的汇编语言，这些汇编代码都是 Intel 风格的。但在 Unix 和 Linux 系统中，更多采用的还是 AT&amp;T 格式，两者在语法格式上有着很大的不同：<br>
</p>
<ol>
    <li>
    <p>在 AT&amp;T 汇编格式中，寄存器名要加上 '%' 作为前缀；而在 Intel 汇编格式中，寄存器名不需要加前缀。例如：</p>
    <p align="center">
    <table cellspacing="0" cellpadding="2" border="1" bordercolorlight="#000000" bordercolordark="#d9d9d9">
        <tbody>
            <tr>
                <td width="200" bgcolor="#d9d9d9" align="center"><strong>AT&amp;T 格式</strong></td>
                <td width="200" bgcolor="#d9d9d9" align="center"><strong>Intel 格式</strong></td>
            </tr>
            <tr>
                <td>pushl %eax</td>
                <td width="200">push eax</td>
            </tr>
        </tbody>
    </table>
    </p>
    </li>
    <li>
    <p>在 AT&amp;T 汇编格式中，用 '$' 前缀表示一个立即操作数；而在 Intel 汇编格式中，立即数的表示不用带任何前缀。例如：</p>
    <p align="center">
    <table cellspacing="0" cellpadding="2" border="1" bordercolorlight="#000000" bordercolordark="#d9d9d9">
        <tbody>
            <tr>
                <td width="200" bgcolor="#d9d9d9" align="center"><strong>AT&amp;T 格式</strong></td>
                <td width="200" bgcolor="#d9d9d9" align="center"><strong>Intel 格式</strong></td>
            </tr>
            <tr>
                <td>pushl $1</td>
                <td width="200">push 1</td>
            </tr>
        </tbody>
    </table>
    </p>
    </li>
    <li>
    <p>AT&amp;T 和 Intel 格式中的源操作数和目标操作数的位置正好相反。在 Intel 汇编格式中，目标操作数在源操作数的左边；而在 AT&amp;T 汇编格式中，目标操作数在源操作数的右边。例如：</p>
    <p align="center">
    <table cellspacing="0" cellpadding="2" border="1" bordercolorlight="#000000" bordercolordark="#d9d9d9">
        <tbody>
            <tr>
                <td width="200" bgcolor="#d9d9d9" align="center"><strong>AT&amp;T 格式</strong></td>
                <td width="200" bgcolor="#d9d9d9" align="center"><strong>Intel 格式</strong></td>
            </tr>
            <tr>
                <td>addl $1, %eax</td>
                <td width="200">add eax, 1</td>
            </tr>
        </tbody>
    </table>
    </p>
    </li>
    <li>
    <p>在 AT&amp;T 汇编格式中，操作数的字长由操作符的最后一个字母决定，后缀'b'、'w'、'l'分别表示操作数为字节（byte，8 比特）、字（word，16 比特）和长字（long，32比特）；而在 Intel 汇编格式中，操作数的字长是用 &quot;byte ptr&quot; 和 &quot;word ptr&quot; 等前缀来表示的。例如：</p>
    <p align="center">
    <table cellspacing="0" cellpadding="2" border="1" bordercolorlight="#000000" bordercolordark="#d9d9d9">
        <tbody>
            <tr>
                <td width="200" bgcolor="#d9d9d9" align="center"><strong>AT&amp;T 格式</strong></td>
                <td width="200" bgcolor="#d9d9d9" align="center"><strong>Intel 格式</strong></td>
            </tr>
            <tr>
                <td>movb val, %al</td>
                <td width="200">mov al, byte ptr val</td>
            </tr>
        </tbody>
    </table>
    </p>
    </li>
    <li>在 AT&amp;T 汇编格式中，绝对转移和调用指令（jump/call）的操作数前要加上'*'作为前缀，而在 Intel 格式中则不需要。  </li>
    <li>
    <p>远程转移指令和远程子调用指令的操作码，在 AT&amp;T 汇编格式中为 &quot;ljump&quot; 和 &quot;lcall&quot;，而在 Intel 汇编格式中则为 &quot;jmp far&quot; 和 &quot;call far&quot;，即：</p>
    <p align="center">
    <table cellspacing="0" cellpadding="2" border="1" bordercolorlight="#000000" bordercolordark="#d9d9d9">
        <tbody>
            <tr>
                <td width="200" bgcolor="#d9d9d9" align="center"><strong>AT&amp;T 格式</strong></td>
                <td width="200" bgcolor="#d9d9d9" align="center"><strong>Intel 格式</strong></td>
            </tr>
            <tr>
                <td>ljump $section, $offset</td>
                <td width="200">jmp far section:offset</td>
            </tr>
            <tr>
                <td>lcall $section, $offset</td>
                <td width="200">call far section:offset</td>
            </tr>
        </tbody>
    </table>
    </p>
    <p>与之相应的远程返回指令则为：</p>
    <p align="center">
    <table cellspacing="0" cellpadding="2" border="1" bordercolorlight="#000000" bordercolordark="#d9d9d9">
        <tbody>
            <tr>
                <td width="200" bgcolor="#d9d9d9" align="center"><strong>AT&amp;T 格式</strong></td>
                <td width="200" bgcolor="#d9d9d9" align="center"><strong>Intel 格式</strong></td>
            </tr>
            <tr>
                <td>lret $stack_adjust</td>
                <td width="200">ret far stack_adjust</td>
            </tr>
        </tbody>
    </table>
    </p>
    </li>
    <li>
    <p>在 AT&amp;T 汇编格式中，内存操作数的寻址方式是</p>
    <table width="100%" cellspacing="0" cellpadding="5" border="1" bgcolor="#cccccc">
        <tbody>
            <tr>
                <td>
                <pre><code> section:disp(base, index, scale) </code></pre>
                <br>
                </td>
            </tr>
        </tbody>
    </table>
    <p>而在 Intel 汇编格式中，内存操作数的寻址方式为：</p>
    <table width="100%" cellspacing="0" cellpadding="5" border="1" bgcolor="#cccccc">
        <tbody>
            <tr>
                <td>
                <pre><code> section:[base + index*scale + disp] </code></pre>
                <br>
                </td>
            </tr>
        </tbody>
    </table>
    <p>由于 Linux 工作在保护模式下，用的是 32 位线性地址，所以在计算地址时不用考虑段基址和偏移量，而是采用如下的地址计算方法：</p>
    <table width="100%" cellspacing="0" cellpadding="5" border="1" bgcolor="#cccccc">
        <tbody>
            <tr>
                <td>
                <pre><code> disp + base + index * scale </code></pre>
                <br>
                </td>
            </tr>
        </tbody>
    </table>
    <p>下面是一些内存操作数的例子：</p>
    <p align="center">
    <table cellspacing="0" cellpadding="2" border="1" bordercolorlight="#000000" bordercolordark="#d9d9d9">
        <tbody>
            <tr>
                <td width="200" bgcolor="#d9d9d9" align="center"><strong>AT&amp;T 格式</strong></td>
                <td width="200" bgcolor="#d9d9d9" align="center"><strong>Intel 格式</strong></td>
            </tr>
            <tr>
                <td>movl -4(%ebp), %eax</td>
                <td width="200">mov eax, [ebp - 4]</td>
            </tr>
            <tr>
                <td>movl array(, %eax, 4), %eax</td>
                <td width="200">mov eax, [eax*4 + array]</td>
            </tr>
            <tr>
                <td>movw array(%ebx, %eax, 4), %cx</td>
                <td width="200">mov cx, [ebx + 4*eax + array]</td>
            </tr>
            <tr>
                <td>movb $4, %fs:(%eax)</td>
                <td width="200">mov fs:eax, 4</td>
            </tr>
        </tbody>
    </table>
    </p>
    </li>
</ol> <a href="http://hi.baidu.com/flyingfat/blog/item/3b8f6af085d5eac27831aac1.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/flyingfat/blog/category/linux%BB%E3%B1%E0%D3%EF%D1%D4">linux汇编语言</a>&nbsp;<a href="http://hi.baidu.com/flyingfat/blog/item/3b8f6af085d5eac27831aac1.html#comment">查看评论</a>]]></description>
        <pubDate>2007-04-10  20:35</pubDate>
        <category><![CDATA[linux汇编语言]]></category>
        <author><![CDATA[flyingfat]]></author>
		<guid>http://hi.baidu.com/flyingfat/blog/item/3b8f6af085d5eac27831aac1.html</guid>
</item>

<item>
        <title><![CDATA[logo 问题集]]></title>
        <link><![CDATA[http://hi.baidu.com/flyingfat/blog/item/228c430f13fc932b6059f3a3.html]]></link>
        <description><![CDATA[
		
		<strong>紧急求救：如何定制嵌入式linux 启动logo(小企鹅<br>
</strong>我的嵌入式ARM-Linux是基于2.4.2内核，支持framebuffer,所以我想用工具软件 
<p> </p>
<p>fblogo(0.5.2版本)将启动小企鹅logo改为自己的logo.png。现在遇到以下几个问</p>
<p>题，请求高手指点：<br>
(1)linux_logo.h跟fblogo是什么编译器（gcc）得到的有关吗？也就是说我用PC</p>
<p>机上的gcc对fblogo源文件编译链接生成可执行文件fblogo，而后用./fblogo </p>
<p>mylogo.png生成的linux_logo.h是要编译到ARM-LINUX内核中的，行吗？<br>
(2)为什么对于大多数png图片执行./fblogo_pc mylogo.png后有错误：<br>
fblogo error: only palette PNGs supported<br>
难道有什么其他的格式要求？<br>
(3)如何对任意BMP图片生成符合要求的PNG图片，有这方面的工具吗？</p>
<p>非常谢谢！<a href="mailto:dengyueming@163.net">dengyueming@163.net</a><br>
</p>
<p><strong>1) 首先下载linux progres<br>
</strong>1) 首先下载linux progress project软件包lpp-0.4.2.tar.gz,解压，在contrib的boot_logo目录中运行make,生成boot_logo工具；<br>
2) 将要在启动时显示的图片(例如:leo.bmp)用GIMP打开，另存为leo2.pcx格式文件;<br>
3) 运行#convert -colors 214 -dither -resize 640x480 leo2.pcx logo.pcx生成214色，640x480的pcx文件；<br>
4) 运行./boot_logo logo.pcx linux_logo.h生成linux_logo文件，将它拷贝到/include/linux/目录下，<br>
5) 修改drivers/video/fbcon.c为<br>
#define LOGO_H&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 480<br>
#define LOGO_W&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 640 </p>
<p> </p>
<p>重新编译内核即可.<br>
</p>
<p><strong>我用fblogo生成的是linux_logo.h，出现的还是小企鹅<br>
</strong>我用fblogo生成的是linux_logo.h文件里的linux_logo[]，<br>
而我的小企鹅是linux_logo16[],而不是linux_logo[].<br>
我的液晶屏是16位的,从fbcon_show_logo()可以看出,当depth=16时,src = linux_logo16;而不是linux_logo.<br>
所以我用fblogo生成的是linux_logo.h取代原来的文件后，出现的还是小企鹅，而不是我所预想的图片。<br>
只有当depth&gt;&nbsp;&nbsp; =24时,才会显示linux_logo[]里的数据.<br>
我想现在好像很少有24位以上的液晶屏吧。<br>
请问各位仁兄：你们的情况是怎样的呢？谢谢!<br>
</p> <a href="http://hi.baidu.com/flyingfat/blog/item/228c430f13fc932b6059f3a3.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/flyingfat/blog/category/Framebuffer">Framebuffer</a>&nbsp;<a href="http://hi.baidu.com/flyingfat/blog/item/228c430f13fc932b6059f3a3.html#comment">查看评论</a>]]></description>
        <pubDate>2007-04-10  00:17</pubDate>
        <category><![CDATA[Framebuffer]]></category>
        <author><![CDATA[flyingfat]]></author>
		<guid>http://hi.baidu.com/flyingfat/blog/item/228c430f13fc932b6059f3a3.html</guid>
</item>

<item>
        <title><![CDATA[framebuffer LOGO -- the right way]]></title>
        <link><![CDATA[http://hi.baidu.com/flyingfat/blog/item/a1e5ae314b6370a95edf0ea0.html]]></link>
        <description><![CDATA[
		
		<p>引用网址：<a href="http://gentoo-wiki.com/HOWTO_Linux_Logo_Hack">http://gentoo-wiki.com/HOWTO_Linux_Logo_Hack</a></p>
<h2>Basis</h2>
<p>This HOW-TO is written for those that want to hack the linux bootup logo. The main files in the kernel for the vesa frame buffer bootup logo are: /usr/src/linux/drivers/video/* &amp; /usr/src/linux/include/linux/linux_logo.h Those files are responsible for the bootup logo when the kernel starts in debug or quiet mode. If we want to change this logo we have to modify the files, by using the program that is appended at the end of this text.The image file that we have to use is a PCX image file with no more than 256 colors and not bigger than 786432 pixels(1024x768). </p>
<p>For more information you can also read the /usr/src/linux/Documentation/fb/vesafb.txt </p>
<h3>Do it Right</h3>
<p>As far as I know, this is the least "hacky" way you can get a custom logo. It preserves all the previous available logos, and lets you choose between them in the Kernel config. </p>
<p>It requires you to edit three files in the <strong>/usr/src/linux/drivers/video/logo</strong> directory, and (obviously) create the image(s) you want to appear. It only covers 224-colour logos - if you want 16-colour or black&amp;white ones, you'll have to figure that out on your own. I did all this yesterday, and the kernel booted fine this morning with my new logo. I changed <a class="external text" title="http://en.wikipedia.org/wiki/Tux" href="http://en.wikipedia.org/wiki/Tux" rel="nofollow"><font color="#0000cc">Tux</font></a> to <a class="external text" title="http://www.gentoo.org/main/en/about.xml" href="http://www.gentoo.org/main/en/about.xml" rel="nofollow"><font color="#0000cc">Larry</font></a>, so that's the example I'll be using throughout this tutorial. Of course you can change this to whatever you want - just make sure you're consistant with your names (eg. don't accidentally switch from "LARRY" to "BARRY" for one file). </p>
<p>OK, let's get down to it. </p>
<ul>
<li>Create your image, (I used the GIMP), and save it as a PNG (mine's called larry.png). It might be a good idea to convert it to indexed (223 colours) first - this is going to happen later anyway, so you may as well get it how you like it now (whether you want it dithered, any custom palettes, etc). I should also point out that the default images are all 80x80 pixels, but you don't have to abide by that. As far as I know, you can go as big as you want (within reason). </li>
</ul>
    <ul>
<li>Change to root, and put yourself in the directory we're working in: </li>
</ul>
        <pre>su -
cd /usr/src/linux/drivers/video/logo/
</pre>
        <ul>
<li>Convert the image with the netpbm tools (media-libs/netpbm): </li>
</ul>
            <pre>pngtopnm /path/to/larry.png | ppmquant -fs 223 | pnmtoplainpnm &gt; logo_larry_clut224.ppm
</pre>
            <p>Don't worry if the existing images seem to have more than one file each - the *.c and *.o ones get created automatically when you compile the kernel. </p>
            <ul>
<li>Open <strong>Kconfig</strong> in your favourite editor, and insert the following section (editing the first two lines as appropriate): </li>
</ul>
                <p>
<table style="BORDER-RIGHT: #ffbfbf 1px solid; BORDER-TOP: #ffbfbf 1px solid; BORDER-LEFT: #ffbfbf 1px solid; BORDER-BOTTOM: #ffbfbf 1px solid; BACKGROUND-COLOR: #fff2f2" cellspacing="0" cellpadding="0" width="75%">
                <tbody>
                    <tr>
                        <td style="BORDER-BOTTOM: #888 1px solid; BACKGROUND-COLOR: #ffafaf"><font size="-1"><strong>File:</strong> /usr/src/linux/drivers/video/logo/Kconfig</font> </td>
                    </tr>
                    <tr>
                        <td>
<div class="scroll">
<pre style="HEIGHT: auto">config LOGO_LARRY_CLUT224
 bool "Gentoo-ised 224-colour logo"
 depends on LOGO
 default y
</pre>
</div>
</td>
                    </tr>
                </tbody>
            </table>
</p>
            <p>I put it underneath the entry for LOGO_LINUX_CLUT224, so it'll appear below the default logos in the kernel setup. </p>
            <ul>
<li>Open <strong>logo.c</strong> in your favourite editor, and insert the following sections. Everything's a bit more cosily packed in this file, so make sure you get them in the right place. Again, change everything that says "larry" to your chosen name. The bit between /* these parentheses */ is a comment, and doesn't make any difference. I changed it anyway. </li>
</ul>
                <p>
<table style="BORDER-RIGHT: #ffbfbf 1px solid; BORDER-TOP: #ffbfbf 1px solid; BORDER-LEFT: #ffbfbf 1px solid; BORDER-BOTTOM: #ffbfbf 1px solid; BACKGROUND-COLOR: #fff2f2" cellspacing="0" cellpadding="0" width="75%">
                <tbody>
                    <tr>
                        <td style="BORDER-BOTTOM: #888 1px solid; BACKGROUND-COLOR: #ffafaf"><font size="-1"><strong>File:</strong> /usr/src/linux/drivers/video/logo/logo.c</font> </td>
                    </tr>
                    <tr>
                        <td>
<div class="scroll">
<p>Add this to the block of similar definitions at the top of the file: </p>
                        <pre style="HEIGHT: auto">extern const struct linux_logo logo_larry_clut224;</pre>
                        <p>Add this to the section headed by "if (depth &gt;= 8) {": </p>
                        <pre style="HEIGHT: auto">#ifdef CONFIG_LOGO_LARRY_CLUT224
  /* Gentoo-ised logo */
  logo = &amp;logo_larry_clut224;
#endif</pre>
</div>
</td>
                    </tr>
                </tbody>
            </table>
</p>
            <ul>
<li>Open <strong>Makefile</strong> ...blahblahblah... and add the following line to that big block of definitions at the top. You know the drill by now. </li>
</ul>
                <p>
<table style="BORDER-RIGHT: #ffbfbf 1px solid; BORDER-TOP: #ffbfbf 1px solid; BORDER-LEFT: #ffbfbf 1px solid; BORDER-BOTTOM: #ffbfbf 1px solid; BACKGROUND-COLOR: #fff2f2" cellspacing="0" cellpadding="0" width="75%">
                <tbody>
                    <tr>
                        <td style="BORDER-BOTTOM: #888 1px solid; BACKGROUND-COLOR: #ffafaf"><font size="-1"><strong>File:</strong> /usr/src/linux/drivers/video/logo/Makefile</font> </td>
                    </tr>
                    <tr>
                        <td>
<div class="scroll">
<pre style="HEIGHT: auto">obj-$(CONFIG_LOGO_LARRY_CLUT224) += logo_larry_clut224.o</pre>
</div>
</td>
                    </tr>
                </tbody>
            </table>
</p>
            <ul>
<li>You should be able to repeat those steps however many times you like if you want to add more than one image. </li>
</ul>
                <ul>
<li>Save all the files, cd down to /usr/src/linux, and follow your normal kernel-rolling procedure - making sure that you select your new image in the configuration: </li>
</ul>
                    <p>
<table style="BORDER-RIGHT: #7070ff 4px solid; BORDER-TOP: #7070ff 4px solid; BORDER-LEFT: #7070ff 4px solid; BORDER-BOTTOM: #7070ff 4px solid; BACKGROUND-COLOR: #faebd7" width="75%">
                    <tbody>
                        <tr>
                            <td style="BORDER-RIGHT: #0000ff 1px solid; BORDER-TOP: #0000ff 1px solid; BORDER-LEFT: #0000ff 1px solid; COLOR: #ffffff; BORDER-BOTTOM: #0000ff 1px solid; BACKGROUND-COLOR: #7070ff"><font size="-1">Linux Kernel Configuration: Kernel 2.6</font> </td>
                        </tr>
                        <tr>
                            <td>
<pre>Device Drivers -&gt;
&nbsp;&nbsp;&nbsp;&nbsp; Graphics Support -&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [*] Support for frame buffer devices
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [*] VESA VGA graphics support
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; VESA driver type -&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console display driver support -&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [*] Video mode selection support
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;*&gt; Framebuffer Console support

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Logo configuration-&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [*] Bootup logo
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ ] &lt;More logos&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [*] Your Custom Logo
</pre>
                            <p>...and run make. (There is no need to run make modules_install.) </p>
</td>
                        </tr>
                    </tbody>
                </table>
</p>
                <ul>
<li><a href="http://gentoo-wiki.com/HOWTO_Linux_Logo_Hack#Finishing_Up"><font color="#800080">Finish up</font></a>. </li>
</ul>
                    <div class="editsection" style="FLOAT: right; MARGIN-LEFT: 5px">[<a title="Edit section: Finishing Up" href="http://gentoo-wiki.com/index.php?title=HOWTO_Linux_Logo_Hack&amp;action=edit&amp;section=12"><font color="#0000cc">edit</font></a>]</div>
<a name="Finishing_Up"></a>
<h3>Finishing Up</h3>
                    <p>This section is common to both methods. </p>
                    <ul>
<li>Stick your newly customised kernel in its usual place under /boot </li>
</ul>
                        <ul>
<li>Make sure you've got a decent framebuffer by adding vga=0x318 or <a title="HOWTO Framebuffer:Bootsplash:Grubsplash" href="http://gentoo-wiki.com/HOWTO_Framebuffer:Bootsplash:Grubsplash#Kernel_mode_numbers"><font color="#0000cc">similar</font></a> to your kernel's command-line: </li>
</ul>
                            <p><strong>NOTE:</strong> You can ignore this step if you selected vesafb-tng under "VESA driver type". </p>
                            <p>
<table style="BORDER-RIGHT: #ffbfbf 1px solid; BORDER-TOP: #ffbfbf 1px solid; BORDER-LEFT: #ffbfbf 1px solid; BORDER-BOTTOM: #ffbfbf 1px solid; BACKGROUND-COLOR: #fff2f2" cellspacing="0" cellpadding="0" width="75%">
                            <tbody>
                                <tr>
                                    <td style="BORDER-BOTTOM: #888 1px solid; BACKGROUND-COLOR: #ffafaf"><font size="-1"><strong>File:</strong> /boot/grub/menu.lst <strong>or</strong> /boot/grub/grub.conf</font> </td>
                                </tr>
                                <tr>
                                    <td>
<div class="scroll">
<pre style="HEIGHT: auto">kernel (hd0,0)/vmlinuz root=/dev/sda3 vga=0x318</pre>
</div>
</td>
                                </tr>
                            </tbody>
                        </table>
</p>
                        <ul>
<li>When you boot into the new kernel, you should see the fruit of your labours! </li>
</ul> <a href="http://hi.baidu.com/flyingfat/blog/item/a1e5ae314b6370a95edf0ea0.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/flyingfat/blog/category/Framebuffer">Framebuffer</a>&nbsp;<a href="http://hi.baidu.com/flyingfat/blog/item/a1e5ae314b6370a95edf0ea0.html#comment">查看评论</a>]]></description>
        <pubDate>2007-04-10  00:06</pubDate>
        <category><![CDATA[Framebuffer]]></category>
        <author><![CDATA[flyingfat]]></author>
		<guid>http://hi.baidu.com/flyingfat/blog/item/a1e5ae314b6370a95edf0ea0.html</guid>
</item>

<item>
        <title><![CDATA[FBLOGO]]></title>
        <link><![CDATA[http://hi.baidu.com/flyingfat/blog/item/778a32a4fed44af69152eedd.html]]></link>
        <description><![CDATA[
		
		<div class="man_header_left"><span class="section">NAME</span> <br>
</div>
<ul>
<li>
<ul>fblogo - Converts images to framebuffer-logo header file </ul>
</li>
    <li><span class="section">SYNOPSIS</span> <br>
    <ul><span class="B">fblogo</span> [-2] [-h] [-d] [-v] [<em><font color="#001050">inputfile</font> [<em><font color="#001050">outputfile</font>]] <br>
</em></em></ul>
</li>
        <li><span class="section">DESCRIPTION</span> <br>
        <ul><span class="paragraph_brs"><br>
<br>
</span><strong>fblogo</strong> takes a png image as input and generates an appropriate linux_logo.h which can simply be included in the kernel. It will be displayed when the framebuffer device is enabled. You can also use it to generate full screen splash screens for the Linux Progress Patch. </ul>
</li>
            <li><span class="section">OPTIONS</span> <br>
            <ul><dl><dt><span class="B">-2, --linux-2.2</span> </dt><dd>Use this option to create a linux_logo.h suitable for 2.2.x kernels. By default, a 2.4.x/2.5.x - suitable linux_logo.h will be created </dd></dl><dl><dt><span class="B">-4, --linux-2.4</span> </dt><dd>Create a linux_logo.h suitable for 2.4.x kernels (default). </dd></dl><dl><dt><span class="B">-h, --help</span> </dt><dd>Displays a short help message </dd></dl><dl><dt><span class="B">-v, --version</span> </dt><dd>Display version string </dd></dl><dl><dt><span class="B">-d, --verbose</span> </dt><dd>Verbose mode, give some feedback. </dd></dl><dl><dt><span class="B"><em><font color="#001050">inputfile</font></em></span> </dt><dd>The input file, has to be a PNG with <strong>less</strong> than 224 colours. If omitted, stdin will be used. </dd></dl><dl><dt><span class="B"><em><font color="#001050">outputfile</font></em></span> </dt><dd>This will most likely be linux_logo.h, so you can simply replace the file in the linux source tree. If omitted, stdout will be used. </dd></dl></ul>
</li>
                <li><span class="section">REQUIREMENTS</span> <br>
                <ul>In order to actually see the resulted logo at boot time, framebuffer-support needs to be enabled in the kernel. <span class="B">CONFIG_EXPERIMENTAL=y</span> <dl><dt><span class="B">CONFIG_FB=y</span> </dt><dd></dd></dl><dl><dt><span class="B">CONFIG_FB_VESA=y</span> </dt><dd>- or whichever driver suits your graphics card. </dd></dl><dl><dt>You also need to tell the kernel to boot with the correct resolution, e.g. if you use lilo, specify a correct value for the vga-Parameter: </dt><dd></dd></dl><dl><dt><span class="B">vga=791</span> </dt><dd></dd></dl><dl><dt>This will enable booting with a resolution of 1024x768 at 16bpp. See Documentation/fb/vesafb.txt in the linux source tree for more modes. </dt><dd></dd></dl></ul>
</li>
                    <li><span class="section">USAGE</span> <br>
                    <ul>Generate a linux_logo.h using fblogo. This is actually the most difficult part, it is tough to get the colours looking good. The best results can be achieved by using netpbm or ImageMagick to do the quantization like so: <dl><dt><span class="B">Using netpbm:</span> </dt><dd></dd></dl><dl><dt>pngtopnm imagefile.png | ppmquant -fs 223 | pnmtopng | fblogo &gt; linux_logo.h </dt><dd></dd></dl><dl><dt><span class="B">Using ImageMagick:</span> </dt><dd></dd></dl><dl><dt>convert -colors 223 -dither &lt;inputimage&gt; &lt;image&gt;.png ; fblogo &lt;image&gt;.png linux_logo.h </dt><dd><br>
</dd></dl><dl><dt>Place this file in include/linux/linux_logo.h </dt><dd></dd></dl><dl><dt>Update drivers/video/fbcon.c to reflect the new size of the logo: </dt><dd></dd></dl><dl><dt>#define LOGO_H&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 80 </dt><dd></dd></dl><dl><dt>#define LOGO_W&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 80 </dt><dd></dd></dl><dl><dt>If you are going to compile a Linux 2.2 kernel, you have to do one additional step: </dt><dd></dd></dl><dl><dt>Edit the file linux/include/asm-&lt;arch&gt;/linux_logo.h and change to the correct LINUX_LOGO_COLORS to the right number, as pointed out when using -v or inside the linux_logo.h produced by fblogo. </dt><dd></dd></dl><dl><dt>Recompile your new kernel. </dt><dd></dd></dl></ul>
</li>
                        <li><span class="section">SEE ALSO</span> <br>
                        <ul><span class="B">fblogo_patch</span> (1) <br>
</ul>
</li>
                            <li><span class="section">AUTHOR</span> <br>
                            <ul>fblogo was originally written by Daniel Ved?y &lt;daniel@kongsberg.online.no&gt;, then adopted by Gordon Fraser &lt;gordon@debian.org&gt;. It is licensed under the terms of the GNU&nbsp;&nbsp; General Public License. </ul>
</li>
</ul> <a href="http://hi.baidu.com/flyingfat/blog/item/778a32a4fed44af69152eedd.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/flyingfat/blog/category/Framebuffer">Framebuffer</a>&nbsp;<a href="http://hi.baidu.com/flyingfat/blog/item/778a32a4fed44af69152eedd.html#comment">查看评论</a>]]></description>
        <pubDate>2007-04-09  23:31</pubDate>
        <category><![CDATA[Framebuffer]]></category>
        <author><![CDATA[flyingfat]]></author>
		<guid>http://hi.baidu.com/flyingfat/blog/item/778a32a4fed44af69152eedd.html</guid>
</item>

<item>
        <title><![CDATA[printk()的实现]]></title>
        <link><![CDATA[http://hi.baidu.com/flyingfat/blog/item/eda29735e02aa41091ef39dc.html]]></link>
        <description><![CDATA[
		
		<p>start_kernel(void)<br>
{lock_kernel();<br>
 printk(linux_banner);<br>
.....<br>
console_init();<br>
}<br>
上面的代码显示在调用console_init之前，已经使用了printk函数。那么printk函数到底是如何在console上实现呢？可否更改printk函数，重定向输出？本文给出答案。</p>
<p>printk在src/kernel/Printk.c中实现：<br>
 int printk(const char *fmt, ...)<br>
在该函数内申请了一块静态内存static char printk_buf[1024];作为输出缓冲区。也就是说，不管console是否存在，printk都可以成功返回。<br>
if (!down_trylock(&amp;console_sem)) {<br>
&nbsp;&nbsp; /*<br>
&nbsp;&nbsp;&nbsp; * We own the drivers.&nbsp;&nbsp; We can drop the spinlock and let<br>
&nbsp;&nbsp;&nbsp; * release_console_sem() print the text<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp; spin_unlock_irqrestore(&amp;logbuf_lock, flags);<br>
&nbsp;&nbsp; console_may_schedule = 0;<br>
&nbsp;&nbsp; release_console_sem();<br>
printk函数，时时刻刻希望得到当前系统的console，因此只要系统调用了console init函数，printk就可以觉察到。在下次调用printk时，printk会把printk_buf中存储的数据输出到console中。这个过程在release_console_sem();实现：<br>
for ( ; ; ) {<br>
&nbsp;&nbsp; spin_lock_irqsave(&amp;logbuf_lock, flags);<br>
&nbsp;&nbsp; must_wake_klogd |= log_start - log_end;<br>
&nbsp;&nbsp; if (con_start == log_end)<br>
&nbsp;&nbsp;&nbsp; break;&nbsp;&nbsp;&nbsp; /* Nothing to print */<br>
&nbsp;&nbsp; _con_start = con_start;<br>
&nbsp;&nbsp; _log_end = log_end;<br>
&nbsp;&nbsp; con_start = log_end;&nbsp;&nbsp; /* Flush */<br>
&nbsp;&nbsp; spin_unlock_irqrestore(&amp;logbuf_lock, flags);<br>
 <strong> call_console_drivers(_con_start, _log_end);<br>
</strong> }<br>
通过调用<strong>call_console_drivers，</strong>printk输出数据到console!<br>
<strong>call_console_drivers</strong>再次调用函数：<br>
_call_console_drivers(start_print, cur_index, msg_level);<br>
再次调用更为底层的__call_console_drivers（）实现。<br>
正是在__call_console_drivers（）中完成了对console驱动中write的调用！<br>
for (con = console_drivers; con; con = con-&gt;next) {<br>
&nbsp;&nbsp; if ((con-&gt;flags &amp; CON_ENABLED) &amp;&amp; con-&gt;write)<br>
&nbsp;&nbsp;&nbsp;<strong><font color="#ff0000">con-&gt;write(con, &amp;LOG_BUF(start), end - start);<br>
</font></strong> }<br>
</p>
<p>因此，在系统没有调用console_init();之前，printk并没有真正把数据发送到console。更改printk，可以很方便的输出到任何需要的设备上。<br>
</p> <a href="http://hi.baidu.com/flyingfat/blog/item/eda29735e02aa41091ef39dc.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/flyingfat/blog/category/Linux">Linux</a>&nbsp;<a href="http://hi.baidu.com/flyingfat/blog/item/eda29735e02aa41091ef39dc.html#comment">查看评论</a>]]></description>
        <pubDate>2007-04-09  23:29</pubDate>
        <category><![CDATA[Linux]]></category>
        <author><![CDATA[flyingfat]]></author>
		<guid>http://hi.baidu.com/flyingfat/blog/item/eda29735e02aa41091ef39dc.html</guid>
</item>


</channel>
</rss>