프로젝트 1 Memory Management 단국대학교컴퓨터학과 29 백승재 ibanez1383@dankook.ac.kr k k http://embedded.dankook.ac.kr/~ibanez1383
강의목표 리눅스의물리메모리관리기법이해 할당 / 해제기법 리눅스의가상메모리관리기법이해 할당 / 해제기법 리눅스의물리메모리와가상메모리연결 / 혹은변환기법이해
가상메모리개념 (1/4) 3 가상메모리개념 프로그램이적재되어있는물리메모리와프로그램의수행시참조하는가상메모리를구분 가상주소 (virtual address) 와물리주소 (physical address) 간단한 C 프로그램예 /* test.c */ #include <stdio.h> int a,b; int glob = 3; char buf[1]; main(int argc, char *argv[]) { int i = 1; int local_var; } a=i+1; printf( value of a = %d\n,a);
가상메모리개념 (2/4) 4 test.c 의가상메모리구조 4GB kernel space /* 지역변수 */ kernel i l 3GB stack argc, argv, i, local_varl user space heap bss data text /* 전역변수 */ a, b, glob, buf /* 명령어 */ a=i+1; printf( value of a = %d\n,a);
가상메모리개념 (3/4) 5 Linux 커널에서가상메모리구조 xffffffff xc env_end arg_end arg_start start_stack end_bss end_data end_code start_code kernel stack bss data text bss data text shared memory other shared library shared C library x brk end_ data end_code start_code bss data text program (Source : Linux kernel Internals)
가상메모리개념 (4/4) 6 물리메모리구조 물리메모리는고정된크기의기본단위로구분된다. 기본단위를페이지프레임 (page frame) 이라고함. 보통 4/8KB physical memory 물리메모리의기본단위를 page frame, 가상메모리의기본단위를 page 라고한다!!
Memory Model(1/2) 7 Bus UMA Bus NUMA (Source : Unix Internals)
Memory Model(2/2) 8 Hybrid NUMA NORMA (Source : Unix Internals)
Bank and Node 9 UMA Bus Bus Bank Bank NUMA Bank pg_data_t contig_page_data Node pg_data_t *pgdat_list typedef struct pglist_data { zone_t node_zones[max_nr_zones]; zonelist_t t node_zonelists[gfp_zonemask+1]; int nr_zones; Node struct page *node_mem_map; unsigned long *valid_addr_bitmap; struct bootmem_data *bdata; unsigned long node_start_paddr; unsigned long node_start_mapnr; unsigned long node_size; int node_id; struct pglist_data *node_next; } pg_data_t; _ Node Node Node NULL
NODE 자료구조 typedef struct pglist_data{ zone_t node_zones[max_nr_zones]; // node를위한zone은 ZONE_HIGHMEM, ZONE_NORMAL, ZONE_DMA 3개이다. // 각 zone을가리키기위한배열임 zonelist_t node_zonelists[gfp_zonemask+1]; // ((xf=15)+1=16) 할당시에우선시되는 zone 순서를나타냄 // free_area_init_core() 에의해 // mm/page_alloc.c내의 build_zonelists() 가호출되면이순서를정렬해놓는다 int nr_zones; // 이 node에몇개의 zone이있는지나타내는 1~3사이의값. // 예를들어어떤 CPU는 ZONE_DMA 에해당되는메모리영역이없을수도있으므로항상 3은아니다 struct page *node_mem_map; // node 의각 physical frame 을나타내는 struct t page 배열의첫번째 page 임. }pg_data_t; // 이는전역배열인 mem_map 의어딘가에들어갈것이다 unsigned long *valid_addr_bitmap; // memory node 상에서, 실제로존재하지않는 'holes' 를나타내기위한 BITMAP // 사실상, Sparc과 Sparc64에서만사용되며다른 arch에선무시됨 struct bootmem_data *bdata // boot memory allocator가사용하는필드 unsigned long node_start_paddr; // node의 physical 한시작주소 // unsigned long은 PAE(physical Address Extension) 을사용하는 IA32나 // PPC44GP같은 PowerPC의변종들에선최적화되어작동하지않는다 // 좀더나은방법은 PFN(Page Frame Number) 를기록하는것이다. // PFN은간단히말해서 page-size단위로계산되는 physical memory의 index이다 // PFN은보통 (page_phys_addr >> PAGE_SHIFT) 로정의된다. unsigned long node_start_mapnr; // mem_map내에서의 page offset을나타냄 // 이숫자는,mem_map 과 lmem_map 이라고불리는 local l mem_map 사이의 page 갯수를계산하는, // free_area_init_core() 에서계산됨 unsigned long node_size; // 이 node내의총 page수 int node_id; // 에서시작되는 Node ID(NID) struct pglist_data *node_next; // NULL 로끝나도록되어있는, 다음 node 를가리키는 pointer 1
Node and Zone 11 Node ZONE ZONE ZONE typedef struct zone_struct { spinlock_t lock; unsigned long free_pages; unsigned long pages_min, pages_low, pages_high; int need_balance; free_area_t free_area[max_order]; wait_queue_head_t * wait_table; unsigned long wait_table_size; unsigned long wait_table_shift; struct pglist_data *zone_pgdat; struct page *zone_mem_map; unsigned long zone_start_paddr; unsigned long zone_start_mapnr; char *name; unsigned long size; } zone_t; ZONE_DMA ZONE_NORMAL ZONE_HIGHMEM X86 System 에서는 ZONE_DMA ~ 16M ZONE_NORMAL 16 ~ 896M ZONE_HIGHMEM 896 ~ end
Kernel Address Space(1/13) 12 Physical Address S/W CPU Data
Kernel Address Space(2/13) 13 Physical Address Linux CPU Data
Kernel Address Space(3/13) 14 Physical Address Linux CPU Data 1M Physical Memory Linux zimage 1G
Kernel Address Space(4/13) 15 Physical Address Linux CPU Data 4G Virtual Address Space 1G Physical Memory 1M Linux zimage
Kernel Address Space(5/13) 16 Physical Address Linux CPU Data 4G Virtual Address Space 1G Physical Memory Kernel 이사용 3G User APP가사용 1M Linux zimage
Kernel Address Space(6/13) 17 Physical Address Linux CPU Data 4G Virtual Address Space 1G Physical Memory 3G 1M Linux zimage
Kernel Address Space(7/13) 18 Physical Address Linux CPU Data 4G Virtual Address Space 1G Physical Memory Paging 3G 1M Linux zimage
Kernel Address Space(8/13) 19 Physical Address Linux CPU Data 4G Virtual Address Space 1G Physical Memory 3G 1M Linux zimage
Kernel Address Space(9/13) 2 Linu x CPU Physical Address Data 4G Virtual Address Space 1G Physical Memory 3G Kernel have no mm_struct! 1M Linux zimage
Kernel Address Space(1/13) 21 Physical Address Linux CPU Data 4G Virtual Address Space 1G Physical Memory Kernel 을위한 Page Global Directory 즉, Master Kernel Page Global Directory 3G swapper_pg_dir 1M Linux zimage
Kernel Address Space(11/13) 22 Physical Address Linux CPU Data 4G Virtual Address Space 1G Physical Memory 이제 Kernel 도 Physical Memory 에접근할수있게되었습니다. Linux Kernel 은 OS 입니다. 모든 Physical Memory 에접근해야합니다. 3G 1M Linux zimage
Kernel Address Space(12/13) 23 Physical Address Linux CPU Data 4G Virtual Address Space 1G Physical Memory 1:1 매핑은어떨까요? 문제점은? 3G 1M Linux zimage
Kernel Address Space(13/13) 24 Physical Address Linux CPU Data 4G Virtual Address Space 1G Physical Memory 896M 896M 까지만 1:1 매핑하고 그이상의메모리는임시로매핑하여사용 3G 1M Linux zimage
ZONE 자료구조 25 typedef struct zone_struct{ spinlock_t lock; //concurrent 한접근으로부터 zone을보호하는 spinlock unsigned long free_pages; // 현재 zone내의 free page들의총개수 unsigned long pages_min, pages_los, pages_high; //zone watermarks int need_balance; // 이플래그는 zone의균형을유지하기위해 kswapd 에게 pageout요청을하는데사용되는 flag이다 free_area_t free_area[mar_order]; //buddy allocator이사용하는 free area bitmaps wait_queue_head_t *wait_table; // Process 들이 page 가 free 되기를기다릴때사용되는 wait queues 의 hash table 이다 // 이는 wait_on_page() 와 unlock_page() 에서매우중요하다 // 물론 process들은한개의 queue에서대기할수도있지만, 이렇게하게된다면 // wake up 하게되는때에, 모든 process들은 lock걸리기전까지는 page를얻기위해경쟁하게된다 // 이렇게공유자원을얻기위해다투는프로세스들의큰그룹을 // Thundering herd 라고부른다. // (thundering herd : 여러프로세스가깨어나서, 이중, 하나만사용할수있는자원을차지하려고경쟁하고, // 나머지프로세스는다시잠든상태로돌아가는상황 ) unsigned long wait_table_size; //hash table내의 queue개수를결정하는, 2의제곱의수 unsigned long wait_table_shift; // 위에정의된 table size를계산하는데사용되는이진비트조합 struct pglist_data *zone_pgdat; // 부모 pg_data_t를가리키는 pointer struct page *zone_mem_map; // 현재 zone이참조하게되는전역배열 mem_map내의첫번째 page unsigned long zone_start_paddr; //node_start_paddr과유사하게사용됨 unsigned long zone_start_mapnr; //node_start_mapnr과유사하게사용됨 char *name; //ZONE을나타내는 'DMA', 'NORMAL', 'HIGHMEM' 중하나의문자열 unsigned long size; // page단위로표현되는 zone의크기 }zone_t;
ZONE 의 watermarks 26 Zone Watermarks
Watermarks 계산 27 Zone Watermarks page_low, pages_min, pages_high 보통 pages_low = pages_min * 2 pages_high = pages_min * 3 pages_min 필드는 free_area_init_core() 함수내에서계산됨 보통 (ZoneSizeInPages / 128)
ZONE 과 PageFrame 28 ZONE Page frame Page frame Page frame Page frame Page frame Page frame Page frame typedef struct page { struct list_head list; struct address_space *mapping; unsigned long index; struct page *next_hash; atomic_t count; unsigned long flags; struct t list_head lru; struct page **pprev_hash; struct buffer_head * buffers; #if defined(config_highmem) defined(want_page_virtual) void *virtual; #endif /* CONFIG_HIGMEM WANT_PAGE_VIRTUAL */ } mem_map_t; Page Page frame frame Page frame Page frame Page frame Page frame Page frame Page frame 각 NODE의모든page 구조체는보통 ZONE_NORMAL의시작부분 ( 혹은커널이올라오기위해예약해놓은메모리바로다음 ) 위치에있는전역배열인 mem_map 에유지된다
Page Frame 자료구조 29 typedef struct page{ struct list_head list; // page는많은list에속해있을수있고, 이필드는 list head를위해사용된다. // 예를들어, mapping되어있는 page는 address_space에의해관리되는세개의원형링크드리스트중하나에속해있을것이다. // 이세개의원형링크드리스트는 clean_pages, dirty_pages, locked_pages이다. // slab allocator 에서이필드는슬랩할당자에의해할당되었을때 page 를관리하기위해 // slab이나 cache structures로의포인터를저장하는역할을한다. // 또한 free pages의 link blocks 에서도사용된다. struct address_space *mapping // 파일이나 device 가 memory mapped 되어있을때, 그들의 inode 는 address_spacespace 와연결되어있다. // 만약이 page가파일에연결되어있다면이필드는 address space를가리킨다. // 만약 page가 anonymous이며 mapping이 set되어있다면, // address_space는 swap address space를관리하는 swapper_space이다. unsigned long index; // 이필드는두가지용도를가지며, 이는 page의 state가결정한다. // 만약이 page가 file mapping의일부라면이는 file내의 offset이다 // 만약이 page가 swap cache의일부라면이는 swap address space(swapper_space) 를위한address_space내의 offset이됨 // 둘째, 만약 page들의블록이특정 process를위해free되었다면 // 블록내에서의순서가저장될것이다. 이는 free_pages_ok() 함수내에서 set 된다 struct page *next_hash; // 파일매핑의일부인 page는 inode와 offset에의해hash된다. // 이필드는같은 hash bucket을공유하는페이지들을 link시켜주는필드이다.
Page Frame 자료구조 3 atomic_t count; // page의참조횟수이다. 만약 이되면이페이지는 free될것이다. // 그보다크다면, 하나이상의프로세스에서사용중이거나, // I/O를기다리기위한작업등으로인해커널내에서사용중임을나타낸다. unsigned long flags; // page 의상태를나타내는 flags 이다. 이는 <linux/mm.h> 내에모두정의되어있고, 표 21 2.1 에나열해놓았다. // bit를 test, clear, set하기위한여러개의매크로가정의되어있으며, 이를표 2.2에보였다. // 사실유일하게관심있는함수는아키텍쳐에의존적인함수인 arch_set_page_uptodate() 를 call하는setpageuptodate() 이다. struct list_head lru; // page 교체정책을위해, 교체되어나갈 page 는 // page_alloc.c내에정의되어있는 active_list나 inactive_list 둘중하나에존재해야한다. // 이필드는이러한 LRU리스트의 list head를가리키게된다. struct page **pprev_hash; // next_hash 의보완책인이필드로인해 hash 는 doubly lonked list 로동작할수있다. struct buffer_head *buffers; // 만약 page가연결되어있는 block device를위한buffer를가지고있다면 // buffer_head에대한정보를유지하기위해사용된다. // 만약 (it is backed by a swap file) 이면프로세스에의해 mapped된 anonymous page인경우엔 // 연결되어있는 buffer_head 를가리킬수도있다. // 이때 page는, 속해있는파일시스템에서정하는 block size단위로, // 저장장치로저장되는 sync작업이일어나야하므로필요하다. #if defined (CONFIG_HIGHMEM) defined(waant_page_virtual) void *virtual; // 일반적으로는 ZONE_NORMAL에속해있는 page만이커널에의해직접지정이가능하다 // ZONE_HIGHMEM zone내에있는 page를주소지정하기위해 kmap() 함수가사용되며 // 이함수는 page를 kernel과 map시켜주는역할을한다.(9장에서논의됨 ) // 고정된개수의 page 만이 map 될수있다. 만약 page 가 map 되었다면, 이필드는 page 의가상주소를나타낸다. #endif /*CONFIG_HIGHMEM WANT_PAGE_VIRTUAL */ }mem_map_t;
Buddy 31 To reduce external fragmentation Fast allocation and de-allocation of pages 연속적인 page( block ) 단위별로관리 1, 2, 4, 8.. pages each one block
free_area_t 구조체 32 /* ~/include/linux/mmzone.h #define MAX_ORDER 1 typedef struct zone_struct { free_area_t free_area[max_order]; } zone_t; typedef struct free_area_struct { struct list_head unsigned long }free_area_t; free_list; *map;
Data structure 33 free_area.[order].free_list 특정크기의 free page block 들의이중연결리스트 free_area.[order].map ((number of pages) -1 ) >> (order + 4)) + 1bytes 한비트가하나의버디의상태를나타낸다
Memory allocation 34 15 14 13 12 11 1 9 8 7 6 5 4 3 2 1 Physical Memory 8. 2page alloc. 요청 free 4 3 2 12 1 5 1 free_area.free_list fee free_area[order].map aea[ode]map Pages 1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 order() 1 1 order(1) 1-> order(2) 1 order(3)
Memory allocation 35 15 14 13 12 11 1 9 14 8 7 6 5 4 3 2 1 Physical Memory. 2page alloc. 요청 free 4 3 2 12 1 5 1 free_area.free_list fee free_area[order].map aea[ode]map Pages 1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 order() 1 1 order(1) -> 1 order(2) 1 -> order(3)
Memory de-allocation 36 15. alloc 14 11번 page 해제요청 13 12 11 11 8 1 9 8 7 6 5 8. 4 3 2 1 free_area.free_list 12 5 1 index = page_idx >> (order + 1) => 11 >> ( + 1 ) = 5 fee free_area[order].map aea[ode]map free index >>= 1 4 3 2 1 Physical Memory Pages order() order(1) order(2) order(3) 1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 1 1-> 1 -> 1-> -> 1
Buddy 관련함수 37
Slab Allocator 38 슬랩할당자 버디알고리즘은적은메모리할당엔부적절 같은크기의메모리공간에대한할당을반복하는경향있으므로캐시개념도입 캐시 : 객체의모음 같은크기메모리공간의창고 슬랩 : 캐시가들어있는주메모리영역을나눈것 (/proc/slabinfo) 연속된 PF하나이상으로구성됨 할당한객체와여유객체를모두포함 빈슬랩의 PF 스스로해제안함
Slab Allocator 구조 39 kmem_cache_t cache_cache next = cache_chain cache cache cache kmem_list3 slabs_full slabs_free slabs_partial slab slab slab slab (full) (full) (full) slab (free) slab (partial) slab (partial) object object
일반캐시와특수캐시 4 일반캐시 첫번째캐시 : 커널이사용하는나머지일반캐시에대한캐시디스크립터 cache_cache 변수에이디스크립터가들어있다 추가캐시 26 개 ( 나머지 26 개 ) : 기하학적으로메모리영역이들어있다. 32, 64, 128, 256, 512, 124, 248, 496, 8192, 16384, 32768, 65536, 13172 바이트메모리영역당두개의캐시디스크립터 두개중하나는 ISA DMA 용, 다른하나는일반할당용 특수캐시 자주할당해제되는커널의자료구조들을위한캐시
슬랩관련함수 41
가상주소공간할당 / 해제 42 일부가상주소공간 = region = 영역 = 구간 = vm_area_struct 메모리구역겹치는일은없음 인접한두구역은접근권한일치시합침
Creating a memory region ex. 43 case 1 arch_get_unmapped_area if addr!= null if addr + len < vma->start VMA. 1G next len addr VMA next VMA. 3G
Creating a memory region ex. 44 case 2 addr!= null addr + len > vma->start. OR addr == null VMA 1G next len addr VMA next VMA return ENOMEM If last vm_end + len > 3G len. addr 3G
Creating a memory region ex. 45 do_mmap_pgoff. 1G VMA next next new VMA len addr next VMA next VMA. 3G
Merging contiguous region 46 do_mmap_pgoff merge-able. 1G VMA next len addr next VMA next VMA. 3G
Remapping and Moving a memory region 47 do_mmap_pgoff memory region growing or shrink find another region. 1G VMA next VMA len next VMA new VMA. 3G
Delete a memory region 48 do_munmap. 1G VMA next VMA next VMA. 3G
Delete a memory region 49 do_munmap. 1G VMA next VMA next next next new VMA VMA. 3G
Linux 의 Page Table Management 전체구조 5
Linux 의 PGD 51 task_struct mm mm_struct pgd include/asm-i386/page.h <<pgd_t>> typedef struct { unsigned long long pgd; } pgd_t; include/asm-arm/page.h <<pgd_t>> typedef unsigned long pgd_t; Page Frame Array of pgd_t type Physical Memory pgd 로딩? X86 이라면 mm->pgd 를 cr3 에복사함으로써이뤄짐 flush_tlb() (cr3 복사는 TLB flushing 을유발하는단점이있음 )
task_struct mm mm_struct pgd Linux 의 PGD, PMD, PTE 52 Physical Memory Page Frame Page Fram me Page Frame Page Frame pgd_t pmd_t pte_t pgd_t pmd_t pte_t pgd_t pmd_t pte_t pgd_t pmd_t pte_t t pgd_t pmd_t pte_t PGD PMD PTE Swap out된경우에는? Swap entry 가 PTE 에저장되어있음 Fault 맞으면이 swap entry 를이용해 do_swap_page() 함수가 page 를처리해줌
주소변환을위한매크로 53
주소변환과정의이해 54 /* mm/memory.c */ static struct page * follow_page(struct mm_struct *mm, unsigned long address, int write) { pgd_t *pgd; pmd_t *pmd; pte_t *ptep, pte; pgd = pgd_offset(mm, address); if( pgd_none(*pgd) pgd_bad(*pgd)) goto out; pmd = pmd_offset(pgd, address); if( pmd_none(*pmd) pmd_bad(*pmd)) goto out; ptep = pte_offset(pmd, address); if(!ptep) goto out; } pte = *ptep;.
인텔처리기의페이징 55 주소변환 Linear Address 31 22 21 12 11 Directory Table Offset Physical Memory Page Directory Page Table 4K page entry entry ( In Physical Memory ) CR3
2.6.11 부터도입된 4 단계페이징 (x86_64 기준 ) 56 64bit address translation 4-level translation 63 48 47 39 38 3 29 21 2 12 11 Sign Extended PML4 Directory Ptr Directory Table Offset PML4 Page-Directory- Pointer Table Page-Directory Page-Table Physical-Address entry entry entry entry 4K Page ( In Physical Memory ) CR3 (PML4) 512 PML4 * 512 PDPTE * 512 PDE * 512 PTE = 2 36 Page frames (256TB)
커널의가상주소사용 (32bit 처리기기준 ) 57 Kernel address space( 32bit ) Virtual Memory 1MB 8MB 16MB 896MB 124MB Dynamically allocated VM_RESERVE (128M) Physical Memory BIOS comm area kernel code image DMA region mem_map
커널의가상주소사용 (64bit 처리기기준 ) 58 xffff ffff ffff ffff xffff ffff fff xffff ffff 88 xffff ffff 828 xffff ffff 8 xffff e2 xffff c2 xffff c1 xffff 81 xffff 8 x 7fff ffff ffff x module mapping space (1919MB) unused hole kernel text mapping (4MB) unused hole ioremap space (32TB) hole (1 TB) direct mapping space (64TB) guard hole. stack heap data text 가상메모리 kernel space user space
mm_struct 59 mm struct <linux/sched.h> h> struct mm_struct { struct vm_area_struct * mmap; // 주소공간내의모든 VMA regions 을연결하는 linked list 의 head rb_root_t mm_rb; //VMA는빠른탐색을위해 red_black tree형태의 linked list로구성된다. // 이필드는tree의 root를나타낸다 struct vm_area_struct * mmap_cache; // 마지막으로 find_vma() 함수가호출되었을때검색된 VMA를저장해놓는필드 // 이는한번사용된 VMA가곧다시사용될것이라는가정에기반한다. pgd_t * pgd; // 이프로세스를위한 PGD atomic_t mm_users; // 주소공간중유저공간에접근한사용자의카운트 atomic_t mm_count; //1 에서부터시작하는,real user를위한카운트필드 int map_count; // 사용중인 VMA개수 struct rw_semaphore mmap_sem; // 이는 VMA list에대한r/w시에보호를위해존재하는 lock이다. // 이를사용하는유저들은보통장시간사용하거나 // 락을잡은채로 sleep할수도있기때문에 spinlock은적합하지않다. // 이 list를 read하려는측에서는 down_read() 를통해세마포어를획득해야한다. // 만약 write를하려면down_write() 를통해서권한을획득해야하며 // 추후 VMA 를업데이트해야하는시점에는 page_table_lock 이란이름의 spinlock 을획득해야만한다.
mm_struct 6 }; spinlock_t page_table_lock; lock; // 이는 mm_struct구조전반에걸친보호 lock이다. //Rss와 VMA를수정으로부터보호해주는역할을담당한다. struct list_head mmlist; // 모든 mm_struct 구조체는이필드를통해연결된다. unsigned long start_code, end_code, start_data, end_data; //code영역의시작과끝, data영역의시작과끝을나타냄 unsigned long start_brk, brk, start_stack; // 힙영역의시작과끝,stack 의시작부분을나타냄 unsigned long arg_start, arg_end, env_start, env_end; //command line argument의주소의시작과끝, environments의시작과끝을나타냄 unsigned long rss, total_vm, locked_vm; //rss: 이프로세스를가사용중인 page 의개수 //global zero page는 RSS에의해카운트되지않는다. //total_vm: 이프로세스에의해점유되고있는전체메모리공간의총합 //locked_vm: 메모리상에 lock되어있는 page의개수 unsigned long def_flags;//vm_locked한가지값만이가능함 // 이는디폴트로앞으로일어날모든매핑이 lock될지를결정하는필드임 unsigned long cpu_vm_mask; //SMP system에서모든가능한 CPU를나타내는비트마스크 // 이는 IPI에의해서 CPU가특정함수를수행해야할지말아야할지를결정할때사용됨 // 이는각 CPU의 TLB를 flush시키는시점에중요하게사용됨 unsigned long swap_address; // 이는전체프로세스가스왑되어버린경우에 page out daemon이 // 어디서 swap 되었는지를기록하는데사용하는필드 unsigned dumpable:1;//prctl() 에의해set되며, 이필드는 process를 trace하고있을때만사용됨 mm_context_t context;// 아키에스페시픽한 MMU context
mm_struct 와가상주소공간구조 61 mm_struct 자료구조분석 include/linux/sched.h struct mm_struct { struct vm_area_struct *mmap; struct vm_area_struct *mmap_avl, *mmap_cache; pgd_t *pgd; atomic_t count; int map_count; struct semaphore mmap_sem; unsigned long context; t unsigned long start_code, end_code, start_data; unsigned long end_data, start_brk, brk, start_stack; unsigned long arg_start, arg_end, env_start, env_end; unsigned long rss, total_vm, locked_vm, def_flags; flags; } unsigned long swap_cnt, swap_address; void *segment; env_end arg_end arg_start start_stack brk end_data end_code start_code kernel stack bss data text typedef struct {unsigned long pgd;} pgd_t; /* include/asm-i386/page.h */
Memory Region 62 task_struct mm mm_struct pgd mmap vm_area_struct vm_end vm_start vm_prot vm_flags vm_next shared libraries pgd: page directory address vm_prot: read/write permissions for this area vm_flags shared with other processes or private to this process vm_end vm_start vm_prot vm_flags vm_next vm_end vm_start vm_prot vm_flags vm_next data text
vm_area_struct 자료구조 63 struct vm_area_struct { struct mm_struct * vm_mm; unsigned long vm_start; // 이 VMA가속해있는 mm_struct //regions의시작주소 unsigned long vm_end; //regions 의 end 주소 struct vm_area_struct *vm_next; // 주소공간내의모든 VMA 는이필드를통해 single linked list 로연결됨 }; pgprot_t vm_page_prot; // 이 VMA 내의 PTE 에적용되는 protections bit. 표 3.1 참조 unsigned long vm_flags; //VMA 의특성과 protections ti 을나타내는 flags rb_node_t vm_rb; //list로연결되어있는 VMA구조에서빠른검색을위해 VMA를 red-black tree로관리한다. // 이는특히대용량의공간이매핑되어있는상황에서페이지폴트가발생하여 // 빠르게적합한 regions을찾는것이중요한경우중요하게사용될수있다. struct vm_area_struct *vm_next_share; //shared library 처럼파일매핑에기반한 shared VMA 를 link 하는필드 struct vm_area_struct **vm_pprev_share; // vm_next_share의반대작업 struct vm_operations_struct * vm_ops; //open(), close(), nopage() 에대한함수포인터를담고있다. //disk와 data를 sync할때사용됨 unsigned long vm_pgoff; struct file * vm_file; unsigned long vm_raend; // 메모리맵되어있는파일인경우 page 단위로 aligned 되어있는 offset // 맵되어있는파일의 struct file에대한포인터 //read-ahead window의 end address. //fault가발생하면실제원하는 page에딸려서몇개의 page가같이올라온다. // 이때얼마나많은 page 가딸려서올라올지를결정한다 void * vm_private_data; //memory manage 에관계없이 device driver 가자체적인정보를저장할때사용된다.
Linux 커널메모리관리함수 64 Interface struct page * alloc_pages(unsigned int gfp_mask, unsigned int order) 2^order 크기의연속된물리적페이지들을할당후, 첫페이지의 page 구조체포인터를리턴 void * page_address(struct page *page) 매개변수로넘긴물리적페이지가현재포함돼있는논리적주소에대한포인터반환 Wrapping Function Page-level allocator : get_free_page() 요청된만큼의연속된메모리를할당 Kernel-level allocator 물리적으로연속하며, 128KB 이하임의길의의메모리할당 : kmalloc() 물리적으로비연속적인메모리할당 : vmalloc() Non-Contiguous Allocation Contiguous Allocation Slab Allocator Page-level Allocation Buddy System