linux 内存管理

https://objectkuan.gitbooks.io/ucore-docs/content/lab2/lab2_3_3_3_phymem_pagelevel.html

http://www.voidcn.com/blog/xiaolei1982/article/p-843929.html

http://duartes.org/gustavo/blog/post/intel-cpu-caches/

http://luodw.cc/2016/02/17/malloc/

http://edsionte.com/techblog/archives/3937

http://guojing.me/linux-kernel-architecture/posts/memory-address/

http://ilinuxkernel.com/?p=1013

http://shuaihanhungry.github.io/2015/11/17/Linux%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86%E4%B9%8Bslab%E5%88%86%E9%85%8D%E5%99%A8/

http://www.secretmango.com/jimb/Whitepapers/slabs/slab.html

http://abcdxyzk.github.io/blog/2015/04/18/kernel-mm-vm-rm/

http://www.jb51.net/LINUXjishu/386344.html

0、概念

在高级语言中,变量名是一串字符(符号);在可执行文件中,变量是地址(段偏移量)表示。

1、逻辑地址、线性地址、物理地址的区别

了解这三个地址的区别前,了解下计算机的发展史。刚开始的机器是16位,这里的16位是指寄存器可存储的位数。由于受限于寄存器的位数,计算机的最大寻址范围为[0~2^16]。但是 机器的物理地址线有20根。从地址根数角度考虑,系统可寻址的范围为0~2^20。这就产生了一个问题,如何在16位寄存器的系统中,寻址20位的物理地址。答案是用两个寄存器合成一个地址,16位的段基址和16位的偏移量。20位的线性地址=16位的段基址*2^4 + 16位的偏移地址。尽管后来机器从16位变成了32位、甚至64位,为了兼容,依然保留这种段寻址方式。线性地址(虚拟地址)是为了解决将不同进程的地址空间区分开引入的,也就是保护模式。对于32位系统,每个进程都有2^32(4G)地址空间。她们之间的转换关系如下:逻辑地址->线性地址->物理地址。逻辑地址=段基址:偏移量。 指令中的地址是逻辑地址中偏移量。因此,cpu执行指令时接触到的是逻辑地址;线性地址也就是虚拟地址。每个进程都有相同的线性地址范围,对于32位系统,线性地址空间是[0~2^32];物理地址:cpu送到地址线的地址。

2、进程地址空间、用户地址空间、内核地址空间(只分析32位系统)

进程地址空间就是指进程的线程地址范围0~4G,其中0~3G是用户地址空间,3G~4G是内核地址空间。当进程在用户模式下执行的时候,产生的是用户地址空间,访问局部物理内存(用户有权访问的)当进程在内核模式执行时,可访问全部物理内存,如果物理内存有16G,则内核需能够用1G的地址空间[3G~4G]访问16G物理地址,这里涉及到的技术我们稍后讨论。

3、内部碎片、外部碎片

内部碎片是指一个存储空间单位(通常指一页)被占用,但是并没有占用满。比如一页4k,只存储了10B。(slab layer 很好的解决了内部碎片)

外部碎片是指一些存储空间并没有被占用,但是由于它们没有连续,而无法被分配(伙伴系统很好的避免了外部碎片)

4、问题

内核地址空间 如何映射到物理地址

你可能感兴趣的:(linux 内存管理)