Embedded Systems GNU tool Reference Book (1) Reference Book (2) Useful Links http://www.sthoward.com/docs/ – Some GNU Documents www.gnu.org – All about GNU http://263.aka.org.cn/Lectures/ – Lecture on Linux & GNU Outline Overview Toolchain Source RT Programming Embedded System Memory Data out Data in Processor Control in Control out From Source to Machine Code *.c *.cpp Assembler Compiler 1010101001 1010101001 1010101001 10101001 10101001 10101001 Lib 101001 1010101 *.s 1010101001 1010101001 10101001 10101001 Linker Executable Binary Simple Example Source Files hello.c C source, contain function main() disp_dat.c C source, functions in it is called by main() of hello.c startup.s Start up code for embedded board hello.lds Link description file Makefile Commands to build them all forward Code of hello.c int main() { char a = ‘a’; char b = ‘b’; disp_dat(a); disp_dat(b); while (1); // loop forever return (0); // never comes here } Code of disp_dat.c void disp_dat(U8 data) { // Wait until send buffer empty while (!((*((volatile U32 *)(0x207098))) & 1)); // send on character into send buffer (*((volatile U32 *)(0x207040))) = (U16)data; } Makefile hello: hello.o disp_dat.o startup.o arm-linux-ld –o hello –T hello.lds \ hello.o \ disp_dat.o\ startuop.o hello.o: hello.c arm-linux-gcc –c hello.c disp_dat.o: disp_dat.c arm-linux-gcc –c disp_dat.c stratup.o: startup.s arm-linux-gcc –c startup.s will explain later Use command “make” to automatically execute the steps listed in Makefile forward Download Code To ROM Outline Overview Toolchain Source File RT Programming CDK Cross Development Kits Toolchain – C/C++ Compiler – Assembler – Linker – Runtime Lib Components of Toolchain Cross-Compiler gcc libc Linux Kernel Headers Binutil Cross-Assembler as Cross-Linker ld Cross-Archiver ar … ranlib ranlib Build Toolchain Build Binary tools Build GCC for the 1st time (without Glibc) Build Glibc (Need kernel head file) Build GCC for the 2nd time (With Glibc) Build uGlibc for embedded development Build GDB C/C++ Compiler C/C++ source Code 10011100 10001011 11101110 11111110 *.c, *.cpp, *.cxx *.o, *.obj *.h. *.hpp, *.hxx Example: • object file is not intended to be executed directly • The structure of the file is usually COFF or ELF arm-linux-gcc –c hello.c hello.c hello.o Assembler ASM code *.a, *.s, *.asm Example: 10011100 10001011 11101110 11111110 *.o, *.obj arm-linux-gcc –c startup.s startup.s startup.o (note that gcc will automatically call assembler according to the postfix of *.s) What’s in object File? Data: 1001001 1011100 1111100 Text: 1111001 1011111 1111101 BSS: 1100001 1111111 1111101 Binary Data Blocks in it Object File Example … … Sections: Idx Name 0 .text 1 .data 2 .bss 3 .stab 4 .stabstr 5 .comment objdump –x file.o Size 00000160 CONTENTS, 00000004 CONTENTS, 00000000 ALLOC 000003fc CONTENTS, 00000557 CONTENTS, 00000026 CONTENTS, VMA LMA 00000000 00000000 ALLOC, LOAD, RELOC, 00000000 00000000 ALLOC, LOAD, DATA 00000000 00000000 File off 00000034 READONLY, 00000194 Algn 2**2 CODE 2**2 00000198 2**0 00000000 00000000 00000198 RELOC, READONLY, DEBUGGING 00000000 00000000 00000594 READONLY, DEBUGGING 00000000 00000000 00000aeb READONLY 2**2 SYMBOL TABLE: 00000000 l df *ABS* 00000000 Helloworld.c … … 2**0 2**0 Function of linker (LD) Linker Data: BSS: 1001001 1100001 1011100 1111111 Data: BSS: 1111100 1001001 1111101 1100001 1011100 1111111 BSS: Text: Data: 1111100 1111101 1100001 11110011001001 1011100 1111111 1011111 Text: 1111100 1111101 1111101 1111001 1011111 Text: 1111101 1111001 1011111 1111101 Object files, *.o *.lds Link description file Data: 1001001 1011100 1111100 1110111 1011000 0001000 BSS: 1100001 1111111 1111101 1100000 Text: 1111001 1011111 1111101 1101101 1111011 1110111 Executable files *.exe, *.elf Function of linker (contd.) Combine Data Blocks Fill Symbol Address The work is under control of file *.lds Outline Overview Toolchain Source RT File Programming With/Without OS Without OS With OS Startup.s Main.c Main.c lds Makefile Makefile Tasks of Startup Code Disable all INT 2. Init Memory & Hardware 3. Copy Data from ROM RAM 4. Initialize Data Area 5. Initialize StacK 6. Enable interrupts. 7. Call main( ). 1. backward Name of Startup code startup.asm startup.s startup.a51 start.asm start.s start.a51 crt0.s – C Runtime @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ exception vectors @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ .globl Helloworld_start Helloworld_start: b reset b UNDEF_Handler b SWI_Handler b PABT_Handler b DABT_Handler b NULL_Handler b IRQ_Handler b FIQ_Handler Example startup.s (1) Interrupt vectors @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Define stack position @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ .extern Helloworld_end Example startup.s (2) .equ UND_STACK_START, __STACK_START + 0x400 @ 1kB .equ SVC_STACK_START, __STACK_START + 0x800 @ 1kB .equ ABT_STACK_START, __STACK_START + 0xc00 @ 1kB .equ IRQ_STACK_START, __STACK_START + 0x1000 @ 1kB .equ FIQ_STACK_START, __STACK_START + 0x1400 @ 1kB .equ SYS_STACK_START, __STACK_START + 0xFFF0 @ UND_SP: .long UND_STACK_START SVC_SP: .long SVC_STACK_START ABT_SP: .long ABT_STACK_START IRQ_SP: .long IRQ_STACK_START FIQ_SP: .long FIQ_STACK_START SYS_SP: .long SYS_STACK_START Define points to the beginning of the stack Example @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@ startup.s (3) @ Reset handler @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@ reset: @ Init SDRAM LDR r1, =0x221000 STR … r3, [r1] LDR r3, =0x8212C267; STR r3, [r1] Reset interrupt routine (init SDRAM) Example startup.s (4) @ setup IRQ stack mrs r0, cpsr bic r0, r0, #0x1f orr r0, r0, #0x12 msr cpsr, r0 ldr r13, =IRQ_SP ldr sp, [r13] … @ setup SVC stack @ set CPSR to IRQ mode @ setup sp_irq Reset interrupt routine (init stacks) mrs bic orr msr r0, r0, r0, cpsr, cpsr r0, r0, r0 ldr ldr r13, sp, =SVC_SP [r13] bl init_sect b main #0xff #0x13 @ set CPSR to SVC mode @ setup sp_svc (call function to init data area) @ C main code (Jump to main) Compile All With Command Line gcc -g –Wall –T hello.lds –o hello\ hello.c \ disp_dat.c \ startup.s The same function of Makefile (so why we use Makefile?) backward forward Format of Several Widely Used Output File ELF – Include Symbol table and relocation information Binary Image – Only include machine code Intel Hex File – ASCII file, for programmer to download code Motorola S Record File – Another ASCII file format for programmer Generating Output Files Gcc generate ELF file by default Objcopy – Motorola Srecord File objcopy –O srec hello.elf hello.srec – Intel HEX file objcopy –O ihex hello.elf hello.hex – Binary File objcopy –O binary hello.elf hello.bin Objdump – Display disassemble data objdump –S hello.elf – Display section and symbol table location objdump –x hello.elf` LDS File Linker Data: BSS: 1001001 1100001 1011100 1111111 Data: BSS: 1111100 1001001 1111101 1100001 1011100 1111111 BSS: Text: Data: 1111100 1111101 1100001 11110011001001 1011100 1111111 1011111 Text: 1111100 1111101 1111101 1111001 1011111 Text: vect: 1111101 1111001 1111001 1011111 1011111 1111101 1111101 Object files *.lds Ld script Data: 1001001 1011100 1111100 1110111 1011000 0001000 BSS: 1100001 1111111 1111101 1100000 Text: 1111001 1011111 1111101 1101101 1111011 1110111 Executable files LDS File (code example) ENTRY(_start) /* list of MEMORY { vect rom ram sram } ROM our memory sections */ : : : : o o o o = = = = 0, l 0x400, l 0x400000, l 0xfffff000,l = = = = CPU SRAM 1k 127k 128k 4k RAM LDS File (MEMORY command ) MEMORY command – Target system's memory map – Used in the SECTIONS – Syntax MEMORY { name : o = origin, l = length name : o = origin, l = length ... } SECTIONS { LDS File (1) .vect : { __vect_start = .; *(.vect); __vect_end = .; } > vect .text : { __text_start = .; *(.text) *(.strings) __text_end = .; } > rom } .bss : { __bss_start = . ; *(.bss) *(COMMON) __bss_end = . ; } > ram LDS File (2) .Data: .BSS: 1001001 1100001 1011100 1111111 .Data: 1111101 .BSS: 1111100 1001001 1100001 .Text: 1011100 1111111 .Data: 1111101 .BSS: 1111001 1111100 1001001 1100001 1011111 Text: 1011100 1111111 1111101 1111001 1111100 1111101 1011111 .Text: 1111101 1111001 1011111 .vect: 1111101 1111001 Object files .Data: 1001001 1011100 1111100 1110111 1011000 1111100 1110111 1111100 1110111 0001000 1111111 .BSS: 1100001 1111111 1111101 1100000 .Text: 1111001 1011111 1111101 1101101 1011111 1111101 1101101 1011111 1111101 1101101 1011111 1111101 1101101 1111011 .vect: 1111001 Executable files LDS File (3) Data: 1001001 1011100 1111100 1110111 1011000 0001000 ROM BSS: 1100001 1111111 1111101 1100000 Text: 1111001 1011111 1111101 1101101 1111011 1110111 Executable files RAM Memory are spitted into sections Sections { … … /* initialized data */ .init : AT (__text_end) { __data_start = .; *(.data) __data_end = .; } > ram /* application stack */ .stack : { __stack_start = .; *(.stack) __stack_end = .; } > ram } LDS File (Section Command) LDS File (AT directive ) Data: 1001001 1011100 1111100 1110111 1011000 0001000 BSS: 1100001 1111111 1111101 1100000 Text: 1111001 1011111 1111101 1101101 1111011 1110111 Executable files ROM Initialization data is stored in the ROM RAM ROM Executable Code Constant Data Init Table For Global Data RAM Program Stack Global data & Static Data *.lds Initialization Data Section .init : AT (__text_end) { __data_start = .; *(.data) __data_end = .; } > ram *.c int global_dat=1234; void main() { disp_dat(global_dat) } If global_dat not initialized, will print out wrong result Function to Initialize Sections (1) // init sections, run it before main() void init_sect(void) { extern void *__TEXT_END; extern void *__DATA_START, *__DATA_END; extern void *__BSS_START, *__BSS_END; .init : AT (__text_end) { __data_start = .; *(.data) __data_end = .; } > ram char *src = (char*)(&__TEXT_END); char *dst = (char*)(&__DATA_START); // ROM has data at end of text; copy it. while (dst < (char*)(&__DATA_END)) *dst++ = *src++; // Zero bss for (dst = (char*)(&__BSS_START); dst < (char*)(&__BSS_END); dst++) *dst = 0; } … Function to Initialize Sections (2) Sections { … . = ALIGN(2); .text : { __TEXT_START = .; *(.text); __TEXT_END = .; } > ROM MEMORY { VECT : o = 0x00000000, l = 0x00001000 ROM : o = 0x00001000, l = 0x00010000 RAM : o = 0x08000000, l = 0x00010000 } } . = ALIGN(2); .init : AT(__TEXT_END) { __DATA_START = .; *(.data); __DATA_END = .; } > RAM . = ALIGN(2); .bss : { __BSS_START = .; *(.bss); __BSS_END = .; } > RAM … … End of Startup file (3) In the end of Start.s file @ setup SVC stack mrs r0, cpsr bic r0, r0, #0xff orr r0, r0, #0x13 msr cpsr, r0 ldr r13, =SVC_SP ldr sp, [r13] bl init_sect b main @ set CPSR to SVC mode @ setup sp_svc @ C main code Running Mode ROM Mode ROM Executable Code & Constant Data RAM Stack & Changing Data ROM Boot loader & Code Image RAM RAM Mode Require a copy function in bootloader to move ROM image into RAM Executable Code, Stack & Changing Data Running Mode (contd.) ROM Mode – – – – Simple Require smaller memory Fixed code address Relative Small Code RAM Mode – – – – Complex Re-locatable code Faster Large Code (SDRAM) RAM Mode Task of Bootloader • Init Basic System Bootloader Code Image (Maybe Compressed) • Init RAM System ROM • Copy (de-compress) ROM Image into RAM RAM • Init .DATA section • Jump To RAM to Run Code Library File (1) Why use Library Files? – Share code with others How to build a library? ar -r ./mylib.a disp_dat.o sum_dat.o This command add 2 *.o files into library *.a (create the library if not found) How to assign a Library for code building? gcc -o hello hello.o mylib.a What’s the standard library? – glibc – uclibc – newlib Library File (2) Library File 1011010101 1010101111 110101111 0000111111 000101111 1110101011 110101111 1111111111 Executable File A Executable File B 111010111 111001000 111000000 010100000 111000000 010100000 111010111 111001000 111000000 010100000 110101111 111010111 000101111 111001000 111000000 010100000 111010111 110101111 111001000 111000000 010100000 111000000 110101111 010100000 000101111 111010111 111001000 111000000 010100000 111010111 111001000 111000000 010100000 Using GCC (1) Function Of GCC – Compile and link Source File C++ Input File Name – *.c, *.C, *.cxx, *,cpp, *.hxx, *.hpp, *.h, *.s, *.S – Gcc find file type by ther suffix, and will automatically call related tool – Any file name with no recognized suffix is send to linker directly Gcc example (GCC options) gcc -o –g hello hello.o mylib.a gcc -c –g –O3 –Wall hello.c Makefile Why using make command? – Execute a script, save time – Explore file dependence, shorten the compile time – Provide extra code maintains script • • • • Clean built object file Install output file into desired directory Build a software in different compile option .. Example hello.h void disp(int c); hello.c #include “hello.h” int main() { disp(3); return 0; } disp_dat.c #include <stdio.h> void disp(int c) { printf(“%d\n”, c); } gcc –o hello hello.c disp_dat.c File Dependence hello.h hello.o hello gcc ld hello.c disp_dat.o gcc disp_dat.c hello: hello.o disp_dat.o ld –o hello hello.o disp_dat.o Makefile hello.o: hello.c hello.h gcc –c hello.c disp_dat.o: disp_dat.c gcc –c disp_dat.c make Details of make and Makefile (1) # Define macros for name of compiler CC = gcc # Define a macr o for the CC flags CCFLAGS = -D_DEBUG -g -m486 # A rule for building a object file test.o: test.c test.h $(CC) -c $(CCFLAGS) test.c gcc –c –D_DEBUG –g –m486 Details of make and Makefile (2) clean: rm -f *.o rm -f hello_mxl Detail of make & Makefile (3) CC AS LD OBJDUMP BIN = = = = = arm-elf-linux-gcc arm-elf-linux-gcc arm-elf-linux-ld arm-elf-linux-objdump arm-elf-linux-objcopy CPFLAGS = -Wall -pipe -g Detail of make & Makefile (4) CSRC ASRC OBJ = = = os_cpu.c ucos_ii.c mx1.c dataproc.c init_sect.c os_cpu_a.s start.s ucos_ii.o os_cpu_a.o os_cpu.o \ start.o mx1.o dataproc.o init_sect.o all: ucos_ii.elf .c.o: $(CC) -c $(CPFLAGS) -I$(INCDIR) $< $(AS) -c $(ASFLAGS) -I$(INCDIR) $< .s.o: ucos_ii.elf: $(OBJ) $(LD) $(LDFLAGS) $(OBJ) -o ucos_ii.elf $(OBJDUMP) -S ucos_ii.elf >> ucos_ii.dasm $(READELF) -a ucos_ii.elf >> ucos_ii.r $(NM) ucos_ii.elf >> ucos_ii.n clean: rm rm rm rm rm rm rm -f -f -f -f -f -f -f *.o *.map *.elf *.dasm *~ *.n *.r Other GNU Tools Tar – tar xvfz foo.tar.gz – tar cvfz foo.tgz /opt/code Objdump – objdump –S foo.elf – objdump –x foo.elf Gdb