# 가상화 활성화

가상화는 소프트웨어를 사용하여 컴퓨터 하드웨어 위에 추상화 계층을 만듭니다.

추상화 계층은 프로세서, 메모리, 스토리지 같은 단일 컴퓨터의 하드웨어 요소를 가상 머신(VM)이라는 다양한 가상 엔터티로 나눕니다. 각 VM은 동일한 하드웨어 컴퓨터에서 실행되지만 고유한 OS를 실행하며 독립적인 컴퓨터처럼 동작합니다.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by Microsoft Visio, SVG Export virtualization.svg Page-1 -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="6.0939in" height="4.89004in" viewbox="0 0 438.761 352.083" xml:space="preserve" color-interpolation-filters="sRGB" class="st10" aria-label="../_images/virtualization-3.svg"><v:documentproperties v:langid="1033" v:viewmarkup="false">	<v:userdefs>		<v:ud v:nameu="msvSubprocessMaster" v:prompt="" v:val="VT4(Rectangle)"></v:ud>		<v:ud v:nameu="msvNoAutoConnect" v:val="VT0(1):26"></v:ud>	</v:userdefs></v:documentproperties>
<style>.svg-1 .st1 { fill: #fafafa; stroke: #d2d7e1; stroke-width: 1.5 }
.svg-1 .st2 { fill: none; stroke: #d2d7e1; stroke-width: 1.5 }
.svg-1 .st3 { fill: #d2d7e1; stroke: #000000; stroke-opacity: 0; stroke-width: 2 }
.svg-1 .st4 { fill: #000000; font-family: Roboto Flex, Qualcomm-Next, sans-serif; font-size: 1.16666em }
.svg-1 .st5 { fill: #7c8aa3; stroke: #000000; stroke-opacity: 0; stroke-width: 2 }
.svg-1 .st6 { fill: #feffff; font-family: Roboto Flex, Qualcomm-Next, sans-serif; font-size: 1.16666em }
.svg-1 .st7 { fill: none; stroke: none; stroke-width: 2 }
.svg-1 .st8 { fill: none; stroke: none; stroke-width: 0.25 }
.svg-1 .st9 { fill: #000000; font-family: Roboto Flex, Qualcomm-Next, sans-serif; font-size: 0.75em }
.svg-1 .st10 { fill: none; fill-rule: evenodd; font-size: 12px; overflow: visible; stroke-linecap: square; stroke-miterlimit: 3 }</style>
<g v:mid="0" v:index="1" v:groupcontext="foregroundPage">	<v:userdefs>		<v:ud v:nameu="msvThemeOrder" v:val="VT0(0):26"></v:ud>	</v:userdefs>	<title>Page-1</title>	<v:pageproperties v:drawingscale="1" v:pagescale="1" v:drawingunits="0" v:shadowoffsetx="9" v:shadowoffsety="-9"></v:pageproperties>	<g id="shape1029-1" v:mid="1029" v:groupcontext="shape" transform="translate(19.4999,-22.5829)">		<title>Rounded Rectangle</title>		<v:userdefs>			<v:ud v:nameu="CTypeTopLeftSnip" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="CTypeTopRightSnip" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="CTypeBotLeftSnip" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="CTypeBotRightSnip" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="CornerLockHoriz" v:prompt="" v:val="VT0(1):5"></v:ud>			<v:ud v:nameu="CornerLockVert" v:prompt="" v:val="VT0(1):5"></v:ud>			<v:ud v:nameu="CornerLockDiag" v:prompt="" v:val="VT0(0):5"></v:ud>			<v:ud v:nameu="TopLeftOffset" v:prompt="" v:val="VT0(0.15):1"></v:ud>			<v:ud v:nameu="TopRightOffset" v:prompt="" v:val="VT0(0.15):1"></v:ud>			<v:ud v:nameu="BotLeftOffset" v:prompt="" v:val="VT0(0.15):1"></v:ud>			<v:ud v:nameu="BotRightOffset" v:prompt="" v:val="VT0(0.15):1"></v:ud>			<v:ud v:nameu="visVersion" v:prompt="" v:val="VT0(15):26"></v:ud>			<v:ud v:nameu="TopLeftOffset" v:prompt="" v:val="VT0(0.069444325034464):1"></v:ud>			<v:ud v:nameu="TopRightOffset" v:prompt="" v:val="VT0(0.069444325034464):1"></v:ud>			<v:ud v:nameu="BotLeftOffset" v:prompt="" v:val="VT0(0.069444325034464):1"></v:ud>			<v:ud v:nameu="BotRightOffset" v:prompt="" v:val="VT0(0.069444325034464):1"></v:ud>		</v:userdefs>		<path d="M5 352.08 L394.76 352.08 A4.99991 4.99991 -180 0 0 399.76 347.08 L399.76 47.08 A4.99991 4.99991 -180 0 0 394.76					 42.08 L5 42.08 A4.99991 4.99991 -180 0 0 0 47.08 L0 347.08 A4.99991 4.99991 -180 0 0 5 352.08 Z" class="st1"></path>	</g>	<g id="shape1007-3" v:mid="1007" v:groupcontext="shape" transform="translate(229.392,-165.403)">		<title>Rectangle.1007</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="221.383" width="175" height="130.7" rx="2.88" ry="2.88" class="st2"></rect>	</g>	<g id="shape1023-5" v:mid="1023" v:groupcontext="shape" transform="translate(31.2499,-165.403)">		<title>Rectangle.1023</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="221.383" width="175" height="130.7" rx="2.88" ry="2.88" class="st2"></rect>	</g>	<g id="shape1016-7" v:mid="1016" v:groupcontext="shape" transform="translate(30.2499,-115.107)">		<title>Rectangle.1016</title>		<desc>Operating system</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="187.721" cy="333.99" width="375.45" height="36.1864"></v:textrect>		<rect x="0" y="315.897" width="375.443" height="36.1864" rx="2.88" ry="2.88" class="st3"></rect>		<text x="132.93" y="338.19" class="st4" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Operating system</text>		</g>	<g id="shape1019-10" v:mid="1019" v:groupcontext="shape" transform="translate(30.2499,-64.8101)">		<title>Rectangle.1019</title>		<desc>Hardware</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="187.721" cy="333.99" width="375.45" height="36.1864"></v:textrect>		<rect x="0" y="315.897" width="375.443" height="36.1864" rx="2.88" ry="2.88" class="st5"></rect>		<text x="157.46" y="338.19" class="st6" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Hardware</text>		</g>	<g id="shape1002-13" v:mid="1002" v:groupcontext="shape" transform="translate(44.1067,-236.892)">		<title>Rectangle.1002</title>		<desc>User space</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="74.6432" cy="328.475" width="149.29" height="47.2151"></v:textrect>		<rect x="0" y="304.868" width="149.286" height="47.2151" rx="2.88" ry="2.88" class="st3"></rect>		<text x="39.97" y="332.68" class="st4" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>User space</text>		</g>	<g id="shape1003-16" v:mid="1003" v:groupcontext="shape" transform="translate(44.1067,-177.873)">		<title>Rectangle.1003</title>		<desc>Operating system</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="74.6432" cy="328.475" width="149.29" height="47.2151"></v:textrect>		<rect x="0" y="304.868" width="149.286" height="47.2151" rx="2.88" ry="2.88" class="st3"></rect>		<text x="19.85" y="332.68" class="st4" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Operating system</text>		</g>	<g id="shape1009-19" v:mid="1009" v:groupcontext="shape" transform="translate(53.673,-300.852)">		<title>Sheet.1009</title>		<desc>Virtual machine #1</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="63.7939" cy="338.968" width="127.59" height="26.2306"></v:textrect>		<rect x="0" y="325.852" width="127.588" height="26.2306" class="st7"></rect>		<text x="5.18" y="343.17" class="st4" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Virtual machine #1</text>		</g>	<g id="shape1005-22" v:mid="1005" v:groupcontext="shape" transform="translate(242.134,-236.686)">		<title>Rectangle.1005</title>		<desc>User space</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="74.6432" cy="328.475" width="149.29" height="47.2151"></v:textrect>		<rect x="0" y="304.868" width="149.286" height="47.2151" rx="2.88" ry="2.88" class="st3"></rect>		<text x="39.97" y="332.68" class="st4" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>User space</text>		</g>	<g id="shape1006-25" v:mid="1006" v:groupcontext="shape" transform="translate(242.134,-177.667)">		<title>Rectangle.1006</title>		<desc>Operating system</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="74.6432" cy="328.475" width="149.29" height="47.2151"></v:textrect>		<rect x="0" y="304.868" width="149.286" height="47.2151" rx="2.88" ry="2.88" class="st3"></rect>		<text x="19.85" y="332.68" class="st4" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Operating system</text>		</g>	<g id="shape1010-28" v:mid="1010" v:groupcontext="shape" transform="translate(219.805,-300.685)">		<title>Sheet.1010</title>		<desc>Virtual machine #2</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="96.9723" cy="338.968" width="193.95" height="26.2306"></v:textrect>		<rect x="0" y="325.852" width="193.945" height="26.2306" class="st7"></rect>		<text x="38.36" y="343.17" class="st4" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Virtual machine #2</text>		</g>	<g id="shape1027-31" v:mid="1027" v:groupcontext="shape" transform="translate(19.4999,-18)">		<title>Sheet.1027</title>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>	</g>	<g id="shape1030-32" v:mid="1030" v:groupcontext="shape" transform="translate(349.261,-32.5829)">		<title>Sheet.1030</title>		<rect x="0" y="339.777" width="12.7435" height="12.306" rx="2" ry="2" class="st5"></rect>	</g>	<g id="shape1031-34" v:mid="1031" v:groupcontext="shape" transform="translate(361.842,-32.5829)">		<title>Sheet.1031</title>		<desc>Hardware</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="23.625" cy="345.93" width="47.25" height="12.306"></v:textrect>		<rect x="0" y="339.777" width="47.25" height="12.306" class="st8"></rect>		<text x="4.17" y="348.63" class="st9" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Hardware</text>		</g></g>
</svg>

**그림: 가상화**

참고

가상화는 사용자 지정 BSP 변형에서만 지원됩니다.

## Qualcomm 가상화 솔루션

퀄컴은 강력한 보안, 높은 성능, OS 독립성, 더 높은 CPU 권한 수준을 위해 설계된 Type-1 하이퍼바이저인 Gunyah를 사용합니다.

Gunyah는 핵심 기능이 향상된 보안을 제공할 수 있도록 어떤 낮은 권한의 OS 커널이나 코드에도 의존하지 않습니다. Gunyah는 격리된 가상 머신 사용 사례, 그리고 상대적으로 신뢰도가 낮은 호스트 가상 머신에서 격리된 가상 머신을 시작하는 경우를 염두에 두고 설계되었습니다.

다음 그림은 Qualcomm 가상화 솔루션 구조를 보여줍니다.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by Microsoft Visio, SVG Export virtualization-solution.svg Page-1 -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="6.84028in" height="5.12466in" viewbox="0 0 492.5 368.975" xml:space="preserve" color-interpolation-filters="sRGB" class="st11 align-center" aria-label="../_images/virtualization-solution.svg"><v:documentproperties v:langid="1033" v:viewmarkup="false">	<v:userdefs>		<v:ud v:nameu="msvNoAutoConnect" v:val="VT0(1):26"></v:ud>	</v:userdefs></v:documentproperties>
<style>.svg-2 .st1 { fill: #fafafa; stroke: #d2d7e1; stroke-linecap: round; stroke-linejoin: round; stroke-width: 2 }
.svg-2 .st2 { fill: #d2d7e1; stroke: #000000; stroke-linecap: round; stroke-linejoin: round; stroke-opacity: 0; stroke-width: 0.75 }
.svg-2 .st3 { fill: #000000; font-family: Roboto Flex, Qualcomm-Next, sans-serif; font-size: 1.16666em }
.svg-2 .st4 { fill: #007884; stroke: #007884; stroke-linecap: round; stroke-linejoin: round; stroke-width: 2 }
.svg-2 .st5 { fill: #ffffff; font-family: Roboto Flex, Qualcomm-Next, sans-serif; font-size: 1.16666em }
.svg-2 .st6 { stroke: #000000; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.5 }
.svg-2 .st7 { fill: none; stroke: none; stroke-linecap: round; stroke-linejoin: round; stroke-width: 0.75 }
.svg-2 .st8 { fill: #007884; stroke: #000000; stroke-opacity: 0; stroke-width: 2 }
.svg-2 .st9 { fill: none; stroke: none; stroke-width: 0.25 }
.svg-2 .st10 { fill: #000000; font-family: Roboto Flex, Qualcomm-Next, sans-serif; font-size: 1.00001em }
.svg-2 .st11 { fill: none; fill-rule: evenodd; font-size: 12px; overflow: visible; stroke-linecap: square; stroke-miterlimit: 3 }</style>
<g v:mid="0" v:index="1" v:groupcontext="foregroundPage">	<title>Page-1</title>	<v:pageproperties v:drawingscale="1" v:pagescale="1" v:drawingunits="19" v:shadowoffsetx="9" v:shadowoffsety="-9"></v:pageproperties>	<g id="shape1003-1" v:mid="1003" v:groupcontext="shape" transform="translate(19,-19)">		<title>Sheet.1003</title>		<rect x="0" y="38" width="454.5" height="330.975" rx="2.88" ry="2.88" class="st1"></rect>	</g>	<g id="shape2-3" v:mid="2" v:groupcontext="shape" transform="translate(32.5,-62.8712)">		<title>Rectangle</title>		<desc>CPU</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="160.875" cy="348.065" width="321.75" height="41.8216"></v:textrect>		<rect x="0" y="327.154" width="321.75" height="41.8216" rx="2.88" ry="2.88" class="st2"></rect>		<text x="147.36" y="352.26" class="st3" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>CPU</text>		</g>	<g id="shape3-6" v:mid="3" v:groupcontext="shape" transform="translate(32.5,-124.349)">		<title>Rectangle.2</title>		<desc>Gunyah hypervisor</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="160.875" cy="348.065" width="321.75" height="41.8216"></v:textrect>		<rect x="0" y="327.154" width="321.75" height="41.8216" rx="2.88" ry="2.88" class="st4"></rect>		<text x="103.45" y="352.26" class="st5" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Gunyah hypervisor</text>		</g>	<g id="shape4-9" v:mid="4" v:groupcontext="shape" transform="translate(283.949,-199.225)">		<title>Rectangle.3</title>		<desc>OS</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="35.3571" cy="348.065" width="70.72" height="41.8216"></v:textrect>		<rect x="0" y="327.154" width="70.7143" height="41.8216" rx="2.88" ry="2.88" class="st2"></rect>		<text x="26.39" y="352.26" class="st3" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>OS</text>		</g>	<g id="shape5-12" v:mid="5" v:groupcontext="shape" transform="translate(158.5,-199.225)">		<title>Rectangle.5</title>		<desc>OS</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="35.3571" cy="348.065" width="70.72" height="41.8216"></v:textrect>		<rect x="0" y="327.154" width="70.7143" height="41.8216" rx="2.88" ry="2.88" class="st2"></rect>		<text x="26.39" y="352.26" class="st3" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>OS</text>		</g>	<g id="shape6-15" v:mid="6" v:groupcontext="shape" transform="translate(33.0511,-199.225)">		<title>Rectangle.6</title>		<desc>RM</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="35.3571" cy="348.065" width="70.72" height="41.8216"></v:textrect>		<rect x="0" y="327.154" width="70.7143" height="41.8216" rx="2.88" ry="2.88" class="st2"></rect>		<text x="24.94" y="352.26" class="st3" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>RM</text>		</g>	<g id="shape8-18" v:mid="8" v:groupcontext="shape" transform="translate(397,-273.666)">		<title>Rectangle.8</title>		<desc>EL0</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="31.3021" cy="346.15" width="62.61" height="45.6508"></v:textrect>		<rect x="0" y="323.325" width="62.6043" height="45.6508" rx="2.88" ry="2.88" class="st2"></rect>		<text x="19.63" y="350.35" class="st3" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>EL0</text>		</g>	<g id="shape10-21" v:mid="10" v:groupcontext="shape" transform="translate(397,-199.008)">		<title>Rectangle.17</title>		<desc>EL1</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="31.3021" cy="348.065" width="62.61" height="41.8216"></v:textrect>		<rect x="0" y="327.154" width="62.6043" height="41.8216" rx="2.88" ry="2.88" class="st2"></rect>		<text x="19.63" y="352.26" class="st3" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>EL1</text>		</g>	<g id="shape11-24" v:mid="11" v:groupcontext="shape" transform="translate(397,-124.349)">		<title>Rectangle.18</title>		<desc>EL2</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="31.3021" cy="348.065" width="62.61" height="41.8216"></v:textrect>		<rect x="0" y="327.154" width="62.6043" height="41.8216" rx="2.88" ry="2.88" class="st2"></rect>		<text x="19.63" y="352.26" class="st3" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>EL2</text>		</g>	<g id="shape13-27" v:mid="13" v:groupcontext="shape" transform="translate(500.475,29.6602) rotate(90)">		<title>Sheet.13</title>		<path d="M0 368.98 L158.68 368.98" class="st6"></path>	</g>	<g id="shape14-30" v:mid="14" v:groupcontext="shape" transform="translate(626.475,29.6602) rotate(90)">		<title>Sheet.14</title>		<path d="M0 368.98 L158.68 368.98" class="st6"></path>	</g>	<g id="shape7-33" v:mid="7" v:groupcontext="shape" transform="translate(158.5,-273.666)">		<title>Rectangle.7</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="323.325" width="70.7143" height="45.6508" rx="2.88" ry="2.88" class="st2"></rect>	</g>	<g id="shape1000-35" v:mid="1000" v:groupcontext="shape" transform="translate(175.726,-284.004)">		<title>Sheet.1000</title>		<desc>APP</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="18.1313" cy="356.488" width="36.27" height="24.9753"></v:textrect>		<rect x="0" y="344" width="36.2626" height="24.9753" class="st7"></rect>		<text x="4.73" y="360.69" class="st3" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>APP</text>		</g>	<g id="shape1001-38" v:mid="1001" v:groupcontext="shape" transform="translate(283.949,-273.666)">		<title>Rectangle.1001</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="323.325" width="70.7143" height="45.6508" rx="2.88" ry="2.88" class="st2"></rect>	</g>	<g id="shape1002-40" v:mid="1002" v:groupcontext="shape" transform="translate(295.612,-284.004)">		<title>Sheet.1002</title>		<desc>APP</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="23.6939" cy="356.488" width="47.39" height="24.9753"></v:textrect>		<rect x="0" y="344" width="47.3878" height="24.9753" class="st7"></rect>		<text x="10.3" y="360.69" class="st3" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>APP</text>		</g>	<g id="shape1004-43" v:mid="1004" v:groupcontext="shape" transform="translate(372.25,-27.0985)">		<title>Sheet.1004</title>		<rect x="0" y="352.324" width="17.2435" height="16.6515" rx="2" ry="2" class="st8"></rect>	</g>	<g id="shape1005-45" v:mid="1005" v:groupcontext="shape" transform="translate(389.331,-29.2713)">		<title>Sheet.1005</title>		<desc>Open source</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="38.7093" cy="362.822" width="77.42" height="12.306"></v:textrect>		<rect x="0" y="356.669" width="77.4185" height="12.306" class="st9"></rect>		<text x="5.07" y="366.42" class="st10" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Open source</text>		</g></g>
</svg>

**그림: Qualcomm 가상화 솔루션 구조**

Gunyah는 다음과 같은 기능을 제공합니다.

표: Gunyah의 기능

| 기능 | 설명 |
| --- | --- |
| 스레드 및 예약 | 스케줄러는 물리적 CPU에서 가상 CPU(VCPU)를 예약하고 CPU의 시간 공유를 허용합니다. |
| 메모리 관리 | Gunyah는 메모리 소유권 및 그에 따라 제어되는 메모리 사용을 추적합니다. Gunyah는 낮은 수준의 동적 메모리 관리 API를 제공하며, 그 위에 높은 수준의 메모리 기부, 대여, 공유가 구축됩니다. |
| 인터럽트 가상화 | Gunyah는 할당된 VM에 직접 라우팅되는 인터럽트를 관리합니다. |
| VM 간 통신 | 메시지 큐와 도어벨은 VM 간 통신을 위한 메커니즘을 제공합니다. |
| 기기 가상화 | VM 간 통신 및 virtio 기본 요소를 사용하는 기기의 반가상화가 지원됩니다. 하드웨어 가상화 및 에뮬레이션은 CPU 타이머 및 인터럽트 컨트롤러 같은 낮은 수준의 구조 기능과 기기를 지원합니다. |
| 리소스 매니저 | Gunyah는 초기에 모든 VM 메모리와 입출력 리소스를 소유하는 루트 VM을 지원합니다. Gunyah 리소스 매니저는 기본으로 포함된 루트 VM이며 동적 VM 관리, 안전한 메모리 기부, 대여, 공유를 비롯한 전반적인 서비스를 제공합니다. |

Gunyah 하이퍼바이저 지원은 [crosvm](https://chromium.googlesource.com/chromiumos/platform/crosvm) 가상 메모리 모니터(VMM)에 추가됩니다. crosvm은 `/dev/gunyah` 인터페이스를 통해 커널의 Gunyah VM 매니저와 상호 작용하고 VM을 생성합니다.

다음 그림은 Qualcomm 가상화 솔루션의 블록을 보여줍니다.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by Microsoft Visio, SVG Export virtualization_solution_new.svg Page-1 -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="7.77778in" height="7.70833in" viewbox="0 0 560 555" xml:space="preserve" color-interpolation-filters="sRGB" class="st19" aria-label="../_images/virtualization_solution_new.svg"><v:documentproperties v:langid="1033" v:viewmarkup="false">	<v:userdefs>		<v:ud v:nameu="msvSubprocessMaster" v:prompt="" v:val="VT4(Rectangle)"></v:ud>		<v:ud v:nameu="msvNoAutoConnect" v:val="VT0(1):26"></v:ud>	</v:userdefs></v:documentproperties>
<style>.svg-3 .st1 { fill: #fafafa; stroke: #c7c8c8; stroke-width: 2 }
.svg-3 .st2 { fill: none; stroke: none; stroke-width: 2 }
.svg-3 .st3 { fill: #000000; font-family: Roboto Flex, Qualcomm-Next, sans-serif; font-size: 1.00001em }
.svg-3 .st4 { fill: #007884; fill-opacity: 0; stroke: #000000; stroke-width: 2 }
.svg-3 .st5 { fill: none; stroke: #3f3f3f; stroke-width: 2 }
.svg-3 .st6 { fill: #007884; stroke: #000000; stroke-opacity: 0; stroke-width: 2 }
.svg-3 .st7 { fill: #ffffff; font-family: Roboto Flex, Qualcomm-Next, sans-serif; font-size: 1.16666em }
.svg-3 .st8 { fill: #ffffff; stroke: #3f3f3f; stroke-width: 2 }
.svg-3 .st9 { fill: none; marker-end: url("#mrkr5-23"); stroke: #7c8aa3; stroke-dasharray: 0.01, 10; stroke-width: 2 }
.svg-3 .st10 { fill: #7c8aa3; fill-opacity: 1; stroke: #7c8aa3; stroke-opacity: 1; stroke-width: 0.44247787610619 }
.svg-3 .st11 { fill: none; stroke: #7c8aa3; stroke-width: 2 }
.svg-3 .st12 { fill: #000000; font-family: Roboto Flex, Qualcomm-Next, sans-serif; font-size: 1.16666em; font-weight: bold }
.svg-3 .st13 { fill: #000000; font-family: Roboto Flex, Qualcomm-Next, sans-serif; font-size: 1.16666em }
.svg-3 .st14 { marker-end: url("#mrkr4-37"); stroke: #000000; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.5 }
.svg-3 .st15 { fill: #000000; fill-opacity: 1; stroke: #000000; stroke-opacity: 1; stroke-width: 0.37313432835821 }
.svg-3 .st16 { stroke: #000000; stroke-dasharray: 4.5, 4.5; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.5 }
.svg-3 .st17 { fill: none; stroke: none; stroke-width: 0.25 }
.svg-3 .st18 { font-family: Symbol; font-size: 1em }
.svg-3 .st19 { fill: none; fill-rule: evenodd; font-size: 12px; overflow: visible; stroke-linecap: square; stroke-miterlimit: 3 }</style>
<defs id="Markers">	<g id="lend5">		<path d="M 2 1 L 0 0 L 1.98117 -0.993387 C 1.67173 -0.364515 1.67301 0.372641 1.98465 1.00043 " style="stroke:none"></path>	</g>	<marker id="mrkr5-23" class="st10" v:arrowtype="5" v:arrowsize="2" v:setback="3.955" refx="-3.955" orient="auto" markerunits="strokeWidth" overflow="visible">		<use xlink:href="#lend5" transform="scale(-2.26,-2.26) "></use>	</marker>	<g id="lend4">		<path d="M 2 1 L 0 0 L 2 -1 L 2 1 " style="stroke:none"></path>	</g>	<marker id="mrkr4-37" class="st15" v:arrowtype="4" v:arrowsize="2" v:setback="5.36" refx="-5.36" orient="auto" markerunits="strokeWidth" overflow="visible">		<use xlink:href="#lend4" transform="scale(-2.68,-2.68) "></use>	</marker></defs><g v:mid="0" v:index="1" v:groupcontext="foregroundPage">	<v:userdefs>		<v:ud v:nameu="msvThemeOrder" v:val="VT0(0):26"></v:ud>	</v:userdefs>	<title>Page-1</title>	<v:pageproperties v:drawingscale="1" v:pagescale="1" v:drawingunits="0" v:shadowoffsetx="9" v:shadowoffsety="-9"></v:pageproperties>	<g id="shape1015-1" v:mid="1015" v:groupcontext="shape" transform="translate(20,-20)">		<title>Sheet.1015</title>		<rect x="0" y="40" width="520" height="515" rx="4" ry="4" class="st1"></rect>	</g>	<g id="shape1008-3" v:mid="1008" v:groupcontext="shape" transform="translate(37.5,-218.786)">		<title>Sheet.1008</title>		<desc>User space</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="41.4161" cy="543.496" width="82.84" height="23.0089"></v:textrect>		<rect x="0" y="531.991" width="82.8322" height="23.0089" class="st2"></rect>		<text x="11.07" y="547.1" class="st3" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>User space</text>		</g>	<g id="shape1009-6" v:mid="1009" v:groupcontext="shape" transform="translate(37.5,-181.996)">		<title>Sheet.1009</title>		<desc>Linux</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="20" cy="539.469" width="40" height="31.0621"></v:textrect>		<rect x="0" y="523.938" width="40" height="31.0621" class="st2"></rect>		<text x="5.66" y="543.07" class="st3" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Linux</text>		</g>	<g id="shape1-9" v:mid="1" v:groupcontext="shape" transform="translate(230,-110)">		<title>Rectangle</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="480" width="220" height="75" rx="4" ry="4" class="st4"></rect>	</g>	<g id="shape9-11" v:mid="9" v:groupcontext="shape" transform="translate(211.045,-348.143)">		<title>Rectangle.9</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="450.617" width="151.258" height="104.383" rx="2.88" ry="2.88" class="st5"></rect>	</g>	<g id="shape1000-13" v:mid="1000" v:groupcontext="shape" transform="translate(254.219,-198.078)">		<title>Rectangle.1000</title>		<desc>/dev/gunyah</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="82.8322" cy="539.469" width="165.67" height="31.0621"></v:textrect>		<rect x="0" y="523.938" width="165.664" height="31.0621" rx="4" ry="4" class="st6"></rect>		<text x="44.69" y="543.67" class="st7" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>/dev/gunyah</text>		</g>	<g id="shape1001-16" v:mid="1001" v:groupcontext="shape" transform="translate(230.22,-342.189)">		<title>Rectangle.1001</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="460.969" width="151.258" height="94.0314" rx="2.88" ry="2.88" class="st8"></rect>	</g>	<g id="shape1002-18" v:mid="1002" v:groupcontext="shape" transform="translate(246.481,-325.511)">		<title>Rectangle.1002</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="460.969" width="181.14" height="94.0314" rx="4" ry="4" class="st6"></rect>	</g>	<g id="shape1003-20" v:mid="1003" v:groupcontext="shape" transform="translate(142.211,-297.527)">		<title>Rectangle.1003</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="365" width="320.975" height="190" rx="2" ry="2" class="st9"></rect>	</g>	<g id="shape1004-24" v:mid="1004" v:groupcontext="shape" transform="translate(38.6707,-260.202)">		<title>Rectangle.1004</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="298.262" width="480.775" height="256.738" rx="2" ry="2" class="st11"></rect>	</g>	<g id="shape1005-26" v:mid="1005" v:groupcontext="shape" transform="translate(32.1679,-491.022)">		<title>Sheet.1005</title>		<desc>crosvm</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="41.4161" cy="543.496" width="82.84" height="23.0089"></v:textrect>		<rect x="0" y="531.991" width="82.8322" height="23.0089" class="st2"></rect>		<text x="16.51" y="547.7" class="st12" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>crosvm</text>		</g>	<g id="shape1006-29" v:mid="1006" v:groupcontext="shape" transform="translate(204.335,-459.518)">		<title>Sheet.1006</title>		<desc>Hypervisor crates</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="60.3325" cy="543.496" width="120.67" height="23.0089"></v:textrect>		<rect x="0" y="531.991" width="120.665" height="23.0089" class="st2"></rect>		<text x="5.87" y="547.7" class="st13" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Hypervisor crates</text>		</g>	<g id="shape1007-32" v:mid="1007" v:groupcontext="shape" transform="translate(-217.949,325.86) rotate(-90)">		<title>Sheet.1007</title>		<path d="M0 555 L88.33 555" class="st14"></path>	</g>	<g id="shape1010-38" v:mid="1010" v:groupcontext="shape" transform="translate(23.3333,-213.609)">		<title>Sheet.1010</title>		<path d="M0 555 L230.89 555" class="st16"></path>	</g>	<g id="shape1011-41" v:mid="1011" v:groupcontext="shape" transform="translate(419.884,-213.609)">		<title>Sheet.1011</title>		<path d="M0 555 L119.56 555" class="st16"></path>	</g>	<g id="shape1012-44" v:mid="1012" v:groupcontext="shape" transform="translate(341.5,-234.527)">		<title>Sheet.1012</title>		<desc>IOCTLs</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="28.5" cy="545.75" width="57" height="18.5"></v:textrect>		<rect x="0" y="536.5" width="57" height="18.5" class="st2"></rect>		<text x="4.39" y="549.95" class="st13" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>IOCTLs</text>		</g>	<g id="shape1014-47" v:mid="1014" v:groupcontext="shape" transform="translate(414.737,-33.0848)">		<title>Sheet.1014</title>		<rect x="0" y="536.17" width="19.5" height="18.8305" rx="2" ry="2" class="st6"></rect>	</g>	<g id="shape1016-49" v:mid="1016" v:groupcontext="shape" transform="translate(254.219,-342.527)">		<title>Sheet.1016</title>		<desc>Gunyah crate DT nodes generation Glue to ioctl bindings</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="82.8322" cy="525" width="165.67" height="60"></v:textrect>		<rect x="0" y="495" width="165.664" height="60" class="st17"></rect>		<text x="11.78" y="512.18" class="st7" v:langid="1033"><v:paragraph></v:paragraph><v:tablist></v:tablist>Gunyah crate<v:newlinechar></v:newlinechar><v:paragraph v:indentfirst="-18" v:indentleft="18" v:bullet="1"></v:paragraph><tspan x="4" dy="1.212em" class="st18" v:isbullet="true">·</tspan><tspan class="st18"> </tspan> DT nodes generation<v:newlinechar></v:newlinechar><tspan x="4" dy="1.216em" class="st18" v:isbullet="true">·</tspan><tspan class="st18"> </tspan>Glue to ioctl bindings</text>		</g>	<g id="shape1018-56" v:mid="1018" v:groupcontext="shape" transform="translate(256.105,-146.438)">		<title>Rectangle.1018</title>		<desc>Gunyah miscdev</desc>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="82.8322" cy="539.469" width="165.67" height="31.0621"></v:textrect>		<rect x="0" y="523.938" width="165.664" height="31.0621" rx="4" ry="4" class="st6"></rect>		<text x="30.7" y="543.67" class="st7" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Gunyah miscdev</text>		</g>	<g id="shape1021-59" v:mid="1021" v:groupcontext="shape" transform="translate(303,-122.5)">		<title>Sheet.1021</title>		<desc>gunyah.ko</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="38.5" cy="547.5" width="77.01" height="15"></v:textrect>		<rect x="0" y="540" width="77" height="15" class="st17"></rect>		<text x="6.2" y="551.7" class="st13" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>gunyah.ko</text>		</g>	<g id="shape1022-62" v:mid="1022" v:groupcontext="shape" transform="translate(435.2,-33.575)">		<title>Sheet.1022</title>		<desc>Open source</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="44.9" cy="546.075" width="89.8" height="17.85"></v:textrect>		<rect x="0" y="537.15" width="89.8" height="17.85" class="st17"></rect>		<text x="4.82" y="550.28" class="st13" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Open source</text>		</g></g>
</svg>

**그림: Qualcomm 가상화 솔루션**

Type 1 하이퍼바이저에 대한 자세한 내용은 [gunyah-hypervisor](https://github.com/quic/gunyah-hypervisor) 를 참조하세요.

### 게스트 VM 빌드 지원

게스트 VM 커널 및 initrd 이미지를 구성하려면 다음 절차를 사용하세요.

게스트 VM 커널을 컴파일하는 동안 게스트 커널 및 최소 `rootfs` 가 모두 빌드됩니다. `qcom_vm_defconfig` 는 게스트 커널을 컴파일하기 위한 기본 구성으로 사용됩니다. `qcom_vm_debug.config` 는 게스트 VM의 디버그 변형을 빌드합니다.

`croshm` 은 VMM 역할을 수행하며, `/dev/gunyah` 인터페이스를 통해 커널 내의 Gunyah VM 매니저와 상호 작용하여 VM을 만듭니다.

#### 게스트 VM 빌드

`crosvm` 지원에 대한 자세한 내용은 [보조 가상 머신 만들기](https://docs.qualcomm.com/bundle/publicresource/topics/80-70020-27/qualcomm_linux_software_components.html#create-secondary-virtual-machine) 를 참조하세요.

빌드 프로세스가 완료되면 특정 이미지가 생성됩니다. 이러한 이미지는 `<workspace>/build-qcom-wayland/tmp-glibc/deploy/images/<SoC>/qcom-console-image` 디렉토리에 저장됩니다.

게스트 VM을 컴파일하려면 다음 명령어를 실행합니다.

export SHELL=/bin/bash && MACHINE=SOC DISTRO=qcom-wayland source setup-environment
    
    bitbake qcom-console-image
    Copy to clipboard

#### 게스트 VM initrd 이미지

- 게스트 VM에 대해 `initramfs-ostree-image-<machine-name>.cpio.gz` 파일이 생성됩니다. 이 이미지에는 부트 프로세스 동안 사용된 initrd 이미지가 포함됩니다.
- `initramfs-ostree-image-<machine>.cpio.gz` 파일이 `build-qcom-wayland\tmp-qcom-guestvm-glibc\deploy\images\<machine-name>` 디렉토리에서 생성됩니다.
- 부팅된 기기에서는 이미지가 시스템 rootfs 내의 `/var/gunyah/initrd.img` 파일에 저장됩니다.

#### 게스트 VM 커널 이미지

- `svm-initramfs-qcom-image-<SoC>.cpio.gz` 이미지는 보조 가상 머신(SVM)용으로 생성되며, 이는 게스트 커널 이미지입니다.
- SVM 커널 이미지는 `build-qcom-wayland/tmp-glibc/deploy/images/<SoC>/linux-svm-kernel-qcom` 디렉토리에 생성됩니다.
- 부팅된 기기에서는 이미지 파일이 시스템 rootfs 내의 `/var/gunyah/Image` 파일에 있습니다.

`initrd.img` 와 SVM 커널 이미지는 모두 `system.img` 파일에 포함되어 있습니다. 마지막 `system.img` 파일은 다른 `<workspace>/build-qcom-wayland/tmp-glibc/deploy/images/<SoC>/qcom-console-image` 이미지가 있는 같은 디렉토리에 있습니다.

### 게스트 가상 머신 시작

`croshm` VMM과 Gunyah 하이퍼바이저를 사용하여 게스트 가상 머신을 시작합니다.

VM를 시작하려면 다음 명령어를 실행합니다.

# /usr/bin/crosvm --log-level=debug --no-syslog run --disable-sandbox --hypervisor \
                                              gunyah --protected-vm-without-firmware \
                                              --serial=type=stdout,hardware=virtio-console,console,stdin,num=1 \
                                              --serial=type=stdout,hardware=serial,earlycon,num=1 \
                                              --initrd /var/gunyah/initrd.img --no-balloon --no-rng \
                                              --params "rw root=/dev/ram earlyprintk=serial panic=0" \
                                              /var/gunyah/Image
    Copy to clipboard

다음은 게스트 VM을 시작하기 위한 `croshm` 명령어에 지원되는 매개변수입니다.

표: 지원되는 매개변수

| 매개변수 | 설명 |
| --- | --- |
| /usr/bin/crosvm<br>    Copy to clipboard | `crosvm` 바이너리의 경로를 보여줍니다. |
| --log-level=debug<br>    Copy to clipboard | `croshm` 을 실행하는 동안 로깅 수준을 디버그로 설정합니다. |
| --no-syslog<br>    Copy to clipboard | syslog를 비활성화합니다. |
| --disable-sandbox<br>    Copy to clipboard | 샌드박싱을 비활성화합니다. |
| --hypervisor gunyah<br>    Copy to clipboard | 사용할 하이퍼바이저를 지정합니다(이 경우 `gunyah`). |
| --protected-vm-without-firmware<br>    Copy to clipboard | VM이 보호되어 있고 펌웨어가 필요하지 않음을 나타냅니다. |
| --serial=...<br>    Copy to clipboard | 입출력을 위한 시리얼 기기를 구성합니다. |
| --initrd /var/gunyah/initrd.img<br>    Copy to clipboard | 초기 RAM 디스크(initrd) 이미지를 지정합니다. |
| --no-balloon<br>    Copy to clipboard | 메모리 벌루닝 비활성화 |
| --no-rng<br>    Copy to clipboard | 게스트 OS의 엔트로피 풀을 시드하는 데 사용되는 엔트로피 소스를 비활성화합니다. |
| --params "..."<br>    Copy to clipboard | 커널 명령줄 옵션을 지정합니다. |
| /var/gunyah/Image<br>    Copy to clipboard | 커널 이미지의 경로를 지정합니다. |

#### VM 및 부팅 로그 보기

다음 샘플 출력은 VM 로그를 보여줍니다.

bash-5.1# cat /proc/cpuinfo
    processor       : 0
    BogoMIPS        : 38.40
    Features        : fp asimd evtstrm aes pmull sha1 crc32 atomics cpuid asimdrdm dcpop asimddp
    CPU implementer : 0x00
    CPU architecture: 8
    CPU variant     : 0x0
    CPU part        : 0x048
    CPU revision    : 0
    
    bash-5.1# cat /proc/meminfo
    MemTotal:         161656 kB
    MemFree:          124940 kB
    MemAvailable:     124032 kB
    Buffers:               0 kB
    Cached:            19816 kB
    SwapCached:            0 kB
    Active:               12 kB
    Copy to clipboard

다음 코드 조각은 부팅 로그를 보여줍니다.

[2022-04-28T17:43:03.290477745+00:00 DEBUG crosvm::crosvm::sys::linux] creating hypervisor: Gunyah { device: None }
    [    0.000000] Booting Linux on physical CPU 0x0000000000 [0x000f0480]
    [    0.000000] Linux version 6.6.0 (oe-user@oe-host) (aarch64-qcom-linux-gcc (GCC) 11.4.0, GNU ld (GNU Binutils) 2.38.20220708) #1 SMP PREEMPT Wed Feb  7 04:56:59 UTC 2024
    [    0.000000] KASLR enabled
    [    0.000000] random: crng init done
    [    0.000000] Machine model: linux,dummy-virt
    [    0.000000] earlycon: uart8250 at MMIO 0x00000000000003f8 (options '')
    [    0.000000] printk: bootconsole [uart8250] enabled
    [    0.000000] efi: UEFI not found.
    [    0.000000] software IO TLB: Reserved memory: created restricted DMA pool at 0x0000000090000000, size 64 MiB
    [    0.000000] OF: reserved mem: initialized node restricted_dma_reserved@90000000, compatible id restricted-dma-pool
    [    0.000000] OF: reserved mem: 0x0000000090000000..0x0000000093ffffff (65536 KiB) map non-reusable restricted_dma_reserved@90000000
    [    0.000000] NUMA: No NUMA configuration found
    [    0.000000] NUMA: Faking a node at [mem 0x0000000080000000-0x0000000093ffffff]
    [    0.000000] NUMA: NODE_DATA [mem 0x8ff509c0-0x8ff52fff]
    [    0.000000] Zone ranges:
    [    0.000000]   DMA      [mem 0x0000000080000000-0x0000000093ffffff]
    [    0.000000]   DMA32    empty
    [    0.000000]   Normal   empty
    [    0.000000] Movable zone start for each node
    [    0.000000] Early memory node ranges
    [    0.000000]   node   0: [mem 0x0000000080000000-0x0000000093ffffff]
    [    0.000000] Initmem setup node 0 [mem 0x0000000080000000-0x0000000093ffffff]
    [    0.000000] On node 0, zone DMA: 16384 pages in unavailable ranges
    [    0.000000] cma: Reserved 32 MiB at 0x000000008d600000 on node -1
    [    0.000000] psci: probing for conduit method from DT.
    [    0.000000] psci: PSCIv1.1 detected in firmware.
    [    0.000000] psci: Using standard PSCI v0.2 function IDs
    [    0.000000] psci: MIGRATE_INFO_TYPE not supported.
    [    0.000000] psci: SMC Calling Convention v1.3
    [    0.000000] percpu: Embedded 31 pages/cpu s86568 r8192 d32216 u126976
    [    0.000000] Detected PIPT I-cache on CPU0
    [    0.000000] CPU features: detected: GIC system register CPU interface
    [    0.000000] CPU features: detected: Spectre-v4
    [    0.000000] CPU features: kernel page table isolation forced ON by KASLR
    [    0.000000] CPU features: detected: Kernel page table isolation (KPTI)
    [    0.000000] alternatives: applying boot alternatives
    [    0.000000] Kernel command line: panic=-1 console=hvc0 earlycon=uart8250,mmio,0x3f8 rw root=/dev/ram earlyprintk=serial panic=0
    [    0.000000] Unknown kernel command line parameters "earlyprintk=serial", will be passed to user space.
    [    0.000000] Dentry cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
    [    0.000000] Inode-cache hash table entries: 32768 (order: 6, 262144 bytes, linear)
    [    0.000000] Fallback order for Node 0: 0
    [    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 80640
    [    0.000000] Policy zone: DMA
    [    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
    [    0.000000] software IO TLB: area num 1.
    [    0.000000] software IO TLB: mapped [mem 0x0000000089600000-0x000000008d600000] (64MB)
    [    0.000000] Memory: 116344K/327680K available (14528K kernel code, 3938K rwdata, 7112K rodata, 6080K init, 571K bss, 178568K reserved, 32768K cma-reserved)
    [    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
    [    0.000000] trace event string verifier disabled
    [    0.000000] rcu: Preemptible hierarchical RCU implementation.
    [    0.000000] rcu:     RCU event tracing is enabled.
    [    0.000000] rcu:     RCU restricting CPUs from NR_CPUS=256 to nr_cpu_ids=1.
    [    0.000000]  Trampoline variant of Tasks RCU enabled.
    [    0.000000]  Tracing variant of Tasks RCU enabled.
    [    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
    [    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1
    [    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
    [    0.000000] GICv3: 988 SPIs implemented
    [    0.000000] GICv3: 0 Extended SPIs implemented
    [    0.000000] Root IRQ handler: gic_handle_irq
    [    0.000000] GICv3: GICv3 features: 16 PPIs
    [    0.000000] GICv3: CPU0: found redistributor 0 region 0:0x000000003ffd0000
    [    0.000000] rcu: srcu_init: Setting srcu_struct sizes based on contention.
    [    0.000000] arch_timer: cp15 timer(s) running at 19.20MHz (virt).
    [    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x46d987e47, max_idle_ns: 440795202767 ns
    [    0.000000] sched_clock: 56 bits at 19MHz, resolution 52ns, wraps every 4398046511078ns
    [    0.002616] arm-pv: using stolen time PV
    [    0.003945] Console: colour dummy device 80x25
    [    0.005300] Calibrating delay loop (skipped), value calculated using timer frequency.. 38.40 BogoMIPS (lpj=76800)
    [    0.008475] pid_max: default: 32768 minimum: 301
    [    0.009923] LSM: initializing lsm=capability,selinux,integrity
    [    0.011702] SELinux:  Initializing.
    [    0.012884] Mount-cache hash table entries: 1024 (order: 1, 8192 bytes, linear)
    [    0.015180] Mountpoint-cache hash table entries: 1024 (order: 1, 8192 bytes, linear)
    [    0.017809] cacheinfo: Unable to detect cache hierarchy for CPU 0
    [    0.019820] RCU Tasks: Setting shift to 0 and lim to 1 rcu_task_cb_adjust=1.
    [    0.022107] RCU Tasks Trace: Setting shift to 0 and lim to 1 rcu_task_cb_adjust=1.
    [    0.024472] rcu: Hierarchical SRCU implementation.
    [    0.025891] rcu:     Max phase no-delay instances is 1000.
    [    0.027767] EFI services will not be available.
    [    0.029190] smp: Bringing up secondary CPUs ...
    [    0.030713] smp: Brought up 1 node, 1 CPU
    [    0.032002] SMP: Total of 1 processors activated.
    [    0.033471] CPU features: detected: 32-bit EL0 Support
    [    0.035048] CPU features: detected: Data cache clean to the PoU not required for I/D coherence
    [    0.037742] CPU features: detected: Common not Private translations
    [    0.039678] CPU features: detected: CRC32 instructions
    [    0.041275] CPU features: detected: LSE atomic instructions
    [    0.043105] CPU features: detected: Privileged Access Never
    [    0.044891] CPU: All CPU(s) started at EL1
    [    0.046161] alternatives: applying system-wide alternatives
    [    0.050071] devtmpfs: initialized
    [    0.051500] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
    [    0.054767] futex hash table entries: 256 (order: 2, 16384 bytes, linear)
    [    0.057122] pinctrl core: initialized pinctrl subsystem
    [    0.058872] DMI not present or invalid.
    [    0.060334] NET: Registered PF_NETLINK/PF_ROUTE protocol family
    [    0.062534] DMA: preallocated 128 KiB GFP_KERNEL pool for atomic allocations
    [    0.064964] DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA pool for atomic allocations
    [    0.067353] DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations
    [    0.069943] audit: initializing netlink subsys (disabled)
    [    0.071632] audit: type=2000 audit(0.056:1): state=initialized audit_enabled=0 res=1
    [    0.074141] thermal_sys: Registered thermal governor 'step_wise'
    [    0.074143] thermal_sys: Registered thermal governor 'power_allocator'
    [    0.076118] cpuidle: using governor menu
    [    0.079536] hw-breakpoint: found 6 breakpoint and 4 watchpoint registers.
    [    0.081693] ASID allocator initialised with 32768 entries
    [    0.083662] Serial: AMBA PL011 UART driver
    [    0.085582] Modules: 2G module region forced by RANDOMIZE_MODULE_REGION_FULL
    [    0.087812] Modules: 0 pages in range for non-PLT usage
    [    0.087813] Modules: 516176 pages in range for PLT usage
    [    0.091914] HugeTLB: registered 1.00 GiB page size, pre-allocated 0 pages
    [    0.099837] HugeTLB: 0 KiB vmemmap can be freed for a 1.00 GiB page
    [    0.101815] HugeTLB: registered 32.0 MiB page size, pre-allocated 0 pages
    [    0.107895] HugeTLB: 0 KiB vmemmap can be freed for a 32.0 MiB page
    [    0.109875] HugeTLB: registered 2.00 MiB page size, pre-allocated 0 pages
    [    0.116064] HugeTLB: 0 KiB vmemmap can be freed for a 2.00 MiB page
    [    0.118084] HugeTLB: registered 64.0 KiB page size, pre-allocated 0 pages
    [    0.124190] HugeTLB: 0 KiB vmemmap can be freed for a 64.0 KiB page
    [    0.128423] ACPI: Interpreter disabled.
    [    0.132206] iommu: Default domain type: Translated
    [    0.133734] iommu: DMA domain TLB invalidation policy: strict mode
    [    0.135749] SCSI subsystem initialized
    [    0.140957] usbcore: registered new interface driver usbfs
    [    0.142744] usbcore: registered new interface driver hub
    [    0.144353] usbcore: registered new device driver usb
    [    0.149976] pps_core: LinuxPPS API ver. 1 registered
    [    0.151488] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
    [    0.162194] PTP clock support registered
    [    0.163436] EDAC MC: Ver: 3.0.0
    [    0.164532] scmi_core: SCMI protocol bus registered
    [    0.166176] FPGA manager framework
    [    0.171350] Advanced Linux Sound Architecture Driver Initialized.
    [    0.173213] vgaarb: loaded
    [    0.174176] clocksource: Switched to clocksource arch_sys_counter
    [    0.235827] VFS: Disk quotas dquot_6.6.0
    [    0.237108] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
    [    0.239428] pnp: PnP ACPI: disabled
    [    0.241483] NET: Registered PF_INET protocol family
    [    0.243293] IP idents hash table entries: 8192 (order: 4, 65536 bytes, linear)
    [    0.245817] tcp_listen_portaddr_hash hash table entries: 256 (order: 0, 4096 bytes, linear)
    [    0.248604] Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear)
    [    0.251034] TCP established hash table entries: 4096 (order: 3, 32768 bytes, linear)
    [    0.253323] TCP bind hash table entries: 4096 (order: 5, 131072 bytes, linear)
    [    0.255664] TCP: Hash tables configured (established 4096 bind 4096)
    [    0.257584] UDP hash table entries: 256 (order: 1, 8192 bytes, linear)
    [    0.259650] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes, linear)
    [    0.261768] NET: Registered PF_UNIX/PF_LOCAL protocol family
    [    0.263829] RPC: Registered named UNIX socket transport module.
    [    0.265673] RPC: Registered udp transport module.
    [    0.267186] RPC: Registered tcp transport module.
    [    0.268641] RPC: Registered tcp-with-tls transport module.
    [    0.270380] RPC: Registered tcp NFSv4.1 backchannel transport module.
    [    0.272421] PCI: CLS 0 bytes, default 64
    [    0.273680] Unpacking initramfs...
    [    0.278241] kvm [1]: HYP mode not available
    [    0.279783] Initialise system trusted keyrings
    [    0.286209] workingset: timestamp_bits=42 max_order=16 bucket_order=0
    [    0.288474] squashfs: version 4.0 (2009/01/31) Phillip Lougher
    [    0.294313] NFS: Registering the id_resolver key type
    [    0.295881] Key type id_resolver registered
    [    0.297197] Key type id_legacy registered
    [    0.302225] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
    [    0.304407] nfs4flexfilelayout_init: NFSv4 Flexfile Layout Driver Registering...
    [    0.310289] 9p: Installing v9fs 9p2000 file system support
    [    0.320607] NET: Registered PF_ALG protocol family
    [    0.322022] Key type asymmetric registered
    [    0.330205] Asymmetric key parser 'x509' registered
    [    0.331833] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 245)
    [    0.334140] io scheduler mq-deadline registered
    [    0.342201] io scheduler kyber registered
    [    0.343459] io scheduler bfq registered
    [    0.353648] pci-host-generic 10000.pci: assigned reserved memory node restricted_dma_reserved@90000000
    [    0.362220] pci-host-generic 10000.pci: host bridge /pci ranges:
    [    0.364055] pci-host-generic 10000.pci:      MEM 0x0002000000..0x0003ffffff -> 0x0002000000
    [    0.370193] pci-host-generic 10000.pci:      MEM 0x0094800000..0xffffffffff -> 0x0094800000
    [    0.372927] pci-host-generic 10000.pci: Memory resource size exceeds max for 32 bits
    [    0.382221] PCI: OF: PROBE_ONLY enabled
    [    0.383535] pci-host-generic 10000.pci: ECAM at [mem 0x00010000-0x0100ffff] for [bus 00]
    [    0.386134] pci-host-generic 10000.pci: PCI host bridge to bus 0000:00
    [    0.394279] pci_bus 0000:00: root bus resource [bus 00]
    [    0.395912] pci_bus 0000:00: root bus resource [mem 0x02000000-0x03ffffff]
    [    0.397972] pci_bus 0000:00: root bus resource [mem 0x94800000-0xffffffffff]
    [    0.406329] pci 0000:00:00.0: [8086:1237] type 00 class 0x060000
    [    0.409065] pci 0000:00:01.0: [1af4:1043] type 00 class 0x00ff00
    [    0.419597] pci 0000:00:01.0: reg 0x10: [mem 0x02000000-0x02007fff]
    [    0.425686] Freeing initrd memory: 6464K
    [    0.428105] pci 0000:00:01.0: PME# supported from D0 D3hot D3cold
    [    0.430575] pci 0000:00:02.0: [1b36:0011] type 00 class 0xffff00
    [    0.432661] pci 0000:00:02.0: reg 0x10: [mem 0x02008000-0x0200800f]
    [    0.436076] pci 0000:00:00.0: Limiting direct PCI/PCI transfers
    [    0.438471] virtio-pci 0000:00:01.0: assigned reserved memory node restricted_dma_reserved@90000000
    [    0.443123] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
    [    0.445534] 2e8.U6_16550A: ttyS0 at MMIO 0x2e8 (irq = 14, base_baud = 115200) is a 16550A
    [    0.448422] 2f8.U6_16550A: ttyS1 at MMIO 0x2f8 (irq = 14, base_baud = 115200) is a 16550A
    [    0.451159] 3e8.U6_16550A: ttyS2 at MMIO 0x3e8 (irq = 15, base_baud = 115200) is a 16550A
    [    0.453983] 3f8.U6_16550A: ttyS3 at MMIO 0x3f8 (irq = 15, base_baud = 115200) is a 16550A
    [    0.456935] msm_serial: driver initialized
    [    0.460508] printk: console [hvc0] enabled
    [    0.461772] printk: bootconsole [uart8250] disabled
    [    0.475305] loop: module loaded
    [    0.475957] megasas: 07.725.01.00-rc1
    [    0.476374] tun: Universal TUN/TAP device driver, 1.6
    [    0.477187] VFIO - User Level meta-driver version: 0.3
    [    0.477691] usbcore: registered new interface driver usb-storage
    [    0.478075] i2c_dev: i2c /dev entries driver
    [    0.478575] sdhci: Secure Digital Host Controller Interface driver
    [    0.479311] sdhci: Copyright(c) Pierre Ossman
    [    0.479612] sdhci-pltfm: SDHCI platform and OF driver helper
    [    0.479932] ledtrig-cpu: registered to indicate activity on CPUs
    [    0.480343] SMCCC: SOC_ID: ARCH_SOC_ID not implemented, skipping ....
    [    0.480864] usbcore: registered new interface driver usbhid
    [    0.481329] usbhid: USB HID core driver
    [    0.482042] NET: Registered PF_PACKET protocol family
    [    0.482342] 9pnet: Installing 9P2000 support
    [    0.482635] Key type dns_resolver registered
    [    0.484383] registered taskstats version 1
    [    0.484775] Loading compiled-in X.509 certificates
    [    0.486896] page_owner is disabled
    [    0.487629] Key type .fscrypt registered
    [    0.487943] Key type fscrypt-provisioning registered
    [    0.488391] clk: Disabling unused clocks
    [    0.488759] ALSA device list:
    [    0.489050]   No soundcards found.
    [    0.490311] Freeing unused kernel memory: 6080K
    [    0.498264] Run /init as init process
    Starting version 250.5+
    bash: cannot set terminal process group (-1): Inappropriate ioctl for device
    bash: no job control in this shell
    bash-5.1#
    Copy to clipboard

#### CPU 2개와 기본 RAM이 포함된 VM 시작

CPU 2개가 포함된 게스트 VM을 시작하려면 `--cpus num-cores=2` 매개변수를 사용합니다.

#/usr/bin/crosvm --log-level=debug --no-syslog run --disable-sandbox --hypervisor \
                                              gunyah --protected-vm-without-firmware \
                                              --cpus num-cores=2 \
                                              --serial=type=stdout,hardware=virtio-console,console,stdin,num=1 \
                                              --serial=type=stdout,hardware=serial,earlycon,num=1 \
                                              --initrd /var/gunyah/initrd.img --no-balloon --no-rng \
                                              --params "rw root=/dev/ram earlyprintk=serial panic=0" \
                                              /var/gunyah/Image
    Copy to clipboard

다음 코드 조각은 VM 로그를 보여줍니다.

bash-5.1# cat /proc/cpuinfo
    processor       : 0
    BogoMIPS        : 38.40
    Features        : fp asimd evtstrm aes pmull sha1 crc32 atomics cpuid asimdrdm dcpop asimddp
    CPU implementer : 0x00
    CPU architecture: 8
    CPU variant     : 0x0
    CPU part        : 0x048
    CPU revision    : 0
    
    processor       : 1
    BogoMIPS        : 38.40
    Features        : fp asimd evtstrm aes pmull sha1 crc32 atomics cpuid asimdrdm dcpop asimddp
    CPU implementer : 0x00
    CPU architecture: 8
    CPU variant     : 0x0
    CPU part        : 0x048
    CPU revision    : 0
    
    bash-5.1# cat /proc/meminfo
    MemTotal:         161656 kB
    MemFree:          124940 kB
    MemAvailable:     124032 kB
    Buffers:               0 kB
    Cached:            19816 kB
    SwapCached:            0 kB
    Active:               12 kB
    Copy to clipboard

#### CPU 2개와 512MB RAM이 포함된 VM 시작

CPU 2개와 512MB RAM이 포함된 게스트 VM을 시작하려면 `--cpus num-cores=2` 및 `--mem size=512` 매개변수를 사용합니다.

#/usr/bin/crosvm --log-level=debug --no-syslog run --disable-sandbox --hypervisor \
                                              gunyah --protected-vm-without-firmware \
                                              --cpus num-cores=2 --mem size=512      \
                                              --serial=type=stdout,hardware=virtio-console,console,stdin,num=1 \
                                              --serial=type=stdout,hardware=serial,earlycon,num=1              \
                                              --initrd /var/gunyah/initrd.img --no-balloon --no-rng            \
                                              --params "rw root=/dev/ram earlyprintk=serial panic=0"           \
                                              /var/gunyah/Image
    Copy to clipboard

다음 코드 조각은 VM 로그를 보여줍니다.

bash-5.1# cat /proc/cpuinfo
    processor       : 0
    BogoMIPS        : 38.40
    Features        : fp asimd evtstrm aes pmull sha1 crc32 atomics cpuid asimdrdm dcpop asimddp
    CPU implementer : 0x00
    CPU architecture: 8
    CPU variant     : 0x0
    CPU part        : 0x048
    CPU revision    : 0
    
    processor       : 1
    BogoMIPS        : 38.40
    Features        : fp asimd evtstrm aes pmull sha1 crc32 atomics cpuid asimdrdm dcpop asimddp
    CPU implementer : 0x00
    CPU architecture: 8
    CPU variant     : 0x0
    CPU part        : 0x048
    CPU revision    : 0
    
    bash-5.1# cat /proc/meminfo
    MemTotal:         418304 kB
    MemFree:          378356 kB
    MemAvailable:     376048 kB
    Buffers:               0 kB
    Cached:            20308 kB
    SwapCached:            0 kB
    Active:                0 kB
    Copy to clipboard

#### 블록 기기가 포함된 VM 시작

VM를 시작하려면 다음 명령어를 실행합니다.

#/usr/bin/crosvm --log-level=debug --no-syslog run --disable-sandbox --hypervisor \
                                              gunyah --protected-vm-without-firmware \
                                              --block disk.img \
                                              --cpus num-cores=2 --mem size=256      \
                                              --serial=type=stdout,hardware=virtio-console,console,stdin,num=1 \
                                              --serial=type=stdout,hardware=serial,earlycon,num=1              \
                                              --initrd /var/gunyah/initrd.img --no-balloon --no-rng            \
                                              --params "rw root=/dev/ram earlyprintk=serial panic=0"           \
                                              /var/gunyah/Image
    Copy to clipboard

- `--block` 플래그를 사용하여 블록 기기 이름을 지정합니다(이 경우 disk.img).
- 이 플래그는 게스트 VM에서 `/dev/vda, /dev/vdb` 및 `/dev/vd*` 노드를 생성합니다.

bash-5.1# ls -al /dev/block/
    total 0
    drwxr-xr-x    2 root     root           220 Jan  1 00:00 .
    drwxr-xr-x    9 root     root          2980 Jan  1 00:00 ..
    lrwxrwxrwx    1 root     root             6 Jan  1 00:00 254:0 -> ../vda
    lrwxrwxrwx    1 root     root             8 Jan  1 00:00 7:0 -> ../loop0
    lrwxrwxrwx    1 root     root             8 Jan  1 00:00 7:1 -> ../loop1
    Copy to clipboard

게스트 VM에서 기기를 마운트하려면 다음 명령어를 실행합니다. `mount -t ext4 /dev/vda /mount-point`

bash-5.1# mkdir /data
    bash-5.1# mount -t ext4 /dev/vda /data
    [  112.311376] EXT4-fs (vda): mounted filesystem 4b577765-65ad-4fd8-910c-0eac437d8afb r/w with ordered data mode. Quota mode: none.
    Copy to clipboard

### KVM 개요

커널 기반 가상 머신(KVM)은 Linux 커널에 통합된 오픈 소스 가상화 모듈입니다. 이러한 통합 덕분에 KVM은 하이퍼바이저 역할을 할 수 있습니다. KVM은 게스트 운영 체제의 하드웨어 지원 가상화를 지원하는 데 도움이 됩니다.

참고

KVM은 Dragonwing™ IQ-8275 및 Dragonwing IQ-9075 SoC에서만 지원됩니다.

**그림: KVM/QEMU 가상화에 대한 전반적인 개요**

다음은 Arm CPU 기반 시스템에서 KVM 하이퍼바이저를 활성화하기 위한 요구 조건입니다.

- 부트 로더가 예외 수준 2(EL2)에서 Linux 커널을 시작
- 커널 구성에서 `CONFIG_KVM` 이 활성화된 상태

기기에서 KVM을 사용할 수 있는지 확인하려면 다음 명령어를 실행하여 `/dev/kvm` 이 있는지 확인합니다.

ls -l /dev/kvm
    Copy to clipboard

Qualcomm Linux 기본 부팅 흐름의 경우, Linux 커널은 EL1에서 시작되며 Gunyah가 하이퍼바이저 역할을 맡습니다. EL2에서 Linux 커널을 부팅하여 KVM 하이퍼바이저를 활성화하는 방법에 대한 지침은 [UEFI](https://docs.qualcomm.com/bundle/publicresource/topics/80-70020-4/boot-developer-touchpoints.html#uefi) 를 참조하세요.

KVM을 활성화할 경우 다음 사항을 고려합니다.

- Arm(v8.1) 이상의 명령어 세트를 지원하는 모든 Qualcomm Linux SoC에서 가상 호스트 확장(VHE)은 기본적으로 활성화되어 있습니다. 이 구성을 사용하면 약간의 수정을 통해 전체 Linux 커널을 EL2에서 실행할 수 있습니다. 게스트 OS 커널 및 사용자 공간은 EL1 및 EL0에서 실행됩니다. VHE를 사용할 경우 게스트와 호스트 커널이 서로 다른 예외 수준에서 실행되므로, 게스트와 호스트 간의 전환에 따른 페널티가 줄어듭니다.
- Linux 커널은 액세스 가능한 모든 비보안 메모리를 관리합니다. Linux 커널로부터 특별히 격리되어야 하는, 보호된 사용 사례는 지원하지 않습니다. Gunyah 하이퍼바이저는 기본 부팅 흐름에서 Linux 커널의 S2 페이지 테이블을 제어합니다.
- 주변 이미지 로딩(PIL) 서비스는 지원되지 않습니다. 따라서 aDSP, cDSP, 신경망 신호 처리기(NSP)가 필요한 애플리케이션은 KVM이 활성화된 상태에서 작동하지 않습니다.
- KVM용 PSCI(Power State Coordination Interface)는 Linux 커널에서 지원됩니다. PSCI는 CPU 핫플러그 및 저전력 모드(LPM)가 KVM과 올바르게 작동하도록 보장합니다.

#### 가상 머신 매니저

QEMU(Quick Emulator)는 가상화를 위한 가상 머신 매니저(VMM)로 사용됩니다. Libvirt는 QEMU와 상호 작용하여 가상 머신을 시작, 중지, 관리하는 관리 계층 역할을 수행합니다.

##### QEMU

KVM과 함께 QEMU를 VMM으로 사용하여 가상 머신을 네이티브 수준의 성능으로 실행할 수 있습니다. QEMU는 고성능 I/O 작업을 제공하는 에뮬레이트된 기기(예: VirtIO 기기)를 지원하고, VM에서 USB 및 PCI(Peripheral Component Interconnect) 기기에 액세스할 수 있도록 보장합니다. QEMU 프로세스 및 해당 스레드는 단일 VM을 관리합니다. VM을 만들려면 QEMU를 직접 호출합니다. 자세한 내용은 [QEMU’s](https://qemu-project.gitlab.io/qemu/index.html) 를 참조하세요.

##### Libvirt

Libvirt는 API 라이브러리, 데몬(libvirtd), 명령줄 유틸리티(virsh) 등이 포함된 도구 모음으로, VM을 관리하는 데 사용됩니다. virsh 유틸리티는 여러 VM을 관리하는 데 유용합니다. 자세한 내용은 [virsh](https://www.libvirt.org/manpages/virsh.html) 를 참조하세요.

#### 게스트 VM 시작

ARM64 기반 VM을 시작하려면 내부적으로 libvirt와 연동하는 QEMU 또는 virsh 명령어를 사용합니다. 이 명령어를 사용하면 VM의 CPU, 메모리, 스토리지를 구성할 수 있습니다. 가상 CPU의 수와 VM에 할당되는 메모리의 양도 지정하세요. 또한 VM은 ramdisk(initrd) 및 `.ext4` 루트 파일 시스템으로 부팅할 수 있습니다.

참고

게스트를 시작하기 전에 게스트 커널 이미지(`Image`), 루트 파일 시스템 CPIO(`rootfs.cpio.gz`), 루트 파일 시스템 이미지(`rootfs.ext4`)가 호스트 파일 시스템의 `/mnt/overlay/guest` 디렉토리에 존재하는지 확인하세요. 이러한 파일 경로와 형식은 참고용으로 제공되는 예시입니다.

##### QEMU

다양한 구성을 갖춘 VM을 생성하려면 다음 명령어를 실행하세요.

###### ramdisk로 부팅

qemu-system-aarch64 \
       -M virt -m 2G \
       -kernel /mnt/overlay/guest/Image \
       -initrd /mnt/overlay/guest/rootfs.cpio.gz \
       -cpu host --enable-kvm -smp 4 -nographic
    Copy to clipboard

###### rootfs 이미지로 부팅

qemu-system-aarch64 \
       -M virt -m 2G \
       -kernel /mnt/overlay/guest/Image \
       -drive file=/mnt/overlay/guest/rootfs.ext4,if=virtio,format=raw \
       -append "root=/dev/vda" \
       -cpu host --enable-kvm -smp 4 -nographic
    Copy to clipboard

##### Libvirt

Libvirt를 활용하면 QEMU 및 KVM을 사용하여 VM을 만들고, 상호 작용하고, 관리할 수 있습니다.

###### virsh를 사용하여 VM 관리

virsh는 VM을 만들고, 제어하고, 모니터링하는 데 사용하는 다양한 명령어를 제공합니다.

VM 관리에 사용되는 virsh 명령어는 다음과 같습니다.

# Define a new VM domain called initrd_simple
    virsh define /mnt/overlay/libvirt_initrd_simple.xml
    Copy to clipboard

# List all domains and check the state of initrd_simple, it is not started yet
    virsh list --all
    Copy to clipboard

# start the initrd_simple VM
    virsh start initrd_simple
    Copy to clipboard

# connect to console
    virsh console initrd_simple
    Copy to clipboard

# Disconnect from console by pressing (Ctrl + ]) key combination
    Copy to clipboard

# shutdown the VM
    Copy to clipboard

virsh shutdown initrd_simple
    Copy to clipboard

# Undefine the VM if there is no intention to restart/resue it
    virsh undefine initrd_simple
    Copy to clipboard

###### ramdisk로 부팅

아래의 XML 콘텐츠를 호스트의 `/mnt/overlay/guest/libvirt_initrd_simple.xml` 에 복사합니다.

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
      <name>simple_initrd</name>
       <!-- specify VM memory in KB  -->
      <memory unit='KiB'>2097152</memory>
       <!-- 4 vCPUs affined to all host CPUs  -->
      <vcpu placement='static'>4</vcpu>
      <resource>
        <partition>/machine</partition>
      </resource>
      <os>
        <type arch='aarch64' machine='virt-6.2'>hvm</type>
        <!-- specify kernel/initrd file  -->
        <kernel>/mnt/overlay/guest/Image</kernel>
        <initrd>/mnt/overlay/guest/rootfs.cpio.gz</initrd>
        <boot dev='hd'/>
      </os>
      <features>
        <gic version='3'/>
      </features>
      <cpu mode='host-passthrough' check='none'/>
      <devices>
        <!-- Guest console will be available over pty on the host -->
        <console type='pty'>
        </console>
      </devices>
    </domain>
    Copy to clipboard

###### rootfs 이미지로 부팅

다음 XML 파일을 `/mnt/overlay/guest/libvirt_rootfs_simple.xml` 파일의 호스트 파일 시스템에 복사합니다. VM 관리 명령어를 `initrd_simple` 대신 `rootfs_simple` 을 VM 도메인/이름으로 사용하세요.

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
      <name>simple_rootfs</name>
      <memory unit='KiB'>2097152</memory>
      <vcpu placement='static'>4</vcpu>
      <resource>
        <partition>/machine</partition>
      </resource>
      <os>
        <type arch='aarch64' machine='virt-6.2'>hvm</type>
        <kernel>/mnt/overlay/guest/Image</kernel>
        <cmdline>root=/dev/vda</cmdline>
        <boot dev='hd'/>
      </os>
      <features>
        <gic version='3'/>
      </features>
      <cpu mode='host-passthrough' check='none'/>
      <devices>
        <console type='pty'>
        </console>
        <disk type="file" device="disk">
          <driver name="qemu" type="raw"/>
          <!-- specify rootfs image file  -->
          <source file="/mnt/overlay/guest/rootfs.ext4"/>
          <target dev="vda" bus="virtio"/>
        </disk>
      </devices>
    </domain>
    Copy to clipboard

> 
> 
>

#### Virtio 프레임워크

Virtio는 반가상화된 하이퍼바이저 환경에서 기기를 추상화합니다. 이는 반가상화된(paravirt) 기기와 상호 작용할 수 있는 I/O 반가상화(paravirtualization) 프레임워크를 제공합니다. 가상 머신 모니터(VMM) 또는 하이퍼바이저(HYP)는 가상 머신(VM)에 노출되는 대부분의 기기를 VirtIO를 사용하여 에뮬레이트합니다.

#### 주요 기능

가상 네트워크의 주요 기능은 다음과 같습니다.

- 반가상화 및 일반 가상화

> 
> 
> - 일반 가상화: 일반 가상 환경에서는 게스트 VM이 하이퍼바이저를 인식하지 못하고, 수정되지 않은 상태로 실행됩니다. 그러나 일반 가상화는 기기 에뮬레이션 때문에 더 많은 오버헤드 비용이 발생합니다.
>     - 반가상화: 반가상화 환경에서는 VM이 하이퍼바이저를 인식하며 OS 수정이 필요합니다. 반가상화를 사용하면 게스트와 호스트 간의 효율적인 통신이 가능합니다.
- Virtio 구조

> 
> 
> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
> <!-- Generated by Microsoft Visio, SVG Export virtio_arch (2).svg Page-1 -->
> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="4.23958in" height="5.59375in" viewbox="0 0 305.25 402.75" xml:space="preserve" color-interpolation-filters="sRGB" class="st17" aria-label="../_images/virtio_arch.svg"><v:documentproperties v:langid="1033" v:viewmarkup="false">	<v:userdefs>		<v:ud v:nameu="msvNoAutoConnect" v:val="VT0(1):26"></v:ud>	</v:userdefs></v:documentproperties>
> <style>.svg-4 .st1 { fill: #fafafa; stroke: #d2d7e1; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.5 }
> .svg-4 .st2 { fill: #040a40; fill-opacity: 0; stroke: #000000; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.5 }
> .svg-4 .st3 { marker-end: url("#mrkr4-13"); marker-start: url("#mrkr4-11"); stroke: #000000; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.5 }
> .svg-4 .st4 { fill: #000000; fill-opacity: 1; stroke: #000000; stroke-opacity: 1; stroke-width: 0.37313432835821 }
> .svg-4 .st5 { fill: #7c8aa3; stroke: #007884; stroke-linecap: round; stroke-linejoin: round; stroke-opacity: 0; stroke-width: 0.24 }
> .svg-4 .st6 { fill: #007884; fill-opacity: 0; stroke: #000000; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.5 }
> .svg-4 .st7 { stroke: none; stroke-linecap: round; stroke-linejoin: round; stroke-width: 0.75 }
> .svg-4 .st8 { fill: #000000; font-family: Roboto Flex, Qualcomm-Next, sans-serif; font-size: 1.33333em }
> .svg-4 .st9 { fill: #ffffff; font-family: Roboto Flex, Qualcomm-Next, sans-serif; font-size: 1.33333em }
> .svg-4 .st10 { fill: #007884; stroke: #007884; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.5 }
> .svg-4 .st11 { fill: #040a40; stroke: #ffffff; stroke-linecap: round; stroke-linejoin: round; stroke-opacity: 0.32; stroke-width: 1.5 }
> .svg-4 .st12 { fill: #007884; stroke: #000000; stroke-opacity: 0; stroke-width: 2 }
> .svg-4 .st13 { fill: none; stroke: none; stroke-width: 0.25 }
> .svg-4 .st14 { fill: #000000; font-family: Roboto Flex, Qualcomm-Next, sans-serif; font-size: 0.75em }
> .svg-4 .st15 { fill: #040a40; stroke: #000000; stroke-opacity: 0; stroke-width: 2 }
> .svg-4 .st16 { fill: #7c8aa3; stroke: #000000; stroke-opacity: 0; stroke-width: 2 }
> .svg-4 .st17 { fill: none; fill-rule: evenodd; font-size: 12px; overflow: visible; stroke-linecap: square; stroke-miterlimit: 3 }</style>
> <defs id="Markers">	<g id="lend4">		<path d="M 2 1 L 0 0 L 2 -1 L 2 1 " style="stroke:none"></path>	</g>	<marker id="mrkr4-11" class="st4" v:arrowtype="4" v:arrowsize="2" v:setback="5.12" refx="5.12" orient="auto" markerunits="strokeWidth" overflow="visible">		<use xlink:href="#lend4" transform="scale(2.68) "></use>	</marker>	<marker id="mrkr4-13" class="st4" v:arrowtype="4" v:arrowsize="2" v:setback="5.36" refx="-5.36" orient="auto" markerunits="strokeWidth" overflow="visible">		<use xlink:href="#lend4" transform="scale(-2.68,-2.68) "></use>	</marker></defs><g v:mid="0" v:index="1" v:groupcontext="foregroundPage">	<title>Page-1</title>	<v:pageproperties v:drawingscale="1" v:pagescale="1" v:drawingunits="19" v:shadowoffsetx="9" v:shadowoffsety="-9"></v:pageproperties>	<g id="shape44-1" v:mid="44" v:groupcontext="shape" transform="translate(18.75,-18.75)">		<title>Rectangle.44</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="37.5" width="267.75" height="365.25" rx="2.88" ry="2.88" class="st1"></rect>	</g>	<g id="shape38-3" v:mid="38" v:groupcontext="shape" transform="translate(29.4375,-288.977)">		<title>Rectangle.38</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="317.792" width="247.5" height="84.9582" rx="2.88" ry="2.88" class="st2"></rect>	</g>	<g id="shape30-5" v:mid="30" v:groupcontext="shape" transform="translate(555.938,245.42) rotate(90)">		<title>Sheet.30</title>		<path d="M7.68 402.75 L8.04 402.75 L39.88 402.75" class="st3"></path>	</g>	<g id="shape29-14" v:mid="29" v:groupcontext="shape" transform="translate(555.938,113.773) rotate(90)">		<title>Sheet.29</title>		<path d="M7.68 402.75 L8.04 402.75 L39.8 402.75" class="st3"></path>	</g>	<g id="shape36-21" v:mid="36" v:groupcontext="shape" transform="translate(29.4375,-64.4107)">		<title>Rectangle.36</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="357.75" width="247.5" height="45" rx="2.88" ry="2.88" class="st5"></rect>	</g>	<g id="shape33-23" v:mid="33" v:groupcontext="shape" transform="translate(29.4375,-157.33)">		<title>Rectangle</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="317.792" width="247.5" height="84.9582" rx="2.88" ry="2.88" class="st6"></rect>	</g>	<g id="shape14-25" v:mid="14" v:groupcontext="shape" transform="translate(101.474,-342.391)">		<title>Sheet.14</title>		<desc>Guest OS</desc>		<v:textblock v:margins="rect(0,0,0,0)"></v:textblock>		<v:textrect cx="48.2514" cy="391.964" width="96.51" height="21.5726"></v:textrect>		<path d="M96.5 381.18 L0 381.18 L0 402.75 L96.5 402.75 L96.5 381.18" class="st7"></path>		<text x="15.19" y="396.76" class="st8" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Guest OS</text>		</g>	<g id="shape17-29" v:mid="17" v:groupcontext="shape" transform="translate(97.4616,-166.325)">		<title>Sheet.17</title>		<desc>Hypervisor</desc>		<v:textblock v:margins="rect(0,0,0,0)"></v:textblock>		<v:textrect cx="52.2634" cy="391.964" width="104.53" height="21.5726"></v:textrect>		<path d="M104.53 381.18 L0 381.18 L0 402.75 L104.53 402.75 L104.53 381.18" class="st7"></path>		<text x="14.13" y="396.76" class="st8" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Hypervisor</text>		</g>	<g id="shape18-33" v:mid="18" v:groupcontext="shape" transform="translate(102.049,-76.1243)">		<title>Sheet.18</title>		<desc>Hardware</desc>		<v:textblock v:margins="rect(0,0,0,0)"></v:textblock>		<v:textrect cx="47.6763" cy="391.964" width="95.36" height="21.5726"></v:textrect>		<path d="M95.35 381.18 L0 381.18 L0 402.75 L95.35 402.75 L95.35 381.18" class="st7"></path>		<text x="13.09" y="396.76" class="st9" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Hardware</text>		</g>	<g id="shape19-37" v:mid="19" v:groupcontext="shape" transform="translate(167.25,-254.641)">		<title>Sheet.19</title>		<desc>virtqueue</desc>		<v:textblock v:margins="rect(0,0,0,0)"></v:textblock>		<v:textrect cx="33.75" cy="391.964" width="67.5" height="21.5726"></v:textrect>		<path d="M67.5 381.18 L0 381.18 L0 402.75 L67.5 402.75 L67.5 381.18" class="st7"></path>		<text x="0.77" y="396.76" class="st8" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>virtqueue</text>		</g>	<g id="shape34-41" v:mid="34" v:groupcontext="shape" transform="translate(68.4438,-196.946)">		<title>Rectangle.34</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="368.359" width="162.562" height="34.3907" rx="2.88" ry="2.88" class="st10"></rect>	</g>	<g id="shape16-43" v:mid="16" v:groupcontext="shape" transform="translate(83.6308,-203.355)">		<title>Sheet.16</title>		<desc>Backend drivers</desc>		<v:textblock v:margins="rect(0,0,0,0)"></v:textblock>		<v:textrect cx="66.0943" cy="391.964" width="132.19" height="21.5726"></v:textrect>		<path d="M132.19 381.18 L0 381.18 L0 402.75 L132.19 402.75 L132.19 381.18" class="st7"></path>		<text x="9.27" y="396.76" class="st9" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Backend drivers</text>		</g>	<g id="shape35-47" v:mid="35" v:groupcontext="shape" transform="translate(64.2251,-299.641)">		<title>Rectangle.35</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="368.359" width="171" height="34.3907" rx="2.88" ry="2.88" class="st11"></rect>	</g>	<g id="shape15-49" v:mid="15" v:groupcontext="shape" transform="translate(71.6032,-306.05)">		<title>Sheet.15</title>		<desc>Frontend drivers</desc>		<v:textblock v:margins="rect(0,0,0,0)"></v:textblock>		<v:textrect cx="78.1219" cy="391.964" width="156.25" height="21.5726"></v:textrect>		<path d="M156.24 381.18 L0 381.18 L0 402.75 L156.24 402.75 L156.24 381.18" class="st7"></path>		<text x="20.15" y="396.76" class="st9" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Frontend drivers</text>		</g>	<g id="shape1000-53" v:mid="1000" v:groupcontext="shape" transform="translate(207.544,-28.944)">		<title>Sheet.1000</title>		<rect x="0" y="390.444" width="12.7435" height="12.306" rx="2" ry="2" class="st12"></rect>	</g>	<g id="shape1001-55" v:mid="1001" v:groupcontext="shape" transform="translate(220.125,-28.944)">		<title>Sheet.1001</title>		<desc>Open source</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="30.375" cy="396.597" width="60.75" height="12.306"></v:textrect>		<rect x="0" y="390.444" width="60.75" height="12.306" class="st13"></rect>		<text x="5.15" y="399.3" class="st14" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Open source</text>		</g>	<g id="shape1002-58" v:mid="1002" v:groupcontext="shape" transform="translate(128.128,-28.491)">		<title>Sheet.1002</title>		<rect x="0" y="390.444" width="12.7435" height="12.306" rx="2" ry="2" class="st15"></rect>	</g>	<g id="shape1003-60" v:mid="1003" v:groupcontext="shape" transform="translate(140.709,-28.491)">		<title>Sheet.1003</title>		<desc>Third party</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="25.875" cy="396.597" width="51.75" height="12.306"></v:textrect>		<rect x="0" y="390.444" width="51.75" height="12.306" class="st13"></rect>		<text x="4.35" y="399.3" class="st14" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Third party</text>		</g>	<g id="shape1004-63" v:mid="1004" v:groupcontext="shape" transform="translate(54.5435,-28.491)">		<title>Sheet.1004</title>		<rect x="0" y="390.444" width="12.7435" height="12.306" rx="2" ry="2" class="st16"></rect>	</g>	<g id="shape1005-65" v:mid="1005" v:groupcontext="shape" transform="translate(67.125,-28.491)">		<title>Sheet.1005</title>		<desc>Hardware</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="23.625" cy="396.597" width="47.25" height="12.306"></v:textrect>		<rect x="0" y="390.444" width="47.25" height="12.306" class="st13"></rect>		<text x="4.17" y="399.3" class="st14" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Hardware</text>		</g></g>
> </svg>
> 
> 
> **Figure : A high-level overview of the virtio architecture**
> 
>     - 프런트엔드 드라이버: 게스트 OS에서 구현됩니다. 프런트엔드 드라이버가 하이퍼바이저의 백엔드 드라이버와 상호 작용합니다.
>     - 백엔드 드라이버: VMM/HYP에서 구현됩니다. 백엔드 드라이버는 실제 기기 에뮬레이션을 처리하며, 가상 큐를 통해 프런트엔드 드라이버와 상호 작용합니다.
>     - 가상 큐: Virtio는 프런트엔드와 백엔드 드라이버 간의 통신을 지원하기 위해 가상 큐(virtqueues)를 사용합니다. 이러한 가상 큐는 게스트-하이퍼바이저 전환을 효율적으로 관리하기 위해 원형으로 구현됩니다.
- Vhost

> 
> 
> Vhost는 VirtIO 데이터 평면 구현을 다른 요소(사용자 프로세스 또는 커널 모듈)에 오프로드하여 성능을 개선하는 프로토콜입니다. 이러한 오프로딩은 게스트 VM과 하이퍼바이저 간의 컨텍스트 전환에 따른 오버헤드를 줄입니다.

    - Vhost-net: 데이터 평면이 QEMU 프로세스를 우회할 수 있도록 허용하여 대기 시간을 줄이고 성능을 개선하는 커널 수준 구현입니다. v-host-net에 대한 자세한 내용은 [Introduction to virtio-networking and vhost-net](https://www.redhat.com/en/blog/introduction-virtio-networking-and-vhost-net) 을 참조하세요.
    - Vhost-user: 데이터 평면을 별도의 프로세스와 함께 처리하여 워크로드에 대한 유연성을 제공하고 성능을 개선하는 user-space 구현입니다. v-host-user에 대한 자세한 내용은 [Vhost-user Protocol](https://www.qemu.org/docs/master/interop/vhost-user.html) 을 참조하세요.

#### 혜택

VirtIO 프레임워크 사용 시 제공되는 혜택은 다음과 같습니다.

- 표준화: Virtio는 기기 에뮬레이션을 위한 공통 인터페이스를 제공합니다. 이 기기는 서로 다른 가상화 플랫폼 간의 코드 재사용 및 효율성을 촉진합니다.
- 유연성: Virtio는 블록 기기와 네트워크 기기를 지원합니다.

#### Virtio 인터페이스

다음은 VirtIO 지원 인터페이스입니다.

##### 9P 전송 개요

`virtio-9p` 를 사용하면 9P(Plan 9 파일 시스템) 프로토콜에 따라 호스트와 VM 간에 파일을 공유할 수 있으므로, VirtIO 프레임워크 내에서 성능을 향상할 수 있습니다.

참고

호스트 및 게스트 커널에서 다음과 같은 구성이 활성화되어 있는지 확인합니다.

Host side: CONFIG_NET_9P, CONFIG_NET_9P_VIRTIO
    Copy to clipboard

Guest side: CONFIG_NET_9P, CONFIG_NET_9P_VIRTIO, CONFIG_9P_FS
    Copy to clipboard

공유 디렉토리 `virtio-9p` 를 만들려면 호스트에서 해당 디렉토리를 정의한 후 이를 마운트하도록 게스트 VM을 구성합니다. 다음 예시를 참조하세요.

> 
> 
> root@qcs9100-ride-sx:~# ls -la /mnt/overlay/test_dir
>     total 12
>     drwxr-xr-x. 2 root root 4096 Apr 29 21:36 .
>     drwxr-xr-x. 7 root root 4096 Apr 29 21:36 ..
>     -rw-r--r--. 1 root root    8 Apr 29 21:36 file.txt
>     root@qcs9100-ride-sx:~# cat /mnt/overlay/test_dir/file.txt
>     testing
>     root@qcs9100-ride-sx:~#
>     Copy to clipboard

호스트에 `/mnt/overlay/test_dir` 디렉토리를 생성하여 게스트 VM과 공유합니다. 이 정보를 libvirt XML 구성 또는 QEMU 인자로 전달합니다. 9P 전송을 구성하려면 다음 명령어를 실행합니다.

qemu-system-aarch64 \
    -M virt -m 2G \
    -kernel /mnt/overlay/guest/Image \
    -drive file=/mnt/overlay/guest/rootfs.ext4,if=virtio,format=raw \
    -append "root=/dev/vda" \
    -cpu host --enable-kvm -smp 4 -nographic \
    -fsdev local,id=fsdev0,path=/mnt/overlay/test_dir,security_model=passthrough \
    -device virtio-9p-pci,fsdev=fsdev0,mount_tag=hostshare
    Copy to clipboard

게스트 VM에서 공유 디렉토리를 식별하고 마운트하려면 `fsdev0` 및 `hostshare` 파일 시스템 기기를 사용합니다.

아래의 샘플 XML로 libvirt 인터페이스에서 Libvirt 게스트 VM을 시작하려면 [Libvirt](https://docs.qualcomm.com/doc/80-70020-3KO/topic/virtualization.html#id7) 를 참조하세요.

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
      <name>simple_9p</name>
      <memory unit='KiB'>2097152</memory>
      <vcpu placement='static'>4</vcpu>
      <resource>
        <partition>/machine</partition>
      </resource>
      <os>
        <type arch='aarch64' machine='virt-6.2'>hvm</type>
        <kernel>/mnt/overlay/guest/Image</kernel>
        <cmdline>root=/dev/vda</cmdline>
        <boot dev='hd'/>
      </os>
      <features>
        <gic version='3'/>
      </features>
      <cpu mode='host-passthrough' check='none'/>
      <devices>
        <console type='pty'>
        </console>
        <disk type="file" device="disk">
          <driver name="qemu" type="raw"/><!-- Specify rootfs image file here -->
          <source file="/mnt/overlay/guest/rootfs.ext4"/>
          <target dev="vda" bus="virtio"/>
        </disk>
        <filesystem type='mount' accessmode='mapped' fmode='644' dmode='755'>
          <!-- Specify the directory to be shared -->
          <source dir='/mnt/overlay/test_dir'/>
          <!-- Specify the mount_tag to identify the mount point -->
          <target dir='hostshare'/>
        </filesystem>
      </devices>
    </domain>
    Copy to clipboard

참고

호스트의 `/mnt/overlay/guest/libvirt_virtio_9p.xml` 파일에 XML 콘텐츠를 복사합니다.

게스트 VM이 부팅되면 VirtIO 기기가 성공적으로 프로브되었는지 확인합니다.

> 
> 
> root@v8a-arm64:~# lspci
>     00:00.0 Host bridge: Red Hat, Inc. QEMU PCIe Host bridge
>     00:01.0 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
>     00:01.1 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
>     00:01.2 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
>     01:00.0 Unclassified device [0002]: Red Hat, Inc. Virtio 1.0 filesystem (rev 01)
>     02:00.0 SCSI storage controller: Red Hat, Inc. Virtio 1.0 block device (rev 01)
>     root@v8a-arm64:~#root@v8a-arm64:~# cat /sys/bus/pci/devices/0000\:01\:00.0/virtio0/uevent
>     DRIVER=9pnet_virtio
>     MODALIAS=virtio:d00000009v00001AF4
>     root@v8a-arm64:~#
>     Copy to clipboard

게스트 VM에 공유 디렉토리를 마운트하려면 다음 명령어를 실행합니다.

mount -t 9p -o trans=virtio hostshare mountpoint
    Copy to clipboard

##### VSOCK 개요

VSOCK은 VM과 호스트 OS 간의 통신을 허용하는 가상 소켓 인터페이스입니다. KVM 및 QEMU에서 사용됩니다. VSOCK 지원은 VirtIO 인터페이스를 통해 이루어집니다. virtio-vsock은 vhost 기반의 VirtIO 기기로, 호스트 커널이 모든 데이터 전송을 관리하는 한편, KVM 하이퍼바이저가 정보를 제어합니다.

KVM 및 QEMU 환경에서 VSOCK 연결을 만들려면 컨텍스트 식별자(CID)와 포트 번호를 지정하세요. CID는 VSOCK 환경에서 각 VM에 할당된 고유 식별자로, 호스트와 VM 간의 통신을 라우팅하는 데 사용됩니다. 호스트는 CID가 2인 반면, VM은 3 이상의 숫자로 시작하는 CID를 할당받습니다.

다음 표에는 CID 값이 나열되어 있습니다.

표: CID 값

| CID | 설명 |
| --- | --- |
| -1 | 바인딩을 위한 주소 |
| 0 | 하이퍼바이저 |
| 1 | 루프백 |
| 2 | 호스트 |

참고

호스트 및 게스트 커널에서 다음과 같은 구성이 활성화되어 있는지 확인합니다.

Host side: CONFIG_VSOCKETS, CONFIG_VHOST_VSOCK
    
    Guest side: CONFIG_VSOCKETS, CONFIG_VIRTIO_VSOCKETS
    Copy to clipboard

- VSOCK 기기 활성화: VSOCK 기기를 활성화하려면 VM 구성 파일(libvirt XML)에서 기기를 지정하거나, QEMU에 인자를 전달합니다.

qemu-system-aarch64 \
        -machine virt -m 2G \
        -kernel /mnt/overlay/guest/Image \
        -drive file=/mnt/overlay/guest/rootfs.ext4,if=virtio,format=raw \
        -append "root=/dev/vda" \
        -cpu host --enable-kvm -smp 4 -nographic \
        -device vhost-vsock-pci,guest-cid=73
        Copy to clipboard

이 명령에서 `guest-cid=73` 은 VM의 CID를 지정합니다.

- libvirt 인터페이스를 사용하여 게스트 VM을 시작합니다. libvirt와 함께 VSOCK 기기를 사용하려면 VM XML 구성 파일에 VSOCK 기기를 정의하세요.

    libvirt 인터페이스를 사용하여 게스트 VM을 시작하려면 [Libvirt](https://docs.qualcomm.com/doc/80-70020-3KO/topic/virtualization.html#id7) 을 참조하세요.

호스트의 `/mnt/overlay/guest/libvirt_virtio_vsock.xml` 에 XML 콘텐츠를 복사합니다. 게스트 VM이 부팅되면 기기가 성공적으로 프로브되었는지 확인합니다.

> 
> 
> root@v8a-arm64:~# lspci
>     00:00.0 Host bridge: Red Hat, Inc. QEMU PCIe Host bridge
>     00:01.0 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
>     00:01.1 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
>     00:01.2 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
>     01:00.0 SCSI storage controller: Red Hat, Inc. Virtio 1.0 block device (rev 01)
>     02:00.0 Communication controller: Red Hat, Inc. Virtio 1.0 socket (rev 01)
>     root@v8a-arm64:~#
>     root@v8a-arm64:~# cat /sys/bus/pci/devices/0000\:02\:00.0/virtio1/uevent
>     DRIVER=vmw_vsock_virtio_transport
>     MODALIAS=virtio:d00000013v00001AF4
>     root@v8a-arm64:~#
>     Copy to clipboard

호스트-게스트 및 게스트-호스트 상호 작용을 확인하려면 `socat` 유틸리티를 사용하세요. 호스트와 게스트에서 `socat` 유틸리티가 지원되는지 확인합니다.

- 호스트에서는 다음 포트를 확인합니다.

> 
> 
> socat STDIN VSOCK-LISTEN:1234
>     Copy to clipboard

- 게스트에서는 호스트 CID(2)를 사용하여 호스트에 연결합니다.

socat STDOUT VSOCK-CONNECT:2:1234
    Copy to clipboard

- 이 설정의 경우, 게스트와 호스트가 동일한 값을 나타냅니다.

##### VirtIO 블록 개요

VirtIO 블록은 VM에 블록 기기를 제공하는 표준화된 방법입니다. 각 VirtIO 블록 기기는 게스트 VM 내부에 있는 디스크처럼 표시됩니다. VirtIO 블록을 사용하면 VM이 읽기와 쓰기 작업을 수행할 수 있습니다.

다음은 virtio-block 기기의 주요 기능입니다.

- 단순성: 구현하고 사용하기 쉬움
- 성능: 오버헤드를 최소화하고 처리량을 최대화할 수 있도록 설계됨
- 유연성: 다양한 유형의 스토리지 백엔드와 함께 사용할 수 있도록 설계됨

참고

게스트 커널에서 `CONFIG_VIRTIO_BLK` 가 활성화되어 있는지 확인하세요.

virtio-block 기기를 사용하려면 다음 작업을 수행합니다.

1. virtio-block 기기를 포함하도록 VM을 구성하고, VM 구성 파일(libvirt XML)에서 기기를 지정하거나, QEMU에 인자를 전달합니다.

    1. VM에서 virtio-block 기기를 활성화하려면 다음 QEMU 명령어를 사용합니다.

qemu-system-aarch64 \
            -M virt -m 2G \
            -kernel /mnt/overlay/guest/Image \
            -drive file=/mnt/overlay/guest/rootfs.ext4,if=virtio,format=raw \
            -append "root=/dev/vda" \
            -cpu host --enable-kvm -smp 4 -nographic \
            -drive file=/mnt/overlay/guest/disk.img,if=virtio,format=raw
            Copy to clipboard

        이 명령어에서 `rootfs.ext4` 및 `disk.img` 는 게스트 VM 내부의 디스크입니다.
    2. libvirt 인터페이스를 사용하여 게스트 VM을 시작합니다. 아래의 샘플 XML로 게스트 VM을 시작하려면 [Libvirt](https://docs.qualcomm.com/doc/80-70020-3KO/topic/virtualization.html#id7): 를 참조하세요.

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
              <name>simple_block_device</name>
              <memory unit='KiB'>2097152</memory>
              <vcpu placement='static'>4</vcpu>
              <resource>
                <partition>/machine</partition>
              </resource>
              <os>
                <type arch='aarch64' machine='virt-6.2'>hvm</type>
                <kernel>/mnt/overlay/guest/Image</kernel>
                <cmdline>root=/dev/vda</cmdline>
                <boot dev='hd'/>
              </os>
              <features>
                <gic version='3'/>
              </features>
              <cpu mode='host-passthrough' check='none'/>
              <devices>
                <console type='pty'>
                </console>
                <disk type="file" device="disk">
                  <driver name="qemu" type="raw"/>
                  <!-- specify rootfs image file  -->
                  <source file="/mnt/overlay/guest/rootfs.ext4"/>
                  <target dev="vda" bus="virtio"/>
                </disk>
                <disk type="file" device="disk">
                  <driver name="qemu" type="raw"/>
                  <!-- specify a different disk image file -->
                  <source file="/mnt/overlay/guest/disk.img"/>
                  <target dev="vdb" bus="virtio"/>
                </disk>
              </devices>
            </domain>
            Copy to clipboard

참고

호스트의 `/mnt/overlay/guest/libvirt_virtio_blk.xml` 에 XML 콘텐츠를 복사합니다.
2. 게스트 OS는 virtio-block 기기를 감지하고 초기화합니다. 이 프로세스에서 게스트 드라이버는 기기와 통신하여 필요한 데이터 구조 및 큐를 설정합니다.

> 
> 
> root@v8a-arm64:~# dmesg | grep virtio
>         [    0.225425] virtio-pci 0000:01:00.0: enabling device (0000 -> 0002)
>         [    0.227073] virtio-pci 0000:02:00.0: enabling device (0000 -> 0002)
>         [    0.234012] virtio_blk virtio0: 4/0/0 default/read/poll queues
>         [    0.235405] virtio_blk virtio0: [vda] 2220734 512-byte logical blocks (1.14 GB/1.06 GiB)
>         [    0.241213] virtio_blk virtio1: 4/0/0 default/read/poll queues
>         [    0.242418] virtio_blk virtio1: [vdb] 8192000 512-byte logical blocks (4.19 GB/3.91 GiB)
>         root@v8a-arm64:~#
>         root@v8a-arm64:~# lspci
>         00:00.0 Host bridge: Red Hat, Inc. QEMU PCIe Host bridge
>         00:01.0 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
>         00:01.1 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
>         00:01.2 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
>         01:00.0 SCSI storage controller: Red Hat, Inc. Virtio 1.0 block device (rev 01)
>         02:00.0 SCSI storage controller: Red Hat, Inc. Virtio 1.0 block device (rev 01)
>         root@v8a-arm64:~#
>         Copy to clipboard
3. 초기화가 완료되면 virtio-block 및 기타 블록 기기를 사용할 수 있습니다. 게스트 OS는 VirtIO 드라이버에서 읽기 및 쓰기 작업을 수행하고, 처리할 작업을 호스트에 전달합니다.
4. VirtIO-block 기기를 관리하려면 게스트 OS에서 사용 가능한 표준 도구와 명령어를 사용하세요. 그 예로, `lsblk` 및 `df` 를 들 수 있습니다.

##### Virtio-IOMMU 개요

Virtio-IOMMU는 가상 환경에서 DMA(직접 메모리 액세스) 관리를 제공하는 반가상화된 입출력 메모리 관리 유닛(IOMMU)입니다. Virtio-IOMMU는 가상 함수 I/O(VFIO) 같은 기존 소프트웨어 API와 통합되며, 페이지 테이블 에뮬레이션의 필요성을 없애 고성능 경량 솔루션으로 작동합니다. Virtio-IOMMU는 물리적 IOMMU의 프록시 역할을 수행하며 게스트에 할당된 기기를 관리합니다. 가상 IOMMU로서 기기를 관리하고, 에뮬레이트하며, 반가상화합니다.

Virtio-IOMMU의 주요 기능은 다음과 같습니다.

- 반가상화: 기존의 전송 메커니즘을 활용하고 오버헤드를 줄입니다.
- 유연성: PCI 패스스루를 지원하고 가상 메모리를 공유합니다.
- 통합: 소프트웨어 API와 통합되고 호환성을 향상합니다. VFIO를 예로 들 수 있습니다.

참고

게스트 커널에서 `CONFIG_VIRTIO_IOMMU` 가 활성화되어 있는지 확인하세요.

Virtio-IOMMU 기기를 사용하려면 다음 작업을 수행합니다.

1. VM에 Virtio-IOMMU 기기를 포함하도록 구성하려면 VM 구성 파일(XML)에서 해당 기기를 지정하거나, QEMU에 인자를 전달합니다.

> 
> 
> 1. Virtio-IOMMU 기기 활성화: VM에서 Virtio-IOMMU 기기를 활성화하려면 다음 QEMU 명령어를 사용합니다.
> 
> 
> 
> 
> > 
> > 
> > qemu-system-aarch64 \
> >     -M virt -m 2G \
> >     -kernel /mnt/overlay/guest/Image \
> >     -drive file=/mnt/overlay/guest/rootfs.ext4,if=virtio,format=raw \
> >     -append "root=/dev/vda" \
> >     -cpu host --enable-kvm -smp 4 -nographic \
> >     -device virtio-iommu-pci
> >     Copy to clipboard
> 
> 
> 2. libvirt 인터페이스를 사용하여 게스트 VM을 시작합니다. 아래의 샘플 XML로 게스트 VM을 시작하려면 [Libvirt](https://docs.qualcomm.com/doc/80-70020-3KO/topic/virtualization.html#id7) 를 참조하세요.
> 
> 
> 
> 
> > 
> > 
> > <domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
> >       <name>simple_iommu</name>
> >       <memory unit='KiB'>2097152</memory>
> >       <vcpu placement='static'>4</vcpu>
> >       <resource>
> >         <partition>/machine</partition>
> >       </resource>
> >       <os>
> >         <type arch='aarch64' machine='virt-6.2'>hvm</type>
> >         <kernel>/mnt/overlay/guest/Image</kernel>
> >         <cmdline>root=/dev/vda</cmdline>
> >         <boot dev='hd'/>
> >       </os>
> >       <features>
> >         <gic version='3'/>
> >       </features>
> >       <cpu mode='host-passthrough' check='none'/>
> >       <devices>
> >         <controller type='pci' index='0' model='pcie-root'>
> >           <alias name='pcie.0'/>
> >         </controller>
> >         <console type='pty'>
> >         </console>
> >         <disk type="file" device="disk">
> >           <driver name="qemu" type="raw"/>
> >           <!-- specify rootfs image file  -->
> >           <source file="/mnt/overlay/guest/rootfs.ext4"/>
> >           <target dev="vda" bus="virtio"/>
> >         </disk>
> >       </devices>
> >       <qemu:commandline>
> >         <qemu:arg value="-device"/>
> >         <qemu:arg value='{"driver":"virtio-iommu-pci","bus":"pcie.0","addr":"0x3"}'/>
> >       </qemu:commandline>
> >     </domain>
> >     Copy to clipboard
> 
> 
> 
> 참고
> 
> 
> 호스트의 `/mnt/overlay/guest/libvirt_virtio_iommu.xml` 에 XML 콘텐츠를 복사합니다.

2. 게스트 OS는 Virtio-IOMMU 기기를 감지하고 초기화합니다. 이 프로세스에서 게스트 드라이버는 기기와 통신하여 필요한 데이터 구조 및 매핑을 설정합니다.

> 
> 
> root@v8a-arm64:~# dmesg | grep virtio
>     [    0.184166] virtio-pci 0000:00:03.0: enabling device (0000 -> 0002)
>     [    0.189122] virtio_iommu virtio0: input address: 64 bits
>     [    0.189516] virtio_iommu virtio0: page mask: 0xfffffffffffff000
>     [    0.220135] virtio-pci 0000:01:00.0: Adding to iommu group 0
>     [    0.220676] virtio-pci 0000:01:00.0: enabling device (0000 -> 0002)
>     [    0.223065] virtio_blk virtio1: 4/0/0 default/read/poll queues
>     [    0.224713] virtio_blk virtio1: [vda] 2220734 512-byte logical blocks (1.14 GB/1.06 GiB)
>     root@v8a-arm64:~#
>     Copy to clipboard
> 
> 
> DMESG 로그를 보면 virtio-block 기기가 IOMMU 그룹 `0` 의 일부인 IOMMU 도메인에 연결되어 있습니다.

3. 초기화가 완료되면 Virtio-IOMMU 기기는 연결된 기기에 대한 DMA 작업을 관리합니다. 게스트 OS는 VirtIO 드라이버에서 매핑 및 매핑 해제 작업을 수행하고, 처리할 작업을 호스트에 전달합니다.

> 
> 
> 다음 예시는 Virtio-IOMMU 기기의 작업을 보여줍니다.
> 
> 
> root@v8a-arm64:~# cat /sys/kernel/iommu_groups/0/devices/0000\:01\:00.0/virtio1/uevent
>     DRIVER=virtio_blk
>     MODALIAS=virtio:d00000002v00001AF4
>     root@v8a-arm64:~#
>     Copy to clipboard

##### Virtio-net 개요

virtio-net 기기는 가상화된 환경에서 네트워크 작업을 위한 인터페이스를 제공하는 가상 네트워크 기기입니다. 이는 높은 성능과 낮은 오버헤드 비용을 제공합니다.

다음은 virtio-net 기기의 주요 기능입니다.

- 효율성: 오버헤드를 최소화하고 처리량을 최대화합니다.
- 단순성: 구현하고 사용하기 쉽습니다.
- 유연성: 다양한 네트워크 구성 및 백엔드를 지원합니다.

참고

게스트 커널에서 `CONFIG_VIRTIO_NET` 가 활성화되어 있는지 확인하세요.

virtio-net 기기를 사용하려면 다음 작업을 수행합니다.

1. virtio-net 기기를 포함하도록 VM을 구성하고, VM 구성 파일(libvirt XML)에서 기기를 지정하거나, QEMU에 인자를 전달합니다.

> 
> 
> 1. VM에서 virtio-net 기기를 활성화하려면 다음 QEMU 명령어를 사용합니다.
> 
> 
> 
> 
> > 
> > 
> > qemu-system-aarch64 \
> >     -M virt -m 2G \
> >     -kernel /mnt/overlay/guest/Image \
> >     -drive file=/mnt/overlay/guest/rootfs.ext4,if=virtio,format=raw \
> >     -append "root=/dev/vda" \
> >     -cpu host --enable-kvm -smp 4 -nographic \
> >     -netdev tap,id=net0,ifname=tap0,script=no,downscript=no \
> >     -device virtio-net-pci,netdev=net0
> >     Copy to clipboard
> > 
> > 
> > 참고
> > 
> > 
> > 이 명령어는 호스트에서 TAP 인터페이스를 만듭니다. TAP 인터페이스를 수동으로 만들려면 다음 명령어를 실행하세요.
> > 
> > 
> > ip tuntap add dev tap0 mode tap
> >     Copy to clipboard
> 
> 
> 2. 아래의 샘플 XML로 게스트 VM을 시작하려면 [Libvirt](https://docs.qualcomm.com/doc/80-70020-3KO/topic/virtualization.html#id7) 를 참조하세요.
> 
> 
> 
> 
> > 
> > 
> > <domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
> >       <name>simple_net</name>
> >       <memory unit='KiB'>2097152</memory>
> >       <vcpu placement='static'>4</vcpu>
> >       <resource>
> >         <partition>/machine</partition>
> >       </resource>
> >       <os>
> >         <type arch='aarch64' machine='virt-6.2'>hvm</type>
> >         <kernel>/mnt/overlay/guest/Image</kernel>
> >         <cmdline>root=/dev/vda</cmdline>
> >         <boot dev='hd'/>
> >       </os>
> >       <features>
> >         <gic version='3'/>
> >       </features>
> >       <cpu mode='host-passthrough' check='none'/>
> >       <devices>
> >         <console type='pty'>
> >         </console>
> >         <disk type="file" device="disk">
> >           <driver name="qemu" type="raw"/><!-- Specify rootfs image file here -->
> >           <source file="/mnt/overlay/guest/rootfs.ext4"/>
> >           <target dev="vda" bus="virtio"/>
> >         </disk>
> >         <interface type='ethernet'>
> >           <target dev='tap0'/>
> >           <model type='virtio'/>
> >         </interface>
> >       </devices>
> >     </domain>
> >     Copy to clipboard
> > 
> > 
> > 호스트 VM과 게스트 VM 간의 직접 통신을 위해 TAP 인터페이스를 만들려면 XML 콘텐츠를 호스트의 `/mnt/overlay/guest/libvirt_virtio_net.xml` 에 복사합니다.

2. 게스트 운영 체제는 virtio-net 기기를 감지하고 초기화합니다. 이 프로세스에서 게스트 드라이버는 기기와 통신하여 필요한 데이터 구조 및 큐를 설정합니다.

> 
> 
> root@v8a-arm64:~# dmesg | grep virtio
>     [    0.394365] virtio-pci 0000:01:00.0: enabling device (0000 -> 0002)
>     [    0.396364] virtio-pci 0000:02:00.0: enabling device (0000 -> 0002)
>     [    0.404496] virtio_blk virtio1: 4/0/0 default/read/poll queues
>     [    0.406048] virtio_blk virtio1: [vda] 2220734 512-byte logical blocks (1.14 GB/1.06 GiB)
>     [    0.980919] virtio_net virtio0 enp1s0: renamed from eth0
>     root@v8a-arm64:~# lspci
>     00:00.0 Host bridge: Red Hat, Inc. QEMU PCIe Host bridge
>     00:01.0 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
>     00:01.1 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
>     00:01.2 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
>     01:00.0 Ethernet controller: Red Hat, Inc. Virtio 1.0 network device (rev 01)
>     02:00.0 SCSI storage controller: Red Hat, Inc. Virtio 1.0 block device (rev 01)
>     root@v8a-arm64:~#
>     Copy to clipboard

3. 작동: virtio-net 기기를 초기화하고 구성한 후에는 다른 네트워크 인터페이스처럼 사용하세요. 게스트 OS는 VirtIO 드라이버에서 일반적인 네트워크 작업을 수행하고, 처리할 작업을 호스트에 전달합니다.

TAP 인터페이스를 사용하려면 호스트 VM과 게스트 VM에서 다음 네트워크 구성을 실행하세요.

- 호스트 구성:

root@qcs9100-ride-sx:~# ip addr add 192.168.100.1/24 dev tap0
        root@qcs9100-ride-sx:~# ip link set dev tap0 up
        Copy to clipboard
- 게스트 구성:

root@v8a-arm64:~# ip addr add 192.168.100.2/24 dev enp1s0
        root@v8a-arm64:~# ip link set dev enp1s0 up
        Copy to clipboard

이 인터페이스에서 네트워크 트래픽을 처리하려면 다음 예시를 사용하세요.

> 
> 
> root@v8a-arm64:~# ping 192.168.100.1
>     PING 192.168.100.1 (192.168.100.1): 56 data bytes
>     64 bytes from 192.168.100.1: seq=0 ttl=64 time=0.364 ms
>     64 bytes from 192.168.100.1: seq=1 ttl=64 time=0.156 ms
>     Copy to clipboard

##### virtio-serial 및 virtio-console 개요

virtio-serial 기기는 가상 환경에서 호스트 VM과 게스트 VM 간의 시리얼 통신을 위한 인터페이스를 제공합니다.

다음은 virtio-serial 기기의 주요 기능입니다.

- 다중 포트: 다중 시리얼 포트를 지원하고, 다양한 통신 채널을 허용합니다.
- 효율성: 오버헤드를 최소화하고 처리량을 최대화합니다.
- 유연성: 다양한 유형의 데이터를 교환하도록 지원합니다. 그 예로, 콘솔 액세스 및 파일 전송을 들 수 있습니다.

참고

게스트 커널에서 `CONFIG_VIRTIO_CONSOLE` 이 활성화되어 있는지 확인하세요.

virtio-serial 기기를 사용하려면 다음 작업을 수행합니다.

1. virtio-serial 기기를 포함하도록 VM을 구성하고, VM 구성 파일(libvirt XML)에서 기기를 지정하거나, QEMU에 인자를 전달합니다.

    1. VM에서 virtio-net 기기를 활성화하려면 다음 QEMU 명령어를 사용합니다.

> 
> 
> qemu-system-aarch64 \
>         -M virt -m 2G \
>         -kernel /mnt/overlay/guest/Image \
>         -drive file=/mnt/overlay/guest/rootfs.ext4,if=virtio,format=raw \
>         -append "root=/dev/vda" \
>         -cpu host --enable-kvm -smp 4 -nographic \
>         -device virtio-serial-pci,id=virtio-serial0 \
>         -chardev pty,id=charconsole0 \
>         -device virtconsole,chardev=charconsole0,id=console0 \
>         -chardev socket,path=/tmp/qemu.sock,server=on,wait=off,id=charchannel0 \
>         -device virtserialport,chardev=charchannel0,name=org.qemu.guest_agent.0
>         Copy to clipboard

    2. 아래의 샘플 XML로 게스트 VM을 시작하려면 [Libvirt](https://docs.qualcomm.com/doc/80-70020-3KO/topic/virtualization.html#id7) 를 참조하세요.

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
          <name>simple_serial</name>
          <memory unit='KiB'>2097152</memory>
          <vcpu placement='static'>4</vcpu>
          <resource>
            <partition>/machine</partition>
          </resource>
          <os>
            <type arch='aarch64' machine='virt-6.2'>hvm</type>
            <kernel>/mnt/overlay/guest/Image</kernel>
            <cmdline>root=/dev/vda</cmdline>
            <boot dev='hd'/>
          </os>
          <features>
            <gic version='3'/>
          </features>
          <cpu mode='host-passthrough' check='none'/>
          <devices>
            <console type='pty'>
            </console>
            <disk type="file" device="disk">
              <driver name="qemu" type="raw"/><!-- Specify rootfs image file here -->
              <source file="/mnt/overlay/guest/rootfs.ext4"/>
              <target dev="vda" bus="virtio"/>
            </disk>
            <controller type='virtio-serial' index='0'>
              <alias name='virtio-serial0'/>
            </controller>
            <console type='pty'>
              <target type='virtio' port='0'/>
            </console>
            <channel type='unix'>
              <target type='virtio' name='org.qemu.guest_agent.0'/>
              <address type='virtio-serial' controller='0' bus='0' port='1'/>
            </channel>
          </devices>
        </domain>
        Copy to clipboard

참고

호스트의 `/mnt/overlay/guest/virtio_serial.xml` 에 XML 콘텐츠를 복사합니다.
2. 게스트 운영 체제는 virtio-serial 기기를 감지하고 초기화합니다. 이 프로세스에서 게스트 드라이버는 기기와 통신하여 필요한 데이터 구조 및 포트를 설정합니다.

> 
> 
> root@v8a-arm64:~# lspci
>     00:00.0 Host bridge: Red Hat, Inc. QEMU PCIe Host bridge
>     00:01.0 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
>     00:01.1 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
>     00:01.2 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
>     01:00.0 Communication controller: Red Hat, Inc. Virtio 1.0 console (rev 01)
>     02:00.0 SCSI storage controller: Red Hat, Inc. Virtio 1.0 block device (rev 01)
>     root@v8a-arm64:~#
>     root@v8a-arm64:~# cat /sys/bus/virtio/devices/virtio0/uevent
>     DRIVER=virtio_console
>     MODALIAS=virtio:d00000003v00001AF4
>     root@v8a-arm64:~#
>     Copy to clipboard

3. 초기화가 완료되면 virtio-serial 기기를 시리얼 기기로 사용할 수 있습니다. 게스트 OS는 virtio 드라이버를 통해 읽기 및 쓰기 작업을 수행하고, 처리할 작업을 호스트에 전달합니다.
4. virtio-serial 기기를 관리하려면 다음 작업을 수행합니다.

    - 성능 모니터링
    - 기기 상태 확인
    - 유지 관리 작업 수행
    - 게스트 OS에서 사용 가능한 표준 도구와 명령어 사용

###### 메모리 벌룬 기기 지원

전통적인 VirtIO 메모리 벌룬 기기는 게스트 메모리를 관리합니다. 이러한 기기는 호스트 시스템이 VM에서 메모리를 회수하도록 지원합니다. 메모리 벌룬은 VM에게 메모리의 일부를 호스트로 반환하도록 명령합니다. 이 프로세스에서는 게스트 VM 내부의 메모리 벌룬을 확장해야 하며, 이로 인해 VM 내 다른 작업에 사용할 수 있는 메모리가 줄어듭니다. 게스트 OS는 호스트에 반환할 메모리 페이지를 결정하며, 필요하지 않거나 액세스하지 않는 페이지가 무엇인지 표시합니다. 그런 다음, 호스트는 게스트 VM에서 이러한 페이지의 매핑을 해제한 후 게스트 VM이 이를 사용할 수 없도록 표시하며, 호스트 시스템이 사용할 수 있도록 합니다. 향후 게스트 VM에 더 많은 메모리가 필요할 경우, 호스트는 벌룬을 축소하여 페이지를 반환합니다. 이 기능을 통해 각 게스트 VM은 사용 가능한 메모리가 관리되는 동안 계속 실행될 수 있습니다.

virtio-balloon 기기가 게스트 VM과 호스트 사이에 실제 메모리를 이동하게 하려면 다음과 같은 방법을 사용하세요.

1. 벌룬 확장: 게스트 드라이버가 메모리를 할당한 후 호스트에게 알립니다. 그러면 호스트는 다른 VM에 확장된 메모리를 재사용합니다.
2. 벌룬 축소: 호스트에게 알린 후, 게스트 드라이버는 이전에 할당된 메모리를 해제하고 게스트 VM이 축소된 메모리를 사용할 수 있게 만듭니다.

`Target balloon size` 는 게스트 VM 메모리 크기를 조정하는 요청을 통해 벌룬 확장 또는 축소를 제어합니다. 크기 조정 요청은 QEMU 모니터 모드 또는 virsh 명령어를 통해 전송됩니다.

다음은 virtio-balloon 기기의 주요 기능입니다.

- 메모리 관리: 요구사항에 따라 메모리 할당을 실시간으로 조정합니다.
- 효율성: 사용하지 않는 메모리를 유휴 상태의 VM에서 회수하여 활성 VM에 재배포합니다.
- 유연성: 다양한 가상화 설정을 활성화하여 리소스 사용을 최적화합니다.

참고

게스트 커널에서 `CONFIG_VIRTIO_BALLOON` 이 활성화되어 있는지 확인하세요.

virtio-balloon 기기를 사용하려면 다음 작업을 수행하세요.

1. virtio-balloon 기기를 포함하도록 VM을 구성하고, VM 구성 파일(libvirt XML)에서 기기를 지정하거나, QEMU에 인자를 전달합니다.

    1. VM에서 virtio-balloon 기기를 활성화하려면 다음 QEMU 명령어를 사용합니다.

qemu-system-aarch64 \
            -M virt -m 2G \
            -kernel /mnt/overlay/guest/Image \
            -drive file=/mnt/overlay/guest/rootfs.ext4,if=virtio,format=raw \
            -append "root=/dev/vda" \
            -cpu host --enable-kvm -smp 4 -nographic \
            -device virtio-balloon-pci,id=balloon0
            Copy to clipboard
    2. 아래의 샘플 XML로 게스트 VM을 시작하려면 [Libvirt](https://docs.qualcomm.com/doc/80-70020-3KO/topic/virtualization.html#id7): 를 참조하세요.

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
              <name>simple_balloon</name>
              <memory unit='KiB'>2097152</memory>
              <vcpu placement='static'>4</vcpu>
              <resource>
                <partition>/machine</partition>
              </resource>
              <os>
                <type arch='aarch64' machine='virt-6.2'>hvm</type>
                <kernel>/mnt/overlay/guest/Image</kernel>
                <cmdline>root=/dev/vda</cmdline>
                <boot dev='hd'/>
              </os>
              <features>
                <gic version='3'/>
              </features>
              <cpu mode='host-passthrough' check='none'/>
              <devices>
                <console type='pty'>
                </console>
                <disk type="file" device="disk">
                  <driver name="qemu" type="raw"/><!-- Specify rootfs image file here -->
                  <source file="/mnt/overlay/guest/rootfs.ext4"/>
                  <target dev="vda" bus="virtio"/>
                </disk>
                <memballoon model='virtio'/>
              </devices>
            </domain>
            Copy to clipboard

참고

호스트의 `/mnt/overlay/guest/libvirt_virtio_balloon.xml` 파일에 XML 콘텐츠를 복사합니다.
2. 게스트 OS는 virtio-balloon 기기를 감지하고 초기화합니다. 이 프로세스에서 게스트 드라이버는 기기와 통신하여 필요한 데이터 구조 및 메모리 관리 메커니즘을 설정합니다.

> 
> 
> root@v8a-arm64:~# lspci
>         00:00.0 Host bridge: Red Hat, Inc. QEMU PCIe Host bridge
>         00:01.0 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
>         00:01.1 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
>         00:01.2 PCI bridge: Red Hat, Inc. QEMU PCIe Root port
>         01:00.0 SCSI storage controller: Red Hat, Inc. Virtio 1.0 block device (rev 01)
>         02:00.0 Unclassified device [00ff]: Red Hat, Inc. Virtio 1.0 memory balloon (rev 01)
>         root@v8a-arm64:~#
>         Copy to clipboard
3. 초기화가 완료되면 virtio-balloon 기기는 VM에 할당된 메모리를 조정합니다. 게스트 OS는 VirtIO 드라이버가 처리하는 메모리 확장 및 축소 작업을 수행한 후, 이를 호스트에 전달하여 처리할 수 있도록 합니다.

게스트 메모리를 조정하려면 호스트에서 다음 virsh 명령어를 실행하세요.

- 게스트 VM의 초기 메모리(2GB)를 확인하려면 다음 명령어를 실행하세요.

> 
> 
> root@v8a-arm64:~# cat /proc/meminfo  | grep Mem
>     MemTotal:        1966180 kB
>     MemFree:         1807432 kB
>     MemAvailable:    1817552 kB
>     root@v8a-arm64:~#
>     Copy to clipboard

- 벌룬을 확장하고 게스트 VM의 메모리를 512MB로 줄이려면 다음 명령어를 실행하세요.

root@qcs9100-ride-sx:~# virsh setmem simple_balloon 512M --live
        Copy to clipboard
- 확장 후 게스트 VM의 메모리를 확인하려면 다음 명령어를 실행하세요.

root@v8a-arm64:~# cat /proc/meminfo  | grep Mem
        MemTotal:         393316 kB
        MemFree:          235708 kB
        MemAvailable:     245836 kB
        root@v8a-arm64:~#
        Copy to clipboard
- 게스트 VM 메모리 축소하려면(게스트로 VM 메모리를 2GB로 다시 줄이기):

root@qcs9100-ride-sx:~# virsh setmem simple_balloon 2G --live
        Copy to clipboard
- 축소 후 게스트 VM의 메모리를 확인하려면:

root@v8a-arm64:~# cat /proc/meminfo  | grep Mem
        MemTotal:        1966180 kB
        MemFree:         1811844 kB
        MemAvailable:    1821988 kB
        root@v8a-arm64:~#
        Copy to clipboard

###### 호스트 기기에 액세스

게스트의 호스트 시스템에서 열거된 기기를 사용할 수 있습니다. 게스트에 대한 기기 할당 인터페이스는 기기 유형에 따라 다릅니다. UART와 같은 일부 기기는 QEMU에 의해 에뮬레이트되는 기기의 백엔드 역할을 합니다. 호스트에서 범용 비동기 송/수신기(UART)를 문자 입출력 기기(chardev) 백엔드로 구성합니다. QEMU chardev에 대한 자세한 내용은 [Character device options](https://www.qemu.org/docs/master/system/invocation.html#hxtool-6) 를 참조하세요.

PCI 및 USB 기기는 VFIO 커널 프레임워크에서 작동합니다.

- PCI 패스스루는 게스트 VM이 호스트의 물리적 PCI 기기에 직접 액세스할 수 있도록 허용합니다. Linux 커널의 VFIO 프레임워크는 기기 할당에 사용됩니다. VFIO에 대한 자세한 내용은 [VFIO - Virtual Function I/O](https://docs.kernel.org/driver-api/vfio.html) 를 참조하세요.
- USB 기기는 패스스루 모드에서 작동하여, 게스트 VM이 호스트에 연결된 USB 주변장치를 사용할 수 있도록 허용합니다. QEMU는 USB 컨트롤러를 에뮬레이트하며, 호스트의 libusb와 함께 작동하여 게스트에 USB 주변장치를 제공합니다. 자세한 내용은 [USB emulation](https://qemu-project.gitlab.io/qemu/system/devices/usb.html) 을 참조하세요.

**USB 패스스루 개요**

호스트 컴퓨터에 열거된 USB 기기를 식별하여 게스트에 할당할 수 있습니다. 호스트에 열거된 모든 USB 기기를 볼 수 있는 방법은 `lusb` 명령어를 사용하는 것입니다. `vendor id` 및 `product id` 로 기기를 찾습니다.

다음 예시에서 USB 메모리 스틱의 `vendor id` 는 0x0781이고 `product id` 는 0x5567입니다.

sh-5.1# lsusb
    Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
    Bus 001 Device 004: ID 0781:5567 SanDisk Corp. Cruzer Blade
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Copy to clipboard

참고

호스트 파일 시스템에서 다음 XML 파일을 `/mnt/overlay/guest/libvirt_usb.xml` 파일에 복사한 후 `vendor id` 및 `product id` 에 따라 수정합니다.

아래의 샘플 XML로 게스트 VM을 시작하고 다음 작업을 수행하세요.

1. 게스트 VM가 시작되면 콘솔에 연결합니다.
2. 게스트 VM에서 `lsusb` 출력을 확인합니다.
3. 게스트에게 할당된 USB 기기가 출력에 나열되어 있는지 확인합니다.

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
      <name>simple_usb</name>
      <memory unit='KiB'>2097152</memory>
      <vcpu placement='static'>4</vcpu>
      <resource>
        <partition>/machine</partition>
      </resource>
      <os>
        <type arch='aarch64' machine='virt-6.2'>hvm</type>
        <kernel>/mnt/overlay/guest/Image</kernel>
        <cmdline>root=/dev/vda</cmdline>
        <boot dev='hd'/>
      </os>
      <features>
        <gic version='3'/>
      </features>
      <cpu mode='host-passthrough' check='none'/>
      <devices>
        <console type='pty'>
        </console>
        <disk type="file" device="disk">
          <driver name="qemu" type="raw"/><!-- Specify rootfs image file here -->
          <source file="/mnt/overlay/guest/rootfs.ext4"/>
          <target dev="vda" bus="virtio"/>
        </disk>
        <controller type='usb' index='0' model='qemu-xhci' ports='4'/>
        <hostdev mode='subsystem' type='usb' managed='yes'>
          <source><!-- Specify USB device VID/PID here -->
            <vendor id='0x0781'/>
            <product id='0x5567'/>
          </source>
        </hostdev>
      </devices>
    </domain>
    Copy to clipboard

**PCI 개요**

호스트 컴퓨터에 열거된 PCI 기기를 식별하여 게스트에 할당할 수 있습니다. 호스트에 열거된 모든 PCI 기기를 볼 수 있는 방법은 `lspci` 명령어를 사용하는 것입니다. `[domain:]bus:device.function` 으로 기기를 찾습니다. `lspci` 명령에 대한 자세한 내용은 [lspci(8)—Linux manual page](https://man7.org/linux/man-pages/man8/lspci.8.html) 를 참조하세요.

다음 예시는 도메인, 버스, 기기에 대해 지원되는 값과 `Ethernet controller: Aquantia Corp. AQC107 NBase-T/IEEE 802.3bz` 기기에 대한 함수를 보여줍니다.

- 도메인은 0001입니다.
- 버스는 01입니다.
- 기기는 00입니다.
- 함수는 0입니다.

sh-5.1# lspci
    0000:00:00.0 PCI bridge: Qualcomm Device 0115
    0000:01:00.0 Network controller: Qualcomm QCNFA765 Wireless Network Adapter (rev 01)
    0001:00:00.0 PCI bridge: Qualcomm Device 0115
    0001:01:00.0 Ethernet controller: Aquantia Corp. AQC107 NBase-T/IEEE 802.3bz
    Copy to clipboard

참고

XML 콘텐츠를 `/mnt/overlay/guest/libvirt_pci.xml` 파일에 복사한 후 기기 요구사항에 따라 XML의 `hostdev` 섹션을 변경합니다.

게스트 VM을 시작하려면 [Libvirt](https://docs.qualcomm.com/doc/80-70020-3KO/topic/virtualization.html#id7) 를 참조하세요. 게스트 VM을 시작한 후에는 콘솔에 연결하고 게스트의 `lspci` 출력을 확인하세요. 게스트에게 할당된 PCI 기기가 출력에 나열되어 있는지 확인합니다.

참고

출력은 QEMU 및 Libvirt에 의해 선택된 게스트 PCI 토폴로지에 따라 여러 가지 슬롯을 표시합니다.

다음 XML의 `hostdev` 에서 `managed` 가 *yes* 로 표시될 경우 PCI 기기는 게스트로 전달되기 전에 호스트에서 분리되며, 게스트가 나간 후 호스트에 다시 연결됩니다. 자세한 내용은 [USB / PCI / SCSI devices](https://libvirt.org/formatdomain.html#usb-pci-scsi-devices) 를 참조하세요.

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
      <name>simple_pci</name>
      <memory unit='KiB'>2097152</memory>
      <vcpu placement='static'>4</vcpu>
      <resource>
        <partition>/machine</partition>
      </resource>
      <os>
        <type arch='aarch64' machine='virt-6.2'>hvm</type>
        <kernel>/mnt/overlay/guest/Image</kernel>
        <cmdline>root=/dev/vda</cmdline>
        <boot dev='hd'/>
      </os>
      <features>
        <gic version='3'/>
      </features>
      <cpu mode='host-passthrough' check='none'/>
      <devices>
        <console type='pty'>
        </console>
        <disk type="file" device="disk">
          <driver name="qemu" type="raw"/>
          <source file="/mnt/overlay/guest/rootfs.ext4"/>
          <target dev="vda" bus="virtio"/>
        </disk>
        <hostdev mode='subsystem' type='pci' managed='yes'>
          <source><!-- specify your PCI device details here -->
            <address domain='0x0001' bus='0x01' slot='0x00' function='0x0'/>
          </source>
        </hostdev>
      </devices>
    </domain>
    Copy to clipboard

**UART 패스스루 개요**

게스트에서 사용할 UART에 해당하는 `/dev/ttyX` 텔레타이프(TTY) 기기 파일을 식별합니다. 호스트에 있는 어떤 애플리케이션도 이 인터페이스를 사용하지 않아야 합니다.

참고

호스트의 `/mnt/overlay/guest/libvirt_uart.xml` 파일에 XML 콘텐츠를 복사한 후 기기 요구사항에 따라 TTY 기기 파일을 수정하세요.

게스트 VM을 시작하고 콘솔에 연결합니다. `/dev/virtio-ports/hostserial` 의 시리얼 인터페이스는 호스트에서 실제 UART의 프런트엔드 역할을 합니다. 다음 XML 파일을 사용하세요.

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
      <name>simple_uart</name>
      <memory unit='KiB'>2097152</memory>
      <vcpu placement='static'>4</vcpu>
      <resource>
        <partition>/machine</partition>
      </resource>
      <os>
        <type arch='aarch64' machine='virt-6.2'>hvm</type>
        <kernel>/mnt/overlay/guest/Image</kernel>
        <cmdline>root=/dev/vda</cmdline>
        <boot dev='hd'/>
      </os>
      <features>
        <gic version='3'/>
      </features>
      <cpu mode='host-passthrough' check='none'/>
      <devices>
        <console type='pty'>
        </console>
        <channel type='dev'>
          <source path='/dev/ttyMSM0'/>
          <target type='virtio' name='hostserial'/>
          <address type='virtio-serial' controller='0' bus='0' port='1'/>
        </channel>
        <disk type="file" device="disk">
          <driver name="qemu" type="raw"/>
          <source file="/mnt/overlay/guest/rootfs.ext4"/>
          <target dev="vda" bus="virtio"/>
        </disk>
      </devices>
    </domain>
    Copy to clipboard

#### KVM 사용자 지정

다음 기능을 사용하여 KVM 하이퍼바이저를 특정 요구사항에 부합하게 수정할 수 있습니다.

#### 원격 명령 실행

게스트 OS 사용자 공간에서 QEMU 게스트 에이전트를 활성화하려면 호스트에서 게스트 VM에 대한 원격 명령어를 실행하세요. `qemu-ga` 에 대한 자세한 내용은 [QEMU Guest Agent](https://qemu-project.gitlab.io/qemu/interop/qemu-ga.html) 를 참조하세요.

`qemu-agent-command` 는 `guest-exec` 및 `guest-exec-status` 를 하위 명령으로 포함하여 게스트 VM의 상태 또는 출력을 실행하고 확인하는 virsh 명령입니다. virtio-serial 인터페이스를 통해 `qemu-ga` 를 구성하는 방법에 대한 자세한 내용은 [QEMU Guest Agent](https://wiki.libvirt.org/Qemu_guest_agent.html) 를 참조하세요.

`virt-exec` 이 virsh 명령을 래핑하고 인터페이스를 제공하는 방법에 대한 자세한 내용은 [kvm-qemu/virt-exec](https://github.com/ildar-shaimordanov/my-scripts/blob/master/kvm-qemu/virt-exec) 를 참조하세요.

다음 예시는 `virt-exec` 유틸리티를 사용하여 호스트 컴퓨터의 게스트 VM에 대해 `/proc/meminfo` 를 실행하는 방법을 보여줍니다.

sh-5.2# ./virt-exec testvm cat /proc/meminfo | grep -i total
    MemTotal:        1968056 kB
    SwapTotal:             0 kB
    VmallocTotal:   133141626880 kB
    CmaTotal:          32768 kB
    HugePages_Total:       0
    Copy to clipboard

##### Watchdog 구성

게스트 VM에서는 QEMU 에뮬레이트된 I6300 ESB watchdog 기기가 지원됩니다. Linux 커널은 이 watchdog 드라이버를 보유하며, 표준 watchdog 문자 입출력 기기를 공개합니다. watchdog을 활성화하려면 게스트 커널 구성에서 `CONFIG_I6300ESB_WDT` 를 설정하세요. 게스트 사용자 공간 데몬은 watchdog을 초기화해야 합니다.

guest Libvirt XML에는 watchdog 타이머에 대해 `poweroff` 또는 `reset` 을 선택할 수 있는 옵션이 있습니다. 자세한 내용은 [Watchdog devices](https://libvirt.org/formatdomain.html#watchdog-devices) 를 참조하세요

게스트 XML에 다음 코드 조각을 추가하여 QEMU에서 I6300 ESB watchdog 에뮬레이션을 활성화합니다. 기본 동작은 게스트를 초기화하는 `reset` 입니다.

<devices>
      <watchdog model='i6300esb'/>
    </devices>
    Copy to clipboard

##### KVM 추적

KVM 추적을 활성화하려면 다음 명령어를 실행합니다.

echo 1 > /sys/kernel/tracing/events/kvm/enable
    Copy to clipboard

KVM 게스트의 상호 작용은 커널 함수 추적(ftrace)에 기록됩니다. KVM과 게스트 VM 간의 상호 작용을 검사하려면 커널 추적 버퍼를 읽습니다.

QEMU는 추적 이벤트도 지원하며, 해당 이벤트는 커널 ftrace로 리디렉션될 수 있습니다. QEMU 추적 백엔드 이벤트를 ftrace 버퍼로 리디렉션하는 방법에 대한 자세한 내용은 [Trace backends](https://qemu-project.gitlab.io/qemu/devel/tracing.html#trace-backends) 를 참조하세요. 이 옵션은 Qualcomm Linux 릴리스에서 기본값으로 선택되어 있습니다.

QEMU 코드에서 VirtIO 추적을 활성화하여 게스트 VM을 시작하려면 다음 명령어를 실행합니다.

qemu-system-aarch64 \
        -M virt -m 2G \
        -kernel /mnt/overlay/guest/Image \
        -drive file=/mnt/overlay/guest/rootfs.ext4,if=virtio,format=raw \
        -append "root=/dev/vda" \
        -cpu host --enable-kvm -smp 4 -nographic \
        -trace "virtio*"
    Copy to clipboard

Last Published: Jan 01, 2026

[Previous Topic
실시간(RT) 커널 개요](https://docs.qualcomm.com/bundle/publicresource/80-70020-3KO/topics/real_time_kernel_overview.md) [Next Topic
커널 로그 캡처](https://docs.qualcomm.com/bundle/publicresource/80-70020-3KO/topics/capture-the-kernel-logs.md)