# 啟用虛擬化

虛擬化使用軟體在電腦硬體上建立抽象層。

抽象層將單一電腦的硬體元件 (例如處理器、記憶體和儲存裝置) 分成不同的虛擬實體，稱為虛擬機器 (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 虛擬化解決方案

Qualcomm 採用 Gunyah，一種專為強大的安全性、高效能、OS 獨立性和更高的 CPU 權限層級而設計的 type-1 虛擬機管理程式。

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 管理、安全記憶體捐贈、出借和共用。 |

[crosvm](https://chromium.googlesource.com/chromiumos/platform/crosvm) 虛擬記憶體監控器 (VMM) 已新增 Gunyah 虛擬機管理程式。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 虛擬化解決方案**

欲深入瞭解類型 1 虛擬機管理程式(hypervisor)，請參閱 [gunyah-hypervisor](https://github.com/quic/gunyah-hypervisor)。

### 客體 VM 建置支援

若要編譯客體 VM 核心和 initrd 映像，請依照下述程序操作：

在客體 VM 核心編譯過程中，建置客體核心和最小 `rootfs`。`qcom_vm_defconfig` 是用於編譯客體核心的基礎組態。`qcom_vm_debug.config` 建置客體 VM 的除錯變體。

`crosvm` 擔任 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 映像，在啟動過程中使用。
- 在 `build-qcom-wayland\tmp-qcom-guestvm-glibc\deploy\images\<machine-name>` 目錄中產生 `initramfs-ostree-image-<machine>.cpio.gz` 檔案。
- 在啟動的裝置上，映像儲存在系統 rootfs 內的 `/var/gunyah/initrd.img` 檔案中。

#### 客體 VM 核心映像

- `svm-initramfs-qcom-image-<SoC>.cpio.gz` 映像檔是為次要虛擬機（SVM）所產生的，該映像即為客體核心映像。
- 在 `build-qcom-wayland/tmp-glibc/deploy/images/<SoC>/linux-svm-kernel-qcom` 目錄中產生 SVM 核心映像。
- 在啟動的裝置上，映像位於系統 rootfs 內的 `/var/gunyah/Image` 檔案中。

`initrd.img` 和 SVM 核心映像被封裝在 `system.img` 檔案中。最終 `system.img` 檔案位於與其他映像 `<workspace>/build-qcom-wayland/tmp-glibc/deploy/images/<SoC>/qcom-console-image` 相同的目錄中。

### 啟動客體虛擬機器

使用 `crosvm` 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

以下是 `crosvm` 命令支援，用來啟動客體 VM 的參數：

表：支援的參數

| 參數 | 說明 |
| --- | --- |
| /usr/bin/crosvm<br>    Copy to clipboard | 顯示 `crosvm` 二進位檔案的路徑 |
| --log-level=debug<br>    Copy to clipboard | 在執行 `crosvm` 時設定要除錯的記錄層級 |
| --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 | 停用用來為客體作業系統的熵池提供種子值的熵來源。 |
| --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 和預設 RAM 啟動 VM

若要透過兩個 CPU 啟動客體 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 和 512 MB RAM 啟動 VM

若要透過兩個 CPU 和 512 MB 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（Kernel-based Virtual Machine，基於核心的虛擬機）是一個開源的虛擬化模組，整合在 Linux 核心中。這種整合使 KVM 能夠充當虛擬機管理程式（Hypervisor）。KVM 支援硬體輔助虛擬化，用於執行客體作業系統。

備註

僅在 Dragonwing™ IQ-8275 和 Dragonwing IQ-9075 SoC 上支援 KVM。

**圖：KVM/QEMU 虛擬化的高階概覽**

以下是在 Arm CPU 架構系統上啟用 KVM 虛擬管理程式(Hypervisor )的必要條件：

- 啟動載入器在例外層級 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) 服務。因此，啟用 KVM 時，任何需要 aDSP、cDSP 和神經訊號處理器 (NSP) 的應用程式都無法運作。
- Linux 核心支援 KVM 的電源狀態協調介面 (PSCI)。PSCI 確保 CPU 熱插拔和低功耗模式 (LPM) 透過 KVM 正常運作。

#### 虛擬機器管理程式

使用快速模擬器 (QEMU) 作為虛擬機器管理程式 (VMM)，以進行虛擬化。Libvirt 擔任管理層，與 QEMU 互動以啟動、停止和管理虛擬機器。

##### QEMU

使用 QEMU 搭配 KVM 作為虛擬機監控器（VMM），可讓虛擬機（VM）以接近原生效能執行。QEMU 支援模擬裝置，例如 virtio 裝置，這些裝置提供高效能的 I/O 操作，並允許虛擬機存取 USB 和 PCI（周邊元件互連）裝置。每個 QEMU 程序及其執行緒負責管理一個虛擬機。可直接呼叫 QEMU 來建立虛擬機。如需更多資訊，請參閱 [QEMU](https://qemu-project.gitlab.io/qemu/index.html)。

##### Libvirt

Libvirt 是一套工具組，包含 API 函式庫、一個守護程式（libvirtd），以及一個命令列工具（virsh），用於管理虛擬機（VM）。其中 virsh 工具特別適合用來管理多個虛擬機。如需更多資訊，請參閱 [virsh](https://www.libvirt.org/manpages/virsh.html)。

#### 啟動客體 VM

若要啟動 ARM64 架構 VM，請使用在內部與 libvirt 結合的 QEMU 或 virsh 命令。這些命令可讓您為 VM 配置 CPU、記憶體和儲存空間。指定分配給 VM 的虛擬 CPU 數量和記憶體量。此外，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` 檔案中。使用以 `rootfs_simple` 而不是 `initrd_simple` 作為 VM 網域 / 名稱的 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 在半虛擬化的虛擬機管理環境中抽象化裝置。它提供一個 I/O 半虛擬化框架，用來與半虛擬化（paravirt）裝置互動。虛擬機監控器（VMM）或虛擬機管理程式（Hypervisor，HYP）會使用 virtio 來模擬大多數暴露給虛擬機（VM）的裝置。

#### 主要特色

以下是虛擬網路的主要特色：

- 半虛擬化和全虛擬化

> 
> 
> - 完全虛擬化（Full virtualization）：在完全虛擬的環境中，客體虛擬機（VM）無法察覺虛擬機管理程式（Hypervisor）的存在，並且可以在不經修改的情況下運行。然而，由於需要模擬硬體裝置，完全虛擬化會導致較高的系統負擔（overhead）。
>     - 半虛擬化（Paravirtualization）：在半虛擬化的環境中，虛擬機（VM）能夠辨識虛擬機管理程式（Hypervisor），並且需要對作業系統進行修改。半虛擬化允許客體與主機之間進行高效率的通訊。
- 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）與虛擬機管理程式（Hypervisor）之間的上下文切換所造成的負擔。

    - 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：使用者空間實作，以另外的處理序處理資料平面，為工作負載提供靈活性和更好的效能。欲深入瞭解 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-3TC/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

備註

將 XML 內容複製到主機的 `/mnt/overlay/guest/libvirt_virtio_9p.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。透過 virtio 介面支援 VSOCK。virtio-vsock 是以 vhost 為基礎的 virtio 裝置，由主機核心管理所有資料傳輸，KVM 超管理器則控制資訊。

若要在 KVM 和 QEMU 環境中建立 VSOCK 連線，請指定脈絡識別碼 (CID) 和連接埠號碼。CID 是在 VSOCK 環境中指派給各個 VM 的唯一識別碼，用來路由主機與虛擬機器之間的通訊。主機的 CID 為 2，指派給 VM 的 CID 則從 3 開始。

下表列出 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：若要將 VSOCK 裝置與 libvirt 搭配使用，請在 VM XML 組態檔中定義 VSOCK 裝置。

    若要使用 libvirt 介面啟動客體 VM，請參閱 [Libvirt](https://docs.qualcomm.com/doc/80-70020-3TC/topic/virtualization.html#id7)。

將 XML 內容複製到主機上的 `/mnt/overlay/guest/libvirt_virtio_vsock.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. 若要配置 VM 以納入 virtio-block 裝置，請在 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-3TC/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

備註

將 XML 內容複製到主機上的 `/mnt/overlay/guest/libvirt_virtio_blk.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 是半虛擬化的輸入 / 輸出記憶體管理單元 (IOMMU)，在虛擬環境中提供直接記憶體存取 (DMA) 管理。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-3TC/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
> 
> 
> 
> 備註
> 
> 
> 將 XML 內容複製到主機上的 `/mnt/overlay/guest/libvirt_virtio_iommu.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 網域，該網域是 IOMMU 群組 `0` 的一部分。

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. 若要配置 VM 以納入 virtio-net 裝置，請在 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-3TC/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. 若要配置 VM 以納入 virtio-serial 裝置，請在 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-3TC/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

備註

將 XML 內容複製到主機上的 `/mnt/overlay/guest/virtio_serial.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 記憶體氣球裝置用來管理客體虛擬機的記憶體，允許主機系統從虛擬機中回收記憶體。記憶體氣球會指示虛擬機將部分記憶體歸還給主機。這個過程會在客體虛擬機內部「充氣」記憶體氣球，從而減少虛擬機可用於其他任務的記憶體。客體作業系統會決定要歸還哪些記憶體頁面，表示哪些頁面它不再需要或不會存取。主機接著會將這些頁面從虛擬機中解除映射，標記為不可供虛擬機使用，並讓主機系統重新使用這些記憶體。如果客體虛擬機之後需要更多記憶體，主機會「放氣」氣球，將頁面歸還給虛擬機。這項功能讓每個虛擬機在記憶體被動態管理的情況下仍能持續運作。

讓 virtio-balloon 裝置在客體 VM 與主機之間重新分配實體記憶體的方式如下：

1. 氣球充氣：客體驅動程式分配記憶體並通知主機。隨後主機將充氣的記憶體改用於其他 VM。
2. 氣球放氣：通知主機後，客體驅動程式會釋出先前分配的記憶體，並讓客體 VM 能夠使用放氣的記憶體。

`Target balloon size` 透過變更客體 VM 記憶體大小的要求來控制氣球充氣或放氣。透過 QEMU 監控模式或 virsh 命令傳送大小調整要求。

以下是 virtio-balloon 裝置的主要特色：

- 記憶體管理：根據要求即時調整記憶體分配。
- 效率：從閒置 VM 回收未使用的記憶體並重新分配給使用中 VM。
- 靈活性：支援各種虛擬化設定，將資源使用最佳化。

備註

確保已在客體核心中啟用 `CONFIG_VIRTIO_BALLOON`。

若要使用 virtio-balloon 裝置，請執行以下操作：

1. 配置 VM 以納入 virtio-balloon 裝置，在 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-3TC/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

備註

將 XML 內容複製到主機上的 `/mnt/overlay/guest/libvirt_virtio_balloon.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 初始記憶體 (2 GB)，請執行以下命令：

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

- 若要讓氣球充氣並將客體 VM 記憶體降低至 512 MB，請執行以下命令：

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 記憶體回到 2 GB)：

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

###### 存取主機裝置

您可以在 Guest 虛擬機中使用主機系統上已列舉的裝置。指派裝置給 Guest 的介面會依據裝置類型而有所不同。有些裝置會作為 QEMU 模擬裝置的後端，例如 UART。請將通用非同步接收器/傳送器（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 檔案。

使用以下範例 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-3TC/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) 裝置檔案，以便從客體使用。確保主機上無任何應用程式使用此介面。

備註

將 XML 內容複製到主機上的 `/mnt/overlay/guest/libvirt_uart.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` 是 virsh 命令，包含 `guest-exec` 和 `guest-exec-status` 子命令以執行和確認客體 VM 的狀態或輸出。欲深入瞭解如何透過 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

##### 看門狗組態

在客體 VM 中支援 QEMU 模擬的 I6300 ESB 看門狗裝置。Linux 核心已內建此看門狗的驅動程式，並提供標準的看門狗字元裝置介面。若要啟用看門狗功能，請在客體核心設定中啟用 CONFIG\_I6300ESB\_WDT。此外，客體使用者空間必須有一個常駐程式（daemon）定期喚醒看門狗（pet the watchdog）。

客體 Libvirt XML 有在看門狗逾時後選擇 `poweroff` 或 `reset` 的選項。如需更多資訊，請參閱 [Watchdog devices](https://libvirt.org/formatdomain.html#watchdog-devices)。

將以下片段新增至客體 XML 以在 QEMU 中啟用 I6300 ESB 看門狗模擬。預設操作為 `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-3TC/topics/real_time_kernel_overview.md) [Next Topic
擷取核心紀錄](https://docs.qualcomm.com/bundle/publicresource/80-70020-3TC/topics/capture-the-kernel-logs.md)