jun-wiki

View My GitHub Profile

Posts (Latest 10 updated) :
Read all
Contents:
  1. 페이지 테이블
    1. 생성, 파괴, 활성화 (Creation, Destruction, and Activation)
    2. 검사 및 갱신 (Inspection and Updates)
    3. Accessed 비트와 Dirty 비트
      1. Aliasing(에일리어싱) 문제
      2. 관련 함수

페이지 테이블

Pintos에서는 pml4 (Page-Map-Level-4) 라고 부른다

페이지 테이블 인터페이스는 내부 구조 접근 용이하게 uint64_t * 로 표현한다

페이지 테이블 인터페이스와 내부 구조 설명이다

생성, 파괴, 활성화 (Creation, Destruction, and Activation)

이름 그대로 역할 한다

  • uint64_t * pml4_create (void);
    새로운 페이지 테이블을 생성해 반환
    새 페이지 테이블은 Pintos의 표준 커널 가상 페이지 매핑은 포함하지만, 사용자 가상 매핑은 포함 X
    메모리 확보 실패시 NULL 포인터 반환

  • void pml4_destroy (uint64_t *pml4);
    pml4가 보유한 모든 자원을 해제

  • void pml4_activate (uint64_t *pml4);
    pml4를 활성화
    활성 페이지 테이블은 CPU가 메모리 참조를 변환할 때 사용하는 테이블


검사 및 갱신 (Inspection and Updates)

페이지 테이블이 보관하는 페이지 ↔ 프레임 매핑을 조회하거나 갱신

실행 중 외에도 중단된 프로세스의 비활성 페이지 테이블에서도 동작한다

필요 시 TLB 플러시 한다

TLB 플러시: CPU가 캐시해둔 TLB 엔트리 버려서 다음에 새로운 페이지 테이블 내용 다시 읽게 하는 동작

  • bool pml4_set_page (uint64_t *pml4, void *upage, void *kpage, bool rw);
    사용자 페이지 upage를 커널 가상 주소 kpage가 식별하는 프레임에 매핑

    • rw == true -> 읽기/쓰기 가능

    • rw == false -> 읽기 전용

    • 조건:

      • upage는 매핑되어 있지 않아야 함

      • kpagepalloc_get_page(PAL_USER)로 얻은 커널 가상 주소여야 함
        성공 시 true,
        실패 시 false 반환

  • void * pml4_get_page (uint64_t *pml4, const void *uaddr);

    • uaddr이 매핑된 프레임 조회

    • 매핑되어 있으면 해당 프레임의 커널 가상 주소 반환, 아니면 NULL반환

  • void pml4_clear_page (uint64_t *pml4, void *upage);

    • 페이지를 pml4에서 “not present” 상태로 표시, 이후 해당 페이지 접근 시 페이지 폴트 발생

    • 단, 접근(accessed) 및 더티(dirty) 비트를 확인을 위해 나머지 PTE 비트들은 보존


Accessed 비트와 Dirty 비트

x86-64 하드웨어는 페이지 교체 알고리즘 구현을 돕기 위해 각 페이지 테이블 엔트리(PTE)에 두 개의 보조 비트를 제공한다

  • Accessed 비트: 해당 페이지에 읽기/쓰기가 발생하면 CPU가 1로 설정

  • Dirty 비트: 해당 페이지에 쓰기가 발생하면 CPU가 1로 설정

CPU는 이를 0으로 재설정 안하며 필요하면 운영체제에서 직접 초기화한다

Aliasing(에일리어싱) 문제

하나의 프레임을 여러 페이지가 가리킬 때다

어떤 주소로 접근했을 때 해당 PTE만 갱신되고, 다른 PTE는 갱신 안되는 문제

관련 함수

  • vpage의 PTE에 dirty 또는 accessed 비트가 설정되어 있으면 true, 아니면 false 반환

    • bool pml4_is_dirty (uint64_t *pml4, const void *vpage);

    • bool pml4_is_accessed (uint64_t *pml4, const void *vpage);


  • vpage의 PTE가 존재하면 dirty 또는 accessed 비트를 주어진 값으로 설정

    • void pml4_set_dirty (uint64_t *pml4, const void *vpage, bool dirty);

    • void pml4_set_accessed (uint64_t *pml4, const void *vpage, bool accessed);