memory.c ( File view )

  • By 2010-08-31
  • View(s):24
  • Download(s):2
  • Point(s): 1
			/*
* 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
*/
/*
* Ǵ01.12.91 ʼд - ڳƱǺҪij
* ӦǺױƵ - 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.
*/
/*
* OKDZȽױдģҳȴҪе㼼ɡҳ
* 02.12.91 ʼдģܹ - Linus
*
* ִͨдԼ30 /bin/sh Թ˲ԣں˵Ҫռö
* 6M ڴ棬Ŀǰȴáڿúܺá
*
* "invalidate()"Ҳ - ⷽһIJ
*/

#include 		// źͷļźŷųźŽṹԼźŲԭ͡

#include 		// ϵͳͷļû޸/жŵȵǶʽꡣ

#include 	// ȳͷļṹtask_structʼ0 ݣ
// һЩйúͻȡǶʽຯ䡣
#include 		// head ͷļ˶ļ򵥽ṹͼѡ
#include 	// ںͷļһЩں˳úԭζ塣

volatile void do_exit (long code);	// ˳kernel/exit.c102 С

//// ʾڴϢ˳
static inline volatile void
oom (void)
{

  printk ("out of memory\n\r");
  do_exit (SIGSEGV);		// do_exit()Ӧʹ˳룬źֵSIGSEGV(11)

}				// ֵͬij뺬ǡԴʱáͬ塣

// ˢҳ任ٻ꺯
// ΪߵַתЧʣCPU ʹõҳݴоƬиٻС޸Ĺҳ
// Ϣ֮󣬾Ҫˢ¸ûʹ¼ҳĿ¼ַĴcr3 ķˢ¡
// eax = 0ҳĿ¼Ļַ
#define invalidate() \
__asm__( "movl %%eax,%%cr3":: "a" (0))

/* these are not to be changed without changing head.s etc */
/* 涨ҪĶҪhead.s ļеϢһı */
// linux 0.11 ںĬֵ֧ڴ16M޸Щʺϸڴ档
#define LOW_MEM 0x100000	// ڴͶˣ1MB
#define PAGING_MEMORY (15*1024*1024)	// ҳڴ15MBڴ15M
#define PAGING_PAGES (PAGING_MEMORY>>12)	// ҳڴҳ
#define MAP_NR(addr) (((addr)-LOW_MEM)>>12)	// ָڴַӳΪҳš
#define USED 100		// ҳ汻ռñ־μ405 С

// CODE_SPACE(addr) ((((addr)+0xfff)&~0xfff) < current->start_code + current->end_code)
// úжϸַǷλڵǰ̵ĴУμ252 С
#define CODE_SPACE(addr) ((((addr)+4095)&~4095) < \
current->start_code + current->end_code)

static long HIGH_MEMORY = 0;	// ȫֱʵڴ߶˵ַ

// 1 ҳڴ棨4K ֽڣ
#define copy_page(from,to) \
__asm__( "cld ; rep ; movsl":: "S" (from), "D" (to), "c" (1024): "cx", "di", "si")

// ڴӳֽͼ(1 ֽڴ1 ҳڴ)ÿҳӦֽڱ־ҳ浱ǰãռã
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.
*/
/*
* ȡ׸(ʵ1 :-)ҳ棬Ϊʹáûпҳ棬
* ͷ0
*/
//// ȡҳ档Ѿûпڴˣ򷵻0
// 룺%1(ax=0) - 0%2(LOW_MEM)%3(cx=PAGING PAGES)%4(edi=mem_map+PAGING_PAGES-1)
// %0(ax=ҳʼַ)
// %4 Ĵʵָmem_map[]ڴֽͼһֽڡֽͼĩ˿ʼǰɨ
// ҳ־ҳΪPAGING_PAGESҳУڴӳֽΪ0򷵻ҳַ
// ע⣡ָֻڴһҳҳ棬ûӳ䵽ij̵Եַȥ
// put_page()ӳġ
unsigned long
get_free_page (void)
{

  register unsigned long __res asm ("ax");

  __asm__ ("std ; repne ; scasb\n\t"	// λλal(0)Ӧÿҳ(di)ݱȽϣ
	   "jne 1f\n\t"		// ûе0 ֽڣת0
	   "movb $1,1(%%edi)\n\t"	// Ӧҳڴӳλ1
	   "sall $12,%%ecx\n\t"	// ҳ*4K = ҳʼַ
	   "addl %2,%%ecx\n\t"	// ټϵͶڴַҳʵʼַ
	   "movl %%ecx,%%edx\n\t"	// ҳʵʼַ??edx Ĵ
	   "movl $1024,%%ecx\n\t"	// Ĵecx üֵ1024
	   "leal 4092(%%edx),%%edi\n\t"	// 4092+edx λ??edi(ҳĩ)
	   "rep ; stosl\n\t"	// edi ָڴ㣨Ҳҳ㣩
	   "movl %%edx,%%eax\n"	// ҳʼַ??eaxֵ
"1:": "=a" (__res): "" (0), "i" (LOW_MEM), "c" (PAGING_PAGES), "D" (mem_map + PAGING_PAGES - 1):"di", "cx",
	   "dx");
  return __res;			// ؿҳַ޿Ҳ򷵻0

}

