I binari sono portatili su architetture CPU diverse?


16

Il mio obiettivo è essere in grado di sviluppare per Linux incorporato. Ho esperienza su sistemi embedded bare metal usando ARM.

Ho alcune domande generali sullo sviluppo per diversi obiettivi della CPU. Le mie domande sono le seguenti:

  1. Se ho un'applicazione compilata per essere eseguita su un " target x86, versione del sistema operativo xyz di Linux ", posso semplicemente eseguire lo stesso binario compilato su un altro " target ARM, versione del sistema operativo xyz di Linux "?

  2. Se sopra non è vero, l'unico modo è quello di ottenere il codice sorgente dell'applicazione per ricostruire / ricompilare usando il toolchain '' ad esempio, arm-linux-gnueabi '?

  3. Allo stesso modo, se ho un modulo kernel caricabile (driver di dispositivo) che funziona su un " target x86, versione del sistema operativo xyz di Linux ", posso semplicemente caricare / utilizzare lo stesso .ko compilato su un altro " target ARM, versione del sistema operativo xyz di Linux " ?

  4. Se sopra non è vero, l'unico modo è quello di ottenere il codice sorgente del driver per ricostruire / ricompilare usando il toolchain '' ad esempio, arm-linux-gnueabi '?


27
no, si, no, si.
Hobbs,

7
Aiuta a rendersi conto che non abbiamo un target AMD e un target Intel, solo un singolo target x86 per entrambi. Questo perché Intel e AMD sono sufficientemente compatibili. Diventa quindi ovvio che il target ARM esiste per un motivo specifico, in particolare perché le CPU ARM non sono compatibili con Intel / AMD / x86.
Salterio il

