linux内核第六记

Linux进程地址空间

1.虚拟内存

Linux操作系统采用虚拟内存管理技术,使得每个进程都拥有独立的进程地址空间,该地址空间为3G,用户看到和接触的都是虚拟地址,无法看到实际的物理地址。利用这种虚拟地址不但能起保护操作系统的作用,更重要的是用户程序可以使用比实际物理内存更大的地址空间。

Linux将4G的虚拟地址空间划分为两个部分:用户空间和内核空间。用户空间从0x00000000~0xbfffffff,内核空3G~4G,通常情况下,用户是不能访问内核地址空间,但用户进程通过系统调用访问内核空间。用户空间对应进程,所以每个进程切换,用户空间就跟着变化。把同一个程序同时运行10次会看到10个进程使用的线性地址一模一样。不一样的是其对应的页表和页目录。

创建进程fork()、程序载入execve()、动态内存分配malloc()的进程相关操作需要分配内存给进程,这是进程申请和获得的不是物理地址,仅仅是虚拟地址。

实际的物理内存只有当进程真的去访问新获取的虚拟地址时,才会由“请页机制”产生“缺页”异常,从而进入分配实际页框的程序。该异常是虚拟内存机制赖以存在的基本保证。它会告诉内核去为进程分配物理页,并建立对应的页表。这之后虚拟地址才实实在在地映射到物理地址上。

2.内核内存分配

2.1在应用程序中,常使用malloc函数进行动态内存分配。而在Linux内核中,通常使用kmalloc来动态内存分配。

kmalloc原型:

#include <linux/slab.h>

void *kmalloc(size_t size,int flags)

参数:

size:要分配内存的大小(分配的是实际的物理内存);

flags:分配标志,用来控制kmalloc的行为。

分配标志

1.GFP_KERNEL:进程上下文中分配。当空闲进程太少时,kmalloc函数使当前进程进入休眠,等待空闲页的出现。(16M-896)

2.GFP_ATOMIC:进程上下文之外的代码(包括中断处理)中分配内存,从不睡眠。分配正确正确返回,分配错误错误返回。

3.__GFP_DMA:这个标志要求分配能够DMA传输的内存去(物理地址在16M以下的页帧)

4.__GFP_HIGHMEM:这个标志分配的内存位于高端内存。(896M以上的)

2.2按页分配(4k)

如果模块需要分配大块的内存,那使用面向页的分配技术会更好。

1).get_zeroed_page (unsigned int flags)

返回指向新页面的指针,并将页面清零。

2).__get_free_page(unsigned int flags)

和上一样,但页面不清零。

3).__get_free_pages(unsigned int flags)

分配若干个连续的页面, 返回指向该内存区域的指针,但不清零这段内存区域。

3.释放内存

当程序用完这些页,可以使用下列之一来释放他们:

void free_page(unsigned long addr)

void free_pages(unsigned long addr, unsigned long order)

4.内存使用


由上图知,分配物理内存的路线有3条:

第一条:来自app应用,如malloc分配内存,拿到内存的虚拟地址空间,但并没有分配物理页,当访问这个虚拟地址时,产生缺页异常,然后请页异常,然后从空闲的物理页里面找出物理内存单元分配给app。

第二条:来自内核,如kmalloc分配内存,然后slab先有物理内存,然后kmalloc分配内存。

第三条:来自内核,如vmalloc,类似于malloc。

*未完







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值