我一直认为战略上蔑视技术,战术上重视技术是很有必要的学习态度。这是一篇 Bringup SoC 芯片的指导手册,更是一篇了解整个系统流程的地图。不会深入了解每个模块的细节,但提供了整个系统的宏观描述,让你站在上帝视角俯视每个知识点,为了对读者更负责,我打算以付费的方式和大家见面,对技术细节有需求的小伙伴欢迎加我微信(rrjike)交流,保证超有所值。

系统在启动的时候,无论是 ROM 加载 Uboot(SPL + Bootloader),还是 Uboot 加载 Kernel,都是把相关的镜像放到对应的内存不同地址,然后运行启动。这个过程看起来很简单,但中间涉及到多个知识点,了解各个子过程对理解启动的本质有很大的帮助作用,对 bring up 芯片更是有必要。我们先从镜像的结构开始,后面逐一介绍 ROM->SPL->UBoot->Kernel 的全过程。

ELF 文件

在介绍加载镜像之前,需要先了解下 ELF 文件的格式定义。

从图中可以看出,一个 ELF 文件是由 4 部分组成,分别是:

ELF 头部,程序头表,节,节头表。

有 3 种类型的 ELF 文件:

目标文件:被链接器读取,用来产生一个可执行文件或者共享库文件;

可执行文件:被操作系统中的加载器从硬盘上读取,载入到内存中去执行;

共享库文件:在动态链接的时候,由 ld-linux.so 来读取;

ELF 头部

描述 ELF header 的结构体:

typedef struct elfhdr{unsigned char e_ident[EI_NIDENT]; /* ELF Identification */Elf32_Half e_type;  /* object file type */Elf32_Half e_machine; /* machine */Elf32_Word e_version; /* object file version */Elf32_Addr e_entry; /* virtual entry point */Elf32_Off e_phoff; /* program header table offset */Elf32_Off e_shoff; /* section header table offset */Elf32_Word e_flags; /* processor-specific flags */Elf32_Half e_ehsize; /* ELF header size */Elf32_Half e_phentsize; /* program header entry size */Elf32_Half e_phnum; /* number of program header entries */Elf32_Half e_shentsize; /* section header entry size */Elf32_Half e_shnum; /* number of section header entries */Elf32_Half e_shstrndx; /* section header table's "sectionheader string table" entry offset */
} Elf32_Ehdr;

看下 ELF 头部的信息:

$ readelf -h vmlinux
ELF Header:Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00Class:                             ELF64Data:                              2's complement, little endianVersion:                           1 (current)OS/ABI:                            UNIX - System VABI Version:                       0Type:                              DYN (Shared object file)Machine:                           AArch64Version:                           0x1Entry point address:               0xffff200008080000Start of program headers:          64 (bytes into file)Start of section headers:          29609944 (bytes into file)Flags:                             0x0Size of this header:               64 (bytes)Size of program headers:           56 (bytes)Number of program headers:         4Size of section headers:           64 (bytes)Number of section headers:         35Section header string table index: 32

这个内容与结构体 Elf32_Ehdr 中的成员变量是一一对应的。

程序头表

描述 Program header table 的结构体:

typedef struct {Elf32_Word p_type;  /* segment type */Elf32_Off p_offset; /* segment offset */Elf32_Addr p_vaddr; /* virtual address of segment */Elf32_Addr p_paddr; /* physical address - ignored? */Elf32_Word p_filesz; /* number of bytes in file for seg. */Elf32_Word p_memsz; /* number of bytes in mem. for seg. */Elf32_Word p_flags; /* flags */Elf32_Word p_align; /* memory alignment */
} Elf32_Phdr;

看下程序头表的信息:

