Niedawno zorientowałem się, że Mac OS X faktycznie może uruchamiać aplikacje 64-bitowe (x64), nawet jeśli jądro x86 jest załadowane. To było dla mnie szokujące po raz pierwszy.
Ale potem zdałem sobie sprawę, że to naprawdę dziwne, jeśli system działa pod procesorem kompatybilnym z x64, nie może uruchamiać aplikacji x64, bez względu na to, jakie jądro zarządza procesami. Czy to naprawdę takie trudne? Wystarczy załadować tę cholerną aplikację do pamięci i ustawić wskaźnik działania procesora na pierwszy bajt, to proste!
Jedyną barierą, jaką można to zrobić, jak mogłem sobie wyobrazić, są jakieś „nagłówki wykonywalne”. Niestety nie czuję się dobrze z architekturą Windows i strukturą binarną, dlatego potrzebuję więcej wyjaśnień tutaj.
De facto UNIXopodobnych binarny standardowy nagłówek ELF ma to brat ELF64, który (jako dokument tutaj opisano) nie ma wiele różnic z Elf32, ale mimo jądra 32-bitowe nie są w stanie uruchomić kod x64. Tak, ten program jest prawdopodobnie powiązany z bibliotekami x64 i pozwala sobie wyobrazić, że właśnie skopiowaliśmy i wkleiliśmy je bezpośrednio do folderu / usr / lib64. Ale jestem pewien, że to nie pomaga, dlaczego?
I wreszcie, co jest takiego specjalnego w jądrze Mac OS X, aby nie martwiło się o zestaw instrukcji programu? Czy Mac OS X ma jakiś uniwersalny i odpowiedni dla nagłówka plików wykonywalnych obu jąder, więc może po prostu załadować aplikację do pamięci i powiedzieć procesorowi „wykonać od razu, nie mam nic przeciwko temu”.
PS: Naprawdę zastanawiałem się, gdzie umieścić to pytanie: na stackoverflow.com lub superuser.com, i postanowiłem umieścić tutaj, ponieważ temat jest prawdopodobnie bardziej specyficzny dla systemu operacyjnego.
uname -a
jądra pod x86 prawdopodobnie wyglądały mniej więcej tak:Darwin MacMini.local 11.1.0 Darwin Kernel Version 11.1.0: Tue Jul 26 16:07:11 PDT 2011; root:xnu-1699.22.81~1/RELEASE_i386 i386
Odpowiedzi:
Prawdziwe pytanie brzmi: dlaczego niektóre inne systemy operacyjne nie mogą uruchamiać 64-bitowych plików binarnych w 32-bitowym jądrze. Nie ma podstawowego powodu, dla którego nie byłoby to możliwe. Podstawowa architektura procesorów obsługuje zarówno 64-bitowy zestaw instrukcji (amd64 aka x86-64), jak i 32-bitowy zestaw instrukcji (i386), i nie ma ograniczeń co do ich używania (w szczególności nie ma „Tryb 64-bitowy”, który jest niezależny od „trybu 32-bitowego”; istnieje jeden długi tryb , który pozwala na instrukcje zarówno z i386, jak i „natywnego” zestawu amd64).
Uruchamianie 64-bitowych aplikacji w 32-bitowym jądrze wymaga nieco więcej pracy wewnątrz jądra, ponieważ musi zarządzać 64-bitowymi wskaźnikami do przestrzeni użytkownika wraz z 32-bitowymi wskaźnikami do przestrzeni jądra. Większość, jeśli nie wszystkie wskaźniki przekazywane w jądrze są albo znane z przestrzeni jądra, albo z przestrzeni użytkownika, więc nie ma problemu, jeśli mają inny rozmiar. Główną trudnością jest rezygnacja z możliwości posiadania uniwersalnego typu wskaźnika, który ma osobne zakresy wartości dla pamięci procesu, pamięci jądra i pamięci używanej przez różne elementy sprzętu (w tym RAM), ale nie jest to możliwe w najnowszych 32-bitowych jądrach w każdym razie na sprzęcie klasy PC (jeśli masz 4 GB lub więcej pamięci RAM lub chcesz zmapować 2 GB pamięci RAM plus 2 GB przestrzeni procesowej plus pamięć jądra i więcej, musisz mieć możliwość mapowania ponad 32 bitów)
Zgodnie z cytowanym artykułem z Wikipedii OSX miał możliwość uruchamiania procesów amd64 na procesorach amd64, zanim miał 64-bitowe jądro. Solaris również obojętnie miesza pliki wykonywalne i386 i amd64 na procesorach amd64, niezależnie od tego, czy jądro jest 32-bitowe czy 64-bitowe (oba są dostępne).
Inne systemy operacyjne mogą uruchamiać procesy i386 na (64-bitowym) jądrze amd64, ale nie procesy amd64 na 32-bitowym jądrze, na przykład Linux, FreeBSD, NetBSD i Windows. Jeszcze inne systemy operacyjne traktują amd64 i i386 jako zupełnie różne architektury, na przykład OpenBSD.
źródło
Nie jestem wystarczająco zaznajomiony z architekturą x86_64, aby podać szczegóły, ale zasadniczo dzieje się tak, że procesor jest przełączany między trybem 64-bitowym a trybem zgodności (32-bitowym) w ramach przełączania kontekstu między jądrem a przestrzenią użytkownika program. Jest to prawie to samo, co można zrobić, aby uruchomić 32-bitowy program pod 64-bitowym jądrem, po prostu odwrotnie.
BTW, OS X nie używa formatu binarnego ELF, używa plików binarnych Mach-O . Format Mach-O pozwala na wielowątkowe („uniwersalne”) pliki binarne, więc programy (i w tym przypadku jądro) mogą być dostarczane zarówno w wersji 32-, jak i 64-bitowej (oraz PPC i PPC64 i ...), a system operacyjny może wybierz, która wersja ma zostać załadowana (a więc i w jakim trybie ją uruchomić) w czasie ładowania. Możesz użyć
file
polecenia w pliku binarnym, aby zobaczyć, w jakim formacie (-ach) jest on. Na przykład, oto aplikacja Chess dostarczana z systemem OS X 10.5:I uwaga dla tych, którzy wątpią, że jest to możliwe: OS X obsługiwał 64-bitowe programy od wersji 10.4 (z ograniczoną obsługą API), ale nie zawierał 64-bitowego jądra aż do wersji 10.6 (a nawet wtedy jądro działało domyślnie w trybie 32-bitowym w większości modeli). Aby uzyskać szczegółowe informacje, zobacz 64-bitowy przewodnik Apple . Wysyłam to z MacBooka Pro z systemem 10.6 z 32-bitowym jądrem (64-bit nie jest obsługiwany w tym konkretnym modelu), ale według Monitora aktywności jedynym procesem, który nie działa w trybie 64-bitowym, jest kernel_task.
źródło
Komputery Mac obsługują uruchamianie 64-bitowych aplikacji na 32-bitowym jądrze, ponieważ plan wieloetapowy to dokładnie zrobić:
Tak więc OS X obsługiwał 64-bitowe aplikacje tak szybko, jak to możliwe, i nadal uruchamiał jądro 32-bitowe tak długo, jak to możliwe, ze względu na sytuację sterownika. (Ziarnistość jądra staje się czynnikiem tylko podczas próby zarządzania ogromnymi ilościami pamięci RAM - tabele stron również zajmują pamięć - i przejście na 64-bitowe jądro oferuje pewne korzyści związane z wydajnością.) Ale Apple z pewnością nie wstydzi się upuszczać rzeczy.
Prawdziwe pytanie brzmi zatem, dlaczego systemy Windows i Linux nie zrobiły tego samego. W przypadku systemu Windows weź pod uwagę, że ich pierwsza próba Win64 była z Itanium, co było zupełnie inne. Ale ostateczna odpowiedź może sprowadzać się do tego, co zwykle ma przez kilka ostatnich dziesięcioleci: kompatybilności z wieloma programami stron trzecich, które nie działały właściwie :
Istnieje wiele informacji w tle na temat przejścia 64-bitowego zarówno po stronie Maca, jak i Windowsa . (Te linki są na końcu każdej serii artykułów; pamiętaj, aby wrócić na początek każdego z nich).
Nie wiem, jaka była ta historia z Linuksem, ale wyobraź sobie, że Linus miał na jej temat mocne zdanie.
źródło
Brakuje ważnej części. Aplikacje wykonują wywołania API do funkcji i usług udostępnianych przez system operacyjny. Jeśli aplikacja 64-bitowa wysyła wskaźnik 64-bitowy do 32-bitowego systemu operacyjnego, wszystko powinno się wysadzić.
Podejrzewam, że aby wszystko działało akceptowalnie w obu przypadkach, system operacyjny musi przeciążać funkcję i zapewniać wersję 64-bitową i 32-bitową każdej funkcji. Dla każdego jądra funkcja „off” (funkcja 64-bitowa w jądrach 32-bitowych, funkcja 32-bitowa w jądrach 64-bitowych) będzie tylko kodem pośredniczącym, który tłumaczy połączenie jako bezpieczne dla 32-bitów, a następnie ponownie wywołuje funkcję natywną.
źródło