整個simulate腳本就是在構(gòu)建qemu仿真的參數(shù)
#!/usr/bin/env python3
#
# Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
#
# SPDX-License-Identifier: BSD-2-Clause
#
import subprocess #用于執(zhí)行外部指令
import sys
import argparse
import time
def parse_args(): #使用parse_args函數(shù)解析命令行參數(shù)
parser = argparse.ArgumentParser()
parser.add_argument('-b', '--binary', dest="qemu_sim_binary", type=str,
help="QEMU binary", default="qemu-system-x86_64")
parser.add_argument('-d', '--gdbserver', dest="qemu_gdbserver", action='store_true',
help="Tell QEMU to wait for gdb on port 1234")
parser.add_argument('-M', '--machine', dest="qemu_sim_machine", type=str,
help="QEMU Machine", default="")
parser.add_argument('-c', '--cpu', dest='qemu_sim_cpu', type=str,
help="QEMU CPU", default="Nehalem")
parser.add_argument('-o', '--cpu-opt', dest='qemu_sim_cpu_opt', type=str,
help="QEMU CPU Options", default=",-vme,+pdpe1gb,-xsave,-xsaveopt,-xsavec,-fsgsbase,-invpcid,+syscall,+lm,enforce")
parser.add_argument('-g', '--graphic', dest='qemu_sim_graphic_opt', type=str,
help="QEMU Graphic Options", default="-nographic")
parser.add_argument('-s', '--serial', dest='qemu_sim_serial_opt', type=str,
help="QEMU Serial Options", default="-serial mon:stdio")
parser.add_argument('-m', '--mem-size', dest='qemu_sim_mem_size', type=str,
help="QEMU Memory Size Option", default="512M")
parser.add_argument('-a', '--args', dest='qemu_sim_args', type=str,
help="Arguments to pass onto QEMU", default="")
parser.add_argument('-k', '--kernel', dest='qemu_sim_kernel_file', type=str,
help="Kernel file to pass onto QEMU", default="images/kernel-x86_64-pc99")
parser.add_argument('-i', '--initrd', dest='qemu_sim_initrd_file', type=str,
help="Initrd file to pass onto QEMU", default="images/hello-world-image-x86_64-pc99")
parser.add_argument("-n", '--dry-run', dest='dry_run', action='store_true',
help="Output command for QEMU (and GDB), but do not execute it")
parser.add_argument('--extra-qemu-args', dest='qemu_sim_extra_args', type=str,
help="Additional arguments to pass onto QEMU", default="")
parser.add_argument('--extra-cpu-opts', dest='qemu_sim_extra_cpu_opts', type=str,
help="Additional cpu options to append onto the existing CPU options",
default="")
args = parser.parse_args()
return args
def notice(message): #用輸出帶有程序名稱前綴的log
# Don't call this without initialising `progname`.
assert(progname)
sys.stderr.write("{}: {}".format(progname, message))
sys.stderr.flush()
if __name__ == "__main__":
args = parse_args() #解析命令行參數(shù)并存儲在args變量中
progname = sys.argv[0] #獲取腳本自身的名稱(progname)
if args.qemu_sim_kernel_file == "": #根據(jù)參數(shù)選擇使用哪個內(nèi)核文件(默認(rèn)為images/hello-world-image-x86_64-pc99)
qemu_sim_images_entry = "-kernel " + args.qemu_sim_initrd_file
else:
qemu_sim_images_entry = "-kernel " + args.qemu_sim_kernel_file + " -initrd " + args.qemu_sim_initrd_file
qemu_sim_cpu_entry = "" #構(gòu)建CPU選項
if args.qemu_sim_cpu != "":
qemu_sim_cpu_entry = "-cpu " + args.qemu_sim_cpu + args.qemu_sim_cpu_opt + \
("," + args.qemu_sim_extra_cpu_opts if args.qemu_sim_extra_cpu_opts else "")
qemu_sim_machine_entry = "" #構(gòu)建QEMU機(jī)器選項
if args.qemu_sim_machine:
qemu_sim_machine_entry = "-machine " + args.qemu_sim_machine
qemu_gdbserver_command = "" #如果選擇啟用GDB調(diào)試服務(wù)器外遇,則添加相應(yīng)的參數(shù)
if args.qemu_gdbserver:
qemu_gdbserver_command = "-s -S"
qemu_sim_mem_size_entry = "-m size=" + args.qemu_sim_mem_size #構(gòu)建內(nèi)存大小選項
qemu_simulate_command_opts = [args.qemu_sim_binary, qemu_sim_machine_entry, qemu_sim_cpu_entry, args.qemu_sim_graphic_opt,
args.qemu_sim_serial_opt, qemu_sim_mem_size_entry, args.qemu_sim_extra_args, qemu_sim_images_entry,
qemu_gdbserver_command] #構(gòu)建額外的QEMU參數(shù)
qemu_simulate_command = " ".join(qemu_simulate_command_opts) #構(gòu)建完整的QEMU命令
notice('QEMU command: ' + qemu_simulate_command) #輸出構(gòu)建的QEMU命令,如果選擇了dry-run選項則僅輸出不執(zhí)行
if args.dry_run:
exit()
if qemu_gdbserver_command != "": #如果啟用了GDB調(diào)試服務(wù)器,則在端口1234上等待GDB連接
notice('waiting for GDB on port 1234...')
qemu_status = subprocess.call(qemu_simulate_command, shell=True) #運(yùn)行QEMU虛擬機(jī),并將返回狀態(tài)存儲在qemu_status中
if qemu_status != 0: #如果QEMU啟動失敗清蚀,等待一段時間后嘗試重置終端,以確苯稍剩控制臺的正確狀態(tài)
delay = 5 # in seconds
# Force a newline onto the output stream.
sys.stderr.write('\n')
msg = "QEMU failed; resetting terminal in lwr0ys0 seconds".format(d=delay) \
+ "--interrupt to abort\n"
notice(msg)
else:
delay = 2 # in seconds #如果QEMU啟動成功,也等待一段時間后重置終端
time.sleep(delay)
subprocess.call("tput reset", shell=True)
執(zhí)行hello-world是RAM鏡像文件中:
parser.add_argument('-k', '--kernel', dest='qemu_sim_kernel_file', type=str,
help="Kernel file to pass onto QEMU", default="images/kernel-x86_64-pc99")
parser.add_argument('-i', '--initrd', dest='qemu_sim_initrd_file', type=str,
help="Initrd file to pass onto QEMU", default="images/hello-world-image-x86_64-pc99")