Каков процесс создания двоичного файла с нуля с помощью инструментов MSVC?

Каков процесс создания двоичного файла с нуля с помощью инструментов MSVC?

В мире GNU вы 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 MCU мог выполнить код при загрузке.


person Vincent Agriesti    schedule 21.11.2020    source источник
comment
Вы хотите иметь возможность разрабатывать / компилировать под Windows или действительно хотите использовать ассемблер / компоновщик Microsoft arm64? Обратите внимание, что поддержка может быть намного меньше. Например, я пытался узнать, откуда скачать armasm64.exe, чтобы попытаться ответить на ваш вопрос, но безрезультатно ...   -  person Frant    schedule 21.11.2020
comment
Я действительно хочу использовать набор инструментов MSVC. Я получил armasm64.exe из MSVC v142 - инструменты сборки VS 2019 C ++ ARM64 (v14.28), найденные на экране установки функции отдельных компонентов VS2019. Я знаю, что Microsoft теперь поддерживает устройства ARM и IoT, поэтому я решил, что, возможно, Visual Studio Build Tools теперь сможет поддерживать разработку на «голом железе». Я потратил немало часов, пытаясь заставить инструментальную цепочку MSVC имитировать то, что я знаю из своего опыта GNU, но я начал думать, что, возможно, разработчик Windows будет лучше понимать, возможно ли это или нет.   -  person Vincent Agriesti    schedule 21.11.2020
comment
@Frant ... в отношении Пожалуйста, обратите внимание, что поддержка может быть намного меньше. ... вот почему я полагаюсь на ТАК. ;-)   -  person Vincent Agriesti    schedule 21.11.2020
comment
нет проблем, просто хотел убедиться, каковы были ваши требования.   -  person Frant    schedule 21.11.2020
comment
Думаю, я пробовал использовать инструменты Microsoft еще когда-то, когда появилась первая поддержка руки, в то время это был тупик. В то время я тоже не знал этого. Это просто один из тех, кто поднимается на гору, потому что это наказание или есть реальная цель / ожидание? LIkely лучше подходит для форума Майкрософт или напрямую с Майкрософт.   -  person old_timer    schedule 22.11.2020
comment
или их объектный файл вписывается в то, что принимает gnu ld? Я предполагаю, что вы можете создавать объекты с помощью msvc C или asm. Если это проблема связывания, и вы не можете получить компоновщик напрямую или компилятор C косвенно, тогда, возможно, используйте или конвертируйте (должно быть просто написать свой собственный инструмент) объекты и используйте компоновщик gnu для фазы ссылки, так же, как clang / llvm часто приводит к этому пути.   -  person old_timer    schedule 22.11.2020
comment
@old_timer: согласно binutils-2.35.1/bfd/config.bfd, похоже, в настоящее время нет никакой поддержки для формата PE и aarch64.   -  person Frant    schedule 23.11.2020
comment
@Frant, таким образом, пишет инструмент преобразования.   -  person old_timer    schedule 23.11.2020
comment
@old_timer: Я больше отвечал на часть or does their object file fit within something that gnu ld accepts? или на ваш комментарий: ответ - нет, насколько я понимаю. Но да, я полагаю, можно было бы написать инструмент преобразования.   -  person Frant    schedule 23.11.2020
comment
@Frant, ах, мир .... да, не удивлен ... (вот почему я сделал свой комментарий о создании инструмента)   -  person old_timer    schedule 23.11.2020
comment
@Vincent Agriesti: компоновщик теперь позволяет указывать базовый адрес ниже 4GiB. Это может быть намеком на то, что инструменты MSVC aarch64 предназначены для создания исполняемых файлов для целевой системы, поддерживающей операционную систему общего назначения с поддержкой MMU. ИМХО это не очень хорошо сочетается с концепцией бинарной прошивки.   -  person Frant    schedule 23.11.2020
comment
@old_timer: pefile, вероятно, будет хорошей отправной точкой для упомянутого вами инструмента, хотя я не большой поклонник Python (я проиграл войну Ruby / Python). Мне пока не удалось определить эквивалент libelf` для формата PE, есть подсказки?   -  person Frant    schedule 23.11.2020
comment
@Frant Я бы погуглил формат файла и просто прочитал. То же самое с elf, просто напишите его, elf - это довольно простой формат файла. Когда я сделал именно это много лет назад, Microsoft output coff и именно это я сделал, чтобы обнаружить, что их компилятор не лучше, если не хуже, чем gcc (который примерно средний или был в то время, и в некоторых случаях не стал намного лучше) худший). поэтому я отказался от инструментов Microsoft. Я не использую никаких библиотек или инструментов, кроме binutils.   -  person old_timer    schedule 23.11.2020
comment
Позвольте нам продолжить это обсуждение в чате.   -  person Frant    schedule 23.11.2020


Ответы (1)


Заявление об ограничении ответственности: я здесь не в своей области знаний, и я предлагаю ответ, основанный на некоторых тестах, которые я провел с помощью инструментов MSVC, после прочтения некоторой документации Microsoft и через три дня после того, как вопрос был задан. и пока не было предложено никаких ответов. Я надеюсь, что этот ответ повлечет за собой более осознанные ответы, так что я с радостью отозвусь от него.

Ответ на вопрос Каков процесс создания двоичного файла с нуля с помощью инструментов 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.

Подсистемы BAREMETAL не существует. При попытке связать aarch64-pe.obj для каждой из подсистем, но EFI_ROM с использованием 0x0000000040000000 в качестве базового адреса, компоновщик завершил работу с той же ошибкой, жалуясь, что начальный адрес не может быть меньше 4 ГБ:

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 с начального адреса менее 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 на «голое железо» в настоящее время.

person Frant    schedule 24.11.2020
comment
Это потрясающая информация! Спасибо, что просмотрели все это. Я смотрю документы .microsoft.com / en-us / cpp / build / reference /, в котором говорится: когда был установлен параметр / DYNAMICBASE: NO, операционная система сначала пытается загрузить программу по указанному ... адресу. Если там недостаточно места, система перемещает программу. Чтобы предотвратить перемещение, используйте параметр / FIXED. Странно, что он не позволяет вам просто переопределить базовый адрес. - person Vincent Agriesti; 01.12.2020
comment
Когда у меня будет время сегодня вечером, я поиграю с переопределением базового адреса ... у вас есть ссылка на то, где задокументирован лимит 4GiB? Я собираюсь сделать запрос на добавление функции в сообщество разработчиков VS, если нет документально подтвержденной причины, по которой у меня нет этой возможности. - person Vincent Agriesti; 01.12.2020
comment
У меня нет ссылки, я просто получал сообщение об ошибке ARM64 image cannot have base address below 4GB каждый раз, когда я использовал базовый адрес менее 4 ГБ. И согласно документации Microsoft, базовый адрес по умолчанию для 64-битного исполняемого файла - 0x140000000. - person Frant; 02.12.2020
comment
Начиная с 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. Если вы согласитесь или получите подтверждение, я буду признателен, если вы примете мой ответ, поскольку это может пометить его как действительный для других людей. - person Frant; 02.12.2020
comment
Я начинаю соглашаться. Я смог использовать ассемблер asmarm.exe (32-битный), чтобы без ошибок установить базовый адрес на 0x0. Интересно, что смещение VA всегда будет равным 0x1000 (4 КиБ) байтов. Я предполагаю, что это жестко запрограммировано, чтобы разработчики не могли ссылаться на ноль без SEGFAULT. Я подозреваю, что это связано с предположением, что весь код, созданный с помощью ассемблера MSVC, будет выполняться в среде виртуальных адресов, управляемой MMU. Позор ... Я действительно надеялся, что это волшебное позволит мне получить доступ к флагу физической памяти. Ну что ж. Спасибо за все ваши усилия! - person Vincent Agriesti; 02.12.2020
comment
Даже без инструментов, предполагающих, что исполняемый файл будет загружен загрузчиком с поддержкой MMU, я думаю, что инструменты Microsoft для создания двоичного образа или файла в шестнадцатеричном формате s-record / Intel из полученного исполняемого файла в формате PE-COFF все равно будут отсутствовать. Что вы думаете? - person Frant; 02.12.2020
comment
Я согласен, что нет документированного инструмента для извлечения раздела / двоичного файла. Тем не менее, компоновщик имеет возможность объединять разделы, что позволяет нам объединить все разделы в .text, после чего было бы достаточно просто написать сценарий оболочки (например, cmd, pwsh), чтобы самостоятельно проанализировать двоичный файл с помощью вывод dumpbin.exe. - person Vincent Agriesti; 02.12.2020
comment
Теоретически решение вопроса AFAIK состоит в том, чтобы вручную создать IVT для перехода к коду, собранному ассемблером arm32 по адресу 0x1000, где мы бы настроили таблицы страниц MMU. После этого вы должны перейти в режим aarch64, скопировать / сопоставить код aarch64 со смещением и ветвью 4GiB, настроить CRT, а затем перейти в страну C. ... Это мало чем отличается от типичного поведения основных операционных систем, когда они выбирают наименьший общий знаменатель перед тем, как перейти вверх по стеку к тому, что мы знаем как современный режим ОС. (т.е. устаревший BIOS x86 в реальном режиме в защищенный режим в ОС) - person Vincent Agriesti; 02.12.2020
comment
Ба ... эти комментарии stackoverflow не делают этого для меня. Если у меня будет время, я напишу что-нибудь более существенное, чтобы подробно описать свой последний комментарий с примерами. В любом случае, ИМХО, это неадекватно для реальной (современной) мировой ситуации. В любой реальной ситуации люди вернутся к LLVM или MinGW. - person Vincent Agriesti; 02.12.2020