क्या अलग-अलग सीपीयू आर्किटेक्चर में बायनेरी पोर्टेबल हैं?


16

मेरा लक्ष्य एम्बेडेड लिनक्स के लिए विकसित करने में सक्षम होना है। मुझे एआरएम का उपयोग करते हुए नंगे-धातु एम्बेडेड सिस्टम पर अनुभव है।

मेरे पास विभिन्न सीपीयू लक्ष्यों के विकास के बारे में कुछ सामान्य प्रश्न हैं। मेरे प्रश्न नीचे दिए गए हैं:

  1. अगर मेरे पास ' x86 टारगेट, लिनक्स ओएस संस्करण xyz ' पर चलने के लिए संकलित कोई एप्लिकेशन है , तो क्या मैं उसी संकलित बाइनरी को किसी अन्य सिस्टम ' ARM टारगेट, linux OS वर्जन xyz ' पर चला सकता हूं ?

  2. यदि ऊपर सच नहीं है, तो एकमात्र तरीका यह है कि प्रासंगिक टूलकिन 'उदाहरण के लिए, आर्म-लिनेक्स-गुनैबी' का उपयोग करके पुनर्निर्माण / पुनर्निर्माण के लिए एप्लिकेशन स्रोत कोड प्राप्त किया जाए?

  3. इसी तरह, अगर मेरे पास एक लोड करने योग्य कर्नेल मॉड्यूल (डिवाइस ड्राइवर) है जो ' x86 टारगेट, लिनक्स ओएस संस्करण xyz ' पर काम करता है , तो क्या मैं उसी संकलित .ko को किसी अन्य सिस्टम ' ARM टारगेट, linux OS संस्करण yyz ' पर लोड / उपयोग कर सकता हूं। ?

  4. अगर ऊपर सच नहीं है, तो एकमात्र तरीका यह है कि संबंधित टूलकिन 'उदाहरण के लिए, आर्म-लिनेक्स-गुनैबी' का उपयोग करके पुनर्निर्माण / पुनर्निर्माण के लिए ड्राइवर स्रोत कोड प्राप्त किया जाए?


27
नहीं, हाँ, नहीं, हाँ।
जूल

7
यह महसूस करने में मदद करता है कि हमारे पास एएमडी लक्ष्य और इंटेल लक्ष्य नहीं है, दोनों के लिए बस एक एकल x86 लक्ष्य है। ऐसा इसलिए है क्योंकि इंटेल और एएमडी पर्याप्त रूप से संगत हैं। तब यह स्पष्ट हो जाता है कि ARM का लक्ष्य एक विशेष कारण से मौजूद है, क्योंकि ARM CPU इंटेल / AMD / x86 के साथ संगत नहीं है।
MSalters

1
नहीं, जब तक कि यह bytecode जावा रनटाइम जैसे पोर्टेबल रनटाइम वातावरण पर चलने के लिए डिज़ाइन नहीं किया गया है। यदि आप एम्बेडेड उपयोग के लिए कोड लिख रहे हैं, तो आपका कोड संभवतः निम्न-स्तरीय प्रोसेसर-विशिष्ट अनुकूलन या सुविधाओं पर निर्भर करेगा और पोर्ट के लिए बहुत मुश्किल होगा, लक्ष्य प्लेटफ़ॉर्म के लिए अधिक संकलन की आवश्यकता होती है (जैसे असेंबली कोड परिवर्तन, संभवतः पुनर्लेखन कई मॉड्यूल या पूरे कार्यक्रम)।
bwDraco

1
@MSalters: वास्तव में, हमारे पास एक AMD लक्ष्य है: amd64 जिसे अक्सर x86-64 लेबल किया जाता है (जबकि x86 आमतौर पर i386 का पुन: लेबलिंग होता है)। सौभाग्य से इंटेल ने AMD आर्किटेक्चर को कॉपी किया (और बाद में विस्तार किया) ताकि कोई भी 64 बिट x86 amd64 बायनेरिज़ चला सके।
स्लीपबेटमैन

जवाबों:


42

नहीं, बायनेरिज़ को लक्ष्य आर्किटेक्चर के लिए (पुनः) संकलित किया जाना चाहिए, और लिनक्स बॉक्स से फैट बायनेरिज़ की तरह कुछ भी नहीं प्रदान करता है । इसका कारण यह है कि कोड एक विशिष्ट वास्तुकला के लिए मशीन कोड के लिए संकलित किया गया है, और मशीन कोड अधिकांश प्रोसेसर परिवारों के बीच बहुत अलग है (उदाहरण के लिए एआरएम और x86 बहुत अलग हैं)।

EDIT: यह ध्यान देने योग्य है कि कुछ आर्किटेक्चर पिछड़े संगतता (और यहां तक ​​कि दुर्लभ, अन्य आर्किटेक्चर के साथ संगतता) के स्तर की पेशकश करते हैं; 64-बिट सीपीयू पर, 32-बिट संस्करणों के लिए पश्चगामी संगतता होना आम है (लेकिन याद रखें: आपके आश्रित पुस्तकालयों को भी 32-बिट होना चाहिए, जिसमें आपका सी मानक पुस्तकालय भी शामिल है, जब तक कि आप सांख्यिकीय रूप से लिंककरें )। यह भी ध्यान देने योग्य है कि इटेनियम , जहां x86 कोड (केवल 32-बिट) चलाना संभव था, यद्यपि बहुत धीरे-धीरे; x86 कोड की खराब निष्पादन गति कम से कम इस कारण से थी कि यह बाजार में बहुत सफल नहीं था।

ध्यान रखें कि आप अभी भी पुराने सीपीयू पर नए निर्देशों के साथ संकलित बायनेरिज़ का उपयोग नहीं कर सकते हैं, यहां तक ​​कि संगतता मोड में भी (उदाहरण के लिए, आप नेहल x86 प्रोसेसर पर 32-बिट बाइनरी में एवीएक्स का उपयोग नहीं कर सकते हैं ; सीपीयू सिर्फ इसका समर्थन नहीं करता है।

ध्यान दें कि संबंधित आर्किटेक्चर के लिए कर्नेल मॉड्यूल संकलित होने चाहिए; इसके अलावा, 32-बिट कर्नेल मॉड्यूल 64-बिट कर्नेल या इसके विपरीत काम नहीं करेगा।

क्रॉस-कंपाइलिंग बायनेरिज़ के बारे में जानकारी के लिए (ताकि आपके पास लक्ष्य एआरएम डिवाइस पर एक टूलकिन न हो), नीचे ग्रोमल का व्यापक उत्तर देखें।


1
यह x86 और x64 के बीच किसी भी संगतता (या इसके अभाव) के बारे में स्पष्ट करने के लायक हो सकता है, यह देखते हुए कि कुछ x86 बायनेरिज़ x64 प्लेटफ़ॉर्म पर चल सकते हैं। (मुझे यकीन नहीं है कि लिनक्स पर यह मामला है, लेकिन यह उदाहरण के लिए विंडोज पर है।)
jpmc26

4
@ jpmc26 यह लिनक्स पर संभव है; लेकिन आपको पहले संगतता लाइब्रेरी स्थापित करने की आवश्यकता हो सकती है। x86 समर्थन Win64 इंस्टॉल का एक गैर-वैकल्पिक हिस्सा है। लिनक्स में यह वैकल्पिक है; और क्योंकि लिनक्स दुनिया के बहुत दूर के 64 बिट संस्करणों को उपलब्ध कराने के साथ कुछ डिस्ट्रोस होने के लिए डिफ़ॉल्ट नहीं है (सभी?) 32 बिट लाइब्रेरी स्थापित हैं। (मुझे यकीन नहीं है कि यह कितना आम है; लेकिन इससे पहले मुख्यधारा के डिस्ट्रोस चलने वाले लोगों से इसके बारे में कुछ प्रश्न देखे गए हैं।)
दान

@ jpmc26 मैंने आपके नोट्स के साथ अपना उत्तर अपडेट किया; मैंने उसका उल्लेख करने के बारे में सोचा था लेकिन जवाब को जटिल नहीं करना चाहता था।
एलिसाफॉक्स

16

एलिजाबेथ मायर्स सही है, प्रत्येक आर्किटेक्चर को प्रश्न में आर्किटेक्चर के लिए एक संकलित बाइनरी की आवश्यकता होती है। एक अलग आर्किटेक्चर के लिए बायनेरिज़ बनाने के लिए आपके सिस्टम पर चलने की ज़रूरत है cross-compiler


ज्यादातर मामलों में आपको एक क्रॉस कंपाइलर संकलित करने की आवश्यकता होती है। मेरे पास केवल अनुभव है gcc(लेकिन मेरा मानना ​​है कि llvm, और अन्य संकलक, समान पैरामीटर हैं)। एक gccपार संकलक जोड़कर हासिल की है --targetकॉन्फ़िगर करें:

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

आप संकलन करने की जरूरत gcc, glibcऔर binutilsइन मानकों के साथ (और लक्ष्य मशीन पर गिरी के कर्नेल हेडर प्रदान करते हैं)।

व्यवहार में यह बहुत अधिक जटिल है और विभिन्न बिल्ड त्रुटियाँ विभिन्न प्रणालियों पर पॉप आउट होती हैं।

जीएनयू टूलकिन को संकलित करने के तरीके के बारे में कई गाइड हैं, लेकिन मैं लिनक्स को स्क्रैच से सुझाऊंगा , जो निरंतर बनाए रखा जाता है और यह समझाने में बहुत अच्छा काम करता है कि प्रस्तुत कमांड क्या करते हैं।

एक अन्य विकल्प क्रॉस-कंपाइलर का बूटस्ट्रैप संकलन है। विभिन्न आर्किटेक्चर पर अलग-अलग आर्किटेक्चर के लिए क्रॉस कंपाइलरों के संकलन के संघर्ष के लिए धन्यवाद crosstool-ngबनाया गया था। यह एक क्रॉस कंपाइलर बनाने के लिए आवश्यक टूलचैन के ऊपर एक बूटस्ट्रैप देता है।

crosstool-ngविभिन्न आर्किटेक्चर पर कई लक्ष्य ट्रिपल का समर्थन करता है , मूल रूप से यह एक बूटस्ट्रैप है जहां लोग क्रॉस-कंपाइलर टूलचैन के संकलन के दौरान होने वाली समस्याओं को सुलझाने के लिए अपना समय समर्पित करते हैं।


कई डिस्ट्रोस पैकेज के रूप में क्रॉस-कंपाइलर प्रदान करते हैं:

दूसरे शब्दों में, क्रॉस कंपाइलर्स के संदर्भ में देखें कि आपके डिस्ट्रो में क्या उपलब्ध है। यदि आपके डिस्ट्रो में आपकी आवश्यकताओं के लिए एक क्रॉस कंपाइलर नहीं है, तो आप हमेशा इसे स्वयं संकलित कर सकते हैं।

संदर्भ:


कर्नेल मॉड्यूल ध्यान दें

यदि आप अपने क्रॉस-कंपाइलर को हाथ से संकलित कर रहे हैं, तो आपके पास कर्नेल मॉड्यूल को संकलित करने की जरूरत है। ऐसा इसलिए है क्योंकि आपको संकलन करने के लिए कर्नेल हेडर की आवश्यकता है glibc

लेकिन, यदि आप अपने डिस्ट्रो द्वारा प्रदान किए गए क्रॉस-कंपाइलर का उपयोग कर रहे हैं, तो आपको लक्ष्य मशीन पर चलने वाले कर्नेल के कर्नेल हेडर की आवश्यकता होगी।


एफडब्ल्यूआईडब्ल्यू फेडोरा में क्रॉस-कंपाइलर भी शामिल हैं।
Mattdm

@mattdm - धन्यवाद, जवाब दिया, मुझे विश्वास है कि मैं फेडोरा विकी से जुड़ा हुआ सही हिस्सा मिला।
कृष्ण जूल

2
लिनक्स से आसान तरीका है स्क्रैच से लिनक्स और टूलचिन को किसी अन्य आर्किटेक्चर के लिए प्राप्त करना है crosstool-ng। आप इसे सूची में जोड़ना चाह सकते हैं। इसके अलावा, किसी भी वास्तुकला के लिए हाथ से एक GNU क्रॉस-टूलचैन को कॉन्फ़िगर करना और संकलित करना अविश्वसनीय रूप से शामिल है और सिर्फ --targetझंडे के मुकाबले कहीं अधिक थकाऊ है । मुझे संदेह है कि एलएलवीएम लोकप्रियता क्यों हासिल कर रहा है; यह इस तरह से आर्किटेक्चर है कि आपको किसी अन्य आर्किटेक्चर को लक्षित करने के लिए पुनर्निर्माण की आवश्यकता नहीं है - इसके बजाय आप एक ही फ्रंटेंड और ऑप्टिमाइज़र लाइब्रेरी का उपयोग करके कई बैकएंड को लक्षित कर सकते हैं।
इविलनोटिक्सिस्ट इडोनोटेक्सिस्ट

@IwillnotexistIdonotexist - धन्यवाद, मैंने उत्तर को आगे बढ़ाया है। मैंने पहले कभी क्रोसस्टूल-एनजी के बारे में नहीं सुना है, और यह बहुत उपयोगी दिखता है। आपकी टिप्पणी वास्तव में मेरे लिए बहुत उपयोगी रही है।
राजघराने का जुलाब

9

नोट एक अंतिम उपाय (यानी जब आप स्रोत कोड की जरूरत नहीं है) के रूप में, आप की तरह emulators का उपयोग कर एक अलग वास्तुकला पर binaries चला सकते हैं कि qemu, dosboxया exagear। कुछ एमुलेटर को लिनक्स के अलावा अन्य सिस्टम का अनुकरण करने के लिए डिज़ाइन किया गया है (जैसे dosboxMS-DOS प्रोग्राम चलाने के लिए डिज़ाइन किया गया है, और लोकप्रिय गेमिंग कंसोल के लिए बहुत सारे एमुलेटर हैं)। अनुकरण का एक महत्वपूर्ण प्रदर्शन ओवरहेड है: उत्सर्जित कार्यक्रम अपने मूल समकक्षों की तुलना में 2-10 गुना धीमी गति से चलते हैं।

यदि आपको एक गैर-देशी सीपीयू पर कर्नेल मॉड्यूल चलाने की आवश्यकता है, तो आपको एक ही आर्किटेक्चर के लिए कर्नेल सहित पूरे ओएस का अनुकरण करना होगा। AFAIK लिनक्स कर्नेल के अंदर विदेशी कोड चलाना असंभव है।


3
उत्सर्जन के लिए गति दंड अक्सर 10x से अधिक होता है, लेकिन अगर कोई 4 जीएचजेड मशीन पर 16Mhz मशीन के लिए लिखे गए कोड को चलाने की कोशिश कर रहा है (250: 1 की गति में अंतर) एक एमुलेटर जिसमें 50: 1 की गति का जुर्माना हो सकता है मूल प्लेटफ़ॉर्म पर चलने की तुलना में यह बहुत तेज़ी से कोड चलाता है।
सुपरकैट

7

न केवल बायनेरिज़ x86 और एआरएम के बीच पोर्टेबल नहीं हैं, एआरएम के विभिन्न स्वाद हैं

अभ्यास में आपका सामना करने की संभावना ARMv6 बनाम ARMv7 है। रास्पबेरी पाई 1 ARMv6 है, बाद के संस्करण ARMv7 हैं। तो यह बाद के लोगों पर कोड संकलित करना संभव है जो Pi 1 पर काम नहीं करता है।

सौभाग्य से ओपन सोर्स और फ्री सॉफ्टवेयर का एक फायदा यह है कि आप इसे किसी भी आर्किटेक्चर पर फिर से बना सकते हैं। हालांकि इसके लिए कुछ काम करना पड़ सकता है।

(एआरएम वर्जन भ्रामक है, लेकिन अगर इंस्ट्रक्शन सेट आर्किटेक्चर (आईएसए) के बारे में बात करने वाले नंबर से पहले वी है। यदि ऐसा नहीं है, तो यह "कॉर्टेक्स एम0" या "एआरएम 926 ईजेएस" जैसे मॉडल नंबर है। मॉडल नंबर में कुछ भी नहीं है। ISA नंबर के साथ करते हैं।)


2
... और फिर एक ही एआरएम स्वाद के लिए अलग-अलग उपफल भी हैं, और सटीक एक ही हार्डवेयर के लिए अलग-अलग एबीआई (मैं पूरे एआरएम सॉफ्ट / सॉफ्टफप / हार्ड फ्लोटिंग पॉइंट मेस के बारे में सोच रहा हूं)।
मट्टियो इतालिया

1
@ मत्तो इतालिया ऊग। कई ABI एक स्नफ़ू थे, एक ऐसी चीज़ जो बीमारी से भी बदतर थी। कुछ ARM में VFP या NEON रजिस्टर नहीं थे, कुछ में 16, कुछ 32 थे। Cortex-A8 पर और इससे पहले NEON इंजन ने बाकी कोर के पीछे एक दर्जन CC चलाए, इसलिए वेक्टर आउटपुट को जीपीआर लागत पर स्थानांतरित किया गया बहुत। एआरएम ने सही काम करने के लिए गोल कर दिया है - सुविधाओं के एक बड़े सामान्य सबसेट को अनिवार्य करना।
इविलनोटिक्सिस्ट इडोनोटेक्सिस्ट जूल 27'16

7

आपको हमेशा एक प्लेटफ़ॉर्म को लक्षित करने की आवश्यकता होती है । सबसे सरल मामले में, लक्ष्य सीपीयू सीधे बाइनरी में संकलित कोड को चलाता है (यह मोटे तौर पर एमएस डॉस के COM निष्पादन के अनुरूप है)। चलो दो अलग-अलग प्लेटफार्मों पर विचार करते हैं जिन्हें मैंने अभी आविष्कार किया है - आर्मिस्टिस और इंटेलियो। दोनों मामलों में, हमारे पास एक साधारण हैलो वर्ल्ड प्रोग्राम होगा जो स्क्रीन पर 42 आउटपुट करता है। मैं यह भी मानूंगा कि आप प्लेटफॉर्म-अज्ञेय तरीके से एक बहु-मंच भाषा का उपयोग कर रहे हैं, इसलिए स्रोत कोड दोनों के लिए समान है:

Print(42)

आर्मिस्टिस पर, आपके पास एक साधारण डिवाइस ड्राइवर होता है जो प्रिंटिंग नंबरों का ध्यान रखता है, इसलिए आपको बस एक पोर्ट पर आउटपुट करना होगा। हमारी पोर्टेबल असेंबली भाषा में, यह कुछ इस तरह के अनुरूप होगा:

out 1234h, 42

हालाँकि, या Intellio सिस्टम में ऐसी कोई बात नहीं है, इसलिए इसे अन्य परतों से गुजरना पड़ता है:

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

ओह, हम पहले से ही दोनों के बीच एक महत्वपूर्ण अंतर है, इससे पहले कि हम भी मशीन कोड के लिए! यह मोटे तौर पर लिनक्स और एमएस डॉस, या आईबीएम पीसी और एक एक्स-बॉक्स के बीच अंतर के अनुरूप होगा (भले ही दोनों एक ही सीपीयू का उपयोग कर सकते हैं)।

लेकिन यही OSes के लिए है। मान लें कि हमारे पास एक एचएएल है जो यह सुनिश्चित करता है कि सभी अलग-अलग हार्डवेयर कॉन्फ़िगरेशन को एक ही तरह से एप्लीकेशन लेयर पर हैंडल किया जाता है - मूल रूप से, हम आर्मिस्टिस पर भी इन्टेलियो दृष्टिकोण का उपयोग करेंगे, और हमारा "पोर्टेबल असेंबली" कोड समान होता है। यह आधुनिक यूनिक्स जैसी प्रणालियों और विंडोज दोनों द्वारा उपयोग किया जाता है, अक्सर एम्बेडेड परिदृश्यों में भी। अच्छा - अब हमारे पास आर्मिस्टिस और इन्टेलियो दोनों पर समान रूप से पोर्टेबल असेंबली कोड हो सकता है। लेकिन बायनेरिज़ के बारे में क्या?

जैसा कि हमने माना है, सीपीयू को सीधे बाइनरी को निष्पादित करने की आवश्यकता है। आइए हमारे कोड की पहली पंक्ति को देखें,mov a, 10h Intellio पर देखें:

20 10

ओह। पता चला है कि mov a, constantयह इतना लोकप्रिय है कि इसका अपना निर्देश है, अपने स्वयं के ओपकोड के साथ। आर्मिस्टिस इसे कैसे संभालता है?

36 01 00 10

हम्म। के लिए opcode हैmov.reg.imm , इसलिए हमें उस रजिस्टर का चयन करने के लिए एक और तर्क की आवश्यकता है जिसे हम असाइन कर रहे हैं। और स्थिरांक हमेशा एक 2-बाइट शब्द होता है, बड़े-एंडियन संकेतन में - कि सिर्फ आर्मिस्टिस को कैसे डिज़ाइन किया गया था, वास्तव में, आर्मिस्टिस में सभी निर्देश 4 बाइट्स लंबे होते हैं, कोई अपवाद नहीं।

अब आर्मिस्टिस पर इंटेलियो से बाइनरी को चलाने की कल्पना करें: सीपीयू निर्देश को डिकोड करना शुरू करता है, ओपकोड पाता है 20h। आर्मिस्टिस पर, यह and.imm.regनिर्देश के अनुरूप, कहता है । यह 2-बाइट शब्द को निरंतर पढ़ने की कोशिश करता है (जो पढ़ता है10XX , पहले से ही एक समस्या है), और फिर रजिस्टर नंबर (दूसरा XX)। हम गलत निर्देशों के साथ, गलत निर्देश निष्पादित कर रहे हैं। और इससे भी बदतर, अगला निर्देश पूरा फर्जी होगा, क्योंकि हमने वास्तव में एक और निर्देश खाया था, यह सोचकर कि यह डेटा था।

एप्लिकेशन के पास काम करने का कोई मौका नहीं है, और यह लगभग तुरंत दुर्घटना या लटकने की संभावना है।

अब, इसका मतलब यह नहीं है कि एक निष्पादन योग्य को हमेशा यह कहने की ज़रूरत है कि यह इंटेलियो या आर्मिस्टिस पर चलता है। आपको बस एक ऐसे प्लेटफॉर्म को परिभाषित करना होगा जो सीपीयू से स्वतंत्र हो (जैसेbash यूनिक्स पर), या सीपीयू और ओएस (जैसे जावा या .NET, और आजकल भी जावास्क्रिप्ट, तरह) दोनों। इस स्थिति में, एप्लिकेशन सभी अलग-अलग सीपीयू और ओएस के लिए एक निष्पादन योग्य का उपयोग कर सकता है, जबकि लक्ष्य प्रणाली पर कुछ एप्लिकेशन या सेवा है (जो सीधे सीपीयू और / या ओएस को लक्षित करता है) जो कि प्लेटफ़ॉर्म-इंडिपेंडेंट कोड को कुछ में अनुवाद करता है। सीपीयू वास्तव में निष्पादित कर सकता है। यह प्रदर्शन, लागत या क्षमता के लिए एक हिट के साथ आ सकता है या नहीं।

सीपीयू आमतौर पर परिवारों में आते हैं। उदाहरण के लिए, x86 परिवार के सभी सीपीयू में निर्देशों का एक सामान्य सेट होता है जो बिल्कुल उसी तरह से एन्कोडेड होते हैं, इसलिए हर x86 सीपीयू हर x86 प्रोग्राम को चला सकता है, जब तक कि यह किसी भी एक्सटेंशन का उपयोग करने की कोशिश नहीं करता है (उदाहरण के लिए, फ्लोटिंग पॉइंट ऑपरेशंस या वेक्टर ऑपरेशन)। X86 पर, आज का सबसे सामान्य उदाहरण इंटेल और एएमडी हैं। एएएमआर एक प्रसिद्ध कंपनी है जो एआरएम परिवार में सीपीयू को डिजाइन करती है, एम्बेडेड उपकरणों के लिए काफी लोकप्रिय है। उदाहरण के लिए Apple के पास स्वयं के ARM CPU भी हैं।

लेकिन एआरएम x86 के साथ पूरी तरह से असंगत है - उनके पास बहुत अलग डिजाइन आवश्यकताएं हैं, और बहुत कम हैं। निर्देशों में पूरी तरह से अलग-अलग ऑपकोड हैं, उन्हें एक अलग तरीके से डिकोड किया गया है, मेमोरी पतों को अलग तरह से व्यवहार किया जाता है ... एक बाइनरी बनाना संभव हो सकता है जो x86 सीपीयू और एआरएम सीपीयू दोनों पर चलता है, कुछ सुरक्षित संचालन का उपयोग करके दोनों के बीच अंतर करें और निर्देशों के दो पूरी तरह से अलग-अलग सेट करने के लिए कूदें, लेकिन इसका मतलब है कि आपके पास दोनों संस्करणों के लिए अलग-अलग निर्देश हैं, बस एक बूटस्ट्रैपर जो रनटाइम पर सही सेट को चुनता है।


3

इस प्रश्न को एक ऐसे वातावरण में फिर से डालना संभव है जो अधिक परिचित हो सकता है। समानता से:

"मेरे पास एक रूबी कार्यक्रम है जिसे मैं चलाना चाहता हूं, लेकिन मेरे मंच में केवल पायथन दुभाषिया है। क्या मैं अपने रूबी कार्यक्रम को चलाने के लिए पायथन दुभाषिया का उपयोग कर सकता हूं, या क्या मुझे पायथन में अपने कार्यक्रम को फिर से लिखना है?"

एक निर्देश सेट वास्तुकला ("लक्ष्य") एक भाषा है - एक "मशीन भाषा" - और विभिन्न सीपीयू विभिन्न भाषाओं को लागू करते हैं। इसलिए एआरएम सीपीयू को इंटेल बाइनरी चलाने के लिए कहना बहुत पसंद है, जो पायथन इंटरप्रेटर का उपयोग करके रूबी प्रोग्राम चलाने की कोशिश कर रहा है।


2

gcc '' आर्किटेक्चर '' शब्द का उपयोग विशिष्ट CPU के '' निर्देश सेट '' के लिए करता है, और "लक्ष्य" में CPU और आर्किटेक्चर के संयोजन को शामिल किया गया है, जैसे कि ABI, libc, एंडियन-नेस और अन्य जैसे अन्य चर (संभवतः "नंगे धातु" सहित)। एक विशिष्ट संकलक में लक्ष्य संयोजनों का एक सीमित सेट होता है (शायद एक एबीआई, एक सीपीयू परिवार, लेकिन संभवतः दोनों 32- और 64-बिट)। एक पार संकलक आमतौर पर साधन या तो सिस्टम के अलावा किसी अन्य लक्ष्य के साथ एक संकलक यह कई लक्ष्यों या कपड़े के साथ एक (यह भी देखें पर चलता है, या इस )।

क्या अलग-अलग सीपीयू आर्किटेक्चर में बायनेरी पोर्टेबल हैं?

सामान्य तौर पर, नहीं। पारंपरिक शब्दों में एक बाइनरी एक विशेष सीपीयू या सीपीयू परिवार के लिए मूल वस्तु कोड है। लेकिन, ऐसे कई मामले हैं जहां वे अत्यधिक पोर्टेबल के लिए मामूली हो सकते हैं:

  • एक आर्किटेक्चर दूसरे का सुपरसेट है (आमतौर पर x86 बायनेरी लक्ष्य i386 या i686 के बजाय नवीनतम और सबसे बड़ा x86 का लक्ष्य है, उदाहरण के लिए -march=core2)
  • एक आर्किटेक्चर मूल इम्यूलेशन या दूसरे का अनुवाद (आप क्रूसो के बारे में सुना हो सकता है ) प्रदान करता है, या संगत सह-प्रोसेसर प्रदान करता है (जैसे PS2 )
  • OS और रनटाइम मल्टीकार का समर्थन करते हैं (उदाहरण के लिए x86_64 पर 32-बिट x 86 बायनेरिज़ चलाने की क्षमता), या VM / JIT को सहज बनाएं ( Dalvik या ART का उपयोग करके Android )
  • "वसा" बायनेरिज़ के लिए समर्थन है जिसमें अनिवार्य रूप से प्रत्येक समर्थित वास्तुकला के लिए डुप्लिकेट कोड होते हैं

यदि आप किसी तरह इस समस्या को हल करने का प्रबंधन करते हैं, तो दूसरी पोर्टेबल बाइनरी समस्या है असंख्य पुस्तकालय संस्करणों की (glibc मैं आपको देख रहा हूं) आप स्वयं मौजूद होंगे। (अधिकांश एम्बेडेड सिस्टम आपको उस विशेष समस्या से कम से कम बचाते हैं।)

यदि आप पहले से नहीं हैं, तो अब दौड़ने gcc -dumpspecsऔर gcc --target-helpयह देखने के लिए एक अच्छा समय है कि आप क्या कर रहे हैं।

फैट बायनेरिज़ में विभिन्न कमियां हैं , लेकिन अभी भी संभावित उपयोग ( ईएफआई ) हैं।

दो अन्य विचार हालांकि अन्य उत्तरों से गायब हैं: ELF और ELF दुभाषिया, और मनमाने ढंग से द्विआधारी प्रारूपों के लिए लिनक्स कर्नेल समर्थन । मैं यहाँ गैर-वास्तविक प्रोसेसर के लिए बायनेरिज़ या बायटेकोड के बारे में विस्तार से नहीं जाऊँगा, हालाँकि इनको "देशी" मानना ​​और जावा या संकलित पायथन बायटेकोड बायनेरिज़ को निष्पादित करना संभव है , ऐसे बायनेरी हार्डवेयर आर्किटेक्चर से स्वतंत्र होते हैं (लेकिन निर्भर करते हैं प्रासंगिक वीएम संस्करण पर, जो अंततः एक देशी बाइनरी चलाता है)।

कोई भी समकालीन Linux सिस्टम ELF बायनेरिज़ ( इस PDF में तकनीकी विवरण ) का उपयोग करेगा , डायनेमिक ELF बायनेरिज़ के मामले में कर्नेल छवि में मेमोरी को लोड करने के लिए प्रभारी है, लेकिन यह ELF बायनेरिज़ का काम है। भारी उठाने के लिए शीर्षासन करें। आम तौर पर इसमें यह सुनिश्चित करना शामिल होता है कि सभी आश्रित डायनेमिक लाइब्रेरी उपलब्ध हैं ('' डायनामिक '' सेक्शन की मदद से जो लाइब्रेरियों और कुछ अन्य संरचनाओं को सूचीबद्ध करता है जो आवश्यक प्रतीकों को सूचीबद्ध करता है) - लेकिन यह लगभग एक सामान्य उद्देश्य अप्रत्यक्ष परत है।

$ 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एक ईएलएफ बाइनरी भी है, इसमें एक दुभाषिया नहीं है, और मूल बाइनरी कोड है।)

ईएलएफ के साथ समस्या यह है कि द्विआधारी में हेडर ( readelf -h /bin/ls) एक विशिष्ट वास्तुकला, वर्ग (32- या 64-बिट), एंडियन-नेस और एबीआई (एप्पल के "सार्वभौमिक" वसा बायनेरिज़ के लिए एक वैकल्पिक द्विआधारी प्रारूप मच-ओ का उपयोग करता है) इसके बजाय जो इस समस्या को हल करता है, यह नेक्स्टस्टेप पर उत्पन्न हुआ है)। इसका मतलब यह है कि एक ईएलएफ निष्पादन योग्य को उस सिस्टम से मेल खाना चाहिए जिस पर इसे चलाया जाना है। एक एस्केप हैच दुभाषिया है, यह किसी भी निष्पादन योग्य हो सकता है (मूल रूप से द्विआधारी और उन्हें आमंत्रित करने वाले अर्क या नक्शे आर्किटेक्चर विशिष्ट सहित), लेकिन आप अभी भी ELF के प्रकार से विवश हैं, जो आपके सिस्टम को चलाने की अनुमति देगा। । (फ्रीबीएसडी के पास लिनक्स ईएलएफ फ़ाइलों को संभालने का एक दिलचस्प तरीका है , brandelfयह ईएलएफ एबीआई क्षेत्र को संशोधित करता है।)

लिनक्स पर मच-ओ के लिए (उपयोग binfmt_misc) समर्थन है , वहां एक उदाहरण है जो आपको दिखाता है कि वसा (32- और 64-बिट) द्विआधारी बनाने और चलाने के लिए कैसे। संसाधन कांटे / एडीएस , जैसा कि मूल रूप से मैक पर किया गया था, एक वर्कअराउंड हो सकता है, लेकिन कोई भी मूल लिनक्स फाइल सिस्टम इसका समर्थन नहीं करता है।

कमोबेश यही बात कर्नेल मॉड्यूल्स पर .koभी लागू होती है, फाइलें भी ELF हैं (हालांकि उनके पास कोई दुभाषिया सेट नहीं है)। इस मामले में एक अतिरिक्त परत है जो uname -rखोज पथ में कर्नेल संस्करण ( ) का उपयोग करती है, कुछ ऐसा जो सैद्धांतिक रूप से ईएलएफ के बजाय संस्करणकरण के साथ किया जा सकता है, लेकिन कुछ जटिलता और थोड़े से लाभ पर मुझे संदेह है।

जैसा कि कहीं और उल्लेख किया गया है, लिनक्स मूल रूप से वसा बायनेरिज़ का समर्थन नहीं करता है, लेकिन एक सक्रिय वसा-बाइनरी प्रोजेक्ट है: फैटीएलएफ । यह लगभग वर्षों से है , इसे कभी-कभी पेटेंट चिंताओं के कारण मानक कर्नेल में आंशिक रूप से एकीकृत नहीं किया गया था। इस समय इसके लिए कर्नेल और टूलचिन समर्थन दोनों की आवश्यकता होती है। यह binfmt_miscदृष्टिकोण का उपयोग नहीं करता है , यह साइड-ईएलएफ हेडर मुद्दों को चरणबद्ध करता है और वसा कर्नेल मॉड्यूल के लिए भी अनुमति देता है।

  1. अगर मेरे पास 'x86 टारगेट, लाइनक्स ओएस वर्जन xyz' पर चलने के लिए संकलित एक एप्लीकेशन है, तो क्या मैं उसी संकलित बाइनरी को किसी अन्य सिस्टम 'ARM टारगेट, linux OS वर्जन xyz' पर चला सकता हूं?

ईएलएफ के साथ नहीं, यह आपको ऐसा नहीं करने देगा।

  1. यदि ऊपर सच नहीं है, तो एकमात्र तरीका यह है कि प्रासंगिक टूलकिन 'उदाहरण के लिए, आर्म-लिनेक्स-गुनैबी' का उपयोग करके पुनर्निर्माण / पुनर्निर्माण के लिए एप्लिकेशन स्रोत कोड प्राप्त किया जाए?

सरल उत्तर है हां। (जटिल उत्तरों में एमुलेशन, इंटरमीडिएट रिप्रेजेंटेशन, ट्रांसलेटर और जेआईटी शामिल हैं। केवल एक i686 बाइनरी का उपयोग करने के लिए एक i686 बाइनरी को "डाउनग्रेड" करने के मामले के अलावा वे शायद यहां दिलचस्प नहीं हैं, और एबीआई फ़िक्सअप मूल कोड के अनुवाद के रूप में संभवतः कठिन हैं। )

  1. इसी तरह, अगर मेरे पास एक लोड करने योग्य कर्नेल मॉड्यूल (डिवाइस ड्राइवर) है जो 'x86 लक्ष्य, लिनक्स ओएस संस्करण xyz' पर काम करता है, तो क्या मैं उसी संकलन को उपयोग / लोड कर सकता हूं। किसी अन्य सिस्टम 'ARM लक्ष्य, linux OS संस्करण yyz' पर। ?

