사용자 모드와 커널 모드의 차이점은 무엇이며, 둘 중 하나를 활성화하는 이유와 방법 및 사용 사례는 무엇입니까?
사용자 모드와 커널 모드의 차이점은 무엇이며, 둘 중 하나를 활성화하는 이유와 방법 및 사용 사례는 무엇입니까?
답변:
커널 모드
커널 모드에서 실행 코드는 기본 하드웨어에 대한 완전하고 제한없는 액세스 권한을 갖습니다. 모든 CPU 명령을 실행하고 모든 메모리 주소를 참조 할 수 있습니다. 커널 모드는 일반적으로 운영 체제의 가장 낮은 수준의 가장 신뢰할 수있는 기능을 위해 예약되어 있습니다. 커널 모드의 충돌은 치명적입니다. 그들은 전체 PC를 중지합니다.
사용자 모드
사용자 모드에서 실행 코드는 하드웨어 또는 참조 메모리에 직접 액세스 할 수 없습니다. 사용자 모드에서 실행되는 코드는 하드웨어 또는 메모리에 액세스하기 위해 시스템 API에 위임해야합니다. 이러한 종류의 격리를 통해 제공되는 보호 기능으로 인해 사용자 모드의 충돌은 항상 복구 할 수 있습니다. 컴퓨터에서 실행되는 대부분의 코드는 사용자 모드에서 실행됩니다.
더 읽어보기
컴퓨터가 작동 할 수있는 두 가지 모드입니다. 이전에는 컴퓨터가 큰 방 같았을 때 무언가 충돌하면 전체 컴퓨터가 중단됩니다. 그래서 컴퓨터 설계자들은 그것을 바꾸기로 결정합니다. 최신 마이크로 프로세서는 하드웨어에서 적어도 두 가지 상태를 구현합니다.
사용자 모드 :
커널 모드 :
전환이 발생하는 방식.
사용자 모드에서 커널 모드로의 전환은 CPU에 의해 자동으로 수행되지 않습니다. CPU가 인터럽트 (타이머, 키보드, I / O)에 의해 중단됩니다. 인터럽트가 발생하면 CPU는 현재 실행중인 프로그램의 실행을 중지하고 커널 모드로 전환하고 인터럽트 처리기를 실행합니다. 이 핸들러는 CPU의 상태를 저장하고, 작업을 수행하고, 상태를 복원하고 사용자 모드로 돌아갑니다.
http://en.wikibooks.org/wiki/Windows_Programming/User_Mode_vs_Kernel_Mode
http://tldp.org/HOWTO/KernelAnalysis-HOWTO-3.html
Windows를 실행하는 컴퓨터의 프로세서에는 사용자 모드와 커널 모드의 두 가지 모드가 있습니다. 프로세서는 프로세서에서 실행중인 코드 유형에 따라 두 가지 모드 사이를 전환합니다. 응용 프로그램은 사용자 모드에서 실행되고 핵심 운영 체제 구성 요소는 커널 모드에서 실행됩니다. 많은 드라이버가 커널 모드에서 실행되지만 일부 드라이버는 사용자 모드에서 실행될 수 있습니다.
사용자 모드 응용 프로그램을 시작하면 Windows에서 응용 프로그램에 대한 프로세스를 만듭니다. 이 프로세스는 애플리케이션에 개인용 가상 주소 공간과 개인용 핸들 테이블을 제공합니다. 응용 프로그램의 가상 주소 공간은 개인용이므로 한 응용 프로그램은 다른 응용 프로그램에 속한 데이터를 변경할 수 없습니다. 각 응용 프로그램은 격리되어 실행되며 응용 프로그램이 충돌하는 경우 충돌은 해당 응용 프로그램으로 제한됩니다. 다른 응용 프로그램과 운영 체제는 충돌의 영향을받지 않습니다.
개인용 일뿐만 아니라 사용자 모드 응용 프로그램의 가상 주소 공간이 제한됩니다. 사용자 모드에서 실행중인 프로세서는 운영 체제 용으로 예약 된 가상 주소에 액세스 할 수 없습니다. 사용자 모드 응용 프로그램의 가상 주소 공간을 제한하면 응용 프로그램이 중요한 운영 체제 데이터를 변경하거나 손상시킬 수 있습니다.
커널 모드에서 실행되는 모든 코드는 단일 가상 주소 공간을 공유합니다. 이는 커널 모드 드라이버가 다른 드라이버 및 운영 체제 자체와 분리되지 않음을 의미합니다. 커널 모드 드라이버가 실수로 잘못된 가상 주소에 쓰는 경우 운영 체제 또는 다른 드라이버에 속한 데이터가 손상 될 수 있습니다. 커널 모드 드라이버가 충돌하면 전체 운영 체제가 충돌합니다.
Windows 사용자 인 경우이 링크를 통해 더 많은 정보를 얻을 수 있습니다.
CPU 링은 가장 명확한 구분입니다.
x86 보호 모드에서 CPU는 항상 4 개의 링 중 하나에 있습니다. Linux 커널은 0과 3 만 사용합니다.
이것은 커널 대 사용자 영역의 가장 어렵고 빠른 정의입니다.
Linux가 링 1과 2를 사용하지 않는 이유 : CPU 권한 링 : 링 1과 2가 사용되지 않는 이유는 무엇입니까?
현재 링은 어떻게 결정됩니까?
현재 벨소리는 다음 조합으로 선택됩니다.
전역 설명자 테이블 : GDT 항목의 메모리 내 테이블이며 각 항목에는 Privl
링을 인코딩 하는 필드 가 있습니다.
LGDT 명령어는 주소를 현재 설명자 테이블로 설정합니다.
세그먼트는 GDT에서 항목의 인덱스를 가리키는 CS, DS 등을 등록합니다.
예를 들어, CS = 0
GDT의 첫 번째 항목이 현재 실행중인 코드에 대해 활성화되어 있음을 의미합니다.
각 반지는 무엇을 할 수 있습니까?
CPU 칩은 다음과 같이 물리적으로 구축됩니다.
링 0은 무엇이든 할 수 있습니다
링 3은 여러 명령을 실행할 수 없으며 여러 레지스터에 쓸 수 없습니다.
자신의 반지를 바꿀 수 없습니다! 그렇지 않으면 자체적으로 ring 0으로 설정 될 수 있고 ring은 쓸모가 없습니다.
즉, 현재 링을 결정하는 현재 세그먼트 설명자를 수정할 수 없습니다 .
페이지 테이블을 수정할 수 없음 : x86 페이징은 어떻게 작동합니까?
즉, CR3 레지스터를 수정할 수 없으며 페이징 자체는 페이지 테이블의 수정을 방지합니다.
이것은 한 프로세스가 보안 / 프로그래밍의 용이성을 위해 다른 프로세스의 메모리를 보지 못하게합니다.
인터럽트 핸들러를 등록 할 수 없습니다. 이들은 메모리 위치에 기록하여 구성되며 페이징으로도 방지됩니다.
처리기는 링 0에서 실행되며 보안 모델을 손상시킵니다.
즉, LGDT 및 LIDT 명령어를 사용할 수 없습니다.
같은 IO 지침을 할 수 없어 in
하고 out
, 따라서 임의의 하드웨어 액세스가 있습니다.
그렇지 않으면 예를 들어 어떤 프로그램이 디스크에서 직접 읽을 수 있다면 파일 권한은 쓸모가 없습니다.
더 정확하게는 Michael Petch 덕분에 OS가 링 3에서 IO 명령을 허용 할 수 있습니다. 이것은 실제로 작업 상태 세그먼트에 의해 제어됩니다 .
불가능한 것은 링 3이 처음에 그것을 가지고 있지 않았다면 그렇게 할 권한을 스스로에게주는 것입니다.
Linux는 항상이를 허용하지 않습니다. 참고 항목 : Linux가 TSS를 통해 하드웨어 컨텍스트 스위치를 사용하지 않는 이유는 무엇입니까?
프로그램과 운영 체제가 링간에 어떻게 전환됩니까?
CPU가 켜지면 링 0에서 초기 프로그램을 실행하기 시작합니다 (좋지만 근사치입니다). 이 초기 프로그램을 커널이라고 생각할 수 있습니다 (하지만 일반적으로 링 0에있는 커널을 호출하는 부트 로더입니다 ).
유저 랜드 프로세스가 커널이 파일에 쓰기처럼 그것을 위해 무언가를하고자 할 때, 그것은 같은 인터럽트를 생성하는 명령어 사용 int 0x80
또는syscall
커널 신호를합니다. x86-64 Linux syscall hello world 예 :
.data
hello_world:
.ascii "hello world\n"
hello_world_len = . - hello_world
.text
.global _start
_start:
/* write */
mov $1, %rax
mov $1, %rdi
mov $hello_world, %rsi
mov $hello_world_len, %rdx
syscall
/* exit */
mov $60, %rax
mov $0, %rdi
syscall
컴파일 및 실행 :
as -o hello_world.o hello_world.S
ld -o hello_world.out hello_world.o
./hello_world.out
이 경우 CPU는 커널이 부팅 할 때 등록한 인터럽트 콜백 핸들러를 호출합니다. 다음은 핸들러를 등록하고 사용 하는 구체적인 베어 메탈 예제입니다 .
이 핸들러는 링 0에서 실행되며, 커널이이 작업을 허용할지 여부를 결정하고, 작업을 수행하고, 링 3에서 userland 프로그램을 다시 시작합니다. x86_64
때 exec
시스템 호출을 사용하는 (또는 경우 커널 시작한다/init
), 커널은 레지스터와 메모리를 준비하고 , 새로운 유저 기반 프로세스를 다음의 엔트리 포인트로 점프 링 (3)에 CPU 스위치
프로그램이 금지 된 레지스터 나 메모리 주소 (페이징으로 인해)에 쓰기와 같은 장난스러운 작업을 시도하면 CPU는 링 0에서 일부 커널 콜백 핸들러도 호출합니다.
그러나 사용자 영역이 장난 스러웠 기 때문에 커널이 이번에는 프로세스를 종료하거나 신호와 함께 경고를 줄 수 있습니다.
커널이 부팅되면 일정한 주파수로 하드웨어 클럭을 설정하여 주기적으로 인터럽트를 생성합니다.
이 하드웨어 시계는 링 0을 실행하는 인터럽트를 생성하고 어떤 사용자 영역 프로세스가 깨어날 지 예약 할 수 있도록합니다.
이렇게하면 프로세스가 시스템 호출을하지 않는 경우에도 스케줄링이 발생할 수 있습니다.
여러 개의 링이있는 이유는 무엇입니까?
커널과 사용자 영역을 분리하면 두 가지 주요 이점이 있습니다.
그것을 가지고 노는 방법?
링을 직접 조작하는 좋은 방법 인 베어 메탈 설정을 만들었습니다 : https://github.com/cirosantilli/x86-bare-metal-examples
안타깝게도 유저 랜드 예제를 만들 수있는 인내심이 없었지만 페이징 설정까지했기 때문에 유저 랜드가 가능해야합니다. 풀 리퀘스트를보고 싶습니다.
또는 Linux 커널 모듈은 링 0에서 실행되므로 제어 레지스터 읽기와 같이 권한있는 작업을 시도하는 데 사용할 수 있습니다 . 프로그램에서 제어 레지스터 cr0, cr2, cr3에 액세스하는 방법은 무엇입니까? 분할 오류 얻기
다음은 호스트를 죽이지 않고 사용해 볼 수 있는 편리한 QEMU + Buildroot 설정 입니다.
커널 모듈의 단점은 다른 kthread가 실행 중이고 실험을 방해 할 수 있다는 것입니다. 그러나 이론적으로는 커널 모듈로 모든 인터럽트 핸들러를 인수하고 시스템을 소유 할 수 있습니다. 실제로 흥미로운 프로젝트가 될 것입니다.
네거티브 링
네거티브 링은 인텔 매뉴얼에서 실제로 참조되지 않지만 실제로 링 0 자체보다 더 많은 기능을 가진 CPU 모드가 있으므로 "네거티브 링"이름에 적합합니다.
한 가지 예는 가상화에 사용되는 하이퍼 바이저 모드입니다.
자세한 내용은 다음을 참조하십시오.
팔
ARM에서는 링을 예외 수준이라고 부르지 만 주요 아이디어는 동일하게 유지됩니다.
ARMv8에는 일반적으로 다음과 같이 사용되는 4 가지 예외 수준이 있습니다.
EL0 : userland
EL1 : 커널 (ARM 용어로 "감독자").
이전에 통합 어셈블리svc
로 알려진 명령 (SuperVisor Call) 과 함께 입력됩니다.이 명령 은 Linux 시스템 호출을 만드는 데 사용됩니다. Hello world ARMv8 예제 :swi
안녕하세요 .S
.text
.global _start
_start:
/* write */
mov x0, 1
ldr x1, =msg
ldr x2, =len
mov x8, 64
svc 0
/* exit */
mov x0, 0
mov x8, 93
svc 0
msg:
.ascii "hello syscall v8\n"
len = . - msg
Ubuntu 16.04에서 QEMU로 테스트하십시오.
sudo apt-get install qemu-user gcc-arm-linux-gnueabihf
arm-linux-gnueabihf-as -o hello.o hello.S
arm-linux-gnueabihf-ld -o hello hello.o
qemu-arm hello
다음은 SVC 핸들러 를 등록하고 SVC 호출을 수행하는 구체적인 베어 메탈 예제입니다 .
hvc
지침 (HyperVisor Call) 과 함께 입력되었습니다 .
하이퍼 바이저는 OS에 대한 것이고 OS는 사용자 영역에 대한 것입니다.
예를 들어 Xen을 사용하면 동일한 시스템에서 Linux 또는 Windows와 같은 여러 OS를 동시에 실행할 수 있으며 Linux가 사용자 영역 프로그램에서 수행하는 것처럼 보안 및 디버그 용이성을 위해 OS를 서로 격리 할 수 있습니다.
하이퍼 바이저는 오늘날 클라우드 인프라의 핵심 부분입니다. 여러 서버를 단일 하드웨어에서 실행할 수 있으므로 하드웨어 사용량을 항상 100 %에 가깝게 유지하고 많은 비용을 절약 할 수 있습니다.
예를 들어 AWS는 2017 년까지 KVM으로 이동하면서 Xen을 사용 했습니다 .
EL3 : 또 다른 수준. TODO 예.
smc
지침 과 함께 입력 됨 (보안 모드 호출)
ARMv8 아키텍처 참조 모델 DDI 0487C.a는 - 장 D1 일 - AArch64 시스템 레벨 프로그래머 모델 - 그림 D1-1 아름답게이 보여
ARM의 상황은 ARMv8.1 VHE (Virtualization Host Extensions) 의 출현으로 약간 변경되었습니다 . 이 확장을 사용하면 커널이 EL2에서 효율적으로 실행될 수 있습니다.
VHE는 KVM과 같은 Linux 내 커널 가상화 솔루션이 Xen을 능가했기 때문에 생성되었습니다 (예 : 위에서 언급 한 AWS의 KVM으로의 이동 참조). 대부분의 클라이언트에는 Linux VM 만 필요하고 상상할 수 있듯이 모두 단일 프로젝트에서 KVM은 Xen보다 간단하고 잠재적으로 더 효율적입니다. 따라서 이제 호스트 Linux 커널이 이러한 경우 하이퍼 바이저 역할을합니다.
뒤늦게 알 수있는 이점으로 인해 ARM이 x86보다 권한 수준에 대해 더 나은 명명 규칙을 가지고 있다는 점에 유의하십시오. 0은 더 낮고 3은 가장 높은 수준이 필요하지 않습니다. 높은 수준은 낮은 수준보다 더 자주 생성되는 경향이 있습니다.
현재 EL은 MRS
명령 으로 쿼리 할 수 있습니다 . 현재 실행 모드 / 예외 수준 등은 무엇입니까?
ARM은 칩 영역을 절약하는 기능이 필요하지 않은 구현을 허용하기 위해 모든 예외 수준을 요구하지 않습니다. ARMv8 "예외 수준"은 다음과 같이 말합니다.
구현에는 모든 예외 수준이 포함되지 않을 수 있습니다. 모든 구현에는 EL0 및 EL1이 포함되어야합니다. EL2 및 EL3은 선택 사항입니다.
예를 들어 QEMU의 기본값은 EL1이지만 EL2 및 EL3은 명령 줄 옵션으로 활성화 할 수 있습니다. qemu-system-aarch64 a53 전원 켜기를 에뮬레이션 할 때 el1 입력
Ubuntu 18.10에서 테스트 된 코드 조각.
in
그리고 out
모든 또는 특정 포트에 대한 읽기 / 쓰기 액세스 권한을 부여하는 현재 작업에 IO 허용 테이블을 가리킬 수 있습니다 3. TSS 링 할 수 있습니다.
나는 어둠 속에서 찔러서 당신이 Windows에 대해 이야기하고 있다고 생각할 것입니다. 간단히 말해서 커널 모드는 하드웨어에 대한 전체 액세스 권한을 갖지만 사용자 모드는 그렇지 않습니다. 예를 들어 대부분의 장치 드라이버는 아니지만 대부분의 장치 드라이버는 하드웨어의 세부 사항을 제어해야하기 때문에 커널 모드로 작성됩니다.
이 wikibook을 참조하십시오 .
다른 답변은 이미 사용자 모드와 커널 모드의 차이점을 설명했습니다. 정말로 자세히 알고 싶다면 Mark Russinovich와 David Solomon이 저술 한 훌륭한 책인 Windows Internals 사본을 얻어야합니다.이 책은 다양한 Windows 운영 체제의 아키텍처와 내부 세부 사항을 설명합니다.
뭐
기본적으로 커널 모드와 사용자 모드의 차이는 OS에 따라 달라지지 않으며 하드웨어 설계를 통해 커널 모드에서만 실행되도록 일부 명령을 제한함으로써 만 가능합니다. 메모리 보호와 같은 다른 모든 목적은 해당 제한에 의해서만 수행 될 수 있습니다.
어떻게
이는 프로세서가 커널 모드 또는 사용자 모드에 있음을 의미합니다. 일부 메커니즘을 사용하면 아키텍처가 커널 모드로 전환 될 때마다 OS 코드를 가져와 실행하도록 보장 할 수 있습니다.
왜
이 하드웨어 인프라가 있으면 일반적인 OS에서 다음과 같은 작업을 수행 할 수 있습니다.