linux 0.11源码 内存管理 memory.c

本文详细探讨了Linux 0.11版本内核中的内存管理机制,尤其是通过`memory.c`文件中的关键代码,揭示了如何进行内存页面的复制操作,涉及`cld`, `rep` 和 `movs` 指令的使用。" 91865331,348161,商城商品分类查询实现,"['前端开发', '后端开发', '数据库', 'Web框架']
摘要由CSDN通过智能技术生成
/*
 *  linux/mm/memory.c
 *
 *  (C) 1991  Linus Torvalds
 */


/*
 * demand-loading started 01.12.91 - seems it is high on the list of
 * things wanted, and it should be easy to implement. - Linus
 */


/*
 * Ok, demand-loading was easy, shared pages a little bit tricker. Shared
 * pages started 02.12.91, seems to work. - Linus.
 *
 * Tested sharing by executing about 30 /bin/sh: under the old kernel it
 * would have taken more than the 6M I have free, but it worked well as
 * far as I could see.
 *
 * Also corrected some "invalidate()"s - I wasn't doing enough of them.
 */



#include <signal.h>
#include <asm/system.h>
#include <linux/sched.h>
#include <linux/head.h>
#include <linux/kernel.h>


volatile void do_exit(long code);

// 内存超过界限
static inline volatile void oom(void)
{
printk("out of memory\n\r");
do_exit(SIGSEGV);
}


// cr3 页目录地址清0
#define invalidate() \
__asm__("movl %%eax,%%cr3"::"a" (0))



/* these are not to be changed without changing head.s etc */
#define LOW_MEM 0x100000
#define PAGING_MEMORY (15*1024*1024)
#define PAGING_PAGES (PAGING_MEMORY>>12)   //页的数目
#define MAP_NR(addr) (((addr)-LOW_MEM)>>12)    //转换到页面的地址
#define USED 100


#define CODE_SPACE(addr) ((((addr)+4095)&~4095) < \
current->start_code + current->end_code)


static long HIGH_MEMORY = 0;

// cld->clear direction; rep->重复执行;movs-> move string to string; 该宏实现了一个内存页面的复制;

#define copy_page(from,to) \
__asm__("cld ; rep ; movsl"::"S" (from),"D" (to),"c" (1024):"cx","di","si")



static unsigned char mem_map [ PAGING_PAGES ] = {0,};


/*
 * Get physical address of first (actually last :-) free page, and mark it
 * used. If no free pages left, return 0.
 */

unsigned long get_free_page(void)
{
register unsigned long __res asm("ax"); //编译时尽量把变量__res放入到eax寄存器;


__asm__( "std ; repne ; scasb\n\t"   //std-> set direction; repne->repeat non-equal; scasb-> compare string data : [eax]与 ei[di]所指内存比较;
"jne 1f\n\t"  // 1是label; f: 表示向后跳转;
"movb $1,1(%%edi)\n\t"  // $+数字->表示立即数;
"sall $12,%%ecx\n\t"
"addl %2,%%ecx\n\t"
"movl %%ecx,%%edx\n\t"
"movl $1024,%%ecx\n\t"
"leal 4092(%%edx),%%edi\n\t"
"rep ; stosl\n\t"
"movl %%edx,%%eax\n"
"1:"
:"=a" (__res)
:"0" (0),"i" (LOW_MEM),"c" (PAGING_PAGES),
"D" (mem_map+PAGING_PAGES-1)
:"di","cx","dx");
return __res;
}


/*
 * Free a page of memory at physical address 'addr'. Used by
 * 'free_page_tables()'
 */
void free_page(unsigned long addr)
{
if (addr < LOW_MEM) return;
if (addr >= HIGH_MEMORY)
panic("trying to free nonexistent page");
addr -= LOW_MEM;
addr >>= 12;
if (mem_map[addr]--) return;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值