在模拟 Cortex-A15 的 QEMU 上启动 QNX
Launch QNX on QEMU emulating Cortex-A15
我有 IFS 图像应该 运行 板载类似于 OMAP5 uEVM。我正在尝试在具有相同 Cortex-A15 CPU.
的 QEMU 虚拟机上 运行 它
我有一堆问题,但首先我想问一下它是否非常可行?
TLDR
我决定使用 U-Boot 作为引导程序。我用 arm-linux-gnueabi-gcc、Ubuntu 的 arm-linux-gnueabihf-gcc 和 linaro 的 arm-eabi-gcc-7.5 编译了它。所有 3 U-Boot 个版本都有效。看起来 QNX 二进制文件不使用硬浮点(armhf 或 armle-v7),即使目标 CPU 支持它。 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
我用 dumpifs -u QNX-IFS.raw QNX-IFS
提取了图像并将其复制到虚拟驱动器。
我的 RAM space 从 0x40000000(virt-6.0 机器)开始,但目标板从 0x80100000 开始。所以我调整了原来的startup_vaddr=0x8010097c
并执行了
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>]
Prefetch abort 意味着它引用了超出范围的内存。这个神奇的地址来自小精灵header。这意味着它正确读取 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
两块板都有相同的 2Gb RAM,但虚拟内存地址不同 space。我决定将我的板内存扩展到 3Gb,使入口点地址在范围内。然后我再次尝试启动内核。它再次崩溃并出现新错误:
=> 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 ...
一方面,对于 Cortex-A15,/proc/boot/procnto-smp-instr 是 elf-executable,另一方面,内核不是常规可执行文件。 Header 暗示它是特定于硬件的。
有追到运行吗?
我还在 qnx 社区网站上找到了一个包含 Cortex-A15 内核的软件包。它包含四个版本的 procnto*。但它们是 armle-v7 的可重定位 object 文件。是否可以 link 使其可执行?
我真的没有 arm 开发经验,也没有 QNX。如果有任何想法或建议,我将不胜感激。
你这里的主要问题是 Arm 板通常彼此之间有很大不同,因此引导加载程序和 OS 内核通常必须在构建时支持它们要使用的任何板 运行在。 (这与 x86 世界非常不同,在 x86 世界中,基本上每台机器看起来或多或少都像标准 PC,并且软件都是针对 运行 构建的。)
所以简短的回答是,除非您构建的 QNX 图像非常通用“运行 在很多不同的东西上,并获取设备树文件来告诉他们有关硬件的信息”。 *],那么如果 QEMU 具有 QNX 映像所期望的硬件模型,它们只会在 QEMU 上 运行。没有OMAP5的QEMU模型
[*] 您可以像这样构建 Linux。您还可以构建 Linux 以非常具体地针对给定的板,而无需额外的设备驱动程序支持其他任何东西。我不知道 QNX 让你做什么。
我有 IFS 图像应该 运行 板载类似于 OMAP5 uEVM。我正在尝试在具有相同 Cortex-A15 CPU.
的 QEMU 虚拟机上 运行 它我有一堆问题,但首先我想问一下它是否非常可行?
TLDR
我决定使用 U-Boot 作为引导程序。我用 arm-linux-gnueabi-gcc、Ubuntu 的 arm-linux-gnueabihf-gcc 和 linaro 的 arm-eabi-gcc-7.5 编译了它。所有 3 U-Boot 个版本都有效。看起来 QNX 二进制文件不使用硬浮点(armhf 或 armle-v7),即使目标 CPU 支持它。 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
我用 dumpifs -u QNX-IFS.raw QNX-IFS
提取了图像并将其复制到虚拟驱动器。
我的 RAM space 从 0x40000000(virt-6.0 机器)开始,但目标板从 0x80100000 开始。所以我调整了原来的startup_vaddr=0x8010097c
并执行了
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>]
Prefetch abort 意味着它引用了超出范围的内存。这个神奇的地址来自小精灵header。这意味着它正确读取 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
两块板都有相同的 2Gb RAM,但虚拟内存地址不同 space。我决定将我的板内存扩展到 3Gb,使入口点地址在范围内。然后我再次尝试启动内核。它再次崩溃并出现新错误:
=> 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 ...
一方面,对于 Cortex-A15,/proc/boot/procnto-smp-instr 是 elf-executable,另一方面,内核不是常规可执行文件。 Header 暗示它是特定于硬件的。
有追到运行吗?
我还在 qnx 社区网站上找到了一个包含 Cortex-A15 内核的软件包。它包含四个版本的 procnto*。但它们是 armle-v7 的可重定位 object 文件。是否可以 link 使其可执行?
我真的没有 arm 开发经验,也没有 QNX。如果有任何想法或建议,我将不胜感激。
你这里的主要问题是 Arm 板通常彼此之间有很大不同,因此引导加载程序和 OS 内核通常必须在构建时支持它们要使用的任何板 运行在。 (这与 x86 世界非常不同,在 x86 世界中,基本上每台机器看起来或多或少都像标准 PC,并且软件都是针对 运行 构建的。)
所以简短的回答是,除非您构建的 QNX 图像非常通用“运行 在很多不同的东西上,并获取设备树文件来告诉他们有关硬件的信息”。 *],那么如果 QEMU 具有 QNX 映像所期望的硬件模型,它们只会在 QEMU 上 运行。没有OMAP5的QEMU模型
[*] 您可以像这样构建 Linux。您还可以构建 Linux 以非常具体地针对给定的板,而无需额外的设备驱动程序支持其他任何东西。我不知道 QNX 让你做什么。