Запустите QNX на QEMU, эмулирующем Cortex-A15

У меня есть изображения IFS, которые должны работать на борту, аналогично OMAP5 uEVM. Я пытаюсь запустить его на виртуальной машине QEMU с тем же процессором Cortex-A15.

У меня куча вопросов, но прежде всего я хотел бы спросить, насколько это реально?

TL; DR

Решил использовать в качестве загрузчика U-Boot. Я скомпилировал его с помощью arm-linux-gnueabi-gcc, arm-linux-gnueabihf-gcc из Ubuntu и arm-eabi-gcc-7.5 из linaro. Все 3 версии U-Boot работают. Похоже, двоичные файлы QNX не используют жесткое плавание (armhf или armle-v7), даже если целевой ЦП поддерживает его. Версия gcc важна? Должен ли я использовать один из инструментов QNX для создания U-Boot?

Образ должен быть основан на QNX 6.5. ifsdump дает мне

      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

Я извлек изображение с помощью и скопировал на виртуальный диск.

Мое пространство RAM начинается с 0x40000000 (машина virt-6.0), а целевая плата - с 0x80100000. Итак, я настроил оригинал и выполнен

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

Он висит вечно. Startup-header и startup. * Кажутся аппаратными, не так ли? Но его цель - запустить / proc / boot / procnto-smp-instr и сценарии запуска.

Затем я попытался запустить ядро ​​с помощью bootelf. Вылетает с:

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

Прерывание предварительной выборки означает, что он обращается к памяти вне допустимого диапазона. Этот магический адрес берется из заголовка elf. Это означает, что он правильно читает elf-header и пытается его запустить.

      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

Обе платы имеют одинаковые 2 ГБ ОЗУ, но разное адресное пространство виртуальной памяти. Я решил расширить память моей платы до 3 Гбайт, чтобы адрес точки входа попал в диапазон. Затем я снова попытался запустить ядро. Он снова вылетает с новой ошибкой:

      => 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 ...

С одной стороны, / proc / boot / procnto-smp-instr является исполняемым файлом elf для Cortex-A15, с другой стороны, ядро ​​не является обычным исполняемым файлом. Заголовок подразумевает, что он зависит от оборудования.

Есть ли погоня за этим?

Также я нашел пакет с ядром для Cortex-A15 на сайте сообщества qnx. Он содержит четыре версии procnto *. Но это перемещаемые объектные файлы для armle-v7. Можно ли связать его, чтобы сделать его исполняемым?

Я действительно не имею опыта разработки оружия и QNX. Буду очень признателен за любую мысль или совет.

1 ответ

Основная проблема здесь в том, что платы Arm обычно сильно отличаются друг от друга, поэтому загрузчики и ядра ОС обычно должны быть построены с поддержкой той платы, на которой они собираются работать. (Это сильно отличается от мира x86, где в основном каждая машина выглядит более или менее как стандартный ПК, и все программное обеспечение построено для работы на нем.)

Итак, краткий ответ заключается в том, что если образы QNX, которые у вас есть, не были созданы так, чтобы быть довольно универсальными, «работать с множеством разных вещей и брать файл дерева устройств, чтобы сообщить им об оборудовании» [*], тогда они будут только запускать в QEMU, если QEMU имеет модель оборудования, которую ожидает образ QNX. Нет модели QEMU OMAP5.

[*] Вы можете собрать Linux вот так. Вы также можете собрать Linux так, чтобы он был очень ориентирован на конкретную плату, без дополнительной поддержки драйверов устройств для чего-либо еще. Я не знаю, что QNX позволяет вам делать.

Другие вопросы по тегам