基于mini2440的裸机led程序及其链接脚本分析

一、开发环境

 单板: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)文中部分内容来自互联网,如果该文侵犯到您的权益,请及时联系我,我将立即删除相关内容。













评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值