C h a p t e r 06
CPU CPU CPU 1MB 600KB 500KB 4GB 512MB 1GB 230
231
Virtual Memory Physical Memory Virtual address Physical address 0 CPU 4GB 3GB 1GB 61 init proc1maps cat 0x08048000 0xC0000000 0x08048000 3GB paging 232
CPU CPU MMUMemory Management Unit MMU 233
taskstruct struct mmstruct mm mmstruct includelinuxschedh struct mm_struct { struct vm_area_struct * mmap; rb_root_t mm_rb; struct vm_area_struct * mmap_cache; pgd_t * pgd; atomic_t mm_users; atomic_t mm_count; int map_count; struct rw_semaphore mmap_sem; spinlock_t page_table_lock; struct list_head mmlist; unsigned long start_code, end_code, start_data, end_data; unsigned long start_brk, brk, start_stack; unsigned long arg_start, arg_end, env_start, env_end; unsigned long rss, total_vm, locked_vm; unsigned long def_flags; unsigned long cpu_vm_mask; unsigned long swap_address; unsigned dumpable:1; mm_context_t context; }; 234
struct vmareastruct mmap vmareastruct vmareastruct mmap 61 vmareastruct vmareastruct includelinuxmmh struct vm_area_struct { struct mm_struct * vm_mm; unsigned long vm_start; unsigned long vm_end; struct vm_area_struct *vm_next; unsigned long vm_flags;... }; vmmm mmstruct vmstart vmend 61 vmflags vmnext vmnext NULL pgdt pgd pgd startcodeendcode 235
startdataenddata BSSBlock Started by Symbol startbrkbrk heap malloc free brk startstack envstartenvendargstartargend 3GB envstart envend argstart argend main env argv argend main sysshmget 62 236
63 237
01 #include<stdio.h> 02 #include<malloc.h> 03 #include<unistd.h> 04 #include<linux/unistd.h> 05 #include<errno.h> 06 #define NR_getvminfo 259 07 int vbss; 08 int vdata=1; 09 10 struct vminfo { 11 unsigned long startcode; 12 unsigned long endcode; 13 unsigned long startdata; 14 unsigned long enddata; 15 unsigned long startbrk; 16 unsigned long brk; 17 unsigned long startstack; 18 }; 19 20 _syscall2(int, getvminfo, int, pid, struct vminfo*, vm) 238
21 22 int main() 23 { 24 25 int i, pid, vstack=2; 26 struct vminfo vm; 27 28 pid = getpid(); 29 i = getvminfo(pid, &vm); 30 31 printf("processs memory information\n"); 32 printf("location of main Function in Code Segment: %p(%lx~%lx)\n",main, vm.startcode, vm.endcode); 33 printf("=============================================\n"); 34 printf("location of Initialied Data in Data Area: %p(%lx~%lx)\n",&vdata, vm.startdata, vm.enddata); 35 printf("=============================================\n"); 36 printf("location of uninitialized Data in BSS Area: %p(%lx~%lx)\n",&vbss, vm.enddata, vm.startbrk); 37 printf("=============================================\n"); 38 printf("stack Location:%p(%lx~)\n",&vstack, vm.startstack); 39 printf("=============================================\n"); 40 41 sbrk(3); 42 char*b = sbrk(0); 43 i = getvminfo(pid, &vm); 44 printf("heap Location:%p(%lx~%lx)\n",b, vm.startbrk, vm.brk); 45 printf("=============================================\n"); 46 return 0; 47 } 239
01 #include <linux/kernel.h> 02 #include <linux/module.h> 03 #include <sys/syscall.h> 04 #include <asm/uaccess.h> 05 #include <linux/mm.h> 06 07 #define NR_getvminfo 259 08 09 asmlinkage int (*saved_entry)(void); 10 extern void *sys_call_table[]; 11 12 struct vminfo { 13 unsigned long startcode; 14 unsigned long endcode; 15 unsigned long startdata; 16 unsigned long enddata; 17 unsigned long startbrk; 18 unsigned long brk; 19 unsigned long startstack; 20 21 }; 22 23 asmlinkage int sys_getvminfo(int pid, struct vminfo *uvm) 24 { 25 26 struct vminfo vm; 27 struct task_struct *t; 240
28 struct mm_struct *mm; 29 30 t = find_task_by_pid(pid); 31 mm = t->active_mm; 32 33 vm.startcode = mm->start_code; 34 vm.endcode = mm->end_code; 35 vm.startdata = mm->start_data; 36 vm.enddata = mm->end_data; 37 vm.startbrk = mm->start_brk; 38 vm.brk = mm->brk; 39 vm.endenv = mm->env_end; 40 vm.startstack = mm->start_stack; 41 42 copy_to_user(uvm, &vm, sizeof(struct vminfo)); 43 return 0; 44 } 45 46 int module_start() 47 { 48 49 saved_entry = sys_call_table[ NR_getvminfo]; 50 sys_call_table[ NR_getvminfo] = sys_getvminfo; 51 return 0; 52 } 53 54 void module_end(void) 55 { 56 sys_call_table[ NR_getvminfo] = saved_entry; 57 } 58 59 module_init(module_start); 60 module_exit(module_end); 61 62 MODULE_LICENSE("GPL"); 241
TARGET = getvminfo INCLUDE = -isystem /usr/src/linux-2.4.32/include CFLAGS = -O2 -D KERNEL -DMODULE $(INCLUDE) //CFLAGS = -O2 $(INCLUDE) CC = gcc ${TARGET}.o: ${TARGET}.c clean: rm -rf ${TARGET}.o #gcc -o app_getvminfo app_getvminfo.c #insmod getvminfo.o #./app_getvminfo 242
243
4GB 4KB 8KB 512MB 512MB4KB 4GB 4KB n n n 244
64Task itask j page table 3 245
65 64 Task i 023 PFNPage Frame Number PPresent 0 1 0 1 2 i1 CPU 32bit 20bit 12bit 246
65 0x100 0x100 2 0000 0000 0000 0000 0000 0001 0000 00002 0 0x100 0 4K0x1000 0x11004KB 0x100 0x1001 0x1001 2 0000 0000 0000 0000 0001 0000 0000 0001220bit 1 P 0 page fault Demand Paging 4GB 4KB 1048756 4byte 4MB 1M 4M 2 3 26 4 247
CPU MMU 2 x86 CPU 80386 8086 protected mode 16bit 16bit 20bit 1MB 80286 8086 real mode 80286 24bit 16bit 16MB selector 24bit base address descriptor table 80286 8086 16bit 64KB 80286 80386 80386 32bit 4GB 8086 CPU 80386 i386 80386 66 MMU 248
1 i386 67 MMU linear address 16bit 32bit 68 TITable Indicator RPLRequested Privilege Level 3 249
64bit 32bit 20bit 4GB GDTGlobal Descriptor Table LDTLocal Descriptor Table GDT GDTR LDT LDTR 2bit DPLDescriptor Privilege Level 03 4 0 3 CPU CPLCurrent Privilege Level RPL CPL DPL CPL 32bit 3 10bit 10bit 12bit 69 250
69 CR3 10bit 03FF 1024 32bit 4byte 4KB 1024 1024 10bit 4KB 1024 251
4KB 12bit 69 12bit 1024 1024 4KB 4GB MMU TLBTranslation Lookaside Buffer TLB TLB TLB 2 610 32bit 0x100 0000 0000 0000 0000 0000 0001 0000 00002 10bit 0000 0000 00 10bit 00 0000 0000 12bit 0001 0000 0000 CR3 CR364KB 64K 10bit 0 0 128K 10bit 10bit 0 0 4K 12bit 252
253
3 i386 Alpha CPU 64bit 2 3 611 26 4 3 2 64bit 32bit i386 2 3 254
i386 3 2 3 pgdtpmdtptet pgdoffset pmdoffset pteoffset CR3 pgdoffset pmdoffset pteoffset pgdoffsetmmaddress pmdoffsetdiraddress pteoffsetdiraddress pgdnonepgdpmdnonepmdptenonex 0 1 255
pgdpresentpgdpmdpresentpmdptepresentpte Present 1 pgdclearpgdpmdclearpmdpteclearpte pgdpagepgd pmdpagepmd ptepagex page 256
01 asmlinkage int sys_getmeminfo(int pid) 02 { 03 struct task_struct *t; 04 struct mm_struct *mm; 05 struct vm_area_struct *mmap; 06 struct file *file; 07 08 char *filename; 09 char *buf; 10 11 t = find_task_by_pid(pid); 12 mm = t->active_mm; 13 mmap = mm->mmap; 14 buf = (char*)kmalloc( 512, GFP_KERNEL); 15 16 while(mmap) { 17 printk("%08lx - %08lx", mmap->vm_start, mmap->vm_end ); 18 file = mmap->vm_file; 19 if(file){ 20 filename = d_path(file->f_dentry, file->f_vfsmnt, buf, 512); 21 printk("%s \n", filename ); 22 } 23 else{ 24 printk("\n"); 25 } 26 mmap = mmap->vm_next; 27 } 28 return 0; 29 } 257
01 /* app_displaymeminfo.c */ 02... 03 #define NR_getmeminfo 258 04 _syscall1(int, getmeminfo, int, pid) 05 06 int main(int argc, int *argv[]) 07 { 08 int i, pid; 09 10 pid = atoi(argv[1]); 11 i = getmeminfo(pid); 12 } TARGET = getmeminfo INCLUDE = -isystem /usr/src/linux-2.4.32/include CFLAGS = -O2 -D KERNEL -DMODULE $(INCLUDE) //CFLAGS = -O2 $(INCLUDE) CC = gcc ${TARGET}.o: ${TARGET}.c 258
clean: rm -rf ${TARGET}.o #gcc -o app_displaymeminfo app_displaymeminfo.c #insmod getmeminfo.o #./app_displaymeminfo 259
613 cat procslabinfo gfpmask allocpagesgfpmaskorder 2 order page 260
allocpagegfpmask allocpages order 0 getfreepagesgfpmaskorder 2 order getfreepagegfpmask getzeroedpagegfpmask 0 getdmapagesgfpmaskorder DMA getfreepages gfpmask GFPDMA kmallocsizeflags size vmallocsize size freepagespageorder 2 order freepagesaddrorder 2 order freepagepage freepageaddr kfreeobjp kmalloc vfreeaddr vmalloc 261
FIFOOPTOptimal Page replacementlru Least Recently UsedLFULeast Frequently UsedMFUMost Frequently Used FIFO OPT LFU MFU LRU LRU LRU LRU LRU LRU LRU LRU Approximation Page Replacement Accessed Dirty 262
614 kswapd kswapd 615 kswapdinit kswapdcansleep kswapdbalance 263
kswapdbalance kswapdbalancepgdat trytofreepageszone shrinkcaches LRU activelist inactivelist swapouttrytofreepageszone 616 trytoswap out 1 0 616 swapout mmstruct swapoutvma swapoutpgd swapoutpmd trytoswapout 264
1 2 3 4 5 6 7 265
1 2 266