7

डालने पर स्थानांतरण त्रुटि पहली बार: मैं एक विशेषज्ञ नहीं हूं, इसलिए कृपया मुझे अपनी व्याख्या करने की कोशिश करने वाली किसी भी गलती से क्षमा करें।बाह्य क्रॉस-संकलित एसपीएआरसी लिनक्स मॉड्यूल

मैं स्पार्क- Linux-GCC-4.4.2 का उपयोग कर एक SPARC मशीन के लिए बाहरी लिनक्स मॉड्यूल को पार करने की कोशिश कर रहा हूं। लिनक्स कर्नेल का संस्करण 2.6.36.4-00037-g059aa91-dirty है। इसे LEON प्रोसेसर से कुछ फ़ाइलों के साथ जोड़ा गया है। निर्माण प्रवाह मुझे प्रदान किया जाता है और यह LinuxBuild, Buildroot, और Busybox का उपयोग करता है। मैं 32 बिट ओएस बनाने की कोशिश कर रहा हूं।

सब कुछ काम करने के लिए लगता है, लेकिन बाद मैं मॉड्यूल संकलन और स्पार्क व्यवस्था करने के लिए यह insmod करने की कोशिश मैं इस त्रुटि मिलती है:

module hellok: Unknown relocation: 6 

यह त्रुटि ~/linuxbuild-1.0.3/linux/linux-2.6-git/arch/sparc/kernel/module.c से आता है मैं खातिर पूरे विधि प्रदान करेगा पूर्णता की:

int apply_relocate_add(Elf_Shdr *sechdrs, 
      const char *strtab, 
      unsigned int symindex, 
      unsigned int relsec, 
      struct module *me) 
{ 
unsigned int i; 
Elf_Rela *rel = (void *)sechdrs[relsec].sh_addr; 
Elf_Sym *sym; 
u8 *location; 
u32 *loc32; 

for (i = 0; i < sechdrs[relsec].sh_size/sizeof(*rel); i++) { 
    Elf_Addr v; 

    /* This is where to make the change */ 
    location = (u8 *)sechdrs[sechdrs[relsec].sh_info].sh_addr 
     + rel[i].r_offset; 
    loc32 = (u32 *) location; 

#ifdef CONFIG_SPARC64 
    BUG_ON(((u64)location >> (u64)32) != (u64)0); 
#endif /* CONFIG_SPARC64 */ 

    /* This is the symbol it is referring to. Note that all 
     undefined symbols have been resolved. */ 
    sym = (Elf_Sym *)sechdrs[symindex].sh_addr 
     + ELF_R_SYM(rel[i].r_info); 
    v = sym->st_value + rel[i].r_addend; 

    switch (ELF_R_TYPE(rel[i].r_info) & 0xff) { 
#ifdef CONFIG_SPARC64 
    case R_SPARC_64: 
     location[0] = v >> 56; 
     location[1] = v >> 48; 
     location[2] = v >> 40; 
     location[3] = v >> 32; 
     location[4] = v >> 24; 
     location[5] = v >> 16; 
     location[6] = v >> 8; 
     location[7] = v >> 0; 
     break; 

    case R_SPARC_DISP32: 
     v -= (Elf_Addr) location; 
     *loc32 = v; 
     break; 

    case R_SPARC_WDISP19: 
     v -= (Elf_Addr) location; 
     *loc32 = (*loc32 & ~0x7ffff) | 
      ((v >> 2) & 0x7ffff); 
     break; 

    case R_SPARC_OLO10: 
     *loc32 = (*loc32 & ~0x1fff) | 
      (((v & 0x3ff) + 
       (ELF_R_TYPE(rel[i].r_info) >> 8)) 
      & 0x1fff); 
     break; 
#endif /* CONFIG_SPARC64 */ 


    case R_SPARC_32: 
    case R_SPARC_UA32: 
     location[0] = v >> 24; 
     location[1] = v >> 16; 
     location[2] = v >> 8; 
     location[3] = v >> 0; 
     break; 

    case R_SPARC_WDISP30: 
     v -= (Elf_Addr) location; 
     *loc32 = (*loc32 & ~0x3fffffff) | 
      ((v >> 2) & 0x3fffffff); 
     break; 

    case R_SPARC_WDISP22: 
     v -= (Elf_Addr) location; 
     *loc32 = (*loc32 & ~0x3fffff) | 
      ((v >> 2) & 0x3fffff); 
     break; 

    case R_SPARC_LO10: 
     *loc32 = (*loc32 & ~0x3ff) | (v & 0x3ff); 
     break; 

    case R_SPARC_HI22: 
     *loc32 = (*loc32 & ~0x3fffff) | 
      ((v >> 10) & 0x3fffff); 
     break; 

    default: 
     printk(KERN_ERR "module %s: Unknown relocation: %x\n", 
       me->name, 
       (int) (ELF_R_TYPE(rel[i].r_info) & 0xff)); 
     return -ENOEXEC; 
    }; 
} 
return 0; 
} 

