Получите настоящую архитектуру M1 Mac независимо от Rosetta

Мне нужно получить реальную архитектуру Mac независимо от того, выполняется ли процесс через Rosetta или нет.

Прямо сейчас в Node.js process.arch возвращает x64, а в оболочке uname -m возвращает x86_64.


person Elmo    schedule 17.12.2020    source источник
comment
Мой вариант использования здесь — отправить версию приложения для руки через автоматическое обновление. Также отслеживайте, кто запускает эмулированное программное обеспечение, и связывайте это с производительностью или другими проблемами.   -  person Elmo    schedule 17.12.2020
comment
Должна быть возможность обнаружить существование Розетты 2 и принять ее на вооружение.   -  person Elmo    schedule 17.12.2020
comment
Существует эта заметка о том, как это сделать в целом. У меня есть сомнения, что для этого уже написан модуль Nodejs.   -  person Ouroborus    schedule 17.12.2020
comment
Спасибо! Знаете ли вы, есть ли способ сделать то же самое в сценарии оболочки? (если ваше терминальное приложение работает в x86, uname -m не вернет руку)   -  person Elmo    schedule 17.12.2020
comment
Напишите исполняемый файл, который выполняет фактическую проверку. В сценарии попробуйте выполнить двоичный файл и проверьте его результаты, а также проверьте, действительно ли он не выполняется.   -  person Ouroborus    schedule 17.12.2020


Ответы (2)


Благодаря @Ouroborus, эта заметка описывает, как определить, является ли ваше приложение переведено.

Если это переведено:

$ sysctl sysctl.proc_translated
sysctl.proc_translated: 1

Если не:

$ sysctl sysctl.proc_translated
sysctl.proc_translated: 0

На компьютерах Mac без ARM:

$ sysctl sysctl.proc_translated
sysctl: unknown oid 'sysctl.proc_translated'
person Elmo    schedule 17.12.2020

Как указывает ответ @Elmo, командная строка sysctl -n sysctl.proc_translated или собственный эквивалентный вызов sysctlbyname() укажет, работаете ли вы под Rosetta.

Два других значения sysctl имеют значение. На оборудовании M1 без Rosetta возвращаются следующие значения:

hw.cputype: 16777228
hw.cpufamily: 458787763

hw.cputype — это 0x0100000C (CPU_TYPE_ARM64), а hw.cpufamily — это 0x1b588bb3 (CPUFAMILY_ARM_FIRESTORM_ICESTORM).

Однако при выполнении под Rosetta низкоуровневый машинный код, который собирает CPUID, имеет приоритет, и следующие два значения возвращаются как через sysctlbyname(), так и через командную строку:

hw.cputype: 7
hw.cpufamily: 1463508716

Они соответствуют 0x7 (CPU_TYPE_X86) и 0x573b5eec (INTEL_WESTMERE).

Похоже, что Rosetta сообщает о чипе Westmere, совместимом с x86, под управлением Rosetta, но этот выбор кажется последовательным везде, где я видел. Эта виртуальная архитектура может быть полезной информацией для некоторых программ.

Другая возможность представлена ​​в реестре IO. В то время как плоскость IOService по умолчанию собирает данные в режиме реального времени, плоскость IODeviceTree сохраняется при загрузке и включает следующие записи в дереве (командная строка ioreg -p IODeviceTree или ioreg -c IOPlatformDevice):

cpu0@0  <class IOPlatformDevice, id 0x10000010f, registered, matched, active, busy 0 (180 ms), retain 8>
    | | | {
...
    | | |   "compatible" = <"apple,icestorm","ARM,v8">

(для ЦП 0-3) и

cpu4@100  <class IOPlatformDevice, id 0x100000113, registered, matched, active, busy 0 (186 ms), retain 8>
    | | | {
...
    | | |   "compatible" = <"apple,firestorm","ARM,v8">

(для ЦП 0-3)

Это явно указывает на чип ARMv8 Firestorm + Icestorm M1.

person Daniel Widdis    schedule 18.01.2021