운영체제 기본/Linux/메모리 매핑/페이지 폴트 처리: 두 판 사이의 차이
잔글 관리자님이 운영체제 기본/Linux의 메모리 매핑/페이지 폴트 처리 문서를 운영체제 기본/Linux/메모리 매핑/페이지 폴트 처리 문서로 이동했습니다: Linux 각론 제목을 계층형 경로로 통일 |
잔글 Linux 각론 경로 변경에 따른 본문·목차·틀 링크 갱신 |
||
| 1번째 줄: | 1번째 줄: | ||
{{이전 다음 문서 | {{이전 다음 문서 | ||
|이전=← 이전 문서<br>[[운영체제 기본/ | |이전=← 이전 문서<br>[[운영체제 기본/Linux/메모리 매핑/mmap과 주소 공간|mmap과 주소 공간]] | ||
|목차=[[운영체제 기본/ | |목차=[[운영체제 기본/Linux/메모리 매핑|메모리 매핑 목차]] | ||
|다음=다음 문서 →<br>[[운영체제 기본/ | |다음=다음 문서 →<br>[[운영체제 기본/Linux/메모리 매핑/익명 메모리 매핑|익명 메모리 매핑]] | ||
}} | }} | ||
| 80번째 줄: | 80번째 줄: | ||
<code>do_pte_missing()</code>은 private anonymous VMA와 파일 등의 처리기를 사용하는 VMA를 나눈다. <code>do_fault()</code>는 읽기, private 쓰기, shared 쓰기를 각각 <code>do_read_fault()</code>, <code>do_cow_fault()</code>, <code>do_shared_fault()</code>로 나눈다. 각 분기는 VMA가 허용한 접근에 필요한 페이지와 권한을 준비한다.<ref name="memory">[https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/mm/memory.c?h=v6.12 Linux v6.12, mm/memory.c], do_pte_missing, do_anonymous_page, do_fault, do_wp_page, wp_page_copy.</ref> | <code>do_pte_missing()</code>은 private anonymous VMA와 파일 등의 처리기를 사용하는 VMA를 나눈다. <code>do_fault()</code>는 읽기, private 쓰기, shared 쓰기를 각각 <code>do_read_fault()</code>, <code>do_cow_fault()</code>, <code>do_shared_fault()</code>로 나눈다. 각 분기는 VMA가 허용한 접근에 필요한 페이지와 권한을 준비한다.<ref name="memory">[https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/mm/memory.c?h=v6.12 Linux v6.12, mm/memory.c], do_pte_missing, do_anonymous_page, do_fault, do_wp_page, wp_page_copy.</ref> | ||
앞으로 [[운영체제 기본/ | 앞으로 [[운영체제 기본/Linux/메모리 매핑/익명 메모리 매핑|익명 매핑]]에서는 0으로 보이는 메모리를 마련하고, [[운영체제 기본/Linux/메모리 매핑/파일 매핑과 COW|파일 매핑]]에서는 파일 페이지를 가져오거나 사본을 만든다. [[운영체제 기본/Linux/메모리 매핑/MMIO 장치 매핑|MMIO 매핑]]은 드라이버가 매핑 시점에 장치 PTE를 설치할 수 있으므로, 모든 매핑이 이 지연 할당 순서를 거치는 것은 아니다. | ||
필요한 입출력이나 메모리를 기다리는 동안 현재 태스크가 잠들 수 있다. 그동안 CPU는 다른 태스크를 실행할 수 있다. 커널이 필요한 페이지를 준비하고 페이지 테이블 잠금 아래 PTE를 설치하면, 예외에서 돌아온 CPU가 중단한 명령을 다시 실행한다. 파일 데이터가 이미 준비되어 있거나 주변 페이지를 함께 연결하는 최적화가 적용되면 더 짧은 경로로 끝날 수도 있다. | 필요한 입출력이나 메모리를 기다리는 동안 현재 태스크가 잠들 수 있다. 그동안 CPU는 다른 태스크를 실행할 수 있다. 커널이 필요한 페이지를 준비하고 페이지 테이블 잠금 아래 PTE를 설치하면, 예외에서 돌아온 CPU가 중단한 명령을 다시 실행한다. 파일 데이터가 이미 준비되어 있거나 주변 페이지를 함께 연결하는 최적화가 적용되면 더 짧은 경로로 끝날 수도 있다. | ||
| 87번째 줄: | 87번째 줄: | ||
공통 코드가 사용하는 PTE라는 이름이 하드웨어 비트 형식까지 같다는 뜻은 아니다. x86-64는 present 비트와 읽기/쓰기, 사용자 접근 등의 속성을 사용하고, RISC-V는 V(valid), R, W, X, U 등의 비트로 유효성과 접근 조건을 표현한다. 페이지 테이블 단계와 실제 엔트리 조작은 아키텍처별 구현에 맡긴다. 이 장에서 중요한 공통 결과는 '''해당 프로세스의 가상 주소가 준비된 페이지를 허용된 권한으로 가리키게 되는 것'''이다.<ref name="x86-pte">[https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/include/asm/pgtable_types.h?h=v6.12 Linux v6.12 arch/x86/include/asm/pgtable_types.h], 페이지 테이블 속성 비트.</ref><ref name="rv-pte">[https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/riscv/include/asm/pgtable-bits.h?h=v6.12 Linux v6.12 arch/riscv/include/asm/pgtable-bits.h], _PAGE_PRESENT, _PAGE_READ, _PAGE_WRITE, _PAGE_EXEC, _PAGE_USER.</ref> | 공통 코드가 사용하는 PTE라는 이름이 하드웨어 비트 형식까지 같다는 뜻은 아니다. x86-64는 present 비트와 읽기/쓰기, 사용자 접근 등의 속성을 사용하고, RISC-V는 V(valid), R, W, X, U 등의 비트로 유효성과 접근 조건을 표현한다. 페이지 테이블 단계와 실제 엔트리 조작은 아키텍처별 구현에 맡긴다. 이 장에서 중요한 공통 결과는 '''해당 프로세스의 가상 주소가 준비된 페이지를 허용된 권한으로 가리키게 되는 것'''이다.<ref name="x86-pte">[https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/include/asm/pgtable_types.h?h=v6.12 Linux v6.12 arch/x86/include/asm/pgtable_types.h], 페이지 테이블 속성 비트.</ref><ref name="rv-pte">[https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/riscv/include/asm/pgtable-bits.h?h=v6.12 Linux v6.12 arch/riscv/include/asm/pgtable-bits.h], _PAGE_PRESENT, _PAGE_READ, _PAGE_WRITE, _PAGE_EXEC, _PAGE_USER.</ref> | ||
RISC-V의 정상적인 페이지 폴트 복구는 시스템 콜의 <code>ecall</code>처럼 <code>epc</code>를 다음 명령으로 증가시키지 않는다. 저장된 fault 명령 위치로 복귀해 같은 load를 다시 수행한다. x86-64도 성공한 페이지 폴트 처리 뒤에는 중단된 load를 다시 실행한다. 레지스터 복원과 사용자 모드 복귀 방식은 [[운영체제 기본/ | RISC-V의 정상적인 페이지 폴트 복구는 시스템 콜의 <code>ecall</code>처럼 <code>epc</code>를 다음 명령으로 증가시키지 않는다. 저장된 fault 명령 위치로 복귀해 같은 load를 다시 수행한다. x86-64도 성공한 페이지 폴트 처리 뒤에는 중단된 load를 다시 실행한다. 레지스터 복원과 사용자 모드 복귀 방식은 [[운영체제 기본/Linux/ELF 로딩/초기 스택과 사용자 모드 진입#사용자 모드 진입: x86-64와 RISC-V|두 아키텍처의 사용자 모드 진입]]에서 다룬다. 커널 안에서 잠금이나 입출력 때문에 폴트 처리를 재시도하는 일과, 사용자 모드로 돌아가 CPU 명령을 다시 실행하는 일은 구별한다.<ref name="rv-traps" /><ref name="rv-entry" /><ref name="rv-fault" /><ref name="x86fault" /> | ||
| 94번째 줄: | 94번째 줄: | ||
{{이전 다음 문서 | {{이전 다음 문서 | ||
|이전=← 이전 문서<br>[[운영체제 기본/ | |이전=← 이전 문서<br>[[운영체제 기본/Linux/메모리 매핑/mmap과 주소 공간|mmap과 주소 공간]] | ||
|목차=[[운영체제 기본/ | |목차=[[운영체제 기본/Linux/메모리 매핑|메모리 매핑 목차]] | ||
|다음=다음 문서 →<br>[[운영체제 기본/ | |다음=다음 문서 →<br>[[운영체제 기본/Linux/메모리 매핑/익명 메모리 매핑|익명 메모리 매핑]] | ||
}} | }} | ||
{{운영체제 기본 둘러보기}} | {{운영체제 기본 둘러보기}} | ||