"No multiboot header found" with minimal kernel - c

I build a simple OS with three files, but get a ogg problem, the files are here:
loader.s
.extern kernel_main
.global _start
.set MB_ALIGN, 1<<0
.set MB_MEMINFO, 1<<1
.set MB_MAGIC, 0x1BADB002
.set MB_FLAGS, MB_ALIGN | MB_MEMINFO
.set MB_CHECKSUM, - (MB_MAGIC + MB_FLAGS)
.section .multiboot
.align 4
.long MB_MAGIC
.long MB_FLAGS
.long MB_CHECKSUM
.section .bss
.align 16
stack_bottom:
.skip 4096
stack_top:
.section .text
_start:
mov $stack_top, %esp
call kernel_main
hang:
cli
hlt
jmp hang
.size _start, . - _start
and kernel.c
#include <stddef.h>
#include <stdint.h>
const int a = 10;
void kernel_main()
{
uint8_t* video = (uint8_t*) 0xB8000;
const char* hello = "Hello World! From MYOS";
for (size_t i = 0; i < 23; i++)
{
video[2 * i] = hello[i];
video[2 * i + 1] = 0x07;
}
}
and linker.ld
ENTRY(_start);
SECTIONS {
. = 1M;
.rodata BLOCK(4K) : ALIGN(4K)
{
*(.multiboot)
}
.text BLOCK(4K) : ALIGN(4K)
{
*(.text)
}
.rodata BLOCK(4K) : ALIGN(4K)
{
*(.rodata)
}
.data BLOCK(4K) : ALIGN(4K)
{
*(.data)
}
.bss BLOCK(4K) : ALIGN(4K)
{
*(COMMON)
*(.bss)
}
}
and I compile these code:
i686-elf-gcc -std=gnu99 -ffreestanding -g -c start.s -o start.o
i686-elf-gcc -std=gnu99 -ffreestanding -g -c kernel.c -o kernel.o
i686-elf-gcc -ffreestanding -nostdlib -g -T linker.ld start.o kernel.o -o mykernel.elf -lgcc
I run this kernel, but got no multiboot header found.
if I modify kernel.c to:
#include <stddef.h>
#include <stdint.h>
const int a = 10; // Just add this line.
void kernel_main()
{
uint8_t* video = (uint8_t*) 0xB8000;
const char* hello = "Hello World! From MYOS";
for (size_t i = 0; i < 23; i++)
{
video[2 * i] = hello[i];
video[2 * i + 1] = 0x07;
}
}
Its work! Why?

Related

Echo of data in UART through interrupts in LM3S811 Qemu Simulation

I am trying to transmit and receive characters in UART through interrupts in LM3S811 using Qemu Simulation. I wrote this code with the help of this https://www.electronicwings.com/arm7/lpc2148-uart0. I am not sure whether it is correct and it does not work. Could someone suggest how to get the task done.
startup code :
.thumb
.global start
start:
.word 0x20001000
.word main
flash.ld
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00010000
SRAM (rxw) : ORIGIN = 0x20000000, LENGTH = 0x00002000
}
SECTIONS
{
.text : {
*(.vectors);
*(.text);
etext = .;
} > FLASH
.rodata : {
*(.rodata);
} > FLASH
.data : {
sdata = .;
*(.data);
edata = .;
} > SRAM AT > FLASH
.bss: {
sbss = .;
*(.bss);
ebss = .;
} > SRAM
}
main.c
#define UARTDR (*((volatile unsigned int *) 0x4000C000)) // Data register for UART...
#define UARTIFLS (*((volatile unsigned int *) 0x40000034)) // Interrupt identification register...
#define UARTFR (*((volatile unsigned int *) 0x4000C018)) // Register which holds the status of the FIFO...
char rx;
_irq void UART0_Inerrupt(void)
{
int iir_value;
iir_value = UARTIFLS // Interrupt Identification register...
if (iir_value & 0x00) { // If interrupt is received, i.e data is present...
rx = UARTDR;
}
UARTDR = rx; // Write to data register for writing to transmit FIFO...
while ( (UARTFR & 0x20) == 1) continue;
}
int main(void)
{
NVICVectAddr0 = (unsigned) UART0_Inerrupt;
while(1);
}
``

printf in newlib is not working in baremetal ARM environment

