历史上的今天

今天是:2024年09月10日(星期二)

正在发生

2021年09月10日 | S3c2440代码重定位详解6---重定位清除BSS段的C函数实现

发布者:脑电狂潮 来源: eefocus关键字:S3c2440  代码重定位  C函数 手机看文章 扫描二维码
随时随地手机看文章

在前面,我们使用汇编程序来实现了重定位和清bss段,本节我们将使用C语言,实现重定位和清除bss段。


1.打开start.S把原来的汇编代码删除改为调用C函数


    /* 重定位text, rodata, data段整个程序 */

    mov r1, #0

    ldr r2, =_start         /* 第1条指令运行时的地址 */

    ldr r3, =__bss_start    /* bss段的起始地址 */


cpy:

    ldr r4, [r1]

    str r4, [r2]

    add r1, r1, #4

    add r2, r2, #4

    cmp r2, r3

    ble cpy


    /* 清除BSS段 */

    ldr r1, =__bss_start

    ldr r2, =_end

    mov r3, #0

clean:

    str r3, [r1]

    add r1, r1, #4

    cmp r1, r2

    ble clean


改为:


    /* 重定位text, rodata, data段整个程序 */

    mov r0, #0

    ldr r1, =_start         /* 第1条指令运行时的地址 */

    ldr r2, =__bss_start    /* bss段的起始地址 */

    sub r2, r2, r1          /*长度*/



    bl copy2sdram  /* src, dest, len */


    /* 清除BSS段 */

    ldr r0, =__bss_start

    ldr r1, =_end


    bl clean_bss  /* start, end */


1、在init.c 实现如上两个C函数


void copy2sdram(volatile unsigned int *src, volatile unsigned int *dest, unsigned int len)  /* src, dest, len */

{

    unsigned int i = 0;


    while (i < len)

    {

        *dest++ = *src++;

        i += 4;

    }

}



void clean_bss(volatile unsigned int *start, volatile unsigned int *end)  /* start, end */

{

    while (start <= end)

    {

        *start++ = 0;

    }

}


汇编中,为C语言传入的参数,依次就是R1、R2、R3。

编译,烧写运行没有问题。


我们假设不想汇编传入参数,而是C语言直接取参数。

1、修改start.S 跳转到C函数不需要任何参数


    bl sdram_init

    //bl sdram_init2     /* 用到有初始值的数组, 不是位置无关码 */


    /* 重定位text, rodata, data段整个程序 */

    bl copy2sdram


    /* 清除BSS段 */

    bl clean_bss


2、修改链接脚本,让__code_start 等于当前地址,也就是这里的0x30000000


SECTIONS

{

    . = 0x30000000;


    __code_start = .; //定义__code_start地址位当前地址


    . = ALIGN(4);

    .text      :

    {

      *(.text)

    }


    . = ALIGN(4);

    .rodata : { *(.rodata) }


    . = ALIGN(4);

    .data : { *(.data) }


    . = ALIGN(4);

    __bss_start = .;

    .bss : { *(.bss) *(.COMMON) }

    _end = .;

}


3、修改init.c 用函数来获取参数


void copy2sdram(void)

{

    /* 要从lds文件中获得 __code_start, __bss_start

     * 然后从0地址把数据复制到__code_start

     */


    extern int __code_start, __bss_start;//声明外部变量


    volatile unsigned int *dest = (volatile unsigned int *)&__code_start;

    volatile unsigned int *end = (volatile unsigned int *)&__bss_start;

    volatile unsigned int *src = (volatile unsigned int *)0;


    while (dest < end)

    {

        *dest++ = *src++;

    }

}



void clean_bss(void)

{

    /* 要从lds文件中获得 __bss_start, _end

     */

    extern int _end, __bss_start;


    volatile unsigned int *start = (volatile unsigned int *)&__bss_start;

    volatile unsigned int *end = (volatile unsigned int *)&_end;



    while (start <= end)

    {

        *start++ = 0;

    }

}


编译烧写运行 ,没有问题。


总结:

C函数怎么使用lds文件总的变量abc?

1、在C函数中声明改变量为extern外部变量类型,比如extern int abc;

2、使用时,要取址,比如:int *p = &abc;//p的只即为lds文件中abc的值

汇编文件中可以直接使用外部链接脚本中的变量,但C函数中要加上取址符号。


解释一下原因:

C函数中,定义一个全局变量int g_i;程序中必然有4字节的空间留出来给这个变量g_i

假如我们的lds文件中有很多变量


lds{

    a1 = ;

    a2 = ;

    a3 = ;

    ...

}


如果我们C程序只用到几个变量,完全没必要全部存储lds里面的所有变量,C程序是不保存lds中的变量的。


对于万一要用到的变量,编译程序时,有一个symbol table符号表:

在这里插入图片描述

如何使用symbol table符号表?

1、对于常规变量g_i,得到里面的值,使用&g_i得到addr;

2、为了保持代码的一致,对于lds中的a1,使用&a1得到里面的值;


结论:

1、C程序中不保存lds文件中的变量,lds再大也不影响;

2、借助symbol table保存lds的变量,使用时加上”&”得到它的值,链接脚本的变量要在C程序中声明为外部变量,任何类型都可以;

