Làm thế nào để OSX chạy Binaries 64 bit trong khi chạy trên kernel 32 bit?


6

Gần đây tôi đã phát hiện ra rằng Mac OS X thực sự CÓ THỂ chạy các ứng dụng 64 bit (x64) ngay cả khi hạt nhân x86 được tải. Điều đó đã gây sốc cho tôi lần đầu tiên.

Nhưng sau đó tôi đã nhận ra rằng điều đó thực sự kỳ lạ nếu hệ thống hoạt động và chạy dưới CPU tương thích x64 không thể chạy các ứng dụng x64, bất kể kernel nào quản lý các tiến trình. Có thực sự khó khăn như vậy? Chỉ cần tải ứng dụng chết tiệt vào bộ nhớ và thiết lập con trỏ hoạt động CPU đến byte đầu tiên, dễ như ăn bánh!

Rào cản duy nhất và duy nhất để làm điều đó, như tôi có thể tưởng tượng, là một loại "tiêu đề thực thi". Thật không may, tôi không thoải mái lắm với kiến ​​trúc Windows và cấu trúc nhị phân, vì vậy tôi cần giải thích thêm ở đây.

Trên thực tế, ELF64 tiêu chuẩn nhị phân hệ điều hành giống như UNIX có ELF64, mà (như tài liệu ở đây mô tả) không có nhiều khác biệt với ELF32, nhưng ngay cả khi các hạt nhân 32 bit không thể chạy mã x64. Có, chương trình này có khả năng được liên kết với các thư viện x64 và hãy tưởng tượng chúng ta vừa sao chép và dán chúng vào thư mục / usr / lib64. Nhưng tôi khá chắc chắn rằng điều đó không có ích, tại sao?

Và cuối cùng, nhân Mac OS X có gì đặc biệt để nó không lo lắng về tập lệnh của chương trình được sử dụng? Mac OS X có một số phổ biến và phù hợp cho cả hai tiêu đề thực thi của hạt nhân, vì vậy nó chỉ có thể tải ứng dụng vào bộ nhớ và nói với CPU "thực thi ngay từ đây, tôi không bận tâm điều gì"?

PS: Tôi thực sự đã suy nghĩ nhiều về việc đặt câu hỏi này ở đâu: trên stackoverflow.com hoặc superuser.com, và quyết định đặt ở đây, bởi vì chủ đề có thể là vấn đề cụ thể hơn về hệ điều hành.


Điều gì khiến bạn nghĩ OSX sẽ chạy nhị phân 64 bit trong khi chạy trên nhân Darwin 32 bit? Bạn đã thấy gì?
James T Snell

Vì tôi khá chắc chắn rằng tôi đang chạy kernel x64 nên phần mềm duy nhất tôi đã cài đặt là x64 và OS chạy chúng hoàn toàn tốt. Nhưng một lúc trước, tôi đã gõ 'uname -a' trong Terminal của mình và rất ngạc nhiên. Ngoài ra, Wikipedia xác nhận điều này - vi.wikipedia.org/wiki/X86-64#Mac_OS_X
pechenie

Wikipedia và bạn có thể bị nhầm lẫn. Chạy HĐH 64 bit không có nghĩa là tất cả các nhị phân của bạn là 32 bit. Nó có nghĩa là kiến ​​trúc hạt nhân và phần cứng của bạn có thể hỗ trợ nhị phân 64 bit. Uname của bạn -a trở về là gì?
James T Snell

Ngoài ra, tôi không hiểu tiêu đề câu hỏi của bạn. Bạn có thể vui lòng diễn đạt lại nó?
James T Snell

Đó không phải là một sai lầm, bạn có thể thử nó nếu bạn có thể. Tôi đã chạy kernel x86, không phải x64, vì vậy nó vẫn có thể chạy phần mềm x64. Bây giờ tôi đã chuyển sang kiến ​​trúc x64_86, nhưng đầu ra của nhân uname -adưới x86 có thể giống như thế: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
pechenie

Câu trả lời:


5

