Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3356874
  • 博文数量: 258
  • 博客积分: 9440
  • 博客等级: 少将
  • 技术积分: 6998
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-03 10:28
个人简介

-- linux爱好者,业余时间热衷于分析linux内核源码 -- 目前主要研究云计算和虚拟化相关的技术,主要包括libvirt/qemu,openstack,opennebula架构和源码分析。 -- 第五届云计算大会演讲嘉宾 微博:@Marshal-Liu

文章分类

全部博文(258)

文章存档

2016年(1)

2015年(4)

2014年(16)

2013年(22)

2012年(41)

2011年(59)

2010年(40)

2009年(75)

分类: LINUX

2011-11-13 16:25:42

  在上一篇文章《位置无关代码(PIC)的思考》 中提到,在elf文件转化成bin文件的过程中,输出段与段之间如果有空隙的话,objcopy会用0来填充段与段之间的空隙,也可以通过objcopy 的选项--gap-fill= val来制定填充值的内容为val,这将会导致bin文件比elf文件大很多的问题,在很多嵌入式设备上将是无法接受的,因为嵌入式设备通常会将程序转化 成bin烧写到FLASH中,这样做的目的就是为了省空间,但结果确实大大的浪费了空间。

    下面先通过一个简单的例子来说明下这个问题。

    1. boot.s文件,模拟bootloader,代码如下:

  1.  .extern _entry  
  2.  .globl _start  
  3.  .text  
  4.  _start:                                                                                           
  5.      jmp _entry  
  6.                    
   2. main.s文件,模拟应用程序或os镜像,代码如下:
  1.  .text  
  2.  .globl _entry  
  3.  _entry:  
  4.      mov $1, %eax                                                                                  
  5.    

3. 链接脚本文件(boot.lds):
  1. OUTPUT_ARCH(i386)  
  2.   ENTRY(_start)  
  3.     
  4.   SECTIONS  
  5.   {  
  6.       . = 0x0;   
  7.     
  8.       . = ALIGN(4);  
  9.       .boot 0x0 :      ;bootloader映射到ROM地址空间中,上电开始运行  
  10.       {  
  11.           boot.o(.text)  
  12.       }  
  13.     
  14.       . = ALIGN(4);                                                                                 
  15.       .text 0x10000   :    ;应用程序或os镜像映射到RAM中,由bootloader从ROM中搬运到RAM中  
  16.       {  
  17.           _tstart = .;  
  18.     
  19.           *(.text)  
  20.      }  
  21.     
  22.       . = ALIGN(4);  
  23.       .data : {*(.data)}  
  24.       _bss_start = .;  
  25.       .bss : {*(.bss)}  
  26.   }  

    下面编译链接上面两个.s文件,并生成bin文件,过程如下:

  1. gcc -c -g boot.s  
  2. gcc -c -g main.s  
  3. ld boot.o main.o -o bootelf -Tboot.lds -Map boot.map --gap-fill=0xff   /*默认填充0,填充ff方便查看*/  
  4. objcopy -O binary bootelf bootbin.bin   

其中-Map boot.map是生成符号表,便于查看某些信息,下面是生成的每个文件的大小的截图:


从图中可以看到bootbin.bin的大小远远大于bootelf,下面我们来计算下文件的大小。

1. 首先先查看下bootbin.bin文件的内容

可以看到正是由于0x10~0x10000之间被填充了0xff,所以才导致了bin文件变大了,而且其大小正好是0x10000+5个字节,从map文件就可以计算出。

弄清楚了问题的根源,下面来分析下解决方法。

1. lds文件写法问题

    虽然这么写看起来清晰写,能够分清哪些代码在ROM中执行哪些代码在RAM中执行,但是却是通过增加额外的REGION来实现的,在《位置无关代码(PIC)的思考》一文中也提到了lds文件的写法,即将ROM中运行的代码也放在RAM地址空间中,至于为什么,前面已经讲过。

2. objcopy填充的问题

    objcopy完全可以通过map文件或elf文件本的信息来对bin文件重新拼装,这个问题objcopy好像没有专门的选项来对应,需要自己通过脚本来实现bin文件的拼装
阅读(6141) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

kangear2013-06-25 11:56:12

bin文件比elf文件大确实恼火。