Launch QNX on QEMU emulating Cortex-A15

1.5k views Asked by At

I have IFS images supposed to run on board similar to OMAP5 uEVM. I am trying to run it on a QEMU virtual machine with the same Cortex-A15 CPU.

I have a bundle of questions, but first of all I would like to ask is it eminently doable?

TLDR

I decided to use U-Boot as a bootloader. I compiled it with arm-linux-gnueabi-gcc, arm-linux-gnueabihf-gcc from Ubuntu and arm-eabi-gcc-7.5 from linaro. All 3 U-Boot versions work. It looks like QNX binaries don't use hard float (armhf or armle-v7) even if target CPU support it. Is the gcc version important? Do I have to use one from the QNX toolchain to build U-Boot?

The image must be based on QNX 6.5. ifsdump gives me

Decompressed 3333189 bytes-> 9535664 bytes
   Offset     Size  Name
        0        8  *.boot
        8      100  Startup-header flags1=0xd flags2=0 paddr_bias=0x7fce00000000
                       preboot_size=0x8
                       image_paddr=0x80100008 stored_size=0x347e78
                       startup_size=0x1a108 imagefs_size=0x9180b0
                       ram_paddr=0x80100008 ram_size=0x9321b8
                       startup_vaddr=0x8010097c
      108    1a008  startup.*
    1a110       5c  Image-header mountpoint=/
                       flags=0x4 script=3 boot=3758096386 mntflg=0
    1a16c     15b4  Image-directory
     ----     ----  Root-dirent
                       gid=0 uid=0 mode=0755 ino=1 mtime=606f22bf
    1c000    94000  proc/boot/procnto-smp-instr
                       gid=0 uid=0 mode=0777 ino=3758096386 mtime=606f1eb4
----- procnto-smp-instr - ELF32LE ET_EXEC EM_ARM -----
 e_flags              : 0x5000002
 e_entry              : 0xfe051c60
 e_phoff              : 52
 e_phentsize          : 32
 e_phnum              : 4
 segment 0
   p_type               : Unknown(1879048193)
   p_offset             : 566704
   p_vaddr              : 0xFE0A65B0
   p_paddr              : 0xFE0A65B0
   p_filesz             : 32
   p_memsz              : 32
   p_flags              : R--
   p_align              : 4
 segment 1
   p_type               : PT_LOAD
   p_offset             : 4096
   p_vaddr              : 0xFE01D000
   p_paddr              : 0x8011D000
   p_filesz             : 550320
   p_memsz              : 550320
   p_flags              : R-X
   p_align              : 4096
 segment 2
   p_type               : PT_LOAD
   p_offset             : 557056
   p_vaddr              : 0xFE0A4000
   p_paddr              : 0x801A4000
   p_filesz             : 46584
   p_memsz              : 46584
   p_flags              : RW-
   p_align              : 4096
 segment 3
   p_type               : PT_NULL
   p_offset             : 0
   p_vaddr              : 0x0
   p_paddr              : 0x0
   p_filesz             : 0
   p_memsz              : 0
   p_flags              : ---
   p_align              : 4

I extracted the image with dumpifs -u QNX-IFS.raw QNX-IFS and copied it to a virtual drive.

My RAM space starts at 0x40000000 (virt-6.0 machine) but the target board at 0x80100000. So I adjusted original startup_vaddr=0x8010097c and executed

fatload virtio 0:1 0x40400000 QNX-IFS.raw
go 0x4040097c

It hangs forever. Startup-header and startup.* seems to be hardware specific, doesn’t it? But it’s goal is to run /proc/boot/procnto-smp-instr and startup scripts.

Next I tried to launch a kernel using bootelf. It crashes with:

=> bootelf 0x4041c000
## Starting application at 0xfe051c60 ...
prefetch abort
pc : [<fe051c5c>]          lr : [<bff598e0>]
reloc pc : [<3e0fbc5c>]    lr : [<000038e0>]

Prefetch abort means that it references memory out of range. This magic address comes from the elf header. It implies that it reads the elf-header correctly and tries to launch it.

readelf -a proc/boot/procnto-smp-instr
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:               0xfe051c60
  Start of program headers:          52 (bytes into file)
  Start of section headers:          0 (bytes into file)
  Flags:                             0x5000002, Version5 EABI, <unknown>
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         4
  Size of section headers:           0 (bytes)
  Number of section headers:         0
  Section header string table index: 0

There are no sections in this file.

There are no sections to group in this file.

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  EXIDX          0x08a5b0 0xfe0a65b0 0xfe0a65b0 0x00020 0x00020 R   0x4
  LOAD           0x001000 0xfe01d000 0x8011d000 0x865b0 0x865b0 R E 0x1000
  LOAD           0x088000 0xfe0a4000 0x801a4000 0x0b5f8 0x0b5f8 RW  0x1000
  NULL           0x000000 0x00000000 0x00000000 0x00000 0x00000     0x4

Both boards have the same 2Gb of RAM but different virtual memory address space. I decided to extend my board memory to 3Gb that makes the entry point address in range. Then I tried to launch a kernel again. It crashes again with new error:

=> bootelf 0x4041c000
## Starting application at 0xfe051c60 ...
undefined instruction
pc : [<fee13c18>]          lr : [<fff598e0>]
reloc pc : [<feebdc18>]    lr : [<000038e0>]
sp : fee14d40  ip : 00000030     fp : 00000028
r10: 00000000  r9 : fef15ed8     r8 : 00000000
r7 : fef30620  r6 : 00000000     r5 : 00000000  r4 : 4041c000
r3 : fe051c60  r2 : 00000001     r1 : fef30620  r0 : 00000000
Flags: nZCv  IRQs off  FIQs off  Mode SVC_32
Code: 00000000 00000000 00000000 00000000 (fee140cf)
Resetting CPU ...

On one hand /proc/boot/procnto-smp-instr is elf-executable for Cortex-A15, on the other hand kernel is not a regular executable. Header implies that it is hardware specific.

Is there any chase to run it?

Also I found a package with kernel for Cortex-A15 on community qnx web site. It contains four versions of procnto*. But they are relocatable object files for armle-v7. Is it possible to link it to make it executable?

I am really not experienced in arm development neither QNX. I would really appreciate any thought or advice.

1

There are 1 answers

0
Peter Maydell On BEST ANSWER

Your main problem here is that Arm boards are generally pretty different from each other, and so bootloaders and OS kernels typically have to be built with support for whatever board they are going to run on. (This is very different from the x86 world, where basically every machine looks more-or-less like a standard PC and software is all built to run on that.)

So the short answer is that unless the QNX images you have were built to be pretty generic "run on a lot of different things, and take a device tree file to tell them about the hardware"[*], then they are only going to run on QEMU if QEMU has a model of the hardware that the QNX image is expecting. There is no QEMU model of OMAP5.

[*] You can build Linux like this. You can also build Linux to be very specifically targeted to a given board, with no extra device driver support for anything else. I don't know what QNX lets you do.