kmap的实现分析与实验

本文深入探讨了Linux系统中ARM架构MMU(内存管理单元)下的kmap实现原理,通过详细的分析揭示了kmap在高阶页表中的映射过程。同时,文章还介绍了进行kmap实验的步骤,帮助读者更好地理解和应用kmap。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

kmap的实现分析

kmap/unkmap系统调用是用来映射高端物理内存页到内核地址空间的api函数,他们分配的内核虚拟地址范围属于[PKMAP_BASE,PAGE_OFFSET]即[0xbfe00000,0xc0000000]范围,大小是2M的虚拟空间,为了映射该块虚拟地址,所使用的二级页表的大小刚好是一个物理page的总计是两个pte table(4KB)
kmap的调用流程分析:
arch/arm/mm/highmem.c
void *kmap(struct page *page)
{
	might_sleep();
	if (!PageHighMem(page)){//如果是低端内存,则直接返内存页对应的直接映射虚拟地址
		//printk("low mem page\n");
		return page_address(page);//所有的低端内存,在内核初始化时就已经映射好了,并且是不变得,且物理到虚拟相差0xc0000000
	}else{
		//printk("high mem page\n");
	}
	return kmap_high(page);//高端内存页
}

进入/trunk/mm/highmem.c的kmap_high

/**
 * kmap_high - map a highmem page into memory
 * @page: &struct page to map
 *
 * Returns the page's virtual memory address.
 *
 * We cannot call this from interrupts, as it may block.
 */
void *kmap_high(struct page *page)
{
	unsigned long vaddr;

	/*
	 * For highmem pages, we can't trust "virtual" until
	 * after we have the lock.
	 */
	lock_kmap();
	vaddr = (unsigned long)page_address(page);
	if (!vaddr)//如果该页的映射还未建立
		vaddr = map_new_virtual(page);//开始建立新的映射
	pkmap_count[PKMAP_NR(vaddr)]++;//该数组的值为1,说明映射已经建立,为2表明该应声存在着引用
	BUG_ON(pkmap_count[PKMAP_NR(vaddr)] < 2);
	unlock_kmap();
	return (void*) vaddr;
}

进入到map_new_virtual函数:
static inline unsigned long map_new_virtual(struct page *page)
{
	unsigned long vaddr;
	int count;

start:
	count = LAST_PKMAP; // 2MB/4096KB=512 entries = LAST_PKMAP

	/* Find an empty entry */
	for (;;) {
		last_pkmap_nr = (last_pkmap_nr + 1) & LAST_PKMAP_MASK;
		if (!last_pkmap_nr) {
			flush_all_zero_pkmaps();
			count = LAST_PKMAP;
		}
		if (!pkmap_count[last_pkmap_nr])//为0,说明该虚拟地址不存在映射,没人使用
			break;	/* Found a usable entry */
		if (--count)//如果遍历了整个kmap虚拟空间,都不能找到空闲的虚拟地址,则休眠等待unkmap释放虚拟地址
			continue;

		/*
		 * Sleep for somebody else to unmap their entries
		 */
		{
			DECLARE_WAITQUEUE(wait, current);

			__set_current_state(TASK_UNINTERRUPTIBLE);
			add_wait_queue(&pkmap_ma
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值