内存管理--page.s memory.c源码分析

1.page.s

  1 /*
  2  *  linux/mm/page.s
  3  *
  4  *  (C) 1991  Linus Torvalds
  5  */
  6
  7 /*
  8  * page.s contains the low-level page-exception code.
  9  * the real work is done in mm.c
 10  */
 用来处理页异常的

 12 .globl _page_fault
 14 _page_fault:
 15     xchgl %eax,(%esp)

 16     pushl %ecx
 17     pushl %edx
 18     push %ds
 19     push %es
 20     push %fs

 21     movl $0x10,%edx
 22     mov %dx,%ds
 23     mov %dx,%es
 24     mov %dx,%fs
与系统调用不同,这里ds,es,fs全部设置为内核数据段

 25     movl %cr2,%edx
cr2中存放的是发生页异常时处理的指令

 26     pushl %edx
 27     pushl %eax
26行压栈的是导致异常的指令线性地址
27行保存的是异常号
上面二者作为参数调用处理函数

 28     testl $1,%eax
 29     jne 1f
 30     call _do_no_page   //  缺页异常
 31     jmp 2f

 32 1:  call _do_wp_page //写保护异常
 33 2:  addl $8,%esp      
 34     pop %fs
 35     pop %es
 36     pop %ds
 37     popl %edx
 38     popl %ecx
 39     popl %eax
 40     iret

总结

该文件是用来处理页错误的,page_fault是在kernel/traps.c中注册的。如下:
181 void trap_init(void)
199:    set_trap_gate(14,&page_fault);
当发生页错误时就会执行这里的_page_fault. 保存寄存器的值,把fs,es,ds均设为内核数据段,压栈发生页面异常的线性地址和出错号作为参数调用相应的函数(do_no_page或者do_wp_page),最后抛弃作为参数压栈的值,并弹出寄存器的值。


2.memory.c


  1 /*
  2  *  linux/mm/memory.c
  3  *
  4  *  (C) 1991  Linus Torvalds
  5  */
  6
  7 /*
  8  * demand-loading started 01.12.91 - seems it is high on the list of
  9  * things wanted, and it should be easy to implement. - Linus
 10  */
 11
 12 /*
 13  * Ok, demand-loading was easy, shared pages a little bit tricker. Shared
 14  * pages started 02.12.91, seems to work. - Linus.
 15  *
 16  * Tested sharing by executing about 30 /bin/sh: under the old kernel it
 17  * would have taken more than the 6M I have free, but it worked well as
 18  * far as I could see.
 19  *
 20  * Also corrected some "invalidate()"s - I wasn't doing enough of them.
 21  */   

 23 #include <signal.h>
 24
 25 #include <asm/system.h>
 26
 27 #include <linux/sched.h>
 28 #include <linux/head.h>
 29 #include <linux/kernel.h>
 30
 31 volatile void do_exit(long code);
 32
 33 static inline volatile void oom(void)
 34 {
 35     printk("out of memory\n\r");
 36     do_exit(SIGSEGV);
 37 }
 38
 39 #define invalidate() \
 40 __asm__("movl %%eax,%%cr3"::"a" (0))
用于刷新页变换高速缓冲

 42 /* these are not to be changed without changing head.s etc */
 43 #define LOW_MEM 0x100000
 44 #define PAGING_MEMORY (15*1024*1024)     //分页的内存总量
 45 #define PAGING_PAGES (PAGING_MEMORY>>12)     //总共的内存页数
 46 #define MAP_NR(addr) (((addr)-LOW_MEM)>>12)     //计算内存页号
 47 #define USED 100
 48
 49 #define CODE_SPACE(addr) ((((addr)+4095)&~4095) < \
 50 current->start_code + current->end_code)
判断给定的线性地址是否在当前进程的代码段中,((addr)+4095)&~4095用于取得addr所在内存页面的末端地址
 52 static long HIGH_MEMORY = 0;
 53
 54 #define copy_page(from,to) \
 55 __asm__("cld ; rep ; movsl"::"S" (from),"D" (to),"c" (1024):"cx","di","si")
 
 57 static unsigned char mem_map [ PAGING_PAGES ] = {0,};
 存放内存页的数组

 59 /*
 60  * Get physical address of first (actually last :-) free page, and mark it
 61  * used. If no free pages left, return 0.
 62  */
 63 unsigned long get_free_page(void)
 64 {
 65 register unsigned long __res asm("ax");
 67 __asm__("std ; repne ; scasb\n\t"
 68     "jne 1f\n\t"
 69     "movb $1,1(%%edi)\n\t"
 70     "sall $12,%%ecx\n\t"
 71     "addl %2,%%ecx\n\t"
 72     "mo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值