arch/arm64/kernel/setup.c
void __init setup_arch(char **cmdline_p)
arch/arm64/mm/mmu.c
void __init early_fixmap_init(void) 함수를 스터디 중, 궁금한점이 있어서 질문을 올립니다.
질문 1. arch/arm64/include/asm/pgtable.h 파일내에
#define pud_valid(pud) pte_valid(pud_pte(pud)) 정의가 되어 있습니다.
구조적으로 보면 pud -> pmd -> pte 순서대로 valid 체크가 되어야 할 것 같은데
바로 pud->pte로 변환하여 valid 체크가 되고 있습니다.
pte_valid 체크를 통해서 어떻게 pud가 valid한지 알 수 있나요?
질문 2. arch/arm64/include/asm/pgtable.h 파일내에
static inline pte_t pud_pte(pud_t pud)
{
return __pte(pud_val(pud));
}
#define __pud_to_phys(pud) __pte_to_phys(pud_pte(pud))
#define __pte_to_phys(pte) (pte_val(pte) & PTE_ADDR_MASK)
pgd,pud,pmd 엔트리를 물리주소로 변환할때 pgd_t, pud_t, pmd_t 속성을 pte_t 캐스트 하고,
@p*d 엔트리 포인터에서 읽은 p*d 엔트리 값에서 물리 주소 값을 읽어오는데,
fixmap_p*d 함수의 리턴 값으로 pgtable.h의 pmd_offset_kimg 함수에서 매크로를 거쳐서 계산될때,
-
p*d가 pte 로 캐스팅되어 물리 주소값을 가져오는 것
-
pte_val(pte) & PTE_ADDR_MASK 의 결과가 물리주소인지 궁금합니다.
.
안녕하세요? 문c블로그(http://jake.dothome.co.kr)의 문영일입니다.
먼저 질문하신 내용들에 대해 답변을 드립니다.
질문 1. arch/arm64/include/asm/pgtable.h 파일내에
#define pud_valid(pud) pte_valid(pud_pte(pud)) 정의가 되어 있습니다.
구조적으로 보면 pud -> pmd -> pte 순서대로 valid 체크가 되어야 할 것 같은데
바로 pud->pte로 변환하여 valid 체크가 되고 있습니다.
pte_valid 체크를 통해서 어떻게 pud가 valid한지 알 수 있나요?
-> 4가지 페이지 테이블의 엔트리 타입들은 pgd_t, pud_t, pmd_t, pte_t와 같습니다.
그런데 arm 및 arm64에서 이들의 valid 체크는 bit0 하나만을 보고 valid 유무를 체크하는
방법으로 동일합니다. 따라서 pte_valid() 매크로 하나만 위와 같이 bit0를 체크하는 루틴을
준비하고, 나머지 pgd_valid(), pud_valid(), pmd_valid() 매크로들은 각각의 사용 엔트리
타입만 pte_t로 바꾼 후 pte_valid() 매크로를 공통으로 사용하고 있습니다.
그리고 p*d_valid() 매크로 함수는 해당 p*d 엔트리에 매핑 엔트리가 존재하는지
여부만을 체크합니다. 따라서 pte_valid()를 호출할 때 상위부터 체크하며
내려오지 않습니다.
질문 2. arch/arm64/include/asm/pgtable.h 파일내에
static inline pte_t pud_pte(pud_t pud)
{
return __pte(pud_val(pud));
}
#define __pud_to_phys(pud) __pte_to_phys(pud_pte(pud))
#define __pte_to_phys(pte) (pte_val(pte) & PTE_ADDR_MASK)
pgd,pud,pmd 엔트리를 물리주소로 변환할때 pgd_t, pud_t, pmd_t 속성을 pte_t 캐스트 하고,
@p*d 엔트리 포인터에서 읽은 p*d 엔트리 값에서 물리 주소 값을 읽어오는데,
fixmap_p*d 함수의 리턴 값으로 pgtable.h의 pmd_offset_kimg 함수에서 매크로를 거쳐서
계산될 때, p*d가 pte 로 캐스팅되어 물리 주소값을 가져오는 것
pte_val(pte) & PTE_ADDR_MASK 의 결과가 물리주소인지 궁금합니다.
-> 네. 물리 주소입니다. arm64의 경우 모든 테이블의 엔트리에서 사용하는 물리 주소 위치가
동일하여 __pgd_to_phys(), __pud_to_phys(), __pmd_to_phys(), __pte_to_phys() 모두 같은 위치의
물리 주소를 알아옵니다. (arm64의 최근 아키텍처 v8.2 이상에서 지원하는 PABITS_52를 제외)
감사합니다.