内核态介绍 : http://www.cnblogs.com/viviwind/archive/2012/09/22/2698450.html
4GB地址空间 : http://blog.csdn.net/zdy0_2004/article/details/42296109
两者就是特权级上的差别,内核态的特权是最高的ring0 用户态ring3
linux上每个进程都有一个4GB的内存空间
程序首先会在用户态运行用户代码,有三种情况会切换到内核态
①系统调用 : 当执行write,read等会调用系统内核的代码
②异常 : 当cpu执行用户态程序时,发生某种异常,就会跳到系统内核处理异常的代码
③中断 : 当设备产生中断信号时,会向执行内核中断代码
内核态地址映射ioremap();用户态地址映射mmap()
malloc:linux实现的是“虚拟内存系统”,对用户而言,所有内存都是虚拟的,也就是说程序并不是直接运行在物理内存上,而是运行在虚拟内存上,然后由虚拟内存转换到物理内存。
linux将所有的内存都以页为单位进行划分,通常每一页是4KB;
使用malloc分配的内存空间在虚拟地址空间上是连续的,但是转换到物理内存空间上有可能是不连续的,因为有可能相邻的两个字节是在不同的物理分页上;
malloc出来的是用户态的虚拟地址
kmalloc:
http://blog.csdn.net/flyingdon/article/details/5107346
在linux中最大分配32×page_size,page_size一般是4k,所以最大是128k,还有16k被也描述符占用,所以最大为128-16k
kmalloc保证申请的地址在物理地址上是连续的
分配出来的是内核态的虚拟地址,其物理地址可以通过virt_to_phys()函数得到
#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
通过上面可以看到仅仅是把地址加上或减去 PAGE_OFFSET,而
PAGE_OFFSET 在 x86 下定义为 0xC0000000