windows - 用MSVC工具生成裸机二进制文件的过程是什么?

标签 windows visual-studio arm64 firmware bare-metal

使用MSVC工具生成裸机二进制文件的过程是什么?
在GNU领域中,您可以cc编译或as将源组装成目标文件,ld将目标文件链接到ELF中(带有链接描述文件),然后将相关部分objcopy作为“固件二进制文件”从ELF中进行编码。我想做同样的事情,但只能使用MSVC提供的工具。
我一直在使用以下ARM64 startup.s进行测试:

 AREA .text, CODE, READONLY
start
 LDR w1, =0xDEADBEEF
 B .
 END
假定仅用0xDEADBEEF加载X1寄存器的低32位,然后旋转。要汇编我运行的代码:
armasm64.exe startup.s
我猜想如果我有一个peripherals.c源文件,则需要将startup.speripherals.c链接到一个可执行文件(COFF?,PE?)中。最后,我需要剥离所有COFF/PE header ,以便ARM MCU在加载时可以执行代码。

最佳答案

免责声明:我不属于我的专业领域,我根据阅读一些Microsoft文档后,使用MSVC工具所做的一些测试,以及在提出问题三天后仍未提出答案的情况下,提出一个答案。 。我希望这个答案会触发更明智的答案,以便我可以收回它。
问题“使用MSVC工具生成裸机二进制文件的过程是什么?”可能是:“没有”。aarch64-pe.asm:

 AREA .text, CODE, READONLY
 EXPORT start
start
 LDR w1, =0xDEADBEEF
 B .
 END
(必须使用EXPORT伪指令将符号“开始”公开,以便链接程序对其进行解析)。
组装:
armasm64.exe aarch64-pe.asm
现在,例如aarch64(版本14.28.29334.0)的链接器仅支持目标子系统的有限列表:
BOOT_APPLICATION,
CONSOLE,
WINDOWS,
NATIVE,
POSIX,
EFI_APPLICATION, EFI_BOOT_SERVICE_DRIVER, EFI_ROM, EFI_RUNTIME_DRIVER
从Microsoft和EFI文档看来,所有这些子系统都需要一个能够理解PECOFF格式的加载程序,或者在BCD WMI Provider子系统的情况下能够运行到BOOT_APPLICATION环境中。
没有所谓的“裸机”子系统。
尝试为每个子系统链接aarch64-pe.obj,但使用EFI_ROM作为基地址的0x0000000040000000时,链接器退出并显示相同的错误,提示起始地址不能小于4GiB:
D:\opt\msvc\arm64>for %I in (BOOT_APPLICATION CONSOLE WINDOWS NATIVE POSIX EFI_APPLICATION EFI_BOOT_SERVICE_DRIVER EFI_ROM EFI_RUNTIME_DRIVER) do link /entry:start /BASE:0x0000000040000000 /subsystem:%I aarch64-pe.obj

D:\opt\msvc\arm64>link /entry:start /BASE:0x0000000040000000 /subsystem:BOOT_APPLICATION aarch64-pe.obj
Microsoft (R) Incremental Linker Version 14.28.29334.0
Copyright (C) Microsoft Corporation.  All rights reserved.

LINK : fatal error LNK1355: invalid base address 0x40000000; ARM64 image cannot have base address below 4GB

D:\opt\msvc\arm64>link /entry:start /BASE:0x0000000040000000 /subsystem:CONSOLE aarch64-pe.obj
Microsoft (R) Incremental Linker Version 14.28.29334.0
Copyright (C) Microsoft Corporation.  All rights reserved.

LINK : fatal error LNK1355: invalid base address 0x40000000; ARM64 image cannot have base address below 4GB

D:\opt\msvc\arm64>link /entry:start /BASE:0x0000000040000000 /subsystem:WINDOWS aarch64-pe.obj
Microsoft (R) Incremental Linker Version 14.28.29334.0
Copyright (C) Microsoft Corporation.  All rights reserved.

LINK : fatal error LNK1355: invalid base address 0x40000000; ARM64 image cannot have base address below 4GB

D:\opt\msvc\arm64>link /entry:start /BASE:0x0000000040000000 /subsystem:NATIVE aarch64-pe.obj
Microsoft (R) Incremental Linker Version 14.28.29334.0
Copyright (C) Microsoft Corporation.  All rights reserved.

