JZ2440 desarrollo de juntas desnuda práctica # 6 guión de enlazado y reubicación

En un control completo de SDRAM, SDRAM y ahora podemos leer y escribir, por lo que el contenido del código para hacer algo con la reubicación SDRAM. Algunos de los contenidos ha sido https://blog.csdn.net/G_METHOD/article/details/104508545 mencionado en la reubicación de qué, por qué debe distinguir entre las reubicaciones, así como la escritura enlazador utilizado para la dirección, por lo aquí será descripción más simple.

Cuando nuestro programa no puede ejecutar en la dirección de destino original, se necesita el código para ser reubicados, y el código es hacer el programa de reubicación para mover para hacer frente a los efectos del programa se está ejecutando desde el normal funcionamiento de la dirección de la actualidad no se puede correr con normalidad.

Generalmente comprende replicación segmentos reubicables y borrar la sección bss, una sección bss valor inicial variable de no mundial 0 o el valor inicial de la recogida de las variables, y no como una sección presencia bss segmento de datos ahorra el bin tamaño del archivo. Y hacer enlaces de navegación para la reubicación es el guión, como la dirección de origen, dirección de destino y por lo tanto puede ser propuesta por el guión de enlazado, el guión puede hacer mientras disposición de la asignación de memoria de enlaces, la posición y la posición relativa del segmento de los acuerdos de distribución de memoria arbitraria, dejando espero su propio vacío, específica guión de enlazado y el contenido detallado se pueden leer http://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_mono/ld.html#IDX237 , puede ser más clara comprensión y utilizar el script enlazador, aquí para hablar de la racionalización de la parte central.

SECTIONS {
...
secname start BLOCK(align) (NOLOAD) : AT ( ldadr )
  { contents } >region :phdr =fill
...
}

Este es el núcleo de donde utilizamos para enlazar a la secuencia de comandos, SECCIONES formato fijo, un script de enlace debe tener como máximo y único, podemos organizar segmento de asignación de memoria en el interior de la sección. secname es el nombre del segmento, generalmente .data, .text, .rodata, .bss, etc., nombre de segmento deben ser reconocidos por el enlazador. Llenar la dirección de inicio de nuestro programa deseado está en marcha, y si no se especifica, el orden y la longitud de la sección de prensa inmediatamente antes de la dada. BLOQUE (Alinear) podemos establecer la operación sólo es absolutamente normal a la dirección inicial de la dirección de segmento está alineado, con el fin de asegurar que el programa, después de la alineación del texto no es la única manera de que esto se menciona en otra forma. Noload indica que el segmento en el archivo ejecutable, leer duende puede ver el segmento, pero no carga en memoria cuando se ejecuta el programa, porque somos los procedimientos de la junta desnudas, que se carga en la dirección de ubicación de almacenamiento, y por lo tanto no dijo esta carga concepto, personalmente creo que no sólo se carga para la capa de aplicación duende. Tenga en cuenta que: AT, en frente de la AT: ambas partes deben tener el espacio. dirección de carga A (ldadr) instrucciones del programa, en el archivo de bin, esta característica se puede utilizar para controlar el tamaño de la bandeja, tal como texto y de datos y bss dispuesto siguiente lugar, pero la dirección de reubicación al respectivo tiempo de ejecución de cada vez, Si no se especifica la misma dirección de inicio de AT (ldadr) la dirección, dirección de carga por defecto y correr. contenido de nuestra libertad para organizar el contenido local dentro del mismo párrafo de la orden. Y detrás de la región debido PhDr y rellenar sin utilizar aquí no es entrar en detalles, no se detalla en el documento vinculado segundo sitio se ha descrito anteriormente.

Ejemplo JZ2440 enlace de salida a la secuencia de comandos siguiente, la dirección de inicio de la SDRAM 0x30000000, que fue utilizado como una dirección de partida, que se utiliza aquí. Símbolo, símbolo que indica la dirección de la posición actual, está disponible sólo en unas secciones, se utilizará como el valor correcto asignación de la dirección actual a una variable, como en los siguientes = __copy_start enlace Guión .. Cuando se utiliza como valor de la izquierda se utiliza para especificar la dirección de la corriente, la asignación debe tenerse en cuenta que las operaciones relacionadas con la necesidad de sumar; símbolo final. ALGIN (4) representa una dirección alineada de 4 bytes, ya que el brazo 4 bytes de valor de referencia de decodificación de paso de ejecución, cuando la dirección no es de 4 bytes alineados, la alineación forzada, si no se alinean, puede ocurrir 0x3002 segmento de datos en este tiempo necesario para escribir la región de datos se alinea directamente realizar la asignación de la dirección 0x3000, 0x3000 caso si la dirección es un código válido se sobreponen, el programa que causa un funcionamiento anormal, por lo tanto, el seguro razones, deben estar alineados con cada segmento.

linker.lds
-------------------------
SECTIONS{
	. = 0x30000000;
	. = ALIGN(4);
	
	_copy_start = .;
	.text : { *(.text) }
	
	. = ALIGN(4);
	.rodata :{ *(.rodata) }
	
	. = ALIGN(4);
	.data : { *(.data) }
	
	. = ALIGN(4);
	_copy_end = .; 
	
	_bss_start = . ;
	.bss : {
		*(.bss)
		*(.COMMON)
	}
	_bss_end = .;
}

