一、开发环境
单板:mini2440,设置nanflasf启动
宿主机:centos 2.6.32
二、源代码
1、led汇编代码
@******************************************************************************
@ File:led_on.S
@ 功能:LED点灯程序,点亮LED1
@******************************************************************************
.text
.global _start
_start:
LDR R0,=0x56000010 @ R0设为GPBCON寄存器。此寄存器
@ 用于选择端口B各引脚的功能:
@ 是输出、是输入、还是其他
MOV R1,#0x00000400
STR R1,[R0] @ 设置GPB5为输出口, 位[10:9]=0b01
LDR R0,=0x56000014 @ R0设为GPBDAT寄存器。此寄存器
@ 用于读/写端口B各引脚的数据
MOV R1,#0x00000000 @ 此值改为0x00000020,
@ 可让LED1熄灭
STR R1,[R0] @ GPB5输出0,LED1点亮
MAIN:
B MAIN
2、链接脚本
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000004; //这个可以换不同的地址试试
. = ALIGN(4);
.text :
{
led_on.o (.text)
*(.text)
}
. = ALIGN(4);
.rodata : { *(.rodata) }
. = ALIGN(4);
.data : { *(.data) }
}
3、makefie
len_on.bin : len_on.S
arm-linux-gcc -g -c -o len_on.o len_on.S
arm-linux-ld -g -Tled.lds len_on.o -o len_on_elf
arm-linux-objcopy -O binary -S len_on_elf len_on.bin
clean:
rm -f len_on.bin len_on_elf *.o
三、分析
这里主要分析两项内容,(1)elf格式文件、bin格式文件 (2)链接脚本,
(1)elf,bin格式文件
elf格式中包含运行地址,加载地址,段地址信息,调试信息等,而bin文件中只包含单纯的指令码,请看len_on_elf,len_on.bin的反汇编代码:
arm-linux-objdump -D -m arm led_on_elf
led_on_elf: file format elf32-littlearm
Disassembly of section .text:
00000004 <_start>:
4: e59f0014 ldr r0, [pc, #20] ; 20 <MAIN+0x4>
8: e3a01b01 mov r1, #1024 ; 0x400
c: e5801000 str r1, [r0]
10: e59f000c ldr r0, [pc, #12] ; 24 <MAIN+0x8>
14: e3a01000 mov r1, #0 ; 0x0
18: e5801000 str r1, [r0]
0000001c <MAIN>:
1c: eafffffe b 1c <MAIN>
20: 56000010 .word 0x56000010
24: 56000014 .word 0x56000014
Disassembly of section .ARM.attributes:
00000000 <.ARM.attributes>:
0: 00001741 andeq r1, r0, r1, asr #14
4: 61656100 cmnvs r5, r0, lsl #2
8: 01006962 tsteq r0, r2, ror #18
c: 0000000d andeq r0, r0, sp
10: 00543405 subseq r3, r4, r5, lsl #8
14: 01080206 tsteq r8, r6, lsl #4
Disassembly of section .debug_line:
00000000 <.debug_line>:
0: 0000003a andeq r0, r0, sl, lsr r0
4: 001f0002 andseq r0, pc, r2
8: 01020000 tsteq r2, r0
c: 000d0efb strdeq r0, [sp], -fp
10: 01010101 tsteq r1, r1, lsl #2
14: 01000000 tsteq r0, r0
18: 00010000 andeq r0, r1, r0
1c: 5f64656c svcpl 0x0064656c
20: 532e6e6f teqpl lr, #1776 ; 0x6f0
24: 00000000 andeq r0, r0, r0
28: 02050000 andeq r0, r5, #0 ; 0x0
2c: 00000004 andeq r0, r0, r4
30: 31010903 tstcc r1, r3, lsl #18
34: 30302f2f eorscc r2, r0, pc, lsr #30
38: 00060230 andeq r0, r6, r0, lsr r2
3c: Address 0x0000003c is out of bounds.
Disassembly of section .debug_info:
00000000 <.debug_info>:
0: 00000063 andeq r0, r0, r3, rrx
4: 00000002 andeq r0, r0, r2
8: 01040000 tsteq r4, r0
c: 00000000 andeq r0, r0, r0
10: 00000004 andeq r0, r0, r4
14: 00000028 andeq r0, r0, r8, lsr #32
18: 5f64656c svcpl 0x0064656c
1c: 532e6e6f teqpl lr, #1776 ; 0x6f0
20: 6e6d2f00 cdpvs 15, 6, cr2, cr13, cr0, {0}
24: 67682f74 undefined
28: 532f7366 teqpl pc, #-1744830463 ; 0x98000001
2c: 65726168 ldrbvs r6, [r2, #-360]!
30: 68746957 ldmdavs r4!, {r0, r1, r2, r4, r6, r8, fp, sp, lr}^
34: 756e694c strbvc r6, [lr, #-2380]!
38: 61732f78 cmnvs r3, r8, ror pc
3c: 656c706d strbvs r7, [ip, #-109]!
40: 65775f73 ldrbvs r5, [r7, #-3955]!
44: 61682f69 cmnvs r8, r9, ror #30
48: 61776472 cmnvs r7, r2, ror r4
4c: 6c2f6572 cfstr32vs mvfx6, [pc], #-456
50: 6f5f6465 svcvs 0x005f6465
54: 4e47006e cdpmi 0, 4, cr0, cr7, cr14, {3}
58: 53412055 movtpl r2, #4181 ; 0x1055
5c: 312e3220 teqcc lr, r0, lsr #4
60: 30352e38 eorscc r2, r5, r8, lsr lr
64: Address 0x00000064 is out of bounds.
Disassembly of section .debug_abbrev:
00000000 <.debug_abbrev>:
0: 10001101 andne r1, r0, r1, lsl #2
4: 12011106 andne r1, r1, #-2147483647 ; 0x80000001
8: 1b080301 blne 200c14 <MAIN+0x200bf8>
c: 13082508 movwne r2, #34056 ; 0x8508
10: 00000005 andeq r0, r0, r5
Disassembly of section .debug_aranges:
00000000 <.debug_aranges>:
0: 0000001c andeq r0, r0, ip, lsl r0
4: 00000002 andeq r0, r0, r2
8: 00040000 andeq r0, r4, r0
c: 00000000 andeq r0, r0, r0
10: 00000004 andeq r0, r0, r4
14: 00000024 andeq r0, r0, r4, lsr #32
arm-linux-objdump -D -b binary -m arm led_on.bin
led_on.bin: file format binary
Disassembly of section .data:
00000000 <.data>:
0: e59f0014 ldr r0, [pc, #20] ; 0x1c
4: e3a01b01 mov r1, #1024 ; 0x400
8: e5801000 str r1, [r0]
c: e59f000c ldr r0, [pc, #12] ; 0x20
10: e3a01000 mov r1, #0 ; 0x0
14: e5801000 str r1, [r0]
18: eafffffe b 0x18
1c: 56000010 undefined
20: 56000014 undefined
可以看到elf格式的二进制文件有我们的链接地址信息,而纯二进制的bin文件是没有的。正因为这样,elf格式的可执行文件在裸机上没法执行,因为还没os,无法提取其中的elf格式信息,而bin格式在os上无法执行(我试验的一个代码是这样,如有错误,请指正),对于无os的裸板,就只能先运行bin格式的可执行文件了,从第一条指令一步一步往下。
(2)链接脚本
这个比较复杂,现在写比较简单的程序,就把现成的内容复制过来,主要是那个链接地址".=0x00000004",这个也可以在makefile的ld命令中使用“-Ttext 0x00000004”指定,大家可能很奇快,为什么我使用0x00000004这个地址呢,我开始使用的是0x00000000,使用这个两个地址,都是可以运行的,why?
mini2440从nanflash启动时,nanflash的前4K代码,会被映射到上s3c2440的片内sram,再从0地址开始执行。
既然这样,指定链接地址为0x00000004能执行吗,可以! 要知道,对于裸板,我们烧入的是bin格式的文件,里面是不包含加载地址之类的信息,所以,对于单存的bin格式,只在sram中运行,指定链接地址是无效的(这句话不敢肯定,待我做完后续初始化sdram后,在考虑)。代码有nanflash控制器,从片内sram0地址开始拷贝,然后运行。
三、参考文献及说明
1、http://blog.csdn.net/ouyang_linux007/article/details/7448505
2、http://wenku.baidu.com/link?url=aGUTIwFJe_UoATNurR6LOuOPFh-GeXZTtJJcLNOesjuuUqPKfT0VwkLjcveNj0XfFZ20QWc8AVF1PpGLYW9lQSIglxXIYKD5TAITswhNaK_
说明:
(1)文中内容只是本人总结,由于个人才疏学浅,本人不对文中的任何内容负责!当您发现文章内容有误时,欢迎与我联系。
(2)文中部分内容来自互联网,如果该文侵犯到您的权益,请及时联系我,我将立即删除相关内容。