zoukankan      html  css  js  c++  java
  • buildroot构建项目(八)--- u-boot 2017.11 适配开发板修改 5 ---- 系统启动初始化之五

      执行完 board_init_f 后,跳回到 crt0.S中继续执行汇编语言

    1     ldr    r0, [r9, #GD_START_ADDR_SP]    /* sp = gd->start_addr_sp,gd->start_addr_sp在fdt的初始位置 */
    2     bic    r0, r0, #7    /* 8-byte alignment for ABI compliance */
    3     mov    sp, r0      /* sp 指向 fdt 初始位置 */
    4     ldr    r9, [r9, #GD_BD]        /* r9 = gd->bd */
    5     sub    r9, r9, #GD_SIZE        /* new GD is below bd,r9 为 gd-t 的基地址 */
    6 
    7     adr    lr, here                /* 跳转到 here 处执行,gd->relocaddr = 0x3400 0000 */

      最后一句,跳转到here处去执行

    1 here:
    2 /*
    3  * now relocate vectors
    4  */
    5     bl    relocate_vectors            /* 重定向向量表 */
    

    一、relocate_vectors 重定向向量表

      relocate.S (archarmlib)  

      这一段主要是对前面所说的向量表进行重定向

     1     /*
     2      * Copy the relocated exception vectors to the
     3      * correct address
     4      * CP15 c1 V bit gives us the location of the vectors:
     5      * 0x00000000 or 0xFFFF0000.
     6      */
     7     ldr    r0, [r9, #GD_RELOCADDR]    /* r0 = gd->relocaddr。0x3400 0000 */
     8     /* 将 c1 的值读到 r2 寄存器中 */
     9     /* 主要是控制  bit[13]: V */
    10     /* 对于支持高端异常向量表的系统,本控制位控制向量表的位置 */
    11     /* 0 :选择低端异常中断向量 0x0~0x1c  */
    12     /* 1 :选择高端异常中断向量0xffff0000~ 0xffff001c */
    13     /* 对于不支持高端异常向量表的系统,读取时该位返回0,写入时忽略 */
    14     mrc    p15, 0, r2, c1, c0, 0    /* V bit (bit[13]) in CP15 c1 */
    15     /* ands 后面的 s 会影响CPSR状态的寄存器的标志位 */
    16     /* 若 相与的 结果为0,则CPSR的状态标志位 Z = 1;反之,Z = 0 */
    17     ands    r2, r2, #(1 << 13)  /* r2 寄存器和 0010 0000 0000 0000 按位与后存入r2中 */
    18     ldreq    r1, =0x00000000        /* If V=0,则Z=1,可执行 ldr指令 */
    19     ldrne    r1, =0xFFFF0000        /* If V=1,则Z=0,可执行 ldr */
    20     /* 将 r2 -- r8 以及 r10 传入相应的地址,每次传输之后递增R0指向的存储地址,因为是32位,每次递增的地址应该是4bytes */
    21     ldmia    r0!, {r2-r8,r10}    /* ldmia 多寄存器寻址指令, */
    22     stmia    r1!, {r2-r8,r10}    /* 将R2-R8 和 r10的数据存储到R1指向的地址上,R1值更新。 */
    23     ldmia    r0!, {r2-r8,r10}    
    24     stmia    r1!, {r2-r8,r10}
    25 #endif

    二、relocate_code

      here执行完后,跳回,执行下面的代码

    1     ldr    r0, [r9, #GD_RELOC_OFF]        /* r0 = gd->reloc_off,gd->reloc_off = gd->relocaddr */
    2     add    lr, lr, r0                  /* lr += r0,异常向量表的地址确定 */
    3     /* 重定向地址确定 */
    4     ldr    r0, [r9, #GD_RELOCADDR]        /* r0 = gd->relocaddr 为 0x3400 0000 - u-boot 大小,即在u-boot的起始地址处 */
    5     b    relocate_code               /* 重定向代码 */

      进入 relocate_code, relocate.S (archarmlib) 

     1 ENTRY(relocate_code)
     2     /* __image_copy_start 在u-boot.lds 文件中定义,为起始地址 0 */
     3     ldr    r1, =__image_copy_start    /* r1 <- SRC &__image_copy_start */
     4     /* subs 影响借位C标志, */
     5     subs    r4, r0, r1        /* r4 <- relocation offset ,r4 为重定向偏移量 */
     6     beq    relocate_done        /* skip relocation,C变为位为1则执行代码 */
     7     /* r2为需要重定位代码的结束地址,r2 - r1就是需要重定位代码长度了 */
     8     ldr    r2, =__image_copy_end    /* r2 <- SRC &__image_copy_end */
     9     
    10 /* 到现在为止,比较重要的几个寄存器的值为
    11  * r0 = gd->reloc_off,r0为重定位偏移量,本处也就是目标地址
    12  * r1 = __image_copy_start,r1为需要重定位代码当前的起始地址,也就是代码段的开始0
    13  * r4 = r0 - r1,r4为重定位的偏移值,偏移值减去0还是0
    14  * r2 =__image_copy_end,r2为需要重定位代码的结束地址,r2 - r1就是需要重定位代码长度了
    15  */ 
    16 copy_loop:
    17     /* 从源地址 [r1] 开始拷贝,pop到r10与r11里面,一次8个字节 */ 
    18     ldmia    r1!, {r10-r11}        /* copy from source address [r1]    */
    19     /* 拷贝到目标地址 [r0]    */
    20     stmia    r0!, {r10-r11}        /* copy to   target address [r0]    */
    21     /* 一直到 [r1] 等于 [r2], 说明代码拷贝结束    */
    22     cmp    r1, r2            /* until source end address [r2]    */
    23     blo    copy_loop
    24 
    25     /*
    26      * fix .rel.dyn relocations
    27      * 重定位修正
    28      */
    29     ldr    r2, =__rel_dyn_start    /* r2 <- SRC &__rel_dyn_start */
    30     ldr    r3, =__rel_dyn_end    /* r3 <- SRC &__rel_dyn_end */
    31 fixloop:
    32     ldmia    r2!, {r0-r1}        /* (r0,r1) <- (SRC location,fixup) */
    33     and    r1, r1, #0xff
    34     cmp    r1, #R_ARM_RELATIVE
    35     bne    fixnext
    36 
    37     /* relative fix: increase location by offset */
    38     add    r0, r0, r4
    39     ldr    r1, [r0]
    40     add    r1, r1, r4
    41     str    r1, [r0]
    42 fixnext:
    43     cmp    r2, r3
    44     blo    fixloop
    45 
    46 relocate_done:
    47 
    48 #ifdef __XSCALE__
    49     /*
    50      * On xscale, icache must be invalidated and write buffers drained,
    51      * even with cache disabled - 4.2.7 of xscale core developer's manual
    52      */
    53     mcr    p15, 0, r0, c7, c7, 0    /* invalidate icache */
    54     mcr    p15, 0, r0, c7, c10, 4    /* drain write buffer */
    55 #endif
    56 
    57     /* ARMv4- don't know bx lr but the assembler fails to see that */
    58 
    59 #ifdef __ARM_ARCH_4__
    60     mov    pc, lr
    61 #else
    62     bx    lr
    63 #endif
    64 
    65 ENDPROC(relocate_code)

      执行完后,跳回 crt0.S中继续执行

     1 /*
     2  * now relocate vectors
     3  */
     4     bl    relocate_vectors            /* 重定向向量表 */
     5     
     6 /* Set up final (full) environment */
     7     bl    c_runtime_cpu_setup    /* we still call old routine here */
     8 
     9 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FRAMEWORK)
    10 
    11     ldr    r0, =__bss_start    /* this is auto-relocated! */
    12     ldr    r1, =__bss_end        /* this is auto-relocated! */
    13     mov    r2, #0x00000000        /* prepare zero to clear BSS */
    14 
    15 clbss_l:cmp    r0, r1            /* while not at end of BSS */
    16     strlo    r2, [r0]        /* clear 32-bit BSS word */
    17     addlo    r0, r0, #4        /* move to next */
    18     blo    clbss_l
    19 
    20 #if ! defined(CONFIG_SPL_BUILD)
    21     /* 这两个函数可以自己实现,或者删除掉 */
    22     bl coloured_LED_init
    23     bl red_led_on
    24 #endif
    25     /* call board_init_r(gd_t *id, ulong dest_addr) */
    26     mov     r0, r9                  /* gd_t */
    27     ldr    r1, [r9, #GD_RELOCADDR]    /* dest_addr */
    28     /* call board_init_r */
    29     ldr    pc, =board_init_r    /* this is auto-relocated! */
    30     /* we should not return here. */
    31 #endif

      执行进入 board_init_r 中

    三、board_init_r

    1 void board_init_r(gd_t *new_gd, ulong dest_addr)
    2 {
    3     if (initcall_run_list(init_sequence_r))
    4         hang();
    5     /* NOTREACHED - run_main_loop() does not return */
    6     hang();
    7 }

      功能函数得实现都在 init_sequeuece_r 中

     1 static init_fnc_t init_sequence_r[] = {
     2     initr_trace,    /* 宏未定义,直接返回 0 */
     3     initr_reloc,    /* gd->flags = 1 */
     4     /* TODO: could x86/PPC have this also perhaps? */
     5 #ifdef CONFIG_ARM
     6     initr_caches,   /* 打印 :Caches not enabled ,暂时未实现*/
     7 #endif
     8     initr_reloc_global_data,    /* 宏未定义,直接返回 0 */
     9     initr_barrier,      /* 宏未定义,直接返回 0 */
    10     initr_malloc,       /* malloc 区分配 */
    11     initr_bootstage,    /* Needs malloc() but has its own timer */
    12     initr_console_record,   /* 终端记录 */
    13     bootstage_relocate,     /* 重定向启动阶段 */
    14 #if defined(CONFIG_ARM) || defined(CONFIG_NDS32)
    15     board_init,    /* Setup chipselects */
    16 #endif
    17     stdio_init_tables,  /* 设备表格初始化 */
    18     initr_serial,       /* 初始化串口,执行得是 Serial.c (driversserial) 得serial_initialize()*/
    19     initr_announce,     /* 打印 u-boot 运行信息 */
    20     INIT_FUNC_WATCHDOG_RESET
    21     power_init_board,   /* 执行得 board.c(common) 中得 */
    22 #ifdef CONFIG_MTD_NOR_FLASH
    23     initr_flash,        /* norflash 初始化 */
    24 #endif
    25     INIT_FUNC_WATCHDOG_RESET
    26 #ifdef CONFIG_CMD_NAND
    27     initr_nand,         /* nand flash 初始化 */
    28 #endif
    29     initr_env,          /* 环境变量初始化 */
    30     INIT_FUNC_WATCHDOG_RESET
    31     initr_secondary_cpu,    /* CPU第二阶段初始化,里面为空 */
    32     INIT_FUNC_WATCHDOG_RESET
    33     stdio_add_devices,  /* 宏未定义,里面执行为空 */
    34     initr_jumptable,    /* jumptable 初始化 */
    35     console_init_r,        /* fully init console as a device */
    36     INIT_FUNC_WATCHDOG_RESET
    37     interrupt_init,     /* 中断初始化 */
    38 #ifdef CONFIG_ARM
    39     initr_enable_interrupts,    /* 中断使能初始化 */
    40 #endif
    41     /* PPC has a udelay(20) here dating from 2002. Why? */
    42 #ifdef CONFIG_CMD_NET
    43     initr_ethaddr,      /* 网络地址初始化 */
    44 #endif
    45 #ifdef CONFIG_CMD_NET
    46     INIT_FUNC_WATCHDOG_RESET
    47     initr_net,      /* 网络初始化 */
    48 #endif
    49     run_main_loop,  /* 启动 内核 */
    50 };

      重新编译一下,编译OK了,制作补丁

      

      

  • 相关阅读:
    【转】ON_COMMAND ON_MESSAGE ON_NOTIFY区别与联系
    Eureka
    application.yml-mysql8
    sprigcloud
    springboot
    maven
    排序算法之基数排序
    排序算法之桶排序
    排序算法之计数排序
    排序算法之堆排序
  • 原文地址:https://www.cnblogs.com/kele-dad/p/8361815.html
Copyright © 2011-2022 走看看