zoukankan      html  css  js  c++  java
  • buildroot构建项目(三)--- u-boot 2017.11 适配开发板修改 1

      当前虽然编译成功了,但是对于我们自己的目标板并不太适用。还得做一系列得修改。

    一、lds 文件分析

      u-boot 中最重要得链接文件即是,u-boot.lds。我们可以查看我们编译出来得 u-boot.lds 文件进行分析,原始文件在 arch/arm/cpu/ 下,编译出来得去掉了不想关得选项。

      u-boot.lds脚本文件告诉链接器linker如何布局代码段、数据段、bss段等,已经配置了u-boot自拷贝(从flash到RAM的copy)的内容。另外,还简要的涉及了动态链接技术等。

      1 /* 指定输出的可执行文件 elf 格式,32位,小端  */
      2 OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
      3 /* 指定输出可执行文件的平台为 arm */
      4 OUTPUT_ARCH(arm)
      5 /* 指定输出可执行文件的起始代码段为_start */
      6 ENTRY(_start)
      7 /* 指定可执行文件的全局入口点,通常这个地址都放在ROM(flash)0x0位置。
      8  * 必须使编译器知道这个地址 */
      9 SECTIONS
     10 {
     11     /* 从0x0位置开始  */
     12  . = 0x00000000;
     13     /* 代码以4字节对齐 */
     14  . = ALIGN(4);
     15     /* 代码段 */
     16  .text :
     17  {
     18         /* u-boot将自己copy到RAM,此为需要copy的程序的start */
     19   *(.__image_copy_start)
     20         /* ./arch/arm/lib/vectors.S,异常向量表 */
     21   *(.vectors)
     22         /* ./arch/arm/cpu/arm920t/start.S */
     23   arch/arm/cpu/arm920t/start.o (.text*)
     24         /* 其他的代码段放在这里,即 start.S/vector.S 之后 */
     25   *(.text*)
     26  }
     27     /* 代码段结束后,有可能4bytes不对齐了,此时做好4bytes对齐,以开始后面的.rodata段 */
     28  . = ALIGN(4);
     29     /* 在代码段之后,存放read only数据段 */
     30  .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
     31     /* 4bytes对齐,以开始接下来的.data段 */
     32  . = ALIGN(4);
     33     /* 可读写数据段 */
     34  .data : {
     35   *(.data*)
     36  }
     37     /* 4字节对齐 */
     38  . = ALIGN(4);
     39     /* 当前地址为4字节对齐后的地址 */
     40  . = .;
     41     /* 4字节对齐 */
     42  . = ALIGN(4);
     43     /* .data段结束后,紧接着存放u-boot自有的一些function,例如u-boot command等 */
     44  .u_boot_list : {
     45   KEEP(*(SORT(.u_boot_list*)));
     46  }
     47  . = ALIGN(4);
     48     /* UEFI支持,  */
     49  .__efi_runtime_start : {
     50   *(.__efi_runtime_start)
     51  }
     52     /*  */
     53  .efi_runtime : {
     54   *(efi_runtime_text)
     55   *(efi_runtime_data)
     56  }
     57     /* */
     58  .__efi_runtime_stop : {
     59   *(.__efi_runtime_stop)
     60  }
     61     /*  */
     62  .efi_runtime_rel_start :
     63  {
     64   *(.__efi_runtime_rel_start)
     65  }
     66     /* */
     67  .efi_runtime_rel : {
     68   *(.relefi_runtime_text)
     69   *(.relefi_runtime_data)
     70  }
     71     /* UEFI结束  */
     72  .efi_runtime_rel_stop :
     73  {
     74   *(.__efi_runtime_rel_stop)
     75  }
     76     /* 4字节对齐  */
     77  . = ALIGN(4);
     78     /* 至此,u-boot需要自拷贝的内容结束,总结一下,包括代码段,数据段,以及u_boot_list */
     79  .image_copy_end :
     80  {
     81   *(.__image_copy_end)
     82  }
     83     /* 在老的uboot中,如果我们想要uboot启动后把自己拷贝到内存中的某个地方,只要把要拷贝的地址写给TEXT_BASE即可,
     84      * 然后boot启动后就会把自己拷贝到TEXT_BASE内的地址处运行,在拷贝之前的代码都是相对的,不能出现绝对的跳转,否则会跑飞。
     85      * 在新版的uboot里,TEXT_BASE的含义改变了。它表示用户要把这段代码加载到哪里,通常是通过串口等工具。
     86      * 然后搬移的时候由uboot自己计算一个地址来进行搬移。新版的uboot采用了动态链接技术,在lds文件中有__rel_dyn_start和__rel_dyn_end,
     87      * 这两个符号之间的区域存放着动态链接符号,只要给这里面的符号加上一定的偏移,拷贝到内存中代码的后面相应的位置处,
     88      * 就可以在绝对跳转中找到正确的函数。 */
     89  .rel_dyn_start :
     90  {
     91   *(.__rel_dyn_start)
     92  }
     93     /* 动态链接符存放在的段 */
     94  .rel.dyn : {
     95   *(.rel*)
     96  }
     97     /* 动态链接符段结束 */
     98  .rel_dyn_end :
     99  {
    100   *(.__rel_dyn_end)
    101  }
    102  .end :
    103  {
    104   *(.__end)
    105  }
    106     /* bin文件结束 */
    107  _image_binary_end = .;
    108  . = ALIGN(4096);
    109  .mmutable : {
    110   *(.mmutable)
    111  }
    112  
    113     /* .bss节包含了程序中所有未初始化的全局变量 */
    114  .bss_start __rel_dyn_start (OVERLAY) : {
    115   KEEP(*(.__bss_start));
    116   __bss_base = .;
    117  }
    118  .bss __bss_base (OVERLAY) : {
    119   *(.bss*)
    120    . = ALIGN(4);
    121    __bss_limit = .;
    122  }
    123     /* bss段结束 */
    124  .bss_end __bss_limit (OVERLAY) : {
    125   KEEP(*(.__bss_end));
    126  }
    127 
    128  .dynsym _image_binary_end : { *(.dynsym) }
    129  .dynbss : { *(.dynbss) }
    130  .dynstr : { *(.dynstr*) }
    131  .dynamic : { *(.dynamic*) }
    132  .plt : { *(.plt*) }
    133  .interp : { *(.interp*) }
    134  .gnu.hash : { *(.gnu.hash) }
    135  .gnu : { *(.gnu*) }
    136  .ARM.exidx : { *(.ARM.exidx*) }
    137  .gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) }
    138 }

    二、norflash 介绍

      ARM的启动都是从0地址开始,所不同的是地址的映射不一样。在 arm 上电的时候,要想让 arm 知道以某种方式(地址映射方式)运行,不可能通过你写的某段程序控制,因为这时候你的程序还没启动,这时候arm会通过引脚的电平来判断。

    2.1 硬件

    2.1.1 存储器地址

      s3c2440  的存储器控制器为访问外部存储的需要器提供了存储器控制信号。 存储器控制器的地址空间总共有 8 个 bank,每个bank  为128M,总共为1G。除了 BANK016/32 位)之外,其它全部 BANK 都可编程访问位宽(8/16/32 位)

    • 8 个存储器 Bank
      • 6 个存储器 Bank ROMSRAM
      • 其余 2 个存储器 Bank ROMSRAMSDRAM
      • 7 个固定的存储器 Bank 起始地址
      • 1 个可变的存储器 Bank 起始地址并 Bank 大小可编程
      • 所有存储器 Bank 的访问周期可编程

      

    • OM管脚是使能NAND Flash 的管脚,当OM=00时,是表示使用  NAND Flash 为引导 ROM。
    • nGCS0 为片选信号控制
    • 0x0000_0000 这些为存储器地址。
    • BANK 6 BANK 7 必须为相同的存储器大小

    2.1.2 OM管脚

      OM有两个管脚,用来控制存储器。

      

      BANK0nGCS0)的数据总线应当配置为 16 位或 32 位的宽度。因为 BANK0 是作为引导 ROM bank(映射到 0x0000_0000),应当在第一个 ROM 访问前决定 BANK0 的总线宽度,其依赖于复位时 OM[1:0]的逻辑电平。

    2.1.3 存储器概念

    • SDRAM(Synchronous Dynamic Random Access Memory):同步动态随机存取存储器,
      • 同步是指Memory工作需要步时钟,内部的命令的发送与数据的传输都以它为基准;
      • 动态是指存储阵列需要不断的刷新来保证数据不丢失;
      • 随机是指数据不是线性依次存储,而是由指定地址进行数据读写,简单的说,它就是cpu使用的外部内存,即我们常说的内存条。
      • 主要用于程序执行时的程序存储、执行或计算
    • SRAM是英文Static RAM的缩写,它是一种具有静止存取功能的内存,不需要刷新电路即能保存它内部存储的数据,速度比SDRAM快,一般用作高速缓冲存储器(Cache)。
    • norflash:非易失闪存,是一种外部存储介质,芯片内执行(XIP,eXecute In Place),这样应用程序可以直接在flash闪存内运行,不必再把代码读到系统RAM中,
      • 由于它有地址总线,cpu可以直接从norflash中取指,直接从FLASH中运行程序,但是工艺复杂,价格比较贵,容量较小(1~4M),NOR的传输效率很高,擦初和写操作效率很低
    • nandflash:它也是非易失闪存(掉电不丢失)的一种,但是它虽然有数据总线,但是没有地址总线,所以cpu不能直接从nandflash中取指运行,由于它价格便宜,所以常常用来存储大量数据,和我们常说的硬盘类似。

    2.2 norflash 启动

    • S3C2440的启动时读取的第一条指令是在0x00上,分别为nand flash和nor flash上启动。
    • Nor flash的有自己的地址线和数据线,可以采用类似于memory的随机访问方式,在nor flash上可以直接运行程序,所以nor flash可以直接用来做 boot,采用 nor flash 启动的时候会把地址映射到 0x00 上。  
    • 任何flash器件的写入操作只能在空或已擦除的单元内进行
      • 擦除NOR器件时是以64~128KB的块进行的,执行一个写入/擦除操作的时间为5s,NORFLASHSECTOR擦除时间视品牌、大小不同而不同,比如,4MFLASH,有的SECTOR擦除时间为60ms,而有的需要最大6S 
    • Nand flash是IO设备,数据、地址、控制线都是共用的,需要软件区控制读取时序,所以不能像nor flash、内存一样随机访问,不能EIP(片上运行),因此不能直接作为boot。
    • 在u-boot 启动中,需要把 程序拷贝到 SDRAM中去运行,也可以不用拷贝。
    • nor 启动的时候,CPU的0地址就指向 norflash

      

    2.2.1 norflash 电路

      运行的目标开发板为  JZ2440 开发板。norflash 型号为 MX29LV160DBTI,16M存储空间,

      

    2.2.2 代码修改

      

      

      

  • 相关阅读:
    安装VMtools vim编辑器的使用 压缩包命令 Linux下的用户管理 (第三天)
    VM虚拟机安装 常用Linux命令 网卡配置 (第二天)
    数据库的交互模式 常用的dos命令 (第一天)
    Validate US Telephone Numbers FreeCodeCamp
    Arguments Optional FreeCodeCamp
    Everything Be True FreeCodeCamp
    Binary Agents FreeCodeCamp
    Steamroller FreeCodeCamp
    Drop it FreeCodeCamp
    Smallest Common Multiple FreeCodeCamp
  • 原文地址:https://www.cnblogs.com/kele-dad/p/8290310.html
Copyright © 2011-2022 走看看