$ readelf -l vmlinuxElf file type is DYN (Shared object file)
Entry point 0xffff200008080000
There are 4 program headers, starting at offset 64Program Headers:Type           Offset             VirtAddr           PhysAddr           FileSiz            MemSiz              Flags  AlignLOAD           0x0000000000010000 0xffff200008080000 0xffff200008080000 0x0000000000f534c8 0x0000000000f534c8  R E    10000LOAD           0x0000000000f70000 0xffff200008fe0000 0xffff200008fe0000 0x00000000007dda00 0x000000000106af20  RWE    10000NOTE           0x000000000133a028 0xffff2000093aa028 0xffff2000093aa028 0x0000000000000024 0x0000000000000024  R      4GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000  RW     10Section to Segment mapping:Segment Sections...00     .head.text .text01     .rodata .init___kcrctab+sort .init__ksymtab_strings .pci_fixup __ksymtab __ksymtab_gpl __kcrctab __kcrctab_gpl __ksymtab_strings __param __modver __ex_table .notes .init.text .exit.text .altinstructions .altinstr_replacement .init.data .data..percpu .rela.dyn .data .got.plt .init___ksymtab+sort __bug_table .mmuoff.data.write .mmuoff.data.read .pecoff_edata_padding .bss02     .notes03

可以看出该 vmlinux 的入口地址是 0xffff200008080000。一共有 4个段(segment),前两个需要 load 到内存的段,它们分别是代码段数据段,属性是读、执行(RE)和读、写、执行(RWE)。

代码段包含了两个 section。数据段包含了很多 section。

  • text 段

代码段,通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定。

  • data 段

数据段,通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。

  • bss 段

通常是指用来存放程序中未初始化的全局变量和静态变量的一块内存区域。BSS段属于静态内存分配。

  • init 段

linux定义的一种初始化过程中才会用到的段,一旦初始化完成,那么这些段所占用的内存会被释放掉,后续会继续说明。

节头表

描述 Section header table 的结构体:

typedef struct {Elf32_Word sh_name; /* name - index into section headerstring table section */Elf32_Word sh_type; /* type */Elf32_Word sh_flags; /* flags */Elf32_Addr sh_addr; /* address */Elf32_Off sh_offset; /* file offset */Elf32_Word sh_size; /* section size */Elf32_Word sh_link; /* section header table index link */Elf32_Word sh_info; /* extra information */Elf32_Word sh_addralign; /* address alignment */Elf32_Word sh_entsize; /* section entry size */
} Elf32_Shdr;

看下节头表的信息:

$ readelf -S vmlinux
There are 35 section headers, starting at offset 0x1c3cfd8:Section Headers:[Nr] Name              Type             Address           Offset           Size              EntSize          Flags  Link  Info  Align[ 0]                   NULL             0000000000000000  00000000   0000000000000000  0000000000000000           0     0     0[ 1] .head.text        PROGBITS         ffff200008080000  00010000   0000000000001000  0000000000000000  AX       0     0     4096[ 2] .text             PROGBITS         ffff200008081000  00011000   0000000000f524c8  0000000000000008  AX       0     0     2048[ 3] .rodata           PROGBITS         ffff200008fe0000  00f70000         0000000000358380  0000000000000000  WA       0     0     4096[ 4] .init___kcrctab+s PROGBITS         ffff200009338380  012c8380     0000000000000004  0000000000000000   A       0     0     1[ 5] .init__ksymtab_st PROGBITS         ffff200009338384  012c8384   0000000000000005  0000000000000000   A       0     0     1[ 6] .pci_fixup        PROGBITS         ffff200009338390  012c8390   0000000000000018  0000000000000000   A       0     0     8[ 7] __ksymtab         PROGBITS         ffff2000093383a8  012c83a8   00000000000155c0  0000000000000000   A       0     0     8[ 8] __ksymtab_gpl     PROGBITS         ffff20000934d968  012dd968   0000000000014fe0  0000000000000000   A       0     0     8[ 9] __kcrctab         PROGBITS         ffff200009362948  012f2948   0000000000005570  0000000000000000   A       0     0     1[10] __kcrctab_gpl     PROGBITS         ffff200009367eb8  012f7eb8   00000000000053f8  0000000000000000   A       0     0     1      [11] __ksymtab_strings PROGBITS         ffff20000936d2b0  012fd2b0   00000000000358d8  0000000000000000   A       0     0     1[12] __param           PROGBITS         ffff2000093a2b88  01332b88   0000000000003548  0000000000000000   A       0     0     8[13] __modver          PROGBITS         ffff2000093a60d0  013360d0   0000000000000f30  0000000000000000   A       0     0     8[14] __ex_table        PROGBITS         ffff2000093a7000  01337000   0000000000003028  0000000000000000   A       0     0     8[15] .notes            NOTE             ffff2000093aa028  0133a028   0000000000000024  0000000000000000   A       0     0     4[16] .init.text        PROGBITS         ffff2000093b0000  01340000   0000000000080af8  0000000000000000  AX       0     0     8[17] .exit.text        PROGBITS         ffff200009430af8  013c0af8   000000000000421c  0000000000000000  AX       0     0     4[18] .altinstructions  PROGBITS         ffff200009434d14  013c4d14   000000000001e3b4  0000000000000000   A       0     0     1[19] .altinstr_replace PROGBITS         ffff2000094530c8  013e30c8   000000000000a36c  0000000000000000  AX       0     0     4[20] .init.data        PROGBITS         ffff20000945e000  013ee000   000000000001f580  0000000000000000  WA       0     0     4096[21] .data..percpu     PROGBITS         ffff20000947e000  0140e000   0000000000014018  0000000000000000  WA       0     0     128[22] .rela.dyn         RELA             ffff200009492018  01422018   00000000001d9c10  0000000000000018   A       0     0     8[23] .data             PROGBITS         ffff200009670000  01600000   0000000000137868  0000000000000000  WA       0     0     4096[24] .got.plt          PROGBITS         ffff2000097a7868  01737868   0000000000000018  0000000000000008  WA       0     0     8      [25] .init___ksymtab+s PROGBITS         ffff2000097a7880  01737880   0000000000000010  0000000000000000  WA       0     0     8     [26] __bug_table       PROGBITS         ffff2000097a7890  01737890   00000000000150b4  0000000000000000  WA       0     0     4[27] .mmuoff.data.writ PROGBITS         ffff2000097bd000  0174d000   000000000000000c  0000000000000000  WA       0     0     2048[28] .mmuoff.data.read PROGBITS         ffff2000097bd800  0174d800   0000000000000008  0000000000000000  WA       0     0     8[29] .pecoff_edata_pad PROGBITS         ffff2000097bd808  0174d808   00000000000001f8  0000000000000000  WA       0     0     1[30] .bss              NOBITS           ffff2000097be000  0174da00   000000000088cf20  0000000000000000  WA       0     0     4096[31] .comment          PROGBITS         0000000000000000  0174da00   0000000000000027  0000000000000001  MS       0     0     1[32] .shstrtab         STRTAB           0000000000000000  01c3ce4a   000000000000018b  0000000000000000           0     0     1[33] .symtab           SYMTAB           0000000000000000  0174da28   00000000002ea610  0000000000000018          34   92369   8[34] .strtab           STRTAB           0000000000000000  01a38038   0000000000204e12  0000000000000000           0     0     1
Key to Flags:W (write), A (alloc), X (execute), M (merge), S (strings)I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)O (extra OS processing required) o (OS specific), p (processor specific)

最后用一幅图总结 ELF 文件 vmlinux 的分布:

镜像的生成

ELF 文件格式是 Linux 环境下的可执行文件格式,在 Linux 环境下,加载器根据 ELF 文件里的地址信息,就可以把它加载到内存指定的地址运行,但是系统启动过程中并没有 ELF 文件的执行环境,需要将 ELF 文件转换为二进制纯指令文件,即 Image。

万字连载(上):如何 Bringup SoC 芯片相关推荐

  1. 阿里平头哥研发专用 SoC 芯片;部分 MacBook Pro 被禁止上飞机;VS Code 1.37 发布 | 极客头条...

    快来收听极客头条音频版吧,智能播报由标贝科技提供技术支持. 「CSDN 极客头条」,是从 CSDN 网站延伸至官方微信公众号的特别栏目,专注于一天业界事报道.风里雨里,我们将每天为朋友们,播报最新鲜有 ...

  2. 多核片上系统(SoC)架构的嵌入式DSP软件设计

    多核片上系统(SoC)架构的嵌入式DSP软件设计 Multicore a System-on-a-Chip (SoC) Architecture SoCs的软件开发涉及到基于最强大的计算模型在各种处理 ...

  3. 概要设计实例_多核片上系统(SoC)架构的嵌入式DSP软件设计

    多核片上系统(SoC)架构的嵌入式DSP软件设计 Multicore a System-on-a-Chip (SoC) Architecture SoCs的软件开发涉及到基于最强大的计算模型在各种处理 ...

  4. vivado SOC——hello word(上)建立SOC系统

    引言 本节为了熟悉vivado的SOC使用,由于我也是开始学,所以请一起学的人点评指点. 软件:vivado 2016.4 板子:米联客701A mini 开发板介绍 创建工程 选择ZYNQ的型号和封 ...

  5. 5W无线充发射IC芯片方案XPM7105、XPM7305 无线充SOC芯片

    FS68001A是泛海微推出的一款无线充电发射端控制SoC芯片, 兼容 WPC Qi v1.2.4 最新标准,支持 A11线圈, 支持 5W .苹果 5W .三星 5W充电 .只需要一个SOP8的主控 ...

  6. 嵌入式学习(二)之SoC芯片的开发流程

    SoC芯片的开发流程 SoC芯片开发流程大致分为四个阶段,其中大部分工作都是借助于电子设计自动化(EDA)工具完成的. 总体设计 总体设计阶段的任务是按照系统需求说明书确定SoC的性能参数,并据此进行 ...

  7. 2.4G SOC芯片CI2451/CI2454应用于遥控玩具汽车的应用方案

    Ci2451 是一款集成无线收发器和 8 位 RISC(精简指令集)MCU 的 SOC 芯片. 优点:超低睡眠功耗,极少外围器件,降低系统应用成本,拥有精简指令集架构,可以很容易做编程和控制.   主 ...

  8. ASR6601:国产M4内核LoRa SoC芯片替代SX1262/SX1278

    目录 LoRa简介 ASR6601关键特性 ASR6601 Soc及LPWAN原理图 ASR6601开发环境搭建与编译下载 ASR6601硬件设计注意事项 ASR6601SE 测试板 LoRa简介 L ...

  9. 蓝牙室内定位,SOC芯片NRF52832

    本次就来深入分析下Nordic的最新蓝牙芯片nRF52832. 目前有很多的芯片原厂发布了自己的BLE SoC芯片,其中NORDIC半导体的nRF52832是知名的nRF51822的后续作品,它将BL ...

最新文章

  1. Linux软件安装包中devel与非devel包之间的区别
  2. CSharpGL(22)实现顺序无关的半透明渲染(Order-Independent-Transparency)
  3. js作用域及作用域链概念理解及使用
  4. .Net Core添加分布式Session
  5. java怎么看具体被挂起的线程_Java线程的挂起、恢复和终止
  6. scp连接计算节点操作
  7. 浅析神经网络为什么能够无限逼近任意连续函数
  8. Windows中查看端口占用情况
  9. cpu是32位的 这指的是数据总线还是地址总线是32条?另外,电脑操作系统是3位的这指的是什么意思?指令是32...
  10. 批处理批量更改文件名并排序
  11. Louvain算法在反作弊上的应用
  12. C++MFC实现win10标准计算器
  13. 机器学习_高偏差(High bias)与高方差(High vars)
  14. Vue3.0调用PC端本地摄像头录像
  15. 计算机本科生优秀毕业论文,本科毕业论文计算机
  16. 资源暂时不可用错误(Out of memery)完美解决方案
  17. 怎么释放mysql连接_数据库连接释放问题
  18. Mysql为什么使用B+树(一)之红黑树简述
  19. 渡阡科技Edu——梦开始的地方
  20. vue项目模拟后台数据

热门文章

  1. cordova打印机插件_phonegap/cordova plugin
  2. 第二章 davinci 大数据分析平台 安装
  3. gcc的-g,-o,-c,-D,-w,-W,-Wall,-O3等参数的意义
  4. MATLAB概率分布函数
  5. flutter 使用百度定位进行定位以及配置
  6. 安装Navicat时出现Missing required library libmysql_e.dll,126报错解决方法
  7. 前端html小技巧—input标签详解
  8. 织梦dedecms - 织梦5.7版本后台去除版权
  9. 企企通携手塑料新材料行业龙头【佛塑科技】,以数字化采购引领行业转型升级
  10. leetcode 875. 爱吃香蕉的珂珂