QEMU Options and Commands
This section contains commonly used options and commands when using QEMU with virtual Xilinx hardware.
A larger list of options can be found here.
Options
These options are passed by the command line when starting QEMU.
If using PetaLinux tools, these options can be passed in by using the --qemu-args "<options>"
argument when booting your machine.
If using a multi-architecture system, such as Zynq UltraScale+ MPSoC or Versal Adaptive SoC, arguments can be passed into the MicroBlaze QEMU machine by using the --pmu-qemu-args "<options>"
argument.
Option | Description | Example | |||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
-accel tcg,thread=<multi|single> | Forces multi-threaded tiny code generator (MTTCG) to run or not run on QEMU. This means each VCPU runs on an individual host CPU thread. This is enabled by default on systems where it is stable and does not need to be explicitly passed in. Forcing MTTCG may cause incorrect emulation. MTTCG can not be enabled with | -accel tcg,thread=multi Enables MTTCG -accel tcg,thread=single Disables MTTCG | |||||||||||||||||||||||||||
-boot [order=<drives>][,once=<drives>][mode=<n>] | Specifies boot parameters when using U-Boot.
| -boot mode=5 Sets the value of boot mode pins to 5 (boot from SD1). | |||||||||||||||||||||||||||
-chardev <backend>,id=<id>[,mux=on|off][,options] | Creates a character devices that allows communication between a QEMU front-end and back-end. This can be thought of as a file descriptor that routes text from inside QEMU to outside QEMU. | -chardev socket,host=127.0.0.1,port=8887,id=pmu-console,server,nowait,mux=on Creates a multiplexed chardev server socket on localhost, with port 8887 that has the name pmu-console. | |||||||||||||||||||||||||||
-d <log item 1, ...> | help | Enables logging to If help is specified, a list of available log items is printed. See QEMU Module Debug Printing for more information on how to use |
Prints any guest errors that occur during emulation to
Prints any guest errors, and trace output for m25p80 decoded commands to | |||||||||||||||||||||||||||
-D <log file> | Redirects stderr to log file. | -D out.log Redirects | |||||||||||||||||||||||||||
-device <driver>[,prop[=<value>][,...]] | Adds the device driver. Typically, when emulating Xilinx hardware with QEMU, this option is used to load software and bring CPUs out of reset by using the | -device loader,file=/path/to/software/bl31.elf,cpu-num=0 Loads bl31.elf and runs it on CPU 0 -device loader,addr=0xFD1A0104,data=0x0000000E,data-len=4 Writes When writing data to an address, the order must be | |||||||||||||||||||||||||||
-display <type> | The type of display to be used | -display none Specifies there's no display. | |||||||||||||||||||||||||||
-drive [file=<path>][,if=<interface>]\ | Defines a new drive. See: Storage Media for more information. | -drive file=/path/to/img/qemu_boot.img,if=sd,format=raw,index=1 Creates an SD drive at index 1 with the image qemu_boot.img. | |||||||||||||||||||||||||||
-dtb <dtb path> | The hardware description for the QEMU machine. Anything that QEMU cannot emulate is discarded. If a Linux kernel is present, the dtb is passed to it through a memory buffer. See: -dtb vs -hw-dtb for more detail. | -dtb /path/to/dtb/system.dtb Speficies the QEMU hardware description to be system.dtb and passes it to the Linux Kernel (if present). | |||||||||||||||||||||||||||
-gdb <host>:<port> | Opens a GDB server on host:port. | -gdb tcp:127.0.0.1:9001 Creates a GDB server on | |||||||||||||||||||||||||||
-global <property>=<val> | Sets driver properties for devices created by the machine model. | -global xlnx,zynqmp-boot.cpu-num=0 Releases A53 CPU 0 from reset. | |||||||||||||||||||||||||||
-hw-dtb <dtb path> | The hardware description for the QEMU machine. See: -dtb vs -hw-dtb for how this differs from the -dtb parameter. | -hw-dtb /path/to/dtb/zynqmp-qemu-multiarch-arm.dtb Specifies the QEMU hardware description to be zynqmp-qemu-multiarch-arm.dtb. | |||||||||||||||||||||||||||
-kernel <kernel img> | Specifies an image, such as a kernel or bare-metal image. | -kernel /path/to/kernel/pmu_rom_qemu_sha3.elf Specifies the image pmu_rom_qemu_sha3.elf. | |||||||||||||||||||||||||||
-m <memory size> | Allocates memory size bytes of RAM for the virtual machine. By default, QEMU allocates 128MB of RAM. | -m 4G This machine will have 4GB of RAM allocated -m 512M This machine will have 512MB of RAM allocated | |||||||||||||||||||||||||||
-M <machine> | Specifies the machine architecture. | -M arm-generic-fdt Specifies that this is an ARM-generic-fdt machine. -M microblaze-fdt Specifies that this is a microblaze-fdt machine. | |||||||||||||||||||||||||||
-machine-path <dir> | Specifies a directory where QEMU creates shared memory files and named UNIX sockets. When emulating Xilinx hardware with QEMU, this is used to share data between architectures in multiarch environments, or for co-simulation. It is recommended you clear the | -machine-path /tmp/qemu-shm Specifies that /tmp/qemu-shm is where QEMU shared memory and UNIX sockets will be created. | |||||||||||||||||||||||||||
-net nic[,netdev=<nd>][,macaddr=<mac>] | When nic is specified, this option configures or creates an on-board network interface card and connects it either to the emulated hub, or to the netdev nd. When user is specified, this option configures a host network back-end and connects it to the emulated default hub. | -net nic Creates an on-board NIC. -net user,id=eth0,tftp=/host/path/for/tftp Creates a network back-end with the ID eth0 that has TFTP access to the host path | |||||||||||||||||||||||||||
-nographic | This machine will have no graphic output. Also passes in the | -nographic Specifies there's no graphics and passes in | |||||||||||||||||||||||||||
-S | Pauses the machine on the first instruction. Typically this is used with the gdb option to debug the boot sequence of your machine. |
Pauses the machine on the first instruction. | |||||||||||||||||||||||||||
-s | Shorthand for -gdb tcp::1234 |
Creates a GDB server on | |||||||||||||||||||||||||||
-serial <dev> | Connects the serial device to dev. | -serial mon:stdio Connect this serial device to the QEMU monitor and STDIO. -serial null Don't connect this serial device -serial chardev:pmu-console Connect this serial device to the chardev pmu-console. |
-dtb vs -hw-dtb
Xilinx QEMU supports two device tree options:
- -hw-dtb is used for the hardware device tree binary that QEMU uses to generate the model. Hardware device tree binaries will have the name of the device it represents. For example,
board-versal-ps-vc-p-a2197-00.dtb
is for Versal andzcu102-arm.dtb
for the ZCU102 board. - -dtb is generally a Linux device tree binary used for Linux kernel boots. With the DTB passed in with
-dtb
option, QEMU removes the nodes that it cannot emulate and later copies them to RAM for the kernel. Xilinx Linux kernel device tree binaries are typically namedsystem.dtb
.
For booting Linux on multi-arch platforms, such as Zynq Ultrascale+ MPSoC and Versal Adaptive SoC, we use the -hw-dtb
option, since guest device tree loading is skipped by QEMU.
If both -hw-dtb
and -dtb
are used in multi-arch environments, the DTB passed in with -dtb
is ignored.
For standalone (single-arch) flows, these two arguments are fully interchangeable; specify only one or the other.
This procedure is applicable only when -kernel
is passed on QEMU command line.
For Zynq Ultrascale+ MPSoC and Versal Adaptive SoC in a multi-architecture environment, the QEMU DTB is different from the kernel system.dtb
.
QEMU DTS are different for Zynq UltraScale+ MPSoC and Versal Adaptive SoC single and multi-architecture models. The following DTBs are available in PetaLinux project:
Zynq UltraScale+ MPSoC
- Single-arch:
zynqmp-qemu-arm.dtb
- Multi-arch:
zynqmp-qemu-multiarch-arm.dtb
,zynqmp-qemu-multiarch-pmu.dtb
Versal Adaptive SoC
- Single-arch:
versal-qemu-ps
.dtb
- Multi-arch:
versal-qemu-multiarch-ps
.dtb
,versal-qemu-multiarch-pmc.dtb
If building DTBs from source, the single-arch and multi-arch device trees will appear under path/to/dts-repo/LATEST/SINGLE_ARCH
and path/to/dts-repo
/LATEST/MULTI_ARCH
respectively.
QEMU Loader Options
[-device loader,(file=<file_name>|data=<value>,data-len=4),[addr=<value>],[cpu-num=<value>],[force-raw=true]] ...
This (repeatable) argument configures the QEMU machine for boot.
The loader driver can perform the following tasks:
- Load software or data into RAM sections
- Set the CPU entry points
- Release CPUs from reset
- Write to registers
In Zynq Ultrascale+ MPSoC, by default, the six ARM CPUs (four ARM-A53 and two ARM-R5) are in reset by their respective reset controllers when no software is loaded.
You can use a combination of -device
loader arguments to load software and setup the CPUs.
There are two basic modes for the loader argument: file mode and single transaction mode. Specify only one mode for each -device
argument.
The following subsections describe these modes.
File Mode
In file mode, the loader accepts a file as data to load. The file can be in any format and is passed using the file=<file_name>
sub-option.
If the file is an ELF or a U-Boot image, the file is parsed and the sections loaded into memory as specified by the image; otherwise, the file is assumed as a raw image and loaded accordingly as an image into memory.
When loading raw images, the address is specified with the addr=<value>
argument. The default address is 0. The address is ignored if the file is an ELF or U-Boot image.
Optionally, you can specify a CPU using the cpu-num=<value>
sub-option. Specifying cpu-num
also sets the Program Counter (PC).
The CPU has a set entry point in the following situations:
- For ELFs and U-Boot images, the entry point is set as specified by the image.
- For raw images, the entry point is set to the start address.
- If you do not specify a CPU, the bus for CPU0 loads images, but no program entry point is set.
There are cases where you might want to treat an ELF or a U-Boot image as a raw data image (particularly useful for testing bootloaders with ELF or U-Boot capability).
In this case, you can pass the force-raw=true
sub-option to instruct the loader to treat the image as raw.
You must specify the addr
, since the section information in the ELF and U-Boot images are ignored.
Single Transaction Mode
In single transaction mode, a single bus transaction occurs.
addr
anddata-len
must be specified.data-len
must equal 4 (corresponding to a single 4-byte transaction).addr
must be 32-bit aligned.
Before the initial system reset for Zynq Ultrascale+ MPSoC or Versal Adaptive SoC, QEMU performs the specified bus transaction.
Optionally, you can specify a CPU using the cpu-num=<value>
sub-option.
The list of CPU enumeration values for Zynq Ultrascale+ MPSoC and Versal Adaptive SoC are given below:
Value | Zynq Ultrascale+ MPSoC CPU |
---|---|
0 | A53-0 |
1 | A53-1 |
2 | A53-2 |
3 | A53-3 |
4 | R5-0 |
5 | R5-1 |
Value | Versal Adaptive SoC CPU |
---|---|
0 | A72-0 |
1 | A72-1 |
2 | R5-0 |
3 | R5-1 |
If you edit the /cpus
node in the DTB, these enumerations change.
The single transaction occurs from the perspective of the specified CPU. If you do not specify a CPU, then the system assumes CPU0
.
Storage Media
Several disk and storage media interfaces are modeled. You can pass each to a regular file(s) to use for stored data.
QEMU updates the files so the data can persist across multiple sessions.
Argument Format
-drive file=<image-path>, if=(mtd|sd|pflash),format=<fmt>,index=<value>[,readonly]
The argument allows specification of extra options such as marking the file as read-only.
The argument can also be used to specify the index of the device, allowing specifying files for devices in an order-independent way.
QSPI
QSPI is modeled with the Flash specified in DTS. The SPI flashes can connect in a single or dual-parallel arrangement.
The file size for each should match Flash model size.
If you are using only a single mode QSPI, then only one QSPI argument is needed.
For each drive, if an image is not provided, QEMU still models the flash, but initializes with NULL
data and discards the data after QEMU exists.
Data can be written and read back within a single session in this case.
Creating a QSPI image and booting with QSPI is outlined here.
Flash Striper Utility
In parallel mode, the data that QSPI passes in for each flash is unique to that flash chip.
The QSPI controller also performs bit or byte striping in dual parallel mode, and because of this a special utility is needed to take a single QSPI data image and format it into two images.
The syntax is as follows:
flash_strip <input> <out1> <out0>
flash_strip_be <input> <out1> <out0>
flash_strip_bw <input> <out1> <out0>
Where:
flash_strip
andflash_strip_be
formats with bit striping.flash_strip_be
expects the flash data bits in big endian.flash_strip_bw
formats the output with byte wise striping.<input>
is a 128MB image for Zynq UltraScale+ or a 256MB image on Versal Adaptive SoC.<out0>
and<out1>
are the two images with half the size of the input image (64MB or 128MB) passable to the-
mtdblock
arguments for QSPI.
The reverse is also possible, taking the two striped images and converting them back to a single 128MB or 256MB image as shown in the following command:
flash_unstrip <output> <in1> <in0>
flash_unstrip_be <output> <in1> <in0>
flash_unstrip_bw <output> <in1> <in0>
Building the Flash Striper utilities
The complete flash striper utility source code is available here.
Building the Bit Stripe Utilities
The bit stripe utilities are used for legacy QSPI (LQSPI) on Zynq7000.
Compile the flash striper utility for your host with the following commands:
gcc flash_stripe.c -o flash_strip gcc flash_stripe.c -o flash_unstrip -DUNSTRIPE
If the flash data bits are in big-endian format use flash_strip_be
when creating the flash images (and flash_unstrip_be
for backwards conversion).
gcc flash_stripe.c -o flash_strip_be -DFLASH_STRIPE_BE gcc flash_stripe.c -o flash_unstrip_be -DUNSTRIPE -DFLASH_STRIPE_BE
Building the Byte Stripe Utilities
The byte stripe utilities are used for generic QSPI (GQSPI) on Zynq UltraScale+ MPSoC and Versal Adaptive SoC.
Compile the flash striper utility for your host with the following commands:
gcc flash_stripe.c -o flash_strip_bw -DFLASH_STRIPE_BW gcc flash_stripe.c -o flash_unstrip_bw -DUNSTRIPE -DFLASH_STRIPE_BW
flash_strip_bw
is also available as part of the PetaLinux tools.
Supported QSPI Flash Models
Vendor | Flash Models |
---|---|
Atmel | at25fs010, 25fs040, at25df041a, at25df321a, at25df641, at26f004, at26df081a, at26df161a, at26df321, at45db081d |
EON | en25f32, en25p32, en25q32b, en25p64, en25q64 |
GigaDevice | gd25q32, gd25q64 |
Intel/Numonyx | 160s33b, 320s33b, 640s33b n25q064 |
Macronix | mx25l2005a, mx25l4005a, mx25l8005, mx25l1606e, mx25l3205d, mx25l6405d, mx25l12805d, mx25l12855e, mx25l25635e, mx25l25655e |
Micron | n25q032a1, n25q032a13, n25q064a11, n25q064a13, n25q128a11, n25q128a13, n25q256a11, n25q256a13, n25q512a11, n25q512a1 |
Spansion – single (large) sector size only, at least for the chips listed here (without boot sectors) | s25sl032p, s25sl064p, s25fl256s0, s25fl256s1, s25fl512s, s70fl01gs, s25sl12800, s25sl12801, s25fl129p0, s25fl129p1, s25sl004a, s25sl008a, s25sl016as, 25sl032a, s25sl064a, s25fl016k, s25fl064k |
Winbond – w25x “blocks” are 64k, “sectors” are 4KiB | w25x10, w25x20, w25x40, w25x80, w25x16, w25x32, w25q32, w25q32dw, w25x64. w25q64, w25q80, w25q80b, w25q256 |
Numonyx | 25q128 |
SST | sst25vf040b, sst25vf080b, sst25vf016b, sst25vf032b, sst25wf512, sst25wf010, sst25wf020, sst25wf040, sst25wf080 |
ST Microelectronics | m25p05, m25p10, m25p20, m25p40, m25p80, m25p16, m25p32, m25p64, m25p128, n25q032, m45pe10, m45pe80, m45pe16, m25pe20, m25pe80, m25pe16, m25px32, m25px32-s0, m25px32-s1, m25px64 |
SPI
For each SPI Flash, if an image is not provided, QEMU still models the flash, but initializes with NULL data and discards the data after QEMU exits.
Data can be written and read back within a single session in this case.
SD
QEMU models an SD card for -drive file=<file_path>,if=sd
The SD card model in QEMU is generic and does not attempt to model a specific physical part.
The size of the input file initializes the size of the emulated SD card.
Only 512MB SD images are officially supported, although powers of two around that order of magnitude will work.
SDXC (>32GB) sizes do not work.
If an SD argument is not specified, no SD card is modeled, the corresponding SD slot is ejected.
This is different from SPI, where the flash is still modeled even if an image is not provided.
Information for booting with SD can be found here.
eMMC
QEMU will model an eMMC card for -
drive file=<file_path>,if=sd
. This requires changes in the system-level control register (SLCR) registers to enable eMMC. The table below shows the registers that need to be modified:
Platform | Register | Fields |
---|---|---|
Zynq UltraScale+ MPSoC | IOU_SLCR | CTRL_REG_SD |
Versal Adaptive SoC | PMC_IOU_SLCR | SD0_CTRL_REG SD1_CTRL_REG |
For Zynq Ultrascale+ MPSoC and Versal index=2
works as an EMMC card connected to sdhci0
.
The size of the input file initializes the size of the emulated eMMC card.
Only 512MB images are supported, although powers of two, around that order of magnitude will work.
EEPROM
QEMU models EEPROMs connected via I2C. A back-end file can be passed as follows:
-drive file=<file_path>,if=mtd,index=<id>.
Users can find the information on the connected EEPROMs in the board's DTS file.
Boot Examples
This section contains boot examples for Zynq Ultrascale+ MPSoC and Versal Adaptive SoC and what each parameter means.
Your boot parameters may vary slightly, depending on your project.
As an side note, these boot commands were created by going into a PetaLinux project and booting with the following command:
$ petalinux-boot --qemu --prebuilt 3
Booting with an Application
The following examples use the FSBL as the application being booted, however the command-line formats used in these examples are applicable to other standalone applications as well.
The FSBL is bundled with PetaLinux or Yocto BSPs.
QEMU does not model the DDRMC, for performance reasons. Because of this, using the FSBL can cause hangs in QEMU.
See the known issues page for what to do if this problem occurs.
A53 Application (Zynq UltraScale+ MPSoC)
A53-0 FSBL in JTAG Mode
qemu-system-aarch64 \ -M arm-generic-fdt \ -m 4G \ -nographic \ -serial null \ -serial null \ -serial mon:stdio \ -hw-dtb ./images/linux/zynqmp-qemu-arm.dtb \ -device loader,file=./images/linux/zynqmp_a53_fsbl.elf,cpu-num=0 \ -device loader,addr=0xfd1a0104,data=0x8000000e,data-len=4
A53-0 FSBL in QSPI Boot Mode (Single)
qemu-system-aarch64 \ -M arm-generic-fdt \ -m 4G \ -nographic \ -serial null \ -serial null \ -serial mon:stdio \ -hw-dtb ./images/linux/zynqmp-qemu-arm.dtb \ -device loader,file=./images/linux/zynqmp_a53_fsbl.elf,cpu-num=0 \ -device loader,addr=0xfd1a0104,data=0x8000000e,data-len=4 \ -drive file=qemu_qspi.bin,if=mtd,format=raw,index=0\ -boot mode=1
A53-0 FSBL in QSPI Boot Mode (Dual Parallel)
qemu-system-aarch64 \ -M arm-generic-fdt \ -m 4G \ -nographic \ -serial null \ -serial null \ -serial mon:stdio \ -hw-dtb ./images/linux/zynqmp-qemu-arm.dtb \ -device loader,file=./images/linux/zynqmp_a53_fsbl.elf,cpu-num=0 \ -device loader,addr=0xfd1a0104,data=0x8000000e,data-len=4 \ -drive file=qemu_qspi_low.bin,if=mtd,format=raw,index=0 \ -drive file=qemu_qspi_high.bin,if=mtd,format=raw,index=1 \ -boot mode=1
Default ZCU102 Petalinux design has QSPI in a dual parallel Configuration.
A53-0 FSBL in SD0 Boot Mode
qemu-system-aarch64 \ -M arm-generic-fdt \ -m 4G \ -nographic \ -serial null \ -serial null \ -serial mon:stdio \ -hw-dtb ./images/linux/zynqmp-qemu-arm.dtb \ -device loader,file=./images/linux/zynqmp_a53_fsbl.elf,cpu-num=0 \ -device loader,addr=0xfd1a0104,data=0x8000000e,data-len=4 \ -drive file=qemu_sd.img,if=sd,format=raw,index=0 \ -boot mode=3
Default ZCU102 board supports SD1. Index should be set to 1 for SD drive argument.
A72 Application (Versal Adaptive SoC)
A72-0 FSBL in JTAG Mode
qemu-system-aarch64 -M arm-generic-fdt \ -m 8G \ -nographic \ -serial null \ -serial null \ -serial mon:stdio \ -device loader,addr=0xFD1A0300,data=0x8000000e,data-len=4 \ -hw-dtb /path/to/dtb/versal-qemu-ps.dtb \ -kernel /path/to/image/image.elf
Zynq UltraScale+ MPSoC R5 Application
R5-0 FSBL in JTAG Mode
qemu-system-aarch64 \ -M arm-generic-fdt \ -m 4G \ -nographic \ -serial null \ -serial null \ -serial mon:stdio \ -hw-dtb ./images/linux/zynqmp-qemu-arm.dtb \ -device loader,file=zynqmp_r5_fsbl.elf,cpu-num=4 \ -device loader,addr=0xff5e023c,data=0x80008fde,data-len=4 \ -device loader,addr=0xff9a0000,data=0x80000218,data-len=4
R5-0 FSBL in QSPI Boot Mode (Single)
qemu-system-aarch64 \ -M arm-generic-fdt \ -m 4G \ -nographic \ -serial null \ -serial null \ -serial mon:stdio \ -hw-dtb ./images/linux/zynqmp-qemu-arm.dtb \ -device loader,file=zynqmp_r5_fsbl.elf,cpu-num=4 \ -device loader,addr=0xff5e023c,data=0x80008fde,data-len=4 \ -device loader,addr=0xff9a0000,data=0x80000218,data-len=4 \ -drive file=qemu_qspi.bin,if=mtd,format=raw,index=0 \ -boot mode=1
R5-0 FSBL in QSPI Boot Mode (Dual Parallel)
qemu-system-aarch64 \ -M arm-generic-fdt \ -m 4G \ -nographic \ -serial null \ -serial null \ -serial mon:stdio \ -hw-dtb ./images/linux/zynqmp-qemu-arm.dtb \ -device loader,file=zynqmp_r5_fsbl.elf,cpu-num=4 \ -device loader,addr=0xff5e023c,data=0x80008fde,data-len=4 \ -device loader,addr=0xff9a0000,data=0x80000218,data-len=4 \ -drive file=qemu_qspi_low.bin,if=mtd,format=raw,index=0 \ -drive file=qemu_qspi_high.bin,if=mtd,format=raw,index=1 \ -boot mode=1
R5-0 FSBL in SD0 Boot Mode
qemu-system-aarch64 \ -M arm-generic-fdt \ -m 4G \ -nographic \ -serial null \ -serial null \ -serial mon:stdio \ -hw-dtb ./images/linux/zynqmp-qemu-arm.dtb \ -device loader,file=zynqmp_r5_fsbl.elf,cpu-num=4 \ -device loader,addr=0xff5e023c,data=0x80008fde,data-len=4 \ -device loader,addr=0xff9a0000,data=0x80000218,data-len=4 \ -drive file= qemu_sd.img,if=sd,format=raw,index=0 \ -boot mode=3
R5 Lockstep FSBL
Only one example is provided for lock step, although all boot modes are valid. See the previous example command line arguments for storage media and boot mode that could be applied to this command line.
This specific example is JTAG boot mode.
qemu-system-aarch64 \ -M arm-generic-fdt \ -nographic \ -serial null \ -serial null \ -serial mon:stdio \ -hw-dtb ./images/linux/zynqmp-qemu-arm.dtb \ -device loader,file=zynqmp_r5_fsbl.elf,cpu=4 \ -device loader,addr=0xff5e023c,data=0x80008fde,data-len=4
Versal Adaptive SoC R5 Application
R5-0 Application in JTAG Mode
/scratch/proj/qemu/build/aarch64-softmmu/qemu-system-aarch64 \ -M arm-generic-fdt \ -device loader,file=/path/to/image.elf,cpu-num=2 \ -device loader,addr=0xff5e0300,data=0x16,data-len=4 \ -device loader,addr=0xff9a0100,data=0x1,data-len=4 \ -device loader,addr=0xff9a0000,data=0x8,data-len=4 \ -serial null \ -serial null \ -serial stdio \ -display none \ -hw-dtb /path/to/dtb/board-versal-ps-virt.dtb
R5 Lockstep
/scratch/proj/qemu/build/aarch64-softmmu/qemu-system-aarch64 \ -M arm-generic-fdt \ -device loader,file=/path/to/image/image.elf,cpu-num=2 \ -device loader,addr=0xff5e0300,data=0x14,data-len=4 \ -device loader,addr=0xff9a0000,data=0x50,data-len=4 \ -device loader,addr=0xff9a0100,data=0x1,data-len=4 \ -serial null \ -serial null \ -serial stdio \ -display none \ -hw-dtb /path/to/dtb/board-versal-ps-virt.dtb
Terminal Commands
These are some of the terminal commands that can be used when QEMU is started with the -nographic
option.
Command | Description |
---|---|
CTRL+A C | Switch between the QEMU monitor and console. |
CTRL+A X | Exit QEMU. |
CTRL+A H | Prints the terminal command help message. |
QEMU Monitor Commands
This is a short list of useful QEMU monitor commands, for a full list, use the help
and help info
commands in the QEMU Monitor.
To get to the QEMU monitor, do CTRL+A C
while in QEMU. To exit the QEMU monitor, do CTRL+A C
while inside the QEMU monitor.
Command | Description |
---|---|
help | Prints a list of monitor commands and a description of each one. |
help info | Prints a list of info monitor commands and a description of each one. |
info qtree | Prints the device tree. |
info mtree | Prints the memory tree. |
info cpus | Shows information for each CPU. |
info registers [-a] | Shows the CPU registers. |
memsave <addr> <len> <file> | Reads len bytes at memory address addr and saves it to file file as raw binary data. |
system_reset | Resets the system. |
x /fmt <addr> | Prints the memory at the virtual address addr, with format dictated by fmt. |
xp /fmt <addr> | Prints the memory at the physical address addr, with format dictated by fmt. |
stop | Stops emulation |
c | Resumes emulation |
q | Quits QEMU. |
Hot Loading
You can use the loader at runtime to load new software into an already running system. This is accessible from the QEMU monitor.
From the monitor, you can stop the emulation using the stop
command:
(qemu) stop
You can then use the loader to add new software or release CPUs from reset. The syntax is:
(qemu) device_add loader,(file=<file>|data=<value>,data len=4),[addr=<value>],[cpu-num=<value>],[force-raw=true]
The options are the same as the ones described in QEMU Loader Options.
The emulation can then be resumed (with the new memory and CPU state from the loading operations) using the c
command:
(qemu) c
Linux Kernel Logbuf Extraction
Using the QEMU monitor command memsave
, it is possible to extract the Linux kernel logbuf and read it.
Get the logbuf address and size
Use readelf
to get the address and size of the logbuf.
$ readelf -a image.elf | grep __log_buf 1: c1324c44 0x20000 OBJECT LOCAL DEFAULT 21 __log_buf
image.elf
is the image you pass into QEMU that contains the Linux kernel whose logbuf you want to extract.
The numbers we care about in this case are c1324c44
and 0x20000
, which are the virtual address and the size of the logbuf respectively.
Dump the logbuf from QEMU
In the QEMU monitor window, type:
(qemu) memsave 0xc1324c44 0x20000 dumpmem.logbuf
Read the contents
Parts of the logbuf will have binary data in it, which can be fixed by using a logbuf reader program, found here.
Compile the reader.
$ gcc logbuf-reader.c -o logbuf-reader
Then pipe the logbuf through the reader and cat
it.
$ cat dumpmem.logbuf | logbuf-reader Ramdisk addr 0x00000000, FDT at 0x813ae998 Linux version 4.19.0-xilinx-v2019.2 (oe-user@oe-host) (gcc version 8.2.0 (GCC)) #1 Thu Oct 3 22:42:39 UTC 2019 setup_memory: max_mapnr: 0x7ffff setup_memory: min_low_pfn: 0x80000 setup_memory: max_low_pfn: 0xb0000 setup_memory: max_pfn: 0xfffff Zone ranges: DMA [mem 0x0000000080000000-0x00000000afffffff] Normal empty HighMem [mem 0x00000000b0000000-0x00000000ffffefff] Movable zone start for each node Early memory node ranges node 0: [mem 0x0000000080000000-0x00000000ffffefff] Initmem setup node 0 [mem 0x0000000080000000-0x00000000ffffefff] On node 0 totalpages: 524287 DMA zone: 1536 pages used for memmap DMA zone: 0 pages reserved DMA zone: 196608 pages, LIFO batch:63 HighMem zone: 327679 pages, LIFO batch:63 earlycon: uartlite_a0 at MMIO 0x40600000 (options '115200n8') bootconsole [uartlite_a0] enabled setup_cpuinfo: initialising setup_cpuinfo: No PVR support. Using static CPU info from FDT wt_msr pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768 pcpu-alloc: [0] 0 Built 1 zonelists, mobility grouping on. Total pages: 522751 Kernel command line: console=ttyUL0,115200 earlycon Dentry cache hash table entries: 131072 (order: 7, 524288 bytes) Inode-cache hash table entries: 65536 (order: 6, 262144 bytes) Memory: 2059012K/2097148K available (4843K kernel code, 152K rwdata, 1380K rodata, 13129K init, 562K bss, 38136K reserved, 0K cma-reserved, 1310716K highmem) Kernel virtual memory layout: * 0xfffea000..0xfffff000 : fixmap * 0xff800000..0xffc00000 : highmem PTEs * 0xff7ff000..0xff800000 : early ioremap * 0xf0000000..0xff7ff000 : vmalloc & ioremap # ...
© Copyright 2019 - 2022 Xilinx Inc. Privacy Policy