Ikkiliklar turli protsessor arxitekturalarida ko'chirib olinadimi?

Maqsadim ko'milgan Linux uchun ishlab chiqishni ta'minlashdir. ARM-dan foydalanib, yalang'och metall o'rnatilgan tizimlarda tajribam bor.

Turli CPU maqsadlari uchun rivojlanish haqida umumiy savollar bor. Savollarim quyidagicha:

  1. Agar x86 maqsadli, Linux OS versiyasi xyz ni ishlatish uchun tuzilgan dasturga ega bo'lsam, yana bir xil tizimdagi ikkilikni yana bir tizimda ishlatishim mumkin ARM maqsadi , Linux operatsion tizimi versiyasi xyz '

  2. Yuqoridagi holatlar to'g'ri bo'lmasa, dasturiy manba kodini masalan, "arm-linux-gnueabi" kabi tegishli asboblar paneli yordamida qayta qurish/qayta tuzish uchun olish kerak.

  3. Xuddi shunday, agar x86 maqsadli, Linux OS versiyasi xyz ustida ishlaydigan yuklanadigan yadro moduli (qurilma drayveri) bo'lsa, men faqatgina o'sha faylni yuklay olaman/foydalanishi mumkin. boshqa ARM maqsadi, Linux operatsion tizimi versiyasi xyz tizimida ko? "

  4. Yuqoridagi holatlar to'g'ri bo'lmasa, faqatgina "arm-linux-gnueabi" kabi tegishli asboblar paneli yordamida qayta tiklash/qayta tiklash uchun haydovchi manba kodini olish kerakmi?

15
Bu bizning AMD maqsadimiz va Intel maqsadiga ega emasligini, ikkala tomon uchun ham bitta x86 maqsad ekanligini tushunishga yordam beradi. Buning sababi, Intel va AMD etarlicha mos keladi. Keyinchalik, ARM maZsadining muayyan sabablar mavjudligi ravshan buladi, chunki ARM CPU Intel/AMD/x86 bilan mos emas.
qo'shib qo'ydi muallif GrouchyGaijin, manba
Yo'q, ha, yo'q, ha.
qo'shib qo'ydi muallif Nigralbus, manba
Yo'q, agar Java kodi kabi Java Runtime kabi portativ ish muhitida ishlaydigan bayt kodi bo'lmasa. Agar siz kiritilgan kod uchun kod yozmoqchi bo'lsangiz, kodingiz ehtimol past darajadagi protsessorga mos optimallashlarga yoki xususiyatlarga tayanadi va maqsadli platformalar uchun faqat kompilyatsiya qilishdan ko'proq narsani talab qiladigan port (masalan, o'rnatish kodi o'zgarishi, ehtimol qayta yozilishi) bir nechta modul yoki butun dastur).
qo'shib qo'ydi muallif Paul Willons, manba
@MSalters: Darhaqiqat, biz AMD funktsiyasiga egamiz: amd64 tez-tez x86-64 deb belgilangan (x86 odatda i386-ni qayta belgilashda). Yaxshiyamki, Intel, AMD 64-bit x86 amd64 ikkiliklarini ishga tushirishi uchun AMD arxitekturasini kopyaladı (va keyinchalik kengaytirildi).
qo'shib qo'ydi muallif anonymous, manba

7 javoblar

Yo'q. Binaries maqsadli arxitektura uchun tuzilgan bo'lishi kerak, va Linux "qutidagi qutqaruvchi fayllar" dan yog 'fayllari ga o'xshamaydi. Buning sababi, kod ma'lum bir arxitektura uchun mashina kodiga tuzilganligi va mashinaning kodi ko'pchilik protsessor oilalari orasida juda farq qiladi (masalan, ARM va x86 juda farq qiladi).

