커널 스터디(iamroot 18기) 4주차 내용 정리 #2, 가상 메모리

문연수·2021년 7월 23일
1

iamroot (Linux Internal)

목록 보기
9/24

8. 가상 메모리

각 태스크는 task_stuct 라는 자료구조를 통해 관리되고, 고유한 가상 메모리 역시 mm_struct 를 통해 관리되어 진다.

mm_struct 자료구조는 크게 세 부분으로 구분되어진다.

  1. 태스크를 구성하고 있는 vm_area_struct
    같은 속성의 연속된 메모리 공간 > 리전 (region, 흔히 말하는 세그먼트)
    이러한 각각의 reginvm_area_struct 로 관리한다.
  2. 주소 변환을 위한 페이지 디렉터리의 시작주소: pgd (Page Global Directory)
  3. 가상 메모리의 구조에 대한 변수들: start_code, start_data, start_stack 등등.

9. vm_area_struct 코드

include/linux/mm_types.h 헤더 파일 내의 내용이다. 다음의 코드에서 다음의 필드를 찾을 수 있다:

  1. vm_start : 시작 주소
  2. vm_end : 끝 주소
  3. vm_flags : 접근 제어 플래그(Read-Only, Writable, etc.)
  4. vm_file : 실제 파일 위치
  5. vm_offset : 파일 내 세그먼트의 위치에 해당하는 오프셋

와 같은 필드를 찾을 수 있다. 4번과 5번은 페이지 폴트 발생 시 사용한다.

리눅스의 가상 주소 메모리 할당의 단위를 페이지(Page) 라 부르며, 크기는 보통 4 KiB 이다.

10. vm_area_struct 구조 및 동작 방식

하나의 태스크는 여러 개의 vm_area_struct 를 가진다. 겹치지 않으며 새로 사용하려는 가상 주소 공간이 인접한 vm_area_struct 와 동일한 속성을 가진다면, 하나의 vm_area_struct 로 합쳐진다.

같은 태스크에 속한 vm_area_struct 는 연결 리스트 + 레드 블랙 트리로 연결되어 있다. 섹션 8 의 그림을 보면 vm_next, vm_prev, vm_rb 가 그것에 해당한다.

효율성 문제 때문인데 탐색에서는 Red black Tree 를 사용하고, 연결 관계 파악에는 Doubly linked List를 사용한다.

각각의 멤버 변수는 가상 주소(Virtual Address) 를 저장한다.

Q. 가상 메모리는 누가 결정하는가?

가상 메모리의 각 주소는 elf_loader 가 결정한다. 커널은 전혀 개입하지 않는다.

data, bss 는 컴파일 타임에 그 크기가 결정되지만 다음의 차이가 있다: bss 는 메모리가 초기화되어 있으나, data 는 그러하지 않음.

스택과 힙 사이 공간에는 라이브러리가 올라간다 (ex. glibc)

Q. mm_struct 의 관리 범위

mm_struct 는 커널과 유저 영역 모두 관리할까?
1. 커널의 mm_structinit_mm 하나만 존재
2. 커널 스택은 task_structvoid *stack 으로 관리됨.

11. 가상 메모리와 물리 메모리의 연결 및 변환

프로그램의 실행은 아래의 순서로 이뤄진다:

  1. 태스크의 생성
  2. 가상 주소 공간 제공
  3. 필요 시 물리 메모리 제공
  4. 실행 파일의 내용을 물리 메모리에 적재
  5. 물리 주소와 가상 주소를 연결

실행 파일의 어느 부분을 물리 메모리에 적재하는지는 ELF Header 를 읽어서 결정한다. 가상주소와의 연결은 미리 정해진 규칙(~/include/linux/elf.h) 을 따른다.

12. 페이지 프레임(Page frame)

페이지(Page): 가상 메모리의 최소 할당 단위
페이지 프레임(Page frame): 물리 메모리의 최소 할당 단위

