使用 MSVC 工具生成裸机二进制文件的过程是什么?
What is the process for generating a bare metal binary with MSVC tools?
使用 MSVC 工具生成裸机二进制文件的过程是什么?
在 GNU 领域,您 cc
编译或 as
assemble 源代码到 object 文件,ld
link object 文件到 ELF(使用 linker 脚本),然后 objcopy
ELF 中的相关部分作为“固件二进制文件”。我想做同样的事情,但只使用 MSVC 提供的工具。
我一直在使用以下 ARM64 startup.s
进行测试:
AREA .text, CODE, READONLY
start
LDR w1, =0xDEADBEEF
B .
END
这是假设简单地用0xDEADBEEF加载X1寄存器的低32位然后自旋。要assemble代码我运行:
armasm64.exe startup.s
我猜如果我有一个 peripherals.c
源文件,我需要 link startup.s
和 peripherals.c
到一个单一的可执行文件(COFF ?,PE?)。最后,我需要去掉 any COFF/PE headers 以便 ARM MCU 可以在加载时执行代码。
免责声明:我不属于我的专业领域,我根据我使用 MSVC 工具所做的一些测试提出了一个答案,在阅读了一些 Microsoft 文档之后,在提出问题三天后,还没有提出任何答案。我希望这个答案会引发更多知情的答案,这样我就可以很乐意收回它。
“使用 MSVC 工具生成裸机二进制文件的过程是什么?”问题的答案。可能是:“有 none”。
aarch64-pe.asm
:
AREA .text, CODE, READONLY
EXPORT start
start
LDR w1, =0xDEADBEEF
B .
END
(符号 'start' 需要使用 EXPORT
指令创建 public 才能被 linker 解析。
组装:
armasm64.exe aarch64-pe.asm
现在,aarch64(版本 14.28.29334.0)的 linker 只支持有限的目标子系统列表:
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
子系统的情况。
没有“BAREMETAL”子系统这样的东西。
当尝试 link aarch64-pe.obj 每个子系统但 EFI_ROM
使用 0x0000000040000000
作为基地址时, linker 退出显示相同的错误,抱怨起始地址不能小于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 可用并且已经由...配置的裸机程序从起始地址开始禁用 MMU,起始地址小于4GiB.
当 运行ning dumpbin.exe
against aarch64-pe.efi 时,基地址似乎设置为 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
当对 linker 以 0x0000000100000000
作为基地址生成的可执行文件执行 dumpbin.exe
时,文件类型始终是 EXECUTABLE IMAGE
.
更重要的是,dumpbin.exe
似乎也不提供将生成的可执行文件转换为标准格式,例如 s-record
或 intel hex
。
因此,我的结论是,MSVC 工具单独暂时不允许构建 aarch64 裸机应用程序。
使用 MSVC 工具生成裸机二进制文件的过程是什么?
在 GNU 领域,您 cc
编译或 as
assemble 源代码到 object 文件,ld
link object 文件到 ELF(使用 linker 脚本),然后 objcopy
ELF 中的相关部分作为“固件二进制文件”。我想做同样的事情,但只使用 MSVC 提供的工具。
我一直在使用以下 ARM64 startup.s
进行测试:
AREA .text, CODE, READONLY
start
LDR w1, =0xDEADBEEF
B .
END
这是假设简单地用0xDEADBEEF加载X1寄存器的低32位然后自旋。要assemble代码我运行:
armasm64.exe startup.s
我猜如果我有一个 peripherals.c
源文件,我需要 link startup.s
和 peripherals.c
到一个单一的可执行文件(COFF ?,PE?)。最后,我需要去掉 any COFF/PE headers 以便 ARM MCU 可以在加载时执行代码。
免责声明:我不属于我的专业领域,我根据我使用 MSVC 工具所做的一些测试提出了一个答案,在阅读了一些 Microsoft 文档之后,在提出问题三天后,还没有提出任何答案。我希望这个答案会引发更多知情的答案,这样我就可以很乐意收回它。
“使用 MSVC 工具生成裸机二进制文件的过程是什么?”问题的答案。可能是:“有 none”。
aarch64-pe.asm
:
AREA .text, CODE, READONLY
EXPORT start
start
LDR w1, =0xDEADBEEF
B .
END
(符号 'start' 需要使用 EXPORT
指令创建 public 才能被 linker 解析。
组装:
armasm64.exe aarch64-pe.asm
现在,aarch64(版本 14.28.29334.0)的 linker 只支持有限的目标子系统列表:
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
子系统的情况。
没有“BAREMETAL”子系统这样的东西。
当尝试 link aarch64-pe.obj 每个子系统但 EFI_ROM
使用 0x0000000040000000
作为基地址时, linker 退出显示相同的错误,抱怨起始地址不能小于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 可用并且已经由...配置的裸机程序从起始地址开始禁用 MMU,起始地址小于4GiB.
当 运行ning dumpbin.exe
against aarch64-pe.efi 时,基地址似乎设置为 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
当对 linker 以 0x0000000100000000
作为基地址生成的可执行文件执行 dumpbin.exe
时,文件类型始终是 EXECUTABLE IMAGE
.
更重要的是,dumpbin.exe
似乎也不提供将生成的可执行文件转换为标准格式,例如 s-record
或 intel hex
。
因此,我的结论是,MSVC 工具单独暂时不允许构建 aarch64 裸机应用程序。