内核杂谈——操作系统对page的使用

目录

page_to_phys

page_address

__get_free_page

mk_pte

slab

举例:vmalloc表项的建立

举例:进程创建时分配内核栈


前面谈过一篇只谈page不谈ddr,是站在操作系统的角度来看待物理内存。

实际上page只是一个外衣,只是一段物理地址的代号,alloc_page出来的page也不可能往里写东西,因为page存在vmemmap中,和实际的线性映射区不搭。

下面举例一些page的使用方法

page_to_phys

#define page_to_phys(page)	(__pfn_to_phys(page_to_pfn(page)))

#define __page_to_pfn(page)	(unsigned long)((page) - vmemmap)
#define	__pfn_to_phys(pfn)	PFN_PHYS(pfn)
#define PFN_PHYS(x)	((phys_addr_t)(x) << PAGE_SHIFT)

首先根据page找到物理页帧号,然后将页帧号转为某个物理块的起始地址(该地址是4K对齐的)。可以用于获取某page对应的起始物理块。

 

page_address

对于没有CONFIG_HIGHMEM,page_address等同于page_to_virt(page)

#define page_to_virt(page)	({					\
	unsigned long __addr =						\
		((__page_to_voff(page)) | PAGE_OFFSET);			\
	__addr = __tag_set(__addr, page_kasan_tag(page));		\
	((void *)__addr);						\
})

#define __page_to_voff(kaddr)	(((u64)(kaddr) & ~VMEMMAP_START) * PAGE_SIZE / sizeof(struct page))

结果就是获取page对应的虚拟地址

 

__get_free_page

作用是将alloc的page 通过page_address(page)转为虚拟地址

unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order)
{
	struct page *page;

	page = alloc_pages(gfp_mask & ~__GFP_HIGHMEM, order);
	if (!page)
		return 0;
	return (unsigned long) page_address(page);
}

在建立页表项的时候会使用该函数建立缺失的表项,然后转为物理地址填到上一级表项中

 

mk_pte

#define mk_pte(page,prot)	pfn_pte(page_to_pfn(page),prot)

#define __page_to_pfn(page)	(unsigned long)((page) - vmemmap)
#define pfn_pte(pfn,prot)	\
	__pte(__phys_to_pte_val((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot))

在L3表项的建立过程中会使用到。将目标page转为物理地址,加上L3表项属性填充到pte中。

 

slab

slab中获取的对象是page中空闲freelist的地址,看一下freelist

static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node)
{
	struct page *page;
//alloc_page获取page
        page = alloc_slab_page(s, alloc_gfp, node, oo);	
//page_address获取page的虚拟地址
        start = page_address(page);
//freelist指向首地址
	page->freelist = start;
	for (idx = 0, p = start; idx < page->objects - 1; idx++) {
//不断获取下一个freelist地址,并链接起来
		next = p + s->size;
		next = setup_object(s, page, next);
		set_freepointer(s, p, next);
		p = next;
	}
	set_freepointer(s, p, NULL);
}

在申请page的时候就填充好了该page的freelist的地址

 

举例:vmalloc表项的建立

static int vmap_pte_range(pmd_t *pmd, unsigned long addr,
		unsigned long end, pgprot_t prot, struct page **pages, int *nr)
{
	pte_t *pte;
//get_user_page建立L3表项
	pte = pte_alloc_kernel(pmd, addr);   

	do {
		struct page *page = pages[*nr];
//mk_pte,填充L3表项
		set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
		(*nr)++;
	} while (pte++, addr += PAGE_SIZE, addr != end);
	return 0;
}

mk_pte的page来自alloc_page
static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
				 pgprot_t prot, int node)
{
...
	for (i = 0; i < area->nr_pages; i++) {
		struct page *page;
		page = alloc_pages_node(node, alloc_mask|highmem_mask, 0);
		area->pages[i] = page;
	}
...
}

 

举例:进程创建时分配内核栈

static unsigned long *alloc_thread_stack_node(struct task_struct *tsk, int node)
{
#ifdef CONFIG_VMAP_STACK
    ......
#else
	struct page *page = alloc_pages_node(node, THREADINFO_GFP,
					     THREAD_SIZE_ORDER);
//返回的是page的地址
	return page ? page_address(page) : NULL;
#endif
}

 

怎么说呢,page其实就是外衣,不能直接使用根据前期线性映射的关系可以获取到物理地址然后获得虚拟地址。打开MMU的机器只能使用虚拟地址,间接使用了物理地址。通常虚拟地址空间大于实际的物理地址空间,对于没有建立映射的虚拟地址,将触发异常然后修复。

 

路,边走边修。

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值