ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

linux下s3c2440重定位(4)连接脚本的学习_拷贝代码和链接脚本的改进

2019-06-03 21:56:25  阅读:327  来源: 互联网

标签:脚本 r1 r2 ALIGN bss start linux s3c2440 data


转载地址 https://blog.csdn.net/thisway_diy/article/details/79397

本节内容重点是感觉start.s文件中的拷贝特性以及清除bss段出现的bug修复

前面重定位时,需要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, [r1]
    str r4, [r2]
    add r1, r1, #4 //r1加4
    add r2, r2, #4 //r2加4
    cmp r2, r3 //如果r2 =< r3继续拷贝
    ble cpy

/* 清除BSS段 */ 
    ldr r1, =bss_start
    ldr r2, =bss_end
    mov r3, #0
clean:
    str r3, [r1]
    add r1, r1, #4
    cmp r1, r2 //如果r1 =< r2则继续拷贝
    ble clean

    bl main

然后编译烧写,发现启动后没有输出字符。修改主程序,尝试以整数格式输出字符,发现输出的数从0开始,应该是 
全局变量被破坏了。

屏蔽掉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);
      . = ALIGN(4);
      data_start = . ;
      *(.data) 
      data_end = . ;
   }

   . = ALIGN(4);//让当前地址向4对齐
   bss_start = .;
   .bss  : { *(.bss) *(.COMMON) }
   bss_end = .;
}

现在重新编译烧写,测试结果正常。 
再次查看反汇编文件,发现现在bss段以4字节对齐,清理bss段也是正常的。

Disassembly of section .bss:

30000004 <g_A>:
30000004:   00000000    andeq   r0, r0, r0

30000008 <g_B>:
30000008:   00000000    andeq   r0, r0, r0
Disassembly of section .comment:

同样的问题也会出在代码重定位这里,如何保证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链接脚本也是类似的。

标签:脚本,r1,r2,ALIGN,bss,start,linux,s3c2440,data
来源: https://blog.csdn.net/dfl448866/article/details/90759290

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有