jz2440裸机开发与分析:S3c2440代码重定位详解4---拷贝代码和链接脚本的改进

本节进行拷贝代码的改进和链接脚本的改进。
前面重定位时,需要ldrb命令从的Nor Flash读取1字节数据,再用strb命令将1字节数据写到SDRAM里面

cpy:
    ldrb r4, [r1] /*首先从flash读出一个字节*/ 
    strb r4, [r2] /*让后把数据写到SDRAM*/
    add r1, r1, #1
    add r2, r2, #1
    cmp r2, r3
    bne cpy

JZ2440上的Nor Flash是16位,SDRAM是32位。
假设现在需要复制16byte数据,
采用ldrb命令每次只能加载1byte,因此CPU需要发出16次命令,内存控制器每次收到命令后,访问硬件Nor Flash,因此需要访问硬件16次;
同理,访问SDRAM时,CPU需要执行strb 16次,内存控制器每次收到命令后,访问硬件SDRAM,也要16次,这样总共访问硬件32次。

现在对其进行改进,使用ldr从Nor Flash中读,ldr命令每次加载4字节数据,因此CPU只需执行4次,但由于Nor Flash是16位的,内存控制器每次收到CPU命令后,需要拆分成两次访问,因此需要访问硬件8次;
使用str写SDRAM,CPU只需执行4次,内存控制器每次收到命令后,直接硬件访问32位的SDRAM,因此这里只需要4次,这样总共访问只需要12次。
在整个操作中,花费时间最长的就是硬件访问,改进后代码,减少了硬件访问的次数,极大的提高了效率。
在这里插入图片描述
根据上面原理修改代码,修改start.S

cpy:	
	ldr r4, [r3]
	str r4, [r0]
	add r0, r0, #4
	add r3, r3, #4
	cmp r0, r1
	ble cpy
	
	/*清除BSS段*/
	mov r0, #0
	ldr r1, =bss_start
	ldr r2, =bss_end
clear:
	str r0, [r1]
	add r1, r1, #4
	cmp r1, r2
	ble clear
	
	bl main

然后编译烧写,发现启动后没有输出字符。修改主程序,尝试以整数格式输出字符,发现输出的数从0开始,应该是
全局变量被破坏了
在这里插入图片描述
在这里插入图片描述
由上图可知:

str r0,[r1]    ===> 
把0存在0x30000002地址里面,
由于要4字节对齐,
所以把把0存在0x30000000地址里面.而0x30000000时数据g_char地址,所以破坏了全局变量

屏蔽掉start.S里面的清理命令,测试是否是清除bss段是清除了全局变量。

clean:
    //str r3, [r1] //注释掉此句话,str不仅把bss段清除,把全局变量这些也清除了
    add r1, r1, #4
    cmp r1, r2
    ble clean

    bl main

屏蔽后,正常输出,锁定了问题大致位置。查看反汇编文件,原来是没有向4取整。
修改链接脚本让bss段,使用ALIGN(4)向4取整。

SECTIONS {
	.text 0 : {*(.text)}
	.rodata : {*(.rodata)}
	.data 0x30000000 : AT(0x700)
	{
		data_load_addr = LOADADDR(.data);
		data_start = . ;
		*(.data)
		data_end = . ;
	}
	. = ALIGN(4); 
	bss_start = .;
	.bss :{*(.bss) *(.COMMON)}
	bss_end = .;
}

现在重新编译烧写,测试结果正常。
再次查看反汇编文件,发现现在bss段以4字节对齐,清理bss段也是正常的
在这里插入图片描述
同样的问题也会出在代码重定位这里,如何保证data段起始地址也是向4对齐呢?
也是使用ALIGN(4)向4取整

SECTIONS
{
    . = 0x30000000;

    . = ALIGN(4);
    .text      :
    {
      *(.text)
    }

    . = ALIGN(4);
    .rodata : { *(.rodata) }

    . = ALIGN(4);
    .data : { *(.data) }

    . = ALIGN(4);
    __bss_start = .;
    .bss : { *(.bss) *(.COMMON) }
    _end = .;
}

Uboot是裸机的集大成者,可以参考uboot链接脚本也是类似的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值