300 likes | 475 Views
발표자 : 선준규. Virtual Machine Management. Contents. Overview Data Structures Guest OS 의 생성 Guest OS 의 제거. Overview. Hypervisor 는 vcpu 0 번으로 동작한다 . Guest OS 생성 시 하나의 고유한 vcpu 를 할당 받는다 . Guest OS 의 초기 페이지 테이블 생성 시 OS binary 만을 맵핑한다 . 각각의 Guest OS 는 고유한 주소공간을 갖는다 .
E N D
발표자 : 선준규 Virtual Machine Management
Contents • Overview • Data Structures • Guest OS의 생성 • Guest OS의 제거
Overview • Hypervisor는 vcpu 0번으로 동작한다. • Guest OS 생성 시 하나의 고유한 vcpu를 할당 받는다. • Guest OS의 초기 페이지 테이블 생성 시 OS binary만을 맵핑한다. • 각각의 Guest OS는 고유한 주소공간을 갖는다. • Guest OS 주소공간은 address_space로 관리되며, 여러 개의 mem_region으로 구성되어 있다. • 속도 향상을 위해 자주 사용되는 자료구조를 사전에 캐시로 만들어 요청 시 빠르게 할당해 줄 수 있도록 한다. • vcpu context switching 시 vcpu의 모드에 따라 복구할 Context가 달라지게 된다.
structvcpu • 필드 구성 및 설명 • long vcpu_id; • 각 Virtual CPU의 고유 ID • structguest_os_info *guest_info; • vcpu에서 동작하는 guest os • structregs_ctxregs; • vcpu간 context switching시 레지스터들의 값을 저장하기 위해 사용될 공간 • structlist_headvcpu_list; • vcpu들의 이중 연결 리스트 • structaddress_space *address; • vcpu가 실제 사용하는 주소 공간 • void *master_table; • vcpu의 주소공간을 구성하기위한 page table • struct timer timer; • vcpu의 timer 정보
structvcpu(Cont’d) • unsigned long state; • 현재vcpu의 상태정보를 나타냄(INITIAL, READY, RUNNING, SUSPENDED, TERMINATED ) • long current_running_mode; • 현재vcpu가 동작중인 모드를 나타냄 ( HYPERVISOR / GUEST OS ) • unsigned inttop_stack; • vcpu가 사용하는 stack의 top • unsigned int guarded; • 스택을보호하기위한 guarded space • unsigned intvcpu_stack[VCPU_STACKSIZE]; • 스택 공간 • unsigned long bottom_stack; • vcpu스택의 시작 주소
structguest_os_info • 필드 구성 및 설명 • long guest_id; • Guest OS의 고유 ID • char name[MAX_OS_NAME_LENGTH] • Guest OS의 name • long state; • 현재 Guest OS의 상태 ( UNINITIALIZED/BOOTING/RUNNING/MIGRATING/HALTING) • long requested_exception; • 요청된 Migration, IRQ등의 정보를 표시 • structvcpu *cpu; • Guest OS가 동작하는vcpu • structregs_ctxsaved_regs_ctx; • Guest OS가 Context Switching 될 때 레지스터 값들이 저장될 장소
structguest_os_info (Cont’d) • unsigned long interrupt_vector; • Guest OS의 interrupt vector 주소 • structlist_headguest_os_info; • guest_os_info구조체를 이중 연결리스트로 구성하기 위한 필드 • void (*boot_kernel)(); • 커널이 수행되기 전에 필요한 초기화 작업 • void (*migrate)(); • Migration 요청 시 수행할 핸들러 • void (*shutdown)(); • OS 종료 시 수행될 핸들러 • void (*reset)(); • Reset 요청이 들어오는 경우 수행되는 핸들러
structguest_os_info (Cont’d) • void (*pause)(); • 일시적으로 Guest OS의 동작을 멈추기 위해 사용 • void (*suspend)(); • 장시간 Guest OS의 동작을 멈추는 경우 사용 (Swap Out) • unsigned long top_stack; • Guest OS Stack 의 Top • unsigned long guarded; • Stack Overflow를 감지하기 위한 guard 영역 • unsigned long guest_os_stack[VCPU_STACKSIZE-2]; • Guest OS의 특별한 동작을 위해 사용되는 임시 스택 • unsigned long bottom_stack; • Stack의 시작 위치
vcpu와 guest_os_info의 관계도 guest_os_head_g guest_os_info guest_os_info vcpu0_g vcpu vcpu
structregs_ctx • 필드 구성 및 설명 • unsigned long reg[NUM_REGS] • 레지스터 R0 ~ R15가 저장 될 장소 • Unsigned long cpsr • flag 레지스터인 cpsr이 저장 될 장소
struct timer • 필드 구성 및 설명 • unsigned long longexpires_time; • Guest OS생성 후, 현재까지 지난 시간 • unsigned long longreal_time; • RTC로 부터 얻은 실제 시간 • unsigned long longlogical_time; • 순수 Guest OS만 수행된 시간 • unsigned long longtime_quantum; • Round Robin Scheduling을 위한 퀀텀
structaddress_space • 필드 구성 및 설명 • structvcpu *cpu; • 이 주소 공간을 사용하는vcpu • structaddress_space *next; • address_space를 이중연결리스트로 구성하기 위한 필드 • structmem_region *active_region; • Guest OS 가 사용하는 메모리 구역에 대한 연결리스트 • long pages_count; • 사용중인 총 페이지 수 • long mem_region_count; • 사용중인 메모리 구역 수
structmem_region • 필드 구성 및 설명 • structaddress_space *belongs_to; • 해당 메모리 구역이 속한 주소공간 • structlist_headmem_region_list; • mem_region을 이중연결리스트로 구성하기 위한 필드 • long page_attribute; • 이mem_region이 기술하고 있는 페이지 테이블 엔트리들의 default 속성 정보를 저장 (User/Supervisor, Locked, etc..) • unsigned long start_vaddr; • unsigned long end_vaddr; • 메모리 구역이 관리할 가상 주소의 시작과 끝 주소 • unsigned long start_paddr • unsigned long end_paddr; • 메모리 구역이 관리할 물리 주소의 시작과 끝 주소
guest_os_info Guest OS의 주소 공간 구성도 address_space address_space active_region vcpu mem_region mem_region mem_region In Use page Unused < Virtual Memory >
새로운 Guest OS의 생성(1) • 생성 방법 • …. structvcpu* vcpu = setup_vcpu(1)setup_guest_os_info(vcpu,0x00010000, 0x10000, “uCOS”);activate_vcpu(vcpu);….
새로운 Guest OS의 생성(2) • 생성과정(Overview) • 새로운 vcpu할당 • 새로운 guest_os_info 할당 및 초기화 • 할당받은guest_os_info를 vcpu에 assign • 스택생성 및 초기화 • guest_os_info정보를 통해 vcpu의 address_space범위 조정 • 페이지 테이블 구성
setup_vcpu() • structvcpu *setup_vcpu(intcpu_num){structvcpu *vcpu= create_vcpu() ;vcpu_map에서vcpu_id번째 비트가 비어있는지 확인 if 비어있다면 , vcpu_id에cpu_num할당 else return 에러init_vcpu_stack(vcpu)vcpu->current_running_mode = HYPERVISOR_MODE;vcpu->state = INITIALvcpu->master_table = 페이지 테이블을 위한 공간 할당structaddress_space *address = alloc_cache(address_space)init_address_space(address, vcpu, 디폴트 가상메모리 시작 주소 ,디폴트 가상 메모리 크기, 디폴트 페이지 속성)vcpu->address = addressvcpu를vcpu_list_g연결리스트에 삽입 return vcpu}
create_vcpu() • structvcpu *create_vcpu(void){ return alloc_cache(vcpu)}
init_vcpu_stack() • void init_vcpu_stack(structvcpu *cpu){cpu-> top_stack = cpu->bottom_stacktop_stack에vcpu시작 문맥 (레지스터 값) 저장}
init_address_space() • intinit_address_space( structaddress_space *address,structvcpu *vcpu, unsigned intstart_addr, intlen, unsigned long page_attribute){ address->vcpu = vcpu;기타address_space필드 초기화;create_mem_region(start_addr,len) address를 vcpu0_g ->address_space의 연결리스트에 추가}
create_mem_region() • create_mem_region(structaddress_space *address, unsigned intstart_addr, intlen, unsigned intdefault_page_attr){현재 address_space에 해당 메모리 구역이 존재하지 않으면,structmem_region *region = alloc_cache(mem_region) Page allocator를 통해 [start_addr,start_addr+len-1]구간 안의 페이지를 할당실제로 페이지 테이블 구성 및 페이지 프레임 할당default_page_attr로 페이지 테이블 엔트리 속성 설정address_space에 메모리 구역 추가}
find_mem_region() • structmem_region *find_mem_region(structaddress_space *address, unsigned intaddr, intlen){address_space에서 해당mem_region을 포함하거나 인접한mem_region을 반환없으면 NULL을 리턴}
merge_mem_regions() • intmerge_mem_regions(structaddress_space *address, structmem_region *region){주위에 region과 인접한mem_region이 있으면 합침}
setup_guest_os_info() • void setup_guest_os_info(structvcpu *cpu, unsigned intphys_loc_addr, unsigned intlen, char *name){structguest_os_info *guest = alloc_cache(guest_os_info); guest의 각 필드 초기화assign_guest_os(cpu,guest);}
assign_guest_os() • intassign_guest_os(structvcpu *vcpu, structguest_os_info *guest){init_guest_os_stack(guest); guest정보를 이용해 vcpu의 address_space범위 조정페이지 테이블 구성vcpu->guest =guest; guest->vcpu = vcpu;guest_os_head_g연결리스트에 guest추가 }
init_guest_os_stack() • void init_guest_os_stack(structguest_os_info *guest){ guest->saved_regs_ctx에 초기 레지스터값 셋팅}
vcpu0의 생성(1) • 설명 • vcpu0는 전역 변수로 선언되며 하이퍼바이저 부팅 시 초기화 시켜 준다. • 관련 전역 변수 • structvcpu*vcpu0_g • 처음 부팅시 동작하는 virtual cpu • structvcpu *current_vcpu; • 현재 동작중인vcpu에 대한 포인터 • unsigned char vcpu_map_g[MAX_NUM_VCPU/8]; • 각vcpu의 id를 관리하기 위한 Bit Map
vcpu0의 생성(2) • 생성방법 • Guest OS 의 생성 방법과 유사 • vcpu0_g = setup_vcpu(0) • current_vcpu = vcpu0_g; • guest_os_info의 설정(setup_guest_os_info())은하지 않음 • activate_vcpu(current_vcpu); • 위 과정은 인터럽트가 해지된 상태에서 진행되어야 함
Guest OS의제거(1) • 제거방법 • vcpu0 의 커맨드 입력창에서 • VM_….1. Guest OS 스케줄링 큐에서 삭제할 guest os를 찾음2. guest os를 큐에서 제거3. address_space를 참고하여 메모리 해제4. vm이 사용중이던 각 자료구조 해제….