Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add x86_64 uefi support #20

Merged
merged 4 commits into from
Aug 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 44 additions & 3 deletions doc_riscv/Markdown/RISC-V-oE多线程QEMU自动化测试使用.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
- 依赖 ``lsof`` 命令( MacOS 环境)
- 依赖 ``netstat`` 命令( Linux 环境)
- 使用
```shell
usage: qemu_test.py [-h] [-l list_file] [-x X] [-c C] [-M M] [-w W] [-m] [--user USER] [--password PASSWORD] [-A {riscv64,x86_64}] [-B B] [-K K] [-P P]
[-I I] [-D D] [-d MUGENDIR] [-g] [--detailed] [--addDisk] [--multiMachine] [--addNic] [--bridge_ip BRIDGE_IP] [-t T] [-F F]
```shell
usage: qemu_test.py [-h] [-l list_file] [-x X] [-c C] [-M M] [-w W] [-m] [--user USER] [--password PASSWORD] [-A {riscv64,x86_64}] [-B B] [-U U] [-K K]
[-P P] [-I I] [-D D] [-d MUGENDIR] [-g] [--detailed] [--addDisk] [--multiMachine] [--addNic] [--bridge_ip BRIDGE_IP] [-t T] [-F F]

options:
-h, --help show this help message and exit
Expand All @@ -26,6 +26,7 @@
--password PASSWORD Specify password
-A {riscv64,x86_64} Specify the qemu architecture
-B B Specify bios
-U U Specify UEFI pflash
-K K Specify kernel
-P P Specify kernel parameters
-I I Specify initrd
Expand Down Expand Up @@ -55,6 +56,7 @@
- 可使用 ``-A`` 参数或 ``"qemuArch"`` 项指定测试使用的 qemu 架构,在没有指定该参数的情况下默认为 RISC-V 架构
- 可使用 ``-c`` 、 ``-M`` 参数或 ``"cores"`` 、 ``"memory"`` 项指定 qemu 虚拟机 CPU 核数和分配的内存大小
- 可使用 ``-B`` 参数或 ``"bios"`` 项指定 qemu 启动使用的固件
- 可使用 ``-U`` 参数或 ``"pflash"`` 项指定 qemu 启动使用的 UEFI 固件 pflash 原始镜像,这个参数只在 x86_64 架构下生效,且由于该镜像会存储启动信息,故每个使用 UEFI 启动的实例都将复制一个独立的 pflash 文件并在关闭时删除,原始的镜像文件并不会被更改
- 可使用 ``-K`` 、 ``-I`` 、 ``-P`` 参数或 ``"kernel"`` 、 ``"initrd"`` 、 ``"kernelParams"`` 项在不使用固件的情况下直接从指定的内核启动,其中 ``-I`` 和 ``-P`` 是可选的,在没有指定内核参数的情况下将使用默认参数启动
- 若需指定 qemu 启动参数中 ``-bios`` 为 ``none`` ,需在配置文件中写明 ``"bios"`` 项为 ``"none"`` 或用 ``-B none`` 参数,否则 qemu 启动参数中 ``-bios`` 会省略
- 不指定 mugen 安装目录程序默认运行测试前准备 mugen 环境(包括安装 git 、 clone 仓库和 mugen 的依赖安装及结点配置),若待测镜像已准备好 mugen ,需用 ``"mugenDir"`` 配置项或 ``-d`` 指定 mugen 安装目录
Expand Down Expand Up @@ -125,6 +127,31 @@
}
```

- x86_64 使用 UEFI 启动示例配置文件
```json
{
"workingDir":"/home/hachi/mugen/qemu-imgs/openEuler-23.09-x86_64/",
"qemuArch":"x86_64",
"pflash":"/usr/share/edk2-ovmf/x64/OVMF.fd",
"drive":"mugen_ready_x86.qcow2",
"user":"root",
"password":"openEuler12#$",
"threads":4,
"cores":4,
"memory":4,
"mugenNative":1,
"detailed":1,
"addDisk":1,
"multiMachine":1,
"addNic":1,
"bridge ip":"10.0.0.1",
"tap num":50,
"mugenDir":"/root/mugen/",
"listFile":"lists/x86fail0_retest",
"generate":1
}
```

- 运行测试
```shell
python3 qemu_test.py -F /path/to/configFile
Expand All @@ -136,6 +163,20 @@
python3 qemu_test.py -w /run/media/brsf11/30f49ecd-b387-4b8f-a70c-914110526718/VirtualMachines/RISCVoE2203Testing20220926/ -B none -K fw_payload_oe_qemuvirt.elf -D openeuler-qemu.qcow2 -x 4 -c 4 -M 4 -m -g -l lists/list_git
```

#### UEFI 启动所需的 OVMF.fd

在 Archlinux 安装

```bash
sudo pacman -S edk2-ovmf
```

在 Debian 安装

```bash
sudo apt-get install ovmf
```

#### 宿主机联立网桥和虚拟网卡

这里给出一个示例演示多个 qemu 虚拟机实例配合测试所需的网桥和虚拟网卡的建立,假设要添加的网桥名为 ``br0`` ,网桥 IP 为 10.0.0.1/24 ,要加入的虚拟网卡名为 ``tap0``
Expand Down
36 changes: 24 additions & 12 deletions qemu_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def run(self):
self.attachVM.append(QemuVM(id= i*self.step+self.qemuVM.id, vcpu=self.qemuVM.vcpu , memory=self.qemuVM.memory,
user=self.qemuVM.user , password=self.qemuVM.password,
arch=self.qemuVM.arch, initrd=self.qemuVM.initrd,
kernel=self.qemuVM.kernel, kparms=self.qemuVM.kparms, bios=self.qemuVM.bios,
kernel=self.qemuVM.kernel, kparms=self.qemuVM.kparms, bios=self.qemuVM.bios, pflash=self.qemuVM.pflash,
workingDir=self.qemuVM.workingDir , bkfile=self.qemuVM.bkFile , path=self.qemuVM.path,
))
self.attachVM[i-1].start(disk=self.initTarget[1],machine=self.initTarget[2],tap_number=self.initTarget[3]+1,taplist=[self.tapQueue.get() for i in range(self.initTarget[3]+1)])
Expand Down Expand Up @@ -134,7 +134,7 @@ def run(self):
self.attachVM.append(QemuVM(id= i*self.step+self.qemuVM.id, vcpu=self.qemuVM.vcpu , memory=self.qemuVM.memory,
user=self.qemuVM.user , password=self.qemuVM.password,
arch=self.qemuVM.arch, initrd=self.qemuVM.initrd,
kernel=self.qemuVM.kernel, kparms=self.qemuVM.kparms, bios=self.qemuVM.bios,
kernel=self.qemuVM.kernel, kparms=self.qemuVM.kparms, bios=self.qemuVM.bios, pflash=self.qemuVM.pflash,
workingDir=self.qemuVM.workingDir , bkfile=self.qemuVM.bkFile , path=self.qemuVM.path,
))
self.attachVM[i-1].start(disk=self.initTarget[1],machine=self.initTarget[2],tap_number=1,taplist=[self.tapQueue.get()])
Expand Down Expand Up @@ -205,7 +205,7 @@ def run(self):
self.attachVM.append(QemuVM(id= i*self.step+self.qemuVM.id, vcpu=self.qemuVM.vcpu , memory=self.qemuVM.memory,
user=self.qemuVM.user , password=self.qemuVM.password,
arch=self.qemuVM.arch, initrd=self.qemuVM.initrd,
kernel=self.qemuVM.kernel, kparms=self.qemuVM.kparms, bios=self.qemuVM.bios,
kernel=self.qemuVM.kernel, kparms=self.qemuVM.kparms, bios=self.qemuVM.bios, pflash=self.qemuVM.pflash,
workingDir=self.qemuVM.workingDir , bkfile=self.qemuVM.bkFile , path=self.qemuVM.path,
))
self.attachVM[i-1].start(disk=target[1],machine=target[2],tap_number=target[3]+1,taplist=[self.tapQueue.get() for i in range(target[3]+1)])
Expand Down Expand Up @@ -238,7 +238,7 @@ def run(self):
self.attachVM.append(QemuVM(id= i*self.step+self.qemuVM.id, vcpu=self.qemuVM.vcpu , memory=self.qemuVM.memory,
user=self.qemuVM.user , password=self.qemuVM.password,
arch=self.qemuVM.arch, initrd=self.qemuVM.initrd,
kernel=self.qemuVM.kernel, kparms=self.qemuVM.kparms, bios=self.qemuVM.bios,
kernel=self.qemuVM.kernel, kparms=self.qemuVM.kparms, bios=self.qemuVM.bios, pflash=self.qemuVM.pflash,
workingDir=self.qemuVM.workingDir , bkfile=self.qemuVM.bkFile , path=self.qemuVM.path,
))
self.attachVM[i-1].start(disk=target[1],machine=target[2],tap_number=1,taplist=[self.tapQueue.get()])
Expand Down Expand Up @@ -289,14 +289,14 @@ def run(self):


class QemuVM(object):
def __init__(self, arch, vcpu, memory, workingDir, bkfile, kernel, kparms, initrd, bios, id=1, port=12055, user='root',password='openEuler12#$',
def __init__(self, arch, vcpu, memory, workingDir, bkfile, kernel, kparms, initrd, bios, pflash, id=1, port=12055, user='root',password='openEuler12#$',
path='/root/GitRepo/mugen-riscv' , restore=True, runArgs=''):
self.arch = arch
self.id = id
self.port , self.ip , self.user , self.password = port , '127.0.0.1' , user , password
self.vcpu , self.memory= vcpu , memory
self.workingDir , self.bkFile = workingDir , bkfile
self.kernel, self.kparms, self.initrd, self.bios = kernel, kparms, initrd, bios
self.kernel, self.kparms, self.initrd, self.bios, self.pflash = kernel, kparms, initrd, bios, pflash
self.drive = 'img'+str(self.id)+'.qcow2'
self.path = path
self.restore = restore
Expand Down Expand Up @@ -351,6 +351,10 @@ def start(self , disk=1 , machine=1 , tap_number=0 , taplist=[]):
biosArg=" -bios "+self.workingDir+self.bios
else:
biosArg=" "
if self.pflash is not None:
self.npflash = self.workingDir+"/OVMF_"+str(self.id)+".fd"
cmd = "cp "+self.pflash+" "+self.npflash
os.system(cmd)

ssh_port=self.port
if self.arch == 'riscv64':
Expand All @@ -360,7 +364,9 @@ def start(self , disk=1 , machine=1 , tap_number=0 , taplist=[]):
elif self.arch == 'x86_64':
cmd = "qemu-system-x86_64 \
-nographic -machine pc -accel kvm \
-cpu qemu64,+rdrand "
-cpu host "
if self.pflash is not None:
cmd += "-drive if=pflash,format=raw,file="+self.npflash+" "
else:
print('Unsupported qemu architecture ' + self.arch)
return
Expand Down Expand Up @@ -468,6 +474,8 @@ def destroy(self):
if self.restore:
os.system('rm -f '+self.workingDir+self.drive)
os.system('rm -f '+self.workingDir+'disk'+str(self.id)+'-*')
if self.pflash is not None:
os.system("rm -f "+self.npflash)


if __name__ == "__main__":
Expand All @@ -483,6 +491,7 @@ def destroy(self):
parser.add_argument('-A', type=str, choices=['riscv64', 'x86_64'], default='riscv64',
help='Specify the qemu architecture', dest='qemuArch')
parser.add_argument('-B',type=str,help='Specify bios')
parser.add_argument('-U',type=str,help='Specify UEFI pflash')
parser.add_argument('-K',type=str,help='Specify kernel')
parser.add_argument('-P',type=str,help='Specify kernel parameters')
parser.add_argument('-I',type=str,help='Specify initrd')
Expand All @@ -509,7 +518,7 @@ def destroy(self):
mugenNative , generateJson , preImg , genList = False , False , False , False
list_file , workingDir , bkFile , orgDrive , mugenPath = None , None , None , None , None
arch = 'riscv64'
kernel, kparms, initrd, bios = None, None, None, None
kernel, kparms, initrd, bios, pflash = None, None, None, None, None
img_base = 'img_base.qcow2'
detailed = False
user , password = "root","openEuler12#$"
Expand Down Expand Up @@ -575,7 +584,7 @@ def destroy(self):
if arch not in ['riscv64', 'x86_64']:
print("Unsupported qemu architecture " + arch)
exit(-1)
if configData.__contains__('workingDir') and (configData.__contains__('bios') or configData.__contains__('kernel')) and configData.__contains__('drive'):
if configData.__contains__('workingDir') and (configData.__contains__('bios') or configData.__contains__('kernel') or configData.__contains__('pflash')) and configData.__contains__('drive'):
if type(configData['workingDir']) == str:
workingDir = configData['workingDir']
else:
Expand All @@ -588,6 +597,8 @@ def destroy(self):
exit(-1)
if configData.__contains__('bios') and type(configData['bios']) == str:
bios = configData['bios']
if configData.__contains__('pflash') and type(configData['pflash']) == str:
pflash = configData['pflash']
if configData.__contains__('kernel') and type(configData['kernel']) == str:
kernel = configData['kernel']
if configData.__contains__('kernelParams') and type(configData['kernelParams']) == str and configData['kernelParams'].strip() != "":
Expand Down Expand Up @@ -653,10 +664,11 @@ def destroy(self):
for i in range(args.t):
tap.put('tap'+str(i))

if args.w != None and (args.B != None or args.K !=None) and args.D != None:
if args.w != None and (args.B != None or args.K != None or args.U != None) and args.D != None:
workingDir = args.w
orgDrive = args.D
bios = args.B
pflash = args.U
kernel = args.K
if args.P.strip() != "":
kparms = args.P
Expand Down Expand Up @@ -690,7 +702,7 @@ def destroy(self):
print('Failed to create img-base')
exit(-1)

preVM = QemuVM(id=1, port=findAvalPort(1)[0], user=user, password=password, arch=arch, kernel=kernel, kparms=kparms, initrd=initrd, bios=bios,
preVM = QemuVM(id=1, port=findAvalPort(1)[0], user=user, password=password, arch=arch, kernel=kernel, kparms=kparms, initrd=initrd, bios=bios, pflash=pflash,
vcpu=coreNum, memory=memSize, path=mugenPath, workingDir=workingDir, bkfile=bkFile,
restore=False)
preVM.start()
Expand Down Expand Up @@ -751,7 +763,7 @@ def destroy(self):
for i in range(threadNum):
qemuVM.append(QemuVM(id=i , vcpu=coreNum , memory=memSize,
user=user , password=password,
arch=arch, initrd=initrd, kernel=kernel, kparms=kparms, bios=bios,
arch=arch, initrd=initrd, kernel=kernel, kparms=kparms, bios=bios, pflash=pflash,
workingDir=workingDir , bkfile=bkFile , path=mugenPath,
runArgs=runningArg))
targetQueue = Queue()
Expand Down