Qemu showing as black screen for ARM (VM) - linux

So I'm using this site to setup Qemu on my Lubuntu VM.
https://azeria-labs.com/emulate-raspberry-pi-with-qemu/
My errors happen when im trying to run the Qemu but the screen appears as black and it says "Guest has not initialized the display (yet)."
Looking at the error it says:
Error: invalid dtb and unrecognized/unsupported machine ID
r1=0x00000183 r2=0x00000100
r2[]=05 00 00 00 01 00 41 54 01 00 00 00 00 10 00 00
Available machine support:
ID (hex) NAME
ffffffff Generic DT based system
ffffffff ARM-Versatile (Device Tree Support)
Please check your kernel config and/or bootloader.
As you can see I used the latest kernel and raspberry image (Buster), so I'm not exactly sure if that's contributing to the error, because the source im using is pretty outdated.
$ qemu-system-arm -kernel ~/qemu_vms/kernel-qemu4.19.50-buster -cpu arm1176 -m 256 -M versatilepb -serial stdio -append "root=/dev/sda2 rootfstype=ext4 rw" -hda ~/qemu_vms/2019-09-26-raspbian-buster.img
I couldn't do the redir part from the online example because for some reason it kept saying -redir: invalid option
Here is the visual output that it's giving me:
https://ibb.co/xDmj7D7
https://ibb.co/9YrmD2M
If anyone can tell me what I did wrong, the output should be something similar to the source im using thanks! :
https://azeria-labs.com/emulate-raspberry-pi-with-qemu/
EDIT: Alright i've made some progress since the last time.
So i forgot to include the dtb because buster needs this as well.
-dtb /.../versatile-pb.dtb \
https://github.com/dhruvvyas90/qemu-rpi-kernel
Used the command format from there, but i encountered that my file was raw so i did a drive command to format=raw
Then another error popped up:
vpb_sic_write: Bad register offset 0x2c
Solved with adding: -serial stdio
source: https://github.com/dhruvvyas90/qemu-rpi-kernel/issues/75
It looks like im in the raspberry, but my Qemu still has a black screen saying: Guest has not initialized the display (yet)

I had the same situation as described above with Raspbian Buster image and kernel. But when I switched to 2019-04-08-raspbian-stretch-full.img and kernel-qemu-4.14.79-stretch without any other changes, then I was able to get graphics (I mean mouse cursor, desktop, etc.) in QEMU. Looks like versatile-pb.dtb has to be corrected for Raspbian Buster.
Raspbian Stretch in QEMU

