一步一步教你:如何在 Linux 上用 QEMU 搭建虛擬機(jī)
QEMU 是一個(gè)強(qiáng)大的開源硬件虛擬化軟件,可以在多種操作系統(tǒng)上運(yùn)行。本文將詳細(xì)介紹如何在 Linux 平臺(tái)上從源碼編譯 QEMU,并創(chuàng)建和配置一個(gè)虛擬機(jī)。我們將使用 CentOS 8.5 作為示例操作系統(tǒng),但部分步驟同樣適用于其他操作系統(tǒng)(如 Ubuntu)。
1. 簡(jiǎn)介
QEMU(Quick Emulator)是一個(gè)強(qiáng)大的開源虛擬化工具,可以模擬整個(gè)計(jì)算機(jī)系統(tǒng),包括 CPU、內(nèi)存、硬盤、網(wǎng)卡等。結(jié)合 KVM(Kernel-based Virtual Machine),QEMU 可以提供高效的虛擬化性能。
2. 安裝依賴
在開始之前,確保你的系統(tǒng)已經(jīng)安裝了必要的依賴項(xiàng)。以下命令適用于基于 Red Hat 的系統(tǒng)(如 CentOS 和 Fedora):
sudo dnf install pixman-devel -y
3. 源碼編譯 QEMU
- 下載 QEMU 源碼:
wget https://download.qemu.org/qemu-8.2.0.tar.xz
tar -xvf qemu-8.2.0.tar.xz
cd qemu-8.2.0
- 安裝編譯依賴:
sudo yum install autoconf automake python3 libmpc-devel mpfr-devel gmp-devel gawk bison flex patchutils gcc gcc-c++ zlib-devel expat-devel libslirp-devel -y
sudo dnf group install "Development Tools" -y
- 安裝 texinfo:
wget https://ftp.gnu.org/gnu/texinfo/texinfo-6.8.tar.xz
tar -xvf texinfo-6.8.tar.xz
cd texinfo-6.8
./configure
make
make install
- 編譯和安裝 QEMU:
cd qemu-8.2.0
./configure --enable-kvm --enable-debug --enable-vnc --enable-werror --target-list="x86_64-softmmu" --enable-slirp
make -j $(nproc)
make install
configure 腳本用于生成 Makefile,其選項(xiàng)可以用 ./configure --help 查看。這里使用到的選項(xiàng)含義如下:
- --enable-kvm:編譯 KVM 模塊,使 QEMU 可以利用 KVM 來(lái)訪問硬件提供的虛擬化服務(wù)
- --enable-debug:?jiǎn)⒂谜{(diào)試符號(hào)的生成,這有助于調(diào)試程序。
- --enable-vnc:?jiǎn)⒂?nbsp;VNC 支持,允許通過 VNC 客戶端連接到 QEMU 實(shí)例,并查看其圖形輸出。
- --enalbe-werror:告訴編譯器將所有的警告都視為錯(cuò)誤,這樣可以確保代碼質(zhì)量更高,任何可能的問題都會(huì)阻止編譯過程。
- --target-list="x86_64-softmmu":選擇目標(biāo)機(jī)器的架構(gòu)。默認(rèn)將所有的架構(gòu)都編譯,但為了更快完成編譯,指定要構(gòu)建的目標(biāo)體系結(jié)構(gòu)。在這個(gè)例子中,它指定了 x86_64 架構(gòu),并且使用軟MMU(內(nèi)存管理單元),這意味著 QEMU 將模擬硬件的內(nèi)存管理功能。
- --enable-slirp:?jiǎn)⒂?nbsp;SLiRP,使 qemu 增加了一種 user mode 的網(wǎng)絡(luò)后端實(shí)現(xiàn),該網(wǎng)絡(luò)后端的實(shí)現(xiàn)是在用戶態(tài)實(shí)現(xiàn)的一套 tcp/ip 協(xié)議棧。
整個(gè)命令的作用就是配置 QEMU 的編譯選項(xiàng),以便它可以支持 KVM 加速、VNC 連接、調(diào)試信息,并且能夠模擬 x86_64 架構(gòu)的機(jī)器,同時(shí)提供 SLiRP 網(wǎng)絡(luò)支持。這些配置完成后,接下來(lái)就可以通過 make 命令開始編譯過程了。
這里需要注意,開啟 --enable-slirp 后,可能會(huì)遇到如下錯(cuò)誤:qemu-system-x86_64: error while loading shared libraries: libslirp.so.0: cannot open shared object file: No such file or directory,這個(gè)錯(cuò)誤表明 QEMU 在啟動(dòng)時(shí)無(wú)法找到或加載 libslirp.so.0 庫(kù)。libslirp.so.0 是 QEMU 用戶模式網(wǎng)絡(luò)支持的一部分,用于模擬網(wǎng)絡(luò)連接。當(dāng) QEMU 嘗試使用用戶模式網(wǎng)絡(luò) (-netdev user) 時(shí),需要這個(gè)庫(kù)來(lái)完成網(wǎng)絡(luò)仿真。為安裝 libslirp.so.0 庫(kù),可通過如下方式:
wget https://gitlab.freedesktop.org/slirp/libslirp/-/archive/v4.8.0/libslirp-v4.8.0.tar.bz2
tar -xvjf libslirp-v4.8.0.tar.bz2
mkdir build
cd build
meson setup --prefix=/usr --buildtype=release ..
ninja
ninja install
即使庫(kù)文件已經(jīng)安裝,但如果 QEMU 可執(zhí)行文件所在環(huán)境的 LD_LIBRARY_PATH 中沒有包含庫(kù)文件所在的目錄,可以手動(dòng)設(shè)置 LD_LIBRARY_PATH:
export LD_LIBRARY_PATH=/path/to/libslirp:$LD_LIBRARY_PATH
如果 libslirp.so.0 存在于 /usr/lib64 目錄中:
export LD_LIBRARY_PATH=/usr/lib64:$LD_LIBRARY_PATH
通過上述步驟,你應(yīng)該能夠解決 QEMU 在啟動(dòng)時(shí)無(wú)法找到 libslirp.so.0 的問題。如果問題仍然存在,請(qǐng)進(jìn)一步檢查其他配置或環(huán)境問題。
4. 創(chuàng)建虛擬機(jī)鏡像
使用 qemu-img 工具創(chuàng)建一個(gè)新的磁盤鏡像文件。這里我們創(chuàng)建一個(gè) 100 GB 的 qcow2 格式的磁盤鏡像。
qemu-img create -f qcow2 CentOS-8.5-VM.qcow2 100G
5. 創(chuàng)建虛擬機(jī)
qemu-system-x86_64 是一個(gè)基于 QEMU 的命令行工具,用于模擬 x86 架構(gòu)的計(jì)算機(jī)系統(tǒng)。假設(shè)您要在虛擬機(jī)中安裝 x86 架構(gòu)操作系統(tǒng),可以使用 qemu-system-x86_64 命令創(chuàng)建虛擬機(jī)并安裝操作系統(tǒng),這里假設(shè)你已經(jīng)下載了 CentOS-8.5.2111-x86_64-dvd1.iso 文件。
qemu-system-x86_64 -name CentOS-8.5-VM -smp 4 -m 4096 -enable-kvm -boot order=dc,once=d -hda /home/tmp/image/vmImages/CentOS-8.5-VM/CentOS-8.5-VM.qcow2 -cdrom /home/tmp/image/qemu/vImage/CentOS-8.5/CentOS-8.5.2111-x86_64-dvd1.iso -netdev user,id=mynic0,hostfwd=tcp::1234-:22 -device virtio-net-pci,netdev=mynic0,mac=52:54:98:76:54:32 -vnc :10 -serial stdio -machine usb=on -device usb-tablet
qemu-system-x86_64 命令用來(lái)創(chuàng)建一個(gè)虛擬機(jī),并配置了一些基本的參數(shù)。這個(gè)命令的各個(gè)參數(shù)意義如下:
- qemu-system-x86_64: QEMU 的二進(jìn)制文件名,這里表示運(yùn)行 x86_64 架構(gòu)的系統(tǒng)級(jí)模擬器。
- -name CentOS-8.5-VM:為虛擬機(jī)命名,雖然這不是一個(gè)必需的參數(shù),但它可以用于標(biāo)識(shí)虛擬機(jī),便于日志記錄或管理。
- -smp n [,cores=cores][,threads=threads][,sockets=sockets] [,maxcpus=maxcpus]:設(shè)置客戶機(jī)總共有 n 個(gè)邏輯 CPU,并設(shè)置了其中 CPU socket 的數(shù)量、每個(gè) socket 上核心(core)的數(shù)量、每個(gè)核心上的線程(thread)數(shù)量。其中:n = sockets x cores x threads。
- n:虛擬CPU(vcpu)的個(gè)數(shù),每個(gè) thread 都視為一個(gè)虛擬 CPU 。
- cores:每個(gè) CPU 擁有的 CPU 核心數(shù)目
- threads:每個(gè) CPU 核心擁有的線程數(shù)目。
- sockets :CPU 插槽數(shù)目,也就是 CPU 的個(gè)數(shù)。
- maxcpus: 根據(jù)文檔,是設(shè)置可熱插拔的 CPU 數(shù)量,經(jīng)測(cè)試,n 的值不可超過maxcpus。
- -m 4096:設(shè)置虛擬機(jī)內(nèi)存大小為 4096 MB(4 GB),默認(rèn)單位是 MB 。
- -enable-kvm:?jiǎn)⒂?nbsp;KVM 加速,提高虛擬機(jī)性能。KVM(Kernel-based Virtual Machine)是一種全虛擬化技術(shù),利用 Linux 內(nèi)核作為 Hypervisor。
- -boot order=dc,once=d:定義設(shè)備的引導(dǎo)次序,每種設(shè)備使用一個(gè)字符表示,a,b 表示軟驅(qū),c 表示第一塊硬盤,d 表示第一個(gè)光驅(qū),n-p 表示網(wǎng)絡(luò)適配器。這里表示設(shè)置引導(dǎo)順序?yàn)閺?nbsp;CD-ROM (d 表示 CD-ROM)引導(dǎo),如果沒有 CD-ROM,則從硬盤(c 表示硬盤)引導(dǎo)。once=d 表示僅在首次啟動(dòng)時(shí)嘗試從 CD-ROM 引導(dǎo),之后的啟動(dòng)都從硬盤引導(dǎo)。
- -hda /home/tmp/image/vmImages/CentOS-8.5-VM/CentOS-8.5-VM.qcow2:指定虛擬機(jī)的硬盤映像文件 /home/tmp/image/vmImages/CentOS-8.5-VM/CentOS-8.5-VM.qcow2,并將其作為第一個(gè)硬盤(hda)加載。
- -cdrom /home/tmp/image/qemu/vImage/CentOS-8.5/CentOS-8.5.2111-x86_64-dvd1.iso:指定 ISO 文件的位置 /home/tmp/image/qemu/vImage/CentOS-8.5/CentOS-8.5.2111-x86_64-dvd1.iso,并將它作為虛擬 CD-ROM 設(shè)備加載。
- -netdev user,id=mynic0,hostfwd=tcp::1234-:22: 配置網(wǎng)絡(luò)設(shè)備,user 表示使用用戶模式網(wǎng)絡(luò),即通過 QEMU 本身的網(wǎng)絡(luò)棧模擬網(wǎng)絡(luò)連接。id=mynic0 給這個(gè)網(wǎng)絡(luò)設(shè)備分配一個(gè)標(biāo)識(shí)符 mynic0。hostfwd=tcp::1234-:22 表示將主機(jī)的端口 1234 映射到虛擬機(jī)的端口 22(SSH 默認(rèn)端口)。
注意:user 指 config user mode host network backend, 端口轉(zhuǎn)發(fā)配置格式為:hostfwd=[tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport。
- -device virtio-net-pci,netdev=mynic0,mac=52:54:98:76:54:32: 添加一個(gè) VirtIO 網(wǎng)卡設(shè)備,指定虛擬網(wǎng)卡設(shè)備類型為 virtio-net-pci,并將其與前面定義的網(wǎng)絡(luò)設(shè)備 mynic0 關(guān)聯(lián)起來(lái)。mac 參數(shù)設(shè)置 MAC 地址為 52:54:98:76:54:32。
- -vnc :10:開啟 VNC 服務(wù),允許遠(yuǎn)程訪問虛擬機(jī)的圖形界面。VNC 服務(wù)將在本地的 5910 端口上監(jiān)聽。
- -serial stdio:開啟串行控制臺(tái),允許通過終端與虛擬機(jī)交互。
- -machine usb=on -device usb-tablet:usb=on 表示啟用 USB 支持。-device usb-tablet 表示添加一個(gè) USB 平板設(shè)備,使得可以通過 USB 接口與虛擬機(jī)交互。在qemu 里面使用 kvm,在 vnc 終端里面鼠標(biāo)會(huì)錯(cuò)位(真實(shí)鼠標(biāo)在外,虛擬鼠標(biāo)在 vnc 內(nèi)部,需要不斷調(diào)整角度)。這兩個(gè)參數(shù)主要為了解決在使用 vnc 連接虛擬機(jī)時(shí)鼠標(biāo)不同步(錯(cuò)位)的問題。
上面命令執(zhí)行后,會(huì)彈出圖形安裝界面,可根據(jù)圖形界面引導(dǎo)進(jìn)行操作系統(tǒng)安裝,操作系統(tǒng)安裝完成后,在圖形安裝界面,點(diǎn)擊重啟系統(tǒng),重新啟動(dòng)虛擬機(jī),同時(shí)可以在宿主機(jī)命令行中按 Ctrl C 終結(jié)上面的 qemu-system-x86_64 命令行創(chuàng)建流程,重新運(yùn)行啟動(dòng)虛擬機(jī)命令。
6. 啟動(dòng)虛擬機(jī)
安裝完成后重起虛擬機(jī)便會(huì)從硬盤啟動(dòng),之后再啟動(dòng)虛擬機(jī)只需要執(zhí)行:
qemu-system-x86_64 -name CentOS-8.5-VM -smp 4 -m 4096 -enable-kvm -hda /home/tmp/image/vmImages/CentOS-8.5-VM/CentOS-8.5-VM.qcow2 -netdev user,id=mynic0,hostfwd=tcp::1234-:22 -device virtio-net-pci,netdev=mynic0,mac=52:54:98:76:54:32 -vnc :10
qemu-system-x86_64 命令用來(lái)啟動(dòng)一個(gè)虛擬機(jī),并配置了一些基本的參數(shù)。這個(gè)命令的各個(gè)參數(shù)意義如下:
- -name CentOS-8.5-VM: 為虛擬機(jī)命名,這樣可以在日志和其他管理工具中更容易識(shí)別虛擬機(jī)。
- -smp 4 :設(shè)置虛擬機(jī)擁有 4 個(gè)虛擬 CPU(SMP,Symmetric Multi-Processing)。
- -m 4096:設(shè)置虛擬機(jī)擁有 4096MB(即 4GB)的內(nèi)存。
- -enable-kvm:?jiǎn)⒂?nbsp;KVM 加速功能,提高虛擬化性能。KVM 是 Linux 內(nèi)核的一個(gè)模塊,提供了硬件加速的虛擬化功能。
- -hda /home/tmp/image/vmImages/CentOS-8.5-VM/CentOS-8.5-VM.qcow2:指定虛擬機(jī)的硬盤映像文件 /home/tmp/image/vmImages/CentOS-8.5-VM/CentOS-8.5-VM.qcow2,并將其作為第一個(gè)硬盤(hda)加載。
- -netdev user,id=mynic0,hostfwd=tcp::1234-:22: 設(shè)置網(wǎng)絡(luò)設(shè)備為用戶模式網(wǎng)絡(luò) (user),并使用 ID mynic0。同時(shí),設(shè)置端口轉(zhuǎn)發(fā)規(guī)則,允許外部主機(jī)通過本地的 1234 端口訪問虛擬機(jī)的 SSH 服務(wù)(默認(rèn)端口 22)。
注意:user 指 config user mode host network backend, hostfwd=[tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport
- -device virtio-net-pci,netdev=mynic0,mac=52:54:98:76:54:32: 指定虛擬網(wǎng)卡設(shè)備類型為 virtio-net-pci,使用前面定義的 netdev=mynic0 網(wǎng)絡(luò)設(shè)備,并設(shè)置 MAC 地址為 52:54:98:76:54:32。
【拓展:QEMU 的網(wǎng)絡(luò)配置】
要理解 QEMU 的網(wǎng)絡(luò)配置實(shí)現(xiàn)由兩個(gè)部分組成:
- 提供給虛擬機(jī)的虛擬網(wǎng)卡(virtual network device)比如經(jīng)典的 e1000,rtl8139 以及 virtio-net-pci 等,是虛擬機(jī)內(nèi)部看到的設(shè)備。
- 與虛擬網(wǎng)卡交互的后端(network backend)虛擬機(jī)往虛擬網(wǎng)卡寫入的數(shù)據(jù)都會(huì)由 network backend 流出到真實(shí)的網(wǎng)絡(luò)環(huán)境中。
QEMU 網(wǎng)絡(luò)配置需要組合使用 -device DEVNAME,netdev=NAME 與 -netdev TYPE,id=NAME,... 命令,-device 用于配置虛擬網(wǎng)卡,-netdev 用于配置網(wǎng)絡(luò)后端, device 中的 netdev 的值與 netdev 中的 id 的值相同,一起配合用于組成一組網(wǎng)絡(luò)配置,一臺(tái)虛擬機(jī)可以配置多個(gè)網(wǎng)絡(luò)。
【拓展:QEMU 配置網(wǎng)絡(luò)環(huán)境通常有 2 種方式】
- 可插拔網(wǎng)卡(pluggable NIC)
-device DEVNAME,netdev=NET-ID,... \-netdev TYPE,id=NET-ID,...
注意:qemu-system-x86_64 -device help 可以查看機(jī)器支持的設(shè)備(包含網(wǎng)卡設(shè)備)
- 板載網(wǎng)卡(On-board NIC)
-nic TYPE,model=DEVNAME,...
注意:qemu-system-x86_64 -nic model=help 可以查看機(jī)器支持的 NIC 設(shè)備。
注意:如果在命令行(通過 -net(已廢棄)、-nic 或 -netdev)指定任何網(wǎng)絡(luò)選項(xiàng),那么 QEMU 將要求您提供足以定義和連接這兩個(gè)部分的選項(xiàng)。(忘記指定網(wǎng)絡(luò)后端或網(wǎng)絡(luò)虛擬設(shè)備會(huì)給出警告信息,如“Warning: netdev mynet0 has no peer”,“Warning: hub 0 is not connected to host network”或者“Warning: hub 0 with no nics”,然后 VM 將啟動(dòng),但是沒有正常運(yùn)行的網(wǎng)絡(luò)) 注意:如果您使用(默認(rèn))SLiRP 用戶網(wǎng)絡(luò),則 ping(ICMP)將不起作用,但 TCP 和 UDP 將起作用。不要嘗試使用 ping 來(lái)測(cè)試您的 QEMU 網(wǎng)絡(luò)配置。
- -vnc :10:開啟 VNC 服務(wù),允許遠(yuǎn)程訪問虛擬機(jī)的圖形界面。VNC 服務(wù)將在本地的 5910 端口上監(jiān)聽。
7. 登錄虛擬機(jī)
啟動(dòng)虛擬機(jī)后,常用登錄虛擬機(jī)可以通過如下 2 種方式:
- 使用 SSH 登錄虛擬機(jī)
- VNC 登錄虛擬機(jī)
具體采用哪種方式取決于你的虛擬機(jī)的配置和需求。
1. 使用 SSH 登錄虛擬機(jī)
如果你的虛擬機(jī)已經(jīng)配置了網(wǎng)絡(luò),并且安裝了 SSH 服務(wù),那么最常用的方法就是通過 SSH 登錄。配置方法如下:
1)確保虛擬機(jī)有網(wǎng)絡(luò)連接
配置虛擬機(jī)的網(wǎng)絡(luò)接口為橋接模式(Bridged)或 NAT 模式(NAT),以便虛擬機(jī)能夠訪問網(wǎng)絡(luò)。
2)安裝 SSH 服務(wù)
在虛擬機(jī)內(nèi)部安裝 SSH 服務(wù)(如 OpenSSH):
- 基于 Red Hat 的系統(tǒng)
sudo dnf install openssh-server
- Ubuntu 系統(tǒng)
sudo apt update && sudo apt install openssh-server
3)啟動(dòng)并設(shè)置 SSH 自啟動(dòng)
設(shè)置 SSH 自啟動(dòng)配置命令如下:
sudo systemctl start ssh
sudo systemctl enable ssh
4)檢查 SSH 服務(wù)狀態(tài)
查看虛擬機(jī)中 SSH 的狀態(tài),命令如下:
sudo systemctl status ssh
5)通過 SSH 登錄
在宿主機(jī)上使用 SSH 客戶端連接虛擬機(jī):
ssh user@virtual_machine_hostname
如果你更改了 SSH 端口,需要加上 -p 參數(shù)指定端口號(hào):
ssh -p host_port user@virtual_machine_hostname
其中,host_port 是宿主機(jī)的端口號(hào),即前面啟動(dòng)虛擬機(jī)時(shí),-netdev user,id=mynic0,hostfwd=tcp::1234-:22 命令中的 1234 端口號(hào)。
讓我們通過 ssh 登錄虛擬機(jī)演示一下,這里通過如下命令:
ssh -p 1234 root@localhost
前面創(chuàng)建虛擬機(jī)時(shí),設(shè)置了宿主機(jī) 1234 端口映射到虛擬機(jī)的 22 端口,因此,可通過 -p 指定宿主機(jī)的 1234 端口轉(zhuǎn)發(fā)到虛擬機(jī)的 22 端口,root 是登錄虛擬機(jī)使用的用戶名,localhost 是安裝虛擬機(jī)時(shí)設(shè)置的虛擬機(jī)主機(jī)名。結(jié)果如下:
dmidecode 可以顯示有關(guān)系統(tǒng)硬件的詳細(xì)信息,包括制造商信息。虛擬機(jī)通常會(huì)在制造商信息中顯示虛擬化平臺(tái)的名稱。如果輸出類似于 QEMU、VMware, Inc. 或 innotek GmbH(VirtualBox),則說(shuō)明該系統(tǒng)運(yùn)行在虛擬機(jī)上。如果輸出的是一個(gè)實(shí)際的硬件制造商名稱,如 Dell Inc. 或 Lenovo,則說(shuō)明該系統(tǒng)運(yùn)行在物理機(jī)上。
2. 使用 VNC 登錄虛擬機(jī)
VNC(Virtual Network Computing) 是一種允許你通過網(wǎng)絡(luò)遠(yuǎn)程控制另一臺(tái)計(jì)算機(jī)桌面的技術(shù)。VNC 主要由兩部分組成:VNC 服務(wù)器(Server)和 VNC 客戶端(Client)。VNC 服務(wù)器運(yùn)行在被控制的計(jì)算機(jī)上,而 VNC 客戶端則運(yùn)行在遠(yuǎn)程控制計(jì)算機(jī)上。
QEMU 本身支持 VNC 功能,這意味著你可以直接通過 QEMU 的命令行參數(shù)啟動(dòng)虛擬機(jī),并啟用 VNC 服務(wù)器功能。這樣就不需要在虛擬機(jī)內(nèi)部單獨(dú)安裝 VNC 服務(wù)器軟件。要在 QEMU 創(chuàng)建的虛擬機(jī)內(nèi)啟用 VNC 功能,使用 QEMU 的 -vnc 選項(xiàng)啟動(dòng)虛擬機(jī),并指定 VNC 端口:-vnc :10 。但宿主機(jī)則需要安裝 VNC 客戶端,從而連接虛擬機(jī)中的 VNC 服務(wù)端。宿主機(jī)上 VNC 客戶端安裝命令如下:
yum install tigervnc -y
在宿主機(jī)上使用 VNC 客戶端連接虛擬機(jī):
vncviewer :10
8. 虛擬機(jī)的倉(cāng)庫(kù)配置
為了加快虛擬機(jī)中軟件包的下載速度,可以修改 CentOS 的倉(cāng)庫(kù)配置,使用國(guó)內(nèi)的鏡像源。
編輯 /etc/yum.repos.d/CentOS-AppStream.repo 文件:
[AppStream]
name=CentOS-$releasever - AppStream
baseurl=http://mirrors.aliyun.com/centos/$releasever/AppStream/$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
編輯 /etc/yum.repos.d/CentOS-Linux-BaseOS.repo 文件:
[baseos]
name=CentOS Linux $releasever - BaseOS
baseurl=http://mirrors.aliyun.com/centos/$releasever/BaseOS/$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
編輯 /etc/yum.repos.d/CentOS-Linux-Extras.repo 文件:
[extras]
name=CentOS Linux $releasever - Extras
baseurl=http://mirrors.aliyun.com/centos/$releasever/extras/$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
9. 常用工具安裝
在虛擬機(jī)中安裝一些常用的開發(fā)工具和庫(kù):
yum install autoconf automake python3 libmpc-devel mpfr-devel gmp-devel gawk bison flex patchutils gcc gcc-c++ zlib-devel expat-devel libslirp-devel -y
10. 虛擬機(jī)GNU工具鏈
下載工具鏈源碼:
git clone https://mirrors.tuna.tsinghua.edu.cn/git/binutils-gdb.git
git clone https://mirrors.tuna.tsinghua.edu.cn/git/gcc.git
安裝依賴:
yum groupinstall "Development Tools" -y
yum install gmp-devel mpfr-devel libmpc-devel -y
【拓展】yum groupinstall "Development Tools" 是一個(gè)命令,用于在基于 Red Hat 的系統(tǒng)(如 CentOS、Fedora、Red Hat Enterprise Linux)上安裝一組常用的開發(fā)工具。該命令解析如下:
- yum(Yellowdog Updater Modified) 是一個(gè)包管理器,用于安裝、更新和卸載軟件包。它可以根據(jù)依賴關(guān)系自動(dòng)解決軟件包之間的依賴關(guān)系。
- groupinstall 命令用于安裝預(yù)定義的軟件包組。每個(gè)組都包含一組相關(guān)的軟件包,這些軟件包通常是為了解決特定的任務(wù)或滿足某種用途而組合在一起的。
- "Development Tools" 是一個(gè)預(yù)定義的軟件包組,包含了開發(fā)人員在編寫、編譯和調(diào)試程序時(shí)需要的各種工具。這些工具通常包括編譯器、鏈接器、調(diào)試工具等。
"Development Tools" 軟件包組中的這些工具通常包括編譯器、鏈接器、調(diào)試工具以及其他與軟件開發(fā)相關(guān)的工具。通常包括但不限于:
- 編譯器:如 gcc 和 g++(GNU 編譯器集合的一部分)。
- 鏈接器:如 ld(GNU 鏈接器)。
- 調(diào)試工具:如 gdb(GNU 調(diào)試器)。
- 庫(kù)文件:如 libstdc++(C++ 標(biāo)準(zhǔn)庫(kù))。
- 文本編輯器:如 vim 或 nano。
- 構(gòu)建工具:如 make 和 autotools(autoconf, automake, libtool)。
- 包管理工具:如 rpm-build。
這些工具是軟件開發(fā)的基本組成部分,對(duì)于編寫、編譯、調(diào)試和打包應(yīng)用程序非常重要。
編譯 binutils-gdb 工具:
cd binutils-gdb/
./configure --enable-gold
# 使用所有可用的 CPU 核心進(jìn)行并行編譯,加快編譯速度。
make -j$(nproc)
# 以 root 權(quán)限安裝編譯好的 binutils
make install
其中,configure 選項(xiàng)的含義如下:
- --enable-gold:選項(xiàng)用于在編譯 binutils-gdb 時(shí)啟用 gold 鏈接器的支持。gold 是 GNU 鏈接器的一個(gè)替代品,設(shè)計(jì)用于提供更好的性能和額外的功能。
安裝好上述工具后,可在 /usr/local/bin/ 路徑下看到日常開發(fā)中常用的二進(jìn)制工具,如下:
[root@localhost repo]# ls /usr/local/bin
addr2line cpp gcc-ar gcov-dump gp-archive gprof ld.bfd objcopy readelf texi2dvi x86_64-pc-linux-gnu-gcc
ar dwp gcc-nm gcov-tool gp-collect-app gprofng ld.gold objdump size texi2pdf x86_64-pc-linux-gnu-gcc-15.0.0
as elfedit gcc-ranlib gdb gp-display-html help2man lto-dump pdftexi2dvi strings texindex x86_64-pc-linux-gnu-gcc-ar
c++ g++ gcore gdb-add-index gp-display-src install-info makeinfo pod2texi strip x86_64-pc-linux-gnu-c++ x86_64-pc-linux-gnu-gcc-nm
c++filt gcc gcov gdbserver gp-display-text ld nm ranlib texi2any x86_64-pc-linux-gnu-g++ x86_64-pc-linux-gnu-gcc-ranlib
運(yùn)行其中一個(gè)工具試驗(yàn)一下:
[root@localhost repo]# addr2line --help
Usage: addr2line [option(s)] [addr(s)]
Convert addresses into line number/file name pairs.
If no addresses are specified on the command line, they will be read from stdin
The options are:
@<file> Read options from <file>
-a --addresses Show addresses
-b --target=<bfdname> Set the binary file format
-e --exe=<executable> Set the input file name (default is a.out)
-i --inlines Unwind inlined functions
-j --section=<name> Read section-relative offsets instead of addresses
-p --pretty-print Make the output easier to read for humans
-s --basenames Strip directory names
-f --functions Show function names
-C --demangle[=style] Demangle function names
-R --recurse-limit Enable a limit on recursion whilst demangling. [Default]
-r --no-recurse-limit Disable a limit on recursion whilst demangling
-h --help Display this information
-v --version Display the program's version
addr2line: supported targets: elf64-x86-64 elf32-i386 elf32-iamcu elf32-x86-64 pei-i386 pe-x86-64 pei-x86-64 elf64-little elf64-big elf32-little elf32-big srec symbolsrec verilog tekhex binary ihex plugin
Report bugs to <https://sourceware.org/bugzilla/>
可以正常使用,但是當(dāng)運(yùn)行 gdb 時(shí),卻報(bào)如下錯(cuò)誤:
[root@localhost repo]# gdb --help
gdb: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.30' not found (required by gdb)
gdb: /lib64/libstdc++.so.6: version `CXXABI_1.3.15' not found (required by gdb)
gdb: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.29' not found (required by gdb)
gdb: /lib64/libstdc++.so.6: version `CXXABI_1.3.13' not found (required by gdb)
上述錯(cuò)誤信息表明 gdb 依賴的 libstdc++.so.6 庫(kù)版本不滿足要求。具體來(lái)說(shuō),gdb 需要的 GLIBCXX_3.4.30 和 CXXABI_1.3.15 版本在你的系統(tǒng)中找不到。這通常是因?yàn)槟愕南到y(tǒng)中的 libstdc++ 庫(kù)版本過舊。 為解決該問題,特進(jìn)行如下操作:
# 更新 libstdc++ 庫(kù)
yum update
yum install libstdc++-devel
# 驗(yàn)證安裝
strings /usr/local/lib64/libstdc++.so.6 | grep GLIBCXX
strings /usr/local/lib64/libstdc++.so.6 | grep CXXABI
# 設(shè)置庫(kù)路徑到 .bashrc 文件中,以便每次登錄時(shí)自動(dòng)設(shè)置
vi ~/.bashrc
# 在文件最后添加如下行:
export LD_LIBRARY_PATH=/usr/local/lib64:$LD_LIBRARY_PATH
進(jìn)行如上操作后,即可解決 gdb 因?yàn)?nbsp;libstdc++ 庫(kù)版本不匹配而無(wú)法運(yùn)行的問題。如果系統(tǒng)提供的庫(kù)版本過舊,可以從源代碼編譯安裝較新版本的 libstdc++ 庫(kù)。
編譯 gcc 工具:
mkdir build
cd build
../configure --enable-languages=c,c++ --disable-multilib
# 使用所有可用的 CPU 核心進(jìn)行并行編譯,加快編譯速度。
make -j$(nproc)
# 以 root 權(quán)限安裝編譯好的 GCC
make install
其中,configure 選項(xiàng)的含義如下:
- --enable-languages=c,c++:?jiǎn)⒂?nbsp;C 和 C++ 語(yǔ)言支持。
- --disable-multilib:禁用多庫(kù)支持,減少編譯時(shí)間。
安裝完成后,驗(yàn)證 gcc/g++ 是否正確安裝:
[root@localhost ~]# gcc --version
gcc (GCC) 15.0.0 20241023 (experimental)
Copyright (C) 2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
[root@localhost ~]# g++ --version
g++ (GCC) 15.0.0 20241023 (experimental)
Copyright (C) 2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
你應(yīng)該看到類似如上的輸出,說(shuō)明 gcc/g++ 已成功安裝。通過以上步驟,你可以下載并安裝 g++ 15.0.0 版本。
11. 總結(jié)
通過以上步驟,你已經(jīng)成功地在 Linux 平臺(tái)上從源碼編譯 QEMU,并創(chuàng)建和配置了一個(gè)虛擬機(jī)。QEMU 提供了強(qiáng)大的虛擬化功能,結(jié)合 KVM 可以顯著提高虛擬機(jī)的性能。