contenidos parte del guión enlazador que describe lo que será colocado en el segmento, el comodín * para todos los archivos, aquí es la implementación de LD archivo de destino especificado, cada archivo -T linker.lds xxx.o yyy.o objetivo en la memoria orden del objeto especificado se ejecuta en el orden de la posición y ld, y si dispuestos en la forma descrita anteriormente, entonces la orden es xxx.o yyy.o, por supuesto, con el fin de especificar un contenido del archivo de destino, como tenemos que empezar. S el archivo de inicio se coloca delante de los otros archivos, por lo que puede

.text : { Start.o(.text) *(.text) }

Separados por espacios intermedios.

Aquí reubicaciones se refieren a la replicación del segmento de programa ejemplar y bss segmentos borran, las variables correspondientes definidos en una posición correspondiente segmento para el programa de reposicionamiento. Necesidad de decir que las variables definidas en las secciones, no hay signo del valor está presente en el elfo en la tabla de símbolos, expandirlo, variables y funciones globales se almacenan en la tabla de símbolos, la tabla de símbolos correspondiente al símbolo no es una dirección correspondiente, la dirección apunta a la zona es el valor inicial de la variable, la situación es una función de más compleja aquí no expandirse, y los guiones de enlace variable almacenada aquí, sino también una dirección correspondiente, pero no hay ningún valor, la dirección correspondiente es el valor de las variables de proceso enlazador, por lo tanto, debe ser usado como un símbolo para uso externo, pero es sólo para tomar la dirección, de la siguiente manera, utilizando el tipo de puntero de dirección de 32 bits que apunta a la operación correspondiente se puede completar rápidamente en esta etapa (para el software y el hardware de características niveles determinados ).

extern uint32_t _bss_start;
uint32_t *target_start_address = &_bss_start;

El conocimiento detallado de la tabla de símbolos y un enlazador de variables de proceso y cómo utilizar C enlace variable de script language puede ver https://sourceware.org/ml/binutils/2007-07/msg00154.html , sobre la base de lo anterior, el código de salida es la siguiente:

Start.S
----------------
.text
.global _start

_start:
	MOV R0,#0
	LDR R1,[R0]
	
	STR R0,[R0]
	LDR R2,[R0]
	
	CMP R2,R0
	LDR SP,=0x40000000+4096
	MOVEQ SP,#4096
	STREQ R1,[R0]
	
	bl HardwareInitAll          //相对跳转
	ldr pc,=main                //绝对跳转,到SDRAM上运行
halt:
    b halt
s3c2440.c
------------------------
#include "s3c2440.h"

....

static void CopySegmentForReloacte(void)
{
	extern uint32_t _copy_start,_copy_end;
	uint32_t *source_start = 0;
	uint32_t *target_start = &_copy_start;
	uint32_t *target_end = &_copy_end;

	while(target_start <= target_end)
	{
		*target_start++ = *source_start++;
	}
}

static void CleanBssSegment(void)
{
	extern uint32_t _bss_start,_bss_end;
	uint32_t *target_start_address = &_bss_start;
	uint32_t *target_end = &_bss_end;

	while(target_start_address <= target_end)
	{
		*target_start_address++ = 0;
	}
}


void HardwareInitAll(void)
{
	WatchDogDisable();
	ClockDevideConfig();
	ChangeModeToAsynchronous();
	MPLLConfig();
	MemoryControllerInit();
	CopySegmentForReloacte();
	CleanBssSegment();
}

main.c
------
#include <stdint.h>

#include "s3c2440.h"
#include "led.h"
#include "uart.h"

char test_char = 'A';

int main()
{
	UartInit();

	while(1)
	{
		putc(test_char);
		if(++test_char > 'Z') { test_char = 'A'; }
		Delay(1000);
	}
	return 0;
}

MAKE, utilice la opción -t para especificar la secuencia de comandos enlazador, de la siguiente manera

al:
        arm-linux-gcc -o Start.o -c Start.S
        arm-linux-gcc -o main.o -c main.c
        arm-linux-gcc -o s3c2440.o -c s3c2440.c
        arm-linux-gcc -o uart.o -c uart.c
        arm-linux-gcc -o led.o -c led.c
        arm-linux-gcc -o key.o -c key.c
        arm-linux-ld -T linker.lds -o led.elf Start.o s3c2440.o led.o key.o uart.o main.o
        arm-linux-objcopy -O binary -S led.elf led.bin
        arm-linux-objdump -D led.elf > led.dis

clean:
        rm *.dis *.o *.bin *.elf

Escribir en el Norflash compilado, si la salida serie normal secuencialmente AZ es decir, un traslado exitoso.

Bl Start.S el salto relativo a que se inicie la función de inicialización y reposicionamiento, ya que los datos de instrucciones efectivas antes de la operación de reubicación no es ejecutable cuando la dirección no se ha completado, la ejecución del programa salta por un relativamente inteligente en el Norflash, cuando el programa de reubicación es decir, después de la dirección en tiempo de ejecución en los datos SDRAM están listos, usando LDR absoluta salto salto oficial a la operación SDRAM. Se puede concluir que prohíben el uso del código de posición dependiente de reubicación antes del código sólo se puede utilizar independientemente de la posición de la ejecución del código de programa.

Deje en blanco, complementado más tarde determinar el código independiente de la posición.

Se han publicado 19 artículos originales · ganado elogios 7 · vistas 6921

Supongo que te gusta

Origin blog.csdn.net/G_METHOD/article/details/104527632
Recomendado
Clasificación