Linux内核:虚拟地址到物理地址,是什么时候开始映射

【Linux内核:虚拟地址到物理地址,是什么时候开始映射】内核空间 和用户空间申请的内存最终和buddy怎么交互?以及在页表映射上的区别?虚拟地址到物理地址,什么时候开始映射?
Buddy的问题分配的力度太大 buddy算法把空闲页面分成1,2,4页,buddy算法会明确知道哪一页内存空闲还是被占用?
4k,8k,16k
无论是在应用还是内核,都需要申请很小的内存 。
从buddy要到的内存,会进行slab切割 。
slab原理:比如在内核中申请8字节的内存,buddy分配4K,分成很多个小的8个字节,每个都是一个object 。
slab,slub,slob 是slab机制的三种不同实现算法 。
linux 会针对一些常规的小的内存申请,数据结构,会做slab申请 。
cat /proc/slabinfo 可以看到内核空间小块内存的申请情况,也是slab分配的情况 。
<num_objs>:每个slab一共可以分出多少个obj,<active_objs> :还可以分配多少个obj,< pagesperslab>:每个slab对应多少个pages,< objperslab>:每个slab可以分出多少个object,< objsize>:每个obj多大,
slab主要分为两类:
一、常用数据结构像 nfsd_drc,UDPv6,TCPv6 ,这些经常申请和释放的数据结构 。比如,存在TCPv6的slab,之后申请 TCPv6 数据结构时,会通过这个slab来申请 。

Linux内核:虚拟地址到物理地址,是什么时候开始映射

文章插图
 
二、常规的小内存申请,做的slab 。例如 kmalloc-32,kmalloc-64,kmalloc-96,kmalloc-128
Linux内核:虚拟地址到物理地址,是什么时候开始映射

文章插图
 

Linux内核:虚拟地址到物理地址,是什么时候开始映射

文章插图
 
注意,slab申请和分配的都是只针对内核空间,与用户空间申请分配内存无关 。用户空间的malloc和free调用的是libc 。
更多Linux内核视频教程文档资料免费领取后台私信【内核大礼包】自行获取 。
Linux内核:虚拟地址到物理地址,是什么时候开始映射

文章插图
 
slab和buddy的关系?
1、slab的内存来自于buddy 。slab相当于二级管理器 。
2、slab和buddy在算法上,级别是对等的 。
两者都是内存分配器,buddy是把内存条分成多个Zone来管理分配,slab是把从buddy拿到的内存,进行管理分配 。
同理,malloc 和free也不找buddy拿内存 。malloc 和free不是系统调用,只是c库中的函数 。
mallopt在C库中有一个api是mallopt,可以控制一系列的选项 。
Linux内核:虚拟地址到物理地址,是什么时候开始映射

文章插图
 
M_TRIM_THRESHOLD:控制c库把内存还给内核的阈值 。
-1UL 代表最大的正整数 。
此处代表应用程序把内存还给c库后,c库并不把内存还给内核 。
<do your RT-thing>
程序在此处申请内存,都不需要再和内核交互了,此时程序的实时性比较高 。
kmalloc vs. vmalloc/ioremap内存空间: 内存+寄存器
register --> LDR/STR
所有内存空间的东西,CPU去访问,都要通过虚拟地址 。CPU --> virt --> mmu --> phys
cpu请求虚拟地址,mmu根据cpu请求的虚拟地址,查页表的物理地址 。
buddy算法,管理这一页的使用情况 。
两个虚拟地址可以映射到同一个物理地址 。
Linux内核:虚拟地址到物理地址,是什么时候开始映射

文章插图
 
页表 -> 数组,任何一个虚拟地址,都可以用地址的高20位,作为页表的行号去读对应的页表项 。而第12位,是指页面内偏移 。(由于一页是4K,2^12 足够描述)
kmalloc 和 vmalloc 申请的内存,有什么区别? 答:申请之后,是否还要去改页表 。一般情况,kmalloc申请内存,不需要再去改页表 。同一张页表,几个虚拟地址可以同时映射到同一个物理地址 。
寄存器,通过ioremap往vmalloc区域,进行映射 。然后改进程的虚拟地址页表 。
总结:所有的页,最底层都是用buddy算法进行管理,用虚拟地址找物理地址 。理解内存分配和映射的区别,无论是lowmem还是highmem 都可以被vmalloc拿走,也可能被用户拿走,只不过拿走之后,还要把虚拟地址往物理地址再映射一遍 。但如果是被kmalloc拿走,一般指低端内存,就不需要再改进程的页表 。因为这部分低端内存,已经做好了虚实映射 。
cat /proc/vmallocinfo |grep ioremap可以看到寄存器中的哪个区域,被映射到哪个虚拟地址 。
vmalloc区域主要用来,vmalloc申请的内存从这里找虚拟地址 和 寄存器的ioremap映射 。


推荐阅读