Access ECAM on QEMU AArch64 virt device - arm

I am trying to implement bare metal PCIE device discovery on QEMU AArch64 virt device. I know, that ECAM area is mapped to 0x3f000000 memory address, and I expect to see there this table.
But when I perform a reading of 4 bytes (MCFG signature) from 0x3f000000 address, I get a synchronous exception.
What am I doing wrong? Is there something I have to perform before accessing PCIE memory mapped area?
QEMU_CMD = qemu-system-aarch64 \
-machine virt \
-m 1024M \
-cpu cortex-a53 \
-serial stdio \
-device virtio-gpu-pci \
-vnc :0 \
-netdev user,id=n1 -device virtio-net-pci,netdev=n1

You're looking at the wrong address. The virt board only puts the ECAM at the 0x3f00_0000 address if it is not using the physical address space above-4GB (which is not the default; QEMU only avoids highmem usage if the user passed -machine highmem=off).
You can check this by asking QEMU to dump the dtb instead of running the guest, by adding "-machine dumpdtb=/tmp/dump.dtb" to your commandline, then disassembling the dtb with "dtc -I dtb -O dts /tmp/dump.dtb | less", and looking at the dtb for the pci controller.
More generally, a guest running in the QEMU "virt" board should not hardcode any addresses of devices, but should always read the dtb that QEMU generates and passes to the guest to determine where in the address space devices are placed. If your code did this it wouldn't have run into this error.

Related

QEMU No 'PCI' bus found for device 'nvme'

I'm debuging NVME code with QEMU , QEMU return an err message:No 'PCI' bus found for device 'nvme'.
However,I checked device info,it shows PCI is surportted.
root#linux:/home/#qemu-system-arm -machine vexpress-a9 -device help
Storage devices:
name "am53c974", bus PCI, desc "AMD Am53c974 PCscsi-PCI SCSI adapter"
name "nvme", bus PCI, desc "Non-Volatile Memory Express"
name "nvme-ns", bus nvme-bus, desc "Virtual NVMe namespace"
name "nvme-subsys", desc "Virtual NVMe subsystem"
Could anybody give me some tips?
QEMU command:
root#linux:~/run-kernel/$ qemu-system-arm -nographic -M vexpress-a9 -m 1024M -kernel arch/arm/boot/zImage -append "rdinit=/linuxrc console=ttyAMA0 loglevel=8" -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -device nvme,drive=nvme0,serial=deadbeaf1,num_queues=8 -drive file=disk.qcow2,if=none,id=nvme0
output:
WARNING: Image format was not specified for 'disk.qcow2' and probing guessed raw.
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
Specify the 'raw' format explicitly to remove the restrictions.
qemu-system-arm: -device nvme,drive=nvme0,serial=deadbeaf1,num_queues=8: No 'PCI' bus found for device 'nvme'
QEMU version:
root#linux:/home/# qemu-system-arm -version
QEMU emulator version 6.0.94
Copyright (c) 2003-2021 Fabrice Bellard and the QEMU Project developers
You're trying to use a PCI device (nvme) on a machine type with no PCI bus (vexpress-a9). This doesn't work, in the same way that trying to plug a real hardware PCI card into a machine with no PCI slots is impossible.
You may be being confused by the '-device help' output: that output lists all devices compiled into that QEMU binary, and does not filter it based on any additional '-machine' option you pass at the same time. So it will always show you everything.

How can I check integrity of a extracted zImage?

