Guía de Makefile Avanzado

Trabajar con archivos como .o, .c, .h, .elf, .bin y organizar subdirectorios junto con Makefiles avanzados que usan comodines como *, %, y $, implica comprender cómo integrar archivos en diferentes etapas del desarrollo de software y gestión de estructuras.  

Relación entre los tipos de archivos:

  1. .c y .h:
    • .c contiene el código fuente.
    • .h contiene las declaraciones (cabeceras) necesarias para que otros archivos .c usen funciones o estructuras comunes.
  2. .o (object files):
    • Son el resultado de compilar archivos .c (sin enlazarlos).
    • Contienen código binario intermedio que será combinado posteriormente.
  3. .elf:
    • Es el formato de archivo ejecutable y vinculable (Executable and Linkable Format) que contiene datos ejecutables o cargables en sistemas específicos.
  4. .bin:
    • Un archivo binario plano y más simple, puede derivarse de un .elf.
  5. .img:
    • Archivo de imagen que representa sectores o sistemas completos (por ejemplo, sistemas de arranque).

Uso de Makefile avanzado:

Los Makefiles son scripts que automatizan la construcción de proyectos. Con comodines y variables, puedes simplificar la gestión y vinculación de múltiples archivos.

# Variables
CC = gcc
CFLAGS = -Wall -g
SRCS = $(wildcard src/*.c)   # Todos los archivos .c en el directorio src/
OBJS = $(SRCS:%.c=%.o)       # Transformar .c a .o
BIN = ejecutable.bin

# Reglas
all: $(BIN)

$(BIN): $(OBJS)
    $(CC) $(CFLAGS) -o $@ $^

%.o: %.c
    $(CC) $(CFLAGS) -c $< -o $@

clean:
    rm -f $(OBJS) $(BIN)

.PHONY: all clean

Qué hace:

  1. Usa wildcard para encontrar todos los archivos .c en un subdirectorio.
  2. Convierte los nombres .c en .o automáticamente con %.
  3. Procesa y genera un ejecutable .bin.

Combinación de estructuras:

Para integrar archivos con estructuras diferentes:

  1. Estándares de nombres: Asegúrate de que los archivos de diferentes estructuras sigan un patrón coherente.
  2. Directorios: Usa subdirectorios para organizar por tipo o funcionalidad (src/, include/, bin/, obj/).
  3. Makefile modular: Divide las reglas en fragmentos independientes para cada subdirectorio y usa include para combinar Makefiles secundarios.

Procesar todo en un solo ejecutable:

El flujo típico sería:

  1. Compilación: Convierte todos los .c a .o.
  2. Enlace: Une los .o para generar .elf.
  3. Generación de binario: Convierte .elf a .bin con herramientas como objcopy.
  4. Creación de imagen: Si es necesario, empaqueta el .bin en un .img. 



Guía: Trabajar con Archivos y Makefiles Avanzados

1. Organización del Proyecto

Divide tu proyecto en subdirectorios para mantener una estructura clara:

  • src/: Archivos de código fuente (.c, .asm).
  • include/: Archivos de cabecera (.h).
  • obj/: Archivos objeto (.o).
  • bin/: Archivos ejecutables o binarios finales (.elf, .bin, .img).

2. Ensamblar y Compilar

Paso A: Archivos .asm

Usa un ensamblador como nasm o as para convertir los archivos .asm en .o:

nasm -f elf64 archivo.asm -o archivo.o

Paso B: Archivos .c

Compila los archivos .c para generar archivos .o:

gcc -c -Wall -Iinclude archivo.c -o archivo.o

3. Vincular los Archivos Objeto (.o)

Usa el linker para unir los archivos .o en un ejecutable .elf:

ld -o ejecutable.elf archivo1.o archivo2.o

4. Generar Archivo Binario

Convierte el archivo .elf en un formato binario .bin:

objcopy -O binary ejecutable.elf ejecutable.bin

5. Crear Imagen (.img)

Empaqueta el archivo .bin en un .img:

dd if=ejecutable.bin of=imagen.img bs=512 count=1

6. Ejemplo de Makefile Avanzado


# Variables
CC = gcc
AS = nasm
LD = ld
OBJCPY = objcopy
CFLAGS = -Wall -Iinclude
ASMFLAGS = -f elf64
SRCS_C = $(wildcard src/*.c)
SRCS_ASM = $(wildcard src/*.asm)
OBJS_C = $(SRCS_C:src/%.c=obj/%.o)
OBJS_ASM = $(SRCS_ASM:src/%.asm=obj/%.o)
BIN = bin/imagen.img

# Reglas
all: $(BIN)

$(BIN): obj/ejecutable.bin
    dd if=$< of=$@ bs=512 count=1

obj/ejecutable.bin: obj/ejecutable.elf
    $(OBJCPY) -O binary $< $@

obj/ejecutable.elf: $(OBJS_C) $(OBJS_ASM)
    $(LD) -o $@ $^

obj/%.o: src/%.asm
    $(AS) $(ASMFLAGS) $< -o $@

obj/%.o: src/%.c
    $(CC) $(CFLAGS) -c $< -o $@

clean:
    rm -f obj/*.o obj/*.elf obj/*.bin bin/*.img

.PHONY: all clean
        

7. Plataformas Diferentes

Para que tu proyecto funcione en varias plataformas:

  • Usa macros y definiciones específicas para adaptar el código.
  • Configura diferentes secciones en ensamblador para cada CPU.
  • Utiliza gcc y gcc-arm para compilar en arquitecturas distintas.

 

Destacado

Bootloader Avanzado en Ensamblador

Bootloader Avanzado en Ensamblador Características del Bootloader Se carga en la dirección 0x7C00 (BIOS). ...