64-бітове ядро, але всі 32-розрядні запущені процеси ELF, як це?


9

Вихід від uname:

root@debian:~ # uname -a
Linux 5asnb 2.6.32-5-amd64 #1 SMP Mon Jun 13 05:49:32 UTC 2011 x86_64 GNU/Linux

Однак /sbin/initвиконуваний файл відображається як 32-розрядний:

root@debian:~ # file /sbin/init
/sbin/init: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped

Інші аспекти системи також суперечать речам:

root@debian:~ # echo $HOSTTYPE
i486

root@debian:~ # getconf LONG_BIT
32

Відповіді:


13

64-бітове ядро ​​можна встановити на 32-бітний Debian. Ви можете бачити, що ядро ​​amd64 доступне для 32-бітового Debian на його сторінці пакунків . Це може бути використане як альтернатива використанню ядра з підтримкою PAE для підтримки більше 4G загальної оперативної пам’яті. Зауважте, що 32-бітні двійкові файли все ще не можуть отримати доступ більше ніж приблизно 3G оперативної пам’яті за процес.


Дякую! ваші відповіді чіткі, як кришталева куля ~: D Ніколи раніше не помічав пакунок ядра Debian, як раніше.
kiiwii

1
Це неправда: 32-бітні програми можуть використовувати весь 4Gio свого віртуального адресного простору під час роботи на 64-бітному ядрі (якщо тільки вони не працюють з особою ADDR_LIMIT_3GB).
ysdx

@ysdx Отже, обмеження на 2 Гб - це специфічна для Windows річ, а адреси вище 0x80000000 будуть дозволені в 32-розрядному просторі користувачів?
Пол

1
@PaulStelian, У 32-розрядної Windows ви за замовчуванням обмежені найнижчими 2 Гб віртуальної пам'яті для ретро-сумісності (я думаю, деякі програми використовуються для резервування покажчиків на найвищі 2 Гб віртуальної пам'яті для спеціальних цілей). Ви можете встановити прапор LARGEADDRESSAWARE у своєму виконуваному файлі ( docs.microsoft.com/fr-fr/cpp/build/reference/… ), щоб увімкнути доступ до всього 4 ГБ віртуальної пам'яті.
ysdx

15

Усі процесори, які підтримують набір інструкцій x64 (також відомий як x86_64 або amd64), також підтримують набір інструкцій x86 (також відомий як i386 або i686, які суворо говорять про конкретні версії x86). Те ж саме стосується ARM A64 (новий 64-розрядний набір інструкцій, що з'являється в ARMv8) та A32 (назва для "класичного" 32-розрядного набору інструкцій), для SPARC64 та SPARC , і я вважаю, для MIPS64 та MIPS . Отже, для всіх цих сімей архітектури, якщо процесор може запускати 64-бітний код, він також може запускати 32-бітний код.

Ядро Linux підтримує 32-розрядний код користувача з 64-бітовим ядром (я думаю, що всі архітектурні сім'ї, згадані вище). Ядро повинно бути однорідним (всі 64-бітні або всі 32-бітні), і кожен процес повинен бути однорідним, але ви можете мати суміш 32-бітних та 64-бітних процесів на 64-бітному ядрі. Зворотне неможливо: за допомогою 32-розрядного ядра ви не можете запускати 64-бітні процеси.

Це вибір дизайну в Linux, мотивований бажанням запустити існуючі 32-бітні бінарні файли на 64-бітних установках. Інші варіанти Unix зробили різні варіанти: Solaris може запускати 64-бітні програми на 32-бітному ядрі, а також навпаки, тоді як OpenBSD не може запускати 32-бітні програми на 64-бітному ядрі.

Інформацію про процесор можна отримати в /proc/cpuinfo. Якщо ваш процесор x86 має lmпрапор, це 64-бітний процесор.

За замовчуванням uname -mабо archпоказує архітектуру, для якої було складено ядро. Linux може встановити "особистість" процесу (за допомогою personality) системного виклику. Ви можете запустити підпроцес в іншій особистості за допомогою setarchкоманди; setarch i686 someprogramабо linux32 someprogramзапускає задану програму в середовищі, де uname -mповертається i686під час setarch amd64 someprogramабо linux64 someprogramзапускає вказану програму в середовищі, де uname -mповертається amd64.

file /sbin/initрозповідає, для якої архітектури initскладено програму. Хоча в інсталяції можна змішати 32-бітні та 64-бітні виконувані файли, зазвичай всі основні програми ОС походять з тієї самої архітектури, оскільки це набагато простіше в управлінні.

$HOSTYPEє змінною bash і говорить вам, для якої архітектури bashбула складена програма.

getconf LONG_BITдозволяє дізнатися, чи встановлений за замовчуванням компілятор C для компіляції 32-бітних або 64-бітних програм. Більш точним тестом є складання та запуск програми, яка друкує sizeof(void*)або sizeof(size_t)- виклик getconfможе дати лише інформацію про те, що getconfвважає компілятором за замовчуванням.


1
Дійсно, чи переходить 32-бітний Solaris в 64-бітний режим, щоб перейти на 64-бітний процес, а потім назад? Це повинно мати величезні накладні витрати, і просто не має сенсу, оскільки тоді ядро ​​ефективно 64-бітне.
Руслан

1
@Ruslan Чому це має величезні накладні витрати? Перемикання режимів на контекстному комутаторі коштує не багато (якщо що, я не знаю x86 на низькому рівні досить добре). Ядро залишається 32-бітним: 32-розрядні віртуальні адреси для відображення ядра, використання 32-бітного набору інструкцій.
Жил 'ТАК - перестань бути злим'

1
Ядро повинно підтримувати деякі 64-бітові структури даних для підтримки 64-бітових додатків, принаймні 64-бітових таблиць сторінок. Це робить його насправді не 32-бітним ядром. Я не намагався заглиблюватися в арку amd64, але думаю, що відключення 64-бітної підтримки матиме значні витрати на відміну від використання спеціально розробленого режиму сумісності.
Руслан

1
@Ruslan Тільки 64-бітні обізнані таблиці сторінок і дуже потрібні, і це невелика вартість. Усього іншого можна уникнути за допомогою правильної конструкції ядра. Я ніколи не копався в ядро ​​Solaris, я вважаю, що вони зробили його досить гнучким (вони мали попередній досвід роботи з SPARC64).
Жил "ТАК - перестань бути злим"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.