I am working in a bare-metal ARM project in which I am trying to integrate newlib library. As a beginner, I am trying to make the printf function working first so that I can see the standard output through UART. I have already gone through many on-line documents that describes how to get this done. Instead of blindly following the steps, I did everything myself by learning things from those documents. I made many mistakes in the beginning but fixed them one by one and kept the work progressing.
But now I have stuck with an issue which no one has ever seems to be experienced so far, according to my internet search. Now let me come to the actual, issue.
The printf function is returning without calling my implementation of _write function. When I debug I can see that the printf is invoking other system calls that I have written myself(Like _isatty, _sbrk and _fstat).
These are the system calls that I have implemented in order to resolve the linking issues(undefined references)
extern char __heap_start__;
extern char __heap_end__;
void _exit(int status)
{
while (1);
}
void *_sbrk(int incr)
{
static char *heap_end = &__heap_start__;
char *base = heap_end;
if(heap_end + incr > &__heap_end__)
{
errno = ENOMEM;
return (void *)-1;
}
heap_end += incr;
return base;
}
int _write(int fd, char *buff, int size)
{
int i;
for(i = 0; i < size; i++)
{
UART0_write_char(buff[i]);
}
return i;
}
int _read(int fd, char *buff, int size)
{
return 0;
}
int _open(const char *name, int flags,int mode)
{
return 0;
}
void _close(int fd)
{
}
int _isatty(int fd)
{
return 1;
}
int _fstat(int fd, struct stat *st)
{
st->st_mode = S_IFCHR;
return 0;
}
off_t _lseek(int fd, off_t offset, int whence)
{
return 0;
}
My linker script
STACK_HEAP_BOUNDARY_OFFSET = 0;
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 512K
SRAM (rw) : ORIGIN = 0x40000000, LENGTH = 32K
}
SECTIONS
{
.text :
{
startup.o (.text)
*(.text .txt.*)
*(.glue_7)
*(.glue_7t)
. = ALIGN(4);
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
.ARM :
{
*(.ARM.exidx*)
} >FLASH
.rodata :
{
*(.rodata .rodata.*)
. = ALIGN(4);
} > FLASH
.data :
{
__data_load__ = LOADADDR (.data);
__data_start__ = .;
*(.data .data.*)
. = ALIGN(4);
__data_end__ = .;
} > SRAM AT > FLASH
.bss :
{
__bss_start__ = .;
*(.bss .bss.*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > SRAM
.heap :
{
__heap_start__ = .;
PROVIDE(end = __heap_start__);
PROVIDE(_heap_start = __heap_start__);
. = . + ((LENGTH(SRAM) - (. - (ORIGIN(SRAM)))) / 2);
. += STACK_HEAP_BOUNDARY_OFFSET;
. = ALIGN(4);
__heap_end__ = .;
PROVIDE(_heap_end = __heap_end__);
} > SRAM
.stack :
{
__stack_start__ = .;
. = . + (LENGTH(SRAM) - (. - (ORIGIN(SRAM))));
. = ALIGN(4);
__stack_end__ = .;
__stack_size__ = __stack_end__ - __stack_start__;
__IRQ_stack_top__ = (__stack_start__ + (__stack_size__ / 2));
} > SRAM
}
My Makefile
TOOLCHAIN_PREFIX:=arm-none-eabi-
CC := $(TOOLCHAIN_PREFIX)gcc
LD := $(TOOLCHAIN_PREFIX)ld
AS := $(TOOLCHAIN_PREFIX)as
AR := $(TOOLCHAIN_PREFIX)ar -cr
OBJCOPY := $(TOOLCHAIN_PREFIX)objcopy
RM := rm -f
TARGET := image.hex
OBJS := startup.o $(patsubst %.c,%.o,$(wildcard *.c))
CFLAGS := -mcpu=arm7tdmi-s -g3 -Wall -I. -gdwarf-2
AS_FLAGS := -mcpu=arm7tdmi-s -g3 -gdwarf-2
LD_FLAGS := -Wl,-Map,$(TARGET:%.hex=%).map -nostartfiles
LD_SCRIPT := lpc2138.ld
all : $(TARGET)
$(TARGET) : $(TARGET:%.hex=%.elf)
$(OBJCOPY) -O ihex $< $#
$(TARGET:%.hex=%.elf) : $(OBJS)
$(CC) -o $# -T $(LD_SCRIPT) $(OBJS) $(LD_FLAGS)
startup.o : startup.s
$(AS) $(AS_FLAGS) -o $# $<
%.o : %.c
$(CC) -c $(CFLAGS) -o $# $<
clean :
$(RM) $(TARGET) $(TARGET:%.hex=%.elf) $(TARGET:%.hex=%).map *.o
Please let me know if any further information is needed from my side. Thank you in advance
EDIT:
Start-up code
/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs */
Mode_USR = 0x10
Mode_FIQ = 0x11
Mode_IRQ = 0x12
Mode_SVC = 0x13
Mode_ABT = 0x17
Mode_UND = 0x1B
Mode_SYS = 0x1F
I_Bit = 0x80 /* when I bit is set, IRQ is disabled */
F_Bit = 0x40 /* when F bit is set, FIQ is disabled */
.text
.arm
.global _start
.func _start
_start:
B _reset /* Reset vector */
B _loop /* Undefined Instruction */
B _loop /* Software Interrupt */
B _loop /* Prefetch Abort */
B _loop /* Data Abort */
NOP /* Reserved */
LDR pc, [pc, #-0x0FF0] /* VicVectAddr */
/* LDR pc, _fiq_addr */
B _loop /* FIQ Handler */
_reset:
/* Enable FIQ and IRQ */
MSR CPSR_c,#(Mode_IRQ | I_Bit | F_Bit)
LDR SP, =__IRQ_stack_top__
MSR CPSR_c,#Mode_SVC
/* Relocate the .data section (copy from ROM to RAM) */
LDR r0,=__data_load__
LDR r1,=__data_start__
LDR r2,=__data_end__
_l1:
CMP r1,r2
LDMLTIA r0!,{r3}
STMLTIA r1!,{r3}
BLT _l1
/* Clear the .bss section (zero init) */
LDR r1,=__bss_start__
LDR r2,=__bss_end__
MOV r3,#0
_l2:
CMP r1,r2
STMLTIA r1!,{r3}
BLT _l2
LDR sp,=__stack_end__
LDR FP,=__stack_end__
LDR r0,=main
MOV lr,pc
BX r0
_loop:
B _loop
/* _fiq_addr:
.word VIC_FIQ_handler
*/
.endfunc
.end

why my vaiable not following the code in gdb stm32 project

my code here:
void _init(void) {return;}
int main(void)
{
/* STM32F2xx HAL library initialization:
- Configure the Flash prefetch, instruction and Data caches
- Configure the Systick to generate an interrupt each 1 msec
- Set NVIC Group Priority to 4
- Global MSP (MCU Support Package) initialization
*/
HAL_Init();
/* Configure the system clock to 64 MHz */
SystemClock_Config();
/* Enable CRC clock */
__CRC_CLK_ENABLE();
Example_Status = 1;
Example_Status = 2;
Example_Status = 3;
.....
and my gdb on my stm32 using stlink-texane are as follow:
(gdb) s
main () at main.c:74
74 __CRC_CLK_ENABLE();
(gdb) s
77 Example_Status = 3;
(gdb) p Example_status
No symbol "Example_status" in current context.
(gdb) p Example_Status
$1 = 139640994
(gdb) n
74 __CRC_CLK_ENABLE();
(gdb) n
77 Example_Status = 3;
(gdb) n
183 Example_Status = ExampleECCKeyGenSignVerif();
(gdb) p Example_Status
$2 = 139640994
i am wondering why the Example_Status outcome not = 3 ?
and the storage of the variable are
arm-none-eabi-objdump --syms main.o | grep Example_Status
00000000 l d .bss.Example_Status 00000000 .bss.Example_Status
00000000 g O .bss.Example_Status 00000004 Example_Status
and my linker file are here:
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x20010000; /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x000;; /* required amount of heap */
_Min_Stack_Size = 0x000;; /* required amount of stack */
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH
/* Constant data goes into FLASH */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >FLASH
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
.ARM : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
/* used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized data sections goes into RAM, load LMA copy after code */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM AT> FLASH
/* Uninitialized data section */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM
/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}
This is my first linux project, i would appreicate if someone can help~
thanks
Edited for adding "disassemble /m"
75 Example_Status = 1;
0x080002ac <+24>: and.w r3, r3, #33554432 ; 0x2000000
0x080002b0 <+28>: cmp r3, #0
---Type <return> to continue, or q <return> to quit---
76 Example_Status = 2;
0x080002b2 <+30>: beq.n 0x80002a8 <main+20>
0x080002b4 <+32>: ldr r3, [pc, #60] ; (0x80002f4 <main+96>)
0x080002b6 <+34>: movw r2, #1795 ; 0x703
77 Example_Status = 3;
0x080002b8 <+36>: strb r3, [r0, #8]
0x080002ba <+38>: str r2, [r3, #0]
0x080002bc <+40>: ldr r2, [pc, #44] ; (0x80002ec <main+88>)
//
(gdb) n
75 Example_Status = 1;
(gdb) n
76 Example_Status = 2;
(gdb) p Example_Status
$1 = 140166176
(gdb) s
When compiling, and you want reliable debugging, do not compile with optimization-level higher than 0:
gcc -O0 mycode.c -o mycode.o -c

Why arm-none-eabi-ld linker leaves padding bytes in single translation unit?

I got some evaluation board with uC STM32F405RG, this micro has ARM Cortext M4 core. Please find reference to the uC :
http://www.st.com/web/catalog/mmc/FM141/SC1169/SS1577/LN1035/PF252144#
I'm using also arm-none-eabi toolchain for linux from below site:
https://launchpad.net/gcc-arm-embedded
After compiling and linking some project I've noticed that linker puts extra padding bytes between mine global variables which are stored in .bss section. Please find short snippet from the map file:
.bss.variable1
0x20002d14 0x15 /path/to/application.o
.bss.variable2
0x20002d29 0x1 /path/to/application.o
.bss.variable3
0x20002d2a 0x1 /path/to/application.o
.bss.variable4
0x20002d2b 0x1 /path/to/application.o
.bss.variable5
0x20002d2c 0x1c /path/to/application.o
.bss.variable6
0x20002d48 0x1 /path/to/application.o
*fill* 0x20002d49 0x3
.bss.variable7
0x20002d4c 0x4 /path/to/application.o
.bss.variable8
0x20002d50 0x8 /path/to/application.o
.bss.variable9
0x20002d58 0x1c /path/to/application.o
.bss.variable10
0x20002d74 0x1 /path/to/application.o
Additionally here is my linker script:
ENTRY(Reset_Handler)
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000 + 256K, LENGTH = 1M - 256K -(3*128K)
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
}
_stack_size = 16K;
_estack = ORIGIN(RAM) + LENGTH(RAM);
_sstack = _estack - _stack_size;
SECTIONS
{
.text :
{
_stext = .;
KEEP(*(.isr_vector))
. += 8;
*(.text)
*(.text*)
*(.rodata)
*(.rodata*)
*(.glue_7)
*(.glue_7t)
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .;
} >FLASH
.ARM.extab :
{
*(.ARM.extab*)
*(.gnu.linkonce.armextab.*)
} >FLASH
.ARM :
{
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(.fini_array*))
KEEP (*(SORT(.fini_array.*)))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
_sidata = .;
.data :
{
. = ALIGN(4);
_sdata = .;
*(.data)
*(.data*)
. = ALIGN(4);
_edata = .;
} >RAM AT> FLASH
. = ALIGN(4);
.bss :
{
_sbss = .;
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
__bss_end__ = _ebss;
} >RAM
.stack :
{
. += _stack_size;
} >RAM
.memory_b1_text :
{
*(.mb1text) /* .mb1text sections (code) */
*(.mb1text*) /* .mb1text* sections (code) */
*(.mb1rodata) /* read-only data (constants) */
*(.mb1rodata*)
} >MEMORY_B1
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}
Here is type declarations, they're distributed around few header files but I'm putting them here at once:
typedef enum
{
False=0,
True=1
} bool;
typedef enum
{
Unknown,
Data,
Crc
} type3_t;
typedef struct
{
unsigned char data[20];
unsigned char size;
} __attribute__((packed)) type1_t;
typedef enum
{
msg1,
msg2,
msg3
} msg_type_t
typedef struct
{
uint8_t msg;
uint32_t src;
uint32_t dest;
} header_t;
typedef struct
{
header_t header;
uint8_t len;
uint8_t id;
uint8_t idx;
uint8_t type;
} header2_t;
typedef struct
{
header2_t header;
uint8_t* data;
} ex_header_t;
typedef struct
{
msg_type_t type;
union
{
uint8_t * rawData;
header_t header;
ex_header_t ex_header;
} u;
uint8_t val;
} type5_t;
typedef struct
{
uint32_t id;
uint8_t idx;
uint8_t crc[2];
} type8_t;
and application.c file, I left order like in *.c file:
static type5_t variable5;
static type5_t variable9;
static type8_t variable8;
static type3_t variable3 = Unknown;
static type1_t variable1;
static bool variable10 = False;
static unsigned char variable6 = 0;
static bool variable4;
static unsigned char variable2 = 0;
/* few function definitions here */
static void * variable7;
The question is why arm-none-eabi-ld linker is doing so? Why linker cannot put in place of padding bytes, variables which are one byte big(e.g. chars) ? Everything is happening in the same translation unit so I think linker should be able to sort them and utilize more RAM memory. Even if one byte (char) or two bytes variables (short) are not present in the same translation unit, why shouldn't linker take them from other *.o files ?

.data LMA overlapps .data VMA addresses

I am quite new to linker script concepts.
I have ran into some strange problems.
the sections does not seem to have the right addresses for VMA.
For example if we look at the .data sections the VMA that has been provided in inside LMA+size.
(meaning that during start-up once I copy the data from LMA to VMA the last bytes of LMA addresses will have been overwritten)
This is how the result looks like, see .data and you will see what I mean:
Sections:
Idx Name Size VMA LMA File off Algn
0 .rcw 00000008 20000000 20000000 00010000 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .init 00000628 20000008 20000008 00010008 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 .text 000177f8 20000630 20000630 00010630 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
3 .flash_data 00000010 20017e28 20017e28 00027e28 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
4 .rodata 00000ec0 20017e38 20017e38 00027e38 2**4
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .xcptn 000008e8 20019000 20019000 00029000 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
6 .extram 00002080 2001a000 200198e8 0002a000 2**13
CONTENTS, ALLOC, LOAD, DATA
7 .data 000008f0 2001c080 2001b968 0002c080 2**3
CONTENTS, ALLOC, LOAD, DATA
8 .got 00000010 2001c970 2001c258 0002c970 2**2
CONTENTS, ALLOC, LOAD, CODE
9 .got2 00000220 2001c980 2001c268 0002c980 2**2
CONTENTS, ALLOC, LOAD, DATA
10 .sdata 00000038 2001cba0 2001c488 0002cba0 2**2
CONTENTS, ALLOC, LOAD, DATA
11 .sbss 00000088 2001cbd8 2001c4c0 0002cbd8 2**2
ALLOC
12 .bss 0000bbbc 2001cc60 2001c548 0002cbd8 2**2
ALLOC
13 .isrvectbl 00000d88 2002881c 20028104 0002cbd8 2**2
ALLOC
14 .debug_aranges 00001618 00000000 00000000 0002cbd8 2**3
CONTENTS, READONLY, DEBUGGING
15 .debug_pubnames 00002843 00000000 00000000 0002e1f0 2**0
CONTENTS, READONLY, DEBUGGING
16 .debug_info 0003f23a 00000000 00000000 00030a33 2**0
CONTENTS, READONLY, DEBUGGING
17 .debug_abbrev 00009c89 00000000 00000000 0006fc6d 2**0
CONTENTS, READONLY, DEBUGGING
18 .debug_line 0000ae64 00000000 00000000 000798f6 2**0
CONTENTS, READONLY, DEBUGGING
19 .debug_frame 00003bb8 00000000 00000000 0008475c 2**2
CONTENTS, READONLY, DEBUGGING
20 .debug_str 00007b24 00000000 00000000 00088314 2**0
CONTENTS, READONLY, DEBUGGING
21 .debug_loc 00015465 00000000 00000000 0008fe38 2**0
CONTENTS, READONLY, DEBUGGING
22 .debug_ranges 00001768 00000000 00000000 000a52a0 2**3
CONTENTS, READONLY, DEBUGGING
23 .comment 00000750 00000000 00000000 000a6a08 2**0
CONTENTS, READONLY
24 .gnu.attributes 00000012 00000000 00000000 000a7158 2**0
CONTENTS, READONLY
the following ld-script is the one that has been provided to me:
ENTRY(__start)
/*
*****************************************************************
* PE_MPC5554_rom.ld
* GNU powerpc-eabispe Linker Script for the MPC5554
* By default, this application runs in internal flash, SRAM, and cache
* c. 2005, P&E Microcomputer Systems, Inc.
* REV AUTHOR DATE DESCRIPTION OF CHANGE
* --- ----------- ---------- ---------------------
* 0.1 C.Baker FSL 19/Jul/06 Changed memory layout, stack
* variables, and filename.
* 0.2 C.Baker FSL 21/Sep/06 Changed stack in cache address.
*****************************************************************
*/
MEMORY
{
/* 32M External SRAM */
ext_ram : org = 0x20000000, len = 0x02000000 /* 32M on the G3 board */
/* Internal Flash RCW */
/* MPC5567 2M Internal Flash, but subtract two 128K blocks for use by emulated eeprom. */
/* but subtract one 128K block for use by BAM. */
/* MPC5567 80K Internal SRAM */
flash_rcw : org = 0x00000000, len = 0x8
int_flash : org = 0x00000008, len = 0x001BFFF8
int_sram : org = 0x40000000, len = 0x14000
/* e4_flash is reserved for emulated eeprom in partition 9 of the High Address Space. */
e4_flash : org = 0x001C0000, len = 0x40000
}
/* The performance of applications can, potentially, be improved by locking */
/* the stack into the cache. However, as this complicates debugging (e.g., */
/* function parameters are not visible from GDB) it is only advisable for */
/* production code, not during development. Set STACK_IN_CACHE to 1 in the */
/* application's "config.inc" to lock the stack into cache. Otherwise, set */
/* STACK_IN_CACHE to 0, and the stack will be placed at the top of the */
/* internal RAM. */
/* Stack Address Parameters */
/* __SP_END = DEFINED( STACK_IN_CACHE ) ? 0x40040000 : 0x40013000; */
__SP_END = 0x40013000;
__STACK_SIZE = 0x1000;
__SP_INIT = __SP_END + __STACK_SIZE;
/*
Optionally define this variable with the address of heap
__heap_start = __SP_END;
*/
/****************************************************************/
SECTIONS
{
.rcw :
{
KEEP( *(.rcw) )
} > ext_ram
/* CRT0 startup code */
.pecrt0 ALIGN(8) :
{
*(.pecrt0)
PEFILL = .;
. = ALIGN(8);
} > ext_ram
.interp ALIGN(8) :
{
*(.interp)
. = ALIGN(8);
} > ext_ram
.hash ALIGN(8) :
{
*(.hash)
. = ALIGN(8);
} > ext_ram
.dynsym ALIGN(8) :
{
*(.dynsym)
. = ALIGN(8);
} > ext_ram
.dynstr ALIGN(8) :
{
*(.dynstr)
. = ALIGN(8);
} > ext_ram
.rela.dyn ALIGN(8) :
{
*(.rela.init)
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
*(.rela.fini)
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
*(.rela.ctors)
*(.rela.dtors)
*(.rela.got)
*(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*)
*(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*)
*(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*)
*(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
. = ALIGN(8);
} > ext_ram
.init ALIGN(8) :
{
PROVIDE (__init = .);
KEEP( *(.init) )
. = ALIGN(8);
} > ext_ram
.text ALIGN(8) :
{
*(.text)
*(.text.*)
*(.gnu.warning)
*(.gnu.linkonce.t*)
__eabi = (.); /*PE*/
LONG(0x4E800020);
. = ALIGN(8);
} > ext_ram
.fini ALIGN(8) :
{
/*PROVIDE (__fini = .);*/
KEEP( *(.fini) )
. = ALIGN(8);
} > ext_ram
.flash_data ALIGN(8) :
{
KEEP( *(.flash_data))
. = ALIGN(8);
} > ext_ram
.rodata ALIGN(8) :
{
. = ALIGN(8);
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r*)
. = ALIGN(8);
} > ext_ram
.rodata1 ALIGN(8) :
{
*(.rodata1)
. = ALIGN(8);
} > ext_ram
.PPC.EMB.apuinfo ALIGN(8) :
{
*(.PPC.EMB.apuinfo)
. = ALIGN(8);
} > ext_ram AT > ext_ram
/* ISR table for software vector mode */
.isrvectbl ALIGN(0x800) : ONLY_IF_RO
{
KEEP( *(.isrvectbl) )
} > ext_ram
PROVIDE (__EXCEPT_START__ = .);
/* IVOR4Handler */
.xcptn ALIGN(8) :
{
KEEP( *(.xcptn) )
. = ALIGN(8);
} > ext_ram
PROVIDE (__EXCEPT_END__ = .);
etext = .;
_etext = .;
__etext = .;
/******************************************************************/
NEXT_LOAD_ADDR = .;
__EXTDATA_ROM = .;
.extram : AT (NEXT_LOAD_ADDR)
{
*(.extram)
. = ALIGN(4);
} > ext_ram
/******************************************************************/
NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.extram);
/*NEXT_LOAD_ADDR = .;
__DATA_ROM = .;*/
__DATA_ROM = NEXT_LOAD_ADDR;
/* .PPC.EMB.sdata2 0x20100000 : AT (NEXT_LOAD_ADDR)*/
.PPC.EMB.sdata2 : AT (NEXT_LOAD_ADDR)
{
_SDA2_BASE_ = .;
__SDATA2_START__ = .;
*(.PPC.EMB.sdata2)
. = ALIGN(8);
} > ext_ram
NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.PPC.EMB.sdata2);
.sdata2 : AT (NEXT_LOAD_ADDR)
{
*(.sdata2)
. = ALIGN(8);
} > ext_ram
NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.sdata2);
.PPC.EMB.sbss2 : AT (NEXT_LOAD_ADDR)
{
*(.PPC.EMB.sbss2)
. = ALIGN(8);
} > ext_ram
NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.PPC.EMB.sbss2);
.sbss2 : AT (NEXT_LOAD_ADDR)
{
*(.sbss2)
__SBSS2_END__ = .;
. = ALIGN(8);
} > ext_ram
NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.sbss2);
.data :
{
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
CONSTRUCTORS
. = ALIGN(8);
} > ext_ram
NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.data);
.data1 :
{
*(.data1)
. = ALIGN(8);
} > ext_ram
NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.data1);
PROVIDE (__GOT_START__ = .);
.got :
{
*(.got)
. = ALIGN(8);
} > ext_ram
NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.got);
.got.plt :
{
*(.got.plt)
. = ALIGN(8);
} > ext_ram
PROVIDE (__GOT_END__ = .);
NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.got.plt);
.got1 :
{
*(.got1)
. = ALIGN(8);
} > ext_ram
NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.got1);
PROVIDE (__GOT2_START__ = .);
.got2 :
{
*(.got2)
. = ALIGN(8);
} > ext_ram
NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.got2);
PROVIDE (__CTOR_LIST__ = .);
.ctors :
{
/*KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))*/
KEEP (*(.ctors))
. = ALIGN(8);
} > ext_ram
NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.ctors);
PROVIDE (__CTOR_END__ = .);
PROVIDE (__DTOR_LIST__ = .);
.dtors : AT (NEXT_LOAD_ADDR)
{
/*KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))*/
KEEP (*(.dtors))
. = ALIGN(8);
} > ext_ram
NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.dtors);
PROVIDE (__DTOR_END__ = .);
PROVIDE (__FIXUP_START__ = .);
.fixup : AT (NEXT_LOAD_ADDR)
{
*(.fixup)
. = ALIGN(8);
} > ext_ram
NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.fixup);
PROVIDE (__FIXUP_END__ = .);
PROVIDE (__GOT2_END__ = .);
.dynamic : AT (NEXT_LOAD_ADDR)
{
*(.dynamic)
. = ALIGN(8);
} > ext_ram
NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.dynamic);
.plt : AT (NEXT_LOAD_ADDR)
{
*(.plt)
. = ALIGN(8);
} > ext_ram
NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.plt);
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
__SDATA_ROM = .;
.sdata :
{
__SDATA_START__ = .;
_SDA_BASE_ = .;
*(.sdata)
. = ALIGN(8);
} > ext_ram
NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.sdata);
.PPC.EMB.sdata0 : AT (NEXT_LOAD_ADDR)
{
__SDATA_END__ = .;
. = ALIGN(8);
} > ext_ram
__DATA_ROM_END = .;
edata = .;
_edata = .;
__edata = .;
/******************************************************************/
.sbss BLOCK (4):
{
PROVIDE (__sbss_start = .);
PROVIDE (___sbss_start = .);
*(.sbss)
*(.scommon)
*(.dynsbss)
} > ext_ram
.PPC.EMB.sbss0 BLOCK (4):
{
*(.PPC.EMB.sbss0)
PROVIDE (__sbss_end = .);
PROVIDE (___sbss_end = .);
PROVIDE (__SBSS_END__ = .);
} > ext_ram
.bss BLOCK (4):
{
PROVIDE (__bss_start = .);
PROVIDE (___bss_start = .);
*(.dynbss)
*(.bss)
*(COMMON)
PROVIDE (__bss_end = .);
} > ext_ram
.isrvectbl BLOCK (4) (NOLOAD): ONLY_IF_RW
{
. = ALIGN(0x800);
KEEP( *(.isrvectbl) )
} > ext_ram
/* ISR table for software vector mode */
/******************************************************************/
/*
Heap grows from lower to higer addresses
Stack grows from higer to lower addresses
*/
/* Define position of heap */
/* Default to location contiguous with .bss section in RAM */
_end = DEFINED (__heap_start) ? __heap_start : ALIGN(8);
PROVIDE(end = _end);
PROVIDE(__end = _end);
/******************************************************************/
.gcc_except_table : {*(.gcc_except_table)}
/* These are needed for ELF backends which have not yet been
converted to the new style linker. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* */
.eh_frame 0 : { *(.eh_frame) }
/******************************************************************/
__SRAM_CPY_START = ADDR(.PPC.EMB.sdata2);
__IV_ADDR = ADDR(.xcptn);
__SRAM_LOAD = (_end);
__SRAM_LOAD_SIZE = (SIZEOF(.flash_data) / 4);
__EXTRAM_CPY_START = ADDR(.extram);
__EXTRAM_CPY_END = ADDR(.extram)+SIZEOF(.extram);
__BSS_SIZE = ((__bss_end - __bss_start) / 4);
__SBSS_SIZE = ((__sbss_end - __sbss_start) / 4);
TEMPSIZE = SIZEOF(.PPC.EMB.sdata2)+SIZEOF(.sdata2)+SIZEOF(.PPC.EMB.sbss2)+SIZEOF(.sbss2)+SIZEOF(.data)+SIZEOF(.data1);
TEMPSIZE = TEMPSIZE + SIZEOF(.got)+SIZEOF(.got.plt)+SIZEOF(.got1)+SIZEOF(.got2)+SIZEOF(.ctors);
TEMPSIZE = TEMPSIZE + SIZEOF(.dtors)+SIZEOF(.fixup)+SIZEOF(.dynamic)+SIZEOF(.plt);
TEMPSIZE = TEMPSIZE + SIZEOF(.sdata)+SIZEOF(.PPC.EMB.sdata0);
__ROM_COPY_SIZE = (TEMPSIZE);
__DATA_VMA = ADDR(.data);
__DATA_LMA = LOADADDR(.data);
__DATA_LMA_END = __DATA_LMA + SIZEOF(.data);
__GOT_VMA = ADDR(.got);
__GOT_LMA = LOADADDR(.got);
__GOT_LMA_END = __GOT_LMA + SIZEOF(.got);
__GOT2_VMA = ADDR(.got2);
__GOT2_LMA = LOADADDR(.got2);
__GOT2_LMA_END = __GOT_LMA + SIZEOF(.got2);
__SDATA_VMA = ADDR(.sdata);
__SDATA_LMA = LOADADDR(.sdata);
__SDATA_LMA_END = __SDATA_LMA + SIZEOF(.sdata);
}
EDIT1:
I get no error/warning when I make all.
The linker is suppose to build everything for external memory with starts at 0x20 000000.
It seems your linker skript tries to compress the image for storage in flash.
During runtime your image is copied to other addresses maybe because of MMU alignment restrictions.
Does the linker emit an error message or is this just that your code does not behave correctly at runtime?
The copy problem you mentioned can be easily bypassed if you copy the sections "backwards".
Copy the last item of the .data section to its runtime address, then copy the next-to-last item to its runtime address...

Resources