[LINUX-02]linux内存管理
1 内存划分
对于 32位linux,进程:0~3G(0-0xc0000000),内核:3G~4G(0xc0000000-0xffffffff),所有进程的内核空间(3G~4G)都是共享的。
线性区映射的物理内存成为低端内存,剩下的内存被称为高端内存。
2 内存管理
2.1 物理内存管理
Linux内存最小管理单位为页(page),通常一页为4K。初始化时,linux会为每个物理内存也建立一个page的管理结构(切记是linux系统不是uboot,也就是物理内存的管理肯定是在linux系统上的),操作物理内存时实际上就是操作page页。某些设备会映射在物理内存地址外,这些地址会在使用时建立page结构。
2.2 进程内存管理:
Linux进程通过vma进行管理,每个进程都有一个task_struct结构体进行维护,其中的mm_struct结构体管理这进程的所有内存。Mm_struct中维护者一个vma链表,其中的每一个vma节点对应着一段连续的进程内存。这里的连续是指在进程空间中连续,物理空间中不一定连续。如果使用malloc等申请一段内存,则内核会给进程增加vma节点。
3 内存分配与映射
3.1 分配
3.1.1 进程空间内存分配
malloc/free:最常用的内存分配函数
valloc/free:分配的内存按页对齐
3.1.2 内核空间内存分配
__get_free_pages/free_pages:分配制定页数的低端内存,不能分配在高端
Alloc_pages/__free_pages:分配izhiding页数的内存,可以是高端内存
Kmalloc/kfree:分配的内存物理上连续,只能在低端分配
Vmalloc/vfree:分配的内存在内核空间中连续,物理上无需连续。Vmalloc由于不需要屋里也连续,会造成TLB抖动,所以性能很差,一般只有在必须申请大块内存时才使用,如动态插入模块时。
3.2 映射
3.2.1 用户空间与物理地址
仅mmap函数(其内部也是靠内核中使用remap_pfn_range实现的。所有地址空间转换都在内核中实现,线性非线性均可);
3.2.2 内核空间与物理地址
3.2.2.1 kmap
实现物理内存到内核地址空间的映射,物理内存地址可以是低端内存区,也可以是高端内存区,如果是低端,作用与page_address相同。
3.2.2.2 ioremap
实现物理地址到内核空间的映射,所谓的物理地址一般是指非物理内存的地址空间,也就是不在linux管理下的物理地址空间。它可以把这一段映射到内核空间中的非线性空间。
3.2.2.3 page_address
只适用于线性区,实现page到内核地址空间的转换。
phy_to_virt:物理转虚拟
virt_to_page:从一个内核虚地址得到该页的描述结构 struct page *
virt_to_phy:虚拟转物理
只适用于线性区。
3.2.3 用户空间与内核空间
进程上下文相关操作,
copy_from_user //将用户空间的数据传送到内核空间, put_user -- Write a simple value into user space.
copy_to_user //从内核区中读取数据到用户区,get_user -- Get a simple variable from user space.
ioctl
等;
--