Windows平台网站图片服务器架设的形成葡京娱乐总站平台


在主流的Web站点中,图片往往是少不了的页面成分,尤其在大型网站中,差不多都将面临“海量图片能源”的储存、访问等相关技术难点。在针对图片服务器的架构扩张中,也会历经重重曲折甚至是血泪教训(越发是最初设计不足,造成前期架构上很难包容和壮大)。

  我们好,笔者是豹哥,猎豹的豹,犀利哥的哥。前些天豹哥给大家讲的是嵌入式开发里的executable文件(elf)

正文将以一个实事求是垂直门户网站的前行历程,向我们频频道来。

  第陆 、五节课里,豹哥已经给我们介绍了2种output文件,本文继续给大家讲project生成的另一种output文件-executable文件,也是特意首要的output文件。

创设在Windows平台之上的网站,往往会被规范众多技巧认为很“保守”,甚至会有点。很超越二分之一原因,是出于微软技术系统的查封和一部分技术人士的短视造成的(当然,重要照旧人的题材)。由于天长日久枯窘开源辅助,所以众六人只好“闭门造车”,那样很不难形成思维局限性和短板。以图片服务器为例子,如若早期没有体量规划和可扩张的筹划,那么随着图片文件的无休止扩展和访问量的上涨,由于在质量、容错/容灾、扩张性等地点的设计不足,后续将会给支付、运营工作带来诸多题材,严重时竟然会影响到网站工作平常运作和网络公司的发展(那并非是在震惊)。

  文件涉及:linker文件

很多同盟社因而选取Windows(.NET)平台来创设网站和图纸服务器,相当大多数由创始团队的技巧背景决定的,早期的技术职员也许更熟知.NET,只怕组织的领导者认为Windows/.NET的易用性、“短平快”的支出形式、人才基金等方面都比较适合创业初期的协会,自然就挑选了Windows。早先时期工作发展到一定范围,也很难轻易将完整架构迁移到此外开源平台上了。当然,对于创设大规模互连网,更建议首要选拔开源架构,因为有这么些早熟的案例和开源生态的支撑(也会有比比皆是坑,就看是你协调第叁去踩坑,依然在人家踩了修复之后您再用),幸免再一次造轮子和付出高额授权费用。对于迁移难度较大的应用,个人相比推荐Linux、Mono、Jexus、Mysql、Memcahed、Redis……混搭的架构,同样能支撑具有高并发访问和命局据量等特点的互连网应用。

单机年代的图纸服务器架设(集中式)

初创一时半刻由于时日热切,开发人员水平也很不难等原因。所以普通就间接在website文件所在的目录下,建立二个upload子目录,用于保存用户上传的图纸文件。假设按工作再细分,能够在upload目录下再建立不相同的子目录来分别。例如:upload\QA,upload\Face等。

在数据库表中保存的也是”upload/qa/test.jpg”那类相对路径。

用户的造访情势如下:

http://www.yourdomain.com/upload/qa/test.jpg

先后上传和写入措施:

程序员A通过在web.config中配备物理目录D:\Web\yourdomain\upload 
然后经过stream的法子写入文件;

程序员B通过Server.MapPath等格局,依据相对路径获取物理目录 
然后也经过stream的章程写入文件。

可取:达成起来最简便,无需任何复杂技术,就能打响将用户上传的公文写入钦命目录。保存数据库记录和走访起来倒是也很有益于。

症结:上传情势混乱,严重不便利网站的恢宏。

本着上述最原始的架构,首要面临着如下难题:

  1. 随着upload目录中文件越多,所在分区(例如D盘)假若出现容积不足,则很难扩大体量。只好停机后转移更大体量的存款和储蓄设备,再将旧数据导入。
  2. 在安顿新本子(布署新本子前经过供给备份)和一般性备份website文件的时候,要求同时操作upload目录中的文件,若是考虑到访问量回升,前边安顿由多台Web服务器组成的负荷均衡集群,集群节点之间一旦做好文件实时同步将是个难点。

 

  仔细看过豹哥从前课程的仇敌一定晓得,豹哥在第一节课relocatable文件里介绍的object文件在格式上其实跟本文要讲的elf文件是类似的,它们都属于ELF文件分支。只不是relocatable文件只是中间过渡文件,而本文要讲的elf却是标准的output文件,这些文件大约涵盖了工程的装有消息,有了这些文件大家既可以在线调节和测试工程,也能够将elf文件转换到image文件,直接下载image文件数据进芯片中脱机械运输营。明日豹哥就为大家仔细分析elf文件。

