Почему 32-битное ядро может запускать 64-битный двоичный файл?
В моем ящике OS X ядро представляет собой 32-битный двоичный файл, и все же он может запускать 64-битный двоичный файл.
Как это работает?
cristi:~ diciu$ file ./a.out
./a.out: Mach-O 64-bit executable x86_64
cristi:~ diciu$ file /mach_kernel
/mach_kernel: Mach-O universal binary with 2 architectures
/mach_kernel (for architecture i386): Mach-O executable i386
/mach_kernel (for architecture ppc): Mach-O executable ppc
cristi:~ diciu$ ./a.out
cristi:~ diciu$ echo $?
1
Ответы
Ответ 1
Процессор может быть переключен с 64-битного режима выполнения на 32 бит, когда он ловушки в контексте ядра, и 32-битное ядро все еще может быть сконструировано для понимания структур, переданных из 64-разрядных приложений для пользовательского пространства.
Ядро MacOS X в любом случае не направляет указатели на разметку из пользовательского приложения, так как оно имеет собственное отдельное адресное пространство. Например, указатель пользовательского пространства в вызове ioctl должен быть сначала разрешен к его физическому адресу, а затем новый виртуальный адрес, созданный в адресном пространстве ядра. На самом деле не имеет значения, был ли этот указатель в ioctl 64 бит или 32 бита, ядро не разыскивает его напрямую в обоих случаях.
Итак, смешивание 32-битного ядра и 64-битных двоичных файлов может работать, и наоборот. То, что вы не можете сделать, это смешивать 32-битные библиотеки с 64-разрядным приложением, поскольку указатели, проходящие между ними, будут усечены. MacOS X поставляет больше своих фреймворков как в 32, так и в 64-разрядных версиях в каждой версии.
Ответ 2
Это не ядро, которое запускает двоичный файл. Это процессор.
Двоичный вызов вызывает библиотечные функции, и они должны быть 64 бит. И если им нужно сделать системный вызов, то их ответственность - справиться с тем, что они сами 64-битные, но ядро всего 32.
Но это не то, о чем вам придется беспокоиться.
Ответ 3
Обратите внимание, что не все 32-разрядные ядра способны запускать 64-битные процессы. У Windows, конечно же, нет этого свойства, и я никогда не видел этого в Linux.
Ответ 4
32-битное ядро, способное загружать и запускать 64-битные двоичные файлы, должно иметь некоторый 64-разрядный код для обработки карт памяти, загрузки программ и нескольких других 64-разрядных проблем.
Однако планировщику и многим другим операциям ОС не требуется работать в режиме 64 бит, чтобы справляться с другими проблемами - он переключает процессор в режим 32 бит и обратно по мере необходимости для обработки драйверов, задач, памяти распределение и отображение, прерывания и т.д.
Фактически, большинство вещей, которые делает ОС, не обязательно будут выполнять более быстрый запуск на 64 бита - ОС не является тяжелым процессором данных, а те части, которые являются (потоки, дисковый ввод-вывод и т.д.), скорее всего, преобразуются в 64 бит (плагины для ОС в любом случае).
Но само оголенное ядро, скорее всего, не будет переключать задачу быстрее и т.д., если оно было 64 бит.
Это особенно характерно, когда большинство людей по-прежнему работают с 32-разрядными приложениями, поэтому переключение режимов не всегда необходимо, даже если это небольшая служебная операция, это занимает некоторое время.
-Adam
Ответ 5
Файл ELF32 может содержать 64-битные инструкции и работать в режиме 64 бит. Единственное, что у него есть, это то, что организация заголовков и символов в 32-битном формате. Смещения таблиц символов - 32 бита. Записи таблицы символов имеют ширину в 32 бита и т.д. Файл, содержащий как 64-битный код, так и 32-битный код, может выставлять себя как 32-битный файл ELF, где он использует 64-битные регистры для своих внутренних вычислений. mach_kernel - один из таких исполняемых файлов. Преимущество в том, что 32-битные ELF-драйверы могут быть связаны с ним. Если он позаботится о прохождении указателей, расположенных ниже 4 ГБ, в другие связанные бинарные файлы ELF, он будет работать нормально.
Ответ 6
Для того чтобы ядро было 64-битным, было бы эффективно использовать только то, что расширения ядра (т.е. обычно драйверы) могут быть 64-битными. На самом деле вам нужно иметь либо все 64-битные расширения ядра, либо (как сейчас) все 32-битные; они должны быть родными для архитектуры запущенного ядра.