嵌入式處理器架構與程式設計 王建民 中央研究院 資訊所 2008年 7月 Contents Introduction Computer Architecture ARM Architecture Development Tools GNU Development Tools ARM Instruction Set ARM Assembly Language ARM Assembly Programming GNU ARM ToolChain Interrupts and Monitor 2 Lecture 9 GNU ARM ToolChain GNU ARM ToolChain C Source Code ARM Assembly Code Compiler Assembler Object Code C Library Binary Utilities Linker Debuggers ARM Executable Simulator 4 Outline GNU ARM Compiler GNU ARM Assembler GNU ARM Linker GNU ARM Utilities GNU ARM Simulator GNU ARM Debuggers 5 arm-elf-gcc1 Usage: arm-elf-gcc [options] files Options: -pass-exit-codes : Exit with highest error code from a phase --help : Display help information --target-help : Display target specific command line options (Use '-v --help' to display command line options of sub-processes) -dumpspecs : Display all of the built in spec strings -dumpversion : Display the version of the compiler -dumpmachine : Display the compiler's target processor 6 arm-elf-gcc2 -print-search-dirs : Display the directories in the compiler's search path -print-libgcc-file-name : Display the name of the compiler's companion library -print-file-name=lib : Display the full path to library lib -print-prog-name=prog : Display the full path to compiler component prog -print-multi-directory : Display the root directory for versions of libgcc -print-multi-lib : Display the mapping between command line options and multiple library search directories 7 arm-elf-gcc3 -Wa,options : Pass comma-separated options on to the assembler -Wp,options : Pass comma-separated options on to the preprocessor -Wl,options : Pass comma-separated options on to the linker -Xassembler arg : Pass arg on to the assembler -Xpreprocessor arg : Pass arg on to the preprocessor -Xlinker arg : Pass arg on to the linker -combine : Pass multiple source files to compiler at once -save-temps : Do not delete intermediate files 8 arm-elf-gcc4 -pipe : Use pipes rather than intermediate files -time : Time the execution of each subprocess -specs=file : Override built-in specs with the contents of file -std=standard : Assume that the input sources are for standard -B directory : Add directory to the compiler's search paths -b machine : Run gcc for target machine, if installed -V version : Run gcc version number version, if installed -v : Display the programs invoked by the compiler 9 arm-elf-gcc5 -### : Like -v but options quoted and commands not executed -E : Preprocess only; do not compile, assemble or link -S : Compile only; do not assemble or link -c : Compile and assemble, but do not link -o file : Place the output into file -x language : Specify the language of the following input files Permissible languages include: c c++ assembler none Options starting with -g, -f, -m, -O, -W, or --param are automatically passed on to the various sub-processes invoked by arm-elf-gcc. In order to pass other options on to these processes the -Wletter options must be used. 10 Example: hello.c /* hello.c, a simple example program */ #include <stdio.h> #define GREETING “Hello, World!\n” int main() { printf(GREETING); return 0; } 11 arm-elf-gcc -S hello.c .file "hello.c" .section .rodata .align 2 .LC0: .ascii .text .align .global .type "Hello, World!\000" 2 main main, %function main: @ args = 0, pretend = 0, frame = 0 @ frame_needed = 1, uses_anonymous_args = 0 mov ip, sp stmfd sp!, {fp, ip, lr, pc} sub fp, ip, #4 ldr r0, .L3 bl puts mov r3, #0 mov r0, r3 ldmfd sp, {fp, sp, pc} .L4: .align 2 .word .size .ident .LC0 main, .-main "GCC: (GNU) 4.0.0" .L3: 12 Outline GNU ARM Compiler GNU ARM Assembler GNU ARM Linker GNU ARM Utilities GNU ARM Simulator GNU ARM Debuggers 13 arm-elf-as1 Usage: arm-elf-as [options] [asmfiles] Options: -a[sub-options] : Turn on listing output. Sub-options [default hls]: c : omit false conditionals d : omit debugging directives h : include high-level source l : include assembly m : include macro expansions n : omit forms processing s : include symbols =file : listing output to file (must be last sub-option) -D : Produce assembler debugging messages 14 arm-elf-as2 --defsym sym=val : Define symbol sym to given value --execstack : Require executable stack for this object --noexecstack : Don't require executable stack -f : Skip whitespace and comment preprocessing --gstabs : Generate stabs debugging information --gstabs+ : Generate stabs debug info with GNU extensions --gdwarf2 : Generate DWARF2 debugging information --help : Show help message and exit --target-help : Show target specific options -I dir : Add dir to search list for .include directives -K : Warn when differences altered for long displacements 15 arm-elf-as3 -L : Keep local symbols (e.g. starting with `L') --MD file : Write dependency information in file -o objfile : Name the output objfile (default a.out) -R : Fold data section into text section --statistics : Print various measured statistics from execution --strip-local-absolute : Strip local absolute symbols --version : Print assembler version number and exit -W, --no-warn : Suppress warnings --warn : Don't suppress warnings --fatal-warnings : Treat warnings as errors -Z : Generate object file even after errors 16 arm-elf-as -als hello.s1 ARM GAS 1 2 3 4 5 5 5 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 hello.s page 1 .file "hello.c" .section .rodata .align 2 .LC0: 0000 48656C6C 6F2C2057 6F726C64 2100 000e 0000 .ascii "Hello, World!\000" -al .text .align 2 .global main .type main, %function main: 0000 0004 0008 000c 0010 0014 0018 001c 0DC0A0E1 00D82DE9 04B04CE2 0C009FE5 FEFFFFEB 0030A0E3 0300A0E1 00A89DE8 @ args = 0, pretend = 0, frame = 0 @ frame_needed = 1, uses_anonymous_args = 0 mov ip, sp stmfd sp!, {fp, ip, lr, pc} sub fp, ip, #4 ldr r0, .L3 bl puts mov r3, #0 mov r0, r3 ldmfd sp, {fp, sp, pc} 17 arm-elf-as -als hello.s2 21 22 23 24 0020 00000000 25 26 ARM GAS .L4: .align 2 .word .size .ident .LC0 main, .-main "GCC: (GNU) 4.0.0" .L3: hello.s page 2 DEFINED SYMBOLS hello.s:10 hello.s:13 hello.s:24 *ABS*:00000000 .text:00000000 .text:00000000 .text:00000020 hello.c main $a $d -as UNDEFINED SYMBOLS puts 18 Outline GNU ARM Compiler GNU ARM Assembler GNU ARM Linker GNU ARM Utilities GNU ARM Simulator GNU ARM Debuggers 19 arm-elf-ld1 Usage: arm-elf-ld [options] files Options: -b target : Specify target for following input files Supported targets: elf32-littlearm elf32-bigarm elf32-little elf32-big srec symbolsrec tekhex binary ihex -d : Force common symbols to be defined -e address : Set the entry point address -E : Export all dynamic symbols -EB : Link big-endian objects -EL : Link little-endian objects 20 arm-elf-ld2 -h filename, -soname filename : Set internal name of shared library -I program, --dynamic-linker program : Set program as the dynamic linker to use -l libname : Search for library libname -L directory : Add directory to library search path -m emulation : Set emulation Supported emulations: armelf -M : Print map file on standard output -o file : Set output file name -O : Optimize output file -q : Generate relocations in final output 21 arm-elf-ld3 -r, -i, --relocatable : Generate relocatable output -R file : Just link symbols (if directory, same as --rpath) -s : Strip all symbols -S : Strip debugging symbols -t : Trace file opens -T file : Read linker script -u symbol : Force symbol to be entered in the output file as an undefined symbol. -v : Print version information -V : Print version and emulation information -x : Discard all local symbols 22 arm-elf-ld4 -X : Discard temporary local symbols (default) --discard-none : Don't discard any local symbols -y symbol : Trace mentions of symbol -Bdynamic : Link against shared libraries -Bstatic : Do not link against shared libraries -Bsymbolic : Bind global references locally --cref : Output cross reference table --help : Print option help -rpath path : Set runtime shared library search path -rpath-link path : Set link time shared library search path 23 arm-elf-ld5 -shared, -Bshareable : Create a shared library -pie, --pic-executable : Create a position independent executable --stats : Print memory usage statistics --target-help : Display target specific options --verbose : Output lots of information during link It is preferred to use arm-elf-gcc to link objects generated from C source codes. $ arm-elf-as -mno-fpu -o hello.o hello.s $ arm-elf-gcc -o hello.elf hello.o 24 Outline GNU ARM Compiler GNU ARM Assembler GNU ARM Linker GNU ARM Utilities GNU ARM Simulator GNU ARM Debuggers 25 arm-elf-objdump1 Display information from object file(s). Usage: arm-elf-objdump options files Options: At least one of the following switches must be given: -a : Display archive header information -f : Display the contents of the overall file header -p : Display object format specific file header contents -h : Display the contents of the section headers -x : Display the contents of all headers 26 arm-elf-objdump2 -d : Display assembler contents of executable sections -D : Display assembler contents of all sections -S : Intermix source code with disassembly -s : Display the full contents of all sections requested -g : Display debug information in object file -e : Display debug information using ctags style -G : Display (in raw form) any STABS info in the file -t : Display the contents of the symbol table(s) -T : Display the contents of the dynamic symbol table -r : Display the relocation entries in the file 27 arm-elf-objdump3 -R : Display the dynamic relocation entries in the file -v : Display this program's version number -i : List object formats and architectures supported -H : Display this information The following switches are optional: -EB : Assume big endian format when disassembling -EL : Assume little endian format when disassembling -I=DIR : Add DIR to search list for source files -l : Include line numbers and filenames in output -w : Format output for more than 80 columns 28 arm-elf-objdump -x hello.o hello.o: file format elf32-littlearm hello.o architecture: arm, flags 0x00000011: HAS_RELOC, HAS_SYMS start address 0x00000000 private flags = 200: [APCS-32] [FPA float format] [software FP] Sections: Idx Name 0 .text 1 .data 2 .bss 3 .rodata 4 .comment Size 00000024 CONTENTS, 00000000 CONTENTS, 00000000 ALLOC 00000010 CONTENTS, 00000012 CONTENTS, VMA LMA 00000000 00000000 ALLOC, LOAD, RELOC, 00000000 00000000 ALLOC, LOAD, DATA 00000000 00000000 File off 00000034 READONLY, 00000058 Algn 2**2 CODE 2**0 00000058 2**0 00000000 00000000 00000058 ALLOC, LOAD, READONLY, DATA 00000000 00000000 00000068 READONLY 2**2 -a -f -p -h 2**0 29 arm-elf-objdump -x hello.o SYMBOL TABLE: 00000000 l 00000000 l 00000000 l 00000000 l 00000000 l 00000000 l 00000020 l 00000000 l 00000000 g 00000000 df d d d d F O d F *ABS* 00000000 hello.c .text 00000000 .data 00000000 .bss 00000000 .rodata 00000000 .text 00000000 $a .text 00000000 $d .comment 00000000 .text 00000024 main *UND* 00000000 puts RELOCATION RECORDS FOR [.text]: OFFSET TYPE VALUE 00000010 R_ARM_PC24 puts 00000020 R_ARM_ABS32 .rodata -t -r 30 arm-elf-objdump -sd hello.o Contents of section .text: 0000 0dc0a0e1 00d82de9 04b04ce2 0010 feffffeb 0030a0e3 0300a0e1 0020 00000000 Contents of section .rodata: 0000 48656c6c 6f2c2057 6f726c64 Contents of section .comment: 0000 00474343 3a202847 4e552920 0010 3000 Disassembly of section .text: 00000000 <main>: 0: e1a0c00d 4: e92dd800 8: e24cb004 c: e59f000c 10: ebfffffe 14: e3a03000 18: e1a00003 1c: e89da800 20: 00000000 mov stmdb sub ldr bl mov mov ldmia andeq 0c009fe5 00a89de8 ......-...L..... .....0.......... .... 21000000 Hello, World!... 342e302e .GCC: (GNU) 4.0. 0. ip, sp sp!, {fp, ip, lr, pc} fp, ip, #4 ; 0x4 r0, [pc, #12] ; 20 <.text+0x20> 10 <main+0x10> r3, #0 ; 0x0 r0, r3 sp, {fp, sp, pc} r0, r0, r0 -s -d 31 arm-elf-readelf1 Display information about the contents of ELF format files Usage: arm-elf-readelf options elf-files Options: -a : Equivalent to: -h -l -S -s -r -d -V -A -I -h : Display the ELF file header -l : Display the program headers -S : Display the sections' header -e : Equivalent to: -h -l –S -s : Display the symbol table 32 arm-elf-readelf2 -n : Display the core notes (if present) -r : Display the relocations (if present) -u : Display the unwind info (if present) -d : Display the dynamic segment (if present) -V : Display the version sections (if present) -A : Display architecture specific information (if any). -D : Use the dynamic section info when displaying symbols 33 arm-elf-readelf3 -x=number : Dump the contents of section number -w[liaprmfFso] : Display the contents of DWARF2 debug sections, where [liaprmfFso] corresponds to [line, info, abbrev, pubnames, ranges, macro, frames, str, loc] -I : Display histogram of bucket list lengths -W : Allow output width to exceed 80 characters -H : Display this information -v : Display the version number of readelf 34 arm-elf-readelf -hl hello.elf ELF Header: Magic: 7f 45 4c 46 01 01 01 61 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: ARM ABI Version: 0 Type: EXEC (Executable file) Machine: ARM Version: 0x1 Entry point address: 0x8100 Start of program headers: 52 (bytes into file) Start of section headers: 168152 (bytes into file) Flags: 0x202, has entry point, GNU EABI, software FP Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 1 Size of section headers: 40 (bytes) Number of section headers: 25 Section header string table index: 22 -h Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x008000 0x00008000 0x00008000 0x03b88 0x03c94 RWE 0x8000 -l Section to Segment mapping: Segment Sections... 00 .init .text .fini .rodata .data .eh_frame .ctors .dtors .jcr .bss 35 arm-elf-readelf -S hello.elf Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0 0 0 [ 1] .init PROGBITS 00008000 008000 000020 00 AX 0 0 4 [ 2] .text PROGBITS 00008020 008020 0030e8 00 AX 0 0 4 [ 3] .fini PROGBITS 0000b108 00b108 00001c 00 AX 0 0 4 [ 4] .rodata PROGBITS 0000b124 00b124 000020 00 A 0 0 4 [ 5] .data PROGBITS 0000b244 00b244 00092c 00 WA 0 0 4 [ 6] .eh_frame PROGBITS 0000bb70 00bb70 000004 00 A 0 0 4 [ 7] .ctors PROGBITS 0000bb74 00bb74 000008 00 WA 0 0 4 [ 8] .dtors PROGBITS 0000bb7c 00bb7c 000008 00 WA 0 0 4 [ 9] .jcr PROGBITS 0000bb84 00bb84 000004 00 WA 0 0 4 [10] .bss NOBITS 0000bb88 00bb88 00010c 00 WA 0 0 4 [11] .comment PROGBITS 00000000 00bb88 000288 00 0 0 1 [12] .debug_aranges PROGBITS 00000000 00be10 000420 00 0 0 8 [13] .debug_pubnames PROGBITS 00000000 00c230 000726 00 0 0 1 [14] .debug_info PROGBITS 00000000 00c956 011f48 00 0 0 1 [15] .debug_abbrev PROGBITS 00000000 01e89e 0031f4 00 0 0 1 [16] .debug_line PROGBITS 00000000 021a92 002a14 00 0 0 1 [17] .debug_frame PROGBITS 00000000 0244a8 000a14 00 0 0 4 [18] .debug_str PROGBITS 00000000 024ebc 001406 01 MS 0 0 1 [19] .debug_loc PROGBITS 00000000 0262c2 002be0 00 0 0 1 [20] .stack PROGBITS 00080000 028ea2 000000 00 W 0 0 1 [21] .debug_ranges PROGBITS 00000000 028ea2 000150 00 0 0 1 [22] .shstrtab STRTAB 00000000 028ff2 0000e3 00 0 0 1 [23] .symtab SYMTAB 00000000 0294c0 001590 10 24 ef 4 [24] .strtab STRTAB 00000000 02aa50 0007f9 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings) I (info), L (link order), G (group), x (unknown) O (extra OS processing required) o (OS specific), p (processor specific) 36 Outline GNU ARM Compiler GNU ARM Assembler GNU ARM Linker GNU ARM Utilities GNU ARM Simulator GNU ARM Debuggers 37 arm-elf-run1 Usage: arm-elf-run [options] program [prog_args] Options: -a args : Pass 'args' to simulator. -m size : Set memory size of simulator, in bytes. -t : Perform instruction tracing. Note: Very few simulators support tracing. Not applicable in GNU ARM ToolChain! -v : Verbose output. prog_args : Arguments to pass to simulated program. Note: Very few simulators support this. This feature is supported by GNU ARM ToolChain! 38 arm-elf-run2 Target specific options: --swi-support=<list> : Comma separated list of SWI protocols to support. This list can contain: NONE, DEMON, ANGEL, REDBOOT and/or ALL. Example $ arm-elf-run --swi-support=ANGEL hello.elf Hello, World! 39 Outline GNU ARM Compiler GNU ARM Assembler GNU ARM Linker GNU ARM Utilities GNU ARM Simulator GNU ARM Debuggers 40 Debuggers Debuggers can do four main kinds of things to help you catch bugs in the act: Start your program, specifying anything that might affect its behavior. Make your program stop on specified conditions. Examine what has happened, when your program has stopped. Change things in your program, so you can experiment with correcting the effects of one bug and go on to learn about another. 41 arm-elf-gdb1 Usage: arm-elf-gdb [options] [executable-file [core-file or process-id]] arm-elf-gdb [options] --args executable-file [inferior-arguments] Options: --args : Arguments after executable-file are passed to inferior --[no]async : Enable (disable) asynchronous version of CLI -b baudrate : Set serial port baud rate used for remote debugging. --batch : Exit after processing options. --cd=dir : Change current directory to dir. 42 arm-elf-gdb2 --command=file : Execute GDB commands from file. --core=corefile : Analyze the core dump corefile. --pid=pid : Attach to running process PID. --directory= dir : Search for source files in dir. --exec=execfile : Use execfile as the executable. --help : Print help message. --interpreter=interp : Select a specific interpreter / user interface --mapped : Use mapped symbol files if supported on this system. --nw : Do not use a window interface. --nx : Do not read .gdbinit file. 43 arm-elf-gdb3 --quiet : Do not print version number on startup. --readnow : Fully read symbol files on first access. --se=file : Use file as symbol file and executable file. --symbols=symfile : Read symbols from symfile. --tty=tty : Use tty for input/output by the program being debugged. --tui : Use a terminal user interface. --version : Print version information and then exit. -w : Use a window interface. --write : Set writing into executable and core files. 44 Getting In and Out of GDB Type “gdb” to start GDB. Type “quit” or Ctrl-D to exit. The most usual way to start GDB is with one argument, specifying an executable program: gdb program You can also start with both an program and a core file: gdb program core You can specify a process ID as a second argument, if you want to debug a running process: gdb program 1234 45 GDB Example $ cat sum.c /* sum.c, a sample program for GDB demo */ #include <stdio.h> main () { int i, sum; sum = 0; for (i=1; i<=5; i++) sum += i; printf("1+2+3+4+5=%i\n", sum); } $ arm-elf-gcc -g -o sum.elf sum.c $ arm-elf-gdb sum.elf GNU gdb 6.1 Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "--host=i686-pc-cygwin --target=arm-elf"... 46 Using GDB1 (gdb) target sim Connected to the simulator. (gdb) load Loading section .init, size 0x20 vma 0x8000 Loading section .text, size 0x8568 vma 0x8020 Loading section .fini, size 0x1c vma 0x10588 Loading section .rodata, size 0x22c vma 0x105a4 Loading section .data, size 0x940 vma 0x108d0 Loading section .eh_frame, size 0x4 vma 0x11210 Loading section .ctors, size 0x8 vma 0x11214 Loading section .dtors, size 0x8 vma 0x1121c Loading section .jcr, size 0x4 vma 0x11224 Start address 0x8100 Transfer rate: 297280 bits in <1 sec. 47 Using GDB2 (gdb) set listsize 15 (gdb) list main 1 /* sum.c, a sample program for GDB demo */ 2 3 #include <stdio.h> 4 5 main () 6 { 7 int i, sum; 8 9 sum = 0; 10 for (i=1; i<=5; i++) 11 sum += i; 12 13 printf("1+2+3+4+5=%i\n", sum); 14 } 15 48 Using GDB3 You need to set break points at specified line or function (gdb) break main Breakpoint 1 at 0x8218: file sum.c, line 9. (gdb) break sum.c:11 Breakpoint 2 at 0x822c: file sum.c, line 11. When you run it, it will stop at break point. (gdb) run Starting program: /home/user/armtest/L07/sum.elf Breakpoint 1, main () at sum.c:9 9 sum = 0; 49 Using GDB4 You can use “n” to run line by line, or “continue” to run program until end or next break point. (gdb) continue Continuing. Breakpoint 2, main () at sum.c:11 11 sum += i; (gdb) n 10 for (i=1; i<=5; i++) (gdb) n Breakpoint 2, main () at sum.c:11 11 sum += i; 50 Using GDB5 You can use “print” to display variable’s value (gdb) print $1 = 1 (gdb) print $2 = 2 (gdb) n 10 (gdb) print $3 = 3 (gdb) print $4 = 2 sum i for (i=1; i<=5; i++) sum i You can use “p” to change variable’s value (gdb) p i = 4 $5 = 4 (gdb) print i $6 = 4 51 Using GDB6 If you want to show variable’s value in every n (next) command, you can use “display”. (gdb) display sum 1: sum = 3 (gdb) display i 2: i = 4 (gdb) n Breakpoint 2, main () at sum.c:11 11 sum += i; 2: i = 5 1: sum = 3 52 Using GDB7 Use “info” to show some information (ex: break points, display). (gdb) info break Num Type Disp Enb Address What 1 breakpoint keep y 0x00008218 in main at sum.c:9 breakpoint already hit 1 time 2 breakpoint keep y 0x0000822c in main at sum.c:11 breakpoint already hit 3 times (gdb) info display Auto-display expressions now in effect: Num Enb Expression 2: y i 1: y sum 53 Using GDB8 Use “disable” to disable your setting, and “enable” to enable it. (gdb) disable display 1 (gdb) n 10 for (i=1; i<=5; i++) 2: i = 5 (gdb) enable display 1 (gdb) n 13 printf("1+2+3+4+5=%i\n", sum); 2: i = 6 1: sum = 8 54