﻿<?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>BlogJava-Snowdream-随笔分类-System</title><link>http://www.blogjava.net/zellux/category/23657.html</link><description>I'm awake but my world is half asleep</description><language>zh-cn</language><lastBuildDate>Wed, 27 Jan 2010 13:00:00 GMT</lastBuildDate><pubDate>Wed, 27 Jan 2010 13:00:00 GMT</pubDate><ttl>60</ttl><item><title>Finding and Reproducing Heisenbugs in Concurrent Programs</title><link>http://www.blogjava.net/zellux/archive/2009/02/17/255048.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Tue, 17 Feb 2009 03:30:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2009/02/17/255048.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/255048.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2009/02/17/255048.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/255048.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/255048.html</trackback:ping><description><![CDATA[
		<p>今年的ASPLOS '09上zhou yuanyuan也有一篇关于如何concurrent program中发现隐藏的atomicity violation bugs的paper，里面提到了这篇paper<br /></p>
		<p>2008-11-30<br /></p>
		<p>OSDI '08上MSR发的paper，针对并发编程中难以发现的bug问题。</p>
		<p>paper的内容主要分两大块。</p>
		<p>一是如何在发现bug的时候记录下线程的运行先后(thread
interleaving)，途径是在线程API和用户程序多写一层wrapper
functions，这里还有一些其他的问题，比如只记录下了thread interleaving的话出现data race怎么解决等。</p>
		<p>另外一块内容是如何遍历出给定程序运行后所能产生的结果的集合，加入这个能实现的话那就能把所有隐藏的bug都找出来了。但是这个搜索空间很大，是
指数级的，的一个结论就是：给定一个程序有n个的线程，所有线程共完成k条指令，那么c次占先调度后线程的排列情况数的复杂度是<img src="http://10.132.140.73/wordpress/wp-content/cache/tex_d7c6a39b544e9306f24feffdc769cfc7.gif" class="tex" alt="k^{c}" align="absmiddle" />的，所以在实现遍历代码的时候必须有效的降低k和c的值。</p>
<img src ="http://www.blogjava.net/zellux/aggbug/255048.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2009-02-17 11:30 <a href="http://www.blogjava.net/zellux/archive/2009/02/17/255048.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Xen Notes [1]</title><link>http://www.blogjava.net/zellux/archive/2008/10/17/235056.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Fri, 17 Oct 2008 12:01:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2008/10/17/235056.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/235056.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2008/10/17/235056.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/235056.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/235056.html</trackback:ping><description><![CDATA[09月 18, 2008<br /><b>第一个testkernel在Xen中的载入</b><br /><br />The Definitive Guide to Xen中第二章的例子，make成功后运行xen create domain_config，报错<br />Error: (2, ‘Invalid kernel’, ‘xc_dom_compat_check: guest type xen-3.0-x86_32 not supported by xen kernel, sorry\n’)

<br /><br />google之后发现是虚拟机类型设置的问题，运行xm info可以看到<br />xen_caps               : xen-3.0-x86_32p

<br />末尾的p表示Xen内核开启了PAE模式，所以载入的kernel也必须开启PAE，在bootstrap.x86_32.S中加入PAE=yes选项即可。<br /><br />09月 25, 2008<br /><b>DomainU中调用do_console_io</b><br /><br />The Definitive Guide to Xen第二章的Exercise，通过调用hypercall page中的console_io项输出Hello World。<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> start_kernel(start_info_t </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> start_info)<br />{<br />    HYPERVISOR_console_io(CONSOLEIO_write,</span><span style="color: rgb(0, 0, 0);">12</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Hello World\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    </span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">);<br />}</span></div><br /><br />但是默认选项编译和启动的Xen是不会保留DomainU中输出的信息。参考drivers/char/console.c，可以看到主要有两个选项控制了DomainU的do_console_io输出：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">#ifndef VERBOSE<br />    </span><span style="color: rgb(0, 128, 0);">/*</span><span style="color: rgb(0, 128, 0);"> Only domain 0 may access the emergency console. </span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> ( current</span><span style="color: rgb(0, 0, 0);">-&amp;</span><span style="color: rgb(0, 0, 0);">gt;domain</span><span style="color: rgb(0, 0, 0);">-&amp;</span><span style="color: rgb(0, 0, 0);">gt;domain_id </span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);"> )<br />        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">EPERM;<br /></span><span style="color: rgb(0, 0, 255);">#endif</span><span style="color: rgb(0, 0, 0);"><br /><br /></span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> ( opt_console_to_ring )<br />{<br />    </span><span style="color: rgb(0, 0, 255);">for</span><span style="color: rgb(0, 0, 0);"> ( kptr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> kbuf; </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">kptr </span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">\0</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">; kptr</span><span style="color: rgb(0, 0, 0);">++</span><span style="color: rgb(0, 0, 0);"> )<br />        putchar_console_ring(</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">kptr);<br />    send_guest_global_virq(dom0, VIRQ_CON_RING);<br />}</span></div><br /><br />VERBOSE选项可以在编译Xen的时候开启debug选项，而opt_console_to_ring则是一个启动选项，在grub的启动选项中增加loglvl=all guest_loglvl=all console_to_ring即可。<br /><br />重启Xen后就能通过xm dmesg看到Hello World了。<br /><br />09月 25, 2008<br /><b>Xen: Remove support for non-PAE 32-bit</b><br /><br />看来我还是用Xen 3.1吧 = =<br /><br />Subject: [Xen-devel] [PATCH] xen: remove support for non-PAE 32-bitLink to this message<br />From: Jeremy Fitzhardinge (jer…@goop.org)<br />Date: 05/09/2008 04:05:34 AM<br />List: com.xensource.lists.xen-devel<br /><br />Non-PAE operation has been deprecated in Xen for a while, and is rarely tested or used. xen-unstable has now officially dropped non-PAE support. Since Xen/pvops’ non-PAE support has also been broken for a while, we may as well completely drop it altogether.<br /><br />10月 07, 2008<br /><b>IA-32 Memory Virtualization</b><br /><a href="http://www.intel.com/technology/itj/2006/v10i3/3-xen/4-extending-with-intel-vt.htm">http://www.intel.com/technology/itj/2006/v10i3/3-xen/4-extending-with-intel-vt.htm</a><br /><img src="http://www.blogjava.net/images/blogjava_net/zellux/27129/o_figure_3.gif" alt="o_figure_3.gif" border="0" width="370" height="487" /><br />上图为full virtulization的情况，即不修改Guest OS的行为时的解决方案。Xen为每个Guest OS维护了一张shadow page table，其中映射的地址为machine address。一种比较高效的方案是设置Guest OS的page table为只读，当Guest OS试图修改这个虚拟页表时，发生page fault被Xen截获，Xen修改shadow page table中相应的数据（把pseudo-physical address转化成machine address）。另外一个优化是guest page table被修改时不修改shadow page table，只是把它放到一个待更新列表中，等Guest OS执行了刷新tlb的指令后再一次性更新。<br /><br />The Definitive Guide to Xen上还提到了另一种基于full paravirtulization和shadow page table之间的方案。Xen把Guest OS的page table置为只读，当Guest OS试图修改page table时，Xen捕获到page fault，把page directory中对应的入口置为无效，再把page table改成可写让Guest OS修改。由于page directory中对应的入口被设成无效了，下次访问该地址时还是会发生page fault，这时候Xen再修改page directory和page table的对应项就行了。<br /><br />这种方法意味着Guest OS中内核管理模块直接和machine address打交道，而其他部分则仍然使用pseudo-physical address。另外这种情况下page directory不能被Guest OS修改。<br /><br />另外Xen还用到了段机制，用来为Xen保留地址空间开始的64M内存。<br /><img src ="http://www.blogjava.net/zellux/aggbug/235056.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2008-10-17 20:01 <a href="http://www.blogjava.net/zellux/archive/2008/10/17/235056.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>几个并行计算、内核相关的链接</title><link>http://www.blogjava.net/zellux/archive/2008/10/10/233603.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Fri, 10 Oct 2008 07:29:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2008/10/10/233603.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/233603.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2008/10/10/233603.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/233603.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/233603.html</trackback:ping><description><![CDATA[
		<p>依然是内网日志的汇总<br /><br />1. sysenter的介绍<br /><a href="http://www.codeguru.com/cpp/w-p/system/devicedriverdevelopment/article.php/c8223" target="_blank">http://www.codeguru.com/cpp/w-p/system/devicedriverdevelopment/article.php/c8223</a></p>
		<p>System Call Optimization with the SYSENTER Instruction<br />by John Gulbrandsen<br />Windows下的</p>
		<p>2. The SLUB allocator<br />slab的改进版本</p>
		<p>
				<a href="http://lwn.net/Articles/229984/" target="_blank">http://lwn.net/Articles/229984/</a>
		</p>
		<p>
				<a href="http://lwn.net/Articles/229096/" target="_blank">http://lwn.net/Articles/229096/</a>
		</p>
		<p>Christoph’s response is the <a href="http://lwn.net/Articles/229096/">SLUB allocator</a>, a drop-in replacement for the slab code. SLUB promises better performance and scalability by dropping most of the queues and related overhead and simplifying the slab structure in general, while retaining the current slab allocator interface.</p>
		<p>Wider use may be in the cards: the SLUB allocator is in the -mm tree now and could hit the mainline as soon as 2.6.22. The simplified code is attractive, as is the claimed <strong>5-10%</strong> performance increase. If merged, SLUB is likely to coexist with the current slab allocator (and the SLOB allocator intended for small systems) for some time. In the longer term, the current slab code may be approaching the end of its life.<br /><br />3. Compilers and More: Parallel Programming Made Easy? <br /><a href="http://www.hpcwire.com/features/Compilers_and_More_Parallel_Programming_Made_Easy.html" target="_blank">http://www.hpcwire.com/features/Compilers_and_More_Parallel_Programming_Made_Easy.html</a></p>
		<p>by Michael Wolfe, Compiler Engineer, The Portland Group, Inc.<br /><br />4. OpenCL slides, SIGGRAPH '08<br />发信人: jjgod (while(!asleep()) sheep++;), 信区: CSArch<br />标  题: SIGGRAPH 08 上的 OpenCL slides<br />发信站: 水木社区 (Mon Sep 15 01:32:03 2008), 站内</p>
		<p>※ 来源:·水木社区 newsmth.net·[FROM: 125.33.176.*]</p>
		<p>附件: munshi-opencl.pdf (1338 KB) 链接:<br /><a href="http://att.newsmth.net/att.php?p.272.35430.226.pdf">http://att.newsmth.net/att.php?p.272.35430.226.pdf</a><br />全文链接：<a href="http://www.newsmth.net/bbscon.php?bid=272&amp;id=35430">http://www.newsmth.net/bbscon.php?bid=272&amp;id=35430</a></p>
		<p>5. linux-gate.so<br /><a href="http://www.trilithium.com/johan/2005/08/linux-gate/">http://www.trilithium.com/johan/2005/08/linux-gate/</a><br />linux下使用sysenter的机制</p>
<img src ="http://www.blogjava.net/zellux/aggbug/233603.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2008-10-10 15:29 <a href="http://www.blogjava.net/zellux/archive/2008/10/10/233603.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OS Lab 零散记录</title><link>http://www.blogjava.net/zellux/archive/2008/10/10/233601.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Fri, 10 Oct 2008 07:21:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2008/10/10/233601.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/233601.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2008/10/10/233601.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/233601.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/233601.html</trackback:ping><description><![CDATA[转自偶的内网博客<br /><br /><strong>Time : 2008-08-20 21:44</strong><br /><strong>汇编文件中导出函数符号<br /></strong><p>Linux 2.4.18的linux/linkage.h文件定义了若干相关的宏<br /></p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000"> SYMBOL_NAME(X) X</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />#ifdef __STDC__<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000"> SYMBOL_NAME_LABEL(X) X##:</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">#else</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000"> SYMBOL_NAME_LABEL(X) X/**/:</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">#endif</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000"> __ALIGN .align 16,0x90</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000"> __ALIGN_STR ".align 16,0x90"</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000"> ALIGN __ALIGN</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000"> ALIGN_STR __ALIGN_STR</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000"> ENTRY(name) \</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  .globl SYMBOL_NAME(name); \<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  ALIGN; \<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  SYMBOL_NAME_LABEL(name)</span></div><p>用ENTRY(name)就能定义函数了。后来发现Flux OSKit中本来就提供了类似功能的宏，定义在inc/asm.h中。<br />使用的时候需要再写一个c语言的wrapper function（至少2.4.18里面是这么做的）<br />asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");</p><p><span class="posttime"><strong>Time : 2008-08-22 15:56<br />OS Lab 4 debugging notes [1]<br /></strong>系统调用 fork()</span></p><p>用Simics跟踪一条条汇编分析页表映射、寄存器值还真是体力活啊。。</p><p>1. 实现Copy On Write时，如果某一个用户态页面有多个进程共享，其中一个进程修改该页面时需要创建一个新的页面。一开始偶忘了把原来页面的内容复制到新的页面了 =_= 另外由于新的页面要代替老的页面，或者说它们的物理地址不同，但虚拟地址相同，我的方法是在内核态开辟一个大小为一个页面的空间作为中转。</p><p>2. do_fork函数中，子进程复制父进程的页表的同时会把父进程页表项置为不可写，注意最后要flush tlb。因为一开始没有flush tlb，导致最后用户态fork返回以后读取的信息来自于tlb，直接改写了共享页面中fork的返回地址，导致切换到子进程时fork的返回地址丢失。这个bug让我郁闷了两三个小时。。</p><p>3. 使用两次fork时，第二次fork返回的pid会被改掉。查了下发现为用户空间分配物理页面的代码里居然在分配好以后没有把对应的struct置为已使用，结果导致第二个子进程COW创建新页面时得到了原来的父进程页面，改写了父进程页面内容。<br /><br /></p><span class="posttime"><strong>Time : 2008-08-23 19:41<br />OS Lab4 debugging notes [2]</strong>  <br />系统调用 exec()
<p>1. 清空页表的用户空间映射的函数一开始写得yts，bug到处都是，比如free的时候没使用指向内存块首地址的指针，记录内存地址的变量没有累加。</p><p>2. exec传递给内核态的两个参数必须先在内核态保存一个副本，否则清空用户态页表后就无法得到这两个参数信息了。</p><p>3. 分配给用户态的页面必须先清零，一方面考虑到安全性，另一方面不清零会隐藏一些潜在的bug。一开始我没有在内核执行exec的时候完整的复制所有的参数，而是直接指向了原进程的内存空间，由于清空页表后再次申请新页表时得到了原来的页面，结果正好原来那个保存参数的页面和新进程的该页面重合了 =_= 于是浪费了不少时间在这个bug上</p><p><strong>Time : 2008-08-31 1:18<br />OS Lab5 debugging notes</strong><br />还算顺利，不过这个lab蛮无聊的，等有空了把syscall改成类似linux的做法，单一中断号+寄存器选择syscall。</p><p>1. 最花时间的一个bug是ls返回值没有改成应用程序数，结果一开始一直以为是brk系统调用没写好，最后才发现问题出在这么小的地方。</p><p>2. brk的逻辑还不是很清楚，尽管通过了简单的测试，但是debug输出的信息显示brk增长的很快，经常是一个页一个页涨的，看来还得查下brk的具体行为。</p><p>3. 写了个比MAGIC_BREAK好用一点的宏，因为用户态的程序都是按二进制读入的，Simics无法得到函数信息（函数名、当前行数等），利用C99的宏写了个新的INFO_BREAK<br /></p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000"> INFO_BREAK \</span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_29_130_Open_Image" onclick="this.style.display='none'; Codehighlighter1_29_130_Open_Text.style.display='none'; Codehighlighter1_29_130_Closed_Image.style.display='inline'; Codehighlighter1_29_130_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_29_130_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_29_130_Closed_Text.style.display='none'; Codehighlighter1_29_130_Open_Image.style.display='inline'; Codehighlighter1_29_130_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"> </span><span id="Codehighlighter1_29_130_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_29_130_Open_Text"><span style="COLOR: #000000">{  \<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        lprintf_kern(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">break in %s:%d</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, __FUNCTION__, __LINE__); \<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        MAGIC_BREAK; \<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000"> (</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">) \</span></div></span><img src ="http://www.blogjava.net/zellux/aggbug/233601.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2008-10-10 15:21 <a href="http://www.blogjava.net/zellux/archive/2008/10/10/233601.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OSLab之中断处理 </title><link>http://www.blogjava.net/zellux/archive/2008/09/02/226312.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Tue, 02 Sep 2008 03:55:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2008/09/02/226312.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/226312.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2008/09/02/226312.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/226312.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/226312.html</trackback:ping><description><![CDATA[发信人: <a href="http://bbs.fudan.edu.cn/cgi-bin/bbs/bbsqry?userid=Zellux">Zellux</a> (null), 信区: Software_06<br />标  题: OSLab之中断处理<br />发信站: 日月光华 (2008年08月30日20:15:58 星期六), 站内信件<br /><br />1. 准备工作<br />在开始分析Support Code之前，先配置下我们的Source Insight，使它能够支持.s文件的搜索。<br /><br />在Options-&gt;Document Options-&gt;Document Types中选择x86 Asm Source File，在File fileter中增加一个*.s，变成*.asm;*.inc;*.s  然后在Project-&gt;Add and Remove <br />Project Files中重新将整个oslab的目录加入，这样以后进行文本搜索时.s文件也不会漏掉了。<br /><br />2. Source Insight使用<br />接下来简单分析下内核启动的过程，在浏览代码的过程中可以迅速的掌握Source Insight的使用技巧。<br /><br />lib/multiboot /multiboot.s完成了初始化工作，可以看到其中一句call <br />EXT(multiboot_main)调用了C函数multiboot_main，使用ctrl+/搜索包含multiboot_main的所有文件，最终base_multiboot_main.c中找到了它的定义。依次进行cpu、内存的初<br />始化，然后开启中断，跳转到kernel_main函数，也是Lab1中所要改写的函数之一。另外<br />在这里可以通过ctrl+单击或者ctrl+=跳转到相应的函数定义处，很方便。<br /><br />3. irq处理初始化工作<br />来看下Lab 1的重点之一，irq的处理。跟踪multiboot_main-&gt;base_cpu_setup-&gt;base_cp<br />u_init-&gt;base_irq_init，可以看到这行代码<br />gate_init(base_idt, base_irq_inittab, KERNEL_CS);<br />继续使用ctrl+/找到base_irq_inittab的藏身之处：base_irq_inittab.s<br /><br />4. base_irq_inittab.s<br />这个汇编文件做了不少重复性工作，方便我们在c语言级别实现各种handler。<br />GATE_INITTAB_BEGIN(base_irq_inittab)   /* irq处理函数表的起始，还记得jump<br />                                          table 吗？ */<br />MASTER(0, 0)                           /* irq0 对应的函数 */<br /><br /><br />来看看这个MASTER(0, 0)宏展开后是什么样子：<br />#define MASTER(irq, num)                        \<br />    GATE_ENTRY(BASE_IRQ_MASTER_BASE + (num), 0f, ACC_PL_K|ACC_INTR_GATE) ;\<br />    P2ALIGN(TEXT_ALIGN)                     ;\<br />0:                                  ;\<br />    pushl   $(irq)          /* error code = irq vector */   ;\<br />    pushl   $BASE_IRQ_MASTER_BASE + (num)   /* trap number */   ;\<br />    pusha               /* save general registers */    ;\<br />    movl    $(irq),%ecx     /* irq vector number */     ;\<br />    movb    $1 &lt;&lt; num,%dl       /* pic mask for this irq */ ;\<br />    jmp master_ints<br /><br />依次push irq号，trap号（0x20+irq号），通用寄存器（eax ecx等）入栈，把irq号保<br />存到ecx寄存器，然后跳转到master_ints，master_ints是所有master interrupts公用<br />的代码。<br /><br />跳过master_ints的前几行，从第七行开始<br />    /* Acknowledge the interrupt */<br />    movb    $0x20,%al<br />    outb    %al,$0x20<br /><br />    /* Save the rest of the standard trap frame (oskit/x86/base_trap.h). */<br />    pushl   %ds<br />    pushl   %es<br />    pushl   %fs<br />    pushl   %gs<br /><br />    /* Load the kernel's segment registers.  */<br />    movw    %ss,%dx<br />    movw    %dx,%ds<br />    movw    %dx,%es<br /><br />    /* Increment the hardware interrupt nesting counter */<br />    incb    EXT(base_irq_nest)<br /><br />    /* Load the handler vector */<br />    movl    EXT(base_irq_handlers)(,%ecx,4),%esi<br /><br />注释写得很详细，首先发送0x20到0x20端口，也就是Lab1文档上所说的发送INT_CTL_DON<br />E到INT_CTL_REG，看来这一步support code已经替我们完成了。接下来保存四个段寄存<br />器ds es fs gs，并读入kernel态的段寄存器信息。<br /><br />最后一句很关键，把base_irq_handlers + %ecx * 4这个值保存到了esi寄存器中，%ecx<br />中保存了irq号，而*4则是一个函数指针的大小，那么base_irq_handlers是什么呢？继<br />续用ctrl+/搜索，可以在base_irq.c中找到这个数组的定义<br />unsigned int (*base_irq_handlers[BASE_IRQ_COUNT])(struct trap_state *ts)<br />且初始时这个数组的每一项都是base_irq_default_handler<br /><br />看来这句汇编代码的功能是把处理irq对应的函数地址保存到了esi寄存器中。<br />为了证实这一点，继续看base_irq_inittab.s的代码：<br />#else<br />    /* Call the interrupt handler with the trap frame as a parameter */<br />    pushl   %esp<br />    call    *%esi<br />    popl    %edx<br />#endif<br />果然，在保存了esp值后，紧接着就调用了esi指向的那个函数。而从那个函数返回后，<br />之前在栈上保存的相关信息都被恢复了：<br /><br />    /* blah blah blah */<br />    /* Return from the interrupt */<br />    popl    %gs<br />    popl    %fs<br />    popl    %es<br />    popl    %ds<br />    popa<br />    addl    $4*2,%esp   /* Pop trap number and error code */<br />    iret<br />这样就恢复到了进入这个irq处理单元前的状态，文档中所要求的保存通用寄存器这一步<br />其实在这里也已经完成了，不需要我们自己写代码。<br /><br />好了，这样一分析后，我们要做的事情就很简单，就是把base_irq_handlers数组中的对<br />应项改成相应的handler函数就行了。<br />注意index是相应的idt_entry号减去BASE_IRQ_SLAVE_BASE，或者直接使用IRQ号。 <br /><br />另外这个数组的初始值都是base_irq_default_handler，用ctrl+左键跳到这个函数的定<br />义，可以看到这个函数只有一句简单的输出语句：<br />    printf("Unexpected interrupt %d\n", ts-&gt;err);<br />而这就是没有注册handler前我们所看到的那句Unexpected interrupt 0的来源了。 <br /><br />5. struct trap_state *ts<br />所有的handler函数的参数都是一个struct trap_state *ts，这个参数是哪来的呢？<br />注意call *%esi的前一行<br />    /* Call the interrupt handler with the trap frame as a parameter */<br />    pushl   %esp<br />这里把当前的esp当作指向ts的指针传给了handler，列一下从esp指向的地址开始的内容<br />，也就是在此之前push入栈的内容： <br /><br />    pushl   $(irq)          /* error code = irq vector */   ;\<br />    pushl   $BASE_IRQ_MASTER_BASE + (num)   /* trap number */   ;\<br />    pusha               /* save general registers */    ;\<br />    pushl   %ds<br />    pushl   %es<br />    pushl   %fs<br />    pushl   %gs <br /><br />再看一下trap_state的定义，你会发现正好和push的顺序相反：<br />    /* Saved segment registers */<br />    unsigned int    gs;<br />    unsigned int    fs;<br />    unsigned int    es;<br />    unsigned int    ds; <br /><br />    /* PUSHA register state frame */<br />    unsigned int    edi;<br />    unsigned int    esi;<br />    unsigned int    ebp;<br />    unsigned int    cr2;    /* we save cr2 over esp for page faults */<br />    unsigned int    ebx;<br />    unsigned int    edx;<br />    unsigned int    ecx;<br />    unsigned int    eax; <br /><br />    /* Processor trap number, 0-31.  */<br />    unsigned int    trapno; <br /><br />    /* Error code pushed by the processor, 0 if none.  */<br />    unsigned int    err; <br /><br />而这个定义后面的<br />    /* Processor state frame */<br />    unsigned int    eip;<br />    unsigned int    cs;<br />    unsigned int    eflags;<br />    unsigned int    esp;<br />    unsigned int    ss;<br />则是发生interrupt时硬件自动push的五个数据（参见Understand the Linux Kernel） <br /><br />也就是说，ts指针指向的是调用当前handler前的寄存器状态，也是当前handler结束后<br />用来恢复的寄存器状态，了解这一点对以后的几个lab帮助很大。 <br /><br />p.s. 另外提一句和这个lab无关的话，非vm86模式下栈上是不会有v86_es等四个寄存器<br />信息的，所以以后根据task_struct指针计算*ts的地址时使用的偏移量不应该是sizeof(<br />struct trap_state) <br /><br />6. The End<br />这样差不多就把support code中处理interrupt的方法过了一遍（另外还有base_trap_in<br />ittab.s，不过和irq的处理很相似）<br /><br />了解这些后Lab1就比较简单了，不需要任何内嵌汇编代码即可完成。<br /><img src ="http://www.blogjava.net/zellux/aggbug/226312.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2008-09-02 11:55 <a href="http://www.blogjava.net/zellux/archive/2008/09/02/226312.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>最近读的两篇paper</title><link>http://www.blogjava.net/zellux/archive/2008/05/20/201737.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Tue, 20 May 2008 12:18:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2008/05/20/201737.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/201737.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2008/05/20/201737.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/201737.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/201737.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一篇介绍一种全新的Web架构，另一篇介绍虚拟机的探测方法&nbsp;&nbsp;<a href='http://www.blogjava.net/zellux/archive/2008/05/20/201737.html'>阅读全文</a><img src ="http://www.blogjava.net/zellux/aggbug/201737.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2008-05-20 20:18 <a href="http://www.blogjava.net/zellux/archive/2008/05/20/201737.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Anti-CAPTCHA</title><link>http://www.blogjava.net/zellux/archive/2008/04/18/193899.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Thu, 17 Apr 2008 16:30:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2008/04/18/193899.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/193899.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2008/04/18/193899.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/193899.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/193899.html</trackback:ping><description><![CDATA[贴几个链接，以后有空再看<br /><br />Microsoft Live Mail  <a href="http://securitylabs.websense.com/content/Blogs/3063.aspx">http://securitylabs.websense.com/content/Blogs/3063.aspx</a>#<br /><a href="http://securitylabs.websense.com/content/Blogs/2907.aspx">http://securitylabs.websense.com/content/Blogs/2907.aspx</a><br /><br />Google <a href="http://securitylabs.websense.com/content/Blogs/2919.aspx">http://securitylabs.websense.com/content/Blogs/2919.aspx</a>#<br /><br /><img src ="http://www.blogjava.net/zellux/aggbug/193899.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2008-04-18 00:30 <a href="http://www.blogjava.net/zellux/archive/2008/04/18/193899.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>读核笔记(6) - 虚拟存储</title><link>http://www.blogjava.net/zellux/archive/2008/02/27/182436.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Wed, 27 Feb 2008 15:29:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2008/02/27/182436.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/182436.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2008/02/27/182436.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/182436.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/182436.html</trackback:ping><description><![CDATA[
		<p>本来想看完pagefault的处理的，不过实验室有事情了，只能先把这一半放上来了。</p>
		<p>页面的分配与回收使用了一个叫做buddy allocator的机制，kernelnewbies上的解释<br />The memory allocation scheme used in the kernel. A vector of lists of free pages is kept, ordered by the size of the chunk (in powers of two). When a chunk is allocated, it is removed from the relevant list. When a chunk is freed back to the free pages pool, it is placed in the relevant list, starting from the top. If it is physically contiguous with a present chunk, they are merged and placed in the list above (i.e. where the chunks are twice the size), and this operation percolates up the vector. As regions are merged whenever possible, this design helps to reduce memory fragmentation.<br /><br />首先在zone_struct{} 中保存了一个free_area_t数组，这个数组记录了各种大小的空闲内存块的信息。<br />include/linux/mmzone.h:<br /></p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img id="Code_Closed_Image_105742" onclick="this.style.display='none'; Code_Closed_Text_105742.style.display='none'; Code_Open_Image_105742.style.display='inline'; Code_Open_Text_105742.style.display='inline';" height="16" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" width="11" align="top" />
				<img id="Code_Open_Image_105742" style="DISPLAY: none" onclick="this.style.display='none'; Code_Open_Text_105742.style.display='none'; Code_Closed_Image_105742.style.display='inline'; Code_Closed_Text_105742.style.display='inline';" height="16" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" width="11" align="top" />
				<span id="Code_Closed_Text_105742" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
				</span>
				<span id="Code_Open_Text_105742" style="DISPLAY: none">
						<br />
						<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
						<img id="Codehighlighter1_0_294_Open_Image" onclick="this.style.display='none'; Codehighlighter1_0_294_Open_Text.style.display='none'; Codehighlighter1_0_294_Closed_Image.style.display='inline'; Codehighlighter1_0_294_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
						<img id="Codehighlighter1_0_294_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_0_294_Closed_Text.style.display='none'; Codehighlighter1_0_294_Open_Image.style.display='inline'; Codehighlighter1_0_294_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" />
						<span id="Codehighlighter1_0_294_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span>
						<span id="Codehighlighter1_0_294_Open_Text">
								<span style="COLOR: #008000">/*</span>
								<span style="COLOR: #008000">
										<br />
										<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /> * On machines where it is needed (eg PCs) we divide physical memory<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /> * into multiple physical zones. On a PC we have 3 zones:<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /> *<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /> * ZONE_DMA      &lt; 16 MB    ISA DMA capable memory<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /> * ZONE_NORMAL    16-896 MB    direct mapped by the kernel<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /> * ZONE_HIGHMEM     &gt; 896 MB    only page cache and user processes<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" /> </span>
								<span style="COLOR: #008000">*/</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<img id="Codehighlighter1_323_872_Open_Image" onclick="this.style.display='none'; Codehighlighter1_323_872_Open_Text.style.display='none'; Codehighlighter1_323_872_Closed_Image.style.display='inline'; Codehighlighter1_323_872_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
								<img id="Codehighlighter1_323_872_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_323_872_Closed_Text.style.display='none'; Codehighlighter1_323_872_Open_Image.style.display='inline'; Codehighlighter1_323_872_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" />typedef </span>
						<span style="COLOR: #0000ff">struct</span>
						<span style="COLOR: #000000"> zone_struct </span>
						<span id="Codehighlighter1_323_872_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.blogjava.net/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_323_872_Open_Text">
								<span style="COLOR: #000000">{<br /><img id="Codehighlighter1_326_362_Open_Image" onclick="this.style.display='none'; Codehighlighter1_326_362_Open_Text.style.display='none'; Codehighlighter1_326_362_Closed_Image.style.display='inline'; Codehighlighter1_326_362_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_326_362_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_326_362_Closed_Text.style.display='none'; Codehighlighter1_326_362_Open_Image.style.display='inline'; Codehighlighter1_326_362_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
								<span id="Codehighlighter1_326_362_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span>
								<span id="Codehighlighter1_326_362_Open_Text">
										<span style="COLOR: #008000">/*</span>
										<span style="COLOR: #008000">
												<br />
												<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />     * Commonly accessed fields:<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />     </span>
										<span style="COLOR: #008000">*/</span>
								</span>
								<span style="COLOR: #000000">
										<br />
										<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    spinlock_t        </span>
								<span style="COLOR: #0000ff">lock</span>
								<span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    unsigned </span>
								<span style="COLOR: #0000ff">long</span>
								<span style="COLOR: #000000">        free_pages;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    unsigned </span>
								<span style="COLOR: #0000ff">long</span>
								<span style="COLOR: #000000">        pages_min, pages_low, pages_high;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
								<span style="COLOR: #0000ff">int</span>
								<span style="COLOR: #000000">            need_balance;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img id="Codehighlighter1_484_524_Open_Image" onclick="this.style.display='none'; Codehighlighter1_484_524_Open_Text.style.display='none'; Codehighlighter1_484_524_Closed_Image.style.display='inline'; Codehighlighter1_484_524_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_484_524_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_484_524_Closed_Text.style.display='none'; Codehighlighter1_484_524_Open_Image.style.display='inline'; Codehighlighter1_484_524_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
								<span id="Codehighlighter1_484_524_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span>
								<span id="Codehighlighter1_484_524_Open_Text">
										<span style="COLOR: #008000">/*</span>
										<span style="COLOR: #008000">
												<br />
												<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />     * free areas of different sizes<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />     </span>
										<span style="COLOR: #008000">*/</span>
								</span>
								<span style="COLOR: #000000">
										<br />
										<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> 数组中每个元素依次维护1个pagesize，2个pagesize，4个pagesize……的空闲块的链表</span>
								<span style="COLOR: #008000">
										<br />
										<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />
								</span>
								<span style="COLOR: #000000">    free_area_t        free_area[MAX_ORDER];  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img id="Codehighlighter1_626_669_Open_Image" onclick="this.style.display='none'; Codehighlighter1_626_669_Open_Text.style.display='none'; Codehighlighter1_626_669_Closed_Image.style.display='inline'; Codehighlighter1_626_669_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_626_669_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_626_669_Closed_Text.style.display='none'; Codehighlighter1_626_669_Open_Image.style.display='inline'; Codehighlighter1_626_669_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
								<span id="Codehighlighter1_626_669_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span>
								<span id="Codehighlighter1_626_669_Open_Text">
										<span style="COLOR: #008000">/*</span>
										<span style="COLOR: #008000">
												<br />
												<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />     * Discontig memory support fields.<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />     </span>
										<span style="COLOR: #008000">*/</span>
								</span>
								<span style="COLOR: #000000">
										<br />
										<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
								<span style="COLOR: #0000ff">struct</span>
								<span style="COLOR: #000000"> pglist_data    </span>
								<span style="COLOR: #000000">*</span>
								<span style="COLOR: #000000">zone_pgdat;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
								<span style="COLOR: #0000ff">struct</span>
								<span style="COLOR: #000000"> page        </span>
								<span style="COLOR: #000000">*</span>
								<span style="COLOR: #000000">zone_mem_map;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    unsigned </span>
								<span style="COLOR: #0000ff">long</span>
								<span style="COLOR: #000000">        zone_start_paddr;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    unsigned </span>
								<span style="COLOR: #0000ff">long</span>
								<span style="COLOR: #000000">        zone_start_mapnr;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img id="Codehighlighter1_803_833_Open_Image" onclick="this.style.display='none'; Codehighlighter1_803_833_Open_Text.style.display='none'; Codehighlighter1_803_833_Closed_Image.style.display='inline'; Codehighlighter1_803_833_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_803_833_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_803_833_Closed_Text.style.display='none'; Codehighlighter1_803_833_Open_Image.style.display='inline'; Codehighlighter1_803_833_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
								<span id="Codehighlighter1_803_833_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span>
								<span id="Codehighlighter1_803_833_Open_Text">
										<span style="COLOR: #008000">/*</span>
										<span style="COLOR: #008000">
												<br />
												<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />     * rarely used fields:<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />     </span>
										<span style="COLOR: #008000">*/</span>
								</span>
								<span style="COLOR: #000000">
										<br />
										<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
								<span style="COLOR: #0000ff">char</span>
								<span style="COLOR: #000000">            </span>
								<span style="COLOR: #000000">*</span>
								<span style="COLOR: #000000">name;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    unsigned </span>
								<span style="COLOR: #0000ff">long</span>
								<span style="COLOR: #000000">        size;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
						</span>
						<span style="COLOR: #000000"> zone_t;</span>
				</span>
		</div>
		<br />free_area_struct {}<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Code_Closed_Image_110231" onclick="this.style.display='none'; Code_Closed_Text_110231.style.display='none'; Code_Open_Image_110231.style.display='inline'; Code_Open_Text_110231.style.display='inline';" height="16" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" width="11" align="top" /><img id="Code_Open_Image_110231" style="DISPLAY: none" onclick="this.style.display='none'; Code_Open_Text_110231.style.display='none'; Code_Closed_Image_110231.style.display='inline'; Code_Closed_Text_110231.style.display='inline';" height="16" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" width="11" align="top" /><span id="Code_Closed_Text_110231" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span><span id="Code_Open_Text_110231" style="DISPLAY: none"><br /><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><img id="Codehighlighter1_32_112_Open_Image" onclick="this.style.display='none'; Codehighlighter1_32_112_Open_Text.style.display='none'; Codehighlighter1_32_112_Closed_Image.style.display='inline'; Codehighlighter1_32_112_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_32_112_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_32_112_Closed_Text.style.display='none'; Codehighlighter1_32_112_Open_Image.style.display='inline'; Codehighlighter1_32_112_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #000000">typedef </span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000"> free_area_struct </span><span id="Codehighlighter1_32_112_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_32_112_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000"> list_head    free_list;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    unsigned </span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">        </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">map;       </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 某个特定大小的页面块分配情况的位图</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" /></span><span style="COLOR: #000000">}</span></span><span style="COLOR: #000000"> free_area_t;</span></span></div><br />页面分配时，找到适合大小的free_area_struct{}，然后从free_list中找有没有空闲的内存块，如果没有就找更大的free_area_struct{}，因为大小都是2^n，很容易把大块内存拆开，一块分配给请求，剩下的保存到对应大小的队列中。<br />页面回收时主要的问题是如何解决过多的内存碎片。当页面块被释放时，先检查是否有相同大小的相邻空闲块存在，如果有的话就结合起来（递归过程）。<img src ="http://www.blogjava.net/zellux/aggbug/182436.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2008-02-27 23:29 <a href="http://www.blogjava.net/zellux/archive/2008/02/27/182436.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Patching CVE-2008-0600, Local Root Exploit</title><link>http://www.blogjava.net/zellux/archive/2008/02/27/182572.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Wed, 27 Feb 2008 15:15:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2008/02/27/182572.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/182572.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2008/02/27/182572.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/182572.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/182572.html</trackback:ping><description><![CDATA[几天前的bug了，突然有兴趣想再试试<br /><a href="http://kerneltrap.org/Linux/Patching_CVE-2008-0600_Local_Root_Exploit"><br />http://kerneltrap.org/Linux/Patching_CVE-2008-0600_Local_Root_Exploit</a><img src ="http://www.blogjava.net/zellux/aggbug/182572.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2008-02-27 23:15 <a href="http://www.blogjava.net/zellux/archive/2008/02/27/182572.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[zz]LKM Rootkits on Linux x86 v2.6</title><link>http://www.blogjava.net/zellux/archive/2008/02/26/182289.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Tue, 26 Feb 2008 11:36:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2008/02/26/182289.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/182289.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2008/02/26/182289.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/182289.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/182289.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 转载自水木KernelTech版。关于hack系统调用表的一篇文章，里面还涉及了上学期ICS Lab中的二进制代码注入，很好很强大。略作整理（为什么技术博客默认的字体不是等宽的 T.T）=-|================================================-{ www.enye-sec.org }-====|=-[ LKM Rootkits on Linux x86...&nbsp;&nbsp;<a href='http://www.blogjava.net/zellux/archive/2008/02/26/182289.html'>阅读全文</a><img src ="http://www.blogjava.net/zellux/aggbug/182289.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2008-02-26 19:36 <a href="http://www.blogjava.net/zellux/archive/2008/02/26/182289.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>信号量使用例程 </title><link>http://www.blogjava.net/zellux/archive/2008/02/21/181074.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Thu, 21 Feb 2008 07:13:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2008/02/21/181074.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/181074.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2008/02/21/181074.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/181074.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/181074.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Unix - semaphore examplehttp://docs.linux.cz/programming/c/unix_examples/semab.htmlCode highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->/**//* semabinit.c ...&nbsp;&nbsp;<a href='http://www.blogjava.net/zellux/archive/2008/02/21/181074.html'>阅读全文</a><img src ="http://www.blogjava.net/zellux/aggbug/181074.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2008-02-21 15:13 <a href="http://www.blogjava.net/zellux/archive/2008/02/21/181074.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>读核笔记(5) - 共享内存</title><link>http://www.blogjava.net/zellux/archive/2008/02/21/181046.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Thu, 21 Feb 2008 06:10:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2008/02/21/181046.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/181046.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2008/02/21/181046.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/181046.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/181046.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: ipc/shm.c:				sys_shmat 连接共享内存																																		Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->														...&nbsp;&nbsp;<a href='http://www.blogjava.net/zellux/archive/2008/02/21/181046.html'>阅读全文</a><img src ="http://www.blogjava.net/zellux/aggbug/181046.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2008-02-21 14:10 <a href="http://www.blogjava.net/zellux/archive/2008/02/21/181046.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hacking the Kernel - 修改系统调用表</title><link>http://www.blogjava.net/zellux/archive/2008/02/19/180686.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Tue, 19 Feb 2008 06:55:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2008/02/19/180686.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/180686.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2008/02/19/180686.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/180686.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/180686.html</trackback:ping><description><![CDATA[昨天硬是没找到正确的sys_call_table的地址，原来我之前在虚拟机上装的ArchLinux是64位的。。<br />今天在真机上成功地修改了系统调用表。<br />测试环境：ArchLinux 2.6.24<br /><br />1. 2.4.20以后的内核出于安全考虑，没有导出sys_call_table符号，所以要先通过System.map找到sys_call_table的地址<br /><u>$ cat /boot/System.map26 | grep sys_call_table</u><br />c0375680 R sys_call_table<br />另外也可以用nm工具获得vmlinux中的所有符号<br /><u>$ nm /usr/src/linux-2.6.24-ARCH/vmlinux | grep sys_call_table</u><br />结果一样<br /><br />2. 以添加一个把uid改成root(0)为例，写一个内核模块：<br />addcall.c<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Code_Closed_Image_145101" onclick="this.style.display='none'; Code_Closed_Text_145101.style.display='none'; Code_Open_Image_145101.style.display='inline'; Code_Open_Text_145101.style.display='inline';" height="16" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" width="11" align="top" /><img id="Code_Open_Image_145101" style="DISPLAY: none" onclick="this.style.display='none'; Code_Open_Text_145101.style.display='none'; Code_Closed_Image_145101.style.display='inline'; Code_Closed_Text_145101.style.display='inline';" height="16" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" width="11" align="top" /><span id="Code_Closed_Text_145101" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span><span id="Code_Open_Text_145101" style="DISPLAY: none"><br /><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">#include </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">linux</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">kernel.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />#include </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">linux</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">module.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />#include </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">linux</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">init.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />#include </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">linux</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">unistd.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />#include </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">linux</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">time.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />#include </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">asm</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">uaccess.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />#include </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">linux</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">sched.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000"> __NR_changeuid 238</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />MODULE_DESCRIPTION(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Change uid to 0</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />MODULE_AUTHOR(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">ZelluX</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> (</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">saved) (</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">**</span><span style="COLOR: #000000"> sys_call_table </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xc0375680</span><span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />asmlinkage </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> sys_changeuid(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">)<br /><img id="Codehighlighter1_372_507_Open_Image" onclick="this.style.display='none'; Codehighlighter1_372_507_Open_Text.style.display='none'; Codehighlighter1_372_507_Closed_Image.style.display='inline'; Codehighlighter1_372_507_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_372_507_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_372_507_Closed_Text.style.display='none'; Codehighlighter1_372_507_Open_Image.style.display='inline'; Codehighlighter1_372_507_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_372_507_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_372_507_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    current</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">uid </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> current</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">euid </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> current</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">suid </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> current</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">fsuid </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    printk(KERN_ALERT </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">uid has been changed.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> __init init_addsyscall(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">)<br /><img id="Codehighlighter1_543_741_Open_Image" onclick="this.style.display='none'; Codehighlighter1_543_741_Open_Text.style.display='none'; Codehighlighter1_543_741_Closed_Image.style.display='inline'; Codehighlighter1_543_741_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_543_741_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_543_741_Closed_Text.style.display='none'; Codehighlighter1_543_741_Open_Image.style.display='inline'; Codehighlighter1_543_741_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_543_741_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_543_741_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    saved </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> (</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">) (</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">)) (sys_call_table[__NR_changeuid]);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    sys_call_table[__NR_changeuid] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (unsigned </span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">) sys_changeuid;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    printk(KERN_ALERT </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">the call has been added.</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> __exit exit_addsyscall(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">)<br /><img id="Codehighlighter1_778_892_Open_Image" onclick="this.style.display='none'; Codehighlighter1_778_892_Open_Text.style.display='none'; Codehighlighter1_778_892_Closed_Image.style.display='inline'; Codehighlighter1_778_892_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_778_892_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_778_892_Closed_Text.style.display='none'; Codehighlighter1_778_892_Open_Image.style.display='inline'; Codehighlighter1_778_892_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_778_892_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_778_892_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    sys_call_table[__NR_changeuid] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (unsigned </span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">) saved;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    printk(KERN_ALERT </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">the call has been removed</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />module_init(init_addsyscall);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />module_exit(exit_addsyscall);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></span></div><br />对应的Makefile：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Code_Closed_Image_145203" onclick="this.style.display='none'; Code_Closed_Text_145203.style.display='none'; Code_Open_Image_145203.style.display='inline'; Code_Open_Text_145203.style.display='inline';" height="16" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" width="11" align="top" /><img id="Code_Open_Image_145203" style="DISPLAY: none" onclick="this.style.display='none'; Code_Open_Text_145203.style.display='none'; Code_Closed_Image_145203.style.display='inline'; Code_Closed_Text_145203.style.display='inline';" height="16" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" width="11" align="top" /><span id="Code_Closed_Text_145203" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span><span id="Code_Open_Text_145203" style="DISPLAY: none"><br /><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">ifneq ($(KERNELRELEASE)</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    obj-m :</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> addcall.o<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />else<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    KERNELDIR ?</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> /lib/modules/$(shell uname -r)/build<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    PWD  :</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> $(shell pwd)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />default:<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        $(MAKE) -C $(KERNELDIR) M</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">$(PWD) modules<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />endif<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></span></div><br />3. 使用insmod addcall.ko载入模块后，用dmesg可以看到the call has been added.<br />4. 测试程序<br />test.c<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Code_Closed_Image_145325" onclick="this.style.display='none'; Code_Closed_Text_145325.style.display='none'; Code_Open_Image_145325.style.display='inline'; Code_Open_Text_145325.style.display='inline';" height="16" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" width="11" align="top" /><img id="Code_Open_Image_145325" style="DISPLAY: none" onclick="this.style.display='none'; Code_Open_Text_145325.style.display='none'; Code_Closed_Image_145325.style.display='inline'; Code_Closed_Text_145325.style.display='inline';" height="16" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" width="11" align="top" /><span id="Code_Closed_Text_145325" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span><span id="Code_Open_Text_145325" style="DISPLAY: none"><br /><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">#include </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">linux</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">unistd.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />#include </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">stdio.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000"> __NR_changeuid 238</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> main()<br /><img id="Codehighlighter1_85_245_Open_Image" onclick="this.style.display='none'; Codehighlighter1_85_245_Open_Text.style.display='none'; Codehighlighter1_85_245_Closed_Image.style.display='inline'; Codehighlighter1_85_245_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_85_245_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_85_245_Closed_Text.style.display='none'; Codehighlighter1_85_245_Open_Image.style.display='inline'; Codehighlighter1_85_245_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_85_245_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_85_245_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Previous uid = %d\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, syscall(__NR_getuid));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    syscall(__NR_changeuid);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Current uid = %d\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, syscall(__NR_getuid));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000"><br /></span></span></div><br />使用gcc -o test test.c编译<br /><br />5. 运行./test，即可看到类似的成功信息：<br />Previous uid = 1002<br />Current uid = 0<br /><br />6. 卸载模块rmmod addcall，此时再次运行./test就会失败<img src ="http://www.blogjava.net/zellux/aggbug/180686.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2008-02-19 14:55 <a href="http://www.blogjava.net/zellux/archive/2008/02/19/180686.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>读核笔记(4) - 共享内存</title><link>http://www.blogjava.net/zellux/archive/2008/02/19/180612.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Tue, 19 Feb 2008 03:30:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2008/02/19/180612.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/180612.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2008/02/19/180612.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/180612.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/180612.html</trackback:ping><description><![CDATA[《边干边学》上一个简单的共享内存的例程：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Code_Closed_Image_110509" onclick="this.style.display='none'; Code_Closed_Text_110509.style.display='none'; Code_Open_Image_110509.style.display='inline'; Code_Open_Text_110509.style.display='inline';" height="16" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" width="11" align="top" /><img id="Code_Open_Image_110509" style="DISPLAY: none" onclick="this.style.display='none'; Code_Open_Text_110509.style.display='none'; Code_Closed_Image_110509.style.display='inline'; Code_Closed_Text_110509.style.display='inline';" height="16" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" width="11" align="top" /><span id="Code_Closed_Text_110509" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span><span id="Code_Open_Text_110509" style="DISPLAY: none"><br /><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">#include </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">unistd.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />#include </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">sys</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">ipc.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />#include </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">sys</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">shm.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />#include </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">errno.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />#include </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">stdio.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />#include </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000"> KEY 1234</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000"> SIZE 1024</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> main()<br /><img id="Codehighlighter1_168_1479_Open_Image" onclick="this.style.display='none'; Codehighlighter1_168_1479_Open_Text.style.display='none'; Codehighlighter1_168_1479_Closed_Image.style.display='inline'; Codehighlighter1_168_1479_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_168_1479_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_168_1479_Closed_Text.style.display='none'; Codehighlighter1_168_1479_Open_Image.style.display='inline'; Codehighlighter1_168_1479_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_168_1479_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_168_1479_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> shmid;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">shmaddr;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000"> shmid_ds buf;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    shmid </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> shmget(KEY, SIZE, IPC_CREAT </span><span style="COLOR: #000000">|</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0600</span><span style="COLOR: #000000">);<br /><img id="Codehighlighter1_300_400_Open_Image" onclick="this.style.display='none'; Codehighlighter1_300_400_Open_Text.style.display='none'; Codehighlighter1_300_400_Closed_Image.style.display='inline'; Codehighlighter1_300_400_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_300_400_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_300_400_Closed_Text.style.display='none'; Codehighlighter1_300_400_Open_Image.style.display='inline'; Codehighlighter1_300_400_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (shmid </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">) </span><span id="Codehighlighter1_300_400_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_300_400_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Failed in creating shared memory: %s\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, strerror(errno));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img id="Codehighlighter1_424_752_Open_Image" onclick="this.style.display='none'; Codehighlighter1_424_752_Open_Text.style.display='none'; Codehighlighter1_424_752_Closed_Image.style.display='inline'; Codehighlighter1_424_752_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_424_752_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_424_752_Closed_Text.style.display='none'; Codehighlighter1_424_752_Open_Image.style.display='inline'; Codehighlighter1_424_752_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (fork() </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">) </span><span id="Codehighlighter1_424_752_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_424_752_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        shmaddr </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">) shmat(shmid, NULL, </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img id="Codehighlighter1_513_634_Open_Image" onclick="this.style.display='none'; Codehighlighter1_513_634_Open_Text.style.display='none'; Codehighlighter1_513_634_Closed_Image.style.display='inline'; Codehighlighter1_513_634_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_513_634_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_513_634_Closed_Text.style.display='none'; Codehighlighter1_513_634_Open_Image.style.display='inline'; Codehighlighter1_513_634_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (shmaddr </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">) </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">) </span><span id="Codehighlighter1_513_634_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_513_634_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Failed in connecting to the shared memory: %s\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, strerror(errno));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />        }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        strcpy(shmaddr, </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Hello, this is child process!\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        shmdt(shmaddr);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br /><img id="Codehighlighter1_759_1477_Open_Image" onclick="this.style.display='none'; Codehighlighter1_759_1477_Open_Text.style.display='none'; Codehighlighter1_759_1477_Closed_Image.style.display='inline'; Codehighlighter1_759_1477_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_759_1477_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_759_1477_Closed_Text.style.display='none'; Codehighlighter1_759_1477_Open_Image.style.display='inline'; Codehighlighter1_759_1477_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    }</span></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span id="Codehighlighter1_759_1477_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_759_1477_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        sleep(</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        shmctl(shmid, IPC_STAT, </span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">buf);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Size of the shared memory: </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">shm_segsz = %d bytes\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, buf.shm_segsz);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Process id of the creator: </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">shm_cpid = %d\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, buf.shm_cpid);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Process id of the last operator: </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">shm_lpid = %d\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, buf.shm_lpid);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        shmaddr </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">) shmat(shmid, NULL, </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img id="Codehighlighter1_1220_1338_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1220_1338_Open_Text.style.display='none'; Codehighlighter1_1220_1338_Closed_Image.style.display='inline'; Codehighlighter1_1220_1338_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_1220_1338_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1220_1338_Closed_Text.style.display='none'; Codehighlighter1_1220_1338_Open_Image.style.display='inline'; Codehighlighter1_1220_1338_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (shmaddr </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">) </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">) </span><span id="Codehighlighter1_1220_1338_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_1220_1338_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Failed in connecting the shared memory: %s\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, strerror(errno));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />        }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">The content of the shared memory: %s\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, shmaddr);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        shmdt(shmaddr);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        shmctl(shmid, IPC_RMID, NULL);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></span></div>主要的API：<br />shmget 创建一块共享内存<br />shmat 将一块已经存在的共享内存映射到一个进程的地址空间<br />shmdt 取消一个进程的地址空间中的一块共享块的映射<br />shmctl 管理共享内存，和ioctl的风格很像<br /><br />每一个新创建的共享都由一个shmid_ds{}表示。struct shmid_ds在linux/shm.h中的定义：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Code_Closed_Image_112420" onclick="this.style.display='none'; Code_Closed_Text_112420.style.display='none'; Code_Open_Image_112420.style.display='inline'; Code_Open_Text_112420.style.display='inline';" height="16" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" width="11" align="top" /><img id="Code_Open_Image_112420" style="DISPLAY: none" onclick="this.style.display='none'; Code_Open_Text_112420.style.display='none'; Code_Closed_Image_112420.style.display='inline'; Code_Closed_Text_112420.style.display='inline';" height="16" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" width="11" align="top" /><span id="Code_Closed_Text_112420" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span><span id="Code_Open_Text_112420" style="DISPLAY: none"><br /><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><img id="Codehighlighter1_0_71_Open_Image" onclick="this.style.display='none'; Codehighlighter1_0_71_Open_Text.style.display='none'; Codehighlighter1_0_71_Closed_Image.style.display='inline'; Codehighlighter1_0_71_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_0_71_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_0_71_Closed_Text.style.display='none'; Codehighlighter1_0_71_Open_Image.style.display='inline'; Codehighlighter1_0_71_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span id="Codehighlighter1_0_71_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id="Codehighlighter1_0_71_Open_Text"><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> Obsolete, used only for backwards compatibility and libc5 compiles </span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_89_647_Open_Image" onclick="this.style.display='none'; Codehighlighter1_89_647_Open_Text.style.display='none'; Codehighlighter1_89_647_Closed_Image.style.display='inline'; Codehighlighter1_89_647_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_89_647_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_89_647_Closed_Text.style.display='none'; Codehighlighter1_89_647_Open_Image.style.display='inline'; Codehighlighter1_89_647_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000"> shmid_ds </span><span id="Codehighlighter1_89_647_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_89_647_Open_Text"><span style="COLOR: #000000">{<br /><img id="Codehighlighter1_119_139_Open_Image" onclick="this.style.display='none'; Codehighlighter1_119_139_Open_Text.style.display='none'; Codehighlighter1_119_139_Closed_Image.style.display='inline'; Codehighlighter1_119_139_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_119_139_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_119_139_Closed_Text.style.display='none'; Codehighlighter1_119_139_Open_Image.style.display='inline'; Codehighlighter1_119_139_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000"> ipc_perm        shm_perm;    </span><span id="Codehighlighter1_119_139_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id="Codehighlighter1_119_139_Open_Text"><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> operation perms </span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_159_187_Open_Image" onclick="this.style.display='none'; Codehighlighter1_159_187_Open_Text.style.display='none'; Codehighlighter1_159_187_Closed_Image.style.display='inline'; Codehighlighter1_159_187_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_159_187_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_159_187_Closed_Text.style.display='none'; Codehighlighter1_159_187_Open_Image.style.display='inline'; Codehighlighter1_159_187_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">            shm_segsz;    </span><span id="Codehighlighter1_159_187_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id="Codehighlighter1_159_187_Open_Text"><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> size of segment (bytes) </span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_218_239_Open_Image" onclick="this.style.display='none'; Codehighlighter1_218_239_Open_Text.style.display='none'; Codehighlighter1_218_239_Closed_Image.style.display='inline'; Codehighlighter1_218_239_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_218_239_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_218_239_Closed_Text.style.display='none'; Codehighlighter1_218_239_Open_Image.style.display='inline'; Codehighlighter1_218_239_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    __kernel_time_t        shm_atime;    </span><span id="Codehighlighter1_218_239_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id="Codehighlighter1_218_239_Open_Text"><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> last attach time </span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_270_291_Open_Image" onclick="this.style.display='none'; Codehighlighter1_270_291_Open_Text.style.display='none'; Codehighlighter1_270_291_Closed_Image.style.display='inline'; Codehighlighter1_270_291_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_270_291_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_270_291_Closed_Text.style.display='none'; Codehighlighter1_270_291_Open_Image.style.display='inline'; Codehighlighter1_270_291_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    __kernel_time_t        shm_dtime;    </span><span id="Codehighlighter1_270_291_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id="Codehighlighter1_270_291_Open_Text"><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> last detach time </span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_322_343_Open_Image" onclick="this.style.display='none'; Codehighlighter1_322_343_Open_Text.style.display='none'; Codehighlighter1_322_343_Closed_Image.style.display='inline'; Codehighlighter1_322_343_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_322_343_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_322_343_Closed_Text.style.display='none'; Codehighlighter1_322_343_Open_Image.style.display='inline'; Codehighlighter1_322_343_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    __kernel_time_t        shm_ctime;    </span><span id="Codehighlighter1_322_343_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id="Codehighlighter1_322_343_Open_Text"><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> last change time </span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_375_394_Open_Image" onclick="this.style.display='none'; Codehighlighter1_375_394_Open_Text.style.display='none'; Codehighlighter1_375_394_Closed_Image.style.display='inline'; Codehighlighter1_375_394_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_375_394_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_375_394_Closed_Text.style.display='none'; Codehighlighter1_375_394_Open_Image.style.display='inline'; Codehighlighter1_375_394_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    __kernel_ipc_pid_t    shm_cpid;    </span><span id="Codehighlighter1_375_394_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id="Codehighlighter1_375_394_Open_Text"><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> pid of creator </span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_426_451_Open_Image" onclick="this.style.display='none'; Codehighlighter1_426_451_Open_Text.style.display='none'; Codehighlighter1_426_451_Closed_Image.style.display='inline'; Codehighlighter1_426_451_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_426_451_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_426_451_Closed_Text.style.display='none'; Codehighlighter1_426_451_Open_Image.style.display='inline'; Codehighlighter1_426_451_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    __kernel_ipc_pid_t    shm_lpid;    </span><span id="Codehighlighter1_426_451_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id="Codehighlighter1_426_451_Open_Text"><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> pid of last operator </span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_482_510_Open_Image" onclick="this.style.display='none'; Codehighlighter1_482_510_Open_Text.style.display='none'; Codehighlighter1_482_510_Closed_Image.style.display='inline'; Codehighlighter1_482_510_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_482_510_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_482_510_Closed_Text.style.display='none'; Codehighlighter1_482_510_Open_Image.style.display='inline'; Codehighlighter1_482_510_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    unsigned </span><span style="COLOR: #0000ff">short</span><span style="COLOR: #000000">        shm_nattch;    </span><span id="Codehighlighter1_482_510_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id="Codehighlighter1_482_510_Open_Text"><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> no. of current attaches </span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_542_560_Open_Image" onclick="this.style.display='none'; Codehighlighter1_542_560_Open_Text.style.display='none'; Codehighlighter1_542_560_Closed_Image.style.display='inline'; Codehighlighter1_542_560_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_542_560_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_542_560_Closed_Text.style.display='none'; Codehighlighter1_542_560_Open_Image.style.display='inline'; Codehighlighter1_542_560_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    unsigned </span><span style="COLOR: #0000ff">short</span><span style="COLOR: #000000">         shm_unused;    </span><span id="Codehighlighter1_542_560_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id="Codehighlighter1_542_560_Open_Text"><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> compatibility </span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_585_610_Open_Image" onclick="this.style.display='none'; Codehighlighter1_585_610_Open_Text.style.display='none'; Codehighlighter1_585_610_Closed_Image.style.display='inline'; Codehighlighter1_585_610_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_585_610_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_585_610_Closed_Text.style.display='none'; Codehighlighter1_585_610_Open_Image.style.display='inline'; Codehighlighter1_585_610_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">             </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">shm_unused2;    </span><span id="Codehighlighter1_585_610_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id="Codehighlighter1_585_610_Open_Text"><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> ditto - used by DIPC </span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_634_645_Open_Image" onclick="this.style.display='none'; Codehighlighter1_634_645_Open_Text.style.display='none'; Codehighlighter1_634_645_Closed_Image.style.display='inline'; Codehighlighter1_634_645_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_634_645_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_634_645_Closed_Text.style.display='none'; Codehighlighter1_634_645_Open_Image.style.display='inline'; Codehighlighter1_634_645_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">            </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">shm_unused3;    </span><span id="Codehighlighter1_634_645_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id="Codehighlighter1_634_645_Open_Text"><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> unused </span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">;</span></span></div><br />其中存放权限信息的ipc_perm{}的定义为：<br />include/linux/ipc.h<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Code_Closed_Image_112730" onclick="this.style.display='none'; Code_Closed_Text_112730.style.display='none'; Code_Open_Image_112730.style.display='inline'; Code_Open_Text_112730.style.display='inline';" height="16" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" width="11" align="top" /><img id="Code_Open_Image_112730" style="DISPLAY: none" onclick="this.style.display='none'; Code_Open_Text_112730.style.display='none'; Code_Closed_Image_112730.style.display='inline'; Code_Closed_Text_112730.style.display='inline';" height="16" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" width="11" align="top" /><span id="Code_Closed_Text_112730" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span><span id="Code_Open_Text_112730" style="DISPLAY: none"><br /><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><img id="Codehighlighter1_0_71_Open_Image" onclick="this.style.display='none'; Codehighlighter1_0_71_Open_Text.style.display='none'; Codehighlighter1_0_71_Closed_Image.style.display='inline'; Codehighlighter1_0_71_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_0_71_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_0_71_Closed_Text.style.display='none'; Codehighlighter1_0_71_Open_Image.style.display='inline'; Codehighlighter1_0_71_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span id="Codehighlighter1_0_71_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id="Codehighlighter1_0_71_Open_Text"><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> Obsolete, used only for backwards compatibility and libc5 compiles </span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000"> ipc_perm<br /><img id="Codehighlighter1_89_243_Open_Image" onclick="this.style.display='none'; Codehighlighter1_89_243_Open_Text.style.display='none'; Codehighlighter1_89_243_Closed_Image.style.display='inline'; Codehighlighter1_89_243_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_89_243_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_89_243_Closed_Text.style.display='none'; Codehighlighter1_89_243_Open_Image.style.display='inline'; Codehighlighter1_89_243_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_89_243_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_89_243_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    __kernel_key_t    key;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    __kernel_uid_t    uid;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    __kernel_gid_t    gid;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    __kernel_uid_t    cuid;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    __kernel_gid_t    cgid;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    __kernel_mode_t    mode; <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    unsigned </span><span style="COLOR: #0000ff">short</span><span style="COLOR: #000000">    seq;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">;</span></span></div><p>mode为该共享的内存的读写权限，和chmod的参数有点像。mode低九位定义了访问许可，解释如下：<br />0400 用户可读  0200用户可写  0040 组成员可读  0020 组成员可写  0004 其他用户可读  0002 其他用户可写<br />没有执行位 0100 0010 和 0001</p><p> </p><img src ="http://www.blogjava.net/zellux/aggbug/180612.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2008-02-19 11:30 <a href="http://www.blogjava.net/zellux/archive/2008/02/19/180612.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>读核笔记(3) - 系统调用</title><link>http://www.blogjava.net/zellux/archive/2008/02/18/180462.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Mon, 18 Feb 2008 06:35:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2008/02/18/180462.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/180462.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2008/02/18/180462.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/180462.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/180462.html</trackback:ping><description><![CDATA[
		<strong>_syscall 宏：<br /></strong>最简单的没有参数的系统调用的实现：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Codehighlighter1_0_67_Open_Image" onclick="this.style.display='none'; Codehighlighter1_0_67_Open_Text.style.display='none'; Codehighlighter1_0_67_Closed_Image.style.display='inline'; Codehighlighter1_0_67_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_0_67_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_0_67_Closed_Text.style.display='none'; Codehighlighter1_0_67_Open_Image.style.display='inline'; Codehighlighter1_0_67_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span id="Codehighlighter1_0_67_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id="Codehighlighter1_0_67_Open_Text"><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. </span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000"> _syscall0(type,name) \</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />type name(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">) \<br /><img id="Codehighlighter1_120_251_Open_Image" onclick="this.style.display='none'; Codehighlighter1_120_251_Open_Text.style.display='none'; Codehighlighter1_120_251_Closed_Image.style.display='inline'; Codehighlighter1_120_251_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_120_251_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_120_251_Closed_Text.style.display='none'; Codehighlighter1_120_251_Open_Image.style.display='inline'; Codehighlighter1_120_251_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_120_251_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_120_251_Open_Text"><span style="COLOR: #000000">{ \<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000"> __res; \<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />__asm__ </span><span style="COLOR: #0000ff">volatile</span><span style="COLOR: #000000"> (</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">int $0x80</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> \<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    : </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">=a</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> (__res) \<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    : </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> (__NR_##name)); \<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />__syscall_return(type,__res); \<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div>以getuid()为例，_syscall0(int, getuid)展开后就变成<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> getuid(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">)<br /><img id="Codehighlighter1_17_178_Open_Image" onclick="this.style.display='none'; Codehighlighter1_17_178_Open_Text.style.display='none'; Codehighlighter1_17_178_Closed_Image.style.display='inline'; Codehighlighter1_17_178_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_17_178_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_17_178_Closed_Text.style.display='none'; Codehighlighter1_17_178_Open_Image.style.display='inline'; Codehighlighter1_17_178_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_17_178_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_17_178_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000"> __res;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    __asm__ </span><span style="COLOR: #0000ff">volatile</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">int $0x80</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />                    :</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">=a</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> (__res)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />                    :</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">  (__NR_getuid));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    __syscall_return(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, __res);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div>程序把系统调用号__NR_getuid放入eax寄存器，然后调用软中断。<br />include/asm-i386/hw_irq.h中的定义：<br /><u>00025   #define SYSCALL_VECTOR  0x80;<br /><br /></u>arch/i386/kernel/traps.c中把该中断号绑定到system_call函数：<br /><u>00944   set_system_gate(SYSCALL_VECTOR,&amp;system_call);<br /></u><br />system_call函数在arch/i386/kernel/entry.S中：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><strong><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></strong><span style="COLOR: #000000">ENTRY(system_call)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    pushl %eax            # save orig_eax<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    SAVE_ALL<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    GET_CURRENT(%ebx)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    testb $0x02</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">tsk_ptrace(%ebx)    # PT_TRACESYS<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    jne tracesys<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    cmpl $(NR_syscalls)</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">%eax<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    jae badsys<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    call *SYMBOL_NAME(sys_call_table)(</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">%eax</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    movl %eax</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">EAX(%esp)        # save the return value<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />ENTRY(ret_from_sys_call)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    cli                # need_resched and signals atomic test<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    cmpl $</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">need_resched(%ebx)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    jne reschedule<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    cmpl $</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">sigpending(%ebx)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    jne signal_return<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />restore_all:<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    RESTORE_ALL</span></div>主要步骤：<br />1. 保留一份系统调用号的最初拷贝<br />2. 保存堆栈环境(SAVE_ALL)<br />3. 得到当前task_struct的地址，保存到ebx中<br />4. 检查系统调用号<br />5. 根据%eax调用号计算地址，调用相应函数<br />6. 在entry.S后面可以看到，<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">.data<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />ENTRY(sys_call_table)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    .long SYMBOL_NAME(sys_ni_syscall)    /* </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">  -  old </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">setup()</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> system call*/<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        <img src="http://www.blogjava.net/images/dot.gif" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    .long SYMBOL_NAME(sys_getuid16)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    .long SYMBOL_NAME(sys_stime)        /* </span><span style="COLOR: #000000">25</span><span style="COLOR: #000000"> */<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    .long SYMBOL_NAME(sys_ptrace)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        <img src="http://www.blogjava.net/images/dot.gif" /></span></div>sys_call_table + %eax * 4是sys_getuid16地址，kernel/uid16.c中： 
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />asmlinkage </span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000"> sys_getuid16(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">)<br /><img id="Codehighlighter1_36_73_Open_Image" onclick="this.style.display='none'; Codehighlighter1_36_73_Open_Text.style.display='none'; Codehighlighter1_36_73_Closed_Image.style.display='inline'; Codehighlighter1_36_73_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_36_73_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_36_73_Closed_Text.style.display='none'; Codehighlighter1_36_73_Open_Image.style.display='inline'; Codehighlighter1_36_73_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_36_73_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_36_73_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> high2lowuid(current</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">uid);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div>很简单的处理代码，返回当前进程的uid。这里asmlinkage修饰符表示函数必须从堆栈中，而不是从寄存器中拿参数（防止gcc用寄存器传参优化）。<br />7. 保存返回值eax到堆栈中的eax<br />8. RESTORE_ALL<br /><br />另外这里再提一下GET_CURRENT的实现<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">#define GET_CURRENT(reg) \<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    movl $-</span><span style="COLOR: #000000">8192</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000"> reg</span><span style="COLOR: #008000">;</span><span style="COLOR: #008000"> \</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">    andl %esp</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000"> reg</span></div>很巧妙的实现，把栈指针与掩码-8192做与操作，末尾13位清零，就是当前的进程的task_struct地址了。<br /><br /><br />接下来是利用内核模块动态添加一个系统调用的例程，由于2.4.20以后sys_call_table符号不再被导出了，要获得这个地址得手动hack。尚未成功，下次回过头来看看。<img src ="http://www.blogjava.net/zellux/aggbug/180462.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2008-02-18 14:35 <a href="http://www.blogjava.net/zellux/archive/2008/02/18/180462.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>读核笔记(2) - 内核模块</title><link>http://www.blogjava.net/zellux/archive/2008/02/10/179568.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Sun, 10 Feb 2008 10:53:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2008/02/10/179568.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/179568.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2008/02/10/179568.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/179568.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/179568.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: /proc文件系统不是直接从内核的存储区中读写数据，二是通过回调函数实现文件读写的。struct proc_dir_entry有一对读写操作函数指针read_proc_t, write_proc_t。一个编写内核模块操作proc文件系统的例子，书上的源程序是在2.4.18下跑起来的，改了三个地方在2.6.23下成功运行。当然Makefile也按照2.6中make modules的方式写了。...&nbsp;&nbsp;<a href='http://www.blogjava.net/zellux/archive/2008/02/10/179568.html'>阅读全文</a><img src ="http://www.blogjava.net/zellux/aggbug/179568.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2008-02-10 18:53 <a href="http://www.blogjava.net/zellux/archive/2008/02/10/179568.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux2.6内核驱动与2.4的区别--Linux2.6内核驱动移植参考[zz]</title><link>http://www.blogjava.net/zellux/archive/2008/02/10/179561.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Sun, 10 Feb 2008 09:00:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2008/02/10/179561.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/179561.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2008/02/10/179561.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/179561.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/179561.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
<p>作者：晏渭川 <br />
随着Linux2.6的发布，由于2.6内核做了新的改动，各个设备的驱动程序在不同程度上要进行改写。为了方便各位Linux爱好者我把自己整理的这分 文档share出来。该文当列举了2.6内核同以前版本的绝大多数变化，可惜的是由于时间和精力有限没有详细列出各个函数的用法。</p>
<p>1、 使用新的入口 <br />
必须包含 &lt;linux/init.h&gt; <br />
module_init(your_init_func); <br />
module_exit(your_exit_func); <br />
老版本：int init_module(void); <br />
void cleanup_module(voi); <br />
2.4中两种都可以用，对如后面的入口函数不必要显示包含任何头文件。</p>
<p>2、 GPL <br />
MODULE_LICENSE("Dual BSD/GPL"); <br />
老版本：MODULE_LICENSE("GPL");</p>
<p>3、 模块参数 <br />
必须显式包含&lt;linux/moduleparam.h&gt; <br />
module_param(name, type, perm); <br />
module_param_named(name, value, type, perm); <br />
参数定义 <br />
module_param_string(name, string, len, perm); <br />
module_param_array(name, type, num, perm); <br />
老版本：MODULE_PARM(variable,type); <br />
MODULE_PARM_DESC(variable,type);</p>
<p>4、 模块别名 <br />
MODULE_ALIAS("alias-name"); <br />
这是新增的，在老版本中需在/etc/modules.conf配置，现在在代码中就可以实现。</p>
<p>5、 模块计数 <br />
int try_module_get(&amp;module); <br />
module_put(); <br />
老版本：MOD_INC_USE_COUNT 和 MOD_DEC_USE_COUNT <br />
<br />
<a href="http://www.fsl.cs.sunysb.edu/%7Esean/parser.cgi?modules">http://www.fsl.cs.sunysb.edu/~sean/parser.cgi?modules</a> <br />
<br />
In 2.4 modules, the MOD_INC_USE_COUNT macro is used to prevent unloading of the module while there is an open file. The 2.6 kernel, however, knows not to unload a module that owns a character device that's currently open.<br />
However, this requires that the module be explicit in specifying ownership of character devices, using the THIS_MODULE macro.</p>
<p>You also have to take out all calls to MOD_INC_USE_COUNT and MOD_DEC_USE_COUNT.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; static struct file_operations fops =<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .owner = THIS_MODULE,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .read = device_read,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .write = device_write,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .open = device_open,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .release = device_release<br />
}&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p>The 2.6 kernel considers modules that use the deprecated facility to be unsafe, and does not permit their unloading, even with rmmod -f.</p>
<p>2.6,2.5的kbuild不需要到处加上MOD_INC_USE_COUNT来消除模块卸载竞争（module unload race）</p>
<p>6、 符号导出 <br />
只有显示的导出符号才能被其他模块使用，默认不导出所有的符号，不必使用EXPORT_NO_SYMBOLS <br />
老板本：默认导出所有的符号，除非使用EXPORT_NO_SYMBOLS</p>
<p>7、 内核版本检查 <br />
需要在多个文件中包含&lt;linux/module.h&gt;时，不必定义__NO_VERSION__ <br />
老版本：在多个文件中包含&lt;linux/module.h&gt;时，除在主文件外的其他文件中必须定义__NO_VERSION__，防止版本重复定义。</p>
<p>8、 设备号 <br />
kdev_t被废除不可用，新的dev_t拓展到了32位，12位主设备号，20位次设备号。 <br />
unsigned int iminor(struct inode *inode); <br />
unsigned int imajor(struct inode *inode); <br />
老版本：8位主设备号，8位次设备号 <br />
int MAJOR(kdev_t dev); <br />
int MINOR(kdev_t dev);</p>
<p>9、 内存分配头文件变更 <br />
所有的内存分配函数包含在头文件&lt;linux/slab.h&gt;，而原来的&lt;linux/malloc.h&gt;不存在 <br />
老版本：内存分配函数包含在头文件&lt;linux/malloc.h&gt;</p>
<p>10、 结构体的初试化 <br />
gcc开始采用ANSI C的struct结构体的初始化形式： <br />
static struct some_structure = { <br />
.field1 = value, <br />
.field2 = value, <br />
.. <br />
}; <br />
老版本：非标准的初试化形式 <br />
static struct some_structure = { <br />
field1: value, <br />
field2: value, <br />
.. <br />
};</p>
<p>11、 用户模式帮助器 <br />
int call_usermodehelper(char *path, char **argv, char **envp, int wait); <br />
新增wait参数</p>
<p>12、 request_module() <br />
request_module("foo-device-%d", number); <br />
老版本： <br />
char module_name[32]; <br />
printf(module_name, "foo-device-%d", number); <br />
request_module(module_name);</p>
<p>13、 dev_t引发的字符设备的变化 <br />
1、取主次设备号为 <br />
unsigned iminor(struct inode *inode); <br />
unsigned imajor(struct inode *inode); <br />
2、老的register_chrdev()用法没变，保持向后兼容，但不能访问设备号大于256的设备。 <br />
3、新的接口为 <br />
a)注册字符设备范围 <br />
int register_chrdev_region(dev_t from, unsigned count, char *name); <br />
b)动态申请主设备号 <br />
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, char *name); <br />
看了这两个函数郁闷吧^_^！怎么和file_operations结构联系起来啊？别急！ <br />
c)包含 &lt;linux/cdev.h&gt;，利用struct cdev和file_operations连接 <br />
struct cdev *cdev_alloc(void); <br />
void cdev_init(struct cdev *cdev, struct file_operations *fops); <br />
int cdev_add(struct cdev *cdev, dev_t dev, unsigned count); <br />
（分别为，申请cdev结构，和fops连接，将设备加入到系统中！好复杂啊！） <br />
d)void cdev_del(struct cdev *cdev); <br />
只有在cdev_add执行成功才可运行。 <br />
e)辅助函数 <br />
kobject_put(&amp;cdev-&gt;kobj); <br />
struct kobject *cdev_get(struct cdev *cdev); <br />
void cdev_put(struct cdev *cdev); <br />
这一部分变化和新增的/sys/dev有一定的关联。</p>
<p>14、 新增对/proc的访问操作 <br />
&lt;linux/seq_file.h&gt; <br />
以前的/proc中只能得到string, seq_file操作能得到如long等多种数据。 <br />
相关函数： <br />
static struct seq_operations 必须实现这个类似file_operations得数据中得各个成员函数。 <br />
seq_printf()； <br />
int seq_putc(struct seq_file *m, char c); <br />
int seq_puts(struct seq_file *m, const char *s); <br />
int seq_escape(struct seq_file *m, const char *s, const char *esc); <br />
int seq_path(struct seq_file *m, struct vfsmount *mnt, <br />
struct dentry *dentry, char *esc); <br />
seq_open(file, &amp;ct_seq_ops); <br />
等等</p>
<p>15、 底层内存分配 <br />
1、&lt;linux/malloc.h&gt;头文件改为&lt;linux/slab.h&gt; <br />
2、分配标志GFP_BUFFER被取消，取而代之的是GFP_NOIO 和 GFP_NOFS <br />
3、新增__GFP_REPEAT，__GFP_NOFAIL，__GFP_NORETRY分配标志 <br />
4、页面分配函数alloc_pages()，get_free_page()被包含在&lt;linux/gfp.h&gt;中 <br />
5、对NUMA系统新增了几个函数： <br />
a) struct page *alloc_pages_node(int node_id, unsigned int gfp_mask, unsigned int order); <br />
b) void free_hot_page(struct page *page); <br />
c) void free_cold_page(struct page *page); <br />
6、 新增Memory pools <br />
&lt;linux/mempool.h&gt; <br />
mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn, mempool_free_t *free_fn, void *pool_data); <br />
void *mempool_alloc(mempool_t *pool, int gfp_mask); <br />
void mempool_free(void *element, mempool_t *pool); <br />
int mempool_resize(mempool_t *pool, int new_min_nr, int gfp_mask);</p>
<p>16、 per-CPU变量 <br />
get_cpu_var(); <br />
put_cpu_var(); <br />
void *alloc_percpu(type); <br />
void free_percpu(const void *); <br />
per_cpu_ptr(void *ptr, int cpu) <br />
get_cpu_ptr(ptr) <br />
put_cpu_ptr(ptr) <br />
老版本使用 <br />
DEFINE_PER_CPU(type, name); <br />
EXPORT_PER_CPU_SYMBOL(name); <br />
EXPORT_PER_CPU_SYMBOL_GPL(name); <br />
DECLARE_PER_CPU(type, name); <br />
DEFINE_PER_CPU(int, mypcint); <br />
2.6内核采用了可剥夺得调度方式这些宏都不安全。</p>
<p>17、 内核时间变化 <br />
1、现在的各个平台的HZ为 <br />
Alpha: 1024/1200; ARM: 100/128/200/1000; CRIS: 100; i386: 1000; IA-64: 1024; M68K: 100; M68K-nommu: 50-1000; MIPS: 100/128/1000; MIPS64: 100; PA-RISC: 100/1000; PowerPC32: 100; PowerPC64: 1000; S/390: 100; SPARC32: 100; SPARC64: 100; SuperH: 100/1000; UML: 100; v850: 24-100; x86-64: 1000. <br />
2、由于HZ的变化，原来的jiffies计数器很快就溢出了，引入了新的计数器jiffies_64 <br />
3、#include &lt;linux/jiffies.h&gt; <br />
u64 my_time = get_jiffies_64(); <br />
4、新的时间结构增加了纳秒成员变量 <br />
struct timespec current_kernel_time(void); <br />
5、他的timer函数没变，新增 <br />
void add_timer_on(struct timer_list *timer, int cpu); <br />
6、新增纳秒级延时函数 <br />
ndelay()； <br />
7、POSIX clocks 参考kernel/posix-timers.c</p>
<p>18、 工作队列（workqueue） <br />
1、任务队列（task queue ）接口函数都被取消，新增了workqueue接口函数 <br />
struct workqueue_struct *create_workqueue(const char *name); <br />
DECLARE_WORK(name, void (*function)(void *), void *data); <br />
INIT_WORK(struct work_struct *work, <br />
void (*function)(void *), void *data); <br />
PREPARE_WORK(struct work_struct *work, <br />
void (*function)(void *), void *data); <br />
2、申明struct work_struct结构 <br />
int queue_work(struct workqueue_struct *queue, struct work_struct *work); <br />
int queue_delayed_work(struct workqueue_struct *queue, struct work_struct *work, <br />
unsigned long delay); <br />
int cancel_delayed_work(struct work_struct *work); <br />
void flush_workqueue(struct workqueue_struct *queue); <br />
void destroy_workqueue(struct workqueue_struct *queue); <br />
int schedule_work(struct work_struct *work); <br />
int schedule_delayed_work(struct work_struct *work, unsigned long delay);</p>
<p>19、 新增创建VFS的"libfs" <br />
libfs给创建一个新的文件系统提供了大量的API. <br />
主要是对struct file_system_type的实现。 <br />
参考源代码： <br />
drivers/hotplug/pci_hotplug_core.c <br />
drivers/usb/core/inode.c <br />
drivers/oprofile/oprofilefs.c <br />
fs/ramfs/inode.c <br />
fs/nfsd/nfsctl.c (simple_fill_super() example)</p>
<p>20、 DMA的变化 <br />
未变化的有： <br />
void *pci_alloc_consistent(struct pci_dev *dev, size_t size, dma_addr_t *dma_handle); <br />
void pci_free_consistent(struct pci_dev *dev, size_t size, void *cpu_addr, dma_addr_t dma_handle); <br />
变化的有： <br />
1、 void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, int flag); <br />
void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t dma_handle); <br />
2、列举了映射方向： <br />
enum dma_data_direction { <br />
DMA_BIDIRECTIONAL = 0, <br />
DMA_TO_DEVICE = 1, <br />
DMA_FROM_DEVICE = 2, <br />
DMA_NONE = 3, <br />
}; <br />
3、单映射 <br />
dma_addr_t dma_map_single(struct device *dev, void *addr, size_t size, enum dma_data_direction direction); <br />
void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, enum dma_data_direction direction); <br />
4、页面映射 <br />
dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset, size_t size, enum dma_data_direction direction); <br />
void dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, enum dma_data_direction direction); <br />
5、有关scatter/gather的函数： <br />
int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction direction); <br />
void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, enum dma_data_direction direction); <br />
6、非一致性映射（Noncoherent DMA mappings） <br />
void *dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *dma_handle, int flag); <br />
void dma_sync_single_range(struct device *dev, dma_addr_t dma_handle, unsigned long offset, size_t size, <br />
enum dma_data_direction direction); <br />
void dma_free_noncoherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t dma_handle); <br />
7、DAC (double address cycle) <br />
int pci_dac_set_dma_mask(struct pci_dev *dev, u64 mask); <br />
void pci_dac_dma_sync_single(struct pci_dev *dev, dma64_addr_t dma_addr, size_t len, int direction);</p>
<p>21、 互斥 <br />
新增seqlock主要用于： <br />
1、少量的数据保护 <br />
2、数据比较简单(没有指针)，并且使用频率很高 <br />
3、对不产生任何副作用的数据的访问 <br />
4、访问时写者不被饿死 <br />
&lt;linux/seqlock.h&gt; <br />
初始化 <br />
seqlock_t lock1 = SEQLOCK_UNLOCKED; <br />
或seqlock_t lock2; seqlock_init(&amp;lock2); <br />
void write_seqlock(seqlock_t *sl); <br />
void write_sequnlock(seqlock_t *sl); <br />
int write_tryseqlock(seqlock_t *sl); <br />
void write_seqlock_irqsave(seqlock_t *sl, long flags); <br />
void write_sequnlock_irqrestore(seqlock_t *sl, long flags); <br />
void write_seqlock_irq(seqlock_t *sl); <br />
void write_sequnlock_irq(seqlock_t *sl); <br />
void write_seqlock_bh(seqlock_t *sl); <br />
void write_sequnlock_bh(seqlock_t *sl); <br />
unsigned int read_seqbegin(seqlock_t *sl); <br />
int read_seqretry(seqlock_t *sl, unsigned int iv); <br />
unsigned int read_seqbegin_irqsave(seqlock_t *sl, long flags); <br />
int read_seqretry_irqrestore(seqlock_t *sl, unsigned int iv, long flags);</p>
<p>22、 内核可剥夺 <br />
&lt;linux/preempt.h&gt; <br />
preempt_disable()； <br />
preempt_enable_no_resched()； <br />
preempt_enable_noresched()； <br />
preempt_check_resched()；</p>
<p>23、 眠和唤醒 <br />
1、原来的函数可用，新增下列函数： <br />
prepare_to_wait_exclusive()； <br />
prepare_to_wait()； <br />
2、等待队列的变化 <br />
typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int sync); <br />
void init_waitqueue_func_entry(wait_queue_t *queue, wait_queue_func_t func);</p>
<p>24、 新增完成事件（completion events） <br />
&lt;linux/completion.h&gt; <br />
init_completion(&amp;my_comp); <br />
void wait_for_completion(struct completion *comp); <br />
void complete(struct completion *comp); <br />
void complete_all(struct completion *comp);</p>
<p>25、 RCU（Read-copy-update） <br />
rcu_read_lock(); <br />
void call_rcu(struct rcu_head *head, void (*func)(void *arg), <br />
void *arg);</p>
<p>26、 中断处理 <br />
1、中断处理有返回值了。 <br />
IRQ_RETVAL(handled)； <br />
2、cli(), sti(), save_flags(), 和 restore_flags()不再有效，应该使用local_save <br />
_flags() 或local_irq_disable()。 <br />
3、synchronize_irq()函数有改动 <br />
4、新增int can_request_irq(unsigned int irq, unsigned long flags); <br />
5、 request_irq() 和free_irq() 从 &lt;linux/sched.h&gt;改到了 &lt;linux/interrupt.h&gt;</p>
<p>27、 异步I/O(AIO) <br />
&lt;linux/aio.h&gt; <br />
ssize_t (*aio_read) (struct kiocb *iocb, char __user *buffer, size_t count, loff_t pos); <br />
ssize_t (*aio_write) (struct kiocb *iocb, const char __user *buffer, size_t count, loff_t pos); <br />
int (*aio_fsync) (struct kiocb *, int datasync); <br />
新增到了file_operation结构中。 <br />
is_sync_kiocb(struct kiocb *iocb)； <br />
int aio_complete(struct kiocb *iocb, long res, long res2);</p>
<p>28、 网络驱动 <br />
1、struct net_device *alloc_netdev(int sizeof_priv, const char *name, void (*setup)(struct net_device *)); <br />
struct net_device *alloc_etherdev(int sizeof_priv); <br />
2、新增NAPI(New API) <br />
void netif_rx_schedule(struct net_device *dev); <br />
void netif_rx_complete(struct net_device *dev); <br />
int netif_rx_ni(struct sk_buff *skb); <br />
(老版本为netif_rx())</p>
<p>29、 USB驱动 <br />
老版本struct usb_driver取消了，新的结构体为 <br />
struct usb_class_driver { <br />
char *name; <br />
struct file_operations *fops; <br />
mode_t mode; <br />
int minor_base; <br />
}; <br />
int usb_submit_urb(struct urb *urb, int mem_flags); <br />
int (*probe) (struct usb_interface *intf, <br />
const struct usb_device_id *id);</p>
<p>30、 block I/O 层 <br />
这一部分做的改动最大。不祥叙。</p>
<p>31、 mmap() <br />
int remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long to, unsigned long size, pgprot_t prot); <br />
int io_remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long to, unsigned long size, pgprot_t prot); <br />
struct page *(*nopage)(struct vm_area_struct *area, unsigned long address, int *type); <br />
int (*populate)(struct vm_area_struct *area, unsigned long address, unsigned long len, pgprot_t prot, unsigned long pgoff, int nonblock); <br />
int install_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, struct page *page, pgprot_t prot); <br />
struct page *vmalloc_to_page(void *address);</p>
<p>32、 零拷贝块I/O(Zero-copy block I/O) <br />
struct bio *bio_map_user(struct block_device *bdev, unsigned long uaddr, unsigned int len, int write_to_vm); <br />
void bio_unmap_user(struct bio *bio, int write_to_vm); <br />
int get_user_pages(struct task_struct *task, struct mm_struct *mm, unsigned long start, int len, int write, int force, struct page **pages, struct vm_area_struct **vmas);</p>
<p>33、 高端内存操作kmaps <br />
void *kmap_atomic(struct page *page, enum km_type type); <br />
void kunmap_atomic(void *address, enum km_type type); <br />
struct page *kmap_atomic_to_page(void *address); <br />
老版本：kmap() 和 kunmap()。</p>
<p>34、 驱动模型 <br />
主要用于设备管理。 <br />
1、 sysfs <br />
2、 Kobjects</p>
<p>推荐文章： <br />
http:/www-900.ibm.com/developerWorks/cn/linux/kernel/l-kernel26/index.shtml <br />
http:/www-900.ibm.com/developerWorks/cn/linux/l-inside/index.shtml</p>
<p>2.6里不需要再定义&#8220;__KERNEL__&#8221;和&#8220;MODULE&#8221;了。 <br />
用下面的Makefile文件编译：</p>
<p>代码:</p>
<p>&nbsp;&nbsp;&nbsp; obj-m&nbsp;&nbsp; := hello.o</p>
<p>&nbsp;&nbsp;&nbsp; KDIR&nbsp;&nbsp; := /lib/modules/$(shell uname -r)/build <br />
&nbsp;&nbsp;&nbsp; PWD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; := $(shell pwd) <br />
&nbsp;&nbsp;&nbsp; default: <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $(MAKE) -C $(KDIR) M=$(PWD) modules</p>
<img src ="http://www.blogjava.net/zellux/aggbug/179561.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2008-02-10 17:00 <a href="http://www.blogjava.net/zellux/archive/2008/02/10/179561.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>多文件内核模块的编译</title><link>http://www.blogjava.net/zellux/archive/2008/02/10/179542.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Sun, 10 Feb 2008 04:34:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2008/02/10/179542.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/179542.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2008/02/10/179542.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/179542.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/179542.html</trackback:ping><description><![CDATA[捣鼓了半天，硬是没用gcc成功编译。还是用make modules算了。<br />
2.6内核编译系统提供了一种不同的写法。<br />
这里obj-m是树根，hello-objs是hello的两个结点。<br />
<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">ifneq&nbsp;($(KERNELRELEASE)</span><span style="color: #000000">,</span><span style="color: #000000">)<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj-m&nbsp;:</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;hello.o<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hello-objs&nbsp;:</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;start.o&nbsp;stop.o<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />else<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;KERNELDIR&nbsp;?</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;/lib/modules/$(shell&nbsp;uname&nbsp;-r)/build<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PWD&nbsp;&nbsp;:</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;$(shell&nbsp;pwd)<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />default:<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(MAKE)&nbsp;-C&nbsp;$(KERNELDIR)&nbsp;M</span><span style="color: #000000">=</span><span style="color: #000000">$(PWD)&nbsp;modules<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />endif<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
 <img src ="http://www.blogjava.net/zellux/aggbug/179542.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2008-02-10 12:34 <a href="http://www.blogjava.net/zellux/archive/2008/02/10/179542.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>读核笔记(1) - 内核模块</title><link>http://www.blogjava.net/zellux/archive/2008/02/07/179428.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Thu, 07 Feb 2008 03:22:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2008/02/07/179428.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/179428.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2008/02/07/179428.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/179428.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/179428.html</trackback:ping><description><![CDATA[<strong>include/linux/module.h</strong><br />