/*
* Free a page of memory at physical address 'addr'. Used by
* 'free_page_tables()'
*/
/*
* ͷַ'addr'ʼһҳڴ档ں'free_page_tables()'
*/
//// ͷַaddr ʼһҳڴ档
// 1MB µڴռں˳ͻ壬Ϊҳڴռ䡣
void
free_page (unsigned long addr)
{

  if (addr < LOW_MEM)
    return;			// ַaddr СڴͶˣ1MB򷵻ء
  if (addr >= HIGH_MEMORY)	// ַaddr>=ڴ߶ˣʾϢ
    panic ("trying to free nonexistent page");
  addr -= LOW_MEM;		// ַȥͶڴλãٳ4KBҳš
  addr >>= 12;
  if (mem_map[addr]--)
    return;			// Ӧڴҳӳֽڲ01 ء
  mem_map[addr] = 0;		// öӦҳӳֽΪ0ʾϢ
  panic ("trying to free free page");

}

/*
* This function frees a continuos block of page tables, as needed
* by 'exit()'. As does copy_page_tables(), this handles only 4Mb blocks.
*/
/*
* 溯ͷҳڴ飬'exit()'Ҫúcopy_page_tables()
* ƣú4Mb ڴ顣
*/
//// ָԵַ޳ҳͷŶӦڴҳָڴ鲢ñС
// ҳĿ¼λַ0 ʼ1024 ռ4K ֽڡÿĿ¼ָһҳ
// ҳַ0x1000 ʼĿ¼ռ䣩ÿҳ1024 Ҳռ4K ڴ档
// ÿҳӦһҳڴ棨4KĿ¼ҳĴСΪ4 ֽڡ
// from - ʼַsize - ͷŵijȡ
int
free_page_tables (unsigned long from, unsigned long size)
{

  unsigned long *pg_table;
  unsigned long *dir, nr;

  if (from & 0x3fffff)		// Ҫͷڴĵַ4M Ϊ߽硣
    panic ("free_page_tables called with wrong alignment");
  if (!from)			// ͼͷں˺ͻռռ䡣
    panic ("Trying to free up swapper memory space");
// ռҳĿ¼(4M Ľλ)Ҳռҳ
  size = (size + 0x3fffff) >> 22;
// һʼĿ¼ӦĿ¼=from>>22ÿռ4 ֽڣҳĿ¼Ǵ
// ַ0 ʼʵʵĿ¼ָ=Ŀ¼<<2Ҳ(from>>20)0xffc ȷ
// Ŀ¼ָ뷶ΧЧ
  dir = (unsigned long *) ((from >> 20) & 0xffc);	/* _pg_dir = 0 */
  for (; size-- > 0; dir++)
    {
				// size ҪͷڴĿ¼
      if (!(1 & *dir))		// Ŀ¼Ч(P λ=0)
	continue;		// Ŀ¼λ0(P λ)ʾӦҳǷڡ
      pg_table = (unsigned long *) (0xfffff000 & *dir);	// ȡĿ¼ҳַ
      for (nr = 0; nr < 1024; nr++)
	{
			// ÿҳ1024 ҳ
	  if (1 & *pg_table)	// ҳЧ(P λ=1)ͷŶӦڴҳ
	    free_page (0xfffff000 & *pg_table);
	  *pg_table = 0;	// ҳ㡣
	  pg_table++;		// ָҳһ
	
}
      free_page (0xfffff000 & *dir);	// ͷŸҳռڴҳ档ҳ
// ַ1M ڣʲô
      *dir = 0;			// ӦҳĿ¼㡣
    
}
  invalidate ();		// ˢҳ任ٻ塣
  return 0;

}