LINK : fatal error LNK1355: invalid base address 0x40000000; ARM64 image cannot have base address below 4GB

D:\opt\msvc\arm64>link /entry:start /BASE:0x0000000040000000 /subsystem:POSIX aarch64-pe.obj
Microsoft (R) Incremental Linker Version 14.28.29334.0
Copyright (C) Microsoft Corporation.  All rights reserved.

LINK : fatal error LNK1355: invalid base address 0x40000000; ARM64 image cannot have base address below 4GB

D:\opt\msvc\arm64>link /entry:start /BASE:0x0000000040000000 /subsystem:EFI_APPLICATION aarch64-pe.obj
Microsoft (R) Incremental Linker Version 14.28.29334.0
Copyright (C) Microsoft Corporation.  All rights reserved.

LINK : fatal error LNK1355: invalid base address 0x40000000; ARM64 image cannot have base address below 4GB

D:\opt\msvc\arm64>link /entry:start /BASE:0x0000000040000000 /subsystem:EFI_BOOT_SERVICE_DRIVER aarch64-pe.obj
Microsoft (R) Incremental Linker Version 14.28.29334.0
Copyright (C) Microsoft Corporation.  All rights reserved.

LINK : fatal error LNK1355: invalid base address 0x40000000; ARM64 image cannot have base address below 4GB

D:\opt\msvc\arm64>link /entry:start /BASE:0x0000000040000000 /subsystem:EFI_ROM aarch64-pe.obj
Microsoft (R) Incremental Linker Version 14.28.29334.0
Copyright (C) Microsoft Corporation.  All rights reserved.

LINK : warning LNK4075: ignoring '/BASE' due to '/SUBSYSTEM:EFI_ROM' specification

D:\opt\msvc\arm64>link /entry:start /BASE:0x0000000040000000 /subsystem:EFI_RUNTIME_DRIVER aarch64-pe.obj
Microsoft (R) Incremental Linker Version 14.28.29334.0
Copyright (C) Microsoft Corporation.  All rights reserved.

LINK : fatal error LNK1355: invalid base address 0x40000000; ARM64 image cannot have base address below 4GB
对于裸机嵌入式系统来说,这可能是个问题,或者这可能要求MMU可用,并且已经由裸机程序进行配置,从禁用起始地址小于4GiB的MMU开始。
当对aarch64-pe.efi运行dumpbin.exe时,由于0000000180000000指令位于ldr,并且文件类型设置为0x0000000180001000,因此基址似乎设置为DLL
dumpbin.exe  /disasm aarch64-pe.efi
File Type: DLL

  0000000180001000: 18000041  ldr         w1,0000000180001008
  0000000180001004: 14000000  b           0000000180001004
  0000000180001008: DEADBEEF

  Summary

        1000 .rdata
        1000 .text
当对链接器以dumpbin.exe为基地址生成的可执行文件执行0x0000000100000000时,文件类型始终为EXECUTABLE IMAGE
甚至更多,dumpbin.exe似乎都不提供将生成的可执行文件转换为s-recordintel hex之类的标准格式的功能。
因此,我的结论是,单独使用MSVC工具 不允许在一段时间内构建aarch64裸机应用程序。

关于windows - 用MSVC工具生成裸机二进制文件的过程是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64944350/

相关文章:

visual-studio - Visual Studio不断更改project.sln文件

visual-studio - 有没有办法在 Resharper 中使用注释禁用自定义模式

ios - 将图像和视频上传到亚马逊 S3(arm64 错误)

c++ - 为什么这段代码在实际的 BCM2837 (pi 3) 上运行时会挂起,但在 qemu 上运行良好

java - 错误: Unable to access jarfile.编码问题

windows - 获取扬声器音频信号,然后将其流式传输

visual-studio - 在 Visual Studio 2015 上安装 Xamarin,并在 Visual Studio 2013 上安装 Xamarin

macos - 这个构造在 ARM64 程序集中的用途是什么,从 macOS 上的 Swift 编译而来 - adrp、ldr、br 指令序列

java - 从同一个批处理文件运行多个批处理文件时出现问题

在 Sublime Text 2 (gcc) 中编译并运行 C