I use the buster img and with the parameter -dtb versatile-pb-buster.dtb(you can download it from https://github.com/dhruvvyas90/qemu-rpi-kernel), then it works.

Related

Qemu booting raw kernel image (not ELF)

is there a way to convince qemu (qemu-system-mipsel v4.1.0, if it matters) to load a binary (non-elf) image built for (ancient) u-boot?
I tried both my uImage and vmlinux.bin, but I always get "The image is not ELF"
Full command-line is:
qemu-system-mipsel -M malta -kernel output/images/vmlinux.bin -serial stdio -drive file=output/images/rootfs.ext2,format=raw -append "rootwait root=/dev/hda" -net nic,model=pcnet -net user
Error is:
qemu-system-mipsel: could not load kernel 'output/images/vmlinux.bin': The image is not ELF
... which is absolutely true! That image (its uImage counter-part, actually) works fine on a real target (very similar to Malta, but that's beyond point; a failing kernel would be a completely different problem) using (in u-boot) something like:
usb reset; fatload usb 0 85000000 uImage; fatload usb 0 86000000 initram.cpio.xz; setenv bootargs rd_start=0x86000000 rd_size=15000000 USE=usb; bootm 85000000
As said: my problem is qemu doesn't even try to load the image, not that it fails at run-time.
What is the right spell to use?
You may have to use the -bios flag to provide the U-boot image and then set up the environment yourself to do the hand-off to the kernel. From my understanding, QEMU requires ELF-formatted images to be provided to the -kernel flag, presumably (heavy emphasis on this word) because the data contained in the ELF headers is necessary to configure the environment in lieu of a true bootloader (since you're effectively bypassing that boot stage and jumping straight to kernel execution). -bios does not have these requirements, as you're probably not going to see a first-stage binary using ELF headers.
If you know the entry point to the kernel image, which it seems like you do based off of that uboot command, you could use the -bios flag in conjunction with the -device loader,addr=[entry point],cpu-num=0. However, if there's any MMU, TLB, or other arch-specific addressing going on in your hardware, you might run into problems with that.
Take all of this with a dose of a skepticism, as I'm only working off of knowledge I've acquired by doing something similar to you. There may be a better way of doing it.
You have to build U-Boot for QEMU MIPS and pass it as kernel to qemu-system-mips.
You can use QEMU tftp parameter to make the directory holding the uImage available to U-Boot.
Use U-Boot's tftp command to load the kernel image and the bootm command to start the kernel.

QEMU Showing Black Screen Only

I compiled my custom kernel with different configs and images like u,zImages. But when I try to run qemu with my image, qemu showing only black screen.
Also I looked at this post but it didn't help me.
EDIT
I just tried to compile kernel with these commands.
make ARCH=arm distclean
make ARCH=arm integrator_defconfig
make ARCH=arm menuconfig
NOTE: I used default menuconfig.
make ARCH=arm CROSS_COMPILE=arm-none-eabi- zImage
qemu-system-arm -M integratorcp -kernel arch/arm/boot/zImage
And last i tried this command;
qemu-system-arm -M integratorcp -kernel arch/arm/boot/zImage -append 'console=ttyAMA0 earlyprintk=ttyAMA0' -serial stdio
NOTE: when i try to use -dtb, qemu giving to me "Unable to copy device tree in memory." error.
"QEMU does nothing with a black screen" almost always means "QEMU is running fine, but the guest code crashed or stopped early in the boot process without sending any output". Almost certainly either your kernel is misconfigured, or your QEMU command line is wrong. You don't give enough information to say which. You need to tell us at least:
what the kernel is you're running and what machine you've configured it for
what the QEMU command line you're using is
Given your updated question with a command line, some suggestions:
tell your guest to use the serial port (use the QEMU option -append 'console=ttyAMA0' to set the guest kernel command line)
either check the serial output view in the GUI, or send it to stdout with -nographic or -serial stdio
enable any earlyprintk or earlycon options in the guest config that you can and on the guest command line, so if the guest fails early you have more chance to catch it
pass the device tree for the kernel with -dtb integratorcp.dtb (use the one from your kernel tree; you'll probably have to tell the kernel makefiles to build it for you)
PS: integratorcp is an absolutely ancient development board -- why do you want to use it?

How to compile and install a 32Bit library on a 64 Bit (Ubuntu 12.04LTS) Linux using autotools, make and gcc?

I'm trying to compile a 32Bit version of a linux library on a 64Bit Ubuntu 12.04LTS running inside a VM (VirtualBox).
So far I've downloaded the source, unzipped it and performed the following steps to build the lib:
libtoolize --force
automake --add-missing
./configure --build=i686-pc-linux-gnu "CFLAGS=-m32" "CXXFLAGS=-m32" "LDFLAGS=-m32"
make
sudo make install
With this I've been able to build an compile the library but, once I run "readelf -h" on the compiled lib I get the following output:
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x1ac0
Start of program headers: 64 (bytes into file)
Start of section headers: 53904 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 7
Size of section headers: 64 (bytes)
Number of section headers: 35
Section header string table index: 32
So I'm stuck with a 64Bit Version of the library and have not yet found a way to force the build and installation of a 32Bit Version. I'd be grateful for hints on how to solve this problem.
You only set --build in your options for ./configure. That means that ./configure should behave as if the program is being compiled on a 32-bit computer. If you want it to run on a 32-bit computer as well, you should use --host=i386-linux-gnu. So the real configure command you want to run is:
./configure --build=i386-linux-gnu --host=i386-linux-gnu

linux application get Killed

I have a "Seagate Central" NAS with an embedded linux on it
$ cat /etc/*release
MontaVista Linux 6, (.dev-snapshot-20130726)
When I try to run my own application on this NAS, it will be "Killed"
without any notifications on dmesg or /var/log/messages
$ cat /proc/cpuinfo
Processor : ARMv6-compatible processor rev 4 (v6l)
BogoMIPS : 279.34
Features : swp half thumb fastmult vfp edsp java
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xb02
CPU revision : 4
Hardware : Cavium Networks CNS3420 Validation Board
Revision : 0000
Serial : 0000000000000000
My toolchain is
Sourcery_CodeBench_Lite_for_ARM_GNU_Linux/arm-none-linux-gnueabi
and my compile switches are
-march=armv6k -mcpu=mpcore -mfloat-abi=softfp -mfpu=vfp
How can I find out which process is killing my application, or what setting I have to change?
PS: I have created a simple HelloWorld application which is also not working !
$ ldd Hello
$ not a dynamic executable
readelf -a Hello
=> http://pastebin.com/kT9FvkjE
readelf -a zip
=> http://pastebin.com/3V6kqA9b
UPDATE 1
I have comiled a new binary with hard float
Readelf output
http://pastebin.com/a87bKksY
But no success ;(
I guess it is really a "lock" topic, which is blocking my application to execute. How can I find out what application kills mine ?
Or how can I disable such kind of function ?
Use these compiler switches:
-march=armv6k -Wl,-z,max-page-size=0x10000,-z,common-page-size=0x10000,-Ttext-segment=0x10000
See also this link regarding the toolchain.
You can run readelf -a against one of the built-in binaries (e.g. /usr/bin/nano) to see the proper text-segment offset in the section headers and page size / alignment in the program headers. The above compiler flags make self-compiled programs match the structure of built in binaries, and have been tested to work. It seems the Seagate Central NAS uses a page size / offset of 0x10000 while the default for ARM gcc is 0x8000.
Edit: I see you ran readelf already. Your pastebin shows
HelloWorld:[ 1] .interp PROGBITS 00008134 000134 000013 00 A 0 0 1
zip:[ 1] .interp PROGBITS 00010134 000134 000013 00 A 0 0 1
The value 10134-134=10000 (hex) yields the correct text-segment linker option. Further down (LOAD...) are the alignment specifiers, which are 0x8000 for your HelloWorld, but 0x10000 for the zip built-in. In my experience, soft-float has not caused problems.
Do you see any output at all?
Is your application dynamically linked?
If so, run the dynamic linker with the verbose option (you'll have to figure out the name of the dynamic linker on your platform, for Arch linux, it is ldd):
ldd --verbose 'your_program_name'
That will tell you if you're missing any dependencies (shared libs etc)
Run readelf -a 'your_program_name'
Make sure the file mentioned in Requesting program interpreter: /lib/ld-linux.so.2 exists. In this case, that filename is /lib/ld-linux.so.2
If this fails to help you figure out the problem, post the complete output of ldd --verbose 'your_program_name' and readelf -a 'your_program_name' in your question.
Another issue may be that the NAS software just kills foreign programs. I'm not sure why it would, but we're talking about a big corporation here (Seagate) and they have odd ideas of how the world works at times...
Edit, after looking at the pastebin of readelf:
From what I see, your Hello executable differs in 2 ways from the zip executable:
It is not dynamically linked, so that throws out a whole load of problems to look for.
There's a difference in how the 2 programs are built. zip does not use softfloats and Hello does. I suspect the soft-float dependency is due to one or both of these compiler switches: -mfloat-abi=softfp -mfpu=vfp
Hello Flags: 0x5000202, has entry point, Version5 EABI, soft-float ABI
zip Flags: 0x5000002, has entry point, Version5 EABI
I'd start with either:
Removing the soft-float option from the Hello build or:
make sure the soft-float emulation libraries are on the machine. I don't know what libs this would depend on, but I do remember MontaVista supplying them the last time I touched their software. It's been 8+ years since I touched MontaVista so it's clouded in a bit of old-memory fog.
This is an old thread, but I just wanted to add that I succeeded in compiling a "hello world" for this old NAS today.
Running ld-linux.so.3 <app> told me that
ELF load command alignment not page-aligned
Googling this, I found this: https://github.com/JuliaLang/julia/issues/33293, which pointed me to linker-options:
-Wl,-z,max-page-size=0x10000
Compiling with these options yielded en ELF that actually did work!
Are you sure your compilation options are correct ?
Try the following :
strace your application (if strace is present on the NAS)
downloas one of the NAS binary and run arm-none-linux-gnueabi-readelf -a on it, do the same on your helloworld program and see if the abi tag differ.
It looks like an illegal instruction issue, a floating point issue or an incompatible libc issue.
Edit : according to readelf output, nas program are compiled without soft float, you should try that.

Determine target ISA extensions of binary file in Linux (library or executable)

We have an issue related to a Java application running under a (rather old) FC3 on an Advantech POS board with a Via C3 processor. The java application has several compiled shared libs that are accessed via JNI.
Via C3 processor is supposed to be i686 compatible. Some time ago after installing Ubuntu 6.10 on a MiniItx board with the same processor, I found out that the previous statement is not 100% true. The Ubuntu kernel hanged on startup due to the lack of some specific and optional instructions of the i686 set in the C3 processor. These instructions missing in C3 implementation of i686 set are used by default by GCC compiler when using i686 optimizations. The solution, in this case, was to go with an i386 compiled version of Ubuntu distribution.
The base problem with the Java application is that the FC3 distribution was installed on the HD by cloning from an image of the HD of another PC, this time an Intel P4. Afterwards, the distribution needed some hacking to have it running such as replacing some packages (such as the kernel one) with the i386 compiled version.
The problem is that after working for a while the system completely hangs without a trace. I am afraid that some i686 code is left somewhere in the system and could be executed randomly at any time (for example after recovering from suspend mode or something like that).
My question is:
Is there any tool or way to find out at what specific architecture extensions a binary file (executable or library) requires? file does not give enough information.
The unix.linux file command is great for this. It can generally detect the target architecture and operating system for a given binary (and has been maintained on and off since 1973. wow!)
Of course, if you're not running under unix/linux - you're a bit stuck. I'm currently trying to find a java based port that I can call at runtime.. but no such luck.
The unix file command gives information like this:
hex: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.4.17, not stripped
More detailed information about the details of the architecture are hinted at with the (unix) objdump -f <fileName> command which returns:
architecture: arm, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x0000876c
This executable was compiled by a gcc cross compiler (compiled on an i86 machine for the ARM processor as a target)
I decide to add one more solution for any, who got here: personally in my case the information provided by the file and objdump wasn't enough, and the grep isn't much of a help -- I resolve my case through the readelf -a -W.
Note, that this gives you pretty much info. The arch related information resides in the very beginning and the very end. Here's an example:
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: ARM
Version: 0x1
Entry point address: 0x83f8
Start of program headers: 52 (bytes into file)
Start of section headers: 2388 (bytes into file)
Flags: 0x5000202, has entry point, Version5 EABI, soft-float ABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 8
Size of section headers: 40 (bytes)
Number of section headers: 31
Section header string table index: 28
...
Displaying notes found at file offset 0x00000148 with length 0x00000020:
Owner Data size Description
GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)
OS: Linux, ABI: 2.6.16
Attribute Section: aeabi
File Attributes
Tag_CPU_name: "7-A"
Tag_CPU_arch: v7
Tag_CPU_arch_profile: Application
Tag_ARM_ISA_use: Yes
Tag_THUMB_ISA_use: Thumb-2
Tag_FP_arch: VFPv3
Tag_Advanced_SIMD_arch: NEONv1
Tag_ABI_PCS_wchar_t: 4
Tag_ABI_FP_rounding: Needed
Tag_ABI_FP_denormal: Needed
Tag_ABI_FP_exceptions: Needed
Tag_ABI_FP_number_model: IEEE 754
Tag_ABI_align_needed: 8-byte
Tag_ABI_align_preserved: 8-byte, except leaf SP
Tag_ABI_enum_size: int
Tag_ABI_HardFP_use: SP and DP
Tag_CPU_unaligned_access: v6
I think you need a tool that checks every instruction, to determine exactly which set it belongs to. Is there even an offical name for the specific set of instructions implemented by the C3 processor? If not, it's even hairier.
A quick'n'dirty variant might be to do a raw search in the file, if you can determine the bit pattern of the disallowed instructions. Just test for them directly, could be done by a simple objdump | grep chain, for instance.
To answer the ambiguity of whether a Via C3 is a i686 class processor: It's not, it's an i586 class processor.
Cyrix never produced a true 686 class processor, despite their marketing claims with the 6x86MX and MII parts. Among other missing instructions, two important ones they didn't have were CMPXCHG8b and CPUID, which were required to run Windows XP and beyond.
National Semiconductor, AMD and VIA have all produced CPU designs based on the Cyrix 5x86/6x86 core (NxP MediaGX, AMD Geode, VIA C3/C7, VIA Corefusion, etc.) which have resulted in oddball designs where you have a 586 class processor with SSE1/2/3 instruction sets.
My recommendation if you come across any of the CPUs listed above and it's not for a vintage computer project (ie. Windows 98SE and prior) then run screaming away from it. You'll be stuck on slow i386/486 Linux or have to recompile all of your software with Cyrix specific optimizations.
Expanding upon #Hi-Angel's answer I found an easy way to check the bit width of a static library:
readelf -a -W libsomefile.a | grep Class: | sort | uniq
Where libsomefile.a is my static library. Should work for other ELF files as well.
Quickest thing to find architecture would be to execute:
objdump -f testFile | grep architecture
This works even for binary.

Resources