# Bật tính năng ảo hóa

Tính năng ảo hóa sử dụng phần mềm để tạo lớp trừu tượng trên phần cứng máy tính.

Lớp trừu tượng này chia các thành phần phần cứng của một máy tính, chẳng hạn như bộ xử lý, bộ nhớ và dung lượng lưu trữ thành các thực thể ảo khác nhau, được gọi là máy ảo (VM). Mỗi VM chạy hệ điều hành riêng và hoạt động như một máy tính độc lập, mặc dù nó chạy trên cùng một phần cứng nền tảng của máy tính.

<?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>

**Hình: Ảo hóa**

Ghi chú

Công nghệ ảo hóa chỉ được hỗ trợ trên biến thể BSP tùy chỉnh.

## Giải pháp ảo hóa Qualcomm

Qualcomm sử dụng Gunyah, một trình quản lý ảo hóa loại 1 được thiết kế để có tính bảo mật mạnh mẽ, hiệu năng cao, cấp đặc quyền CPU cao hơn và hoạt động độc lập với hệ điều hành..

Gunyah đảm bảo chức năng cốt lõi để tăng cường bảo mật mà không phụ thuộc vào bất kỳ kernel hệ điều hành hoặc mã có đặc quyền thấp nào. Gunyah được thiết kế cho các use case riêng của máy ảo và để khởi chạy các máy ảo riêng biệt từ máy ảo chủ ít tin cậy hơn.

Hình sau đây minh họa kiến trúc giải pháp ảo hóa 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>

**Hình: Kiến trúc giải pháp ảo hóa Qualcomm**

Gunyah cung cấp các tính năng sau:

Bảng: Tính năng của Gunyah

| Tính năng | Mô tả |
| --- | --- |
| Luồng và lập lịch | Trình lập lịch sẽ lên lịch cho các CPU ảo (VCPU) trên các CPU vật lý và cho phép chia sẻ thời gian của các CPU. |
| Quản lý bộ nhớ | Gunyah theo dõi quyền sở hữu và mức sử dụng bộ nhớ dưới sự kiểm soát của mình. Gunyah cung cấp các API quản lý bộ nhớ động cấp thấp, làm nền tảng cho các cơ chế cấp cao hơn như cấp phát, cho mượn và chia sẻ bộ nhớ. |
| Ảo hóa tín hiệu ngắt | Gunyah quản lý các tín hiệu ngắt được gửi trực tiếp đến máy ảo được chỉ định . |
| Giao tiếp giữa các máy ảo | Hàng đợi thông báo và cơ chế doorbell cung cấp các phương thức giao tiếp giữa các máy ảo. |
| Ảo hóa thiết bị | Ảo hóa bán phần các thiết bị được hỗ trợ thông qua hoạt động giao tiếp giữa các máy ảo và các primitive của virtio. Công nghệ ảo hóa và mô phỏng phần cứng hỗ trợ các tính năng và thiết bị kiến trúc cấp thấp, chẳng hạn như bộ hẹn giờ CPU và bộ điều khiển tín hiệu ngắt. |
| Trình quản lý tài nguyên | Gunyah hỗ trợ một máy ảo root sở hữu ban đầu toàn bộ bộ nhớ và tài nguyên đầu vào/đầu ra của các máy ảo. Trình quản lý tài nguyên Gunyah là máy ảo root được tích hợp mặc định và cung cấp các dịch vụ cấp cao bao gồm quản lý máy ảo động, cấp phát, cho mượn và chia sẻ bộ nhớ bảo mật. |

