#windows #visual-studio #arm64 #firmware #bare-metal
#Windows #visual-studio #arm64 #прошивка #простой
Вопрос:
Каков процесс создания простого двоичного файла с помощью инструментов MSVC?
В GNU land вы cc
компилируете или as
собираете исходные файлы в объектные файлы, ld
связываете объектные файлы в ELF (с помощью скрипта компоновщика), а затем objcopy
соответствующие разделы из ELF в качестве «двоичного файла прошивки». Я хочу сделать то же самое, но только с использованием инструментов, предоставленных MSVC.
Я тестировал со следующим ARM64 startup.s
:
AREA .text, CODE, READONLY
start
LDR w1, =0xDEADBEEF
B .
END
Предполагается, что просто загружаются младшие 32 бита регистра X1 с помощью 0xDEADBEEF, а затем выполняется вращение. Чтобы собрать код, который я запускаю:
armasm64.exe startup.s
Я предполагаю, что если бы у меня был peripherals.c
исходный файл, мне нужно было бы связать startup.s
и peripherals.c
в один исполняемый файл (COFF?, PE?). Наконец, мне нужно было бы удалить любые заголовки COFF / PE, чтобы микроконтроллер ARM мог выполнять код при загрузке.
Комментарии:
1. Вы хотите иметь возможность разрабатывать / компилировать под Windows или вы действительно хотите использовать ассемблер / компоновщик Microsoft arm64? Пожалуйста, обратите внимание, что поддержка может быть гораздо менее доступной. Например, я пытался выяснить, где скачать armasm64.exe от того, чтобы попытаться ответить на ваш вопрос, но безрезультатно…
2. Я действительно хочу использовать набор инструментов MSVC. Я получил armasm64.exe из «MSVC v142 — VS 2019 C ARM64 build tools (v14.28)», найденного на экране установки отдельных компонентов VS2019. Я знаю, что Microsoft теперь поддерживает устройства ARM и IoT, поэтому я подумал, что, возможно, инструменты сборки Visual Studio теперь должны поддерживать простую разработку. Я потратил немало часов, пытаясь заставить набор инструментов MSVC имитировать то, что я знаю из своего опыта работы с GNU, но я начал думать, что, возможно, у разработчика Windows было бы лучшее мышление, чтобы знать, возможно ли это или нет.
3. @Франт … что касается «Пожалуйста, обратите внимание, что поддержка может быть гораздо менее доступной». … вот почему я склоняюсь к SO. 😉
4. нет проблем, просто хотел убедиться, каковы ваши требования.
5. Я думаю, что я пытался использовать инструменты Microsoft еще тогда, когда появилась первая поддержка arm, в то время это был тупик. В то время я тоже не знал так много. Это просто один из тех, кто поднимается на гору, потому что там есть наказания или есть реальная цель / ожидание? Вероятно, лучше подходит для форума Microsoft или напрямую с Microsoft.
Ответ №1:
Отказ от ответственности: я не в своей области знаний, и я предлагаю ответ, основанный на некоторых тестах, которые я провел с использованием инструментов MSVC, после прочтения некоторой документации Microsoft и через три дня после того, как был задан вопрос, ответы на который еще не были предложены. Я надеюсь, что этот ответ вызовет более обоснованные ответы, так что я могу с радостью отказаться от него.
Ответ на вопрос «Каков процесс создания простого двоичного файла с помощью инструментов MSVC?» вероятно: «Его нет».
aarch64-pe.asm
:
AREA .text, CODE, READONLY
EXPORT start
start
LDR w1, =0xDEADBEEF
B .
END
(Символ «start» должен быть общедоступным с помощью 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
подсистемы.
Не существует такой вещи, как подсистема «BAREMETAL». При попытке связать aarch64-pe.obj для каждой из подсистем, но EFI_ROM
используя 0x0000000040000000
в качестве базового адреса, компоновщик завершал работу, отображая ту же ошибку, жалуясь, что начальный адрес не может быть меньше 4 ГБ:
D:optmsvcarm64>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:optmsvcarm64>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:optmsvcarm64>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:optmsvcarm64>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:optmsvcarm64>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:optmsvcarm64>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:optmsvcarm64>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:optmsvcarm64>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:optmsvcarm64>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:optmsvcarm64>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 отключен с начального адреса менее 4 ГБ.
При запуске dumpbin.exe
с 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
При выполнении dumpbin.exe
с исполняемыми файлами, созданными компоновщиком с 0x0000000100000000
базовым адресом, тип файла был согласованным EXECUTABLE IMAGE
.
Более того, похоже, dumpbin.exe
не предлагает преобразование результирующего исполняемого файла в стандартный формат, такой как s-record
или intel hex
либо.
Поэтому я пришел к выводу, что одни только инструменты MSVC не позволяют создавать приложения aarch64 на основе простого металла на данный момент.
Комментарии:
1. Это потрясающая информация! Спасибо, что посмотрели все это. Я смотрю на docs.microsoft.com/en-us/cpp/build/reference/… в котором говорится: «когда параметр /DYNAMICBASE:NO был установлен, операционная система сначала пытается загрузить программу по указанному … адресу. Если там недостаточно места, система перемещает программу. Чтобы предотвратить перемещение, используйте параметр /FIXED . » Странно, что это не позволит вам просто переопределить базовый адрес.
2. Когда у меня будет немного времени сегодня вечером, я поиграю с переопределением базового адреса… у вас есть ссылка на то, где задокументировано ограничение в 4 ГБ? Я собираюсь сделать запрос функции сообществу разработчиков VS, если нет документированной причины не иметь этой возможности.
3. У меня нет ссылки, я просто получал сообщение об
ARM64 image cannot have base address below 4GB
ошибке каждый раз, когда я использовал базовый адрес меньше 4 ГБ. И согласно документации Microsoft , базовый адрес по умолчанию для 64-разрядного исполняемого файла равен0x140000000
.4. Поскольку
the operating system first attempts to load a program at its specified or default base address. If sufficient space is not available there, the system relocates the program. To prevent relocation, use the /FIXED option.
это, по-моему, подтверждает, что инструменты Microsoft не подходят для создания простых программ: это означает, что для загрузки исполняемых программ, которые они создают, требуется сложный загрузчик с поддержкой MMU. В случае, если вы согласитесь или получите подтверждение, я был бы признателен, если бы вы приняли мой ответ, поскольку это может пометить его как действительный для других людей.5. Я начинаю соглашаться. Я смог использовать asmarm.exe (32-битный) ассемблер для установки базового адреса в 0x0 без ошибок. Интересно, что он по-прежнему всегда будет иметь смещение VA в 0x1000 (4 КБ) байт. Я предполагаю, что это жестко запрограммировано, чтобы разработчики не могли ссылаться на ноль без SEGFAULT. Я подозреваю, что это связано с тем, что существует предположение, что весь код, созданный с помощью ассемблера MSVC, будет выполняться в среде виртуальных адресов, управляемой MMU. Позор… Я действительно надеялся на этот волшебный флаг «разрешить мне доступ к физической памяти». Ну что ж. Спасибо за все ваши усилия!