1
No, a meno che non sia progettato per bytecode per essere eseguito su un ambiente di runtime portatile come Java Runtime. Se stai scrivendo codice per uso incorporato, il tuo codice probabilmente si baserà su ottimizzazioni o funzionalità specifiche del processore di basso livello e sarà molto difficile portarlo, richiedendo molto di più che una semplice compilazione per la piattaforma di destinazione (ad es. Modifiche del codice assembly, possibilmente riscrittura più moduli o l'intero programma).
bwDraco,

1
@MSalters: In realtà, abbiamo un target AMD: amd64 che è spesso etichettato x86-64 (mentre x86 è di solito una rietichettatura di i386). Fortunatamente Intel ha copiato (e successivamente ampliato) l'architettura AMD in modo che qualsiasi x86 a 64 bit possa eseguire binari amd64.
Slebetman,

Risposte:


42

No. I binari devono essere (ri) compilati per l'architettura di destinazione e Linux non offre niente di simile a binari grassi pronti all'uso. Il motivo è perché il codice viene compilato in codice macchina per un'architettura specifica e il codice macchina è molto diverso tra la maggior parte delle famiglie di processori (ARM e x86 per esempio sono molto diversi).

EDIT: vale la pena notare che alcune architetture offrono livelli di compatibilità all'indietro (e ancora più rara, compatibilità con altre architetture); sulle CPU a 64 bit, è comune avere retrocompatibilità con le versioni a 32 bit (ma ricorda: anche le tue librerie dipendenti devono essere a 32 bit, inclusa la libreria C standard, a meno che non ti colleghi staticamente ). Vale anche la pena menzionare Itanium , dove era possibile eseguire il codice x86 (solo 32 bit), anche se molto lentamente; la scarsa velocità di esecuzione del codice x86 era almeno parte del motivo per cui non ebbe molto successo sul mercato.

Tieni presente che non puoi ancora utilizzare i binari compilati con le istruzioni più recenti sulle CPU più vecchie, anche nelle modalità di compatibilità (ad esempio, non puoi utilizzare AVX in un binario a 32 bit sui processori Nehalem x86 ; la CPU semplicemente non lo supporta.

Si noti che i moduli del kernel devono essere compilati per l'architettura pertinente; inoltre, i moduli del kernel a 32 bit non funzioneranno sui kernel a 64 bit o viceversa.

Per informazioni sui file binari di compilazione incrociata (quindi non è necessario disporre di una toolchain sul dispositivo ARM di destinazione), vedere la risposta completa di Grochmal di seguito.


1
Potrebbe valere la pena chiarire l'eventuale compatibilità (o mancanza di ciò) tra x86 e x64, dato che alcuni binari x86 possono essere eseguiti su piattaforme x64. (Non sono sicuro che questo sia il caso su Linux, ma è su Windows, per esempio.)
jpmc26

4
@ jpmc26 è possibile su Linux; ma potrebbe essere necessario installare prima le librerie di compatibilità. Il supporto x86 è una parte non opzionale delle installazioni di Win64. In Linux è facoltativo; e poiché il mondo Linux è molto più avanti nel rendere disponibili versioni a 64 bit di tutto ciò che è disponibile, alcune distribuzioni non hanno come default l'installazione di librerie (tutto?) a 32 bit. (Non sono sicuro di quanto sia comune; ma ho già visto alcune domande a riguardo da parte di persone che gestiscono distribuzioni mainstream prima.)
Dan è Fiddling di Firelight il

@ jpmc26 Ho aggiornato la mia risposta con le tue note; Ho pensato di menzionarlo, ma non volevo complicare la risposta.
Elizafox,

16

Elizabeth Myers ha ragione, ogni architettura richiede un binario compilato per l'architettura in questione. Per creare binari per un'architettura diversa da quella su cui è in esecuzione il sistema è necessario un cross-compiler.


Nella maggior parte dei casi è necessario compilare un compilatore incrociato. Ho solo esperienza con gcc(ma credo che llvm, e altri compilatori, abbiano parametri simili). Un gcccross-compilatore si ottiene aggiungendo --targetalla configurazione:

./configure --build=i686-arch-linux-gnu --target=arm-none-linux-gnueabi

È necessario compilare gcc, glibce binutilscon questi parametri (e fornire gli header del kernel del kernel al computer di destinazione).

In pratica, ciò è notevolmente più complicato e diversi errori di compilazione vengono visualizzati su sistemi diversi.

Esistono diverse guide su come compilare la toolchain GNU, ma raccomanderò Linux From Scratch , che viene continuamente mantenuto e fa un ottimo lavoro nello spiegare cosa fanno i comandi presentati.

Un'altra opzione è una compilation bootstrap di un cross-compilatore. Grazie alla lotta per la compilazione di cross compiler per architetture diverse su architetture diverse è crosstool-ngstata creata. Fornisce un bootstrap sulla toolchain necessaria per costruire un compilatore incrociato.

crosstool-ngsupporta diverse terzine target su architetture diverse, fondamentalmente è un bootstrap in cui le persone dedicano il loro tempo a risolvere i problemi che si verificano durante la compilazione di una toolchain cross-compilatore.


Diverse distribuzioni forniscono cross-compilatori come pacchetti:

In altre parole, controlla cosa ha a disposizione la tua distribuzione in termini di cross-compilatori. Se la tua distribuzione non ha un compilatore incrociato per le tue esigenze, puoi sempre compilarlo da solo.

Riferimenti:


Nota sui moduli del kernel

Se stai compilando il tuo cross-compilatore a mano, hai tutto il necessario per compilare i moduli del kernel. Questo perché è necessario compilare le intestazioni del kernel glibc.

Ma, se stai usando un cross-compilatore fornito dalla tua distribuzione, avrai bisogno delle intestazioni del kernel del kernel che gira sul computer di destinazione.


FWIW Fedora include anche cross-compilatori.
Mattdm,

@mattdm - grazie, risposta ottimizzata, credo di avere la parte giusta del wiki fedora collegato.
grochmal,

2
Un modo più semplice di Linux From Scratch per ottenere un Linux e toolchain per un'altra architettura è crosstool-ng. Potresti volerlo aggiungere all'elenco. Inoltre, la configurazione e la compilazione manuale di una cross-toolchain GNU per qualsiasi architettura è incredibilmente coinvolta e molto più noiosa delle semplici --targetbandiere. Sospetto che sia parte del motivo per cui LLVM sta guadagnando popolarità; È progettato in modo tale da non avere bisogno di una ricostruzione per indirizzare un'altra architettura, ma è possibile scegliere come target più backend utilizzando le stesse librerie frontend e ottimizzatore.
Iwillnotexist Idonotexist,

@IwillnotexistIdonotexist - grazie, ho modificato ulteriormente la risposta. Non ho mai sentito parlare di crosstool-ng prima, ed è molto utile. Il tuo commento è stato davvero utile per me.
grochmal,

9

Si noti che come ultima risorsa (ovvero quando non si dispone del codice sorgente), è possibile eseguire binari su un'architettura diversa utilizzando emulatori come qemu, dosboxo exagear. Alcuni emulatori sono progettati per emulare sistemi diversi da Linux (ad esempio, dosboxsono progettati per eseguire programmi MS-DOS e ci sono molti emulatori per le console di gioco più diffuse). L'emulazione ha un notevole sovraccarico di prestazioni: i programmi di emulazione vengono eseguiti 2-10 volte più lentamente rispetto alle loro controparti native.

Se devi eseguire i moduli del kernel su una CPU non nativa, dovrai emulare l'intero sistema operativo incluso il kernel per la stessa architettura. AFAIK è impossibile eseguire codice straniero all'interno del kernel Linux.


3
La penalità di velocità per l'emulazione è spesso persino superiore a 10x, ma se si sta tentando di eseguire il codice scritto per una macchina da 16 MHz su una macchina da 4 GHz (una differenza di velocità di 250: 1), un emulatore con una penalità di velocità 50: 1 può comunque eseguire il codice molto più velocemente di quanto sarebbe stato eseguito sulla piattaforma originale.
supercat,

7

Non solo i binari non sono portatili tra x86 e ARM, ci sono diversi tipi di ARM .

Quello che probabilmente incontrerai nella pratica è ARMv6 vs ARMv7. Raspberry Pi 1 è ARMv6, le versioni successive sono ARMv7. Quindi è possibile compilare il codice su quelli successivi che non funzionano su Pi 1.

Fortunatamente uno dei vantaggi dell'open source e del software libero è avere il sorgente in modo da poterlo ricostruire su qualsiasi architettura. Anche se questo potrebbe richiedere del lavoro.

(Il versioning ARM è confuso, ma se c'è una V prima del numero parla dell'architettura del set di istruzioni (ISA). In caso contrario, è un numero di modello come "Cortex M0" o "ARM926EJS". I numeri di modello non hanno nulla da fare con i numeri ISA.)


2
... e poi ci sono anche diversi sottoflavori per lo stesso sapore ARM e persino ABI diversi per lo stesso identico hardware (sto pensando a tutto il pasticcio ARM soft / softfp / hard in virgola mobile).
Matteo Italia,

1
@MatteoItalia Ugh. Le ABI multiple erano uno snafu, una cura per qualcosa che era peggio della malattia. Alcuni ARM non avevano affatto i registri VFP o NEON, altri ne avevano 16, altri 32. Su Cortex-A8 e precedenti il ​​motore NEON aveva una dozzina di CC dietro il resto del core, quindi trasferire un'uscita vettoriale a un GPR costava un sacco. ARM ha iniziato a fare la cosa giusta - imponendo un ampio sottoinsieme comune di funzionalità.
Iwillnotexist Idonotexist,

7

Devi sempre scegliere come target una piattaforma. Nel caso più semplice, la CPU di destinazione esegue direttamente il codice compilato nel file binario (questo corrisponde approssimativamente agli eseguibili COM di MS DOS). Consideriamo due diverse piattaforme che ho appena inventato: Armistice e Intellio. In entrambi i casi, avremo un semplice programma Hello World che produrrà 42 sullo schermo. Supporrò anche che stai usando un linguaggio multipiattaforma in modo indipendente dalla piattaforma, quindi il codice sorgente è lo stesso per entrambi:

Print(42)

Su Armistice, hai un semplice driver di dispositivo che si occupa della stampa dei numeri, quindi tutto ciò che devi fare è inviare a una porta. Nel nostro linguaggio dell'assemblaggio portatile, ciò corrisponderebbe a qualcosa del genere:

out 1234h, 42

Tuttavia, o il sistema Intellio non ha nulla del genere, quindi deve passare attraverso altri livelli:

mov a, 10h
mov c, 42
int 13h

Spiacenti, abbiamo già una differenza significativa tra i due, prima ancora di arrivare al codice macchina! Ciò corrisponderebbe approssimativamente al tipo di differenza che hai tra Linux e MS DOS, o un PC IBM e un X-Box (anche se entrambi possono usare la stessa CPU).

Ma è a questo che servono i sistemi operativi. Supponiamo di avere un HAL che si assicuri che tutte le diverse configurazioni hardware siano gestite allo stesso modo sul livello dell'applicazione - fondamentalmente, useremo l'approccio Intellio anche sull'Armistizio e il nostro codice "assembly portatile" finisce allo stesso modo. Viene utilizzato sia dai moderni sistemi Unix che da Windows, spesso anche in scenari integrati. Bene: ora possiamo avere lo stesso codice assembly portatile su Armistice e Intellio. Ma che dire dei binari?

Come abbiamo ipotizzato, la CPU deve eseguire direttamente il binario. Diamo un'occhiata alla prima riga del nostro codice mov a, 10h, su Intellio:

20 10

Oh. Si scopre che mov a, constantè così popolare che ha le sue istruzioni, con il suo codice operativo. Come gestisce l'Armistizio?

36 01 00 10

Hmm. C'è il codice operativo per mov.reg.imm, quindi abbiamo bisogno di un altro argomento per selezionare il registro a cui stiamo assegnando. E la costante è sempre una parola di 2 byte, in notazione big-endian - è così che è stato progettato Armistice, infatti tutte le istruzioni in Armistice sono lunghe 4 byte, senza eccezioni.

Ora immagina di eseguire il binario da Intellio su Armistice: la CPU inizia a decodificare l'istruzione, trova opcode 20h. Su Armistice, questo corrisponde, diciamo, alle and.imm.registruzioni. Prova a leggere la costante di parola a 2 byte (che legge 10XX, già un problema), quindi il numero di registro (un altroXX ). Stiamo eseguendo l'istruzione sbagliata, con argomenti sbagliati. E peggio ancora, la prossima istruzione sarà completamente falsa, perché in realtà abbiamo mangiato un'altra istruzione, pensando che fossero dati.

L'applicazione non ha alcuna possibilità di funzionare e molto probabilmente si bloccherà o si bloccherà quasi immediatamente.

Ora, questo non significa che un eseguibile debba sempre dire che funziona su Intellio o Armistice. Devi solo definire una piattaforma che sia indipendente dalla CPU (come bashsu Unix) o sia dalla CPU che dal sistema operativo (come Java o .NET, e oggigiorno anche JavaScript, in un certo senso). In questo caso, l'applicazione può utilizzare un eseguibile per tutte le diverse CPU e sistemi operativi, mentre sul sistema di destinazione è presente qualche applicazione o servizio (che indirizza direttamente la CPU e / o il sistema operativo corretti) che traduce il codice indipendente dalla piattaforma in qualcosa di La CPU può effettivamente essere eseguita. Ciò può avere o meno un impatto su prestazioni, costi o capacità.

Le CPU di solito appartengono alle famiglie. Ad esempio, tutte le CPU della famiglia x86 hanno un insieme comune di istruzioni codificate esattamente allo stesso modo, quindi ogni CPU x86 può eseguire tutti i programmi x86, purché non cerchi di utilizzare alcuna estensione (ad esempio, operazioni in virgola mobile o operazioni vettoriali). Su x86, gli esempi più comuni oggi sono Intel e AMD, ovviamente. Atmel è una società ben nota che progetta CPU della famiglia ARM, abbastanza popolare per i dispositivi embedded. Apple ha anche CPU ARM proprie, per esempio.

Ma ARM è assolutamente incompatibile con x86: hanno requisiti di progettazione molto diversi e hanno ben poco in comune. Le istruzioni hanno codici operativi completamente diversi, sono decodificati in modo diverso, gli indirizzi di memoria sono trattati in modo diverso ... Potrebbe essere possibile creare un binario che gira su una CPU x86 e una CPU ARM, usando alcune operazioni sicure per distinguere tra i due e saltare a due set di istruzioni completamente diversi, ma significa comunque che hai istruzioni separate per entrambe le versioni, con solo un bootstrapper che seleziona il set corretto in fase di esecuzione.


3

È possibile ripetere il cast di questa domanda in un ambiente che potrebbe essere più familiare. Per analogia:

"Ho un programma Ruby che voglio eseguire, ma la mia piattaforma ha solo un interprete Python. Posso usare l'interprete Python per eseguire il mio programma Ruby o devo riscrivere il mio programma in Python?"

Un'architettura di set di istruzioni ("target") è un linguaggio - un "linguaggio macchina" - e diverse CPU implementano linguaggi diversi. Quindi chiedere a una CPU ARM di eseguire un binario Intel è molto simile a provare a eseguire un programma Ruby usando un interprete Python.


2

gcc usa i termini '' architettura '' per indicare il '' set di istruzioni '' di una CPU specifica, e "target" copre la combinazione di CPU e architettura, insieme ad altre variabili come ABI, libc, endian-ness e altro (possibilmente includendo "bare metal"). Un tipico compilatore ha un insieme limitato di combinazioni di destinazione (probabilmente un ABI, una famiglia di CPU, ma probabilmente sia a 32 che a 64 bit). Un compilatore incrociato di solito indica un compilatore con una destinazione diversa dal sistema su cui viene eseguito, oppure uno con più destinazioni o ABI (vedere anche questo ).

I binari sono portatili su architetture CPU diverse?

In generale, no. Un binario in termini convenzionali è un codice oggetto nativo per una particolare CPU o famiglia di CPU. Tuttavia, ci sono diversi casi in cui possono essere da moderatamente a altamente portatili:

  • un'architettura è un superset di un'altra (comunemente i binari x86 hanno come target i386 o i686 anziché l'ultimo e il più grande x86, ad es. -march=core2)
  • un'architettura fornisce l'emulazione o la traduzione nativa di un'altra (potresti aver sentito parlare di Crusoe ) o fornisce coprocessori compatibili (ad esempio PS2 )
  • il sistema operativo e il runtime supportano il multiarch (ad esempio, la capacità di eseguire binari x86 a 32 bit su x86_64) o rendere la VM / JIT senza soluzione di continuità (Android utilizzando Dalvik o ART )
  • c'è il supporto per i binari "fat" che essenzialmente contengono codice duplicato per ogni architettura supportata

Se in qualche modo riesci a risolvere questo problema, l' altro problema binario portatile di una miriade di librerie (glibc ti sto guardando) si presenterà. (La maggior parte dei sistemi embedded ti salva almeno da quel particolare problema.)

Se non l'hai già fatto, ora è un buon momento per correre gcc -dumpspecse gcc --target-helpvedere cosa stai affrontando.

I binari fat hanno vari svantaggi , ma hanno ancora potenziali usi ( EFI ).

Ci sono altre due considerazioni che mancano nelle altre risposte: ELF e l'interprete ELF e il supporto del kernel Linux per formati binari arbitrari . Non entrerò nei dettagli sui binari o sul bytecode per processori non reali qui, anche se è possibile trattarli come "nativi" ed eseguire binari di codice byte Java o Python compilati , tali binari sono indipendenti dall'architettura hardware (ma dipendono invece sulla versione VM pertinente, che alla fine esegue un file binario nativo).

Qualsiasi sistema Linux contemporaneo utilizzerà i binari ELF (dettagli tecnici in questo PDF ), nel caso dei binari ELF dinamici il kernel ha il compito di caricare l'immagine in memoria ma è il lavoro dell '"interprete" impostato nell'ELF intestazioni per fare il sollevamento pesante. Normalmente questo implica assicurarsi che tutte le librerie dinamiche dipendenti siano disponibili (con l'aiuto della sezione '' Dinamica '' che elenca le librerie e alcune altre strutture che elencano i simboli richiesti) - ma questo è quasi un livello di riferimento indiretto per scopi generali.

$ file /bin/ls
/bin/ls: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses \
shared libs), stripped
$ readelf -p .interp /bin/ls
    String dump of section '.interp':
      [     0]  /lib/ld-linux.so.2

( /lib/ld-linux.so.2è anche un file binario ELF, non ha un interprete ed è un codice binario nativo.)

Il problema con ELF è che l'intestazione nel binario ( readelf -h /bin/ls) lo contrassegna per una specifica architettura, classe (32 o 64 bit), endian-ness e ABI (i binari fat "universali" di Apple usano un formato binario alternativo Mach-O invece che risolve questo problema, questo ha avuto origine su NextSTEP). Ciò significa che un eseguibile ELF deve corrispondere al sistema su cui deve essere eseguito. Un tratteggio di escape è l'interprete, questo può essere qualsiasi eseguibile (incluso uno che estrae o mappa le sottosezioni specifiche dell'architettura del file binario originario e le invoca), ma sei ancora vincolato dal tipo o dai tipi di ELF che il tuo sistema consentirà di eseguire . (FreeBSD ha un modo interessante di gestire i file ELF di Linux , brandelfmodifica il campo ABI ELF.)

C'è (usando binfmt_misc) il supporto per Mach-O su Linux , c'è un esempio che ti mostra come creare ed eseguire un binario fat (32-64 bit). I fork di risorse / ADS , come originariamente fatto sul Mac, potrebbero essere una soluzione alternativa, ma nessun filesystem Linux nativo lo supporta.

Più o meno la stessa cosa vale per i moduli del kernel, i .kofile sono anche ELF (anche se non hanno un set di interpreti). In questo caso c'è un livello aggiuntivo che utilizza la versione del kernel ( uname -r) nel percorso di ricerca, qualcosa che teoricamente si potrebbe fare invece in ELF con il versioning, ma sospetto che abbia una certa complessità e poco guadagno.

Come notato altrove, Linux non supporta nativamente i binari fat, ma esiste un progetto fat-binary attivo: FatELF . È in circolazione da anni , non è mai stato integrato nel kernel standard in parte a causa di problemi di brevetto (ora scaduti). In questo momento richiede sia il kernel che il supporto della toolchain. Non usa l' binfmt_miscapproccio, questo fa da passo tra i problemi dell'intestazione ELF e consente anche moduli del kernel fat.

  1. Se ho un'applicazione compilata per essere eseguita su un "target x86, versione del sistema operativo xyz di Linux", posso semplicemente eseguire lo stesso binario compilato su un altro "sistema ARM, versione del sistema operativo xyz di Linux"?

Non con ELF, non ti permetterà di farlo.

  1. Se sopra non è vero, l'unico modo è quello di ottenere il codice sorgente dell'applicazione per ricostruire / ricompilare usando il toolchain '' ad esempio, arm-linux-gnueabi '?

La semplice risposta è sì. (Le risposte complicate includono emulazione, rappresentazioni intermedie, traduttori e JIT; ad eccezione del caso di "downgrade" di un binario i686 per utilizzare solo i codici operativi i386, probabilmente non sono interessanti qui, e le correzioni ABI sono potenzialmente tanto difficili quanto la traduzione di codice nativo. )

  1. Allo stesso modo, se ho un modulo kernel caricabile (driver di dispositivo) che funziona su un "target x86, versione del sistema operativo xyz di Linux", posso semplicemente caricare / utilizzare lo stesso .ko compilato su un altro sistema "target ARM, versione del sistema operativo xyz di Linux" ?

No, ELF non ti consente di farlo.

  1. Se sopra non è vero, l'unico modo è quello di ottenere il codice sorgente del driver per ricostruire / ricompilare usando il toolchain '' ad esempio, arm-linux-gnueabi '?

La semplice risposta è sì. Credo che FatELF ti consenta di creare una multiarchitettura .ko, ma a un certo punto deve essere creata una versione binaria per ogni architettura supportata. Le cose che richiedono moduli del kernel spesso vengono fornite con il sorgente e sono costruite come richiesto, ad esempio VirtualBox lo fa.

Questa è già una lunga risposta sconclusionata, c'è solo un'altra deviazione. Il kernel ha già una macchina virtuale integrata, anche se dedicata: la VM BPF utilizzata per abbinare i pacchetti. Il filtro leggibile dall'uomo "host foo e non porta 22") viene compilato in un bytecode e il filtro del pacchetto del kernel lo esegue . Il nuovo eBPF non è solo per i pacchetti, in teoria che il codice VM è portatile su qualsiasi Linux contemporaneo e llvm lo supporta, ma per motivi di sicurezza probabilmente non sarà adatto a nient'altro che alle regole amministrative.


Ora, a seconda di quanto sei generoso con la definizione di un eseguibile binario, puoi (ab) usare binfmt_miscper implementare il supporto binario fat con uno script di shell e file ZIP come formato contenitore:

#!/bin/bash

name=$1
prog=${1/*\//}      # basename
prog=${prog/.woz/}  # remove extension
root=/mnt/tmpfs
root=$(TMPDIR= mktemp -d -p ${root} woz.XXXXXX)
shift               # drop argv[0], keep other args

arch=$(uname -m)                  # i686
uname_s=$(uname -s)               # Linux
glibc=$(getconf GNU_LIBC_VERSION) # glibc 2.17
glibc=${glibc// /-}               # s/ /-/g

# test that "foo.woz" can unzip, and test "foo" is executable
unzip -tqq "$1" && {
  unzip -q -o -j -d ${root} "$1"  "${arch}/${uname_s}/${glibc}/*" 
  test -x ${root}/$prog && ( 
    export LD_LIBRARY_PATH="${root}:${LD_LIBRARY_PATH}"
    #readlink -f "${root}/${prog}"   # for the curious
    exec -a "${name}" "${root}/${prog}" "$@" 
  )
  rc=$?
  #rm -rf -- "${root}/${prog}"       # for the brave
  exit $rc
}

Chiamalo "wozbin" e configuralo con qualcosa del tipo:

mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
printf ":%s:%s:%s:%s:%s:%s:%s" \
  "woz" "E" "" "woz" "" "/path/to/wozbin" ""  > /proc/sys/fs/binfmt_misc/register

Questo registra i .wozfile con il kernel, lo wozbinscript viene invocato invece con il suo primo argomento impostato sul percorso di un .wozfile richiamato .

Per ottenere un file portatile (fat) .woz , è sufficiente creare un test.wozfile ZIP con una gerarchia di directory così:

i686/ 
    \- Linux/
            \- glibc-2.12/
armv6l/
    \- Linux/
            \- glibc-2.17/

All'interno di ogni directory arch / OS / libc (una scelta arbitraria) posizionare i file testbinari specifici dell'architettura e i componenti come i .sofile. Quando lo invochi, la sottodirectory richiesta viene estratta in un filesystem tmpfs in memoria ( /mnt/tmpfsqui) e invocata.


0

berry boot, risolvi alcuni dei tuoi problemi .. ma non risolve il problema su come eseguire arm hf, normall / regullAr distro linux per x86-32 / 64bit.

Penso che dovrebbe essere integrato in isolinux (boatloader linux su usb) alcuni convertitori live che potrebbero riconoscere regullar distro e in ride / live convertiti in hf.

Perché? Perché se ogni Linux può essere convertito da Berry Boot a lavorare su arm-hf, quindi potrebbe essere in grado di creare un meccanismo di avvio Bery per isolinux ciò che avviamo usando Exaple Eacher o il disco di avvio di Ubuntu Creat incorporato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.