강의 들으면서 핵심 내용만 간단하게 정리 진행 중....
Memory 관련 Linux Register
CR0: Real mode vs Protection mode 구분 가능 (?)
CR2: 페이지폴트를 일으킨 가상 주소 저장
CR3:현재 프로세스의 페이지테이블의 주소 (Vritual Adress - Phsical Address 매핑 테이블)
참고할만 한 자료: https://blackcon.tistory.com/117
Page Fault
x86 의 경우 Page Fault error code 는 다음과 같다.
arch/x86/include/asm/traps.h
/*
* Page fault error code bits:
*
* bit 0 == 0: no page found 1: protection fault
* bit 1 == 0: read access 1: write access
* bit 2 == 0: kernel-mode access 1: user-mode access
* bit 3 == 1: use of reserved bit detected
* bit 4 == 1: fault was an instruction fetch
* bit 5 == 1: protection keys block access
*/
arm 의 경우는 다르며 arch/arm64/include/asm/traps.h 에는 없음. 정리된 주석이 없어 더 살펴봐야 함
Page Fault 발생 시점의 Stack Trace
exec 하면서 Page fault 가 날 수도 있고, 여러 경우가 있음
Page Fault Handler 주요 흐름
Page Fault Handling 이라 함은 페이지 변환 테이블을 수정하는 것이다. 다음과 같은 일을 한다.
(1) 물리 메모리 (Page Frame) 할당
(2) Virtual Address 와 Physical Adrdress 연결
(3) Page Table 한 요소 (entry) flag 세팅
*PTE: Page Table Entry
Interrupt 나 Exception 이 호출될 때 Entry 에서 시작한다. Page Fault 라는 Exception이 시작하는 부분은 x86 의 경우 arch/x86/entry/entry_64.S 에서 시작한다.
arch/x86/entry/entry_64.S 의 한 부분이 다음과 같다.
idtentry page_fault do_page_fault has_error_code=1 read_cr2=1
page_fault 가 호출되면 c로 된 do_page_fault 함수를 호출하고 has_error_code와 read_cr2 (cr2는 fault 가 났을 때 가상 메모리 주소)를 인자로 받아간다.
mm/fault.c 에서 do_page_fault 함수를 확인할 수 있다.
dotraplinkage void
do_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned long address)
{
enum ctx_state prev_state;
prev_state = exception_enter();
trace_page_fault_entries(regs, error_code, address);
__do_page_fault(regs, error_code, address);
exception_exit(prev_state);
}
NOKPROBE_SYMBOL(do_page_fault);
arm 의 경우에는 entry 가 아닌 다른 진입점이 있을 것으로 예상함. do_page_fault 는 있으나 .S 파일이 없음
__do_page_fault 는 arch/x86/mm/fault.c에서 다음과 같다.
static noinline void
__do_page_fault(struct pt_regs *regs, unsigned long error_code,
unsigned long address)
{
...
unlikely 란 if 의 결과 값을 예상하고 미리 분기를 하는 함수. 강의 내용이 커널 3점대 버전으로 진행되는 것 같다. 5점 대 버전에서는 x86 에 상단 내용이 없음.
주된 내용만 살펴보면 page fault 핸들링은 다음과 같이 동작한다.
do_user_addr_fault() : arch/x86/mm/fault.c
-> handle_mm_fault() : mm/memory.c
-> __handle_mm_fault() : mm/memory.c
-> handle_pte_fault() : mm/memory.c
-> ptep_set_access_flags() : arch/x86/mm/pgtable.c
-> set_pte() “페이지 테이블 한요소(pte) 수정”
task_struct 구조체: task (process) 관리 목적의 커널 자료 구조
ㄴ mm_struct : task_struct 하위 구조체. 가상 메모리 관리 목적의 커널 자료 구조.
ㄴ vma : mm_struct 의 하위. 가상 메모리 공간을 관리하는 자료 구조. stack 공간, heap 공간, code 공간.
'Linux' 카테고리의 다른 글
4-Level Page Table (0) | 2022.12.18 |
---|---|
MMAP (0) | 2022.12.18 |
리눅스 프로그램과 커널 프로그램 (0) | 2022.12.09 |
리눅스 운영체제의 구성 (0) | 2022.12.09 |
커널 분석 및 디버깅 툴; uftrace (0) | 2022.12.09 |