sys_execve() 시스템 콜은 인자로 전달된 프로그램을 메모리에 적재한다. sys_execv() 는 아래의 순서로 동작한다:

  1. free 한 페이지 프레임들을 할당 받는다.
  2. 파일의 일부 내용을 할당받은 페이지 프레임에 적재한다.
  3. 물리 메모리를 가상 주소로 변환하기 위한 페이지 테이블을 생성한다.
  4. 프로그램 실행

13. 요구 페이징 (demand paging)

파일의 모든 내용을 실행 즉시 물리 메모리에 적재하는 것이 아닌, 페이지 테이블의 NP (Not Present) 상태일 때, 폴트를 발생시켜 그 때 로드한다. 이를 요구 페이징(demand paging) 이라 한다.

요구 페이징을 확인하기 위해 간단한 예제 코드를 작성해보았다:

#include <stdio.h>
#include <stdbool.h>

char array[1024 * 1024 * 1024]; // 1 GiB

int main(void)
{
	while (true)
		/* do nothing */;

	return 0;
}

보는 것처럼 가상 메모리(VIRT)는 크지만 실제 사용하고 있는 메모리(RES)는 그리 많지 않다.

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>

char array[1024 * 1024 * 1024]; // 1 GiB

int main(void)
{
	srand((unsigned long) time(NULL));

	for (int i = 0; i < 1024 * 1024 * 1024; i++)
		array[i] = rand();

	while (true)
		/* do nothing */;

	return 0;
}

코드를 바꿔서 배열의 각 원소에 임의의 값을 집어 넣도록 했더니 실제 물리 메모리 사용량이 1.0g 로 바뀐 것을 볼 수 있다.

14. 가상 주소를 물리 주소로 변환하는 과정

PGD = Page Global Directory
PDM = Page Middle Directory
PTE = Page Table Entry

~/mm/memory.c => follow_page_pte()

대부분의 CPU 는 가상주소를 물리주소로 변환해주는 별도의 하드웨어를 장착하고 있고 이를, MMU (Memory management Unit) 이라 부른다. 지원하는 페이지 레벨은 CPU 제조사 별로 다르다.

64 bit CPU 인 경우 3 단계 페이징 기법으로 표현하기에 무리가 있으므로 4 단계 페이징을 사용한다 > 5.10 버전에선 5 단계까지 사용

버디나 슬랩 할당자는 연속적인 메모리 공간을 할당해주는데, 시스템은 연속적인 물리 메모리가 늘 넉넉하진 않다. 따라서 반드시 물리적으로 연속되지 않아도 되는, 가상적으로만 연속인 메모리를 할당해주는 vmalloc()vfree() 를 통해 할당&해제 받을 수 있다.

15. 가상 메모리의 장장점

장점

  1. 물리 메모리의 크기와 상관없이 상당히 큰 주소의 가상 공간을 사용자에게 제공할 수 있다.
  2. 프로그램의 모든 페이지들을 물리 메모리에 적재할 필요없이 페이지 폴트를 이용해 필요할 때만 적재하여 메모리를 효율적으로 사용할 수 있다 (demand paging)
  3. 여러 태스크가 특정 영역을 공유하고 있다면, 페이지 테이블에서 같은 페이지 프레임을 가르키게 하는 것으로 공유 메모리를 지원할 수 있다.

단점

  1. 물리 메모리에 접근하기 위해 가상 주로르 변환해야 한다. 이는 프로그램의 수행 시간을 떨어뜨린다.
  2. 메모리 접근에 대한 예측성을 떨어뜨린다.
  3. 큰 가상 주소를 지원하기 위해서는 다양한 하드웨어 장치(HAT (Hardware Addresss Translation) 또는 MMU (Memory Management Unit)) 를 필요로 한다.

출처

[이미지] https://www.programmersought.com/article/55702605527/
[사이트] https://medium.com/@mxatone/kernel-memory-randomization-and-trampoline-page-tables-9f73827270ab
[책] 리눅스 커널: 내부구조 (백승제, 최종무 저)

profile
2000.11.30

2개의 댓글

comment-user-thumbnail
2023년 11월 16일

운영체제 과제를 하는 도중에 많이 도움을 받았습니다 감사합니다 ㅠㅠ

1개의 답글