Linux低端内存映射,Linux内核态的内存分配和内存映射的关系

在内存中,有两种资源。这两种资源都需要申请。

1. 物理内存空间

2. 虚拟地址

像分配内存函数kmalloc 和__get_free_page函数是在低端内存中分配物理内存空间,然后直接返回相对应的内核逻辑地址(低端内存都映射到内核逻辑地址上3G~4G)。

然而vmalloc函数是在高端内存中分配物理内存空间的,因为没有相对应的内核逻辑地址,所以需要再分配内核虚拟地址,然后修改页表,映射内核虚拟地址和物理内存空间,最后返回内核虚拟地址。

假设有一段物理内存是一个page结构数组,用于跟踪系统中的物理内存。设这段起始内存地址是START_ADDR。

struct page *mem_map = (struct page *)START_ADDR;

假如某个struct page *page指针指向这个page结构数组中的某个元素,则可以通过 page – mem_map得到这个元素的下标。而下标跟物理内存页相关联,进而得到物理内存地址。

也就是说根据 struct page的地址,能找到这个page所代表物理页的地址。

kmap()是主要用在高端存储器页框的内核映射中,一般是这么使用的:

使用alloc_pages()在高端存储器区得到struct page结构,然后调用kmap(struct *page)在内核地址空间PAGE_OFFSET+896M之后的地址空间中(PKMAP_BASE到FIXADDR_STAR)建立永久映射(如果page结构对应的是低端物理内存的页,该函数仅仅返回该页对应的虚拟地址)

kmap()也可能引起睡眠,所以不能用在中断和持有锁的代码中

不过kmap 只能对一个物理页进行分配,所以尽量少用。

使用kmap的原因:

对于高端物理内存(896M之后),并没有和内核地址空间建立一一对应的关系(即虚拟地址=物理地址+PAGE_OFFSET这样的关系),所以不能使用get_free_pages()这样的页分配器进行内存的分配,而必须使用alloc_pages()这样的伙伴系统算法的接口得到struct *page结构,然后将其映射到内核地址空间,注意这个时候映射后的地址并非和物理地址相差PAGE_OFFSET.

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值