7

En primer lugar: no soy un experto, así que disculpe cualquier error que haga tratando de explicarme.Error de reubicación al insertar el módulo de SPARC Linux externo compilado cruzado

Estoy tratando de realizar una compilación cruzada de un módulo externo de Linux para una máquina SPARC utilizando Sparc- Linux-GCC-4.4.2. La versión del kernel de Linux es 2.6.36.4-00037-g059aa91-dirty. Se ha corregido con algunos archivos del procesador LEON. El flujo de compilación se me proporciona y usa LinuxBuild, Buildroot y Busybox. Estoy tratando de hacer un sistema operativo de 32 bits.

Todo parece funcionar pero después de compilar el módulo y trato de insmodéelo al sistema SPARC me sale este error:

module hellok: Unknown relocation: 6 

Este error proviene de ~/linuxbuild-1.0.3/linux/linux-2.6-git/arch/sparc/kernel/module.c que proporcionará todo el método por el bien de exhaustividad:

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; 
} 

por lo que entiendo el caso de que el defecto es el que estoy cayendo debajo. ELF_R_TYPE(rel[i].r_info (SPARC) Movimientos tipos se definen en mi archivo ~/linuxbuild-1.0.3/dist/buildroot/build-br/staging/usr/include/elf.h y algunos son los siguientes:

/* 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. */ 
... 

Así reubicación 6 corresponde a R_SPARC_DISP32 aka PC relativa de 32 bits. Esto se define en la declaración de caso module.c, pero solo en la sección de 64 bits. Creo que o bien debo escribir el traslado yo mismo o averiguar qué bandera de reubicación necesito y cambiar el indicador durante la compilación. Realmente no entiendo qué está pasando en el código de reubicación, así que por favor ayúdame a descubrir cómo debo solucionar esto. No creo que pueda construir el sistema operativo como de 64 bits porque parece romper el sistema, así que ayúdenme a encontrar soluciones alternativas.

+0

¿Es posible que esto tiene que ver con la MMU? – Stuart

+1

Solo pensando en voz alta, pero ¿puede [objetivo] -objdump -r algunos módulos compilados de la máquina de destino y averiguar qué tipo de reubicaciones están utilizando? Y luego, ¿en qué parte del sistema de compilación se elige el tipo que se utilizará? ¿Qué tan seguro está de que su sistema de construcción/configuración/encabezados coincida con lo que hay en la máquina? –

+0

¿Qué procesador Leon? ¿Qué distribución se está ejecutando, algo de Gaisler o algo más? ¿Tienes -m32 en tus banderas de construcción? –

Respuesta

2

Tengo exactamente el mismo problema con mi propio módulo, para una configuración de Leon-Linux (linuxbuild-1.0.1).

Lo que hice es que me moví parte del código del 'caso R_SPARC_DISP32' (las 4 líneas) después de la línea '#endif/* CONFIG_SPARC64 * /'

Eso es un mal truco Harry ;-) pero al menos ahora puedo insmod el módulo ... Ahora tengo que buscar efectos secundarios en el lado del usuario, cuando las aplicaciones llaman a las rutinas del módulo.

Por lo tanto, continuará ...

Saludos, Karim

+0

También usé esto por un tiempo, pero no me sentía cómodo ya que no podía estar seguro de que esto fuera apropiado. Creo que el indicador -fno-dwarf2-dfi-asm es mejor, pero no puede ser positivo. – Stuart

Cuestiones relacionadas