struct module:<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;module<br />
<img id="Codehighlighter1_14_1634_Open_Image" onclick="this.style.display='none'; Codehighlighter1_14_1634_Open_Text.style.display='none'; Codehighlighter1_14_1634_Closed_Image.style.display='inline'; Codehighlighter1_14_1634_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_14_1634_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_14_1634_Closed_Text.style.display='none'; Codehighlighter1_14_1634_Open_Image.style.display='inline'; Codehighlighter1_14_1634_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_14_1634_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_14_1634_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;用于在用户空间传入module对象时判断传入的结构是否有效</span><span style="color: #008000"><br />
<img id="Codehighlighter1_81_103_Open_Image" onclick="this.style.display='none'; Codehighlighter1_81_103_Open_Text.style.display='none'; Codehighlighter1_81_103_Closed_Image.style.display='inline'; Codehighlighter1_81_103_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_81_103_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_81_103_Closed_Text.style.display='none'; Codehighlighter1_81_103_Open_Image.style.display='inline'; Codehighlighter1_81_103_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;size_of_struct;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_81_103_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff">/**/</span><span id="Codehighlighter1_81_103_Open_Text"><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;==&nbsp;sizeof(module)&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;module&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">next;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;指向本module的名称，通常内核空间里申请的name内存位置都是紧跟在module{}结构后面的</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">name;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;本module{}结构的空间&nbsp;+&nbsp;紧接着这段内存申请的归module{}结构使用的一部分空间<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;size&nbsp;=&nbsp;sizeof(struct&nbsp;module)&nbsp;+&nbsp;sizeof(misc&nbsp;data)</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;size;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;模块引用计数器，还没搞清楚这里的pad是干什么用的<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;i386中atomic_t的定义:&nbsp;typedef&nbsp;struct&nbsp;{&nbsp;volatile&nbsp;int&nbsp;counter;&nbsp;}&nbsp;atomic_t;</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;union<br />
<img id="Codehighlighter1_437_473_Open_Image" onclick="this.style.display='none'; Codehighlighter1_437_473_Open_Text.style.display='none'; Codehighlighter1_437_473_Closed_Image.style.display='inline'; Codehighlighter1_437_473_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_437_473_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_437_473_Closed_Text.style.display='none'; Codehighlighter1_437_473_Open_Image.style.display='inline'; Codehighlighter1_437_473_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_437_473_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_437_473_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;atomic_t&nbsp;usecount;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;pad;<br />
<img id="Codehighlighter1_482_523_Open_Image" onclick="this.style.display='none'; Codehighlighter1_482_523_Open_Text.style.display='none'; Codehighlighter1_482_523_Closed_Image.style.display='inline'; Codehighlighter1_482_523_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_482_523_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_482_523_Closed_Text.style.display='none'; Codehighlighter1_482_523_Open_Image.style.display='inline'; Codehighlighter1_482_523_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;uc;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_482_523_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff">/**/</span><span id="Codehighlighter1_482_523_Open_Text"><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;Needs&nbsp;to&nbsp;keep&nbsp;its&nbsp;size&nbsp;-&nbsp;so&nbsp;says&nbsp;rth&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;模块当前状态，已初始化/运行中/被移除/被访问过等</span><span style="color: #008000"><br />
<img id="Codehighlighter1_579_599_Open_Image" onclick="this.style.display='none'; Codehighlighter1_579_599_Open_Text.style.display='none'; Codehighlighter1_579_599_Closed_Image.style.display='inline'; Codehighlighter1_579_599_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_579_599_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_579_599_Closed_Text.style.display='none'; Codehighlighter1_579_599_Open_Image.style.display='inline'; Codehighlighter1_579_599_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;flags;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_579_599_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff">/**/</span><span id="Codehighlighter1_579_599_Open_Text"><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;AUTOCLEAN&nbsp;et&nbsp;al&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;定义的内核模块符号数</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;nsyms;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;引用的模块链表节点数，遍历模块依赖性时使用</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;ndeps;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;符号表</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;module_symbol&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">syms;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;记录依赖的其他模块的数组</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;module_ref&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">deps;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;记录引用该模块的其他模块的数组</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;module_ref&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">refs;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;初始化和删除模块时调用的函数指针</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;(</span><span style="color: #000000">*</span><span style="color: #000000">init)(</span><span style="color: #0000ff">void</span><span style="color: #000000">);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;(</span><span style="color: #000000">*</span><span style="color: #000000">cleanup)(</span><span style="color: #0000ff">void</span><span style="color: #000000">);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;中断向量表的入口和结束位置</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;exception_table_entry&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">ex_table_start;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;exception_table_entry&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">ex_table_end;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />#ifdef&nbsp;__alpha__<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;gp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #0000ff">#endif</span><span style="color: #000000"><br />
<img id="Codehighlighter1_1035_1176_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1035_1176_Open_Text.style.display='none'; Codehighlighter1_1035_1176_Closed_Image.style.display='inline'; Codehighlighter1_1035_1176_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_1035_1176_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1035_1176_Closed_Text.style.display='none'; Codehighlighter1_1035_1176_Open_Image.style.display='inline'; Codehighlighter1_1035_1176_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_1035_1176_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff">/**/</span><span id="Codehighlighter1_1035_1176_Open_Text"><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;Members&nbsp;past&nbsp;this&nbsp;point&nbsp;are&nbsp;extensions&nbsp;to&nbsp;the&nbsp;basic<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;module&nbsp;support&nbsp;and&nbsp;are&nbsp;optional.&nbsp;&nbsp;Use&nbsp;mod_member_present()<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;examine&nbsp;them.&nbsp;&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;这两个指针维持一些模块相关信息，方便卸载后再次装载模块时的配置</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;module_persist&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">persist_start;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;module_persist&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">persist_end;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;(</span><span style="color: #000000">*</span><span style="color: #000000">can_unload)(</span><span style="color: #0000ff">void</span><span style="color: #000000">);<br />
<img id="Codehighlighter1_1344_1380_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1344_1380_Open_Text.style.display='none'; Codehighlighter1_1344_1380_Closed_Image.style.display='inline'; Codehighlighter1_1344_1380_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_1344_1380_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1344_1380_Closed_Text.style.display='none'; Codehighlighter1_1344_1380_Open_Image.style.display='inline'; Codehighlighter1_1344_1380_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;runsize;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_1344_1380_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff">/**/</span><span id="Codehighlighter1_1344_1380_Open_Text"><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;In&nbsp;modutils,&nbsp;not&nbsp;currently&nbsp;used&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br />
<img id="Codehighlighter1_1411_1448_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1411_1448_Open_Text.style.display='none'; Codehighlighter1_1411_1448_Closed_Image.style.display='inline'; Codehighlighter1_1411_1448_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_1411_1448_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1411_1448_Closed_Text.style.display='none'; Codehighlighter1_1411_1448_Open_Image.style.display='inline'; Codehighlighter1_1411_1448_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">kallsyms_start;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_1411_1448_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff">/**/</span><span id="Codehighlighter1_1411_1448_Open_Text"><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;All&nbsp;symbols&nbsp;for&nbsp;kernel&nbsp;debugging&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">kallsyms_end;<br />
<img id="Codehighlighter1_1506_1540_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1506_1540_Open_Text.style.display='none'; Codehighlighter1_1506_1540_Closed_Image.style.display='inline'; Codehighlighter1_1506_1540_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_1506_1540_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1506_1540_Closed_Text.style.display='none'; Codehighlighter1_1506_1540_Open_Image.style.display='inline'; Codehighlighter1_1506_1540_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">archdata_start;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_1506_1540_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff">/**/</span><span id="Codehighlighter1_1506_1540_Open_Text"><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;arch&nbsp;specific&nbsp;data&nbsp;for&nbsp;module&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">archdata_end;<br />
<img id="Codehighlighter1_1595_1632_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1595_1632_Open_Text.style.display='none'; Codehighlighter1_1595_1632_Closed_Image.style.display='inline'; Codehighlighter1_1595_1632_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_1595_1632_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1595_1632_Closed_Text.style.display='none'; Codehighlighter1_1595_1632_Open_Image.style.display='inline'; Codehighlighter1_1595_1632_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">kernel_data;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_1595_1632_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff">/**/</span><span id="Codehighlighter1_1595_1632_Open_Text"><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;Reserved&nbsp;for&nbsp;kernel&nbsp;internal&nbsp;use&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: #000000">;</span></div>
<br />
struct module_symbol:<br />
保存目标代码中的内核符号，读取文件装入模块时通过这个数据结构将里面包含的符号信息读入。<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;module_symbol<br />
<img id="Codehighlighter1_21_92_Open_Image" onclick="this.style.display='none'; Codehighlighter1_21_92_Open_Text.style.display='none'; Codehighlighter1_21_92_Closed_Image.style.display='inline'; Codehighlighter1_21_92_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_21_92_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_21_92_Closed_Text.style.display='none'; Codehighlighter1_21_92_Open_Image.style.display='inline'; Codehighlighter1_21_92_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_21_92_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_21_92_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;value;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;入口地址</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">name;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;内核符号名称</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" /></span><span style="color: #000000">}</span></span><span style="color: #000000">;</span></div>
<br />
struct module_ref:<br />
注意这里dep和ref记录的不对称，应该可以看成是一个ref链表吧<br />
module{} 中的deps数组分别指向了各个依赖的module_ref{}<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;module_ref<br />
<img id="Codehighlighter1_18_137_Open_Image" onclick="this.style.display='none'; Codehighlighter1_18_137_Open_Text.style.display='none'; Codehighlighter1_18_137_Closed_Image.style.display='inline'; Codehighlighter1_18_137_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_18_137_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_18_137_Closed_Text.style.display='none'; Codehighlighter1_18_137_Open_Image.style.display='inline'; Codehighlighter1_18_137_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_18_137_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_18_137_Open_Text"><span style="color: #000000">{<br />
<img id="Codehighlighter1_41_62_Open_Image" onclick="this.style.display='none'; Codehighlighter1_41_62_Open_Text.style.display='none'; Codehighlighter1_41_62_Closed_Image.style.display='inline'; Codehighlighter1_41_62_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_41_62_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_41_62_Closed_Text.style.display='none'; Codehighlighter1_41_62_Open_Image.style.display='inline'; Codehighlighter1_41_62_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;module&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">dep;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_41_62_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff">/**/</span><span id="Codehighlighter1_41_62_Open_Text"><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;"parent"&nbsp;pointer&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br />
<img id="Codehighlighter1_85_105_Open_Image" onclick="this.style.display='none'; Codehighlighter1_85_105_Open_Text.style.display='none'; Codehighlighter1_85_105_Closed_Image.style.display='inline'; Codehighlighter1_85_105_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_85_105_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_85_105_Closed_Text.style.display='none'; Codehighlighter1_85_105_Open_Image.style.display='inline'; Codehighlighter1_85_105_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;module&nbsp;</span><span style="color: #000000">*</span><span style="color: #0000ff">ref</span><span style="color: #000000">;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_85_105_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff">/**/</span><span id="Codehighlighter1_85_105_Open_Text"><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;"child"&nbsp;pointer&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;module_ref&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">next_ref;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: #000000">;</span></div>
<br />
struct kernel_sym:<br />
在sys_get_kernel_syms()中用到的结构，该函数将内核符号拷贝到用户空间的kernel_sym{}中，从而可以在用户态存放模块信息。<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;kernel_sym<br />
<img id="Codehighlighter1_18_120_Open_Image" onclick="this.style.display='none'; Codehighlighter1_18_120_Open_Text.style.display='none'; Codehighlighter1_18_120_Closed_Image.style.display='inline'; Codehighlighter1_18_120_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_18_120_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_18_120_Closed_Text.style.display='none'; Codehighlighter1_18_120_Open_Image.style.display='inline'; Codehighlighter1_18_120_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_18_120_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_18_120_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;value;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;内核符号地址</span><span style="color: #008000"><br />
<img id="Codehighlighter1_72_118_Open_Image" onclick="this.style.display='none'; Codehighlighter1_72_118_Open_Text.style.display='none'; Codehighlighter1_72_118_Closed_Image.style.display='inline'; Codehighlighter1_72_118_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_72_118_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_72_118_Closed_Text.style.display='none'; Codehighlighter1_72_118_Open_Image.style.display='inline'; Codehighlighter1_72_118_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;name[</span><span style="color: #000000">60</span><span style="color: #000000">];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_72_118_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff">/**/</span><span id="Codehighlighter1_72_118_Open_Text"><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;should&nbsp;have&nbsp;been&nbsp;64-sizeof(long);&nbsp;oh&nbsp;well&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: #000000">;</span></div>
<br />
module.c中的一些函数先略去了，书上蛮详细的<br />
<br />
<strong>模块的加载和卸载</strong><br />
insmod的任务：<br />
从命令行中读入模块名，确定代码所在文件的位置<br />
计算需要的内存<br />
执行系统调用create_module()，传递新模块的名称和大小<br />
用QM_MODULES获得所有已经链接模块的模块名<br />
用QM_SYMBOL获得内核符号表和已经链接到内核的模块的符号表<br />
使用这些信息重新定位该模块文件中的代码<br />
在用户空间分配内存，拷贝相关信息<br />
调用sys_init_module()，传递上面创建的用户态的内存区地址<br />
释放用户态内存，结束<br />
<br />
rmmod的任务：<br />
用QM_MODULES和QM_REFS取得已经链接的模块列表和依赖关系<br />
调用delete_module
<img src ="http://www.blogjava.net/zellux/aggbug/179428.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2008-02-07 11:22 <a href="http://www.blogjava.net/zellux/archive/2008/02/07/179428.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux 内核相关资料链接</title><link>http://www.blogjava.net/zellux/archive/2008/02/06/179405.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Wed, 06 Feb 2008 11:00:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2008/02/06/179405.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/179405.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2008/02/06/179405.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/179405.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/179405.html</trackback:ping><description><![CDATA[
		<p>
				<strong>如果一些文章的链接失效，google相应的标题应该还是很容易找到其他网站的转载的。<br /></strong>
		</p>
		<p>
				<strong>中断处理：</strong>
				<br />
				<a target="_blank" href="http://linux.chinaunix.net/bbs/thread-996409-1-1.html">Interrupt in Linux</a>
				<br />相当不错的中文资料<br /></p>
		<p>
				<strong>内核调度：</strong>
				<a title="Inside the Linux scheduler" href="http://www.ibm.com/developerworks/linux/library/l-scheduler/?S_TACT=105AGX52&amp;S_CMP=cn-a-l">
						<br />Inside the Linux scheduler</a>  <br />讲的是用expired/active两个数组维护的O(1)算法，大多数讲2.6内核的书上都会提到的调度算法 (2008-02-06)<br /><br /><a title="Multiprocessing with the Completely Fair Scheduler" href="http://www.ibm.com/developerworks/linux/library/l-cfs/?S_TACT=105AGX52&amp;S_CMP=cn-a-l">Multiprocessing with the Completely Fair Scheduler</a><br />最新的2.6.23采用的CFS，还没搞懂 (2008-02-06)<br /><br /><a href="http://www.ibm.com/developerworks/cn/linux/l-cn-scheduler/index.html">http://www.ibm.com/developerworks/cn/linux/l-cn-scheduler/index.html<br /></a>Linux 调度器发展简述 (2008-02-13)<br /><br /><strong>内核模块：<br /></strong>2.6 内核中的模块注入 (2008-02-17)<br /><a href="http://www.linuxforum.net/forum/showflat.php?Cat=&amp;Board=security&amp;Number=536404&amp;page=0&amp;view=collapsed&amp;sb=5&amp;o=31&amp;fpart">http://www.linuxforum.net/forum/showflat.php?Cat=&amp;Board=security&amp;Number=536404&amp;page=0&amp;view=collapsed&amp;sb=5&amp;o=31&amp;fpart</a><br /><br /><strong>系统调用：</strong><br />Linux 2.6 新增的 vsyscall 系统服务调用机制 (2008-02-18)<br /><a href="http://blog.csdn.net/wishfly/archive/2005/01/23/264435.aspx">http://blog.csdn.net/wishfly/archive/2005/01/23/264435.aspx</a><br /><br />Linux on-the-fly kernel patching without LKM (2008-02-19)<br /><a href="http://doc.bughunter.net/rootkit-backdoor/kernel-patching.html">http://doc.bughunter.net/rootkit-backdoor/kernel-patching.html<br /><br /></a><strong>内存管理：<br /></strong><a href="http://linux-mm.org/LinuxMM">http://linux-mm.org/LinuxMM</a><br />Linux-mm.org is a wiki for documenting how memory management works and for coordinating new memory management development projects. (2008-02-21)<br /><br /><strong>并发同步：</strong><br /><a href="http://hi.baidu.com/charleswen/blog/item/61f3e40ebc26dcce7acbe1c8.html">http://hi.baidu.com/charleswen/blog/item/61f3e40ebc26dcce7acbe1c8.html</a><br />Linux内核中的同步和互斥分析报告 (2008-02-21)<br /><br /><a href="http://www-128.ibm.com./developerworks/cn/linux/kernel/sync/index.html">http://www-128.ibm.com./developerworks/cn/linux/kernel/sync/index.html</a><br />Linux 2.4.x内核同步机制 (2008-02-22)<br /><br /><strong>Big Picture:<br /></strong><a href="http://www.linuxdriver.co.il/kernel_map">http://www.linuxdriver.co.il/kernel_map</a><br />Interactive Linux kernel map (2008-02-16)<br />把内核中的函数相互调用做成了一张可放大缩小的地图，单击相应函数名会跳转到lxr的相应代码链接。 <br /><br /><strong>编程资料：<br /></strong><a href="http://www.jegerlehner.ch/intel/">http://www.jegerlehner.ch/intel/</a><br />Intel Assembler CodeTable 80x86 (2008-02-21)<br /><br />相关站点：<br /><a href="http://kernelnewbies.org/">http://kernelnewbies.org</a><br />Linux Kernel Newbies<br /><br /><a href="http://bbs4.newsmth.net/bbsdoc.php?board=KernelTech">http://bbs4.newsmth.net/bbsdoc.php?board=KernelTech</a><br />水木KernelTech版<br /><br /><a href="http://www.phrack.org/">http://www.phrack.org</a><br />Phrack is an underground ezine made by and for hackers.<br />有不少和内核相关的hack资料</p>
<img src ="http://www.blogjava.net/zellux/aggbug/179405.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2008-02-06 19:00 <a href="http://www.blogjava.net/zellux/archive/2008/02/06/179405.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Inside the Windows Vista Kernel</title><link>http://www.blogjava.net/zellux/archive/2007/12/21/169311.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Fri, 21 Dec 2007 07:07:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2007/12/21/169311.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/169311.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2007/12/21/169311.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/169311.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/169311.html</trackback:ping><description><![CDATA[<a href="http://www.microsoft.com/technet/technetmag/issues/2007/02/VistaKernel">http://www.microsoft.com/technet/technetmag/issues/2007/03/VistaKernel</a><br />
<a href="http://www.microsoft.com/technet/technetmag/issues/2007/03/VistaKernel">http://www.microsoft.com/technet/technetmag/issues/2007/03/VistaKernel</a><br />
<a href="http://www.microsoft.com/technet/technetmag/issues/2007/04/VistaKernel">http://www.microsoft.com/technet/technetmag/issues/2007/03/VistaKernel</a><br /><img src ="http://www.blogjava.net/zellux/aggbug/169311.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2007-12-21 15:07 <a href="http://www.blogjava.net/zellux/archive/2007/12/21/169311.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于矩阵乘法的优化</title><link>http://www.blogjava.net/zellux/archive/2007/12/06/165777.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Thu, 06 Dec 2007 05:17:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2007/12/06/165777.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/165777.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2007/12/06/165777.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/165777.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/165777.html</trackback:ping><description><![CDATA[CS:APP P521<br />
在CC同学的帮助下终于看懂这个程序了<br />
关键在于P488的Generic Cache Memory Organization，以前看过，没留下什么印象<br />
cache是有多个(2<sup>s</sup>个）大小为block size的片组成的<br />
这样在访问B[k][j]时，B[k][j]&nbsp;- B[k][j +&nbsp;bsize - 1]这条内存就被cache了<br />
重复bsize次后B[k][k] - b[k + bsize - 1][k + bsize - 1]这块内存被cache<br />
后面做乘法就快很多的<br />
<img src ="http://www.blogjava.net/zellux/aggbug/165777.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2007-12-06 13:17 <a href="http://www.blogjava.net/zellux/archive/2007/12/06/165777.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>内核中的List结构</title><link>http://www.blogjava.net/zellux/archive/2007/10/12/152279.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Fri, 12 Oct 2007 03:38:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2007/10/12/152279.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/152279.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2007/10/12/152279.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/152279.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/152279.html</trackback:ping><description><![CDATA[<span style="font-family: Verdana"><span style="font-family: Verdana"><span style="font-family: 宋体"><span style="font-family: Verdana"><span style="font-family: Verdana"><span style="font-family: Arial">发信人: CJC (蓝色雪狐), 信区: 05SS<br />
标&nbsp; 题: OS_Lab3 指南 List<br />
发信站: 复旦燕曦BBS (2007年10月11日03:55:12 星期四), 转信<br />
<br />
&nbsp;&nbsp;&nbsp; 先写点List的东西吧，这个其实在以前并不作为重点讲，不过好像大家对它还是有些偏<br />
见，所以这次稍微讲下吧。作用是为到时候建立进程关系列表做准备。<br />
&nbsp;&nbsp;&nbsp; 讲的内容都在/usr/src/linux.../include/linux/list.h中，大家只要把一些不必要的<br />
ifdef和一些prefetch的东西删掉就好了。<br />
<br />
&nbsp;&nbsp;&nbsp; 首先讲讲历史。在没有范型的Java里面我们用的链表往往会这样（如果转成C的话）：<br />
typedef struct list_head {<br />
&nbsp;&nbsp;&nbsp; struct list_node *prev;<br />
&nbsp;&nbsp;&nbsp; void *data;<br />
&nbsp;&nbsp;&nbsp; struct list_node *next;<br />
} list_t;<br />
&nbsp;&nbsp;&nbsp; 通过这个结构，我们就能完成链表的功能了。但是我觉得这个数据结构不好，原因有二<br />
：<br />
&nbsp;&nbsp;&nbsp; 第一：这个结构比较容易引起内存碎片。<br />
<span style="font-family: Verdana"><span style="font-family: Verdana"><span style="font-family: Comic Sans MS"><span style="font-family: Tahoma"><span style="font-family: 宋体">&nbsp;&nbsp;&nbsp; ┌──┬─┬──┐<br />
&nbsp;&nbsp;&nbsp; │prev│&nbsp; │next│&lt;----多余内存消耗<br />
&nbsp;&nbsp;&nbsp; └──┴┼┴──┘<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; │&nbsp;&nbsp; ┌───┐<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; └─&gt;│ data │<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; └───┘</span></span></span></span></span><br />
&nbsp;&nbsp;&nbsp; 这种设计每一个节点都会引起一块多余的内存消耗。<br />
<br />
&nbsp;&nbsp;&nbsp; 第二：类型不明确，因为现在没办法用范型。如果写明了类型，那么还要为每种类型的<br />
list自己再做一整套函数，得不偿失。<br />
<br />
&nbsp;&nbsp;&nbsp; 当然，还会考虑类似于我们希望用别人写得比较好的代码之类的原因。<br />
<br />
&nbsp;&nbsp;&nbsp; 那让我们来看看我们版本里的list_t是怎么定义的<br />
typedef struct list_head {<br />
&nbsp;&nbsp;&nbsp; struct list_head *next, *prev;<br />
} list_t;<br />
&nbsp;&nbsp;&nbsp; 乍一看，这个list_head里面什么都没包含，只有一对前后指针，没有指向数据的指针<br />
。那怎么用呢？这里的做法我叫做：反包含。我们来看一个具体的使用例子：<br />
typedef struct test_struct {<br />
&nbsp;&nbsp;&nbsp; int val1;<br />
&nbsp;&nbsp;&nbsp; int val2;<br />
&nbsp;&nbsp;&nbsp; char vals[4];<br />
&nbsp;&nbsp;&nbsp; list_t all_tests;&nbsp;&nbsp; //千万注意，这里是list_t，不是list_t *<br />
} test_t;<br />
<br />
&nbsp;&nbsp;&nbsp; 那么我们声明了这个数据结构在内存中是什么样的呢？<br />
<span style="font-family: 宋体">&nbsp;(test_list)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ┌─────┐┬&nbsp;&nbsp;&nbsp; &lt;--my_test_struct_p(test_t *)<br style="font-family: " />
┌──┬──┐&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; │&nbsp;&nbsp; val1&nbsp;&nbsp; ││<br style="font-family: " />
│prev│next├┐&nbsp;&nbsp;&nbsp;&nbsp; ├─────┤│<br style="font-family: " />
└──┴──┘│&nbsp;&nbsp;&nbsp;&nbsp; │&nbsp;&nbsp; val2&nbsp;&nbsp; ││h<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; │&nbsp;&nbsp;&nbsp;&nbsp; ├─────┤│<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; │&nbsp;&nbsp;&nbsp;&nbsp; │&nbsp;&nbsp; vals&nbsp;&nbsp; ││<br style="font-family: " />
表示指向首地址└──&gt;├──┬──┤┴&nbsp;&nbsp;&nbsp; &lt;--my_list_p(list_t *)<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; │prev│next│&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //这里如果是list_t *就不是这样画了！<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; └──┴──┘</span><br />
&nbsp;&nbsp;&nbsp; 上图就是一个test_t的结构图。小地址在上，大地址在下，val1上面的那条分界线作为<br />
val1的起始地址（请注意我my_test_struct_p及其它指针的画法，是指向上面那根线，表示<br />
为那个东西的起始地址，为清楚起见推荐大家以后这样画）<br />
&nbsp;&nbsp;&nbsp; 然后为了把所有的test_t数据结构串起来，我们需要一个全局变量：test_list，类行<br />
为list_t（如果这里声明list_t *的话一定要为它分配空间！如果是死的全局变量、全局数<br />
组和一些临时数组，推荐直接声明成类型而不是指针，因为编译器会放在dat/bss和stack段<br />
里。但是如果这个数据结构是返回类型的分配空间，一定要malloc!否则回去就会错。这里<br />
也提醒一下）<br />
&nbsp;&nbsp;&nbsp; 我们可以看到test_list.next是指向my_test_struct_p-&gt;all_tests，而不是my_test_s<br />
truct。但是对我有用的应该是my_test_struct。所以一般处理方法有二，<br />
&nbsp;&nbsp;&nbsp; 第一种比较死板，就是在数据结构的一开始就放一个list_t（命名为list），那么&amp;lis<br />
t=&amp;stru，可以直接(xxx *)list_p。但是问题是如果一个数据结构可以同属两个链表，如pc<br />
b，又要是run_list的成员，又要是all_tasks的成员，还要是父进程children的成员&#8230;&#8230;这<br />
种方法显然是不够的。<br />
&nbsp;&nbsp;&nbsp; 第二种方法就相对好些。大家可以看，<br />
&nbsp;&nbsp;&nbsp; ((unsigned int)my_list_p)-h=(unsigned int)my_test_struct_p<br />
&nbsp;&nbsp;&nbsp; 而怎么得到h呢？是不是需要每个数据结构都定义一个h呢？不需要，可以这样看<br />
&nbsp;&nbsp;&nbsp; h=(unsigned int)(&amp;(((test_t *)0)-&gt;all_tests))<br />
&nbsp;&nbsp;&nbsp; 就是把0地址当作是test_t数据结构的开始地址，那么这个数据结构的all_tests所在的<br />
地址就是h了。<br />
&nbsp;&nbsp;&nbsp; 通过把这两个算式结合，我们可以得到一个宏：<br />
#define list_entry(ptr, type, member) \<br />
&nbsp;&nbsp;&nbsp; ((type *)((char *)(ptr)-(unsigned long)(&amp;((type *)0)-&gt;member)))<br />
&nbsp;&nbsp;&nbsp; 在这里的用法就是：<br />
&nbsp;&nbsp;&nbsp; my_test_struct_p = list_entry(test_list.next, test_t, all_tests);<br />
&nbsp;&nbsp;&nbsp; （如果使用类似于Simics的编辑器的话，all_tests的显示会是类似于没有定义变量，<br />
不用管它，的确是这样的。最后编译成功就对了）。<br />
&nbsp;&nbsp;&nbsp; 看过了最精妙的list_entry之后我们就可以来看一些简单的操作了<br />
#define INIT_LIST_HEAD(ptr) do { \<br />
&nbsp;&nbsp;&nbsp; (ptr)-&gt;next = (ptr); (ptr)-&gt;prev = (ptr); \<br />
} while (0)<br />
&nbsp;&nbsp;&nbsp; 为什么要加while(0)可以参见lab2指南里面的一些define帮助。其大致概念如下：<br />
<span style="font-family: 宋体">┌─────────┐<br style="font-family: " />
│&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; │<br style="font-family: " />
└-&gt;┌──┬──┐&nbsp; │<br style="font-family: " />
┌─┤prev│next├─┘&nbsp;&nbsp;&nbsp;&nbsp; //这里为了画清逻辑，不把指针放在首地址<br style="font-family: " />
│&nbsp; └──┴──┘&lt;-┐<br style="font-family: " />
│&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; │<br style="font-family: " />
└─────────┘</span><br />
&nbsp;&nbsp;&nbsp; 这是一个环状链表。一般这个作为头指针，链表为空的判断依据就是：<br />
static inline int list_empty(struct list_head *head)<br />
{<br />
&nbsp;&nbsp;&nbsp; return head-&gt;next == head;<br />
}<br />
&nbsp;&nbsp;&nbsp; 然后是添加，先有一个辅助函数：<br />
static inline void __list_add(struct list_head *new,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct list_head *prev,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct list_head *next)<br />
{<br />
&nbsp;&nbsp;&nbsp; next-&gt;prev = new;<br />
&nbsp;&nbsp;&nbsp; new-&gt;next = next;<br />
&nbsp;&nbsp;&nbsp; new-&gt;prev = prev;<br />
&nbsp;&nbsp;&nbsp; prev-&gt;next = new;<br />
}<br />
&nbsp;&nbsp;&nbsp; 这个是添加在第一个：<br />
static inline void list_add(struct list_head *new, struct list_head *head)<br />
{<br />
&nbsp;&nbsp;&nbsp; __list_add(new, head, head-&gt;next);<br />
}<br />
<span style="font-family: 宋体">┌───────────────────┐<br style="font-family: " />
│&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ┌─────┐&nbsp;&nbsp; │<br style="font-family: " />
└-&gt;┌──┬──┐┌─&gt;├──┬──┤&nbsp;&nbsp; │<br style="font-family: " />
┌─┤prev│next├┘ ┌┤prev│next├-─┘&nbsp; //这里的数据结构就省略画了<br style="font-family: " />
│&nbsp; └──┴──┘&lt;─┘├──┴──┤ &lt;-┐<br style="font-family: " />
│&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; └─────┘&nbsp;&nbsp; │<br style="font-family: " />
<span style="font-family: 宋体"><span style="font-family: ">└───────────────────┘</span><br style="font-family: " />
&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; ori_first<br style="font-family: " />
<span style="font-family: ">┌────────────────────────────┐<br style="font-family: " />
│&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 style="font-family: " />
└-&gt;┌──┬──┐┌─&gt;├──┬──┤┌─&gt;├──┬──┤&nbsp; │<br style="font-family: " />
┌─┤prev│next├┘ ┌┤prev│next├┘ ┌┤prev│next├─┘<br style="font-family: " />
│&nbsp; └──┴──┘&lt;─┘├──┴──┤&lt;─┘├──┴──┤&lt;-┐<br style="font-family: " />
│&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 style="font-family: " />
└────────────────────────────┘</span><br style="font-family: " />
&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; new&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ori_first</span></span><br />
&nbsp;&nbsp;&nbsp; 这个是添加在head-&gt;prev，由于是环状的，那么就是添在了最后一个<br />
static inline void list_add_tail(struct list_head *new, struct list_head *head)<br />
{<br />
&nbsp;&nbsp;&nbsp; __list_add(new, head-&gt;prev, head);<br />
}<br />
<span style="font-family: 宋体">┌────────────────────────────┐<br style="font-family: " />
│&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 style="font-family: " />
└-&gt;┌──┬──┐┌─&gt;├──┬──┤┌─&gt;├──┬──┤&nbsp; │<br style="font-family: " />
┌─┤prev│next├┘ ┌┤prev│next├┘ ┌┤prev│next├─┘<br style="font-family: " />
│&nbsp; └──┴──┘&lt;─┘├──┴──┤&lt;─┘├──┴──┤&lt;-┐<br style="font-family: " />
│&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 style="font-family: " />
└────────────────────────────┘<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ori_first&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new</span><br />
<br />
&nbsp;&nbsp;&nbsp; 接下来是删除：<br />
&nbsp;&nbsp;&nbsp; 这是辅助方法<br />
static inline void __list_del(struct list_head *prev, struct list_head *next)<br />
{<br />
&nbsp;&nbsp;&nbsp; next-&gt;prev = prev;<br />
&nbsp;&nbsp;&nbsp; prev-&gt;next = next;<br />
}<br />
&nbsp;&nbsp;&nbsp; 这个是用了辅助方法__list_del并且把entry的前后都设为NULL，是为了安全起见<br />
static inline void list_del(struct list_head *entry)<br />
{<br />
&nbsp;&nbsp;&nbsp; __list_del(entry-&gt;prev, entry-&gt;next);<br />
&nbsp;&nbsp;&nbsp; entry-&gt;next = (void *) 0;<br />
&nbsp;&nbsp;&nbsp; entry-&gt;prev = (void *) 0;<br />
}<br />
&nbsp;&nbsp;&nbsp; 个人觉得list_del_init, list_move, list_move_tail, list_splice没啥太大作用&#8230;<br />
&#8230;不过后面两个非常重要：<br />
#define list_for_each(pos, head) \<br />
&nbsp;&nbsp;&nbsp; for (pos = (head)-&gt;next; pos != (head); pos = pos-&gt;next)<br />
#define list_for_each_prev(pos, head) \<br />
&nbsp;&nbsp;&nbsp; for (pos = (head)-&gt;prev, prefetch(pos-&gt;prev); pos != (head); \<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pos = pos-&gt;prev, prefetch(pos-&gt;prev))<br />
<br />
使用方法：<br />
list_t *pos;<br />
list_for_each(pos, &amp;test_list) {<br />
&nbsp;&nbsp;&nbsp; test_t *tmp = list_entry(pos, test_t, all_tests);<br />
&nbsp;&nbsp;&nbsp; //do something on tmp<br />
}<br />
=======================================================================<br />
list_t *pos, *n;<br />
list_for_each_safe(pos, n, &amp;test_list) {<br />
&nbsp;&nbsp;&nbsp; test_t *tmp = list_entry(pos, test_t, all_tests);<br />
&nbsp;&nbsp;&nbsp; //do something on tmp<br />
}<br />
======================================================================<br />
&nbsp;&nbsp;&nbsp; 那么这两个有什么差别呢？我们可以来看这个例子：<br />
list_for_each(pos, &amp;test_list) {<br />
&nbsp;&nbsp;&nbsp; list_del(pos);<br />
}<br />
&nbsp;&nbsp;&nbsp; 首先，我们得到pos=test_list.next，然后删除，此时pos-&gt;next=0，如果按照list_fo<br />
r_each的话下一个循环的pos就是NULL，再访问下去就出错了！同样的，修改位置也是。所<br />
以在需要修改队列结构的时候，一定要使用list_for_each_safe。如果只修改对应的数据结<br />
构其他字段，可以用list_for_each，因为这个效率比较高。<br />
<br />
&nbsp;&nbsp;&nbsp; 有了这些方法基本上就可以使用了。我们可以来看一个物理内存管理的例子：<br />
#define USER_MEM_SIZE (256*1024*1024)<br />
#define USER_MEM_START (16*1024*1024)<br />
#define PAGE_SHIFT 12<br />
#define PAGE_SIZE (1&lt;&lt;(PAGE_SHIFT))<br />
#define PAGE_COUNT (((USER_MEM_SIZE)-(USER_MEM_START))&gt;&gt;(PAGE_SHIFT))<br />
#define PAGE_START(ptr) (((ptr)-(all_pages))&lt;&lt;(PAGE_SHIFT)+(USER_MEM_START))<br />
//获取这个page数据结构对应的起始地址<br />
#define PAGE_STRU(addr) (&amp;all_pages[((addr)-(USER_MEM_START))&lt;&lt;(PAGE_SHIFT)])<br />
<br />
typedef struct page_struct {<br />
&nbsp;&nbsp;&nbsp; unsigned long use_count;<br />
&nbsp;&nbsp;&nbsp; list_t mem_list;<br />
} page_t;<br />
<br />
list_t free_list, lru_list; //lru是用作换出的，最近使用在队首，换出队尾页<br />
//如果编译器不肯让我们这样定义的话用lmm_alloc或者out_alloc也可以。<br />
page_t all_pages[PAGE_COUNT];<br />
<br />
void init()<br />
{<br />
&nbsp;&nbsp;&nbsp; int i;<br />
&nbsp;&nbsp;&nbsp; INIT_LIST_HEAD(&amp;free_list);<br />
&nbsp;&nbsp;&nbsp; INIT_LIST_HEAD(&amp;lru_list);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //初始化两个链表<br />
&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; PAGE_COUNT; i++) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; all_pages[i] = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; list_add_tail(&amp;all_pages[i].mem_list, &amp;free_list);&nbsp; //加入free_list<br />
&nbsp;&nbsp;&nbsp; }<br />
}<br />
<br />
//此处返回值作为错误信息，addr作为所需返回的物理内存起始地址<br />
int get_page(unsigned int *addr)<br />
{<br />
&nbsp;&nbsp;&nbsp; if (list_empty(&amp;free_list)) //没有空页<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br />
&nbsp;&nbsp;&nbsp; list_t *lst = free_list.next;<br />
&nbsp;&nbsp;&nbsp; list_del(lst);<br />
&nbsp;&nbsp;&nbsp; list_add(lst, &amp;lru_list);&nbsp;&nbsp; //最近使用，放到队首<br />
&nbsp;&nbsp;&nbsp; *addr = PAGE_START(list_entry(lst, page_t, mem_list);<br />
&nbsp;&nbsp;&nbsp; return 0;<br />
}<br />
<br />
void use_page(unsigned int addr)<br />
{<br />
&nbsp;&nbsp;&nbsp; page_t *pg = PAGE_STRU(addr);<br />
&nbsp;&nbsp;&nbsp; list_del(&amp;pg-&gt;mem_list);<br />
&nbsp;&nbsp;&nbsp; list_add(&amp;pg-&gt;mem_list, &amp;lru_list); //将页面放到lru队列首<br />
}<br />
<br />
void return_page(unsigned int addr)<br />
{<br />
&nbsp;&nbsp;&nbsp; page_t *pg = PAGE_STRU(addr);<br />
&nbsp;&nbsp;&nbsp; list_del(&amp;pg-&gt;mem_list);<br />
&nbsp;&nbsp;&nbsp; list_add(&amp;pg-&gt;mem_list, &amp;free_list); //将页面放到free队列首，下次取时用<br />
}<br />
<br />
&nbsp;&nbsp;&nbsp; 物理页面管理基本上就类似于此。我们接下来来看一个稍微复杂些的例子，就是进程父<br />
子关系的例子，去年又同学跟我反映这是一个交错链接或者说是嵌套链接，其实不然。我们<br />
拆分开来看：<br />
<span style="font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ┌─────────-┐<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; │┌-────────┼───┐<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; │ ↘ A-&gt;children&nbsp;&nbsp;&nbsp; │&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; │<br style="font-family: " />
┌───-┼─&gt;┌──┬──┐&nbsp; │&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; │<br style="font-family: " />
│&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; └-─┤prev│next├┐│&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; │<br style="font-family: " />
│&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; └──┴──┘││&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; │<br style="font-family: " />
│┌────────────┘│&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; │<br style="font-family: " />
││&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ┌-───┘&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; │<br style="font-family: " />
││ ┌─────┐&nbsp;&nbsp; ↘┌─────┐│<br style="font-family: " />
│└&gt;├──┬──┤┌─&gt;├──┬──┤│<br style="font-family: " />
└-─┤prev│next├┘ ┌┤prev│next├┘<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp; ├──┴──┤&lt;─┘├──┴──┤<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp; └─────┘&nbsp;&nbsp;&nbsp;&nbsp; └─────┘<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; B&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C</span><br />
&nbsp;&nbsp;&nbsp; 由图可知，A有BC两个子进程，分别连接到A进程的children上。此时，处理A的childre<br />
n又有两种方法，第一种是增加指针，第二种是作为A进程的一部分。利用上面的思考方法，<br />
我们可以知道，如果按照第一种做法，那么势必会引起更多的内存碎片，不方便。于是我们<br />
把children作为pcb的一个field。那么B和C里面的prev/next该叫什么呢？因为B和C也是pc<br />
b的数据结构，已经不可能再叫children了（而且他们也应该有children节点，因为他们也<br />
可能有子进程）。那么我们就叫它为sibling吧。因为在这个链表里，除了A是父进程，其余<br />
的都是兄弟进程。<br />
&nbsp;&nbsp;&nbsp; 所以pcb的父子关系可以这样写：<br />
#define TASK_STATE_RUNNING 0<br />
#define TASK_STATE_ZOMBIE 1<br />
//调用了wait指令，等待子进程结束<br />
#define TASK_STATE_WAIT_CHILD 2<br />
<br />
typedef struct pcb_struct{<br />
&nbsp;&nbsp;&nbsp; struct pcb_struct *parent;&nbsp; 父进程<br />
&nbsp;&nbsp;&nbsp; unsigned long state;<br />
&nbsp;&nbsp;&nbsp; list_t children;<br />
&nbsp;&nbsp;&nbsp; list_t sibling;<br />
&nbsp;&nbsp;&nbsp; list_t all_tasks;<br />
} pcb_t;<br />
<br />
//init是一个非常特殊的进程，一般我们的kernel一起来，就只负责两个进程：init和idle<br />
//init的作用是先fork，子进程运行shell，它自身while(1) {wait(...);}就是负责回收<br />
//孤儿进程。<br />
//并且在此，我们可以把所有的进程都连接在init的all_tasks上面，这样又可以节省一个<br />
//相当于前例test_list的全局变量。找所有进程只须遍历init-&gt;all_tasks即可。<br />
//所以在生成init的时候应该是INIT_LIST_HEAD(&amp;task-&gt;all_tasks)<br />
void init_pcb(pcb_t *task, pcb_t *init)<br />
{<br />
&nbsp;&nbsp;&nbsp; INIT_LIST_HEAD(&amp;task-&gt;children);<br />
&nbsp;&nbsp;&nbsp; INIT_LIST_HEAD(&amp;task-&gt;sibling);<br />
&nbsp;&nbsp;&nbsp; task-&gt;parent = NULL;<br />
&nbsp;&nbsp;&nbsp; task-&gt;state = TASK_STATE_RUNNING;<br />
&nbsp;&nbsp;&nbsp; list_add_tail(&amp;task-&gt;all_tasks, &amp;init-&gt;all_tasks);<br />
}<br />
<br />
void add_child(pcb_t *parent, pcb_t *child)<br />
{<br />
&nbsp;&nbsp;&nbsp; child-&gt;parent = parent;<br />
&nbsp;&nbsp;&nbsp; list_add_tail(&amp;child-&gt;sibling, &amp;parent-&gt;children);&nbsp; //想想为什么<br />
}<br />
<br />
void do_exit(pcb_t *task, pcb_t *init)<br />
{<br />
&nbsp;&nbsp;&nbsp; //exit_mem_first_part<br />
&nbsp;&nbsp;&nbsp; list_t *pos, *n;<br />
&nbsp;&nbsp;&nbsp; list_for_each_safe(pos, n, &amp;task-&gt;children) //将所有子进程交给init<br />
&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //~~~~<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; task_t *child = list_entry(pos, task_t, sibling); //这里是sibling<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; child-&gt;parent = init;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; list_del(&amp;child-&gt;sibling);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; list_add_tail(&amp;child-&gt;sibling, &amp;init_children);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (child-&gt;state == TASK_STATE_ZOMBIE &amp;&amp; init-&gt;state != TASK_STATE_WAIT_<br />
CHILD)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //这里激活init，并把init放到进程列表的尾端<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; //然后切换到父进程运行<br />
}<br />
&nbsp;&nbsp;&nbsp; 如果看懂了以上的所有例子，那么链表结构应该就差不多了。由于篇幅关系，PCB的构<br />
建就单列开来吧。这里专门讲LIST好了。:)<br />
&nbsp;&nbsp;&nbsp; 如果有代码觉得看的郁闷的，拿张纸画画对应的内存结构应该就会好些了<br />
--<br />
<br />
※ 修改:&#183;CJC 于 Oct 11 03:57:46 修改本文&#183;[FROM: 穿梭而来]<br />
※ 来源:&#183;复旦燕曦BBS yanxibbs.cn&#183;[FROM: 穿梭而来]</span></span></span> </span></span></span>
<img src ="http://www.blogjava.net/zellux/aggbug/152279.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2007-10-12 11:38 <a href="http://www.blogjava.net/zellux/archive/2007/10/12/152279.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux核心源码的目录结构</title><link>http://www.blogjava.net/zellux/archive/2007/10/04/150384.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Thu, 04 Oct 2007 09:26:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2007/10/04/150384.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/150384.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2007/10/04/150384.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/150384.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/150384.html</trackback:ping><description><![CDATA[以下转载自《Linux&nbsp;kernel》<br />
<br />
核心源码的顶层是/usr/src/linux目录，在此目录下你可以看到大量子目录：<br />
arch<br />
这个子目录包含了所有体系结构相关的核心代码。它还包含每种支持的体系结构的子目录，如i386。<br />
include<br />
这个目录包括了用来重构核心的大多数include文件。对于每种支持的体系结构分别有一个子目录。&nbsp;此目录中的asm子目录中是对应某种处理器的符号连接，如include/asm-i386。要修改处理器结构&nbsp;则只需编辑核心的makefile并重新运行Linux核心配置程序。<br />
init<br />
此目录包含核心启动代码。<br />
mm<br />
此目录包含了所有的内存管理代码。与具体体系结构相关的内存管理代码位于arch/*/mm目录下，&nbsp;如arch/i386/mm/fault.c&nbsp;。<br />
drivers<br />
系统中所有的设备驱动都位于此目录中。它又进一步划分成几类设备驱动，如block。<br />
ipc<br />
此目录包含了核心的进程间通讯代码。<br />
modules<br />
此目录仅仅包含已建好的模块。<br />
fs<br />
所有的文件系统代码。它也被划分成对应不同文件系统的子目录，如vfat和ext2。<br />
kernel<br />
主要核心代码。同时与处理器结构相关代码都放在arch/*/kernel目录下。<br />
net<br />
核心的网络部分代码。<br />
lib<br />
此目录包含了核心的库代码。与处理器结构相关库代码被放在arch/*/lib/目录下。<br />
scripts<br />
此目录包含用于配置核心的脚本文件（如awk和tk脚本）。&nbsp;<br />
<img src ="http://www.blogjava.net/zellux/aggbug/150384.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2007-10-04 17:26 <a href="http://www.blogjava.net/zellux/archive/2007/10/04/150384.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CSAPP - Explicitly Blocking Signals </title><link>http://www.blogjava.net/zellux/archive/2007/09/05/142862.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Wed, 05 Sep 2007 04:22:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2007/09/05/142862.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/142862.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2007/09/05/142862.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/142862.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/142862.html</trackback:ping><description><![CDATA[看了半天总算对这节有了个大致的感觉，首先看几个和sigprocmask相关的函数：<br />
<br />
#include &lt;signal.h&gt;<br />
<br />
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);<br />
int sigemptyset(sigset_t *set);<br />
int sigfillset(sigset_t *set);<br />
int sigaddset(sigset_t *set, int signum);<br />
int sigdelset(sigset_t *set, int signum);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Return: 0 if OK, -1 on error<br />
int sigismember(const sigset_t *set, int signum);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Return: 1 if member, 0 if not, -1 on error<br />
<br />
sigprocmask用于改变当前blocked signals的集合，how参数指定了具体的行为：<br />
SIG_BLOCK 把set中的信号添加到blocked列表(blocked = blocked | set)<br />
SIG_UNBLOCK 把set中的信号从blocked列表中移出(blocked = blocked &amp; ~set)<br />
SIG_SETMASK blocked = set<br />
<br />
另外，如果oldset的值不是NULL的话，之前的blocked列表会保存在oldset中。<br />
<br />
而sigaddset sigdelset sigfillset sigemptyset都是用于操作sigset_t列表的函数。<br />
<br />
sigprocmask适用于在父子进程间同步的情况，以一个典型的UNIX shell程序为例，父进程需要在一个job
list中记录它所有的子进程，当父进程创建一个子进程时，它把子进程加入到job list中；当父进程reap一个子进程时，就从job
list中移出这个进程。<br />
如果不同步父子进程，有可能发生这种情况：<br />
1. 父进程执行fork函数，内核调度新创建的子进程替换父进程运行<br />
2. 在父进程能够再次运行前，子进程终止，成为一个zombie，内核发送SIGCHLD信号给父进程<br />
3. 父进程可以运行前，内核发现了未处理的(pending)SIGCHLD信号，让它由父进程的handler处理<br />
4. handler reap了终止的进程，调用deletejob函数，实际上没有任何作用，因为父进程还没有把该子进程加入列表<br />
5. handler完成后，内核继续运行父进程，后者调用fork完成后继续，错误地把不存在的子进程加入了job list
<img src ="http://www.blogjava.net/zellux/aggbug/142862.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2007-09-05 12:22 <a href="http://www.blogjava.net/zellux/archive/2007/09/05/142862.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CSAPP - Alignment</title><link>http://www.blogjava.net/zellux/archive/2007/08/10/135947.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Fri, 10 Aug 2007 15:14:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2007/08/10/135947.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/135947.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2007/08/10/135947.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/135947.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/135947.html</trackback:ping><description><![CDATA[把以前跳过去的几节补一下<br><br>对齐就是指为了提高处理器的效率，把某些基础类型的地址规定为必须是某个值(通常是2,4或8）的整数倍。<br>如果不这样处理，例如把一个double值分开存放在地址为8*n的两边，处理器每次从内存中读取8字节，这样就需要读取两次才能得到这个double值了。<br>Linux的做法是把2字节数据（如short）存放在偶数的地址中，把其他更大的数据（int, int *, float, double）放在以4为约数的地址中。<br>Windows则使用了相对现代的处理器而言更好的做法，任何k字节的数据必须存放在以k的倍数为起始的地址中，即double必须存放在以8*n为起始的地址中。<br>GCC的编译开关-malign-double也可以达到这种效果，但因此可能导致与某些假定4字节对齐方式的库的链接错误。<br>一个简单的例子：<br>struct S1 {<br>&nbsp;&nbsp;&nbsp; int i;<br>&nbsp;&nbsp;&nbsp; char c;<br>&nbsp;&nbsp;&nbsp; int j;<br>};<br>对齐后的保存方式为<br>0-4: i<br>4-5: c<br>8-12: j<br><br><img src ="http://www.blogjava.net/zellux/aggbug/135947.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2007-08-10 23:14 <a href="http://www.blogjava.net/zellux/archive/2007/08/10/135947.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CSAPP - Linking - 动态链接库</title><link>http://www.blogjava.net/zellux/archive/2007/08/07/135097.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Tue, 07 Aug 2007 15:10:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2007/08/07/135097.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/135097.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2007/08/07/135097.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/135097.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/135097.html</trackback:ping><description><![CDATA[1. 静态库(static library)的主要缺陷：<br>
1) 静态库通常需要维护和定期更新，而这些库的使用者就得注意这些变化，并且在库修改后重新将自己的程序和库链接起来<br>
2) 以printf和scanf这两个函数为例，它们的代码在每个运行的进程里都保留了一份，在一个典型的操作系统上运行着50-100个进程，这无疑是对系统资源的严重浪费。（内存的一个有趣的特性是，它永远是一个短缺的资源，无关一个系统里有多大的内存）<br>
<br>
2. 共享库(shared library)弥补了静态库的这些缺陷。所谓共享库，就是指在<strong>运行时</strong>可以被读入到<strong>任意的</strong>内存地址，并与程序链接的模块。这个过程也被称为动态链接(dynamic linking)，由动态链接器(dynamic linker)完成。<br>
Unix系统中共享对象通常后缀为.so，微软的操作系统中大量使用了共享库，通常被称为DLL(dynamic link libraries)<br>
<br>
3. 共享库的&#8220;共享&#8221;表现在两个方面：<br>
1) 在任何一个给定的文件系统中，对于某个特定的库，只有一个.so文件<br>
2) 共享库单独的一份.text域可以由多个不同的运行进程共享。<br>
<br>
4. 编译一个共享库：gcc -shared -fPIC -o libvector.so addvec.c multvec.c<br>
-fPIC开关让编译器产生位置独立的代码(PIC, position independent code)<br>
-shared开关使得编译器产生共享对象的文件<br>
<br>
5. 动态链接的几个应用：<br>
1) 软件的分布式开发<br>
2) 开发高效的Web服务器<br>
早期的Web服务器通过fork和execve调用子进程来产生动态的内容，被称为CGI，而现代的Web服务器则通过基于动态链接库的一种高效的方式。<br>
主要的方法是把生成动态内容的函数打包到一个共享库中，当服务器端接收到一个请求后，服务器动态地读入并且链接到相应的函数，并直接调用这个函数，而
fork和execve则是在子进程的环境中运行的。函数调用后继续存在，以后的类似请求都只需要一个简单的调用就可以了。另外，方法也可以在不停止服务
器的情况下更新，也可以加入新的函数。<br>
<br>
6. Unix系统中读入并链接共享库的方法<br>
#include &lt;dlfcn.h&gt;<br>
void *dlopen(const char *filename, int flag);<br>
// returns: ptr to handle if OK, NULL on error<br>
需要通过-rdynamic编译，具体见CSAPP P569<br>
<br>
获得已经打开的库的句柄(handle)<br>
#include &lt;dlfcn.h&gt;<br>
void #dlsym(void *handle, char *symbol);<br>
// returns: ptr to symbol if OK, NULL on error<br>
<br>
关闭共享库<br>
#include &lt;dlfcn.h&gt;<br>
int dlclose(void *handle);<br>
// returns: 0 if OK, -1 on error<br>
<br>
获得错误信息<br>
#include &lt;dlfcn.h&gt;<br>
const char *dlerror(void); <img src ="http://www.blogjava.net/zellux/aggbug/135097.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2007-08-07 23:10 <a href="http://www.blogjava.net/zellux/archive/2007/08/07/135097.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CSAPP - Linking - Strong and weak symbols</title><link>http://www.blogjava.net/zellux/archive/2007/08/02/134126.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Thu, 02 Aug 2007 15:45:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2007/08/02/134126.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/134126.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2007/08/02/134126.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/134126.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/134126.html</trackback:ping><description><![CDATA[<span style="color: #575874;">《窃听风暴》的男主角乌尔里希&#183;穆埃(Ulrich M&#252;he)
病逝了。。。</span><br style="color: #575874;"><span style="color: #575874;">好片子，好演员，可惜了。。。</span><br><br>CSAPP 第七章Linking太枯燥了<img src="http://www.blogjava.net/CuteSoft_Client/CuteEditor/images/face8.gif" align="absmiddle" border="0">&nbsp; 啃了半天总算看到一点实际经历中遇到过的。<br><br>在编译阶段，编译器把全局变量标记为strong或者weak，并导出到汇编程序中，由汇编程序把这些信息隐式地添加到relocatable object file的符号表(symbol table)中。<br>函数和被初始化的全局变量被标记为strong，未初始化的全局变量被标记为weak。<br>Unix连接器(linker)使用下面的规则来处理多个符号的情况：<br>1. 不允许多个strong symbol的存在<br>2. 如果有一个strong symbol和若干个weak symbol，使用strong symbol<br>3. 只有若干个weak symbol，则使用其中任意一个<br><br>几个例子（未特殊说明的情况，变量定义均在全局范围）：<br>1. foo1.c和bar1.c中都有int main()方法，即存在了两个strong symbol，连接器就会产生一条错误信息。<br>2.
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">/* foo3.c */<br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">stdio.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;f(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">);<br><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;x&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">15213</span><span style="color: #000000;">;<br><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;main()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;f();<br>&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">x&nbsp;=&nbsp;%d\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;x);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br>}</span></div>
<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;bar3.c&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;x;<br><br>void&nbsp;f()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;x&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">15212</span><span style="color: #000000;">;<br>}</span></div>
main()方法调用f()后，x变为15212并被输出。<br><span style="color: red; font-weight: bold;">注意这可能不是main()方法的作者原来的意图。</span><br>类似的情况也可能发生在两个weak symbol同名的时候。<br><br>3. 全局变量类型不同的情况：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;foo5.c&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">stdio.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;f(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">);<br><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;x&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">15213</span><span style="color: #000000;">;<br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;y&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">15212</span><span style="color: #000000;">;<br><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;main()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;f();<br>&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">x&nbsp;=&nbsp;0x%x&nbsp;&nbsp;y&nbsp;=&nbsp;0x%x&nbsp;\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;x,&nbsp;y);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br>}<br></span></div>
<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;bar4.c&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">double</span><span style="color: #000000;"> x;<br><br></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;f()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;x&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">0.0</span><span style="color: #000000;">;<br>}<br></span></div>
根据书上的内容，<br>linux&gt; gcc -o foobar5 foo5.c bar5.c<br>linux&gt; ./foobar5<br>结果应该是<br>x = 0x0&nbsp; y = 0x80000000<br><br>但是在自己机器上编译时报错了，可能连接器版本较高，会自动找出这种错误<img src="http://www.blogjava.net/CuteSoft_Client/CuteEditor/images/face22.gif" align="absmiddle" border="0"><br>/usr/bin/ld: Warning: alignment 4 of symbol `x' in /tmp/ccupQXSG.o is smaller than 8 in /tmp/ccNNG9XZ.o<br>是double和int大小不义导致的对齐问题<br><br><br>这些问题都比较细小难以被查觉，通常在程序执行了一段时间后才出现较严重的问题，因此很难被修复，尤其当许多程序员不清楚连接器的工作方式的时候。<br>另外可以使用GCC的-warn-common标记(flag)，使得它在解析多个同名的全局变量时发出警告。<br>试了下没成功@@<br>gcc --warn-common提示无法识别的命令行选项，gcc -Wall则不会发出警告。<br>  <img src ="http://www.blogjava.net/zellux/aggbug/134126.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2007-08-02 23:45 <a href="http://www.blogjava.net/zellux/archive/2007/08/02/134126.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>