zoukankan      html  css  js  c++  java
  • 裸机代码(uboot) : clear bss

    一. bss介绍:

      代码中函数、变量、常量 / bss段、data段、text段 /sct文件、.map文件的关系[实例分析arm代码(mdk)]

    
    
    bss和data的区别:
        全局的未初始化变量存在于.bss段中,具体体现为一个占位符;
        全局的已初始化变量存于.data段中;
    
        .bss是不占用.exe文件空间的,其内容由操作系统初始化(清零);
        而.data却需要占用,其内容由程序初始化。
    
        若这样定义一个全局变量:int g_inBss[9] ;
        则它在.bss段,这里占用占位符的空间。
    
        若这样定义一个全局变量:int g_inData[9] ={1,2,3,4,5,6,7,8,9};
        则它在.data段,程序占用数组全部大小的空间。
    
    bss和data的联系:
        都在rw区域;
        bss段在运行起来成为进程之后,占的空间大小和data就相同了。
    
    

    二. 分析uboot代码中的clearbss段的代码:


    _bss_start 和 __bss_start
    ====================================
    1. u-boot-1.1.6/board/100ask24x0/u-boot.lds

    ......
    ENTRY(_start)
    SECTIONS
    {
        . = 0x00000000;

        . = ALIGN(4);
        .text      :
        {
          cpu/arm920t/start.o    (.text)
              board/100ask24x0/boot_init.o (.text)
          *(.text)
        }
        ......
        ......
        . = ALIGN(4);
        __bss_start = .;
        .bss : { *(.bss) }
        _end = .;
    }

    __bss_start 是bss段的起始地址,
    _end 是bss段的终止地址.

    ====================================

    2. u-boot-1.1.6/cpu/arm920t/start.S

    .globl _bss_start
    _bss_start:
        .word __bss_start

    .globl _bss_end
    _bss_end:
        .word _end
        
        分析{
            .word .word expr {,expr}… 分配一段字内存单元,幵用expr初始化字内存单元(32bit)
            
            关亍 _bss_start 和 _bss_end 都是两个标号,对应着此处的地址。
            而两个地址里面分别存放的值是 __bss_start 和 _end,
        }

    ====================================

    3. 汇编的清零bss段:
    clear_bss:
        ldr    r0, _bss_start        /* find start of bss segment        */
        ldr    r1, _bss_end        /* stop here                        */
        mov r2, #0x00000000        /* clear                            */

    clbss_l:  str    r2, [r0]        /* clear loop...                    */
        add    r0, r0, #4
        cmp    r0, r1
        ble    clbss_l
        
        {
            ldr    r0, _bss_start   表示装载 _bss_start 地址中的值,即装载 __bss_start
            ldr    r0, _bss_end     表示装载 _bss_end 地址中的值,即装载 _end
        }

    ====================================
    4. 网上找的c语言中的clear_bss, 觉得有问题:

    void clean_bss(void)
    {
        extern int __bss_start, _end;
        int *p = &__bss_start;

        for (; p < &_end; p++)
            *p = 0;
    }

    &__bss_start 就是: _bss_start
    &_end 就是: _bss_end

    从c语言语法上看,__bss_start和_end和bss段代表bss段的起始地址和终止地址.

    但是_bss_start和_bss_end却不能代表bss段的起始地址和终止地址, 因此我得出了这个结论:     "clean_bss中那个for循环并不能起到清零bss段的作用."

     

  • 相关阅读:
    使用SDL2显示一张图片,SDL2上手贴
    两种方法操作其它mac应用的窗口
    golang子进程的启动和停止,mac与linux的区别
    自己动手,装一个液晶电视
    在Ubuntu上搭建kindle gtk开发环境
    macOS的OpenCL高性能计算
    量子计算及量子计算的模拟
    iPhone多次输入错误密码锁机后刷机恢复(原有内容会丢失)
    Day 2 总结
    Day 13 linux 的输入输出与管道的使用
  • 原文地址:https://www.cnblogs.com/mylinux/p/5604458.html
Copyright © 2011-2022 走看看