$ binwalk -e linux_image.img
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 Android bootimg, kernel size: 6897653 bytes, kernel addr: 0x81C08000, ramdisk size: 5959520 bytes, ramdisk addr: 0x81C08000, product name: ""
2048 0x800 Linux kernel ARM boot executable zImage (little-endian)
18479 0x482F gzip compressed data, maximum compression, from Unix, last modified: 1970-01-01 00:00:00 (null date)
6761720 0x672CF8 device tree image (dtb)
6883304 0x6907E8 Unix path: /dev/block/platform/soc/7824900.sdhci/by-name/vendor
6899712 0x694800 gzip compressed data, maximum compression, has original file name: "rootfs.cpio", from Unix, last modified: 2019-04-06 00:42:26
9706949 0x941DC5 MySQL ISAM compressed data file Version 11
$ dd if=linux_image.img of=vmlinuz bs=1 skip=2048 count=6897653
$ file vmlinuz
vmlinuz: Linux kernel ARM boot executable zImage (little-endian)
$ dd if=vmlinuz bs=1 skip=$(LC_ALL=C grep -a -b -o $'\x1f\x8b\x08\x00\x00\x00\x00\x00' vmlinuz-3.18.66-perf | head -n 1 | cut -d ':' -f 1) | zcat | grep -a 'Linux version'
Linux version 3.18.66 (build#test) (gcc version 4.9.3 (GCC) ) #1 SMP PREEMPT Fri Apr 1 13:16:33 PDT 2018
Running 'qemu-system-arm.exe -machine vexpress-a9 -cpu cortex-a7 -smp 4 -kernel vmlinuz' blank screen
If you pull a random Arm Linux kernel (including Android) from somewhere and try to run it on anything other than the hardware that it is intended to boot on, the expected result is that it crashes very early in bootup without being able to output anything to screen or serial port, ie you get a black screen and nothing happens. The most likely situation here is that your image is fine and not corrupt, it's just not built to run on the vexpress-a9 board you're running it on.
In the unlikely event that this really is a kernel built for the vexpress-a9, the next problem you have is that you haven't passed QEMU a device tree blob via the -dtb option. Modern Linux kernels don't hardcode all the information about the boards they can run on, but instead expect the bootloader (which is QEMU in this case) to pass them a data file which provides information about where all the devices are for the board. If you don't do that, then the result is the same as above: kernel crashes very early in bootup without being able to output any information, so black screen.

Problems mounting a ubi image using QEMU

I'm trying to emulate a nand flash with qemu and use that to mount an existent ubifs image on the virtual machine.
I added a nand device and a drive of the type mtd, resulting on the following command:
$ qemu-system-arm -nographic -M virt -m 64 -device nand,chip_id=0x59 -drive if=mtd,format=raw,file=data.ubi -kernel openwrt-armvirt-32-zImage-initramfs
Warning: Orphaned drive without device: id=mtd0,file=data.ubi,if=mtd,bus=0,unit=0
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 4.19.56 (buildbot#builds) (gcc version 7.4.0 (OpenWrt GCC 7.4.0 r10348-577174cf60)) #0 SMP Tue Jun 25 14:46:01 2019
[ 0.000000] CPU: ARMv7 Processor [412fc0f1] revision 1 (ARMv7), cr=30c5387d
[ 0.000000] CPU: div instructions available: patching division code
[ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction cache
[ 0.000000] OF: fdt: Machine model: linux,dummy-virt
[ 0.000000] Memory policy: Data cache writealloc
[ 0.000000] psci: probing for conduit method from DT.
[ 0.000000] psci: PSCIv0.2 detected in firmware.
...
I can't access to the data.ubi probably because of the following warning:
"Warning: Orphaned drive without device"
How can I add the ubi image to the nand device correctly?
You have to link the -drive and -device via an id parameter:
qemu-system-arm \
`: [...]` \
-device nand,chip_id=0x59,id=myubiflash \
-drive if=mtd,format=raw,file=data.ubi,id=myubiflash \
`: [...]`
If you really read the message carefully, you'll notice that the drive id defaults to mtd0:
Warning: Orphaned drive without device: id=mtd0,file=data.ubi,if=mtd,bus=0,unit=0
And of course qemu can't magically guess that you meant to define the -device nand for the drive.
The error message is exactly on the spot here.
Edit
I'll admit, no perfect understanding of the layers of syntax in QEMU commandline on my side either.
Also, the QEMU doc isn't the easiest to read; however it has this passage:
A block driver node created with -blockdev can be used for a guest device by specifying its node name for the drive property in a -device argument that defines a block device.
-blockdev is synonym to -drive in this context.
If I can interpret it right, the meaning of this is that instead of
-device […],id=foo, -drive […],id=foo
you're supposed to use
-device […],drive=foo, -drive […],id=foo
Can't test this ATM, but either of those should make it work for you.

Can I easily compile u-boot with more commands for arm versatile bp

I have compiled u-boot from u-boot-2013.01.y branch for versatilebp board (arm), and I need fatload command that is not present in this configuation.
I'm running u-boot under qemu
DRAM: 128 MiB
WARNING: Caches not enabled
Using default environment
In: serial
Out: serial
Err: serial
Net: SMC91111-0
Warning: SMC91111-0 using MAC address from net device
VersatilePB # fat
Unknown command 'fat' - try 'help'
VersatilePB # help
? - alias for 'help'
base - print or set address offset
bdinfo - print Board Info structure
bootm - boot application image from memory
bootp - boot image via network using BOOTP/TFTP protocol
cmp - memory compare
cp - memory copy
crc32 - checksum calculation
dhcp - boot image via network using DHCP/TFTP protocol
env - environment handling commands
erase - erase FLASH memory
flinfo - print FLASH memory information
go - start application at address 'addr'
help - print command description/usage
iminfo - print header information for application image
loop - infinite loop on address range
md - memory display
mm - memory modify (auto-incrementing address)
mtest - simple RAM read/write test
mw - memory write (fill)
nm - memory modify (constant address)
ping - send ICMP ECHO_REQUEST to network host
printenv- print environment variables
protect - enable or disable FLASH write protection
reset - Perform RESET of the CPU
setenv - set environment variables
tftpboot- boot image via network using TFTP protocol
version - print monitor, compiler and linker version
VersatilePB #
I need fatload to load file containing image of fat filesystem containing kernel of freebsd. Can I somehow change compile config for that board to compile u-boot with fatload command? Or it's just not possible/not supported for that board?
Having done more or less exactly this for a Versatile AB, it's most certainly possible. The simplest way is to find where that board's command set is defined, and hack in the commands you want by defining the relevant CONFIG_CMD_* symbols. In this case, that place is include/configs/versatile.h.
Looking at my checkout of 2015.07, I seem to have added, among others (I think I was trying to convince the MMC to work at the time), these lines:
#define CONFIG_CMD_FAT
#define CONFIG_DOS_PARTITION 1

Running qemu on ARM with KVM acceleration

I'm trying to emulate an ARM VM on an ARM host, a cubieboard2 embedded board, by means of qemu. I've compiled qemu from the source code and enabled kvm. Now the problem is that launching qemu-system-arm as follows:
$ /usr/local/bin/qemu-system-arm -M accel=kvm -cpu host -kernel vmlinuz-3.2.0-4-vexpress -initrd initrd.img-3.2.0-4-vexpress -sd debian_wheezy-_armhf_standard.qcow2 -append "console=ttyAMA0 root=/dev/mmcblk0p2" -nographic
I have this error:
qemu-system-arm: -M accel=kvm: Unsupported machine type
Use -machine help to list supported machines!
What is wrong in the command I've typed. How to enable kvm?
How about reading this:
https://groups.google.com/forum/#!topic/cubieboard/4EGONZMoIAU
And yes, you are right, as the Cubieboard2 has A15, HYP hypervisor is implemented and KVM should be running in it.
More about HYP mode is covered here:
http://lwn.net/Articles/557132/
there is another way you can see the failing mode (why qemu command failed): execute your command under "strace", and you will be able to clearly see when /dev/kvm is opened, and if it succeed, non-zero fd will be returned after open("/dev/kvm") is called. and before all this - "lsmod" should return a line indicating "kvm.ko" kernel module is running, and if you can read your kernel's config file, there should be a "CONFIG_KVM" embedded within.
-M takes a machine name (eg "vexpress-a15" or "virt"), not a set of suboption=value settings. You want -machine suboption=value,... for that.
("-M name" is a shortcut for "-machine type=name".)
You also need to specify a machine name, either via -machine type=name or -M name, otherwise QEMU will complain that you didn't specify one.

Resources