नहीं, ELF आपको ऐसा नहीं करने देगा।

  1. अगर ऊपर सच नहीं है, तो एकमात्र तरीका यह है कि संबंधित टूलकिन 'उदाहरण के लिए, आर्म-लिनेक्स-गुनैबी' का उपयोग करके पुनर्निर्माण / पुनर्निर्माण के लिए ड्राइवर स्रोत कोड प्राप्त किया जाए?

सरल उत्तर है हां। मेरा मानना ​​है कि फेटेलएफ आपको .koमल्टी-आर्किटेक्चर बनाने की सुविधा देता है, लेकिन कुछ बिंदु पर प्रत्येक समर्थित आर्किटेक्चर के लिए एक बाइनरी संस्करण बनाना पड़ता है। जिन चीजों के लिए कर्नेल मॉड्यूल की आवश्यकता होती है वे अक्सर स्रोत के साथ आते हैं, और आवश्यकतानुसार बनाए जाते हैं, जैसे कि VirtualBox यह करता है।

यह पहले से ही एक लंबे समय तक चलने वाला उत्तर है, केवल एक और चक्कर है। कर्नेल में पहले से ही एक वर्चुअल मशीन है, जो एक समर्पित है: बीपीएफ वीएम जो पैकेट से मिलान करने के लिए उपयोग किया जाता है। मानव पठनीय फिल्टर "होस्ट फू और पोर्ट 22 नहीं") एक बायटेकोड पर संकलित है और कर्नेल पैकेट फ़िल्टर इसे निष्पादित करता है । नया ईएक्सपीएफ सिर्फ पैकेट के लिए नहीं है, सिद्धांत रूप में कि वीएम कोड किसी भी समकालीन लिनक्स में पोर्टेबल है, और llvm इसका समर्थन करता है, लेकिन सुरक्षा कारणों से यह शायद प्रशासनिक नियमों के अलावा किसी अन्य चीज के लिए उपयुक्त नहीं है।