EDIT: ayrim arxitekturalar orqaga qarab muvofiqligi (va hatto kamroq, boshqa mimarilerle muvofiqligi) taklif qiladi; 64 bitlik protsessorlarda 32 bitli versiyalarga qayta moslashuv mavjudligi ma'lum (lekin esda tuting: agar siz statistika bilan bog'lanish ). Bundan tashqari, x86 kodini (faqat 32 bit) ishlatish mumkin bo'lgan Itanium , juda sekin bo'lsa ham; x86 kodining yomon ijro etilishi tezligi bozorda juda muvaffaqiyatli bo'lmagani sababli edi.

Shuni esda tutingki, oldingi protsessorlar bo'yicha yangi ko'rsatmalar bilan birgalikda foydalaniladigan ikkilangan fayllarni, hatto moslik rejimlarida ham ishlata olmaysiz (masalan, 32-bitli ikkilikli AVX-dan " Nehalem x86 protsessorlari , CPU faqat uni qo'llab-quvvatlamaydi.

Eslatma: yadro modullari tegishli arxitektura uchun yaratilishi kerak; Bundan tashqari, 32-bit yadro modullari 64-bitli yadrolarda yoki aksincha ishlamaydi.

O'zaro o'zaro kompilyatsiya qilinadigan ikkiliklar haqida ma'lumot olish uchun (shuning uchun maqsad ARM qurilmasida asbobcha chalinishi shart emas), pastda grochmalning to'liq javobini ko'ring.

40
qo'shib qo'ydi
@ jpmc26 Linuxda mumkin; ammo oldin moslik kutubxonalarini o'rnatishingiz kerak bo'lishi mumkin. x86-quvvatlash Win64-ni o'rnatishning majburiy bo'lmagan qismidir. Linuxda ixtiyoriy; va Linux dunyosi juda ko'prog'i 64bit versiyalarni tarqatishda foydalanadigan ba'zi bir distroslar 32bitlik kutubxonalar o'rnatilmagan (hammasi). (Men qanchalik keng tarqalganligini bilmayman, biroq bu haqda ilgari yondashuvlarni tarqatuvchi odamlar tomonidan bir nechta savollarni ko'rgansiz).
qo'shib qo'ydi muallif hbaromega, manba
X86 va x64 orasida biron-bir x86 ikkiliklarining x64 platformalarida ishlay olishi mumkinligi sababli, x86 va x64 o'rtasida biron-bir moslik (yoki yo'qligi) haqida aniqlik kiritish mumkin. (Linuxda bunga ishonchim komil emas, lekin Windows da mavjud.)
qo'shib qo'ydi muallif jpmc26, manba
@ jpmc26 Javoblarim bilan mening fikrimni yangiladim; Men buni eslatishni o'yladim, ammo javobni murakkablashtirishni xohlamadim.
qo'shib qo'ydi muallif dr_rk, manba

Elizabet Myers to'g'ri, har bir arxitektura arxitekturasi uchun olingan ikkilikni talab qiladi. Sizning tizimingizdan ko'ra boshqa arxitektura uchun ikkiliklarni yaratish uchun cross-compiler kerak.


Ko'pgina hollarda o'zaro faoliyat derleyici yaratishingiz kerak. Faqatgina gcc bilan tajribam bor (lekin menimcha llvm va boshqa kompilyatorlar shunga o'xshash parametrlarga ega). gcc o'zaro faoliyat kompilyatorga - target parametrini qo'shish orqali erishiladi:

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

Ushbu parametrlar bilan gcc , glibc va binutils ni kompilyatsiya qilishingiz kerak (va yadroning yadro sarlavhalarini maqsadli mashinada taqdim etishingiz kerak).

Amalda, bu juda murakkab va turli xil tuzilish xatolar turli tizimlarda paydo bo'ladi.

GNU asboblar to'plamini qanday kompilyatsiya qilish haqida bir qancha qo'llanma bor, lekin men Linux From Scratch , bu doimiy ravishda saqlanadi va berilgan buyruqlar nima ekanligini tushuntirishda juda yaxshi ish qiladi.

Boshqa bir variant - bu o'zaro faoliyat kompilyatorning ochilish chizmasi. Turli xil arxitektorlarni turli mimarilerda kompilyatsiya qilish uchun yaratilgan kurash tufayli turli xil mimarilerda crosstool-ng yaratildi. Cross-derivat yaratish uchun zarur bo'lgan asboblar paneli orqali dastlabki chiziqni ochib beradi.

crosstool-ng supports several target triplets on different architectures, basically it is a bootstrap where people dedicate their time to sort out problems occurring during the compilation of a cross-compiler toolchain.


Bir nechta taqsimot paketlar sifatida o'zaro translyatsiyani ta'minlaydi:

Boshqacha qilib aytadigan bo'lsak, distribyutoringiz o'zaro o'zaro tuzilgan kompilyatorlar uchun qanday tekshiruvga ega ekanligini tekshiring. Sizning distroda sizning ehtiyojlaringiz uchun chizma kompilyatori bo'lmasa, uni har doim o'zingiz tuzishingiz mumkin.

Manbalar:


Yadro modullari eslatma

O'zingizning o'zaro faoliyat kompilyatoringizni qo'l bilan tuzadigan bo'lsangiz, siz yadro modullarini tuzish uchun kerak bo'lgan hamma narsangiz bor. Buning sababi glibc ni tuzish uchun yadro sarlavhalariga kerak.

Biroq, agar siz distro tomonidan taqdim etilgan o'zaro faoliyat kompilyatordan foydalansangiz, maqsadli mashinada ishlaydigan yadro yadro sarlavhalariga ega bo'lishingiz kerak bo'ladi.

15
qo'shib qo'ydi
FWIW Fedora-da o'zaro faoliyat kompilyatorlar ham mavjud.
qo'shib qo'ydi muallif Chris Pietschmann, manba
@mattdm - rahmat, javob tweaked, fedora wiki bog'liq bo'lgan to'g'ri qismini bor ishonaman.
qo'shib qo'ydi muallif grochmal, manba
@IwillnotexistIdonotexist - rahmat, men javobni ko'paytirdim. Men ilgari hech qanday jumboqni eshitmaganman va bu juda foydali ko'rinadi. Fikringiz aslida men uchun juda foydali bo'ldi.
qo'shib qo'ydi muallif grochmal, manba
Linuxni boshqa bir me'morchilikka ega bo'lish uchun Linuxdan va boshqa usullardan foydalanishni osonlashtirish osonroqdir crosstool-ng . Buni ro'yxatga qo'shishingiz mumkin. Bundan tashqari, har qanday arxitektura uchun qo'l bilan GNU o'zaro faoliyat-chiziqchasini sozlash va tuzish, faqat - target bayroqchalariga qaraganda juda zerikarli va juda zerikarli. Men LVVM nima uchun ommalashib ketayotganining bir qismi ekanligiga shubha qilaman; Bu boshqa arxitekturani ta'mirlash uchun qayta tiklashning hojati yo'qligi tufayli arxitekturaga aylanadi - buning o'rniga bir xil frontend va optimizator kutubxonalari yordamida bir nechta orqa nishonni aniqlab olishingiz mumkin.
qo'shib qo'ydi muallif DonyorM, manba

Oxirgi chora sifatida (ya'ni sizda manba kodi bo'lmasa), qemu , dosbox yoki exagear . Ayrim emulyatorlar Linuxdan boshqa tizimlarni (masalan, dosbox ) MS-DOS dasturlarini ishlatish uchun yaratilgan va ommabop o'yin konsollari uchun ko'p emulyatorlar mavjud bo'lgan tizimlarni taqlid qilishga mo'ljallangan. Emulatsiyani sezilarli darajada oshiradi: emulyatsiya qilingan dasturlar o'zlarining mahalliy hamkasblaridan 2-10 barobar ko'proq ishlaydi.

Agar yadro modullarini noreal bo'lmagan protsessorda ishlatishingiz kerak bo'lsa, xuddi shu arxitektura uchun yadrosi ham o'z ichiga olgan barcha OS-ni taqlid qilishingiz kerak bo'ladi. AFAIK Linux yadrosida tashqi kodni ishlatish mumkin emas.

9
qo'shib qo'ydi
Emulyatsiya uchun tez penalti odatda 10x dan yuqori bo'lsa-da, lekin 4 gigagertsli mashinada 16 MGtsli mashinaga yozilgan kodni ishlatish uchun harakat qilinsa (tezlikda 250: 1 farq) 50: 1 tezlikda jazo olgan emulyator kodni haqiqiy platformada ishlashiga qaraganda ancha tezroq.
qo'shib qo'ydi muallif supercat, manba

Faqat x86 va ARM o'rtasida ko'chma fayllar emas, balki ARM ning turli tatları bor. .

Amaliyotda duch keladigan narsa ARMv6 va ARMv7. Raspberry Pi 1 ARMv6, keyingi versiyalari ARMv7. Shunday qilib, kodni P1-da ishlamaydigan keyinroq tuzish mumkin.

Yaxshiyamki, ochiq manba va erkin dasturiy ta'minotning bitta foyda manbai bo'lib, uni har qanday arxitekturaga tiklashingiz mumkin. Bu ba'zi bir ishlarni talab qilishi mumkin.

(ARM versiyasi chalkashlikdir, lekin agar u oldin "V" belgisi mavjud bo'lsa, u "Cortex M0" yoki "ARM926EJS" kabi model raqamidir. ISA raqamlari bilan amalga oshiriladi.)

7
qo'shib qo'ydi
... va shu bilan bir xil ARM lazzati uchun turli subflavoralar bor va hatto bir xil qurilma uchun turli ABI'ler (butun ARM soft/softfp/hard floating point messi haqida o'ylayman).
qo'shib qo'ydi muallif PoloHoleSet, manba
@MatteoItalia Ugh. Ko'p ABIlar kasallikdan ko'ra yomonroq bo'lgan narsa uchun shifokor edi. Ayrim ARMlarda VFP yoki NEON reestri yo'q edi, ba'zilari 16 ga, 32ga yaqin edi. Cortex-A8 va undan oldin NEON qidiruvi yadroning qolgan qismida o'nga yaqin CCni yoydi, shuning uchun bir GPR ga vektorli chiqishni o'tkazish juda ko'p. ARM to'g'ri ishni bajarishga kirishdi - keng tarqalgan xususiyatlar majmui.
qo'shib qo'ydi muallif DonyorM, manba

Siz doimo a platformasini maqsadlashingiz kerak. Eng oddiy holatda, maqsad protsessor bevosita ikkilikda to'plangan kodni ishlaydi (bu taxminan MS DOS'ning MAQOMOTI bajariladigan fayllariga mos keladi). Keling, men yaratgan ikki xil platformani ko'rib chiqaylik - Armistice va Intellio. Ikkala holatda ham, oddiygina salom dunyo dasturiga ega bo'lamiz. Shuningdek, siz platforma-agnostik usulda ko'p platformali tildan foydalanayotganingizni taxmin qilaman, shuning uchun manba kodi ikkalasi uchun ham bir xil:

Print(42)

Qurolli to'qnashuvlarda sizda bosma raqamlarga e'tibor beradigan oddiy qurilma drayveri bor, shuning uchun faqat bitta portga chiqish kerak. Portativ assambleyamiz tilida, bu quyidagilarga javob beradi:

out 1234h, 42

Biroq, Intellio tizimida bunday narsa yo'q, shuning uchun boshqa qatlamlardan o'tish kerak:

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

Afsuski, ikkalamiz o'rtasida ham juda katta farq bor, hatto biz mashina kodiga ega bo'lishimizdan oldin! Bu taxminan Linux va MS DOS, yoki IBM PC va X-Box o'rtasida mavjud bo'lgan farqlarga mos keladi (har ikkisi ham bir xil CPUdan foydalansa ham).

Biroq, bu operatsion tizimlar uchun. Keling, har xil apparat konfiguratsiyasi dastur qatlamida bir xil tarzda ishlashiga ishonch hosil qiladigan HAL borligini tasavvur qilaylik, asosan, Intellio yondashuvini hatto Armistice da qo'llaymiz va bizning "portativ qurilma" kodimiz bir xil bo'ladi. Bu, ham zamonaviy Unix-o'xshash tizimlar va Windows tomonidan ishlatiladi, ko'pincha ko'milgan senariylarda ham. Yaxshi - Endi biz har ikkala urush va Intellio da bir xil chindan ham ko'chma o'rnatish kodiga egamiz. Ammo ikkiliklar haqida nima deyish mumkin?

Biz taxmin qilganimizdek, CPU o'zaro o'zaro to'g'ridan-to'g'ri ishlashi kerak. Keling, kodimizning birinchi satrini ko'rib chiqaylik, mov a, 10h , Intellio da:

20 10

Oh. mov a, constant - bu o'z pop-kodi bilan o'z ko'rsatmalariga ega ekanligi juda mashhurligini ko'rsatadi. Mudofaa bu qanday ishlaydi?

36 01 00 10

Hmm. mov.reg.imm uchun opcode mavjud, shuning uchun biz tayinlagan reestrni tanlash uchun yana bir dalil kerak. Har doim sobit - ikki baytli so'z, har doim katta harflar bilan nishonlanadi - bu qanday qilib armiyani ishlab chiqdi, aslida barcha harbiy vositalardagi ko'rsatmalar 4 bayttan iborat, istisnolar yo'q.

Keling, Intellio-dan sulh bitiklarida o'zaro ishlashni tasavvur qiling: protsessor ko'rsatmalarni dekodlashni boshlaydi, opcode 20h ni topadi. Mütarekede, bu and.imm.reg ko'rsatmalariga mos keladi. Ikki baytli so'zni sobit (u 10XX o'qib chiqadigan muammodir) va keyin ro'yxatdan o'tish raqamini (boshqa XX ) o'qishga harakat qiladi. Biz noto'g'ri dalillar bilan noto'g'ri ko'rsatma ijro etmoqdamiz. Va bundan ham yomoni, keyingi ko'rsatma to'liq soxta bo'ladi, chunki biz haqiqatan ham boshqa ma'lumot ko'rsatib, ma'lumotni deb o'ylab qoldik.

Dasturda ishlash imkoniyati yo'q, va bu, ehtimol, tezda qulab tushishi yoki osib qo'yilishi mumkin.

Endi, bu bajariladigan har doim Intellio yoki sivilizatsiyaga tegishli deb aytish kerak degani emas. Siz faqat CPU (masalan, bash Unix-da) yoki CPU va OS (Java yoki. NET kabi, va hatto hatto JavaScript-ni kabi) mustaqil mustaqil platformani aniqlashingiz kerak. Bu holda, dastur turli xil protsessorlar va operatsion tizimlar uchun bitta dasturiy ta'minotdan foydalanishi mumkin, ammo maqsadli tizimda (to'g'ri CPU va/yoki OS ni to'g'ridan-to'g'ri maqsadga yo'naltiradigan) dastur yoki xizmat mavjud bo'lsa, platformadan mustaqil kodni CPU aslida bajarishi mumkin. Bu ishlashga, narxga yoki qobiliyatga zarar etkazishi mumkin yoki bo'lmasligi mumkin.

CPU odatda oilada bo'ladi. Misol uchun, x86 oilasidagi barcha CPUlar xuddi shu tarzda kodlangan keng tarqalgan ko'rsatmalar to'plamiga ega, shuning uchun har bir x86 protsessor har qanday kengaytmani ishlatishga harakat qilmasa har bir x86 dasturini ishga tushirishi mumkin (masalan, suzuvchi nuqta operatsiyalari yoki vektor operatsiyalari). X86-da, bugungi kunda eng keng tarqalgan misollar - Intel va AMD. Atmel ARM oilasida CPU ishlab chiqaruvchi taniqli kompaniya bo'lib, ko'milgan qurilmalar uchun juda mashhur. Apple shuningdek o'zlarining ARM protsessorlariga ega, masalan.

Ammo ARM x86 bilan mutlaqo mos kelmaydi - ular juda ko'p turli dizayn talablariga ega va juda kam umumiydir. Ko'rsatmalar butunlay boshqacha opcodlara ega, ular boshqa yo'l bilan kod hal qilinmoqda, xotira manzillari boshqacha muomala qilinadi ... X86 protsessor va ARM protsessorida ishlaydigan ikkilikni amalga oshirish mumkin. Ikkala tomonni ajratib olish va ikkita turli xil ko'rsatmalarga o'tish, ammo bu hali hammasi uchun har ikkala versiya uchun alohida yo'riqnomangiz borligini anglatadi.

7
qo'shib qo'ydi

Bu savolni yanada tanish bo'lishi mumkin bo'lgan muhitga qayta burish mumkin. Xuddi shunday:

"Menda ishlashni istagan ruby dasturi bor, lekin platformamda faqat Python tarjimoni bor, Python tarjimonini ruby dasturini ishlatishim mumkinmi yoki Python'dagi dasturimni qayta yozishim kerakmi?"

Buyruqlar majmui arxitekturasi ("maqsad") tildir - "mashina tili" - va turli CPUlar turli tillarni qo'llaydi. Ya'ni, Intel ikkilikini ishlatish uchun ARM protsessorini so'rash Python tarjimoni yordamida ruby dasturini ishlatish uchun juda o'xshash.

3
qo'shib qo'ydi

gcc ma'lum protsessorning "buyruqlar to'plamini" anglatadigan "me'morchilik" so'zlarini ishlatadi va "maqsad" CPU va arxitekturaning kombinatsiyasini o'z ichiga oladi, ABI, libc, endianess va boshqa kabi o'zgaruvchilardan iborat. (ehtimol, "yalang'och metal" ni o'z ichiga oladi). Odatda derleyici cheklangan maqsad majmuasiga ega (ehtimol bitta ABI, bitta CPU oilasi, balki ehtimol 32 va 64 bit). Cross-compiler odatda ishlaydigan tizimdan boshqa maqsadga ega bo'lgan kompilyatorni yoki bir nechta maqsadli yoki ABI-lardan biri (shuningdek, this ).

Ikkiliklar turli CPU arxitekturalarida ko'chiradimi?

Odatda, yo'q. An'anaviy atamalardagi ikkilik, ma'lum bir CPU yoki CPU oilasi uchun tabiiy ob'ekt kodi dir. Biroq, ular o'rtacha darajada yuqori portativ bo'lishi mumkin bo'lgan bir necha holatlar mavjud:

  • one architecture is a superset of another (commonly x86 binaries target i386 or i686 rather than the latest and greatest x86, e.g. -march=core2)
  • one architecture provides native emulation or translation of another (you might have heard of Crusoe), or provides compatible co-processors (e.g. PS2)
  • the OS and runtime support multiarch (e.g. ability to run 32-bit x86 binaries on x86_64), or make the VM/JIT seamless (Android using Dalvik or ART)
  • there is support for "fat" binaries which essentially contain duplicate code for each supported architecture

Agar siz bu muammoni echishga muvaffaq bo`lsangiz boshqa portativ ikkilik muammo Ko'p sonli kutubxona versiyalari (glibc men sizga qarayapman) o'z-o'zidan paydo bo'ladi. (Ko'pgina ko'milgan tizimlar sizni ushbu muammodan xalos qiladi).

Agar siz allaqachon mavjud bo'lmasa, hozirda gcc -dumpspecs va gcc -target-help ni ishlatish uchun yaxshi vaqt.

Yog 'ikkilamchi tomonlari turli kamchiliklari bor , lekin hali ham potentsial foydalanishi mumkin ( EFI ).

Boshqa javoblardan boshqa ikkita fikr mavjud: ELF va ELF tarjimoni va Linux yadrosi o'zboshimchalik bilan qo'llab-quvvatlanadi. Ikkilik formatlar . Men bu yerda haqiqiy bo'lmagan protsessorlar uchun ikkiliklar yoki baytode haqida batafsil ma'lumotga ega bo'lmayman, ammo ularni "ona" deb bilish va Java yoki , bu ikkiliklar apparat me'morchiligi bilan bog'liq emas (lekin uning o'rniga tegishli VM versiyasiga bog'liq, natijada mahalliy ikkilikni boshqaradi).

Zamonaviy Linux tizimi ELF ikkiliklaridan foydalanadi (texnik tafsilotlar bu PDF-da ), dinamik alf ikkiliklari bo'lsa, yadro tasvirni xotiraga yuklashga mas'uldir, lekin ELF sarlavhalarida o'rnatilgan "tarjimon" ishi og'ir o'chirishni amalga oshiradi. Odatda bu barcha qaram dinamik kutubxonalar mavjudligiga ishonch hosil qilishni o'z ichiga oladi (kutubxonalar va kerakli belgilarni sanab o'tadigan boshqa tuzilmalarni sanab o'tadigan "dinamik" bo'limi yordamida) - bu deyarli deyarli Umumiy maqsadlar uchun indiretsion qatlami.

$ 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 da ELF ikkilik, uning tarjimonlari yo'q va mahalliy ikkilik koddir.)

ELF bilan bog'liq muammo ikkilik ichidagi ( readelf -h/bin/ls ) ustunni ma'lum bir arxitektura, sinf (32- yoki 64 bit), endianess va ABI (Apple "universal" yog 'ikkiliklari muqobil ikkilik formatda foydalanadi, buning o'rniga Mach-O < bu muammo, bu NextSTEP dan kelib chiqdi). Buning ma'nosi, bir ELF olib boriladi, çalıştırılacak tizimi eşleşmelidir. Agar qochish latchi tarjimon bo'lsa, bu har qanday executable (shu jumladan dastlab ikkilikning o'ziga xos kichik qismlarini chiqaradigan yoki xaritalar xaritasi chiqaradigan yoki chiqaradigan) va lekin Sizning sistemangizni ishlashga ruxsat beradi. (FreeBSD-ning qiziqarli uslubi Linux alf fayllarini ishlash , < code> brandelf , ELF ABI maydonini o'zgartiradi.)

There is (using binfmt_misc) support for Mach-O on linux, there's an example there that shows you how to create and run a fat (32- & 64-bit) binary. Resource forks/ADS, as originally done on the Mac, could be a workaround, but no native Linux filesystem supports this.

Bundan tashqari, yadro modullari uchun ham xuddi shunday narsa qo'llaniladi, .ko fayllari ham ELF (hech qanday tarjimon o'rnatilmagan bo'lsa ham). Bu holatda qidirish yo'lida yadro versiyasidan foydalanadigan qo'shimcha qatlam mavjud bo'lib, uni nazariy jihatdan versiya bilan almashtirish mumkin, ammo ba'zi murakkablik va kam daromad bilan gumon qilmoqdaman .

Boshqa joylarda qayd etilganidek, Linux yog 'ikkiliklarini qo'llab-quvvatlamaydi, lekin u erda faol yog '-ikkilik loyihadir: YoRDAM . yillar atrofida , hech qachon standart yadroga hech qachon qo'shilmadi (qisman muddati tugagan) patent muammolari. Shu vaqt ichida yadro va asboblar bilan ishlashni talab qiladi. Bu binfmt_misc yondashuvini ishlatmaydi, shu bilan birga ELF sarlavhasi muammolarini echadi va yog 'yadrolari modullariga ham ruxsat beradi.

      
  1. Agar "x86 maqsadli, Linux OS versiyasi x.y.z" da ishlash uchun tuzilgan dasturga ega bo'lsam, boshqa tizim "ARM maqsadi, Linux operatsion tizimi versiyasi x.y.z" da bir xil kompilyatsiya ikkilikni ishlatishim mumkinmi?
  2.   

ELF bilan emas, bu sizga ruxsat bermaydi.

      
  1. Yuqoridagi holatlar to'g'ri bo'lmasa, dasturiy manba kodini masalan, "arm-linux-gnueabi" kabi tegishli asboblar paneli yordamida qayta qurish/qayta tuzish uchun olish kerakmi?
  2.   

Oddiy javob ha. (Murakkab javoblar quyidagilarni o'z ichiga oladi: emulyatsiya, oraliq vakillar, translators va JIT, "i686 ikkilik faqat i386 opcodlarini ishlatishi mumkin, chunki ular bu erda qiziqarli emas va ABI fixups mahalliy kodni tarjima qilishda qiyin bo'lishi mumkin.)

      
  1. Shunga o'xshab, 'x86 maqsadli, Linux operatsion tizimi versiyasi xyz' da ishlaydigan yuklanadigan yadro moduli (qurilma drayveri) bo'lsa, boshqa tizimning ARM maqsadidagi, OS versiyasi xyz '?
  2.   

Yo'q, ELF bu ishni qilishga ruxsat bermaydi.

      
  1. Yuqoridagi holatlar to'g'ri bo'lmasa, faqatgina "arm-linux-gnueabi" kabi tegishli asboblar paneli yordamida qayta tiklash/qayta tiklash uchun haydovchi manba kodini olish kerakmi?
  2.   

Oddiy javob ha. FATELF sizga juda ko'p arxitektura bo'lgan .ko ni yaratishga imkon beradi deb o'ylayman, lekin bir nuqtada har qanday qo'llab-quvvatlanadigan arxitektura uchun ikkilangan versiya yaratilishi kerak. Yadro modullarini talab qiladigan narsalar ko'pincha manbaga ega bo'ladi va kerak bo'lganda quriladi, masalan. VirtualBox buni amalga oshiradi.

This is already a long rambling answer, there's only one more detour. The kernel already has a virtual machine built in, albeit a dedicated one: the BPF VM which is used to match packets. The human readable filter "host foo and not port 22") is compiled to a bytecode and the kernel packet filter executes it. The new eBPF is not just for packets, in theory that VM code is portable across any contemporary linux, and llvm supports it but for security reasons it's probably not going to be suitable for anything other than administrative rules.


Endi ikkilik bajariladigan ta'rifi bilan qanchalik saxiy ekanligingizga bog'liq ravishda, qobiq skripti bilan yog 'o'zaro yordamni va ZIP fayllarini konteyner formati sifatida ishlatish uchun binfmt_misc dan foydalanishingiz mumkin:

#!/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}" "[email protected]" 
  )
  rc=$?
  #rm -rf -- "${root}/${prog}"       # for the brave
  exit $rc
}

Ushbu "wozbin" deb nomlang va uni quyidagicha sozlang:

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

Ushbu kod .woz fayllarini yadro bilan qayd qiladi, wozbin skripti uning birinchi argumentini chaqirilgan .woz faylining yo'liga o'rnatiladi .

Portativ (yog ') .woz faylini olish uchun faqat katalog hiyerarşisiyle test.woz ZIP faylini yarating.

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

Har bir arch/OS/libc katalogida (o'zboshimchalik bilan tanlangan) arxitektura uchun maxsus test ikkilik va .so fayllari kabi tarkibiy qismlarni joylashtiring. Siz uni chaqirganingizda, kerakli kichik katalog tmpfs ning xotirasidagi fayl tizimiga (bu erda /mnt/tmpfs ) bu yerda chiqariladi va chaqiriladi.

2
qo'shib qo'ydi