linux每个进程4g,用户进程共享3~4G内核地址空间---Linux内核笔记 - 阿木的专栏 - CSDN博客...

本文探讨了Linux系统中用户进程如何共享3~4G的内核地址空间。通过分析内核源代码,详细解释了当进程尝试访问内核地址空间时,如何通过缺页中断机制将内核页表复制到进程页表的过程。

用户进程共享3~4G内核地址空间---Linux内核笔记 收藏

首先要说明的一点是:Linux在内核态运行时(中断生生或系统调用发生后进入内核态),使用的是当前进程的页目录,这样做的好处是不用频繁的切换页目录,防止频繁刷新TLB,提高效率。

每个用户进程有自己独立的0~3G地址空间,共享3~4G地址空间,也就是说每个进程页表的前768项是独立的,后面的256项全部进程共享。中断发生或系统调用后,进程陷入内核态,这时候需要使用3G~4G的内核地址空间,那么内核是在什么时候拷贝内核页表到进程页表的呢?

拷贝的时机发生在进程试图访问内核地址(这时候当前进程3~4G这段地址未映射),会发生缺页中断。

再看看缺页中断函数是如何工作的:

asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)

{

struct task_struct *tsk;

struct mm_struct *mm;

struct vm_area_struct * vma;

unsigned long address;

unsigned long page;

unsigned long fixup;

int write;

siginfo_t info;

/* get the address */

__asm__("movl %%cr2,%0":"=r" (address));

/* It's safe to allow irq's after cr2 has been saved */

if (regs->eflags & X86_EFLAGS_IF)

local_irq_enable();

tsk = current;

//如果产生缺页的地址>TASK_SIZE(3G的地方)且发生在内核态(用户态没有权限访问内>3G的地址),

//跳转到vmalloc_fault

if (address >= TASK_SIZE && !(error_code & 5))

goto vmalloc_fault;

。。。。。。。。。。。。。。。。。。。

//这里处理>3G内存的缺页中断,从init_mm(内核地址空间)拷贝一个页表到当前进程对应

//的页表项

vmalloc_fault:

{

int offset = __pgd_offset(address);

pgd_t *pgd, *pgd_k;

pmd_t *pmd, *pmd_k;

pte_t *pte_k;

asm("movl %%cr3,%0":"=r" (pgd));

pgd = offset + (pgd_t *)__va(pgd);

pgd_k = init_mm.pgd + offset;

if (!pgd_present(*pgd_k))

goto no_context;

set_pgd(pgd, *pgd_k);

pmd = pmd_offset(pgd, address);

pmd_k = pmd_offset(pgd_k, address);

if (!pmd_present(*pmd_k))

goto no_context;

set_pmd(pmd, *pmd_k);

pte_k = pte_offset(pmd_k, address);

if (!pte_present(*pte_k))

goto no_context;

return;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值