2011-04-11 19 views
8

के लिए गतिशील लोडर कैसे लिखें I arm9 प्रोसेसर के आधार पर एक प्रोजेक्ट पर काम कर रहा हूं। हम किसी भी ऑपरेटिंग सिस्टम के बिना केवल नंगे धातु का उपयोग करते हैं, इसलिए दुर्भाग्यवश हमारे पास साझा पुस्तकालयों/गतिशील लोडर के लिए अभी तक कोई समर्थन नहीं है।नंगे-धातु आर्म-एप्लिकेशन

मैं एसडी कार्ड से उदाहरण के लिए पुस्तकालयों को लोड करने में सक्षम होना चाहता हूं, जो मुख्य एप्लिकेशन से कार्यों को भी कॉल कर सकता है।

मेरी पहली कोशिश लिंकर ओवरले क्षमता (लाइब्रेरी को विशिष्ट बिल्कुल स्थित वर्गों में रखकर) का उपयोग करना था, लेकिन यहां मुख्य ऐप फ़ंक्शंस को कॉल करने में समस्या है जैसा कि मैंने पहले उल्लेख किया था -> मुख्य अनुप्रयोग के प्रत्येक परिवर्तन के साथ पुस्तकालयों में कॉलबैक करने में सक्षम होने के लिए फिर से दोबारा तैयार किया जाएगा।

इस बात के अनुसार मुझे अपना खुद का गतिशील लोडर लिखना होगा, लेकिन मैं इस क्षेत्र में नौसिखिया हूं। क्या कोई मुझे कोई उदाहरण दे सकता है कि इस तरह से कैसे निपटें या इस तरह के प्रोजेक्ट से कैसे शुरुआत करें? हम arm-elf लक्ष्य के लिए जीसीसी का उपयोग कर रहे हैं।

संबंध जनवरी

+0

आम तौर पर, यदि कोई "लाइब्रेरी" एक "प्रोग्राम" में वापस कॉल करता है तो यह एक फ़ंक्शन पॉइंटर को कॉल करके करता है जो लाइब्रेरी में पिछले कॉल में पारित किया गया है। इस तरह पुस्तकालय कार्यक्रम के संशोधन पर निर्भर नहीं है। कार्यक्रम बनाने के लिए लाइब्रेरी के सटीक निर्माण पर "कम" निर्भर करता है, कूदने वाली टेबल सरल होगी। –

उत्तर

5

चेक this application note। यह कुछ विवरणों में वर्णन करता है कि डायनामिक लिंकिंग कैसे काम करती है और आपको अपना डायनामिक लोडर लिखने के लिए क्या करना है। यह इसके लिए कुछ विकल्प भी देता है। मुझे लगता है कि जंप टेबल एक लागू करने में काफी आसान है और बदलते एपीआई पते के साथ आपकी समस्या का समाधान करेगा।


संपादित: यहां बताया गया एक सरल कूद तालिका करने के लिए है। सबसे पहले, तय करें कि आपको अपने मुख्य कार्यक्रम से कौन से फ़ंक्शंस की आवश्यकता है। मुख्य कार्यक्रम में

typedef struct _MyAPI 
{ 
    int (*init)(int flags); 
    int (*exit)(int exitcode); 
    void * (*getmem)(size_t size); 
    void (*freemem)(void *ptr); 
} MyAPI; 

, इस संरचना का एक उदाहरण परिभाषित करते हैं, संकेत में भरने, और कुछ पूर्वनिर्धारित पते पर यह जगह:: फिर समारोह संकेत की एक संरचना बनाने (

#include <jumptbl.h> 
int main_init(int flags) 
{ 
    return 0; 
} 
//... 
MyAPI main_API __attribute__((section(".jumptbl"))) = 
{ 
    &main_init, 
    &main_exit, 
    &main_getmem, 
    &main_freemem, 
}; 

अगर आप इस दृष्टिकोण का उपयोग, आप लिंकर फ़ाइल में .jumptbl खंड वर्णन करने के लिए और यकीन है कि यह एक निश्चित पता)

हो जाता लोड मॉड्यूल में बनाने के लिए, jumptable सूचक हो और इसका इस्तेमाल मुख्य कार्यक्रम को कॉल करना होगा:

#include <jumptbl.h> 

MyAPI *pAPI = (MyAPI*)(0x1000000); // there should be a better way to do this 

int main() 
{ 
    pAPI->init(0); 
    void *block = pAPI->getmem(0x30); 
    //... 
} 

आशा है कि इससे मदद मिलती है!

+0

उत्तर के लिए धन्यवाद। क्या आप जानते हैं कि बांह कंपाइलर टूलचेन जीसीसी से कितना अलग है? एप्नोट एक जंप टेबल बनाने के लिए symdefs फ़ाइल का उपयोग करने का सुझाव देता है, लेकिन दुर्भाग्य से मुझे gcc में symdefs विकल्प नहीं पता है ... – Honza

+0

मुझे यकीन नहीं है कि symdefs क्या हैं, लेकिन मैंने jumptables पर एक छोटा सा तरीका जोड़ा है, उम्मीद है यह काफी स्पष्ट है। –

+0

jumtables के बारे में जानकारी के लिए धन्यवाद। यह एक आदर्श उदाहरण है, जैसा कि मुझे चाहिए था। – Honza