6

Недавно я выяснил, что Mac OS X действительно может запускать 64-битные (x64) приложения, даже если загружено ядро x86. Это было шокирующим для меня впервые.

Но потом я понял, что это действительно странно, если система работает и работает под x64-совместимым процессором, который не может запускать приложения x64, независимо от того, какое ядро управляет процессами. Это действительно так сложно? Просто загрузите чертово приложение в память и установите указатель работы процессора на первый байт, как пирог!

Единственный барьер для этого, как я мог себе представить, это некие "исполняемые заголовки". К сожалению, я не очень доволен архитектурой Windows и бинарной структурой, поэтому мне нужно больше пояснений здесь.

Де-факто стандарт UNF-подобных UNIX-двоичных заголовков ELF имеет своего брата ELF64, который (как здесь описывается в документе) не сильно отличается от ELF32, но даже при том, что 32-битные ядра не способны выполнять код x64. Да, эта программа, вероятно, связана с библиотеками x64, и давайте представим, что мы просто скопировали и вставили их прямо в папку /usr /lib64. Но я уверен, что это не поможет, почему?

И, наконец, что особенного в ядре Mac OS X, чтобы его не беспокоило использование набора программных инструкций? Есть ли в Mac OS X универсальный и подходящий для заголовка исполняемых файлов обоих ядер, так что он просто может загрузить приложение в память и сказать процессору «выполнить прямо отсюда, я не против того, что за этим стоит»?

PS: я действительно много думал о том, где разместить этот вопрос: на stackoverflow.com или superuser.com, и решил разместить здесь, потому что тема, скорее всего, более специфична для ОС.

4 ответа4

5

Реальный вопрос заключается в том, почему некоторые другие операционные системы не могут запускать 64-битные двоичные файлы на 32-битном ядре. Нет фундаментальной причины, почему это было бы невозможно. Базовая архитектура процессора поддерживает как 64-битный набор инструкций (amd64 или x86-64), так и 32-битный набор инструкций (i386), и нет ограничений на их совместное использование (в частности, нет «64-битный режим», который отличается от «32-битного режима»; есть один длинный режим, который позволяет выполнять инструкции как из i386, так и из «нативного» набора amd64).

Запуск 64-битных приложений на 32-битном ядре требует немного больше работы внутри ядра, потому что он должен управлять 64-битными указателями на пространство пользователя вместе с 32-битными указателями на пространство ядра. Большинство, если не все указатели, передаваемые в ядре, либо известны как пространство ядра, либо как пространство пользователя, так что это не проблема, если они имеют другой размер. Основная трудность заключается в отказе от возможности иметь универсальный тип указателя, который имеет отдельные диапазоны значений для памяти процесса, памяти ядра и памяти, используемой различными аппаратными средствами (включая ОЗУ), но это невозможно в современных 32-битных ядрах. в любом случае на оборудовании класса ПК (если у вас 4 ГБ или больше ОЗУ или вы хотите отобразить 2 ГБ ОЗУ, 2 ГБ пространства процесса, память ядра и более, вам все равно нужно иметь возможность сопоставлять адреса более 32 бит)).

Согласно цитируемой вами статье в Википедии , OSX могла запускать процессы amd64 на процессорах amd64 до того, как у нее появилось 64-битное ядро. Solaris также безразлично смешивает исполняемые файлы i386 и amd64 на процессорах amd64, независимо от того, является ли ядро 32-битным или 64-битным (доступны оба варианта).

Другие операционные системы могут запускать процессы i386 в (64-разрядном) ядре amd64, но не процессы amd64 в 32-разрядном ядре, например Linux, FreeBSD, NetBSD и Windows. В то же время другие операционные системы рассматривают amd64 и i386 как совершенно разные архитектуры, например OpenBSD.

4

Я недостаточно знаком с архитектурой x86_64, чтобы дать подробности, но, по сути, происходит то, что процессор переключается между 64-битным режимом и режимом совместимости (32-битный) как часть переключения контекста между ядром и пользовательским пространством программа. Это почти то же самое, что было бы сделано для запуска 32-битной программы под 64-битным ядром, только в обратном порядке.

Кстати, OS X не использует двоичный формат ELF, он использует двоичные файлы Mach-O . Формат Mach-O допускает многоархитектурные ("универсальные") двоичные файлы, поэтому программы (и в этом отношении ядро) могут поставляться как в 32-, так и в 64-битных (и PPC, и PPC64, и ...), а ОС может выберите версию для загрузки (и, следовательно, в каком режиме ее запускать) во время загрузки. Вы можете использовать команду file в двоичном файле, чтобы увидеть, в каком формате он находится. Например, вот приложение Chess, поставляемое с OS X v10.5:

$ file Applications/Chess.app/Contents/MacOS/Chess 
Applications/Chess.app/Contents/MacOS/Chess: Mach-O universal binary with 4 architectures
Applications/Chess.app/Contents/MacOS/Chess (for architecture ppc): Mach-O executable ppc
Applications/Chess.app/Contents/MacOS/Chess (for architecture ppc64):   Mach-O 64-bit executable ppc64
Applications/Chess.app/Contents/MacOS/Chess (for architecture i386):    Mach-O executable i386
Applications/Chess.app/Contents/MacOS/Chess (for architecture x86_64):  Mach-O 64-bit executable x86_64

