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 (arch\arm\lib)

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

 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 (arch\arm\lib)

 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 (drivers\serial) 得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了,制作补丁

  

  

原文地址:https://www.cnblogs.com/kele-dad/p/8361815.html

时间: 2024-11-05 11:44:46

buildroot构建项目(八)--- u-boot 2017.11 适配开发板修改 5 ---- 系统启动初始化之五的相关文章

buildroot构建项目(五)--- u-boot 2017.11 适配开发板修改 4 ---- 系统启动初始化之三

一.内存控制器 在关闭了MMU和caches 之后 就进入lowlevel_init 函数,对内存控制器进行初始化.lowlevel_init.S (board\samsung\mini2440) 1.1 内存控制器介绍 前面已经看过这张表格了.从这张表格中可以看处,我们的程序代码,不管使用不使用 NAND Flash 都是从0地址开始启动,只不过使用 Nand flash 需要将前4K代码拷贝进 SRAM中去. 1.2 内存控制器的寄存器 1.2.1 总线宽度和等待控制寄存器 每一个 BANK

buildroot构建项目(七)--- u-boot 2017.11 适配开发板修改 4 ---- 系统启动初始化之四

设置完寄存器控制器后,则跳出cpu_init_crit,进入_main 函数.即进入crt0.S (arch\arm\lib)  跟着代码流程慢慢走 一.crt0.S 1.1 第一步执行代码 1 /* 预设堆栈指针为CONFIG_SYS_INIT_SP_ADDR */ 2 /* #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x1000 - GENERATED_GBL_DATA_SIZE) */ 3 /* #define CON

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 /

buildroot构建项目(一)---buildroot介绍

1.1 什么是buildroot Buildroot是Linux平台上一个构建嵌入式Linux系统的框架.整个Buildroot是由Makefile脚本和Kconfig配置文件构成的.你可以和编译Linux内核一样,通过buildroot配置,menuconfig修改,编译出一个完整的可以直接烧写到机器上运行的Linux系统软件(包含boot.kernel.rootfs以及rootfs中的各种库和应用程序). 下载:git clone git://git.buildroot.net/buildr

基于OpenConnect 构建的SSL VPN解决方案 2017/11/10

本文转载于灵跃云 :原文链接 1.写在前面 VPN(Virtual Private Network),虚拟专用网络,是一种通过公用网络安全地对企业内部专用网络进行远程访问的连接方式,可有效保障通信的机密性.如,出差办公人员可通过VPN通道安全地访问公司内部OA系统.发展至今的VPN同时融合了访问控制.路由选择.传输管理等多种功能,在全球的信息安全体系及各行业的信息系统中已发挥着重要作用. 常见的VPN主要有: ● PPTP VPN ● L2TP VPN ● IPSec VPN ● SSL VPN

iTOP-IMX6UL 实战项目:ssh 服务器移植到 arm 开发板

实验环境:迅为提供的Ubuntu12.04.2 以及虚拟机 编译器:arm-2009q3 编译器 开发板系统:QT系统 开发板使用手册中给Windows 系统安装了 ssh 客户端,给 Ubuntu 安装了 ssh 服务器,这样就可以通过ssh 在 Windows 和虚拟机 Ubuntu 之间传输文件.其实在开发 板上也是可以移植和安装ssh 服务器,这样就可以通过网络,在 Windows 和开发板之间传 输文件.“实战教程-ssh 服务器移植到开发板”,我们要完成的目标是能够通过 ssh 在开

构建 Zookeep + Dubbo + Spring Boot 的分布式调用项目(一)

一.写在前头 在开始构建前,默认你已经能够成功安装并启动 Zookeeper 注册中心,能够成功安装并启动 Dubbo 控制台: 在本例中,我的 Zookeeper 注册中心 IP 地址为 192.168.10.41,端口号为 4183,Dubbo 控制台的访问地址为 http://192.168.10.41:8080: 为了体现分布式调用,本例中创建了以下两个项目,dubbo-consumer 远程调用 dubbo-provider 提供的服务: dubbo-provider        

使用docker构建第一个spring boot项目

在看了一些简单的docker命令之后 打算自己尝试整合一下docker+spring boot项目本文是自己使用docker+spring boot 发布一个项目1.docker介绍 docke是提供简单易用的容器接口Docker 将应用程序与该程序的依赖,打包在一个文件里面.运行这个文件,就会生成一个虚拟容器.程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样.有了 Docker,就不用担心环境问题. 总体来说,Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入

Buildroot构建指南——根文件系统(Rootfs)

Buildroot构建指南--根文件系统(Rootfs) Buildroot的Rootfs构建流程有一个大框架,有些部分是Buildroot系统做好的,有些细节需要自己来实现,Rootfs也是Buildroot中最为复杂的部分. Rootfs的构建流程概述 Rootfs的构建流程如图1所示.其中浅色框中为Buildroot实现的框架,深紫色框为用户实现的脚本. Figure 1 Buildroot系统的rootfs制作 需要归纳的几点如下: 1.      新版buildroot已经把rootf