64-bitowe jądro, ale wszystkie 32-bitowe uruchomione procesy ELF, jak to jest?

9

Dane wyjściowe z 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

Jednak /sbin/initplik wykonywalny jest wyświetlany jako 32-bitowy:

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

Inne aspekty systemu również wydają się zaprzeczać:

root@debian:~ # echo $HOSTTYPE
i486

root@debian:~ # getconf LONG_BIT
32
kiiwii
źródło

Odpowiedzi:

13

Jądro 64-bitowe można zainstalować w systemie Debian 32bit. Możesz zobaczyć, że jądro amd64 jest dostępne dla 32-bitowego Debiana na stronie pakietu . Może to być wykorzystane jako alternatywa dla użycia jądra obsługującego PAE do obsługi ponad 4G całkowitej pamięci RAM. Pamiętaj, że 32-bitowe pliki binarne nadal nie mogą uzyskać dostępu do więcej niż około 3G pamięci RAM na proces.

Jordan
źródło
dzięki! twoje odpowiedzi są jasne jak kryształowa kula ~: D Nigdy nie zauważyłem, że Debian tak traktuje pakiet jądra.
kiiwii
1
To nieprawda: 32-bitowe programy mogą korzystać z całego 4Gio wirtualnej przestrzeni adresowej, gdy działają na 64-bitowym jądrze (chyba że działają z osobowością ADDR_LIMIT_3GB).
ysdx
@ysdx Tak więc ograniczenie do 2 GB jest specyficzne dla systemu Windows, a adresy powyżej 0x80000000 będą dozwolone w 32-bitowej przestrzeni użytkownika?
Paul Stelian,
1
@PaulStelian, W 32-bitowym systemie Windows domyślnie jesteś ograniczony do najniższych 2 GB pamięci wirtualnej w celu zachowania kompatybilności retro (myślę, że niektóre programy rezerwują wskaźniki na najwyższe 2 GB pamięci wirtualnej specjalnego przeznaczenia). Możesz ustawić flagę LARGEADDRESSAWARE w pliku wykonywalnym ( docs.microsoft.com/fr-fr/cpp/build/reference/… ), aby wyrazić zgodę na uzyskiwanie dostępu do całej 4 GB pamięci wirtualnej.
ysdx
15

Wszystkie procesory obsługujące zestaw instrukcji x64 (znany również jako x86_64 lub amd64) obsługują również zestaw instrukcji x86 (znany również jako i386 lub i686, które są ściśle określonymi wersjami x86). To samo dotyczy ARM A64 (nowy 64-bitowy zestaw instrukcji pojawiający się w ARMv8) i A32 (nazwa „klasycznego” 32-bitowego zestawu instrukcji), dla SPARC64 i SPARC , i wierzę w MIPS64 i MIPS . Tak więc we wszystkich tych rodzinach architektury, jeśli procesor może uruchamiać kod 64-bitowy, może również uruchamiać kod 32-bitowy.

Jądro Linux obsługuje uruchamianie 32-bitowego kodu użytkownika z 64-bitowym jądrem (myślę, że we wszystkich wyżej wymienionych rodzinach architektur). Jądro musi być jednorodne (wszystkie 64-bitowe lub wszystkie 32-bitowe), a każdy proces musi być jednorodny, ale możesz mieć mieszankę 32-bitowych i 64-bitowych procesów na 64-bitowym jądrze. Odwrotna sytuacja nie jest możliwa: w przypadku jądra 32-bitowego nie można uruchamiać procesów 64-bitowych.

Jest to wybór projektowy w systemie Linux, motywowany chęcią uruchomienia istniejących 32-bitowych plików binarnych w 64-bitowych instalacjach. Inne warianty Uniksa dokonały różnych wyborów: Solaris może uruchamiać programy 64-bitowe na jądrze 32-bitowym, a także odwrotnie, podczas gdy OpenBSD nie może uruchamiać programów 32-bitowych na jądrze 64-bitowym.

Możesz uzyskać informacje o procesorze w /proc/cpuinfo. Jeśli twój procesor x86 ma lmflagę, jest to procesor 64-bitowy.

Domyślnie uname -mlub archpokazuje architekturę, dla której jądro zostało skompilowane. Linux może ustawić „osobowość” procesu (z personality) wywołaniem systemowym. Za pomocą polecenia możesz uruchomić podproces w innej osobowości setarch; setarch i686 someprogramlub linux32 someprogramuruchamia określony program w środowisku, w którym uname -mzwraca i686, setarch amd64 someprogramlub linux64 someprogramuruchamia określony program w środowisku, w którym uname -mzwraca amd64.

file /sbin/initmówi dla jakiej architektury initjest skompilowany program. Chociaż możliwe jest mieszanie 32-bitowych i 64-bitowych plików wykonywalnych w instalacji, zwykle wszystkie podstawowe programy systemu operacyjnego mają tę samą architekturę, ponieważ jest o wiele łatwiejsze do zarządzania.

$HOSTYPEjest zmienną bash i mówi, dla jakiej architektury bashzostał skompilowany program.

getconf LONG_BITinformuje, czy domyślny kompilator C jest skonfigurowany do kompilacji programów 32-bitowych czy 64-bitowych. Bardziej precyzyjnym testem jest skompilowanie i uruchomienie programu, który drukuje sizeof(void*)lub sizeof(size_t)- wywołanie getconfmoże dostarczyć tylko informacji o tym, co getconfuważa za domyślny kompilator.

Gilles „SO- przestań być zły”
źródło
1
Rzeczywiście, czy 32-bitowy system Solaris przełącza się na tryb 64-bitowy, aby przejść do procesu 64-bitowego, a następnie z powrotem? To musi mieć ogromny narzut i po prostu nie ma sensu, ponieważ wtedy jądro jest w rzeczywistości 64-bitowe.
Ruslan
1
@ Ruslan Dlaczego miałoby to ogromne koszty ogólne? Przełączanie trybów na przełączniku kontekstu nie kosztuje dużo (jeśli już, nie znam wystarczająco dobrze x86 na niskim poziomie). Jądro pozostaje 32-bitowe: 32-bitowe adresy wirtualne dla mapowań jądra, użycie 32-bitowego zestawu instrukcji.
Gilles „SO- przestań być zły”
1
Jądro musi utrzymywać niektóre struktury danych specyficzne dla 64-bitów, aby obsługiwać 64-bitowe aplikacje, co najmniej 64-bitowe tabele stron. To sprawia, że ​​tak naprawdę nie jest to 32-bitowe jądro. Nie próbowałem naprawdę zagłębiać się w architekturę amd64, ale myślę, że wyłączenie obsługi 64-bitowej spowoduje znaczne obciążenie w przeciwieństwie do używania specjalnie zaprojektowanego trybu zgodności.
Ruslan
1
@Ruslan Tylko 64-bitowe tabele stron ze świadomością i naprawdę konieczne, a to niewielki koszt. Wszystkich innych można uniknąć dzięki właściwemu projektowi jądra. Nigdy nie kopałem w jądrze Solaris, przypuszczam, że zorganizowali go tak, aby był wystarczająco elastyczny (wcześniej mieli doświadczenie z SPARC64).
Gilles „SO- przestań być zły”