GNU/Linux >> Znalost Linux >  >> Linux

Linux – jak je Mono magické?

Učím se C#, a tak jsem vytvořil malý program v C#, který říká Hello, World! , pak jej zkompiloval pomocí mono-csc a spustil jej pomocí mono :

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

Všiml jsem si toho, když jsem stiskl TAB v bash , Hello.exe byl označen jako spustitelný. Ve skutečnosti běží pouze pomocí shellu, který načte název souboru!

Hello.exe není soubor ELF s legrační příponou:

$ 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 znamená, že se jedná o staticky propojený spustitelný soubor Microsoft Windows. Pusťte jej do krabice Windows a ono se to (mělo) spustit.

Mám wine nainstalován, ale wine , který je vrstvou kompatibility pro aplikace Windows, trvá asi 5x déle, než spustíte Hello.exe jako mono a jeho spouštění přímo, takže to není wine který to provozuje.

Předpokládám, že existuje nějaké mono modul jádra nainstalovaný s mono který zachycuje exec syscall/s nebo zachytí binární soubory začínající 4D 5A , ale lsmod | grep mono a přátelé vrátí chybu.

Co se tu děje a jak to jádro ví toto je spustitelný soubor speciální?

Jen pro důkaz, že to není moje shell pracovní kouzlo, použil jsem Crap Shell (aka sh ) jej spustit a stále běží nativně.

Zde je celý program, protože komentátor byl zvědavý:

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");
  }
}

Přijatá odpověď:

Toto je binfmt_misc v akci:umožňuje jádru sdělit, jak spouštět binární soubory, o kterých neví. Podívejte se na obsah /proc/sys/fs/binfmt_misc; mezi soubory, které tam vidíte, byste měli vysvětlit, jak spustit Mono binární soubory:

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

(na systému Debian). To říká jádru, že binární soubory začínající MZ (4d5a ) by měla být dána run-detectors . Ten zjistí, zda ke spuštění binárního souboru použít Mono nebo Wine.

Binární typy lze kdykoli přidat, odebrat, povolit a zakázat; podrobnosti naleznete v dokumentaci výše (sémantika je překvapivá, zde použitý virtuální souborový systém se nechová úplně jako standardní souborový systém). /proc/sys/fs/binfmt_misc/status udává globální stav a každý binární „deskriptor“ ukazuje svůj individuální stav. Další způsob, jak deaktivovat binfmt_misc je uvolnit jeho modul jádra, pokud je vytvořen jako modul; to také znamená, že je možné jej umístit na černou listinu, abyste se mu zcela vyhnuli.

Tato funkce umožňuje podporu nových binárních typů, jako jsou spustitelné soubory MZ (které zahrnují binární soubory Windows PE a PE+, ale také binární soubory DOS a OS/2!), soubory Java JAR… Umožňuje také podporu známých binárních typů na nových architekturách , typicky pomocí Qemu; takže s příslušnými knihovnami můžete transparentně spouštět binární soubory ARM Linux na procesoru Intel!

Související:Linux Things I Forget Cheat Sheet

Vaše otázka pocházela z křížové kompilace, i když ve smyslu .NET, a to přináší upozornění s binfmt_misc :některé konfigurační skripty se chovají špatně, když se pokoušíte o křížovou kompilaci na systému, který může spouštět křížově kompilované binární soubory. Detekce křížové kompilace obvykle zahrnuje vytvoření binárního souboru a pokus o jeho spuštění; pokud běží, neprovádíte křížovou kompilaci, pokud ne, ano (nebo je váš kompilátor nefunkční). autoconf skripty lze v tomto případě obvykle opravit explicitním určením architektury sestavení a hostitele, ale někdy budete muset vypnout binfmt_misc dočasně…


Linux
  1. Jak používat BusyBox na Linuxu

  2. Jak používám cron v Linuxu

  3. Jak rozdělit disk v Linuxu

  1. Jak nainstalovat Python na Linux

  2. Jak nainstalovat Javu na Linux

  3. Vývoj C# na Linuxu

  1. Jak nainstalovat Linux ve 3 krocích

  2. Jak přesunout soubor v Linuxu

  3. Jak přidat svůj vlastní software do balíčku Buildroot Linux?