Tính năng hỗ trợ trình quản lý ảo hóa Gunyah được thêm vào trình giám sát bộ nhớ ảo (VMM) [crosvm](https://chromium.googlesource.com/chromiumos/platform/crosvm). crosvm tương tác với trình quản lý máy ảo Gunyah trong kernel thông qua giao diện `/dev/gunyah` và tạo ra một máy ảo.

Hình sau đây minh họa các khối trong giải pháp ảo hóa 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>

**Hình: Giải pháp ảo hóa Qualcomm**

Để biết thêm thông tin về trình quản lý ảo hóa loại 1, hãy xem [gunyah-hypervisor](https://github.com/quic/gunyah-hypervisor).

### Hỗ trợ bản build máy ảo khách

Để biên dịch kernel máy ảo khách và ảnh initrd, hãy sử dụng quy trình sau:

Trong quá trình biên dịch kernel máy ảo khách, cả kernel máy ảo và `rootfs` tối giản đều được build. `qcom_vm_defconfig` đóng vai trò là cấu hình cơ sở để biên dịch kernel máy ảo. `qcom_vm_debug.config` build biến thể gỡ lỗi của máy ảo khách.

`crosvm` đóng vai trò là VMM và tương tác với trình quản lý VM Gunyah trong kernel thông qua giao diện `/dev/gunyah` để tạo Máy ảo.

#### Build máy ảo khách

Để biết thêm thông tin về hỗ trợ `crosvm`, hãy xem [Tạo máy ảo thứ cấp](https://docs.qualcomm.com/bundle/publicresource/topics/80-70020-27/qualcomm_linux_software_components.html#create-secondary-virtual-machine).

Sau khi quá trình build hoàn tất, một số ảnh sẽ được tạo ra. Những ảnh này được lưu trữ trong thư mục `<workspace>/build-qcom-wayland/tmp-glibc/deploy/images/<SoC>/qcom-console-image`.

Để biên dịch máy ảo khách, hãy chạy lệnh sau:

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

#### Ảnh initrd của máy ảo khách

- Tệp `initramfs-ostree-image-<machine-name>.cpio.gz` được tạo cho máy ảo khách. Ảnh này chứa ảnh initrd, được dùng trong quá trình khởi động.
- Tệp `initramfs-ostree-image-<machine>.cpio.gz` được tạo trong thư mục `build-qcom-wayland\tmp-qcom-guestvm-glibc\deploy\images\<machine-name>`.
- Trên thiết bị đã khởi động, ảnh được lưu trữ trong tệp `/var/gunyah/initrd.img` trong rootfs của hệ thống.

#### Ảnh kernel của máy ảo khách

- Ảnh `svm-initramfs-qcom-image-<SoC>.cpio.gz` được tạo cho máy ảo thứ cấp (SVM), là ảnh kernel máy ảo khách.
- Ảnh kernel SVM được tạo trong thư mục `build-qcom-wayland/tmp-glibc/deploy/images/<SoC>/linux-svm-kernel-qcom`.
- Trên thiết bị đã khởi động, ảnh nằm trong tệp `/var/gunyah/Image` trong rootfs của hệ thống.

Cả ảnh kernel `initrd.img` và SVM đều được đóng gói trong tệp `system.img`. Tệp `system.img` cuối cùng nằm trong cùng thư mục với các ảnh khác `<workspace>/build-qcom-wayland/tmp-glibc/deploy/images/<SoC>/qcom-console-image`.

### Khởi chạy máy ảo khách

Sử dụng VMM `crosvm` và trình quản lý ảo hóa Gunyah để khởi chạy máy ảo khách.

Để khởi chạy máy ảo, hãy chạy lệnh sau:

# /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

Sau đây là các tham số được hỗ trợ cho lệnh `crosvm` để khởi chạy máy ảo khách:

Bảng: Tham số được hỗ trợ

| Tham số | Mô tả |
| --- | --- |
| /usr/bin/crosvm<br>    Copy to clipboard | Hiển thị đường dẫn của tệp thực thi `crosvm` |
| --log-level=debug<br>    Copy to clipboard | Đặt mức ghi log để gỡ lỗi trong khi chạy `crosvm` |
| --no-syslog<br>    Copy to clipboard | Tắt syslog |
| --disable-sandbox<br>    Copy to clipboard | Tắt sandboxing |
| --hypervisor gunyah<br>    Copy to clipboard | Chỉ định trình quản lý ảo hóa sẽ được sử dụng (trong trường hợp này là `gunyah`) |
| --protected-vm-without-firmware<br>    Copy to clipboard | Chỉ ra rằng máy ảo được bảo vệ và không yêu cầu firmware |
| --serial=...<br>    Copy to clipboard | Đặt cấu hình các thiết bị serial cho đầu vào/đầu ra |
| --initrd /var/gunyah/initrd.img<br>    Copy to clipboard | Chỉ định ảnh ổ đĩa RAM ban đầu (initrd) |
| --no-balloon<br>    Copy to clipboard | Tắt tính năng balloon bộ nhớ |
| --no-rng<br>    Copy to clipboard | Vô hiệu hóa nguồn entropy được dùng để đặt nhóm entropy của hệ điều hành máy  ảo khách |
| --params "..."<br>    Copy to clipboard | Chỉ định các tùy chọn dòng lệnh kernel |
| /var/gunyah/Image<br>    Copy to clipboard | Chỉ định đường dẫn tới ảnh kernel |

#### Xem máy ảo và log khởi động

Đầu ra mẫu sau mô tả VM log:

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

Đoạn mã sau mô tả log khởi động:

[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

#### Khởi chạy máy ảo với hai CPU và RAM mặc định

Để khởi chạy máy ảo khách có hai CPU, hãy sử dụng tham số `--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

Đoạn mã sau đây hiển thị log của máy ảo:

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

#### Khởi chạy máy ảo với hai CPU và RAM 512 MB

Để khởi chạy máy ảo khách có hai CPU và RAM 512 MB, hãy sử dụng các tham số `--cpus num-cores=2` và `--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

Đoạn mã sau đây hiển thị log của máy ảo:

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

#### Khởi chạy máy ảo với thiết bị khối

Để khởi chạy máy ảo, hãy chạy lệnh sau:

#/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

- Sử dụng cờ `--block` để chỉ định tên thiết bị khối (trong trường hợp này là disk.img).
- Cờ này tạo các node `/dev/vda, /dev/vdb` và `/dev/vd*` trong máy ảo khách.

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

Để mount thiết bị vào máy ảo khách, hãy chạy lệnh sau: `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

### Tổng quan về KVM

Máy ảo dựa trên kernel (KVM) là mô-đun ảo hóa nguồn mở được tích hợp vào Linux kernel. Sự tích hợp này cho phép KVM hoạt động như một trình quản lý ảo hóa. KVM hỗ trợ ảo hóa phần cứng cho hệ điều hành máy ảo khách.

Ghi chú

KVM chỉ được hỗ trợ trên SoC Dragonwing™ IQ-8275 và Dragonwing IQ-9075.

**Hình: Tổng quan cấp cao về ảo hóa KVM/QEMU**

Sau đây là các điều kiện tiên quyết để bật KVM Hypervisor trên các hệ thống chạy CPU Arm:

- Trình tải khởi động khởi động Linux kernel ở mức exception 2 (EL2)
- `CONFIG_KVM` được bật trong cấu hình kernel

Để xác minh xem KVM có sẵn trên thiết bị hay không, hãy chạy lệnh sau để xác minh sự tồn tại của `/dev/kvm`:

ls -l /dev/kvm
    Copy to clipboard

Trong quy trình khởi động mặc định của Qualcomm Linux, Linux Kernel bắt đầu ở EL1 trong khi Gunyah đảm nhận vai trò của Hypervisor. Để biết hướng dẫn về cách khởi động Linux Kernel trong EL2 để kích hoạt KVM Hypervisor, hãy xem [UEFI](https://docs.qualcomm.com/bundle/publicresource/topics/80-70020-4/boot-developer-touchpoints.html#uefi).

Cân nhắc điều sau đây khi bật KVM:

- Tiện ích mở rộng máy chủ ảo (VHE) được bật theo mặc định trên tất cả các SoC Qualcomm Linux hỗ trợ tập lệnh Arm (v8.1) trở lên. Cấu hình này cho phép toàn bộ Linux Kernel chạy ở EL2 với một số sửa đổi nhỏ. Kernel hệ điều hành máy ảo khách và không gian người dùng chạy ở EL1 và EL0. Với VHE, quá trình chuyển đổi giữa máy ảo khách và máy chủ ít bị ảnh hưởng hơn vì kernel máy ảo khách và máy chủ hoạt động ở các mức exception khác nhau.
- Linux Kernel quản lý toàn bộ nhớ truy cập không bảo mật. Nó không hỗ trợ các use case bảo mật mà yêu cầu cách ly đặc biệt khỏi Linux kernel. Trình quản lý ảo hóa Gunyah kiểm soát các bảng trang S2 của Linux Kernel trong quy trình khởi động mặc định.
- Dịch vụ tải ảnh ngoại vi (PIL) không được hỗ trợ. Do đó, bất kỳ ứng dụng nào yêu cầu aDSP, cDSP và bộ xử lý tín hiệu nơ-ron (NSP) đều không hoạt động khi KVM được bật.
- Giao diện điều phối trạng thái nguồn (PSCI) cho KVM được hỗ trợ trên Linux kernel. PSCI đảm bảo chế độ hotplug CPU và chế độ tiết kiệm điện (LPM) hoạt động chính xác với KVM.

#### Trình quản lý máy ảo

Trình giả lập nhanh (QEMU) được dùng làm trình quản lý máy ảo (VMM) cho quá trình ảo hóa. Libvirt hoạt động như một lớp quản lý tương tác với QEMU để khởi động, dừng và quản lý máy ảo.

##### QEMU

Sử dụng QEMU như một VMM với KVM để chạy máy ảo ở hiệu năng gần như máy thực. QEMU hỗ trợ các thiết bị mô phỏng (như thiết bị virtio) để cung cấp các hoạt động I/O hiệu năng cao và cho phép truy cập vào các thiết bị USB và kết nối thành phần ngoại vi (PCI) từ máy ảo. Tiến trình QEMU và các luồng của tiến trình này quản lý một máy ảo duy nhất. Gọi trực tiếp QEMU để tạo máy ảo. Để biết thêm thông tin, hãy xem [QEMU’s](https://qemu-project.gitlab.io/qemu/index.html).

##### Libvirt

Libvirt là một bộ công cụ, bao gồm thư viện API, daemon (libvirtd) và tiện ích dòng lệnh (virsh) để quản lý máy ảo. Tiện ích virsh hữu ích khi quản lý nhiều máy ảo. Để biết thêm thông tin, hãy xem [virsh](https://www.libvirt.org/manpages/virsh.html).

#### Khởi chạy máy ảo khách

Để khởi chạy máy ảo ARM64, hãy sử dụng lệnh QEMU hoặc virsh hoạt động dựa trên libvirt. Các lệnh cho phép bạn đặt cấu hình máy ảo với CPU, bộ nhớ và dung lượng lưu trữ. Chỉ định số lượng CPU ảo và dung lượng bộ nhớ được phân bổ cho máy ảo. Ngoài ra, máy ảo có thể khởi động bằng ramdisk (initrd) và hệ thống tệp root `.ext4`.

Ghi chú

Xác minh rằng ảnh kernel máy ảo (`Image`), CPIO hệ thống tệp root (`rootfs.cpio.gz`) và ảnh hệ thống tệp root (`rootfs.ext4`) có trong thư mục `/mnt/overlay/guest` trong hệ thống tệp máy chủ trước khi khởi chạy máy ảo. Những đường dẫn và định dạng tệp này chỉ là ví dụ để tham khảo.

##### QEMU

Để khởi động các máy ảo có nhiều cấu hình khác nhau, hãy chạy các lệnh sau:

###### Khởi động bằng 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

###### Khởi động bằng ảnh 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 cho phép bạn sử dụng QEMU và KVM để tạo, tương tác và quản lý máy ảo.

###### Quản lý máy ảo bằng virsh

virsh cung cấp một loạt các lệnh để tạo, kiểm soát và giám sát máy ảo.

Sau đây là các lệnh virsh được dùng để quản lý máy ảo:

# 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

###### Khởi động bằng ramdisk

Sao chép nội dung XML sau vào `/mnt/overlay/guest/libvirt_initrd_simple.xml` trên máy chủ:

<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

###### Khởi động bằng ảnh rootfs

Sao chép tệp XML sau vào hệ thống tệp lưu trữ trong tệp `/mnt/overlay/guest/libvirt_rootfs_simple.xml`. Sử dụng lệnh quản lý máy ảo với `rootfs_simple` làm tên miền/tên máy ảo thay vì `initrd_simple`.

<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 framework

Virtio trừu tượng hóa các thiết bị trong môi trường trình quản lý ảo hóa bán phần. Virtio cung cấp một framework ảo hóa bán phần I/O để tương tác với các thiết bị ảo hóa bán phần (paravirt). Trình giám sát máy ảo (VMM) hay trình quản lý ảo hóa (HYP) mô phỏng hầu hết các thiết bị được kết nối với máy ảo (VM) bằng virtio.

#### Tính năng chính

Sau đây là những tính năng chính của mạng ảo:

- Ảo hóa bán phần và ảo hóa toàn phần

> 
> 
> - Ảo hóa toàn phần: Trong môi trường ảo hóa toàn phần, máy ảo khách không nhận ra trình quản lý ảo hóa và chạy mà không cần sửa đổi. Tuy nhiên, ảo hóa toàn phần sẽ dẫn đến tăng thời gian xử lý  giữa máy ảo và máy chủ do phải mô phỏng thiết bị.
>     - Ảo hóa bán phần: Trong môi trường ảo hóa bán phần, Máy ảo nhận ra trình quản lý ảo hóa và yêu cầu chỉnh sửa hệ điều hành. Ảo hóa bán phần cho phép giao tiếp hiệu quả hơn giữa máy khách và máy chủ.
- Kiến trúc 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**
> 
>     - Driver front-end: Triển khai trong hệ điều hành máy ảo khách. Driver front-end tương tác với driver back-end trong phần mềm giám sát máy ảo
>     - Driver back-end : Triển khai trong VMM/HYP. Driver back-end xử lý việc mô phỏng thiết bị thực tế và tương tác với driver front-end thông qua hàng đợi ảo
>     - Hàng đợi ảo: Virtio sử dụng hàng đợi ảo (virtqueue) hỗ trợ  cho việc giao tiếp giữa driver front-end và back-end. Các hàng đợi này được triển khai dưới dạng vòng lặp để quản lý hiệu quả quá trình chuyển đổi từ máy ảo khách sang trình quản lý ảo hóa.
- Vhost

> 
> 
> Vhost là một giao thức chuyển giao phần xử lý dữ liệu của thiết bị  virtio sang một phần tử khác (tiến trình người dùng hoặc mô-đun kernel) để nâng cao hiệu năng. Việc chuyển giao này làm giảm chi phí chuyển đổi ngữ cảnh giữa máy ảo khách và trình quản lý ảo hóa.

    - Vhost-net: Một triển khai ở cấp độ kernel cho phép luồng dữ liệu bỏ qua tiến trình QEMU, nhằm giảm độ trễ và cải thiện hiệu năng. Để biết thêm thông tin về v-host-net, hãy xem [Introduction to virtio-networking and vhost-net](https://www.redhat.com/en/blog/introduction-virtio-networking-and-vhost-net).
    - Vhost-user: Sự triển khai không gian người dùng xử lý luồng dữ liệu bằng một tiến trình riêng biệt, nhằm mang lại tính linh hoạt và hiệu năng tốt hơn cho khối lượng công việc. Để biết thêm thông tin về v-host-user, hãy xem [Vhost-user Protocol](https://www.qemu.org/docs/master/interop/vhost-user.html).

#### Lợi ích

Sau đây là những lợi ích khi sử dụn virtio framework:

- Chuẩn hóa: Virtio cung cấp giao diện chung để mô phỏng thiết bị. Nó thúc đẩy việc tái sử dụng mã nguồn và tính hiệu quả trên nhiều nền tảng ảo hóa khác nhau.
- Linh hoạt: Virtio hỗ trợ các thiết bị khối và thiết bị mạng.

#### Giao diện virtio

Sau đây là các giao diện được virtio hỗ trợ:

##### Tổng quan về giao thức truyền 9P

`virtio-9p` cho phép bạn chia sẻ tệp giữa máy chủ và máy ảo theo giao thức 9P (hệ thống tệp Plan 9) để nâng cao hiệu năng trong virtio framework.

Ghi chú

Đảm bảo rằng các cấu hình sau được bật trong kernel máy chủ và máy ảo khách:

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

Để tạo một thư mục dùng chung `virtio-9p`, hãy định nghĩa thư mục đó trên máy chủ và đặt cấu hình máy ảo khách để mount thư mục đó. Xem ví dụ sau:

> 
> 
> 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

Tạo một thư mục `/mnt/overlay/test_dir` trên máy chủ để chia sẻ thư mục đó với máy ảo khách. Truyền thông tin này trong cấu hình XML libvirt hoặc dưới dạng đối số QEMU. Để đặt cấu hình giao thức truyền 9P, hãy chạy lệnh sau:

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

Để xác định và mount thư mục dùng chung trên máy ảo khách, hãy sử dụng các thiết bị hệ thống tệp `fsdev0` và `hostshare`.

Để khởi chạy máy ảo khách Libvirt từ giao diện libvirt với XML mẫu sau, hãy xem [Libvirt](https://docs.qualcomm.com/doc/80-70020-3VI/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

Ghi chú

Sao chép nội dung XML vào tệp `/mnt/overlay/guest/libvirt_virtio_9p.xml` trên máy chủ.

Sau khi máy ảo khách khởi động, hãy xác minh xem thiết bị virtio đã được nhận diện thành công chưa.

> 
> 
> 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

Để mount  thư mục dùng chung trong máy ảo khách, hãy chạy lệnh sau:

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

##### Tổng quan về VSOCK

VSOCK là giao diện socket ảo cho phép giao tiếp giữa máy ảo và hệ điều hành máy chủ. Giao diện này được dùng trong KVM và QEMU. VSOCK được hỗ trợ thông qua giao diện virtio. virtio-vsock là thiết bị virtio dựa trên vhost, trong đó kernel máy chủ quản lý mọi hoạt động truyền dữ liệu trong khi trình quản lý ảo hóa KVM kiểm soát thông tin.

Để tạo kết nối VSOCK trong môi trường KVM và QEMU, hãy chỉ định mã định danh ngữ cảnh (CID) và đặt số cổng. CID là mã định danh duy nhất được gán cho từng máy ảo trong môi trường VSOCK dùng để định tuyến giao tiếp giữa máy chủ và máy ảo. Máy chủ có CID là 2 trong khi máy ảo được gán CID bắt đầu từ 3 trở lên.

Bảng sau đây liệt kê các giá trị CID:

Bảng: Giá trị CID

| CID | Mô tả |
| --- | --- |
| -1 | Bất kỳ địa chỉ nào để liên kết |
| 0 | Trình quản lý ảo hóa |
| 1 | Loopback |
| 2 | Máy chủ |

Ghi chú

Đảm bảo rằng các cấu hình sau được bật trong kernel máy chủ và máy ảo khách.

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

- Bật thiết bị VSOCK: Để bật thiết bị VSOCK, hãy chỉ định thiết bị trong tệp cấu hình máy ảo (libvirt XML) hoặc truyền đối số cho 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

Trong lệnh này, `guest-cid=73` chỉ định CID cho máy ảo.

- Khởi chạy máy ảo khách bằng giao diện libvirt: Để sử dụng thiết bị VSOCK với libvirt, hãy định nghĩa thiết bị VSOCK trong tệp cấu hình VM XML.

    Để khởi chạy máy ảo khách bằng giao diện libvirt, hãy xem [Libvirt](https://docs.qualcomm.com/doc/80-70020-3VI/topic/virtualization.html#id7).

Sao chép nội dung XML vào `/mnt/overlay/guest/libvirt_virtio_vsock.xml` trên máy chủ. Sau khi máy ảo khách khởi động, hãy xác minh rằng thiết bị đã được khởi tạo thành công.

> 
> 
> 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

Để xác minh tương tác giữa máy chủ với máy ảo khách và giữa máy ảo khách với máy chủ, hãy sử dụng tiện ích `socat`. Đảm bảo rằng tiện ích `socat` được hỗ trợ trên cả máy chủ và máy ảo khách.

- Trên máy chủ, hãy xác minh cổng sau:

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

- Trên máy ảo khách, kết nối với máy chủ bằng CID máy chủ (2):

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

- Trong thiết lập này, máy ảo khách và máy chủ sẽ hiển thị cùng một giá trị.

##### Tổng quan về virtio block

Virtio block là một cách chuẩn hóa để cung cấp các thiết bị khối cho máy ảo. Mỗi thiết bị virtio block nhận diện như một ổ đĩa bên trong máy ảo khách. Virtio block cho phép máy ảo thực hiện các hoạt động đọc và ghi.

Sau đây là những tính năng chính của thiết bị virtio-block:

- Đơn giản: Dễ triển khai và sử dụng
- Hiệu năng: Được thiết kế để giảm thiểu chi phí tài nguyên  và tối đa hóa thông lượng
- Linh hoạt: Được thiết kế để sử dụng với nhiều loại back end lưu trữ khác nhau

Ghi chú

Đảm bảo rằng `CONFIG_VIRTIO_BLK` được bật trong kernel máy ảo khách.

Để sử dụng thiết bị virtio-block, hãy thực hiện như sau:

1. Để đặt cấu hình máy ảo để bao gồm thiết bị virtio-block, hãy chỉ định thiết bị trong tệp cấu hình máy ảo (libvirt XML) hoặc truyền đối số cho QEMU.

    1. Để kích hoạt thiết bị virtio-block trong VM, hãy sử dụng lệnh QEMU sau:

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

        Trong lệnh này, `rootfs.ext4` và `disk.img` là các ổ đĩa bên trong máy ảo khách.
    2. Khởi chạy máy ảo khách bằng giao diện libvirt: Để khởi chạy máy ảo khách bằng XML mẫu sau, hãy xem [Libvirt](https://docs.qualcomm.com/doc/80-70020-3VI/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

Ghi chú

Sao chép nội dung XML vào `/mnt/overlay/guest/libvirt_virtio_blk.xml` trên máy chủ.
2. Hệ điều hành máy ảo khách phát hiện thiết bị virtio-block và khởi động nó. Trong quá trình này, driver trong máy ảo khách sẽ giao tiếp với thiết bị để thiết lập các cấu trúc dữ liệu và hàng đợi cần thiết.

> 
> 
> 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. Sau khi khởi động, bạn có thể sử dụng virtio-block và các thiết bị khối khác. Hệ điều hành máy ảo khách thực hiện các hoạt động đọc và ghi trên virtio driver và truyền các hoạt động này cho máy chủ để xử lý.
4. Để quản lý thiết bị virtio-block, hãy sử dụng các công cụ và lệnh chuẩn có sẵn trong hệ điều hành máy ảo khách. Ví dụ: `lsblk` và `df`.

##### Tổng quan về Virtio-IOMMU

Virtio-IOMMU là một đơn vị quản lý bộ nhớ đầu vào/đầu ra ảo hóa bán phần (IOMMU) cung cấp khả năng quản lý quyền truy cập bộ nhớ trực tiếp (DMA) trong môi trường ảo. Virtio-IOMMU tích hợp với các API phần mềm có sẵn như I/O hàm ảo (VFIO) nên không cần mô phỏng bảng trang, giúp giải pháp này nhẹ và có hiệu năng cao. Virtio-IOMMU hoạt động như một proxy cho các IOMMU vật lý và quản lý các thiết bị được gán cho máy ảo khách. Là IOMMU ảo, nó quản lý, mô phỏng và ảo hóa bán phần các thiết bị.

Sau đây là các tính năng chính của Virtio-IOMMU:

- Ảo hóa bán phần: Tận dụng các cơ chế truyền tải có sẵn và giảm chi phí tài nguyên
- Linh hoạt: Hỗ trợ PCI passthrough và chia sẻ bộ nhớ ảo
- Tích hợp: Tích hợp với API phần mềm và tăng cường khả năng tương thích. Ví dụ: VFIO

Ghi chú

Đảm bảo rằng `CONFIG_VIRTIO_IOMMU` được bật trong kernel máy ảo khách.

Để sử dụng thiết bị Virtio-IOMMU, hãy thực hiện như sau:

1. Để đặt cấu hình máy ảo nhằm bao gồm thiết bị Virtio-IOMMU, hãy chỉ định thiết bị trong tệp cấu hình máy ảo (XML) hoặc truyền đối số cho QEMU.

> 
> 
> 1. Bật thiết bị Virtio-IOMMU: Để bật thiết bị Virtio-IOMMU trong máy ảo, hãy sử dụng lệnh QEMU sau:
> 
> 
> 
> 
> > 
> > 
> > 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. Khởi chạy máy ảo khách bằng giao diện libvirt: Để khởi chạy máy ảo khách bằng XML mẫu sau, hãy xem [Libvirt](https://docs.qualcomm.com/doc/80-70020-3VI/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
> 
> 
> 
> Ghi chú
> 
> 
> Sao chép nội dung XML vào `/mnt/overlay/guest/libvirt_virtio_iommu.xml` trên máy chủ.

2. Hệ điều hành máy ảo khách phát hiện thiết bị Virtio-IOMMU và khởi động thiết bị đó. Trong quá trình này, driver máy ảo khách sẽ giao tiếp với thiết bị để thiết lập các cấu trúc dữ liệu và ánh xạ cần thiết.

> 
> 
> 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 log mô tả thiết bị virtio-block được kết nối với miền IOMMU, là một phần của nhóm IOMMU `0`.

3. Sau khi khởi động, thiết bị Virtio-IOMMU quản lý các hoạt động DMA cho các thiết bị được kết nối. Hệ điều hành máy ảo khách thực hiện các hoạt động ánh xạ và hủy ánh xạ với driver virtio và chuyển các hoạt động này cho máy chủ để xử lý.

> 
> 
> Ví dụ sau đây mô tả các hoạt động của thiết bị 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

##### Tổng quan về virtio-net

Thiết bị virtio-net là thiết bị mạng ảo cung cấp giao diện cho các hoạt động mạng trong môi trường ảo hóa. Nó mang lại hiệu năng cao và có chi phí tài nguyên thấp.

Sau đây là những tính năng chính của thiết bị virtio-net:

- Hiệu quả: Giảm thiểu chi phí tài nguyên và tối đa hóa thông lượng.
- Đơn giản: Dễ triển khai và sử dụng.
- Linh hoạt: Hỗ trợ nhiều cấu hình mạng và backend khác nhau.

Ghi chú

Đảm bảo rằng `CONFIG_VIRTIO_NET` được bật trong kernel máy ảo khách.

Để sử dụng thiết bị virtio-net, hãy thực hiện như sau:

1. Để đặt cấu hình máy ảo nhằm bao gồm thiết bị virtio-net, hãy chỉ định thiết bị trong tệp cấu hình máy ảo (libvirt XML) hoặc truyền đối số cho QEMU.

> 
> 
> 1. Để kích hoạt thiết bị virtio-net trong máy ảo, hãy sử dụng lệnh QEMU sau:
> 
> 
> 
> 
> > 
> > 
> > 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
> > 
> > 
> > Ghi chú
> > 
> > 
> > Lệnh này tạo ra giao diện Tap trên máy chủ. Để tạo giao diện Tap theo cách thủ công, hãy chạy lệnh sau:
> > 
> > 
> > ip tuntap add dev tap0 mode tap
> >     Copy to clipboard
> 
> 
> 2. Để khởi chạy máy ảo khách bằng XML mẫu sau, hãy xem [Libvirt](https://docs.qualcomm.com/doc/80-70020-3VI/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
> > 
> > 
> > Để tạo giao diện tap cho việc giao tiếp trực tiếp giữa máy ảo chủ và máy ảo khách, hãy sao chép nội dung XML vào `/mnt/overlay/guest/libvirt_virtio_net.xml` trên máy chủ.

2. Hệ điều hành máy ảo khách phát hiện thiết bị virtio-net và khởi động nó. Trong quá trình này, driver trên máy ảo khách sẽ giao tiếp với thiết bị để thiết lập các cấu trúc dữ liệu và hàng đợi cần thiết.

> 
> 
> 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. Vận hành: Sau khi bạn khởi động và đặt cấu hình thiết bị virtio-net, hãy sử dụng thiết bị như giao diện mạng khác. Hệ điều hành máy ảo khách thực hiện các hoạt động mạng thông thường với driver virtio và chuyển các hoạt động này cho máy chủ để xử lý.

Để sử dụng giao diện Tap, hãy chạy các cấu hình mạng sau trên máy ảo chủ và máy ảo khách:

- Cấu hình máy chủ:

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
- Cấu hình máy ảo khách:

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

Để chạy lưu lượng mạng trên giao diện này, hãy sử dụng ví dụ sau:

> 
> 
> 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

##### Tổng quan về virtio-serial và virtio-console

Thiết bị virtio-serial cung cấp giao diện cho giao tiếp serial giữa máy ảo chủ và máy ảo khách trong môi trường ảo.

Sau đây là những tính năng chính của thiết bị virtio-serial:

- Nhiều cổng: Hỗ trợ nhiều cổng serial, cho phép nhiều kênh giao tiếp khác nhau
- Hiệu quả: Giảm thiểu chi phí tài nguyên và tối ưu hóa thông lượng
- Linh hoạt: Hỗ trợ nhiều loại hình trao đổi dữ liệu khác nhau. Ví dụ: truy cập console và truyền tệp

Ghi chú

Đảm bảo rằng `CONFIG_VIRTIO_CONSOLE` được bật trong kernel máy ảo khách.

Để sử dụng thiết bị virtio-serial, hãy thực hiện như sau:

1. Để đặt cấu hình máy ảo nhằm bao gồm thiết bị virtio-serial, hãy chỉ định thiết bị trong tệp cấu hình máy ảo (libvirt XML) hoặc truyền đối số cho QEMU.

    1. Để kích hoạt thiết bị virtio-net trong máy ảo, hãy sử dụng lệnh QEMU sau:

> 
> 
> 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. Để khởi chạy máy ảo khách bằng XML mẫu sau, hãy xem [Libvirt](https://docs.qualcomm.com/doc/80-70020-3VI/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

Ghi chú

Sao chép nội dung XML vào `/mnt/overlay/guest/virtio_serial.xml` trên máy chủ.
2. Hệ điều hành máy ảo khách phát hiện thiết bị virtio-serial và khởi động thiết bị. Trong quá trình này, driver trong máy ảo  khách sẽ giao tiếp với thiết bị để thiết lập các cấu trúc dữ liệu và các cổng cần thiết.

> 
> 
> 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. Sau khi khởi động, bạn có thể sử dụng thiết bị virtio-serial như một thiết bị serial. Hệ điều hành máy ảo khách thực hiện các hoạt động đọc và ghi bằng driver virtio và truyền  các hoạt động này cho máy chủ để xử lý.
4. Để quản lý thiết bị virtio-serial, hãy thực hiện như sau:

    - Theo dõi hiệu năng
    - Xác minh trạng thái thiết bị
    - Thực hiện các công việc bảo trì
    - Sử dụng các công cụ và lệnh chuẩn có sẵn trong hệ điều hành máy  ảo khách

###### Hỗ trợ thiết bị Memory balloon

Thiết bị virtio memory balloon thông thường quản lý bộ nhớ máy ảo  khách. Thiết bị này cho phép hệ thống máy chủ thu hồi lại bộ nhớ từ máy ảo. Memory balloon sẽ yêu cầu máy ảo trả lại một phần bộ nhớ cho máy chủ. Quá trình này bao gồm việc bơm balloon bên trong máy ảo khách, làm giảm lượng bộ nhớ khả dụng cho các tác vụ khác trong máy ảo. Hệ điều hành máy ảo khách quyết định trang bộ nhớ nào cần trả lại cho máy chủ, chỉ ra những trang nào không cần hoặc không truy cập. Sau đó, máy chủ sẽ hủy ánh xạ các trang này khỏi máy ảo khách rồi đánh dấu chúng là không khả dụng đối với máy ảo khách và cho phép hệ thống máy chủ sử dụng chúng. Nếu sau này máy ảo khách cần nhiều bộ nhớ hơn, máy chủ sẽ làm xả balloon để trả lại các trang. Tính năng này cho phép mỗi máy ảo khách tiếp tục chạy trong khi bộ nhớ trống của máy ảo đó được quản lý.

Sử dụng phương pháp sau cho thiết bị virtio-balloon để di chuyển bộ nhớ vật lý giữa máy ảo khách và máy chủ:

1. Bơm balloon: Driver trên máy ảo khách cấp phát bộ nhớ và thông báo cho máy chủ. Sau đó, máy chủ sẽ tái sử dụng bộ nhớ đã được bơm cho các máy ảo khác.
2. Xả balloon: Sau khi thông báo cho máy chủ, driver trên máy ảo khách sẽ giải phóng bộ nhớ đã được cấp phát trước đó và cho phép máy ảo khách sử dụng bộ nhớ đã được xả.

`Target balloon size` kiểm soát việc bơm hoặc xả balloon thông qua yêu cầu thay đổi kích thước bộ nhớ máy ảo khách. Yêu cầu thay đổi kích thước được gửi qua chế độ giám sát QEMU hoặc qua lệnh virsh.

Sau đây là những tính năng chính của thiết bị virtio-balloon:

- Quản lý bộ nhớ: Điều chỉnh việc cấp phát bộ nhớ theo thời gian thực dựa trên các yêu cầu.
- Hiệu quả: Thu hồi bộ nhớ chưa sử dụng từ các máy ảo nhàn rỗi và phân phối lại cho các VM đang hoạt động.
- Linh hoạt: Cho phép nhiều thiết lập ảo hóa khác nhau để tối ưu hóa sử dụng tài nguyên.

Ghi chú

Đảm bảo rằng `CONFIG_VIRTIO_BALLOON` được bật trong kernel máy ảo khách.

Để sử dụng thiết bị virtio-balloon, hãy thực hiện như sau:

1. Đặt cấu hình mấy ảo để bao gồm thiết bị virtio-balloon, chỉ định thiết bị trong tệp cấu hình máy ảo (libvirt XML) hoặc truyền đối số cho QEMU.

    1. Để kích hoạt thiết bị virtio-balloon trong máy ảo, hãy sử dụng lệnh QEMU sau:

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. Để khởi chạy máy ảo khách bằng XML mẫu sau, hãy xem [Libvirt](https://docs.qualcomm.com/doc/80-70020-3VI/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

Ghi chú

Sao chép nội dung XML vào tệp `/mnt/overlay/guest/libvirt_virtio_balloon.xml` trên máy chủ.
2. Hệ điều hành máy ảo khách phát hiện thiết bị virtio-balloon và khởi tạo nó. Trong quá trình này, driver trong máy ảo khách sẽ giao tiếp với thiết bị để thiết lập các cấu trúc dữ liệu và cơ chế quản lý bộ nhớ cần thiết.

> 
> 
> 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. Sau khi khởi tạo, thiết bị virtio-balloon sẽ điều chỉnh bộ nhớ được cấp phát cho máy ảo. Hệ điều hành máy ảo khách thực hiện các hoạt động bơm và xả bộ nhớ, được xử lý bởi driver virtio và truyền thông tin này về máy chủ để xử lý.

Để điều chỉnh bộ nhớ máy ảo khách, hãy chạy các lệnh virsh sau trên máy chủ:

- Để xác minh bộ nhớ ban đầu của máy ảo khách (2 GB), hãy chạy lệnh sau:

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

- Để bơm balloon và giảm bộ nhớ máy ảo khách xuống còn 512 MB, hãy chạy lệnh sau:

root@qcs9100-ride-sx:~# virsh setmem simple_balloon 512M --live
        Copy to clipboard
- Để xác minh bộ nhớ máy ảo khách sau khi bơm, hãy chạy lệnh sau:

root@v8a-arm64:~# cat /proc/meminfo  | grep Mem
        MemTotal:         393316 kB
        MemFree:          235708 kB
        MemAvailable:     245836 kB
        root@v8a-arm64:~#
        Copy to clipboard
- Để làm xả balloon (Bộ nhớ máy ảo khách trở lại 2 GB):

root@qcs9100-ride-sx:~# virsh setmem simple_balloon 2G --live
        Copy to clipboard
- Để xác minh bộ nhớ máy ảo khách sau khi xả:

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

###### Truy cập thiết bị trên máy chủ

Bạn có thể sử dụng các thiết bị được liệt kê trên hệ thống máy chủ từ máy ảo khách. Giao diện gán thiết bị cho máy ảo khách sẽ khác nhau tùy theo loại thiết bị. Một số thiết bị có vai trò là back end cho thiết bị được QEMU mô phỏng, ví dụ như UART. Đặt cấu hình UART làm back end như một thiết bị ký tự (chardev) trên máy chủ. Để biết thêm thông tin về QEMU chardev, hãy xem [Character device options](https://www.qemu.org/docs/master/system/invocation.html#hxtool-6).

Các thiết bị PCI và USB hoạt động dựa trên VFIO framework của kernel.

- PCI passthrough cho phép máy ảo khách truy cập trực tiếp vào thiết bị PCI vật lý trên máy chủ. VFIO framework trong Linux kernel được dùng để gán thiết bị PCI cho máy ảo. Để biết thêm thông tin về VFIO, hãy xem [VFIO - Virtual Function I/O](https://docs.kernel.org/driver-api/vfio.html).
- Thiết bị USB hoạt động ở chế độ Passthrough, cho phép máy ảo khách sử dụng các thiết bị ngoại vi USB được kết nối với máy chủ. QEMU mô phỏng bộ điều khiển USB và hoạt động với libusb trên máy chủ để cung cấp các thiết bị ngoại vi USB cho máy ảo khách. Để biết thêm thông tin, hãy xem [USB emulation](https://qemu-project.gitlab.io/qemu/system/devices/usb.html).

**Tổng quan về USB passthrough**

Xác định thiết bị USB được liệt kê trên máy chủ để gán cho máy khách. Để xem tất cả các thiết bị USB được liệt kê trên máy chủ, hãy sử dụng lệnh `lusb`. Tìm thiết bị theo `vendor id` và `product id`.

Trong ví dụ sau, `vendor id` là 0x0781 và `product id` là 0x5567 đối với USB stick.

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

Ghi chú

Sao chép tệp XML sau vào hệ thống tệp máy chủ trong tệp `/mnt/overlay/guest/libvirt_usb.xml` và sửa đổi tệp XML theo `vendor id` và `product id`.

Khởi chạy máy ảo khách có XML mẫu sau và thực hiện như sau:

1. Sau khi máy ảo khách được khởi chạy, hãy kết nối với console máy ảo.
2. Xác minh đầu ra `lsusb` trong máy ảo khách.
3. Đảm bảo rằng đầu ra liệt kê thiết bị USB được gán cho máy khách.

<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

**Tổng quan về PCI**

Xác định thiết bị PCI được liệt kê trên máy chủ để gán cho máy ảo khách. Để xem tất cả các thiết bị PCI được liệt kê trên máy chủ, hãy sử dụng lệnh `lspci`. Tìm thiết bị theo `[domain:]bus:device.function`. Để biết thêm thông tin về lệnh `lspci`, hãy xem [lspci(8)—Linux manual page](https://man7.org/linux/man-pages/man8/lspci.8.html).

Ví dụ sau đây mô tả các giá trị được hỗ trợ cho miền, bus, thiết bị và chức năng của thiết bị `Ethernet controller: Aquantia Corp. AQC107 NBase-T/IEEE 802.3bz`:

- Miền là 0001
- Bus là 01
- Thiết bị là 00
- Chức năng là 0 cho

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

Ghi chú

Sao chép nội dung XML vào tệp `/mnt/overlay/guest/libvirt_pci.xml` và thay đổi phần `hostdev` trong tệp XML theo yêu cầu của thiết bị.

Để khởi chạy máy ảo khách, hãy xem [Libvirt](https://docs.qualcomm.com/doc/80-70020-3VI/topic/virtualization.html#id7). Sau khi bạn khởi chạy máy ảo khách, hãy kết nối console của máy ảo và xác minh đầu ra `lspci` trong máy ảo khách. Đảm bảo rằng đầu ra liệt kê thiết bị PCI được gán cho máy ảo khách.

Ghi chú

Đầu ra hiển thị các khe cắm khác nhau dựa trên cấu trúc PCI của máy ảo khách được lựa chọn bởi QEMU và Libvirt.

Khi `managed` được đánh dấu là *yes* trong `hostdev` trong XML sau, thiết bị PCI sẽ được tách khỏi máy chủ trước khi chuyển sang máy khách và được gắn lại vào máy chủ sau khi máy khách thoát. Để biết thêm thông tin, hãy xem [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

**Tổng quan về UART passthrough**

Xác định tệp thiết bị điện báo (TTY) `/dev/ttyX` tương ứng với UART để sử dụng từ máy ảo khách. Đảm bảo rằng không có ứng dụng nào trên máy chủ đang sử dụng giao diện này.

Ghi chú

Sao chép nội dung XML vào tệp `/mnt/overlay/guest/libvirt_uart.xml` trên máy chủ và sửa đổi tệp thiết bị TTY theo yêu cầu của thiết bị.

Khởi chạy máy ảo khách và kết nối với console máy ảo. Giao diện serial tại đường dẫn `/dev/virtio-ports/hostserial` hoạt động như một giao diện người dùng tới UART thực trên máy chủ. Sử dụng tệp XML sau:

<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

#### Tùy chỉnh KVM

Các tính năng sau đây cho phép bạn sửa đổi trình quản lý ảo hóa KVM để đáp ứng các yêu cầu cụ thể:

#### Thực thi lệnh từ xa

Để kích hoạt QEMU Guest Agent trong không gian người dùng hệ điều hành máy ảo khách, chạy lệnh từ xa trên máy ảo khách từ máy chủ. Để biết thêm thông tin về `qemu-ga`, hãy xem [QEMU Guest Agent](https://qemu-project.gitlab.io/qemu/interop/qemu-ga.html).

`qemu-agent-command` là lệnh virsh bao gồm `guest-exec` và `guest-exec-status` là các lệnh con để thực thi và xác minh trạng thái hoặc đầu ra của máy ảo khách. Để biết thêm thông tin về cách đặt cấu hình `qemu-ga` thông qua giao diện virtio-serial, hãy xem [QEMU Guest Agent](https://wiki.libvirt.org/Qemu_guest_agent.html).

Để biết thêm thông tin về cách `virt-exec` đóng gói các lệnh virsh và cung cấp giao diện, hãy xem [kvm-qemu/virt-exec](https://github.com/ildar-shaimordanov/my-scripts/blob/master/kvm-qemu/virt-exec).

Ví dụ sau đây mô tả cách chạy `/proc/meminfo` trên máy ảo khách từ máy chủ bằng tiện ích `virt-exec`:

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

##### Cấu hình Watchdog

Thiết bị QEMU-emulated I6300 ESB watchdog được hỗ trợ trong máy ảo khách. Linux kernel có driver watchdog này và cung cấp thiết bị ký tự chuẩn để tương tác. Để bật watchdog, hãy đặt `CONFIG_I6300ESB_WDT` trong cấu hình kernel máy ảo khách. Daemon trong không gian người dùng máy ảo khách phải thực hiện viêc pet watchdog.

Libvirt XML cho máy ảo khách có tùy chọn `poweroff` hoặc `reset` khi watchdog timeout. Để biết thêm thông tin, hãy xem [Watchdog devices](https://libvirt.org/formatdomain.html#watchdog-devices).

Thêm đoạn mã sau vào XML của máy ảo khách để bật mô phỏng I6300 ESB watchdog trong QEMU. Hành động mặc định là `reset`, hành động này sẽ khởi động lại máy ảo  khách.

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

##### Tính năng trace KVM

Để bật tính năng trace KVM, hãy chạy lệnh sau:

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

Các tương tác của máy ảo KVM được ghi lại trong tính năng trace hàm trong kernel (ftrace). Để kiểm tra sự tương tác giữa KVM và máy ảo khách, hãy đọc kernel trace buffer.

QEMU cũng hỗ trợ các sự kiện trace, có thể được chuyển hướng đến ftrace kernel. Để biết thêm thông tin về cách chuyển hướng các sự kiện back-end trace QEMU đến buffer ftrace, hãy xem [Trace backends](https://qemu-project.gitlab.io/qemu/devel/tracing.html#trace-backends). Tùy chọn này được chọn theo mặc định trong bản phát hành Qualcomm Linux.

Để khởi chạy máy ảo khách đã bật tính năng trace virtio trong mã QEMU, hãy chạy lệnh sau:

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
Tổng quan về kernel theo thời gian thực (RT)](https://docs.qualcomm.com/bundle/publicresource/80-70020-3VI/topics/real_time_kernel_overview.md) [Next Topic
Ghi lại kernel log](https://docs.qualcomm.com/bundle/publicresource/80-70020-3VI/topics/capture-the-kernel-logs.md)