운영체제 기본/보호: 두 판 사이의 차이

통합한 장치 제어와 입출력 문서의 대응 절로 IRQ 링크 갱신
메모리 접근에서 #PF·#GP, IDT 진입과 커널의 예외 처리까지 연결
21번째 줄: 21번째 줄:
하드웨어의 권한 모드를 사용하는 운영체제에서는 일반 프로그램을 제한된 권한으로 실행하고, 메모리 매핑이나 장치 제어처럼 시스템 전체에 영향을 주는 동작은 커널이 담당한다. 사용자 모드에서도 산술 연산과 허용된 메모리 접근은 CPU가 직접 실행한다. 모든 명령을 커널이 대신 실행하면 보호를 위해 지나치게 큰 비용을 치르게 된다.
하드웨어의 권한 모드를 사용하는 운영체제에서는 일반 프로그램을 제한된 권한으로 실행하고, 메모리 매핑이나 장치 제어처럼 시스템 전체에 영향을 주는 동작은 커널이 담당한다. 사용자 모드에서도 산술 연산과 허용된 메모리 접근은 CPU가 직접 실행한다. 모든 명령을 커널이 대신 실행하면 보호를 위해 지나치게 큰 비용을 치르게 된다.


주소 공간은 접근 가능한 메모리의 범위를 나눈다. '''MMU(Memory Management Unit, 메모리 관리 장치)'''는 CPU가 사용하는 가상 주소를 물리 주소로 변환하고, 그 주소에 대한 읽기·쓰기·실행이 허용되는지 검사하는 하드웨어다. 운영체제가 주소의 연결 관계와 접근 권한을 설정하면 MMU가 메모리 접근에 그 규칙을 적용한다. 운영체제가 모든 메모리 접근을 소프트웨어로 하나씩 감시하는 방식은 아니다. 프로그램이 다른 주소를 계산했다고 해서 해당 메모리에 접근할 권한까지 생기지는 않는다. 잘못된 접근은 예외를 일으킬 수 있고, 운영체제는 이를 처리하거나 해당 프로그램의 실행을 중단한다. 주소 변환 정보를 저장하는 페이지 테이블과 변환 결과를 캐시하는 TLB는 [[운영체제 기본/가상 메모리#페이지 단위의 간접 참조와 그 비용|가상 메모리]]에서 다룬다.
주소 공간은 접근 가능한 메모리의 범위를 나눈다. '''MMU(Memory Management Unit, 메모리 관리 장치)'''는 CPU가 사용하는 가상 주소를 물리 주소로 변환하고, 그 주소에 대한 읽기·쓰기·실행이 허용되는지 검사하는 하드웨어다. 운영체제가 주소의 연결 관계와 접근 권한을 설정하면 MMU가 메모리 접근에 그 규칙을 적용한다. 운영체제가 모든 메모리 접근을 소프트웨어로 하나씩 감시하는 방식은 아니다. 프로그램이 다른 주소를 계산했다고 해서 해당 메모리에 접근할 권한까지 생기지는 않는다. 허용되지 않은 접근을 발견하면 CPU는 아래에서 설명하는 예외 처리 경로로 제어를 넘긴다. 주소 변환 정보를 저장하는 페이지 테이블과 변환 결과를 캐시하는 TLB는 [[운영체제 기본/가상 메모리#페이지 단위의 간접 참조와 그 비용|가상 메모리]]에서 다룬다.


자원별 권한은 별도로 판단한다. 사용자 모드라는 이유만으로 모든 파일 접근이 금지되는 것은 아니며, 어떤 파일을 읽을 수 있다고 해서 수정도 허용되는 것은 아니다. CPU 권한 모드는 어떤 종류의 동작을 직접 실행할 수 있는지, 주소 공간은 어떤 메모리에 접근할 수 있는지, 자원 권한은 어떤 대상에 어떤 연산을 허용할지를 나눈다. <ref name="source-2">[https://mit-pdos.github.io/xv6-riscv-book/first.html xv6: Operating system organization].</ref>
자원별 권한은 별도로 판단한다. 사용자 모드라는 이유만으로 모든 파일 접근이 금지되는 것은 아니며, 어떤 파일을 읽을 수 있다고 해서 수정도 허용되는 것은 아니다. CPU 권한 모드는 어떤 종류의 동작을 직접 실행할 수 있는지, 주소 공간은 어떤 메모리에 접근할 수 있는지, 자원 권한은 어떤 대상에 어떤 연산을 허용할지를 나눈다. <ref name="source-2">[https://mit-pdos.github.io/xv6-riscv-book/first.html xv6: Operating system organization].</ref>
== 보호 위반과 예외 ==
CPU가 명령어를 실행하다가 별도의 처리가 필요한 조건을 발견하여 정해진 처리 코드로 제어를 넘기는 일을 '''예외(exception)'''라고 한다. 여기서 다루는 메모리 접근 예외는 해당 명령어의 실행에 따라 동기적으로 발생한다. 장치가 현재 명령어와 무관하게 보내는 하드웨어 인터럽트와 구별되는 점이다.<ref name="intel-exception">Intel, [https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-3a-part-1-manual.pdf Intel 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A], 2016년 9월, 6.1~6.3절, 6.12절 및 6.15절의 General-Protection Exception과 Page-Fault Exception.</ref>
x86에서 메모리 접근에 필요한 페이지 매핑이 없거나 페이지 접근 권한을 위반하면 '''페이지 폴트(page fault, #PF)'''가 발생한다. 주소의 형태 자체가 x86-64의 규칙에 맞지 않는 경우처럼 '''일반 보호 예외(general-protection exception, #GP)'''가 발생하는 경우도 있다. 즉, 잘못된 메모리 접근을 모두 #PF라고 부르는 것은 아니다.<ref name="intel-exception" />
CPU는 #PF의 벡터 14 또는 #GP의 벡터 13으로 '''인터럽트 서술자 테이블(Interrupt Descriptor Table, IDT)'''의 게이트를 선택하고, 그 항목이 가리키는 커널 진입 코드로 실행을 넘긴다. 커널의 예외 처리 코드가 원인과 복구 가능성을 판단한다. 허용되지 않은 사용자 프로그램의 접근이라면 운영체제는 오류를 알리고, 처리되지 않은 오류는 보통 프로세스 종료로 이어진다. CPU가 직접 프로그램을 죽이는 것은 아니다.<ref name="intel-exception" />
반면 #PF가 항상 잘못된 프로그램을 뜻하지는 않는다. 유효한 주소에 필요한 페이지를 아직 준비하지 않았을 뿐이라면 운영체제가 이를 마련하고 실행을 재개할 수 있다.<ref name="linux-page-tables">Linux 커널 문서, [https://cdn.kernel.org/doc/html/latest/mm/page_tables.html Page Tables], Page Faults.</ref> 이처럼 복구할 수 있는 경우는 [[운영체제 기본/가상 메모리#페이지 폴트의 처리|가상 메모리의 페이지 폴트 처리]]에서 다룬다. IDT를 통한 진입과 복귀의 구체적인 과정은 [[운영체제 기본/장치 제어와 입출력#처리 진입점과 IDT|장치 제어와 입출력의 IDT 절]]에서 이어서 설명한다.


== 경계를 넘는 요청도 검증해야 한다 ==
== 경계를 넘는 요청도 검증해야 한다 ==