Câu hỏi thực sự là tại sao một số hệ điều hành khác không thể chạy nhị phân 64 bit trên kernel 32 bit. Không có lý do cơ bản tại sao nó sẽ không thể. Kiến trúc bộ xử lý cơ bản hỗ trợ cả tập lệnh 64 bit (amd64 aka x86-64) và tập lệnh 32 bit (i386) và không có hạn chế nào về hai được sử dụng cùng nhau (đặc biệt, không có Chế độ 64-bit của Nhật Bản, tách biệt với chế độ 32-bit, một chế độ dài duy nhất , cho phép các hướng dẫn từ cả i386 và bộ bản gốc amd64.

Chạy các ứng dụng 64 bit trên kernel 32 bit đòi hỏi một chút công việc bên trong kernel, bởi vì nó phải quản lý các con trỏ 64 bit đến không gian người dùng cùng với các con trỏ 32 bit vào không gian kernel. Hầu hết nếu không phải tất cả các con trỏ được truyền xung quanh trong kernel đều được biết là không gian kernel hoặc được biết là không gian người dùng, vì vậy nó không phải là vấn đề nếu chúng có kích thước khác nhau. Khó khăn chính là đã đề cập đến khả năng có một loại con trỏ phổ quát có các phạm vi giá trị riêng biệt cho bộ nhớ xử lý, bộ nhớ kernel và bộ nhớ được sử dụng bởi các phần cứng khác nhau (bao gồm RAM), nhưng điều này không thể có trong các hạt nhân 32 bit gần đây dù sao trên phần cứng lớp PC (nếu bạn có 4GB RAM trở lên hoặc muốn ánh xạ 2GB RAM cộng với 2GB không gian xử lý cộng với bộ nhớ kernel và hơn thế nữa, bạn cần có khả năng ánh xạ hơn 32 bit '

Theo bài viết trên Wikipedia mà bạn trích dẫn, OSX có khả năng chạy các quy trình amd64 trên bộ xử lý amd64 trước khi nó có kernel 64 bit. Solaris cũng vô tình trộn lẫn các tệp thực thi i386 và amd64 trên bộ xử lý amd64, bất kể kernel là 32 bit hay 64 bit (cả hai đều có sẵn).

Các hệ điều hành khác có thể chạy các quy trình i386 trên kernel (64 bit), nhưng không xử lý amd64 trên kernel 32 bit, ví dụ Linux, FreeBSD, NetBSD và Windows. Tuy nhiên, các hệ điều hành khác coi amd64 và i386 là các kiến ​​trúc hoàn toàn khác nhau, ví dụ OpenBSD.


Con trỏ AIUI không phải là vấn đề trong OS X vì dù sao chúng cũng không được chuyển giữa kernel và không gian người dùng. Ngay cả với quy trình 32 bit chạy dưới nhân 32 bit, quy trình có thể có tới 4GB dung lượng bộ nhớ ảo được xác định và hạt nhân cũng có thể có tối đa 4GB và hai không trùng nhau. Nếu bạn chuyển một con trỏ từ không gian người dùng đến kernel, điều đó sẽ vô nghĩa vì có gì đó hoàn toàn khác ở địa chỉ đó trong không gian kernel.
Gordon Davisson

Nếu bạn nhìn vào mã nguồn, bạn có thể thấy nó được thực hiện như thế nào. Trên OS X 32 bit, kernel không được ánh xạ vào không gian địa chỉ người dùng nên cả hai đều có không gian địa chỉ 32 bit hoàn toàn riêng biệt. Bất kỳ dữ liệu nào được chuyển qua đều được sao chép hoặc ánh xạ lại. Hình phạt là TLB cache bỏ lỡ.
Nga

Câu hỏi đặt ra là làm thế nào CPU có thể lưu trữ ngữ cảnh khi chế độ 32 bit không thể truy cập vào 64 bit hàng đầu cũng như 8 thanh ghi cao?
phuclv

1
@ LưuViênPhúc Bạn cần một chút mã 64 bit, chỉ để lưu và khôi phục các thanh ghi. Theo như tôi biết thì có thể có trên x86-64 (và đó là cách mà Solaris làm điều đó). Đây thực sự sẽ là một vấn đề khi bạn không thể trộn các hướng dẫn 64 bit và 32 bit mà không có thay đổi đặc quyền.
Gilles

4

Tôi không đủ quen thuộc với kiến ​​trúc x86_64 để cung cấp chi tiết, nhưng về cơ bản, điều xảy ra là CPU được chuyển đổi giữa chế độ 64 bit và chế độ tương thích (32 bit) như một phần của chuyển đổi ngữ cảnh giữa kernel và không gian người dùng chương trình. Điều này khá giống với những gì đã được thực hiện để chạy chương trình 32 bit dưới nhân 64 bit, chỉ xảy ra ngược lại.

BTW, OS X không sử dụng định dạng nhị phân ELF, nó sử dụng nhị phân Mach-O . Định dạng Mach-O cho phép các nhị phân đa kiến ​​trúc ("phổ quát"), vì vậy các chương trình (và đối với vấn đề đó là kernel) có thể được cung cấp trong cả 32 và 64 bit (và PPC và PPC64 và ...), và HĐH có thể chọn phiên bản nào để tải (và do đó sẽ chạy chế độ nào) tại thời điểm tải. Bạn có thể sử dụng filelệnh trên tệp nhị phân để xem định dạng của nó. Ví dụ: đây là ứng dụng Cờ vua được cung cấp với OS X v10.5:

$ file Applications/Chess.app/Contents/MacOS/Chess 
Applications/Chess.app/Contents/MacOS/Chess: Mach-O universal binary with 4 architectures
Applications/Chess.app/Contents/MacOS/Chess (for architecture ppc): Mach-O executable ppc
Applications/Chess.app/Contents/MacOS/Chess (for architecture ppc64):   Mach-O 64-bit executable ppc64
Applications/Chess.app/Contents/MacOS/Chess (for architecture i386):    Mach-O executable i386
Applications/Chess.app/Contents/MacOS/Chess (for architecture x86_64):  Mach-O 64-bit executable x86_64

Và một lưu ý cho những người nghi ngờ rằng điều này là có thể: OS X hỗ trợ các chương trình 64 bit bắt đầu từ v10.4 (với hỗ trợ API hạn chế), nhưng không bao gồm kernel 64 bit cho đến v10.6 (và thậm chí sau đó, kernel chạy ở chế độ 32 bit theo mặc định trên hầu hết các kiểu máy). Xem hướng dẫn chuyển đổi 64 bit của Apple để biết chi tiết. Tôi đang đăng bài này từ MacBook Pro chạy 10.6 với kernel 32 bit (64 bit không được hỗ trợ cho model cụ thể này), nhưng theo Activity Monitor, quá trình duy nhất không chạy ở chế độ 64 bit là kernel_task.


4

Máy Mac hỗ trợ chạy các ứng dụng 64 bit trên kernel 32 bit vì kế hoạch nhiều giai đoạn để thực hiện chính xác điều đó:

  1. Các ứng dụng Mac vận chuyển dưới dạng "nhị phân chất béo" trong "gói" cho phép cả bốn combo 64/32-bit và Intel / PPC là một phần của một bản cài đặt, có thể đơn giản chỉ bằng một lần kéo và thả. HĐH chạy một cái thích hợp.
  2. Máy Mac sử dụng PAE để truy cập hơn 4GB RAM khi chạy kernel 32 bit. Windows không cho phép PAE trên các phiên bản không phải Máy chủ vì các vấn đề tương thích với trình điều khiển, chúng có nhiều hơn, bao gồm cả các bên thứ ba.
  3. Tiger thêm ABI 64 bit (Giao diện nhị phân ứng dụng) để chạy mã 64 bit trên hạt nhân 32 bit và phiên bản 64 bit của API cấp thấp (Giao diện lập trình ứng dụng) cho "bảng điều khiển" (không phải GUI) ứng dụng.
  4. Leopard bổ sung Cacao 64 bit cho các ứng dụng GUI (nhưng không phải Carbon 64 bit).
  5. Snow Leopard bổ sung kernel 64 bit, mặc định chỉ trên một số model cao cấp nhất định.
  6. Lion yêu cầu CPU 64 bit, nhưng vẫn bao gồm kernel 32 bit. Ví dụ, một máy Mac cũ có CPU 64 bit nhưng GPU chỉ có trình điều khiển 32 bit sẽ phải chạy kernel 32 bit.

Vì vậy, OS X đã hỗ trợ các ứng dụng 64 bit càng sớm càng tốt và tiếp tục chạy kernel 32 bit càng lâu càng tốt vì tình trạng trình điều khiển. (Số bit của hạt nhân chỉ trở thành một yếu tố khi thử quản lý lượng RAM lớn - các bảng trang cũng mất bộ nhớ - và chuyển sang nhân 64 bit mang lại một số lợi ích về hiệu suất.) Nhưng Apple chắc chắn không ngại bỏ việc đồ đạc.

Câu hỏi thực sự sau đó là tại sao Windows và Linux không làm điều tương tự. Đối với Windows, hãy xem xét rằng nỗ lực đầu tiên của họ tại Win64 là với Itanium, điều này hoàn toàn khác. Nhưng câu trả lời cuối cùng có thể làm sôi sục những gì nó thường có trong vài thập kỷ qua: khả năng tương thích với một loạt các chương trình của bên thứ ba không thực hiện đúng cách :

Việc triển khai 64 bit của OS X khác biệt đáng kể so với Windows, xử lý các phiên bản 32 bit và 64 bit của nó như hai hệ điều hành riêng biệt được lưu trữ trên các phương tiện cài đặt khác nhau. Điều này được thực hiện chủ yếu để duy trì khả năng tương thích của Windows với các ứng dụng cũ - di chuyển hoặc đổi tên những thứ như thư mục System32 sẽ phá vỡ các chương trình dự kiến ​​sẽ có ở đó - và kết quả là cả hai bị tách ra đến mức thậm chí không có bản nâng cấp đường dẫn giữa Windows 32 bit và Windows 64 bit. Do đó, và vì các ứng dụng và trình điều khiển Windows thường có các phiên bản 32 bit và 64 bit riêng biệt, quá trình chuyển đổi sang 64 bit của Windows đã trở nên nhẹ hơn và người dùng có thể thấy rõ hơn một chút.

Có rất nhiều thông tin cơ bản về quá trình chuyển đổi 64 bit ở cả phía Mac và phía Windows . (Các liên kết này nằm ở phần cuối của mỗi loạt bài viết; hãy chắc chắn quay lại phần đầu của mỗi bài viết.)

Tôi không biết câu chuyện với Linux là gì, nhưng hãy tưởng tượng Linus có ý kiến ​​mạnh mẽ về nó.


1
Từ phía Linux: hạt nhân hỗ trợ cả kiến ​​trúc 32 bit và 64 bit trước khi amd64 tồn tại. Chạy các quy trình 64 bit trên kernel 32 bit sẽ yêu cầu một số kỹ thuật lại, ít nhất là trong các phần phụ thuộc vào kiến ​​trúc của mã. Đã đủ để chạy các nhị phân i386 trên kernel amd64, nhưng không phải là mặt khác (phức tạp hơn), bởi vì không có trường hợp sử dụng nào thực sự thúc đẩy cho hướng đó (nếu bạn muốn chạy các tiến trình 64 bit, không có lý do gì để không chạy Nhân 64 bit).
Gilles

Cảm ơn bạn rất nhiều vì lời giải thích của bạn, tôi chưa thể nâng cao (chưa đủ danh tiếng) và tôi cũng không thể chấp nhận hai câu trả lời, nhưng cả bạn và Gilles đều nói rõ hơn với tôi một chút!
pechenie

0

Tôi đã nhận ra rằng thật kỳ lạ nếu hệ thống hoạt động và chạy dưới CPU tương thích x64 không thể chạy các ứng dụng x64, bất kể hạt nhân nào quản lý các tiến trình. Có thực sự khó khăn như vậy? Chỉ cần tải ứng dụng chết tiệt vào bộ nhớ và thiết lập con trỏ hoạt động CPU đến byte đầu tiên, dễ như ăn bánh!

Bạn đang thiếu một phần quan trọng. Ứng dụng thực hiện lệnh gọi API đến các chức năng và dịch vụ do hệ điều hành cung cấp. Nếu một ứng dụng 64 bit gửi con trỏ 64 bit đến hệ điều hành 32 bit, mọi thứ sẽ nổ tung.

Tôi nghi ngờ rằng để làm cho mọi thứ hoạt động có thể chấp nhận được, dù sao đi nữa, HĐH phải quá tải chức năng và cung cấp cả phiên bản 64 bit và 32 bit của mỗi chức năng. Đối với mỗi hạt nhân, chức năng "tắt" (chức năng 64 bit trên hạt nhân 32 bit, chức năng 32 bit trên hạt nhân 64 bit) sẽ chỉ là một sơ khai chuyển cuộc gọi thành an toàn 32 bit và sau đó gọi lại chức năng gốc.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.