И примечание для тех, кто сомневается, что это возможно: OS X поддерживала 64-битные программы, начиная с v10.4 (с ограниченной поддержкой API), но не включала 64-битное ядро до v10.6 (и даже тогда, ядро работало в 32-битном режиме по умолчанию на большинстве моделей). Подробнее см. В руководстве по 64-битному переходу Apple . Я публикую это на MacBook Pro с 10.6 с 32-битным ядром (64-битная версия не поддерживается для этой конкретной модели), но, согласно Activity Monitor, единственным процессом, не работающим в 64-битном режиме, является kernel_task.

4

Маки поддерживают запуск 64-битных приложений поверх 32-битного ядра, потому что многоступенчатый план делает именно это:

  1. Приложения Mac поставляются в виде "толстых двоичных файлов" в виде "комплектов", которые позволяют использовать все четыре комбинации 64/32-битных и Intel/PPC в одной установке, которая может быть проста, как одно перетаскивание. ОС запускает соответствующую.
  2. Mac используют PAE для доступа к более чем 4 ГБ оперативной памяти при работе с 32-разрядным ядром. Windows не допускает PAE на версиях, не относящихся к Серверу, из-за проблем совместимости с драйверами, которых у них гораздо больше, включая сторонние.
  3. Tiger добавляет 64-разрядный ABI (двоичный интерфейс приложения) для запуска 64-разрядного кода поверх 32-разрядного ядра и 64-разрядную версию низкоуровневых API-интерфейсов (интерфейс программирования приложений) для "консоли" (не GUI) приложения.
  4. Leopard добавляет 64-битное Какао для приложений с графическим интерфейсом (но не 64-битный Carbon).
  5. Snow Leopard добавляет 64-битное ядро, которое используется по умолчанию только на некоторых моделях высокого класса.
  6. Lion требует 64-битный процессор, но все еще включает в себя 32-битное ядро. Например, старый Mac с 64-битным процессором, но с графическим процессором, в котором есть только 32-битные драйверы, должен будет работать с 32-битным ядром.

Таким образом, OS X поддерживал 64-битные приложения как можно скорее и продолжал запускать 32-битное ядро как можно дольше из-за ситуации с драйверами. (Бесполезность ядра становится фактором только при попытке управлять огромными объемами ОЗУ - таблицы страниц также занимают память - и переключение на 64-разрядное ядро дает некоторые преимущества в производительности.) Но Apple, конечно, не стесняется отбрасывать вещи.

Тогда реальный вопрос заключается в том, почему Windows и Linux не делают одно и то же. Для Windows учтите, что их первая попытка Win64 была с Itanium, который был совершенно другим. Но окончательный ответ может сводиться к тому, что он обычно имеет в течение последних нескольких десятилетий: совместимость с кучей сторонних программ, которые делали вещи не совсем правильно:

64-разрядная реализация OS X значительно отличается от Windows, которая рассматривает свои 32-разрядную и 64-разрядную версии как две разные операционные системы, хранящиеся на разных установочных носителях. Это делается главным образом для поддержания совместимости Windows со старыми приложениями - перемещение или переименование таких вещей, как папка System32, может нарушить работу программ, которые ожидали ее появления, - и в результате они разделяются до такой степени, что даже обновления не происходит. путь между 32-битной Windows и 64-битной Windows. Из-за этого, а также из-за того, что приложения и драйверы Windows обычно имеют разные 32-разрядные и 64-разрядные версии, переход Windows на 64-разрядные версии был немного более сложным и немного более заметным для пользователя.

Существует много фоновой информации о 64-битном переходе как на стороне Mac, так и на стороне Windows. (Эти ссылки относятся к последней из каждой серии статей; обязательно вернитесь к началу каждой из них.)

Я не знаю, что за история была с Linux, но представьте, что у Линуса было твердое мнение об этом.

0

Я понял, что это действительно странно, если система работает и работает под x64-совместимым процессором, который не может запускать приложения x64, независимо от того, какое ядро управляет процессами. Это действительно так сложно? Просто загрузите чертово приложение в память и установите указатель работы процессора на первый байт, как пирог!

Вы упускаете важную часть. Приложения делают вызовы API для функций и сервисов, предоставляемых операционной системой. Если 64-битное приложение отправляет 64-битный указатель на 32-битную операционную систему, все должно взорваться.

Я подозреваю, что для обеспечения приемлемой работы в любом случае ОС должна перегрузить функцию и предоставить как 64-битную, так и 32-битную версию каждой функции. Для каждого ядра функция off (64-битная функция в 32-битных ядрах, 32-битная функция в 64-битных ядрах) будет просто заглушкой, которая переводит вызов в 32-битную безопасную, а затем повторно вызывает собственную функцию.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .