• u-boot移植(二)---修改前工作:代码流程分析1


    一、代码执行总体流程图

    1.1 代码路径 

    • U-boot.lds (archarmcpu) 

    • vectors.S (archarmlib) 

    • start.S (archarmcpuarm920t) 

    • lowlevel_init.S (boardsamsungjz2440) 

    • crt0.S (archarmlib)

    • relocate.S (archarmlib) 

    • Board_init.c (commoninit) 

    • Board_f.c (common) 

    • Jz2440.h (includeconfigs) 

    • Generic-asm-offsets.h (includegenerated) 

    1.2 启动代码流程图

      

    二、链接文件

      目录:u-boot-2017.03/arch/arm/cpu

      文件:u-boot.lds

      编写好的 .lds 文件,在用 arm-Linux-ld 连接命令时带 -Tfilename 来调用执行,如:arm-linux-ld-Tnand.lds x.o y.o -o xy.o

      也用-Ttext参数直接指定连接地址,如 arm-linux-ld-Ttext 0x30000000 x.o y.o -oxy.o

      既然程序有了两种地址,就涉及到一些跳转指令的区别。 
      ARM汇编中,常有两种跳转方法:b跳转指令、ldr指令向PC赋值。 
      要特别注意这两条指令的意思: 
      1> b step:b跳转指令是相对跳转,依赖当前PC的值,偏移量是通过该指令本身的bit[23:0]算出来的,这使得使用b指令的程序不依赖于要跳到的代码的位置,只看指令本身。 
      2> ldr pc, =board_init_r :该指令是一个伪指令编译后会生成以下代码:ldr pc, [pc, #8]

        从内存中的某个位置读出数据并赋给PC,同样依赖当前PC的值,所以可以用它实现从Flash到RAM的程序跳转。

      2种方式指明程序地址,这里分析下第二种方式,在根目录 Makefile文件有如下一行:

      

      在文件 include/configs/jz2440.h 有定义:

      

      我们在这里可以用下面的命令生成 u-boot.dis文件(注意交叉编译器的名字):

      arm-2440-linux-gnueabi-objdump -D -m arm u-boot > u-boot.dis

      

      在0 地址执行的是 _start.S文件,然后跳转到reset执行,接着定义异常向量表:

      

      在u-boot.lds 脚本中并没有指定基地址, 根目录下的 u-boot 脚本是由 arch/arm/cpu/u-boot.lds 在编译的时候生成的,所以如果要修改u-boot.lds 需要找到正确的地方。

      u-boot.lds 分析:  1 #include <config.h>

      2 /* 指定输出可执行文件是elf格式,32位ARM指令,小端模式  */
      3 OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
      4 OUTPUT_ARCH(arm) /* 指定输出文件的的平台体系为ARM */
      5 ENTRY(_start)    /* 指定可执行映像文件的起始段的段名是 _start,这里跳转到vector.S执行 */
      6 SECTIONS
      7 {
      8     /DISCARD/ : { *(.rel._secure*) }
      9     /* 指定可执行的 image 文件的全局入口点,通常这个地址都发给你法rom(flash)0x0位置。
     10      * 必须使编译器知道这个地址,一般不修改此处,而是修改其它地方的宏定义*/
     11     . = 0x00000000;
     12     . = ALIGN(4);
     13     .text :
     14     {
     15         /* 映像文件赋值起始地址,它在文件 arch/arm/lib/sections.c 中定义:
     16          * char __image_copy_start[0] __attribute__((section(".__image_copy_start")));*/
     17         *(.__image_copy_start)
     18         /* arch/arm/lib/vectors.S 里有一句:.section ".vectors"  */
     19         /* 这里的 vectors 是让vector.S 链接的二进制文件的开头部分 */
     20         *(.vectors)
     21         CPUDIR/start.o (.text*)        /* 执行 start.S */
     22         *(.text*)                    /* 其他代码 */
     23     }
     24 
     25     . = ALIGN(4);
     26     /* 只读数据段,所有的只读数据段都放在这个位置  */
     27     .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
     28 
     29     . = ALIGN(4);
     30     /* 可读写数据段,所有的可读写数据段都放在这个位置 */
     31     .data : {
     32         *(.data*)
     33     }
     34 
     35     . = ALIGN(4);
     36 
     37     . = .;
     38 
     39     . = ALIGN(4);
        /* U-BOOT命令段 */
    40 .u_boot_list : { 41 KEEP(*(SORT(.u_boot_list*))); 42 } 43 44 . = ALIGN(4); 45 46 .image_copy_end : 47 { 48 *(.__image_copy_end) 49 } 50
        /* 相对动态信息段 */ 51 .rel_dyn_start : 52 { 53 *(.__rel_dyn_start) 54 } 55 56 .rel.dyn : { 57 *(.rel*) 58 } 59 60 .rel_dyn_end : 61 { 62 *(.__rel_dyn_end) 63 } 64 65 .end : 66 { 67 *(.__end) 68 } 69 70 _image_binary_end = .; 71 72 /* 73 * Deprecated: this MMU section is used by pxa at present but 74 * should not be used by new boards/CPUs. 75 */ 76 . = ALIGN(4096); 77 .mmutable : { 78 *(.mmutable) 79 } 80 81 /* 82 * Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c 83 * __bss_base and __bss_limit are for linker only (overlay ordering)

         * bss段,里面放置的是初始值为0的全局变量和静态变量,这些变量不会保存在
            * 二进制文件中

     84  */
     85 
     86     .bss_start __rel_dyn_start (OVERLAY) : {
     87         KEEP(*(.__bss_start));
     88         __bss_base = .;
     89     }
     90 
     91     .bss __bss_base (OVERLAY) : {
     92         *(.bss*)
     93          . = ALIGN(4);
     94          __bss_limit = .;
     95     }
     96 
     97     .bss_end __bss_limit (OVERLAY) : {
     98         KEEP(*(.__bss_end));
     99     }
    100 
    101     .dynsym _image_binary_end : { *(.dynsym) }
    102     .dynbss : { *(.dynbss) }
    103     .dynstr : { *(.dynstr*) }
    104     .dynamic : { *(.dynamic*) }
    105     .plt : { *(.plt*) }
    106     .interp : { *(.interp*) }
    107     .gnu.hash : { *(.gnu.hash) }
    108     .gnu : { *(.gnu*) }
    109     .ARM.exidx : { *(.ARM.exidx*) }
    110     .gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) }
    111 }

      链接执行,首先是进入到arch/arm/vector.S 中执行,在其中执行 _start.S_start.S 的首行就跳转到 start.S 中的 reset 中去执行了。

      这里没有执行SPL,若要加上SPL,则还需要加上 nandflash 

      链接脚本暂时的流程为:

      

      跳转A处,A代码在Vector.S中,执行_start.S代码,下一节看 _start.S的代码,并分析其过程。

    备注:后续会更新此文档

  • 相关阅读:
    软件工程课程建议
    结对编程2
    结对编程---《四则运算》
    AVAudioPlayer播放音乐
    《问吧》需求分析
    有关结对编程的感想
    UItabBarController
    ViewController 视图控制器的常用方法
    <问吧>调查问卷心得体会
    UINavigationController导航控制器
  • 原文地址:https://www.cnblogs.com/kele-dad/p/6932034.html
Copyright © 2020-2023  润新知