集群时代的图样服务器架设(实时同步)

在website站点上边,新建一个名为upload的虚拟目录,由于虚拟目录的八面玲珑,能在早晚水准上代表物理目录,并合作原有的图样上传和访问格局。用户的走访格局依然是:

http://www.yourdomain.com/upload/qa/test.jpg

优点:配置进一步灵活,也能同盟老版本的上传和做客方式。

因为虚拟目录,能够本着本地任意盘符下的即兴目录。那样一来,仍是能够通过交接外置存储,来实行单机的容积增加。

缺陷:安插成由多台Web服务器组成的集群,各种Web服务器(集群节点)之间(虚拟目录下的)须求实时的去共同文件,由于一起功能和实时性的范围,很难保障某一整日各节点上文件是完全一致的。

主干架构如下图所示:

葡京娱乐总站平台 1

从上海教室可见到,整个Web服务器架设已经拥有“可扩张、高可用”了,首要难点和瓶颈都集中在多台服务器之间的文书同步上。

上述架构中只幸而这几台Web服务器上互动“增量同步”,那样一来,就不帮忙文件的“删除、更新”操作的协同了。

中期的想法是,在应用程序层面做决定,当用户请求在web1服务器进行上传写入的还要,也联合去调用其余web服务器上的上传接口,那明显是大做文章的。所以我们选拔使用GL450sync类的软件来做定时文件同步的,从而省去了“重复造轮子”的基金,也回落了危机性。

同步操作里面,一般有相比较经典的三种模型,即推拉模型:所谓“拉”,就是指轮询地去获得更新,所谓推,就是发生变动后积极的“推”给任何机器。当然,也得以选拔加高级的轩然大波通报机制来形成此类动作。

在高并发写入的气象中,同步都会合世频率和实时性难题,而且多量文件同步也是很成本系统和带宽能源的(跨网段则更明显)。

壹 、elf文件基础

  ELF全称Executable and Linkable
Format,可实施连接格式,ELF格式的公文最早用于存储Linux程序,后演变到A大切诺基M系统上存款和储蓄A奇骏M程序。ELF文件(指标文件)格式重要三种:

  • 可重定向文件:用来和任何的指标文件一起来创制三个可执行文件大概共享指标文件(也称object文件或然静态库文件,经常后缀为.o和.a的文本)。那个文件是用以编写翻译和链接阶段。
  • 可执行文件:用于转移应用image,载入存款和储蓄器执行(后缀平日为.out恐怕.elf)。这些文件是用来加载执行等级。
  • 共享指标文件:用于和别的共享指标文件大概object文件一起生成可执行文件,或许和可执行文件一起开创应用image。(也称共享库文件,后缀为.so的文书)。那个文件既可用于编写翻译和链接阶段,也可用来加载执行阶段。

  大家在ARAV4M开发中越多接触的是前三种格式,第叁种格式前边种类小说relocatable文件已经介绍过,本文的卓荦超伦是第二种格式-可执行文件。不管是哪一种格式的ELF文件,其都只怕带有如下二种基本索引表:

  • file header:一般在文书的始发,描述了ELF文件的完整协会状况。
  • program
    header
    :告诉系统怎样创设image,可执行文件必须有所program
    header,而可重定向文件则不要求。
  • section
    header
    :包涵了描述文件section的消息,每一种section都有3个header,每三个header给出诸如section名称、section大小等音信。可重定向文件必须含有section
    header。

  既然知道了留存二种索引表,那么表的结构定义在哪儿呢?github上的linux仓Curry有现实定义,在elf.h头文件里。

Linux仓库:https://github.com/torvalds/linux.git
elf.h路径:\linux\include\uapi\linux\elf.h

  打开elf.h文件便可找到多少个表的原型定义,鉴于方今的A哈弗M
Cortex-M都是32bit,所以那边仅列出32bit下的表的原型:Elf32_Ehdr、Elf32_Phdr、Elf32_Shdr。

// file header
#define EI_NIDENT    16
typedef struct elf32_hdr{
  unsigned char e_ident[EI_NIDENT];     /* Magic number and other info */
  Elf32_Half    e_type;                 /* Object file type */  
  Elf32_Half    e_machine;              /* Architecture */  
  Elf32_Word    e_version;              /* Object file version */  
  Elf32_Addr    e_entry;                /* Entry point virtual address */  
  Elf32_Off     e_phoff;                /* Program header table file offset */  
  Elf32_Off     e_shoff;                /* Section header table file offset */  
  Elf32_Word    e_flags;                /* Processor-specific flags */  
  Elf32_Half    e_ehsize;               /* ELF header size in bytes */  
  Elf32_Half    e_phentsize;            /* Program header table entry size */  
  Elf32_Half    e_phnum;                /* Program header table entry count */  
  Elf32_Half    e_shentsize;            /* Section header table entry size */  
  Elf32_Half    e_shnum;                /* Section header table entry count */  
  Elf32_Half    e_shstrndx;             /* Section header string table index */ 
} Elf32_Ehdr;

// program header
typedef struct elf32_phdr{
  Elf32_Word    p_type;           /* Segment type */
  Elf32_Off     p_offset;         /* Segment file offset */
  Elf32_Addr    p_vaddr;          /* Segment virtual address */
  Elf32_Addr    p_paddr;          /* Segment physical address */
  Elf32_Word    p_filesz;         /* Segment size in file */
  Elf32_Word    p_memsz;          /* Segment size in memory */
  Elf32_Word    p_flags;          /* Segment flags */
  Elf32_Word    p_align;          /* Segment alignment, file & memory */
} Elf32_Phdr;

// section header
typedef struct elf32_shdr {
  Elf32_Word    sh_name;          /* Section name, index in string tbl */
  Elf32_Word    sh_type;          /* Type of section */
  Elf32_Word    sh_flags;         /* Miscellaneous section attributes */
  Elf32_Addr    sh_addr;          /* Section virtual addr at execution */
  Elf32_Off     sh_offset;        /* Section file offset */
  Elf32_Word    sh_size;          /* Size of section in bytes */
  Elf32_Word    sh_link;          /* Index of another section */
  Elf32_Word    sh_info;          /* Additional section information */
  Elf32_Word    sh_addralign;     /* Section alignment */
  Elf32_Word    sh_entsize;       /* Entry size if section holds table */
} Elf32_Shdr;

集群时代的图形服务器架设创新(共享存款和储蓄)

套用虚拟目录的主意,通过UNC(网络路径)的法门达成共享存款和储蓄(将upload虚拟目录指向UNC)

用户的拜会格局1:

http://www.yourdomain.com/upload/qa/test.jpg

用户的拜会格局2(能够配备独立域名):

http://img.yourdomain.com/upload/qa/test.jpg

支撑UNC所在server上配备独立域名指向,并安顿轻量级的web服务器,来兑现独立图片服务器。

可取:
通过UNC(互联网路径)的法子来进展读写操作,能够幸免多服务器之间同步相关的难题。相对来讲很灵活,也支撑扩大体积/增添。帮衬配置成单身图片服务器和域名访问,也完全包容旧版本的造访规则。

缺点
:不过UNC配置有个别麻烦,而且会造成一定的(读写和安全)质量损失。恐怕会产出“单点故障”。若是存款和储蓄级别没有raid或许更尖端的灾备措施,还会导致数据丢失。

着力架构如下图所示:

葡京娱乐总站平台 2

在先前时代的成都百货上千基于Linux开源架构的网站中,要是不想一起图片,大概会动用NFS来落到实处。事实注解,NFS在高并发读写和海量存款和储蓄方面,功用上设有一定难点,并非最佳的选料,所以大多数互连网公司都不会使用NFS来兑现此类应用。当然,也能够经过Windows自带的DFS来落到实处,缺点是“配置复杂,效能未知,而且缺少资料大批量的其实案例”。此外,也有一部分商户选用FTP或Samba来落到实处。

 

下面提到的两种架构,在上传/下载操作时,都通过了Web服务器(尽管共享存款和储蓄的那种架构,也足以计划独立域名和站点来提供图片访问,但上传写入还是得经过Web服务器上的应用程序来拍卖),那对Web服务器来讲确实是引致巨大的压力。所以,更提议利用独立的图样服务器和单身的域名,来提供用户图片的上传和走访。

二、解析elf文件

  所谓工欲善其事,必先利其器,在起始解析elf文件此前,我们无法不先找到一款适合的解析工具,readelf正是GNU/Linux官方推出的专用解析工具。有了这些分析工具,大家便足以逐步分析elf文件。

独自图片服务器/独立域名的益处

  1. 图表访问是很成本服务器财富的(因为会涉及到操作系统的上下文切换和磁盘I/O操作)。分离出来后,Web/App服务器能够更注意发挥动态处理的力量。
  2. 单独存款和储蓄,更方便做扩大容积、容灾和数量迁移。
  3. 浏览器(相同域名下的)并发策略限制,品质损失。
  4. 访问图片时,请求音讯中总带cookie信息,也会招致质量损失。
  5. 方便人民群众做图片访问请求的负载均衡,方便利用种种缓存策略(HTTP
    Header、Proxy Cache等),也特别便于迁移到CDN。

……

 

我们能够动用Lighttpd恐怕Nginx等轻量级的web服务器来架构独立图片服务器。

2.1 解析工具readelf

  既然elf文件是Linux系统下常用的可执行文件格式,那么Linux社区一定会有配套的工具去分析它,是的,那几个工具就叫readelf,在GNU工具集binutils里。

时下的图样服务器架设(分布式文件系统+CDN)

在营造当前的图样服务器架设此前,能够先彻底废弃web服务器,间接配置单独的图片服务器/域名。但面临如下的题材:

  1. 旧图片数据怎么做?能无法继续合作旧图片路径访问规则?
  2. 单独的图片服务器上供给提供单身的上传写入的接口(服务API对外宣告),安全难点何以保管?
  3. 同理,如若有多台独立图片服务器,是行使可扩充的共享存款和储蓄方案,照旧接纳实时同步机制?

 

直至应用级其余(非系统级) DFS(例如法斯特DFS HDFS MogileFs
MooseFS、TFS)的风靡,简化了这些标题:执行冗余备份、帮衬活动同步、援助线性扩充、帮忙主流语言的客户端api上传/下载/删除等操作,部分扶助文件目录,部分帮忙提供Web的方式来拜访。

