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

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.

Related

Access ECAM on QEMU AArch64 virt device

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.

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.

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.

Can't boot basic OpenEmbedded-Core on Freescale i.MX28

I've been trying to build and boot OpenEmbedded-Core on the evaluation kit for Freescale's ARM i.MX28, using the Freescale ARM layer for OpenEmbedded-Core. Unfortunately, I can't find a basic "Getting Started" guide (though there is a Yocto getting-started guide). Unfortunately, I haven't been able to "get started", to the point of successfully booting to a basic command prompt on the board's debug serial port.
Here is what I've been able to piece together, and as far as I've managed to get so far.
Fetch sources
mkdir -p oe-core/freescale-arm
cd oe-core/freescale-arm
git clone git://git.openembedded.org/openembedded-core oe-core
git clone git://github.com/Freescale/meta-fsl-arm.git
cd oe-core
git clone git://git.openembedded.org/meta-openembedded
git clone git://git.openembedded.org/bitbake bitbake
Set up environment
. ./oe-init-build-env
That puts us in a new sub-directory build and sets certain environment variables.
Edit configuration
Edit the conf/bblayers.conf and local.conf files:
conf/bblayers.conf should have the meta-fls-arm and meta-oe layers added for BBLAYERS. E.g.:
BBLAYERS ?= " \
/home/craigm/oe-core/freescale-arm/oe-core/meta \
/home/craigm/oe-core/freescale-arm/oe-core/meta-openembedded/meta-oe \
${TOPDIR}/../../meta-fsl-arm \
"
In conf/local.conf, I set:
BB_NUMBER_THREADS = "4"
PARALLEL_MAKE = "-j 4"
MACHINE = "imx28evk"
Build
bitbake core-image-minimal
I ran this build overnight, and it has completed successfully for me. Output files were in ~/oe-core/freescale-arm/oe-core/build/tmp-eglibc/deploy/images.
There are two boot options that I'd like to try, as described below. Boot from SD card is simpler, but takes quite a long time (~30 min) to write the image to the SD card. Booting from TFTP + NFS is faster, but requires more set-up.
Boot from SD Card
Write image to SD card:
sudo dd if=tmp-eglibc/deploy/images/core-image-minimal-imx28evk.sdcard of=/dev/sdc
It took something like 30 minutes (3.5 GB file). Then I put it in the board's SD card slot 0, and powered-up. It got as far as loading the kernel, then stopped:
U-Boot 2012.04.01-00059-g4e6e824 (Aug 23 2012 - 18:08:54)
Freescale i.MX28 family at 454 MHz
BOOT: SSP SD/MMC #0, 3V3
DRAM: 128 MiB
MMC: MXS MMC: 0
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Net: FEC0, FEC1
Hit any key to stop autoboot: 0
reading boot.scr
** Unable to read "boot.scr" from mmc 0:2 **
reading uImage
2598200 bytes read
Booting from mmc ...
## Booting kernel from Legacy Image at 42000000 ...
Image Name: Linux-2.6.35.3-11.09.01+yocto-20
Created: 2012-08-23 7:53:40 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2598136 Bytes = 2.5 MiB
Load Address: 40008000
Entry Point: 40008000
Verifying Checksum ... OK
Loading Kernel Image ... OK
OK
Starting kernel ...
Uncompressing Linux... done, booting the kernel.
Boot from TFTP + NFS
First, I tried to write U-Boot onto an SD card:
sudo dd if=tmp-eglibc/deploy/images/u-boot-imx28evk.mxsboot-sdcard of=/dev/sdc
Then I put it in the board's SD card slot 0, and powered-up. But all I got in the debug serial port was:
0x8020a01d
So, I decided to use Freescale's distribution of U-Boot for i.MX28 (from their LTIB distribution) onto an SD card. I set suitable U-Boot parameters for NFS booting with parameters from DHCP.
setenv bootargs console=ttyAMA0,115200n8
setenv bootargs_nfs setenv bootargs ${bootargs} root=/dev/nfs ip=dhcp nfsroot=,v3,tcp fec_mac=${ethaddr}
saveenv
I connected to a DD-WRT router with the following DNSmasq settings:
dhcp-boot=,,192.168.250.106
dhcp-option=17,"192.168.250.106:/home/craigm/rootfs"
On my host PC, I set up a TFTP server to serve the uImage file from ~/oe-core/freescale-arm/oe-core/build/tmp-eglibc/deploy/images/.
I also set up a root NFS server to serve the root file system. I edited /etc/exports to serve /home/craigm/rootfs. I extracted the root file system:
bitbake meta-ide-support
rm -Rf ~/rootfs
runqemu-extract-sdk tmp-eglibc/deploy/images/core-image-minimal-imx28evk.tar.bz2 ~/rootfs
Then I put the U-Boot SD card in the board's SD card slot 0, and powered-up. It got as far as this, then stopped:
...
TCP cubic registered
NET: Registered protocol family 17
can: controller area network core (rev 20090105 abi 8)
NET: Registered protocol family 29
can: raw protocol (rev 20090105)
mxs-rtc mxs-rtc.0: setting system clock to 1970-01-01 00:03:33 UTC (213)
eth0: Freescale FEC PHY driver [Generic PHY] (mii_bus:phy_addr=0:00, irq=-1)
eth1: Freescale FEC PHY driver [Generic PHY] (mii_bus:phy_addr=0:01, irq=-1)
Sending DHCP requests .
PHY: 0:00 - Link is Up - 100/Full
., OK
IP-Config: Got DHCP answer from 192.168.250.106, my address is 192.168.250.142
IP-Config: Complete:
device=eth0, addr=192.168.250.142, mask=255.255.255.0, gw=192.168.250.1,
host=192.168.250.142, domain=, nis-domain=(none),
bootserver=192.168.250.106, rootserver=192.168.250.106, rootpath=/home/craigm/rootfs
Looking up port of RPC 100003/3 on 192.168.250.106
Looking up port of RPC 100005/3 on 192.168.250.106
VFS: Mounted root (nfs filesystem) on device 0:15.
Freeing init memory: 160K
I'm not sure if it's running without a serial console, or some other problem. I can ping it on 192.168.250.142, but I can't Telnet or SSH to it.
Questions
Is there any sort of "getting started" guide for OpenEmbedded-Core on Freescale's i.MX28?
Is the Freescale ARM layer really intended for use with OpenEmbedded-Core, Yocto, or what? I don't really understand how those projects relate.
Has anyone else had success booting a minimal image of OpenEmbedded-Core on Freescale's i.MX28? If so, how did your procedure differ from mine?
I'm not sure at this stage whether the problem is just a non-functional serial console, or some other sort of issue. It's hard to diagnose these problems that prevent even getting a basic system running. Any pointers on how to diagnose at this point?
Why would the U-Boot be broken so it can't even boot?
From the boot message it looks like U-boot is working fine. U-boot is not broken.
The following boot message
2598200 bytes read
Booting from mmc ...
## Booting kernel from Legacy Image at 42000000 ...
Image Name: Linux-2.6.35.3-11.09.01+yocto-20
Created: 2012-08-23 7:53:40 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2598136 Bytes = 2.5 MiB
Load Address: 40008000
Entry Point: 40008000
Verifying Checksum ... OK
Loading Kernel Image ... OK
OK
Starting kernel ...
Uncompressing Linux... done, booting the kernel.
By the above log u-boot has done its job.
"Booting the kernel" is the point where bootloader given the control to the kernel.
I guess the problem might be in kernel image or in memory.
To eliminate the problem of memory, try to check the manual and try to read and write in the RAM using the board's reference manual.
From the boot log RAM looks like has no problem. It has been initialized.
DRAM: 128 MiB
Check if the following message is not causing any problem.
* Warning - bad CRC, using default environment
Check if all the devices have been initialized and nothing is skipped after the bad crc warning.

Resources