अब, आप बाइनरी एक्ज़ीक्यूटेबल की परिभाषा के साथ कितने उदार हैं, इस पर निर्भर करता है कि आप binfmt_miscशेल स्क्रिप्ट के साथ फैट बाइनरी सपोर्ट को लागू करने के लिए (एब) का उपयोग कर सकते हैं , और कंटेनर फॉर्म के रूप में जिप फाइलें:

#!/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
}

इस "wozbin" को कॉल करें, और इसे कुछ इस तरह सेट करें:

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

यह .wozकर्नेल के साथ फाइल को पंजीकृत करता है, wozbinस्क्रिप्ट को इसके बजाय पहले दर्ज किए गए तर्क के साथ लागू किया जाता .wozहै।

एक पोर्टेबल (वसा) .woz फ़ाइल प्राप्त करने के लिए , बस test.wozएक डायरेक्टरी पदानुक्रम के साथ एक ज़िप फ़ाइल बनाएँ :

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

प्रत्येक मेहराब / OS / libc निर्देशिका (एक मनमाना विकल्प) के भीतर आर्किटेक्चर-विशिष्ट testबाइनरी और घटक जैसे कि .soफाइलें रखें। जब आप इसे आमंत्रित करते हैं तो आवश्यक उपनिर्देशिका को एक tmpfs में मेमोरी फाइल सिस्टम ( /mnt/tmpfsयहाँ पर ) में डाला जाता है और इनवोक किया जाता है।


0

बेरी बूट, आपकी कुछ समस्याओं को हल करते हैं .. लेकिन यह समस्या को हल नहीं करते हैं कि x86-32 / 64bit के लिए आर्म hf, normall / regullAr linux distro पर कैसे चला जाए।

मुझे लगता है कि इसे आइसोलिनक्स (यूएसबी पर बोटलोडर लाइनक्स) में बनाया जाना चाहिए। कुछ लाइव कन्वर्टर रेगुलर डिस्ट्रो को पहचान सकते हैं और राइड में लाइव / एचएफ में बदल सकते हैं।

क्यों? क्योंकि अगर प्रत्येक लिनेक्स को बांह-बूट पर काम करने के लिए बेरी बूट द्वारा परिवर्तित किया जा सकता है, तो यह बीरी बूट तंत्र में निर्मित करने में सक्षम हो सकता है, जिसे हम प्रत्येक एक्सएपल के लिए उपयोग करते हुए बूट करते हैं या उबंटू प्राणी स्टार्ट डिस्क में निर्मित होते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.