考虑到各DFS的表征,客户端API语言协理景况(须求扶助C#),文书档案和案例,以及社区的帮助度,大家最终甄选了法斯特DFS来陈设。

唯一的标题是:大概会不协作旧版本的造访规则。如若将旧图片一回性导入FastDFS,但鉴于旧图片访问路径分布存款和储蓄在不一样工作数据库的各样表中,全体立异起来也十一分困难,所以必须得十分旧版本的访问规则。架构升级往往比做全新架构更有难度,正是因为还要协作从前版本的标题。(给飞机在空中换引擎可比造架飞机难得多)

2.1.1 GNU工具集(binutils)

  GNU是“GNU’s Not
Unix”的递归缩写,又称作GNU陈设,很多盛名的开源软件及工具都以GNU开发的(比如著名的C语言编译器GCC)。binutils是GNU一种类binary小工具的集合,大家从底下的链接里找到官方binutils包。

主页:http://www.gnu.org/software/binutils/
仓库:git://sourceware.org/git/binutils-gdb.git
下载:http://ftp.gnu.org/gnu/binutils/
文档:https://sourceware.org/binutils/docs-2.29/binutils/index.html

  不过使用上述包里的readelf会有一个标题,上述工具是在Linux系统下利用的,而大家日常做AOdysseyM
Cortex-M开发很多都以在windows平台下,那么怎么在windows下使用readelf工具呢?别急,cygwin给了大家扶助。

缓解方案如下:

首先,关闭旧版本上传入口(制止后续行使导致数据不一样)。将旧图片数据通过rsync工具2遍性迁移到独门的图样服务器上(即下图中讲述的Old
Image
Server)。在最前端(七层代理,如Haproxy、Nginx)用ACL(访问规则控制),将旧图片对应USportageL规则的请求(正则)匹配到,然后将呼吁直接转账钦命的web
服务器列表,在该列表中的服务器上配备好提供图片(以Web形式)访问的站点,并插足缓存策略。那样达成旧图片服务器的分开和缓存,包容了旧图片的造访规则并进步旧图片访问作用,也幸免了实时同步所推动的题材。

 

完整架构如图:

葡京娱乐总站平台 3

基于法斯特DFS的独门图片服务器集群架构,即便早已分外的老道,但是出于国内“南北互联”和IDC带宽开支等题材(图片是尤其消耗流量的),大家最后依旧采取了商用的CDN技术,达成起来也非常简单,原理其实也很简单,小编那里只做个简易的介绍:

将img域名cname到CDN厂商钦命的域名上,用户请求访问图片时,则由CDN厂商提供智能DNS解析,将新近的(当然也大概有任何更扑朔迷离的政策,例如负载情形、健康处境等)服务节点地址再次回到给用户,用户请求到达钦赐的服务器节点上,该节点上提供了近乎Squid/Vanish的代理缓存服务,要是是第一次呼吁该路线,则会从源站获取图片财富再次来到客户端浏览器,假诺缓存中留存,则一贯从缓存中得到并再次来到给客户端浏览器,达成请求/响应进程。

出于选择了商用CDN服务,所以我们并不曾考虑用Squid/Vanish来自行营造前置代理缓存。

地点的总体集群架构,可以很便利的做横向扩展,能满足一般垂直领域中山大学型网站的图片服务须求(当然,像taobao那样超大规模的或是另当别论)。经测试,提供图片访问的单台Nginx服务器(至强E5四核CPU、16G内部存款和储蓄器、SSD),对小静态页面(压缩后大致唯有10kb左右的)能够扛住几千个并发且毫无压力。当然,由于图片本身体量比纯文本的静态页面大过多,提供图片访问的服务器的抗并发能力,往往会受限于磁盘的I/O处理能力和IDC提供的带宽。Nginx的抗并发能力也许十二分强的,而且对能源占用十分的低,尤其是拍卖静态能源,就如都不须求有过多操心了。能够依照实际访问量的必要,通过调整Nginx的参数,对Linux内核做调优,到场分级缓存策略等伎俩能够做更大程度的优化,也得以通过扩展服务器大概升级服务器配置来做扩大,最直白的是透过购买更高级的存储设备和更大的带宽,以满足更大访问量的供给。

值得一提的是,在“云计算”流行的当下,也推荐高速发展之间的网站,使用“云存款和储蓄”那样的方案,既能帮你搞定各项存款和储蓄、增加、备灾的标题,又能源办公室好CDN加快。最重庆大学的是,价格也不贵。

总结,有关图片服务器架设扩展,大概围绕那一个难题展开:

  1. 体量规划和扩张难点。
  2. 数量的同步、冗余和容灾。
  3. 硬件装备的资金和可信赖性(是平时固态硬盘,仍然SSD,或许更高端的存款和储蓄设备和方案)。
  4. 文件系统的选料。依照文件本性(例如文件大小、读写比例等)选用是用ext四分之三可能NFS/GFS/TFS这个开源的(分布式)文件系统。
  5. 图表的增长速度访问。接纳商用CDN或许自行建造的代办缓存、web静态缓存架构。
  6. 旧图片路径和走访规则的包容性,应用程序层面包车型地铁可扩展,上传和访问的属性和安全性等。
2.1.2 cygwin(windows下使用GNU)

  Cygwin是1个在windows平台上运营的类UNIX模拟条件,是cygnus
solutions公司(已被Redhat收购)开发的自由软件。它对于学习UNIX/Linux操作环境,或许从UNIX到Windows的应用程序移植,特别是使用GNU工具集在Windows上海展览中心开嵌入式系统开发,格外有效。

// 下载链接
Installer:http://cygwin.com/install.html
Package:  https://cygwin.com/packages/package_list.html
// 相关包(根据平台选择)
binutils                - GNU assembler, linker, and similar utilities
cygwin32-binutils       - Binutils for Cygwin 32bit toolchain
mingw64-x86_64-binutils - Binutils for MinGW-w64 Win64 toolchain 
mingw64-i686-binutils   - Binutils for MinGW-w64 Win32 toolchain

  下载安装好cygwin包后,便可在装置目录下\cygwin64\bin\找到x86_64-w64-mingw32-readelf.exe工具(豹哥接纳的是mingw64-x86_64-binutils包)。

2.1.3 readelf.exe用法

  readelf.exe服从标准的windows命令行用法,使用–help可以列出全体命令option及其简介,上面仅列出相比较常用的option。

C:\cygwin64\bin>x86_64-w64-mingw32-readelf.exe --help
Usage: readelf <option(s)> elf-file(s)
 Display information about the contents of ELF format files
 Options are:
  -a --all               Equivalent to: -h -l -S -s -r -d -V -A -I
  -h --file-header       Display the ELF file header
  -l --program-headers   Display the program headers
     --segments          An alias for --program-headers
  -S --section-headers   Display the sections' header
     --sections          An alias for --section-headers
  -t --section-details   Display the section details
  -e --headers           Equivalent to: -h -l -S
  -s --syms              Display the symbol table
     --symbols           An alias for --syms
  --dyn-syms             Display the dynamic symbol table
  -r --relocs            Display the relocations (if present)
  -d --dynamic           Display the dynamic section (if present)
  -V --version-info      Display the version sections (if present)
  -A --arch-specific     Display architecture specific information (if any)
  -I --histogram         Display histogram of bucket list lengths
  @<file>                Read options from <file>

2.2 逐步分析elf文件

  万事俱备了,初步分析elf文件,以第二节课project文件里demo工程为例。编写翻译链接该工程可在D:\myProject\bsp\builds\demo\Release\Exe路径下获得demo.elf文件。该文件大小32612
bytes,显然那样简单的三个小工程image
size不恐怕那样大,表达elf文件里的记录音讯数据占比一点都一点都不小。

2.2.1 获得file header
C:\cygwin64\bin>x86_64-w64-mingw32-readelf.exe -h demo.elf
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x41
  Start of program headers:          31740 (bytes into file)
  Start of section headers:          31772 (bytes into file)
  Flags:                             0x5000000, Version5 EABI
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         1
  Size of section headers:           40 (bytes)
  Number of section headers:         21
  Section header string table index: 1

  第二步首先分析file header,后面介绍里说过file
header是身处文件最前边的。通过readelf -h命令可以收获file
header解析后的音信。让大家来对待一下,使用Hex艾德itor直接打开demo.elf可获得如下数据,仅取前52bytes(0x34)数据,因为Elf32_Ehdr大小正是52bytes:

offset(h)
00000000: 7F 45 4C 46 01 01 01 00 00 00 00 00 00 00 00 00
00000010: 02 00 28 00 01 00 00 00 41 00 00 00 FC 7B 00 00
00000020: 1C 7C 00 00 00 00 00 05 34 00 20 00 01 00 28 00
00000030: 15 00 01 00 -- -- -- -- -- -- -- -- -- -- -- --

  能够看看前16byte是e_ident[16],与分析后的Magic是同样的;再来验证prgram
header偏移e_phoff=0x00007BFC,数量e_phnum=0x0001,大小e_phentsize=0x0020,也是与分析后的音讯格外的;余下可机关对照。

2.2.2 获得program header
C:\cygwin64\bin>x86_64-w64-mingw32-readelf.exe -l demo.elf

Elf file type is EXEC (Executable file)
Entry point 0x41
There are 1 program headers, starting at offset 31740

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000034 0x00000000 0x00000000 0x004c4 0x004c4 R E 0x100

 Section to Segment mapping:
  Segment Sections...
   00     A0 rw P1 ro

  再来分析program header,通过readelf -l命令能够获得program
header解析后的新闻。从上面能够识破header早先地点在demo.elf的31740
byte处(与file header里的e_phoff音讯是对应的),header新闻提醒program
data从offset 0x34先河,大小共0x4c4
bytes,Reset_Handler入口是0x41。继续在Hex艾德itor查看31740处初阶的32byte数据,因为Elf32_Phdr大小正是32bytes:

offset(h)
00007BF0: -- -- -- -- -- -- -- -- -- -- -- -- 01 00 00 00
00007C00: 34 00 00 00 00 00 00 00 00 00 00 00 C4 04 00 00
00007C10: C4 04 00 00 05 00 00 00 00 01 00 00 -- -- -- --

  能够看来p_offset=0x00000034,p_memsz=0x000004c4,
与地方解析后的音讯是平等的;余下可自行对照。
那里的消息就比较重庆大学了,因为那提示了全数image
binary数据所在(知道了那一个音信,大家便足以平素写脚本依照elf文件生成image
binary),继续在Hex艾德itor里看下去(仅截取部分显得):

offset(h)
00000030: -- -- -- -- 00 20 00 10 41 00 00 00 03 04 00 00
00000040: 3F 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000060: 61 04 00 00 00 00 00 00 00 00 00 00 63 04 00 00
00000070: 65 04 00 00 72 B6 0E 48 0E 49 88 60 00 22 00 23
00000080: 00 24 00 25 00 26 00 27 B8 46 B9 46 BA 46 BB 46

  ACR-VM系统的image前拾六个指针都以系统中断向量,大家可以看看SP=0x一千两千,
PC=0x00000041,那与地点解析的Reset_Handler入口是0x41是协作的。

2.2.3 获得section header
c:\cygwin64\bin>x86_64-w64-mingw32-readelf.exe -S demo.elf
There are 21 section headers, starting at offset 0x7c1c:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 006338 000000 00      0   0  4
  [ 1] .shstrtab         STRTAB          00000000 006338 0000e6 00      0   0  4
  [ 2] .strtab           STRTAB          00000000 006420 000b7c 00      0   0  4
  [ 3] .symtab           SYMTAB          00000000 006f9c 000c60 10      2 135  4
  [ 4] A0 rw             PROGBITS        00000000 000034 000040 01  AX  0   0 256
  [ 5] P1 ro             PROGBITS        00000040 000074 000484 01  AX  0   0  4
  [ 6] P3 ui             NOBITS          10000000 0004f8 002000 01  WA  0   0  8
  [ 7] P2 rw             NOBITS          10002000 0004f8 000438 01  WA  0   0  8
  [ 8] .debug_abbrev     PROGBITS        00000000 0004f8 0002c6 01      0   0  0
  [ 9] .debug_aranges    PROGBITS        00000000 0007c0 00016c 01      0   0  0
  [10] .debug_frame      PROGBITS        00000000 00092c 00057c 01      0   0  0
  [11] .debug_info       PROGBITS        00000000 000ea8 000e2e 01      0   0  0
  [12] .debug_line       PROGBITS        00000000 001cd8 000dcb 01      0   0  0
  [13] .debug_loc        PROGBITS        00000000 002aa4 00024c 01      0   0  0
  [14] .debug_macinfo    PROGBITS        00000000 002cf0 00011e 01      0   0  0
  [15] .debug_pubnames   PROGBITS        00000000 002e10 00012a 01      0   0  0
  [16] .iar.debug_frame  PROGBITS        00000000 002f3c 00007e 01      0   0  0
  [17] .iar.debug_line   PROGBITS        00000000 002fbc 000367 01      0   0  0
  [18] .comment          PROGBITS        00000000 003324 002fa2 01      0   0  0
  [19] .iar.rtmodel      PROGBITS        00000000 0062c8 000047 01      0   0  0
  [20] .ARM.attributes   ARM_ATTRIBUTES  00000000 006310 000026 01      0   0  0
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  y (purecode), p (processor specific)

  再来分析section header,通过readelf -S命令能够拿走section
header解析后的新闻。能够看出有成都百货上千个section,在那之中最要紧的陆个section是A0(readonly
vector), P1(readonly code,data), P2(readwrite data, heap),
P3(STACK)。具体分析,各位朋友自身摸索看。

2.2.4 获得symbol list
c:cygwin64\bin>x86_64-w64-mingw32-readelf.exe -s demo.elf

Symbol table '.symtab' contains 198 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
    74: 10002018    16 OBJECT  LOCAL  DEFAULT    7 s_array
    75: 10002014     4 OBJECT  LOCAL  DEFAULT    7 s_variable0
    76: 10002010     4 OBJECT  LOCAL  DEFAULT    7 s_variable2
   135: 00000000     0 OBJECT  GLOBAL DEFAULT    4 __vector_table
   140: 00000041     0 FUNC    GLOBAL DEFAULT    5 Reset_Handler
   141: 00000098     4 OBJECT  GLOBAL DEFAULT    5 s_constant
   142: 000000ad    32 FUNC    GLOBAL DEFAULT    5 main
   143: 000000cd    14 FUNC    GLOBAL DEFAULT    5 normal_task
   144: 000000db    60 FUNC    GLOBAL DEFAULT    5 heap_task
   155: 0000034d    84 FUNC    GLOBAL DEFAULT    5 init_data_bss
   156: 000003a1    18 FUNC    GLOBAL DEFAULT    5 init_interrupts
   157: 000003dd    12 FUNC    GLOBAL DEFAULT    5 SystemInit
   186: 10002001    16 FUNC    GLOBAL DEFAULT    7 ram_task
   191: 10002034     4 OBJECT  GLOBAL DEFAULT    7 n_variable1

  通过readelf -s命令能够获得symbol
list解析后的音讯。可以见见有过四个symbol,豹哥在此地仅列出利用工程里自定义的函数和变量,从symbol表里大家得以摸清函数/变量在存款和储蓄器中切实分配地址和尺寸,那对于大家尤其分析和调节和测试应用是有赞助的。

2.3 elf文件layout

  经过上一节对demo.elf里相继header的辨析,此时咱们便足以粗略地画出elf文件layout。

File offset Data content Data size in bytes
0x00000000 ELF file header 52
0x00000034 Image binary (Section4-A0 rw, .intvec中断向量表) 0x40
0x00000074 Image binary (Section5-P1 ro, readonly section(.text, .rodata…)) 0x484
0x000004F8 Section8-20 (包含各种辅助调试和系统段.debug_xx, .iar.xx) 0x5E3E
0x00006336 NULL 0x2
0x00006338 Section1-.shstrtab字符串表 0xE6
0x00006420 Section2-.strtab字符串信息 0xB7C
0x00006F9C Section3-.symtab符号信息 0xC60
0x00007BFC ELF Program header 0x20
0x00007C1C ELF Section headers (0 – 20) 21 * 40

番外一、几个elf转换image工具

  在前日的番外篇里,豹哥给大家顺便介绍两款专业的elf文件转换到image文件的工具。

工具1:GNU工具objcopy

位置:C:\cygwin64\bin>x86_64-w64-mingw32-objcopy.exe
用法:
      objcopy.exe -O binary -S demo.elf demo.bin
      objcopy.exe -O srec   -S demo.elf demo.s19

备注:一说需用arm-linux-objcopy,待验证

工具2:IAR工具ielftool.exe

位置:\IAR Systems\Embedded Workbench xxx\arm\bin\ielftool.exe
用法:
      ielftool.exe --bin  demo.elf demo.bin
      ielftool.exe --ihex demo.elf demo.hex
      ielftool.exe --srec demo.elf demo.s19

  至此,嵌入式开发里的executable文件(elf)文件豹哥便介绍实现了,掌声在哪儿~~~