s3c2440裸机-代码重定位-3-清bss原理及实现

发布者:SereneHarmony最新更新时间:2024-07-05 来源: elecfans关键字:代码重定位 手机看文章 扫描二维码
随时随地手机看文章

1.清bss的引入(为什么要清bss)

我们先举个例子:


#include 's3c2440_soc.h'

#include 'uart.h'


char g_Char = 'A'; //.data

char g_Char3 = 'a';

const char g_Char2 = 'B'; //.rodata

int g_A = 0; //bss

int g_B; //bss


int main(void)

{

    uart0_init();


    puts('nrg_A = ');

    printHex(g_A);

    puts('nr');


    while (1)

    {

        putchar(g_Char);

        g_Char++;         /* nor启动时, 此代码无效 ,重定位到sdram的baseaddr后有效*/


        putchar(g_Char3);

        g_Char3++;

        delay(1000000);

    }

    return 0;

}

我们把程序烧进去,然后打印g_A,但是发现g_A这个值并不是0,而是一个随机值。为什么呢?


这个时候我们做完了重定位,把代码copy到了sdram上,然后sdram上紧接着的地址就是.bss的基地址了,这时候bss段的这块内存没有经过任何处理,所以是随机的。


那么我们重定位完代码后需要进行清除sdram上.bss段的数据,因为我们知道bss是未初始化和初始值为0的全局变量。


2.怎么清bss

当然只需要往bss段写入全0就ok了,我们编写链接脚本如下:


SECTIONS

 {

     . = 0x30000000;


     . = ALIGN(4);

     .text      :

     {

       *(.text)

     }


     . = ALIGN(4);

     .rodata : { *(.rodata) }


     . = ALIGN(4);

     .data : { *(.data) }


     . = ALIGN(4);

     __bss_start = .;

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

     _end = .;

 }

再编写start.s,清除bss段的代码如下:


/* 清除BSS段 */

    ldr r1, =__bss_start

    ldr r2, =_end

    mov r3, #0

clean:

    strb r3, [r1]

    add r1, r1, #1

    cmp r1, r2

    ble clean


    bl main

halt:

    b halt

我们把程序再烧进去,然后打印g_A,但是发现g_A的值是0了。本质上就是对重定位后的bss段数据清0.


关键字:代码重定位 引用地址:s3c2440裸机-代码重定位-3-清bss原理及实现

上一篇:s3c2440裸机-代码重定位-4-清bss的优化和位置无关码
下一篇:s3c2440裸机-代码重定位-2-编程实现

推荐阅读最新更新时间:2026-03-24 18:46