关键字:S3c2440  代码重定位  C函数 引用地址:S3c2440代码重定位详解6---重定位清除BSS段的C函数实现

上一篇:S3c2440代码重定位详解5---代码重定位与位置无关码
下一篇:S3c2440ARM异常与中断体系详解1---概念引入与处理流程

推荐阅读

就在本周,继苹果之后,其市值也一度突破万亿美元大关,美国四大科技巨头在资本市场表现强劲备受全球关注,成为本周科技最大热点事件,与此同时,美国未来5年投入20亿美元发展人工智能技术引发热议,不过,在国内,以传统企业碧桂园将利用800亿打造机器人产业生态备受瞩目。 在科技巨头在积极推动下,和人工智能广泛落地各行业,那么,本周一下大事件...
随着技术水平的不断提升以及在社会生活各个领域中的应用,人工智能已经不再被视为一种“魔法”,而成为赋能社会各行各业的生产力。百度创始人李彦宏坦言,现阶段“人工智能不再讲究酷炫,而是要讲究如何扎扎实实地推进和落地。” 如果说AI是蒸汽机与内燃机,那么AI算力则是“煤炭与石油”——AI 应用建立在算力之上,若没有算力可“烧”,AI将是空中楼阁...
适用于通用传动系统的普通笼型异步电动机,也适用于在变频调速系统上使用。因此由变频器供电的笼型变频异步电动机,其结构设计参数(机座号和尺寸均可参照通用的笼型异步电动机,但要注意的是由于变频电机在各种不同的频率下运行,所以在设计制造笼型变频异步电动机时要注意这一因素对电机运行产生的各种不良影响,其中一个最主要的影响是变频电机运行时,...
据业内消息人士称,中国台湾地区的一线IC设计公司已通知客户,从2022年第一季度起将进一步提价。其他设计公司也在寻求未来3-6个月内提高芯片价格,或将于明年开始生效。据《电子时报》报道,随着台积电交期延长至4-5个月,设计厂商不得不计划再次涨价以反映继续上升的成本,但由于下游设备组装商和制造商越来越不愿意接受价格进一步上涨,设计公司能否成本...

史海拾趣

问答坊 | AI 解惑

CNGI进入应用测试阶段

2010年至2011年将有可能实现商用。 从2008年1月1日起,美国国防部将全面切换到IPv6网络,2008年6月,美国联邦政府也将全面切换到IPv6网络,这将对IPv6的商用产生巨大的影响。而以CERNET2为代表的我国基于IPv6的下一代互联网示范工程CNGI在网络测试 ...…

查看全部问答∨

基本电子元件资料

基本电子元件资料,很详细,适合初学者看…

查看全部问答∨

怎么仿真ISE生成的ROM

xilinx的ROM在modelsim中仿真出错,提示无法读取.mif文件!!!…

查看全部问答∨

周立功写给学单片机的年轻人

作为过来人思前想后,我感到完全有责任将发自心底的感受传递给年轻一代,“一个企业家心灵深处渴望优秀人才的卓越追求和深层次的叹息、痛苦和感受”。您们千万不要等到毕业求职时才觉得自己能力太差,世界上从来就没有后悔药。当然,如果您现在看了 ...…

查看全部问答∨

大学生应该学习哪些电子知识

有不少的在校的大学生写信给我,问在学校里应该学习什么电子知识.就业形势越来越严峻,不光是在中国,全球都一样,全球经济的发展速度放慢,至少会持续几年的时间.半导体产业目前进入低潮,很多公司裁员和亏损.但是技术还是在不断进步,摩尔定律还在起作用 ...…

查看全部问答∨

怎样提供面试成功率?

大家工作多年,阅人无数,阅公司无数。怎样提供面试成功率,相信大家都很有经验?大家分享一下经验,供后来者。…

查看全部问答∨

超乎想象]人动力车中的坦克

这辆Hyperbike堪称人动力车中的坦克,乘坐它出行,再跟儿童车相撞的时候,大概是再也不会输掉啦。当然,驱动它运转需要全身肌肉的参与,耗费的体力也是儿童车所无法比较的。它的这一优点——并非指它能撞赢儿童车——使得它获得了美国国家航空航天 ...…

查看全部问答∨

i.mx35 CAN发送数据不能进中断?

请问哪位调试过i.mx35芯片,在WINCE下编写测试应用时,发送完毕后一直没中断提示。请问 这个是什么原因?…

查看全部问答∨

VS2005里面调试的时候怎么看全局的静态变量(局部变量看起来很简单)?看内存?那全局的静态变量在内存里面的地址怎么计算?

VS2005里面调试的时候怎么看全局的静态变量(局部变量看起来很简单)?看内存?那全局的静态变量在内存里面的地址怎么计算?看EXE文件对应生成的MAP文件吗?…

查看全部问答∨

超高分求助:500分求wince 5下nor flash的分区问题

各位高手,现在有这样一个问题,急着解决,高分求助,在线等待 环境:wince 5,pb5      XScale PXA270, 32M SDRAM, 32M Nor Flash,现在生成的nk的大小为20MB左右,想用剩下的空间做文件存储用,如何操作?…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

更多每日新闻

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved