﻿<?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>博客生活-天上星，加油！</title><link>http://www.cnweblog.com/lianzhanfeng/</link><description /><language>zh-cn</language><lastBuildDate>Wed, 29 Apr 2026 20:42:19 GMT</lastBuildDate><pubDate>Wed, 29 Apr 2026 20:42:19 GMT</pubDate><ttl>60</ttl><item><title>kmalloc, vmalloc分配的内存结构</title><link>http://www.cnweblog.com/lianzhanfeng/archive/2010/08/10/313055.html</link><dc:creator>Peter.Lian</dc:creator><author>Peter.Lian</author><pubDate>Tue, 10 Aug 2010 03:27:00 GMT</pubDate><guid>http://www.cnweblog.com/lianzhanfeng/archive/2010/08/10/313055.html</guid><wfw:comment>http://www.cnweblog.com/lianzhanfeng/comments/313055.html</wfw:comment><comments>http://www.cnweblog.com/lianzhanfeng/archive/2010/08/10/313055.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnweblog.com/lianzhanfeng/comments/commentRss/313055.html</wfw:commentRss><trackback:ping>http://www.cnweblog.com/lianzhanfeng/services/trackbacks/313055.html</trackback:ping><description><![CDATA[对于提供了MMU（存储管理器，辅助操作系统进行内存管理，提供虚实地址转换等硬件支持）的处理器而言，Linux提供了复杂的存储管理系统，使得进程所能访问的内存达到4GB。<br />
<br />
　　进程的4GB内存空间被人为的分为两个部分--用户空间与内核空间。用户空间地址分布从0到3GB(PAGE_OFFSET，在0x86中它等于0xC0000000)，3GB到4GB为内核空间。<br />
<br />
　　内核空间中，从3G到vmalloc_start这段地址是物理内存映射区域（该区域中包含了内核镜像、物理页框表mem_map等等），比如我们使用的 VMware虚拟系统内存是160M，那么3G～3G+160M这片内存就应该映射物理内存。在物理内存映射区之后，就是vmalloc区域。对于 160M的系统而言，vmalloc_start位置应在3G+160M附近（在物理内存映射区与vmalloc_start期间还存在一个8M的gap 来防止跃界），vmalloc_end的位置接近4G(最后位置系统会保留一片128k大小的区域用于专用页面映射)<br />
<br />
　　　　　kmalloc和get_free_page申请的内存位于物理内存映射区域，而且在物理上也是连续的，它们与真实的物理地址只有一个固定的偏移，因此存在较简单的转换关系，virt_to_phys()可以实现内核虚拟地址转化为物理地址：<br />
&nbsp;&nbsp; &nbsp;#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)<br />
&nbsp;&nbsp; &nbsp;extern inline unsigned long virt_to_phys(volatile void * address)<br />
&nbsp;&nbsp; &nbsp;{<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;　return __pa(address);<br />
&nbsp;&nbsp; &nbsp;}<br />
上面转换过程是将虚拟地址减去3G（PAGE_OFFSET=0XC000000）。<br />
<br />
与之对应的函数为phys_to_virt()，将内核物理地址转化为虚拟地址：<br />
&nbsp;&nbsp; &nbsp;#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))<br />
&nbsp;&nbsp; &nbsp;extern inline void * phys_to_virt(unsigned long address)<br />
&nbsp;&nbsp; &nbsp;{<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;　return __va(address);<br />
&nbsp;&nbsp; &nbsp;}<br />
virt_to_phys()和phys_to_virt()都定义在include\asm-i386\io.h中。<br />
<br />
而vmalloc申请的内存则位于vmalloc_start～vmalloc_end之间，与物理地址没有简单的转换关系，虽然在逻辑上它们也是连续的，但是在物理上它们不要求连续。<br />
<br />
我们用下面的程序来演示kmalloc、get_free_page和vmalloc的区别：<br />
#include &lt;linux/module.h&gt;<br />
#include &lt;linux/slab.h&gt;<br />
#include &lt;linux/vmalloc.h&gt;<br />
MODULE_LICENSE("GPL");<br />
unsigned char *pagemem;<br />
unsigned char *kmallocmem;<br />
unsigned char *vmallocmem;<br />
<br />
int __init mem_module_init(void)<br />
{<br />
　//最好每次内存申请都检查申请是否成功<br />
　//下面这段仅仅作为演示的代码没有检查<br />
　pagemem = (unsigned char*)get_free_page(0);<br />
　printk("&lt;1&gt;pagemem addr=%x", pagemem);<br />
<br />
　kmallocmem = (unsigned char*)kmalloc(100, 0);<br />
　printk("&lt;1&gt;kmallocmem addr=%x", kmallocmem);<br />
<br />
　vmallocmem = (unsigned char*)vmalloc(1000000);<br />
　printk("&lt;1&gt;vmallocmem addr=%x", vmallocmem);<br />
<br />
　return 0;<br />
}<br />
<br />
void __exit mem_module_exit(void)<br />
{<br />
　free_page(pagemem);<br />
　kfree(kmallocmem);<br />
　vfree(vmallocmem);<br />
}<br />
<br />
module_init(mem_module_init);<br />
module_exit(mem_module_exit);<br />
<br />
　　我们的系统上有160MB的内存空间，运行一次上述程序，发现pagemem的地址在0xc7997000（约3G+121M）、kmallocmem地址在0xc9bc1380（约3G+155M）、vmallocmem的地址在0xcabeb000（约3G+171M）处，符合前文所述的内存布局。<br />
 <img src ="http://www.cnweblog.com/lianzhanfeng/aggbug/313055.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnweblog.com/lianzhanfeng/" target="_blank">Peter.Lian</a> 2010-08-10 11:27 <a href="http://www.cnweblog.com/lianzhanfeng/archive/2010/08/10/313055.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>自定义事件</title><link>http://www.cnweblog.com/lianzhanfeng/archive/2009/03/03/298976.html</link><dc:creator>Peter.Lian</dc:creator><author>Peter.Lian</author><pubDate>Tue, 03 Mar 2009 08:15:00 GMT</pubDate><guid>http://www.cnweblog.com/lianzhanfeng/archive/2009/03/03/298976.html</guid><wfw:comment>http://www.cnweblog.com/lianzhanfeng/comments/298976.html</wfw:comment><comments>http://www.cnweblog.com/lianzhanfeng/archive/2009/03/03/298976.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnweblog.com/lianzhanfeng/comments/commentRss/298976.html</wfw:commentRss><trackback:ping>http://www.cnweblog.com/lianzhanfeng/services/trackbacks/298976.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;我们这个控件将演示控件的自定义事件的书写。这个控件有一个类型为string的SensitiveText属性，当用户在输入框中输入的文字为InvalidText时就会触发OnSensitiveText事件。按照惯例，我先把源码展示给大家：unit TextSenseEdit;interfaceuses&nbsp;&nbsp;SysUtils, Classes,...&nbsp;&nbsp;<a href='http://www.cnweblog.com/lianzhanfeng/archive/2009/03/03/298976.html'>阅读全文</a><img src ="http://www.cnweblog.com/lianzhanfeng/aggbug/298976.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnweblog.com/lianzhanfeng/" target="_blank">Peter.Lian</a> 2009-03-03 16:15 <a href="http://www.cnweblog.com/lianzhanfeng/archive/2009/03/03/298976.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在Internet传播声音 </title><link>http://www.cnweblog.com/lianzhanfeng/archive/2008/11/28/294824.html</link><dc:creator>Peter.Lian</dc:creator><author>Peter.Lian</author><pubDate>Fri, 28 Nov 2008 09:21:00 GMT</pubDate><guid>http://www.cnweblog.com/lianzhanfeng/archive/2008/11/28/294824.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在几年以前IP电话被炒的沸沸扬扬，但用过的人都觉得这个技术非常不成熟，语音质量很差，时断时续，还经常有延迟，结果这项技术的应用没有普及开来。但随着Internet应用的越来越广泛以及相关技术发展的日新月异，声音质量不断提高，通过Internet打电话早已不再是梦想，已经成为了我们生活中的一部分。今天我使用IP电话打长途，每分钟只需要3毛钱，使用OICQ的语音聊天，网友仿佛就在你的身边。如果我们的带...&nbsp;&nbsp;<a href='http://www.cnweblog.com/lianzhanfeng/archive/2008/11/28/294824.html'>阅读全文</a><img src ="http://www.cnweblog.com/lianzhanfeng/aggbug/294824.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnweblog.com/lianzhanfeng/" target="_blank">Peter.Lian</a> 2008-11-28 17:21 <a href="http://www.cnweblog.com/lianzhanfeng/archive/2008/11/28/294824.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>