/*
* Well, here is one of the most complicated functions in mm. It
* copies a range of linerar addresses by copying only the pages.
* Let's hope this is bug-free, 'cause this one I don't want to debug :-)
*
* Note! We don't copy just any chunks of memory - addresses have to
* be divisible by 4Mb (one page-directory entry), as this makes the
* function easier. It's used only by fork anyway.
*
* NOTE 2!! When from==0 we are copying kernel space for the first
* fork(). Then we DONT want to copy a full page-directory entry, as
* that would lead to some serious memory waste - we just copy the
* first 160 pages - 640kB. Even that is more than we need, but it
* doesn't take any more memory - we don't copy-on-write in the low
* 1 Mb-range, so the pages can be shared with the kernel. Thus the
* special case for nr=xxxx.
*/
/*
* ˣڴmm Ϊӵij֮һֻͨڴҳ
* һΧԵַеݡϣûдΪҲ
* ٵ?
*
* ע⣡Dzǽκڴ - ڴĵַҪ4Mb ı
* һҳĿ¼ӦڴСΪʹܼ򵥡
* fork()ʹãfork.c 56 У
*
* ע2from==0 ʱΪһfork()øں˿ռ䡣ʱ
* 븴ҳĿ¼Ӧڴ棬Ϊᵼڴص˷ - 
* ֻͷ160 ҳ - Ӧ640kBʹǸЩҳҲѾǵ
* ⲻռøڴ - ڵ1Mb ڴ淶ΧDzִдʱƲ
* Щҳں˹nr=xxxx nr ڳָҳ
*/
//// ָԵַͳȣҳڴӦҳĿ¼ҳӶƵҳĿ¼
//// ҳӦԭڴʹá
// ַָͳȵڴӦҳĿ¼ҳҳҳԭڴ
// ˺̽ڴֱһִдʱŷµڴҳдʱƻƣ
int
copy_page_tables (unsigned long from, unsigned long to, long size)
{

  unsigned long *from_page_table;
  unsigned long *to_page_table;
  unsigned long this_page;
  unsigned long *from_dir, *to_dir;
  unsigned long nr;

// ԴַĿĵַҪ4Mb ڴַ߽ϡ
  if ((from & 0x3fffff) || (to & 0x3fffff))
    panic ("copy_page_tables called with wrong alignment");
// ȡԴַĿĵַĿ¼(from_dir to_dir)μ115 ע͡
  from_dir = (unsigned long *) ((from >> 20) & 0xffc);	/* _pg_dir = 0 */
  to_dir = (unsigned long *) ((to >> 20) & 0xffc);
// ҪƵڴռ
...
...
(Not finished, please download and read the complete file)
			
...
Expand> <Close

Want complete source code? Download it here

Point(s): 1

Download
0 lines left, continue to read
Sponsored links

File list

Tips: You can preview the content of files by clicking file names^_^
Name Size Date
linux0.00 B0% 04-10-07
<boot>0.00 B04-10-07 15:01
bootsect.s12.49 kB08-01-04 21:38
head.s13.22 kB08-01-04 21:38
setup.s12.42 kB08-01-04 21:38
<fs>0.00 B04-10-07 15:01
bitmap.c8.46 kB02-09-04 13:12
block_dev.c3.95 kB02-09-04 13:12
buffer.c17.71 kB02-09-04 13:12
char_dev.c4.09 kB02-09-04 13:12
exec.c18.90 kB02-09-04 13:12
fcntl.c3.33 kB02-09-04 13:12
file_dev.c4.82 kB02-09-04 13:12
file_table.c209.00 B02-09-04 13:12
inode.c14.92 kB02-09-04 13:12
ioctl.c1.94 kB02-09-04 13:12
Makefile6.80 kB08-01-04 21:45
namei.c37.20 kB02-09-04 13:12
open.c10.00 kB02-09-04 13:12
pipe.c5.42 kB02-09-04 13:12
read_write.c5.86 kB02-09-04 13:12
stat.c2.69 kB02-09-04 13:12
super.c13.57 kB02-09-04 13:12
truncate.c2.46 kB02-09-04 13:12
<include>0.00 B04-10-07 15:01
a.out.h8.22 kB02-09-04 13:14
<asm>0.00 B04-10-07 15:01
io.h772.00 B02-09-04 13:14
memory.h1.03 kB08-01-04 22:13
segment.h2.50 kB02-09-04 13:14
system.h4.08 kB02-09-04 13:14
const.h589.00 B02-09-04 13:14
ctype.h1.68 kB02-09-04 13:14
errno.h2.30 kB02-09-04 13:14
fcntl.h3.30 kB02-09-04 13:14
<linux>0.00 B04-10-07 15:01
config.h2.16 kB02-09-04 13:14
fs.h9.72 kB02-09-04 13:14
hdreg.h2.94 kB02-09-04 13:14
head.h760.00 B02-09-04 13:14
kernel.h1.44 kB02-09-04 13:14
mm.h473.00 B02-09-04 13:14
sched.h13.25 kB02-09-04 13:14
sys.h5.41 kB02-09-04 13:14
tty.h3.93 kB02-09-04 13:14
signal.h4.01 kB02-09-04 13:14
stdarg.h1.77 kB02-09-04 13:14
stddef.h378.00 B02-09-04 13:14
string.h21.75 kB02-09-04 13:14
<sys>0.00 B04-10-07 15:01
stat.h2.37 kB02-09-04 13:14
times.h377.00 B02-09-04 13:14
types.h1.10 kB02-09-04 13:14
utsname.h423.00 B02-09-04 13:14
wait.h1.48 kB02-09-04 13:14
termios.h13.58 kB02-09-04 13:14
time.h1.81 kB02-09-04 13:14
unistd.h9.21 kB02-09-04 13:14
utime.h392.00 B02-09-04 13:14
<init>0.00 B04-10-07 15:01
main.c12.52 kB02-09-04 13:12
<kernel>0.00 B04-10-07 15:01
asm.s5.10 kB08-01-04 22:48
<blk_drv>0.00 B04-10-07 15:01
blk.h5.69 kB02-09-04 13:14
floppy.c23.49 kB02-09-04 13:12
hd.c17.14 kB02-09-04 13:12
ll_rw_blk.c7.59 kB02-09-04 13:12
Makefile4.25 kB08-01-04 22:53
ramdisk.c6.13 kB02-09-04 13:12
<chr_drv>0.00 B04-10-07 15:01
console.c30.91 kB02-09-04 13:12
keyboard.S21.04 kB08-01-04 22:59
Makefile4.81 kB08-01-04 22:59
rs_io.s5.75 kB08-01-04 22:59
serial.c2.91 kB02-09-04 13:12
tty_io.c18.40 kB02-09-04 13:12
tty_ioctl.c10.70 kB02-09-04 13:12
exit.c8.08 kB02-09-04 13:12
fork.c6.78 kB15-07-07 22:10
<math>0.00 B04-10-07 15:01
Makefile3.21 kB08-01-04 23:01
math_emulate.c2.08 kB02-09-04 13:12
mktime.c2.72 kB02-09-04 13:12
panic.c952.00 B02-09-04 13:12
printk.c1.75 kB02-09-04 13:12
sched.c18.57 kB16-07-07 21:23
signal.c5.61 kB02-09-04 13:12
sys.c7.62 kB02-09-04 13:12
system_call.s12.53 kB08-01-04 22:48
traps.c8.29 kB04-10-07 14:57
vsprintf.c9.96 kB02-09-04 13:12
<lib>0.00 B04-10-07 15:01
close.c397.00 B02-09-04 13:12
ctype.c1.72 kB02-09-04 13:12
dup.c401.00 B02-09-04 13:12
errno.c66.00 B02-09-04 13:12
execve.c607.00 B02-09-04 13:12
Makefile4.83 kB08-01-04 22:30
malloc.c13.50 kB02-09-04 13:12
open.c1.22 kB02-09-04 13:12
setsid.c382.00 B02-09-04 13:12
string.c199.00 B02-09-04 13:12
wait.c774.00 B02-09-04 13:12
write.c545.00 B02-09-04 13:12
_exit.c616.00 B02-09-04 13:12
Makefile8.58 kB08-01-04 22:21
<mm>0.00 B04-10-07 15:01
Makefile2.91 kB08-01-04 22:34
memory.c25.10 kB02-09-04 13:12
page.s842.00 B08-01-04 22:34
<tools>0.00 B04-10-07 15:01
build.c8.12 kB02-09-04 13:12
...
Sponsored links

memory.c (286.77 kB)

Need 1 point
Your Point(s)

Your Point isn't enough.

Get point immediately by PayPal

More(Debit card / Credit card / PayPal Credit / Online Banking)

Submit your source codes. Get more point

LOGIN

Don't have an account? Register now
Need any help?
Mail to: support@codeforge.com

切换到中文版?

CodeForge Chinese Version
CodeForge English Version

Where are you going?

^_^"Oops ...

Sorry!This guy is mysterious, its blog hasn't been opened, try another, please!
OK

Warm tip!

CodeForge to FavoriteFavorite by Ctrl+D