1. 소개
* 이번 소개는 저희 스터디 그룹에서 하고 있는 Linux KVM 가상화 기능과 관련된 내부 구조를 설명하려고 합니다. 가능한 프로그램 언어 등의 지식을 전제로하지 않는 간단한 설명을 기반으로 작성해 보았습니다.
* Linux KVM은 여러 아키텍처 플랫폼에 대응하고 있으며 여기서는 X86, 및 X86_64 아키텍처를 전제로 소개 하겠습니다.
2. KVM의 동작
2.1 CPU의 특권 모드
*가상화 기능이없는 x86 CPU는 RING 0 ~ RING 3 4종류의 특권한 모드를 가진다.
*Winodws 나 Linux 등의 OS를 실행하는 경우 RING 0 RING 3 2가지 모드만을 사용한다.
*RING 0은 모든 CPU 명령 실행 모드에서 Linux 커널 코드는이 모드에서 동작한다.
*RING 3는 물리적 HW 자원을 조작하는 명령은 실행할 수없는 유저모드이며 프로세스의 코드는이 모드에서 동작한다.
(사용자 프로세스가 물리적 HW 자원에 액세스할 때 시스템 호출은 Linux 커널 코드를 호출한다.)
*가상화 기능 (Intel - VT)을 가진 Intel CPU에서는 VMX root 모드 VMX non - root 모드의 구별이 추가되어 각각의 모드에 대해 RING 0 ~ RING 3이 존재한다.
*가상화 하이퍼 바이저 (Xen, KVM)을 사용하지 않는 경우, Linux는 모든 VMX root 모드로 이동
*Xen의 경우, Xen 하이퍼 바이저는 VMX root / RING 0 동작하며. 각 VM은 VMX non - root / RING 0, RING 3으로 동작
*VMX non - root / RING 0 물리적 HW 자원에 대한 액세스가 발생하면 VM exit가 발생하여 CPU는 강제로 VMX root / RING 0
하이퍼 바이저 처리를 이행한다.
2.2.KVM의 특권 모드의 이용 방법
*KVM은 VMX root / RING 0, RING 3에서 작동하는 일반적인 Linux 시스템에서 kvm 프로세스로 가상 머신을 실행한다.
*하나의 가상 시스템에 대응하여 1 개의 kvm 프로세스를 시작한다.
*kvm 프로세스는 특수 장치 파일 / dev / kvm을 통해 KVM 커널 모듈 기능을 이용함.
*가상 머신에 여러 개의 가상 CPU를 할당하면 각 가상 CPU에 kvm 프로세스 내부에서 독립적인 스레드가 생성된다.
*kvm 프로세스의 메모리 공간에는 qemu 장치 에뮬레이터와 게스트 커널 코드가 로드된다.
*따라서, 게스트 커널은 원칙적으로 다른 가상 머신 (다른 kvm 프로세스)의 메모리 공간에 액세스할 수 없다.
*게스트 커널 코드는 물리적 CPU에서 특권 모드 VMX non - root / RING 0에서 실행된다.
*따라서, 게스트 커널의 동작은 물리적 시스템과 완전히 동일하게 처리되며. 게스트 커널에서 시작되는 일반 프로세스는 일반적인
커널의 처리에 따라 VMX nonroot / RING 3에서 실행된다.
*게스트 커널에서 물리적 HW 자원에 대한 액세스가 발생하면 VM exit가 발생하여 KVM 모듈 처리로 전환된다.
2.3 가상 장치에 액세스하는 방법
*VM exit를받은 KVM 모듈은 액세스되는 물리적 자원에 따라 처리를 전달한다.
*예를 들어, 디스크 장치에 대한 액세스의 경우는 KVM 모듈은 kvm 과정에서 qemu 장치 에뮬레이터 처리를 리턴한다.
*qemu 장치 에뮬레이터는 VMX root / RING 3 움직이고있어 호스트 커널에서 본 일반 사용자 프로세스로 가상 디스크 파일에
액세스한다.
*qemu 장치 에뮬레이터는 게스트 커널의 공유 메모리를 사용하여 가상 디스크 파일에 읽고 쓰는 데이터를 게스트 커널과
통신한다. (가상적인 DMA 처리됨)
*kvm 프로세스의 가상 디스크 파일에 액세스 호스트 커널에서 일반 프로세스 디스크 액세스와 동등 호스트 커널의 디스크
캐시를 사용한다.
2.4 메모리 관리에 대해
*비 가상화 환경에서는 물리적 메모리 위치는 Page Frame Number (PFN)로 표시된다.
*Linux 커널은 각 프로세스의 가상 주소에 해당하는 PFN 프로세스마다 제공되는 페이지 테이블에 기록한다.
*프로세스의 실행 시간은 하드웨어에 탑재된 Memory Management Unit (MMU)이 페이지 테이블을 참조하여 가상 주소를
자동으로 PFN로 변환한다.
*KVM 가상화 환경에서는 물리적 메모리 위치는 Machine Page Frame Number (MPFN)로 표시되며, 각 가상 머신이 인식하는
가상 물리적 메모리 위치는 Guest Page Frame Number (GPFN)로 표시된다.
*KVM 모듈은 각 kvm 프로세스 GPFN에 해당하는 MPFN의 대응표를 내부적으로 유지하고 각 kvm 프로세스 가상 물리적
메모리를 할당한다.
2.5.KVM의 메모리 주소 변환 (1)
*Intel EPT (Extended Page Tables)와 같은 2 단계의 페이지 변환을 지원하는 CPU를 사용하는 경우는 MMU가 아래를 참조하여 게스트 OS에서 프로세스의 가상 주소 -> GPFN -> MPFN 변환을 수행한다 .
*게스트 커널이 관리하는 페이지 테이블 (게스트 OS에서 프로세스의 가상 주소와 GPFN의 대응표)
*KVM 모듈이 관리하는 변환 테이블 (GPFN과 MPFN의 대응표)
2.6. KVM의 메모리 주소 변환 (2)
*2 단계의 페이지 변환 지원하지 않는 CPU의 경우 Shadow Pagetable를 이용한다.
*메모리 페이지 테이블에 대한 액세스의 경우는 게스트 커널 보여 가상 페이지 테이블을 변경하는 동시에 해당하는 실제 메모리
페이지 테이블 (Shadow Pagetable)를 동시에 변경한다.
*게스트 커널에서 사용자 프로세스가 메모리에 액세스하면 MMU는 Shadow Pagetable에 따라 해당 물리적 메모리에 액세스 한다.
소스 분석 해놓고 올리지 못한 자료가 많은데..
저희가 인원이 워낙 없고 각자 회사 일로 바쁘다 보니 제대로 공유하지 못했던 것 같습니다.
멤버들과 상의해서 차츰 올리도록 하겠습니다.
댓글 3
번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
---|---|---|---|---|
공지 | [공지] 하이퍼바이져 스터디 관련 Q&A 게시판 입니다. | woos | 2016.04.09 | 237 |
214 | 안녕하세요 | 컴퓨터 | 2016.11.12 | 205 |
213 | VMCS 정리 일부 입니다. | 최연기 | 2013.06.20 | 2364 |
212 | 안녕하세요. | 김태훈91 | 2013.06.15 | 1387 |
211 | [소스] 스터디용 KVM 소스 코드 Git 공유 합니다. [5] | 박지훈a | 2013.05.26 | 3362 |
210 | Xen 4.3 RC test day | 최연기 | 2013.05.08 | 2252 |
209 | 안녕하세요 [2] | 김동선1 | 2013.05.03 | 1849 |
208 | intel manual | 조정욱 | 2012.04.28 | 2526 |
» | kvm 의 내부구조 요약 정리 [3] | 최용석 | 2012.04.17 | 19550 |
206 | Xen 스터디 OT후 첫 알림글 입니다 [6] | 이승재 | 2012.04.08 | 3565 |
205 | 스터디하시고 계신가요? [2] | 세훈킴 | 2011.12.27 | 5007 |
204 | 스터디 진행이 궁금합니다. [5] | 김강수 | 2011.12.06 | 4951 |
203 | 스터디참여문의 [2] | 서영덕 | 2011.11.27 | 5922 |
202 | 잘 다녀왔습니다. ㅋ | 최용석 | 2011.11.11 | 4342 |
201 | ARM 서버의 가능성? [11] | 박은병 | 2011.10.30 | 7553 |
200 | 스터디를 위한 소스를 google code에 업로드 하였습니다. [3] | 김연희 | 2011.09.24 | 6027 |
199 | 스터디 소스 관리가 너무 어렵습니다 ㅜㅜㅜ svn으로 옮기는 것은 어떨까요?? [2] | 김연희 | 2011.09.19 | 5610 |
198 | 레드햇 클라우드 솔루션 소개 자료 | 이승희_대전 | 2011.09.03 | 5866 |
197 | vimrc 파일 입니다. | 김연희 | 2011.09.03 | 6217 |
196 | 저희 다시 시작해야죠~ [8] | 이상철 | 2011.08.04 | 6774 |
.
답변이 늦었네요.. ㅋ 이제서야 확인 하고 답변을 드립니다. 네.. 정확히는 qemu/kvm process라고 하는 것 같습니다. 어찌 보면 강조하고 싶은 관점의 차이인듯 싶은데요.. kvm process는 일반 사용자 프로세서와 차이점이 있어서 그림과 같이 구분을 두게 되었습니다. 먼저.. 우리가 잘 알고 있듯이 일반적인 리눅스 커널은 커널 모드와 사용자 모드, 이렇게 두가지로 구분합니다. 그러나 KVM은 여기에 게스트 운영체제(가상화 환경에서 수행되는 운영체제) 실행에 사용되는 게스트 모드라는 새로운 모드를 추가 하였고 이 새로운 모드에서는 가상머신이 자체 커널 모드와 사용자 모드를 가질 수 있도록 하는 하는 것이 특징 입니다. 물론 게스트 운영체제라 할지라도 호스트 머신의 일반 프로세스로 실행되지만 KVM에서 제공하는 /dev/kvm 장치 노드를 통해서 자신만의 메모리 주소공간을 가지기 때문에 다른 프로세스들과 구분됩니다. malloc()의 경우도 위의 그림과 같이 일반 프로세스가 실행하는 것과 kvm 단지 qemu이라면 평범한(?) 프로세스이겠지만 qemu-kvm.lib이라 하여 kvm의 정책에 맞게 고쳐졌고 위에서 설명드린 이유로 때문에 kvm process란 이름으로 특징지워진 그림으로 표현 하였습니다. (그리고 실제 http://www.linux-kvm.org/page/Memory 여기에 들어가시면 qemu/kvm process라고 말하는 것을 확인 하실 수 있습니다.) 가상 머신에 대한 프로세스 상태와 메모리관리에 대한 가상화에 집중하고 있고 qemu는 이를 효과 적으로 지원 하기 위해 I/O 하드웨어 가상화쪽으로 집중하고 있습니다. kvm과 qemu은 매우 밀접하게 동작하고 정확히는 qemu/kvm process라 부르는 것이 정확한 표현 인것 같습니다.