तो मुझे समझ में डिफ़ॉल्ट मामला एक मैं गिरने रहा है के अंतर्गत। ELF_R_TYPE(rel[i].r_info (एसपीएआरसी Relocations) प्रकार मेरी ~/linuxbuild-1.0.3/dist/buildroot/build-br/staging/usr/include/elf.h फाइल में परिभाषित कर रहे हैं और कुछ इस प्रकार हैं:

/* SPARC relocs. */ 

#define R_SPARC_NONE  0 /* No reloc */ 
#define R_SPARC_8   1 /* Direct 8 bit */ 
#define R_SPARC_16   2 /* Direct 16 bit */ 
#define R_SPARC_32   3 /* Direct 32 bit */ 
#define R_SPARC_DISP8  4 /* PC relative 8 bit */ 
#define R_SPARC_DISP16  5 /* PC relative 16 bit */ 
#define R_SPARC_DISP32  6 /* PC relative 32 bit */ 
#define R_SPARC_WDISP30  7 /* PC relative 30 bit shifted */ 
#define R_SPARC_WDISP22  8 /* PC relative 22 bit shifted */ 
#define R_SPARC_HI22  9 /* High 22 bit */ 
#define R_SPARC_22   10 /* Direct 22 bit */ 
#define R_SPARC_13   11 /* Direct 13 bit */ 
#define R_SPARC_LO10  12 /* Truncated 10 bit */ 
#define R_SPARC_GOT10  13 /* Truncated 10 bit GOT entry */ 
#define R_SPARC_GOT13  14 /* 13 bit GOT entry */ 
#define R_SPARC_GOT22  15 /* 22 bit GOT entry shifted */ 
#define R_SPARC_PC10  16 /* PC relative 10 bit truncated */ 
#define R_SPARC_PC22  17 /* PC relative 22 bit shifted */ 
#define R_SPARC_WPLT30  18 /* 30 bit PC relative PLT address */ 
#define R_SPARC_COPY  19 /* Copy symbol at runtime */ 
#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */ 
#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */ 
#define R_SPARC_RELATIVE 22 /* Adjust by program base */ 
#define R_SPARC_UA32  23 /* Direct 32 bit unaligned */ 

/* Additional Sparc64 relocs. */ 
... 

तो स्थानांतरण 6 करने के लिए R_SPARC_DISP32 उर्फ ​​PC सापेक्ष 32 बिट मेल खाती है। यह module.c केस स्टेटमेंट में परिभाषित किया गया है, लेकिन केवल 64-बिट अनुभाग के तहत। मुझे लगता है कि मुझे या तो खुद को स्थानांतरित करने की आवश्यकता है या मुझे पता है कि संकलन के दौरान मुझे किस स्थानांतरण स्थान की आवश्यकता है और ध्वज बदलना है। मैं वास्तव में समझ नहीं पा रहा हूं कि स्थानांतरण कोड में क्या हो रहा है, इसलिए कृपया मुझे यह समझने में सहायता करें कि मुझे इसे कैसे ठीक करना चाहिए। मुझे नहीं लगता कि मैं ओएस को 64-बिट के रूप में बना सकता हूं क्योंकि ऐसा लगता है कि यह सिस्टम तोड़ने लगता है, इसलिए कृपया वैकल्पिक समाधान खोजने में मेरी सहायता करें।

+0

क्या यह संभव है यह MMU के साथ क्या करना है? – Stuart

+1

बस जोर से सोचते हुए, लेकिन क्या आप [लक्ष्य] -objdump -r लक्ष्य मशीन से कुछ संकलित मॉड्यूल कर सकते हैं और यह पता लगा सकते हैं कि वे किस प्रकार के स्थानान्तरण का उपयोग कर रहे हैं? और फिर पता लगाएं कि निर्माण प्रणाली में कहां उपयोग करने के लिए चुना गया है? आप कितने आश्वस्त हैं कि आपके निर्माण प्रणाली/कॉन्फ़िगरेशन/हेडर मशीन पर क्या मेल खाते हैं? –

+0

कौन सा लियोन प्रोसेसर? कौन सा वितरण चल रहा है - गैसलर से कुछ या कुछ और? क्या आपके पास अपने निर्माण झंडे में -32 है? –

उत्तर

2

लियोन-लिनक्स कॉन्फ़िगरेशन (लिनक्सबिल्ड-1.0.1) के लिए मेरे पास अपने मॉड्यूल के साथ बिल्कुल वही समस्या है।

मैं क्या है कि मैं कोड की 'मामले R_SPARC_DISP32' भाग ले जाया गया है (4 लाइनों) बस लाइन के बाद '#endif/* CONFIG_SPARC64 * /'

कुछ बुरी हैक हैरी है कि ;-) लेकिन कम से कम अब मैं मॉड्यूल को इन्सोडोड कर सकता हूं ... अब जब उपयोगकर्ता मॉड्यूल के दिनचर्या को कॉल करता है, तो मुझे उपयोगकर्ता-भूमि पक्ष पर दुष्प्रभावों की आवश्यकता होती है।

तो, जारी रखा जाएगा ...

सादर, करीम

+0

मैंने थोड़ी देर के लिए भी इसका इस्तेमाल किया, लेकिन मुझे सहज महसूस नहीं हुआ क्योंकि मैं यह सुनिश्चित नहीं कर सका कि यह उचित है। मुझे लगता है कि -फनो-बौना 2-डीएफआई-एएसएम ध्वज बेहतर है, लेकिन सकारात्मक नहीं हो सकता है। – Stuart

संबंधित मुद्दे