Kernel 64-bit, tetapi semua proses menjalankan ELF 32-bit yang dapat dijalankan, bagaimana ini?

9

Output dari 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

Namun /sbin/initexecutable muncul sebagai 32-bit:

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

Aspek-aspek lain dari sistem tampaknya juga bertentangan dengan hal-hal:

root@debian:~ # echo $HOSTTYPE
i486

root@debian:~ # getconf LONG_BIT
32
kiiwii
sumber

Jawaban:

13

Kernel 64bit dapat diinstal pada Debian 32bit. Anda dapat melihat bahwa kernel amd64 tersedia untuk Debian 32bit pada halaman paketnya . Ini dapat digunakan sebagai alternatif untuk menggunakan kernel yang diaktifkan PAE untuk mendukung lebih dari 4G total RAM. Perhatikan bahwa binari 32bit masih tidak dapat mengakses lebih dari sekitar 3G RAM per proses.

jordanm
sumber
Terima kasih! jawaban Anda sejelas bola kristal ~: D Tidak pernah memperhatikan Debian memperlakukan paket kernel seperti ini sebelumnya.
kiiwii
1
Itu tidak benar: program 32 bit dapat menggunakan seluruh 4Gio dari ruang alamat virtual mereka ketika berjalan pada kernel 64-bit (kecuali jika mereka berjalan dengan kepribadian ADDR_LIMIT_3GB).
ysdx
@ysdx Jadi membatasi untuk 2GB adalah hal khusus Windows dan alamat di atas 0x80000000 akan diizinkan dalam ruang pengguna 32-bit?
Paul Stelian
1
@ PaulStelian, Pada Windows 32 bit, Anda secara default terbatas pada memori virtual 2GB terendah untuk kompatibilitas retro (saya pikir beberapa program digunakan untuk memesan pointer ke memori virtual 2GB tertinggi untuk tujuan khusus). Anda dapat mengatur flag LARGEADDRESSAWARE di executable Anda ( docs.microsoft.com/fr-fr/cpp/build/reference/… ) untuk memilih ikut serta mendapatkan akses ke seluruh memori virtual 4GB.
ysdx
15

Semua prosesor yang mendukung set instruksi x64 (juga dikenal sebagai x86_64 atau amd64) juga mendukung set instruksi x86 (juga dikenal sebagai i386 atau i686, yang merupakan versi spesifik dari x86). Hal yang sama berlaku untuk ARM A64 (set instruksi 64-bit baru muncul di ARMv8) dan A32 (nama untuk set instruksi 32-bit "klasik"), untuk SPARC64 dan SPARC , dan saya percaya untuk MIPS64 dan MIPS . Jadi pada semua keluarga arsitektur ini, jika sebuah prosesor dapat menjalankan kode 64-bit, ia juga dapat menjalankan kode 32-bit.

Kernel Linux mendukung menjalankan kode userland 32-bit dengan kernel 64-bit (pada semua keluarga arsitektur yang disebutkan di atas, saya kira). Kernel harus homogen (semua 64-bit atau 32-bit), dan setiap proses harus homogen, tetapi Anda dapat memiliki campuran proses 32-bit dan 64-bit pada kernel 64-bit. Kebalikannya tidak mungkin: dengan kernel 32-bit, Anda tidak dapat menjalankan proses 64-bit.

Ini adalah pilihan desain di Linux, dimotivasi oleh keinginan untuk menjalankan binari 32-bit yang ada pada instalasi 64-bit. Varian Unix lain telah membuat pilihan berbeda: Solaris dapat menjalankan program 64-bit pada kernel 32-bit dan sebaliknya, sementara OpenBSD tidak dapat menjalankan program 32-bit pada kernel 64-bit.

Anda dapat memperoleh informasi tentang CPU di /proc/cpuinfo. Jika CPU x86 Anda memiliki lmbenderanya, itu adalah CPU 64-bit.

Secara default, uname -matau archmemperlihatkan arsitektur tempat kernel dikompilasi. Linux dapat mengatur "kepribadian" dari suatu proses (dengan personality) panggilan sistem. Anda dapat menjalankan subproses dalam kepribadian yang berbeda dengan setarchperintah; setarch i686 someprogramatau linux32 someprogrammenjalankan program yang ditentukan di lingkungan tempat uname -mpengembalian i686sementara setarch amd64 someprogramatau linux64 someprogrammenjalankan program yang ditentukan di lingkungan tempat uname -mpengembalian amd64.

file /sbin/initmemberi tahu Anda apa arsitektur initprogram ini dikompilasi. Meskipun mungkin untuk menggabungkan executable 32-bit dan 64-bit dalam instalasi, biasanya semua program inti OS berasal dari arsitektur yang sama, karena jauh lebih mudah untuk dikelola.

$HOSTYPEadalah variabel bash dan memberi tahu Anda apa arsitektur bashprogram itu dikompilasi.

getconf LONG_BITmemberi tahu Anda apakah kompiler C default telah diatur untuk mengkompilasi program 32-bit atau 64-bit. Tes yang lebih tepat adalah dengan mengkompilasi dan menjalankan program yang mencetak sizeof(void*)atau sizeof(size_t)memanggil getconfhanya dapat memberikan informasi tentang apa yang getconfdianggap sebagai kompiler default.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
1
Memang, apakah Solaris 32 bit beralih ke mode 64 bit untuk beralih ke proses 64-bit dan kemudian kembali? Ini harus memiliki overhead yang besar, dan tidak masuk akal, karena kernel 64 bit yang efektif.
Ruslan
1
@Ruslan Mengapa ada overhead yang besar? Mengalihkan mode pada pengalih konteks tidak membutuhkan biaya banyak (jika ada, saya tidak tahu x86 pada level yang cukup rendah). Kernel tetap 32-bit: alamat virtual 32-bit untuk pemetaan kernel, penggunaan 32-bit set instruksi.
Gilles 'SANGAT berhenti menjadi jahat'
1
Kernel harus memelihara beberapa struktur data spesifik 64-bit untuk mendukung aplikasi 64 bit, setidaknya tabel halaman 64bit-aware. Ini membuatnya bukan kernel 32 bit. Saya belum mencoba untuk benar-benar masuk ke dalam lengkungan amd64, tapi saya pikir beralih dukungan 64 bit akan memiliki overhead yang cukup berbeda dengan menggunakan mode kompatibilitas yang dirancang khusus.
Ruslan
1
@Ruslan Tabel tabel hanya 64-bit dan benar-benar diperlukan, dan itu adalah biaya yang sangat kecil. Segala sesuatu yang lain dapat dihindari dengan desain kernel yang tepat. Saya tidak pernah menggali ke dalam Solaris kernel, saya kira mereka mengatur agar cukup fleksibel (mereka memiliki pengalaman sebelumnya dengan SPARC64).
Gilles 'SANGAT berhenti menjadi jahat'