elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado:


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  Problema con linker script
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Problema con linker script  (Leído 3,403 veces)
Khronos14


Desconectado Desconectado

Mensajes: 443


A lie is a lie


Ver Perfil WWW
Problema con linker script
« en: 4 Septiembre 2012, 13:39 pm »

Hola, estoy desarrollando un Kernel y tengo un problema con los strings. El Kernel bootea desde la disquetera, carga el Stage2 y entra en modo largo, luego se inicia el Kernel en C++.

Hasta ahora, lo estaba desarrollando en Windows, usando Nasm y MinGW, pero me encontré con el problema de las cadenas y lo porté a GNU/Linux.

En Windows, mi linker script es este:

Código
  1. OUTPUT_FORMAT("pe-x86-64")
  2. ENTRY("loader")
  3. SECTIONS
  4. {
  5.    . = 0x100000;
  6.    .text :
  7.    {
  8.        code = .;
  9.        *(.text)
  10.        text_end = .;
  11.    }
  12.    .rodata :
  13.    {
  14.        rodata = text_end;
  15.        *(.rodata)
  16. *(.rdata)
  17.        rodata_end  = .;      
  18.    }    
  19.    .data :
  20.    {
  21.        data = rodata_end;
  22.        *(.data)
  23.        data_end = .;
  24.    }
  25.    .bss :  
  26.    {
  27.        bss = data_end;
  28.        *(.bss)
  29.        bss__end = .;
  30.    }
  31.    end = .;
  32. }
  33.  

Y compilo todo, con el siguiente bat:

Código:
@echo off
set nasm="tools\nasm.exe"
set bochs="C:\Program Files (x86)\Bochs-2.5.1\bochs.exe"
set fat12maker="tools\fat12maker.exe"
set ld="..\MinGW64\bin\x86_64-w64-mingw32-ld.exe"
set cpp="..\MinGW64\bin\x86_64-w64-mingw32-g++.exe"
set objcopy="..\MinGW64\bin\x86_64-w64-mingw32-objcopy.exe"
set cpp_params=-I.\Kernel\ -nostdlib -nostartfiles -nodefaultlibs -masm=intel -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin

mkdir bin\

%nasm% -fbin bootloader\Stage_1.asm -o Stage_1.bin
if NOT %ERRORLEVEL%==0 goto error

%nasm% -fbin bootloader\Stage_2.asm -o Stage_2.bin
if NOT %ERRORLEVEL%==0 goto error

%cpp% %cpp_params% -c Kernel\kernel.cpp -o bin\kernel.o
%cpp% %cpp_params% -c Kernel\Drivers\screen.cpp -o bin\screen.o
%cpp% %cpp_params% -c Kernel\string.cpp -o bin\string.o
%cpp% %cpp_params% -c Kernel\io.cpp -o bin\io.o
%cpp% %cpp_params% -c Kernel\idt.cpp -o bin\idt.o
%nasm% -f win64 Kernel\Stage_3.asm -o bin\Stage_3.o
if NOT %ERRORLEVEL%==0 goto error

%ld% -nostdlib -nodefaultlibs -T linker.ld bin\Stage_3.o bin\kernel.o bin\idt.o bin\screen.o bin\string.o bin\io.o -o Kernel.out
%objcopy% -x -g -X -S -O binary Kernel.out kernel.bin

copy /b Stage_2.bin+kernel.bin Stage_2.bin
if NOT %ERRORLEVEL%==0 goto error

%fat12maker% -b Stage_1.bin -i Stage_2.bin -o Kernel.img
%bochs% -f bochsconf

goto fin

:error
echo Se produjo un error de compilacion
exit

:fin
echo Compilacion satisfactoria
rmdir /S /Q bin\

Se ejecuta bien, pero no se muestran las cadenas que son constantes globales. No puedo hacer algo como esto:

Código
  1. const char * interrupts_exceptions[] = {
  2. "0 - Division by zero exception",
  3. "1 - Debug exception",
  4. "2 - Non maskable interrupt",
  5. "3 - Breakpoint exception",
  6. "4 - 'Into detected overflow",
  7. "5 - Out of bounds exception",
  8. "6 - Invalid opcode exception",
  9. "7 - No coprocessor exception",
  10. "8 - Double fault",
  11. "9 - Coprocessor segment overrun",
  12. "10 - Bad TSS",
  13. "11 - Segment not present",
  14. "12 - Stack fault",
  15. "13 - General protection fault",
  16. "14 - Page fault",
  17. "15 - Unknown interrupt exception",
  18. "16 - Coprocessor fault",
  19. "17 - Alignment check exception",
  20. "18 - Machine check exception",
  21. "19 - Reserved exception",
  22. "20 - Reserved exception",
  23. "21 - Reserved exception",
  24. "22 - Reserved exception",
  25. "23 - Reserved exception",
  26. "24 - Reserved exception",
  27. "25 - Reserved exception",
  28. "26 - Reserved exception",
  29. "27 - Reserved exception",
  30. "28 - Reserved exception",
  31. "29 - Reserved exception",
  32. "30 - Reserved exception"
  33. "31 - Reserved exception"};
  34.  
  35. void idt::init_idt()
  36. {
  37. idt_ptr = (idt_ptr_t*)IDT_ADDRESS;
  38. *idt_entries = (idt_entry_t*)IDT_ADDRESS;
  39.  
  40. clean_gates();
  41. screen::kprintf("Exceptions pointer: 0x%p\n", ::interrupts_exceptions);
  42. screen::kprintf("String: %s\n", ::interrupts_exceptions[0]); //<--------------------------
  43.  
  44. idt_set_gate(0, (QWORD)isr0, 0x08, 0x8E);
  45. }
  46.  

Esto es lo que muestra: http://forum.osdev.org/download/file.php?id=2342&mode=view

Estuve buscando información en http://wiki.osdev.org/Main_Page pero no consigo arreglar el problema.

El linker script de linux es este:

Código
  1. OUTPUT_FORMAT(binary)
  2. ENTRY(loader)
  3. SECTIONS
  4. {
  5.    . = 0x100000;
  6.    .text :
  7.    {
  8.        code = .;
  9.        *(.text)
  10.        text_end = .;
  11.    }
  12.    .rodata :
  13.    {
  14.        rodata = text_end;
  15.        *(.rodata)
  16.        rodata_end  = .;      
  17.    }    
  18.    .data :
  19.    {
  20.        data = rodata_end;
  21.        *(.data)
  22.        data_end = .;
  23.    }
  24.    .bss :  
  25.    {
  26.        bss = data_end;
  27.        *(.bss)
  28.        bss__end = .;
  29.    }
  30.    end = .;
  31. }
  32.  

Y el Makefile:

Código
  1. CPP = g++
  2. CPP_PARAMS = -I./Kernel/ -nostdlib -nostartfiles -nodefaultlibs -masm=intel -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin
  3. OBJECTS = Stage_3.o kernel.o screen.o string.o io.o idt.o
  4. FAT12MAKER = ./tools/fat12maker/fat12maker
  5.  
  6.  
  7. all:
  8. nasm -fbin bootloader/Stage_1.asm -o Stage_1.bin
  9. nasm -fbin bootloader/Stage_2.asm -o Stage_2.o
  10.  
  11. nasm -felf64 Kernel/Stage_3.asm -o Stage_3.o
  12. $(CPP) $(CPP_PARAMS) -c Kernel/kernel.cpp -o kernel.o
  13. $(CPP) $(CPP_PARAMS) -c Kernel/Drivers/screen.cpp -o screen.o
  14. $(CPP) $(CPP_PARAMS) -c Kernel/string.cpp -o string.o
  15. $(CPP) $(CPP_PARAMS) -c Kernel/io.cpp -o io.o
  16. $(CPP) $(CPP_PARAMS) -c Kernel/idt.cpp -o idt.o
  17.  
  18. ld -nostdlib -nodefaultlibs -T linker-linux.ld $(OBJECTS) -o Kernel.o
  19. cat Stage_2.o Kernel.o > Stage_2.bin
  20. $(FAT12MAKER) -b Stage_1.bin -i Stage_2.bin -o Kernel.img
  21. bochs -f bochsconf-linux
  22.  
  23. clean:
  24. rm *.o
  25. rm *.bin
  26.  

Pero en Linux, funciona peor. Sólo funcionan las cadenas que se declaran como variables locales:

Código
  1. extern "C" void kmain(WORD Foo, WORD Foo2)
  2. {
  3. char saludo[] = "Hello!\n";
  4. screen::clear_screen();
  5. screen::hide_cursor();
  6.  
  7. screen::kprintf("Adios\n"); //No funciona
  8. screen::kprintf(saludo); //Funciona
  9.  

Estoy muy perdido, espero que alguien pueda echarme una mano...

Saludos.


En línea

Khronos14


Desconectado Desconectado

Mensajes: 443


A lie is a lie


Ver Perfil WWW
Re: Problema con linker script
« Respuesta #1 en: 4 Septiembre 2012, 23:04 pm »

Puede que hay puesto demasiada información, tan solo necesito entender como colocar las secciones de un linker script para el linker de GCC, y para el formato ELF.

Si alguien tiene experiencia trabajando con el linker "a pelo" y puede ayudarme, se lo agradecería mucho.

Saludos.


En línea

Khronos14


Desconectado Desconectado

Mensajes: 443


A lie is a lie


Ver Perfil WWW
Re: Problema con linker script
« Respuesta #2 en: 5 Septiembre 2012, 22:58 pm »

Bueno, conseguí arreglarlo, tras una semana rompiéndome la cabeza lo conseguí. Este es el linker script, usando MinGW:

Código
  1. OUTPUT_FORMAT("pe-x86-64")
  2. ENTRY(loader)
  3. SECTIONS
  4. {
  5.     .text 0x001216 :
  6. {
  7. *(.text)
  8. }
  9. .rdata :
  10. {
  11. *(.rdata)
  12. }
  13. .data :
  14. {
  15. *(.data)
  16. }
  17. .bss :
  18. {
  19. *(.bss)
  20. }
  21. }
  22.  

ld -nostdlib -nodefaultlibs -T linker.ld bin\Stage_3.o bin\kernel.o bin\idt.o bin\screen.o bin\string.o bin\io.o -o Kernel.out

Usando el comando ld de esa manera, nos generaría un ejecutable que trabajaría según la dirección de memoria 0x001216.

El Stage_2 de mi Kernel lo cargo en 0x001000, a lo que hay que sumarle el código del Stage_2 que luego carga el Kernel en C++. El tamaño del Stage_2 es de 0x216 bytes, por lo que sumándolo a la dirección base, se soluciona el problema.

Una vez linkeado nuestro ejecutable, lo convertimos a binario con objcopy, tal como hago en el bat que puse antes. Ahora tengo que portarlo a GCC para poder compilarlo en Linux, pero debería ser bastante fácil.

Saludos.
En línea

sistemx

Desconectado Desconectado

Mensajes: 48


Ver Perfil
Re: Problema con linker script
« Respuesta #3 en: 6 Septiembre 2012, 01:12 am »

Damn quisiera entender un kernel, pero solo se C basico y casi nada de Assembly
En línea

Khronos14


Desconectado Desconectado

Mensajes: 443


A lie is a lie


Ver Perfil WWW
Re: Problema con linker script
« Respuesta #4 en: 6 Septiembre 2012, 15:16 pm »

Damn quisiera entender un kernel, pero solo se C basico y casi nada de Assembly

Sin ensamblador poco puedes hacer, te compras un libro y te pones un hora al dia o así. Debido al número limitado de instrucciones que tiene, se puede aprender bastante rápido, si ya sabes programar.

Después tendrías que aprender buenas prácticas en ensamblador. Por ejemplo, para poner un registro a 0, puedes hacer:

Código
  1. mov rax, 0
  2. xor rax, rax
  3.  

Las dos operaciones producen el mismo efecto, pero es más rápida la segunda. Otro ejemplo: la multiplicación por potencias de 2^n.

Código
  1. imul ax, 14, 8
  2.  

Si ya tienes almacenado en el registro ax un 14, es más rápido esto:

Código
  1. shl ax, 3 ; 2^3 = 8
  2.  

Son buenas prácticas que adquieres con el tiempo.

Saludos.
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Duda sobre linker
Programación C/C++
criskapunk 2 4,067 Último mensaje 25 Marzo 2011, 05:23 am
por D4RIO
Problemas con el linker
GNU/Linux
El_Java 3 3,497 Último mensaje 3 Julio 2012, 18:46 pm
por Foxy Rider
Linker en VC++
Programación C/C++
eleon 0 1,607 Último mensaje 24 Julio 2012, 15:16 pm
por eleon
Problema linker VS (C++ y SDL)
Programación C/C++
Bob1098 3 3,931 Último mensaje 13 Agosto 2016, 17:08 pm
por AlbertoBSD
Simbolo no resuelto por el linker.
ASM
Usuario887 5 4,294 Último mensaje 28 Febrero 2021, 22:05 pm
por Eternal Idol
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines