GNU/Linux >> Belajar Linux >  >> Linux

Linux – Bagaimana Mono Ajaib?

Saya sedang belajar C#, jadi saya membuat program C# kecil yang mengatakan Hello, World! , lalu kompilasi dengan mono-csc dan jalankan dengan mono :

$ mono-csc Hello.cs
$ mono Hello.exe
Hello, World!

Saya perhatikan ketika saya menekan TAB di bash , Hello.exe ditandai dapat dieksekusi. Memang, ini berjalan hanya dengan shell yang memuat nama file!

Hello.exe adalah tidak file ELF dengan ekstensi file lucu:

$ readelf -a Hello.exe
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start
$ xxd Hello.exe | head -n1
00000000: 4d5a 9000 0300 0000 0400 0000 ffff 0000  MZ..............

MZ berarti itu adalah executable Microsoft Windows yang terhubung secara statis. Jatuhkan ke kotak Windows, dan itu akan (harus) berjalan.

Saya punya wine diinstal, tetapi wine , sebagai lapisan kompatibilitas untuk aplikasi Windows, membutuhkan waktu sekitar 5x lebih lama untuk menjalankan Hello.exe sebagai mono dan mengeksekusinya secara langsung, jadi itu bukan wine yang menjalankannya.

Saya berasumsi ada beberapa mono modul kernel diinstal dengan mono yang memotong exec syscall/s, atau menangkap binari yang dimulai dengan 4D 5A , tetapi lsmod | grep mono dan teman mengembalikan kesalahan.

Apa yang terjadi di sini, dan bagaimana kernel mengetahui bahwa ini executable itu spesial?

Sebagai bukti, itu bukan milikku keajaiban kerja shell, saya menggunakan Crap Shell (alias sh ) untuk menjalankannya dan masih berjalan secara native.

Inilah programnya secara lengkap, karena seorang komentator penasaran:

using System;

class Hello {
  /// <summary>
  ///   The main entry point for the application
  /// </summary>
  [STAThread]
  public static void Main(string[] args) {
    System.Console.Write("Hello, World!n");
  }
}

Jawaban yang Diterima:

Ini adalah binfmt_misc dalam tindakan:memungkinkan kernel untuk diberitahu bagaimana menjalankan binari yang tidak diketahuinya. Lihat isi /proc/sys/fs/binfmt_misc; di antara file yang Anda lihat di sana, seseorang harus menjelaskan cara menjalankan binari Mono:

enabled
interpreter /usr/lib/binfmt-support/run-detectors
flags:
offset 0
magic 4d5a

(pada sistem Debian). Ini memberitahu kernel bahwa biner dimulai dengan MZ (4d5a ) harus diberikan kepada run-detectors . Yang terakhir menentukan apakah akan menggunakan Mono atau Wine untuk menjalankan biner.

Jenis biner dapat ditambahkan, dihapus, diaktifkan, dan dinonaktifkan kapan saja; lihat dokumentasi di atas untuk detailnya (semantiknya mengejutkan, sistem file virtual yang digunakan di sini tidak berperilaku sepenuhnya seperti sistem file standar). /proc/sys/fs/binfmt_misc/status memberikan status global, dan setiap "deskriptor" biner menunjukkan status individualnya. Cara lain untuk menonaktifkan binfmt_misc adalah membongkar modul kernelnya, jika dibangun sebagai modul; ini juga berarti mungkin untuk memasukkannya ke daftar hitam untuk menghindarinya sepenuhnya.

Fitur ini memungkinkan jenis biner baru untuk didukung, seperti executable MZ (yang mencakup binari Windows PE dan PE+, tetapi juga biner DOS dan OS/2!), file Java JAR… Ini juga memungkinkan jenis biner yang diketahui untuk didukung pada arsitektur baru , biasanya menggunakan Qemu; jadi, dengan pustaka yang sesuai, Anda dapat menjalankan binari ARM Linux secara transparan pada prosesor Intel!

Terkait:Hal-hal Linux yang Saya Lupakan Lembar Cheat

Pertanyaan Anda berasal dari kompilasi silang, meskipun dalam arti .NET, dan itu memunculkan peringatan dengan binfmt_misc :beberapa skrip konfigurasi tidak berfungsi dengan baik saat Anda mencoba mengkompilasi silang pada sistem yang dapat menjalankan binari yang dikompilasi silang. Biasanya, mendeteksi kompilasi silang melibatkan pembuatan biner dan mencoba menjalankannya; jika berjalan, Anda tidak melakukan kompilasi silang, jika tidak, Anda (atau kompiler Anda rusak). autoconf skrip biasanya dapat diperbaiki dalam kasus ini dengan secara eksplisit menentukan arsitektur build dan host, tetapi terkadang Anda harus menonaktifkan binfmt_misc sementara…


Linux
  1. Cara menginstal Python di Linux

  2. Cara menginstal Java di Linux

  3. Cara mempartisi disk di Linux

  1. Cara menggunakan BusyBox di Linux

  2. Bagaimana saya menggunakan cron di Linux

  3. Bagaimana cara menambahkan perangkat lunak saya sendiri ke paket Buildroot Linux?

  1. Cara menginstal Linux dalam 3 langkah

  2. Cara memindahkan file di Linux

  3. Mengembangkan C# di Linux