ARM芯片学习(S5PV210开发)——代码定位
什么是代码重定位 代码重定位就是代码的复制或者说搬移,把在A地址存放的代码复制一份到B地址,至于A、B地址,程序员是事先知道的,可以通过芯片的数据手册查询得知。并且由于某些条件的限制,有时候不能直接将代码下载到B地址,只能先下载到A地址,然后运行代码,将代码复制到B地址接着运行。 为什么要代码重定位 重定位不是为了优化性能,而是由于硬件的限制,不得不进行重定位。试想一下,我们拿到一台设备,只要上电就可以运行代码,那代码必定要先保存在设备的存储介质中,并且是掉电不丢失的存储介质,具有掉电不丢失性质的存储介质有磁盘、flash等,但是这些都不能用作内存,内存都是RAM。这就矛盾了,内存是掉电丢失,必然不能用于存储代码,但是代码又必
[单片机]
S3c2440裸机-spi编程-2.OLED显示面板
1.OLED显示面板介绍 以QG-2864TMBEG01这款OLED为例,可见它支持Parallel/i2c/SPI这3种方式对它进行控制,这里仅对它进行SPI控制。它的product Specification见附件。 并行接口时序: SPI串行接口时序 Tr/Tf: 表示spi clk上升/下降延不能超过40ns Tclkl/Tclkh: 表示spi clk低/高电平持续至少20ns Tcycle: 表示spi clk一个时钟周期至少100ns Tdsw/Tdhw: 表示spi data的建立/持续时间至少15ms Tcss:片选建立时间至少20ns Tcsh:片选持续时间至少10ns Tas/Tah:地址建立/
[单片机]
<font color='red'>S3c2440</font><font color='red'>裸机</font>-spi编程-2.OLED显示面板
s3c2440裸机-内存控制器2-不同位宽外设与CPU地址总线的连接
不同位宽设备的连接 我们先看一下2440芯片手册上外设rom是如何与CPU地址总线连接的。 8bit rom与CPU地址线的连接 8bit*2 rom与CPU地址线的连接 8bit*4 rom与CPU地址线的连接 16bit rom与CPU地址线的连接 16bit*2 rom与CPU地址线的连接 从上面的图中,我们知道可以对2片位宽为8bit的外设扩展级联成1个16bit的外设,同理可用4片位宽为8bit的外设进行级联成1个32bit的外设... 从上面的图中,我们还看见一个规律: 当外设总线位宽为8bit时, 外设A0接CPU的地址总线ADDR , A - ADDR ...A - AD
[单片机]
s3c2440裸机-内存控制器3-SDRAM原理-cpu是如何访问sdram的
1.SDRAM原理 black (1)SDRAM内部存储结构: (2)再看看与2440连接的SDRAM原理图: sdram引脚说明: A0-A12:地址总线 D0-D15:数据总线(位宽16,2片级联成位宽32) BA0-BA1:bank选择 nSCS:片选 nSRAS:行地址选择 nSCAS:列地址选择 nWE:写使能 SCLK:时钟 SCKE:时钟使能 (3)SDRAM的地址范围: 之前我们讲“二、不同位宽外设与CPU地址总线的连接”这一节的时候,我们留下了一个问题,SDRAM的地址范围是多少? 我们知道地址范围肯定是base_addr + size。我们根据片选接了nGCS6,base_addr=0x30
[单片机]
s3c2440裸机-NorFlash1-原理
1.flash种类与特性: flash一般分为nand flash和nor flash,各自特性如下表: - Nor NAND XIP(片上执行) yes no 性能(擦除) 非常慢(5s,块太大) 快(3ms) 性能(写) 慢 快 性能(读) 快 快 可靠性 高 一般(容易出现位反转) 可擦除次数 10000 ~ 100000 100000 ~ 1000000 接口 与ram类似,可直接访问任意地址 I/O接口(无地址线,必须串行访问,命令、地址、数据共用8位IO) 易用性 容易 复杂 主要用途 常用于保存代码和关键数据 用于保存数据 价格 高 低 容量 小 大 常用文件系统类型 jffs yaffs
[单片机]
s3c2440裸机-Norflash2-适配访问时序
前面我们了解了norFlash的特性和原理,那么cpu是如何和nor进行通信的呢?下面开始详细介绍。 1.内存控制器适配norflash 如图是S3C2440的内存控制器的可编程访问周期读写时序,里面的时间参数要根据外部norflash的性能进行配置,这里先列出时间参数的含义: Tacs: Address set-up time before nGCSn(表示地址信号A发出多久后才能发出nGCS片选) Tcos: Chip selection set-up time before nOE(表示片选信号nGCS发出多久后才能发出读使能信号) Tacc:access cycle(数据访问周期) Tacp:page模式下的访问
[单片机]
s3c2440裸机-异常中断3-swi软中断
swi(软中断) 我们知道arm有7中工作模式,除了usr模式,其他6种都是特权模式。我们知道usr模式无法修改CPSR直接进入其他特权模式,但linux应用程序一般运行在usr模式,既然usr模式权限非常低,是无法直接访问硬件寄存器的,那么它是如何访问硬件的呢? linux应用程序是通过系统调用,从而进入内核态,运行驱动程序来访问的硬件,那么系统调用又是如何实现的呢,就是通过软中断swi指令来进入svc模式,进入到svc模式后当然就能访问硬件啦。 所以我们的应用程序在usr模式想访问硬件,必须切换模式,怎么切换? 有以下两种方式: 1.发生异常或中断(被动的) 2.swi + 某个值(主动的) 现在介绍如何进
[单片机]
s3c2440裸机-spi编程-3-gpio模拟spi驱动OLED
操作OLED,通过三条线(SCK、DO、CS)与OLED相连,这里没有DI是因为2440只会向OLED传数据而不用接收数据。 gpio_spi.c来实现gpio模拟spi,负责spi通讯。对于OLED,有专门的指令和数据格式,要传输的数据内容,在oled.c这一层来实现,负责组织数据。 因此,我们需要实现以上两个文件。 1.SPI初始化 新建一个gpio_spi.c文件,实现SPI初始化SPIInt() 1.1 GPIO init(pinmux管脚等配置) 上图J3为板子pin2pin到OLED的底座。 GPF1作为OLED片选引脚,设置为输出; GPG4作为OLED的数据(Data)/命令(Command)选择引脚,
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

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