从零移植uboot 2017 到nuc970(第二天)
2017-03-02 18:34
423 查看
第二天继续
首先看,arch/arm/cpu/arm926se.x/start.S
这里穿插下 主目录的makefile 找到边查边学,需要看GUN官网的make手册来确定不了解的语法
首先从make help中得到这个defconfig - New config with default from ARCH supplied defconfig
所以前后呼应,要是想制作自己定制的UBOOT,在/include/configs/中建立自己的.h文件,这样再看makefile中一定有这样的实现
机制
# for commands that shall be hidden in non-verbose mode.第一个作用就不说了,非重要性作用,并不影响移植,但可能对于
错误的定位比较关键。其实就是回显功能
在找MAKE的时候并没有发现MAKEFILE中的定义,所以一定是built-in variable
事实果然是这样的
The value of this variable is the file name with which make was invoked. If this file name was /bin/make, then the recipe executed is ‘cd subdir && /bin/make’.
If you use a special version of make to run the top-level makefile, the same special version will be executed for recursive invocations.
显然makefile如同shell一样的叠层感觉,再看build 我在哪里都没有找到,我个人推测是其他地方Include进来的,所以先不管啦,以后的记录有解释
bl lowlevel_init /* go setup pll,mux,memory */将会是非常重要的地方
但是这个函数来自哪里呢,#include <common.h>中没有相关的定义,所以一定是其他文件中,这个可以想象到和硬件相关 因为英文说了 建立pll ,mux ,memory,
所以去/broad找找看。
随便一个arm架构的,就三星的smdk52xx吧,发现了汇编文件
1.关狗,
2.初始化sram
3.关中断并清中断标志位
下面就是调到_main 这可是重中之重,
/arch/arm/crt0.S
这里还是要问自己一些概念sram.sdram dram ddr的区别?
第一天没必要过分追究细节,主要把握几个关键点。
1.在调用b_i_f前的准备工作,其是内嵌sram所以不需要任何更改。
2.在调用b_i_f时,其使用init_sequence_f这个结构体,存储了函数指针来调用一系列的初始化函数。注意spl和非spl是有区别的
3.之后立即建立过渡环境,堆栈和gd会到sdram中。
4.搬移代码到dram中
5.建立最终的环境调用board_init_r(),其中也是通过init_sequence_r执行一系列函数,其中这里面肯定有大量需要个人定制修改参数的函数board_init initr_flash initr_nand,等等
其中最后一个run_main_loop.
在回顾一遍 README中提到的概念,上述分析了非spl段的情况,且不完全。
今天到这里吧,我自己的分析和逻辑判断就到这里,俗话说想更快的成功,必须站在巨人的肩膀上,晚上就是总结,和当网上查看别人解析的uboot
我还是目的为了移植我新塘的板子上,没必要过分追究细节,我的主要任务也不是这个。
首先看,arch/arm/cpu/arm926se.x/start.S
#include <config.h> //首先包含了这个,要清楚是哪里产生的。这是include目录的.config也是自动产生的
//区别于主目录下由make xx_defconfig产生的.config ************************************************************************* * * Startup Code (reset vector) * * do important init only if we don't start from memory! * setup Memory and board specific bits prior to relocation. * relocate armboot to ram * setup stack * ************************************************************************* */ .globl reset //这里要注意,start.S中看到的只是reset之后的代码,也就是上电复位的第一条执行代码
//但是绝不是代表reset的代码位于0地址。 reset: /* * set the cpu to SVC32 mode */ mrs r0,cpsr bic r0,r0,#0x1f orr r0,r0,#0xd3 msr cpsr,r0 /* * we do sys-critical inits only at reboot, * not when booting from ram! */ #ifndef CONFIG_SKIP_LOWLEVEL_INIT bl cpu_init_crit #endif bl _main /*------------------------------------------------------------------------------*/ .globl c_runtime_cpu_setup c_runtime_cpu_setup: bx lr /* cpu_init_crit: /* * flush D cache before disabling it */ mov r0, #0 flush_dcache: mrc p15, 0, r15, c7, c10, 3 bne flush_dcache mcr p15, 0, r0, c8, c7, 0 /* invalidate TLB */ mcr p15, 0, r0, c7, c5, 0 /* invalidate I Cache */ /* * disable MMU and D cache * enable I cache if CONFIG_SYS_ICACHE_OFF is not defined */ mrc p15, 0, r0, c1, c0, 0 bic r0, r0, #0x00000300 /* clear bits 9:8 (---- --RS) */ bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */ #ifdef CONFIG_SYS_EXCEPTION_VECTORS_HIGH orr r0, r0, #0x00002000 /* set bit 13 (--V- ----) */ #else bic r0, r0, #0x00002000 /* clear bit 13 (--V- ----) */ #endif orr r0, r0, #0x00000002 /* set bit 1 (A) Align */ #ifndef CONFIG_SYS_ICACHE_OFF orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */ #endif mcr p15, 0, r0, c1, c0, 0 #ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY /* * Go setup Memory and board specific bits prior to relocation. */ mov ip, lr /* perserve link reg across call */ bl lowlevel_init /* go setup pll,mux,memory */ mov lr, ip /* restore link */ #endif mov pc, lr /* back to my caller */ #endif /* CONFIG_SKIP_LOWLEVEL_INIT */非常简洁,config.h中的CONFIG_SKIP_LOWLEVEL_INIT,将决定是否初始化cpu
这里穿插下 主目录的makefile 找到边查边学,需要看GUN官网的make手册来确定不了解的语法
首先从make help中得到这个defconfig - New config with default from ARCH supplied defconfig
所以前后呼应,要是想制作自己定制的UBOOT,在/include/configs/中建立自己的.h文件,这样再看makefile中一定有这样的实现
机制
%config: scripts_basic outputmakefile FORCE $(Q)$(MAKE) $(build)=scripts/kconfig $@首先由浅入深,# A simple variant is to prefix commands with $(Q) - that's useful
# for commands that shall be hidden in non-verbose mode.第一个作用就不说了,非重要性作用,并不影响移植,但可能对于
错误的定位比较关键。其实就是回显功能
在找MAKE的时候并没有发现MAKEFILE中的定义,所以一定是built-in variable
事实果然是这样的
The value of this variable is the file name with which make was invoked. If this file name was /bin/make, then the recipe executed is ‘cd subdir && /bin/make’.
If you use a special version of make to run the top-level makefile, the same special version will be executed for recursive invocations.
显然makefile如同shell一样的叠层感觉,再看build 我在哪里都没有找到,我个人推测是其他地方Include进来的,所以先不管啦,以后的记录有解释
bl lowlevel_init /* go setup pll,mux,memory */将会是非常重要的地方
但是这个函数来自哪里呢,#include <common.h>中没有相关的定义,所以一定是其他文件中,这个可以想象到和硬件相关 因为英文说了 建立pll ,mux ,memory,
所以去/broad找找看。
随便一个arm架构的,就三星的smdk52xx吧,发现了汇编文件
lowlevel_init: mov r9, lr /* r5 has always zero */ mov r5, #0 ldr r8, =S5PC100_GPIO_BASE /* Disable Watchdog */ ldr r0, =S5PC100_WATCHDOG_BASE @0xEA200000 orr r0, r0, #0x0 str r5, [r0] /* setting SRAM */ ldr r0, =S5PC100_SROMC_BASE ldr r1, =0x9 str r1, [r0] /* S5PC100 has 3 groups of interrupt sources */ ldr r0, =S5PC100_VIC0_BASE @0xE4000000 ldr r1, =S5PC100_VIC1_BASE @0xE4000000 ldr r2, =S5PC100_VIC2_BASE @0xE4000000 /* Disable all interrupts (VIC0, VIC1 and VIC2) */ mvn r3, #0x0 str r3, [r0, #0x14] @INTENCLEAR str r3, [r1, #0x14] @INTENCLEAR str r3, [r2, #0x14] @INTENCLEAR /* Set all interrupts as IRQ */ str r5, [r0, #0xc] @INTSELECT str r5, [r1, #0xc] @INTSELECT str r5, [r2, #0xc] @INTSELECT /* Pending Interrupt Clear */ str r5, [r0, #0xf00] @INTADDRESS str r5, [r1, #0xf00] @INTADDRESS str r5, [r2, #0xf00] @INTADDRESS很显然是一系列底层初始化,而且值得注意的是,这个时候位于sram中,
1.关狗,
2.初始化sram
3.关中断并清中断标志位
下面就是调到_main 这可是重中之重,
/arch/arm/crt0.S
这里还是要问自己一些概念sram.sdram dram ddr的区别?
* This file handles the target-independent stages of the U-Boot * start-up where a C runtime environment is needed. Its entry point * is _main and is branched into from the target's start.S file. * * _main execution sequence is: * 1. Set up initial environment for calling board_init_f(). * This environment only provides a stack and a place to store * the GD ('global data') structure, both located in some readily * available RAM (SRAM, locked cache...). In this context, VARIABLE * global data, initialized or not (BSS), are UNAVAILABLE; only * CONSTANT initialized data are available. GD should be zeroed * before board_init_f() is called. * * 2. Call board_init_f(). This function prepares the hardware for * execution from system RAM (DRAM, DDR...) As system RAM may not * be available yet, , board_init_f() must use the current GD to * store any data which must be passed on to later stages. These * data include the relocation destination, the future stack, and * the future GD location. * 3. Set up intermediate environment where the stack and GD are the * ones allocated by board_init_f() in system RAM, but BSS and * initialized non-const data are still not available. * * 4a.For U-Boot proper (not SPL), call relocate_code(). This function * relocates U-Boot from its current location into the relocation * destination computed by board_init_f(). * * 4b.For SPL, board_init_f() just returns (to crt0). There is no * code relocation in SPL. * * 5. Set up final environment for calling board_init_r(). This * environment has BSS (initialized to 0), initialized non-const * data (initialized to their intended value), and stack in system * RAM (for SPL moving the stack and GD into RAM is optional - see * CONFIG_SPL_STACK_R). GD has retained values set by board_init_f(). * * 6. For U-Boot proper (not SPL), some CPUs have some work left to do * at this point regarding memory, so call c_runtime_cpu_setup. * * 7. Branch to board_init_r(). * * For more information see 'Board Initialisation Flow in README.
/* * Set up initial C runtime environment and call board_init_f(0). */ #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK) ldr sp, =(CONFIG_SPL_STACK) #else ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) #endif #if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC destination */ mov r3, sp bic r3 4000 , r3, #7 mov sp, r3 #else bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ #endif mov r0, sp bl board_init_f_alloc_reserve mov sp, r0 /* set up gd here, outside any C code */ mov r9, r0 bl board_init_f_init_reserve mov r0, #0 bl board_init_f这里我注重看最后调用c函数,所以必须要有stack,
第一天没必要过分追究细节,主要把握几个关键点。
1.在调用b_i_f前的准备工作,其是内嵌sram所以不需要任何更改。
2.在调用b_i_f时,其使用init_sequence_f这个结构体,存储了函数指针来调用一系列的初始化函数。注意spl和非spl是有区别的
3.之后立即建立过渡环境,堆栈和gd会到sdram中。
4.搬移代码到dram中
5.建立最终的环境调用board_init_r(),其中也是通过init_sequence_r执行一系列函数,其中这里面肯定有大量需要个人定制修改参数的函数board_init initr_flash initr_nand,等等
其中最后一个run_main_loop.
在回顾一遍 README中提到的概念,上述分析了非spl段的情况,且不完全。
今天到这里吧,我自己的分析和逻辑判断就到这里,俗话说想更快的成功,必须站在巨人的肩膀上,晚上就是总结,和当网上查看别人解析的uboot
我还是目的为了移植我新塘的板子上,没必要过分追究细节,我的主要任务也不是这个。
相关文章推荐
- 从零移植uboot 2017 到nuc970(第九天)
- 从零移植uboot 2017 到nuc970(第十二天)
- 从零移植uboot 2017 到nuc970(第六天)
- 从零移植uboot 2017 到nuc970(第七天)
- 从零移植uboot 2017 到nuc970(第八天)
- 从零移植uboot 2017 到nuc970(第二十三天)(第一阶段结束)
- 从零移植uboot 2017 到nuc970(第十七天)
- 从零移植uboot 2017 到nuc970(第一天)
- 从零移植uboot 2017 到nuc970(第三天)
- 从零移植uboot 2017 到nuc970(第四天)
- 从零移植uboot 2017 到nuc970(第五天)
- 从零移植uboot 2017 到nuc970(第二十一天)
- 从零移植uboot 2017 到nuc970(第十一天)
- 从零移植uboot 2017 到nuc970(第十三天)
- 从零移植uboot 2017 到nuc970(第二十天)
- 从零移植uboot 2017 到nuc970(第十天)
- 从零移植uboot 2017 到nuc970(第二十二天)
- 从零移植uboot 2017 到nuc970(第十四天)
- 从零移植uboot 2017 到nuc970(第十五天)
- 从零移植uboot 2017 到nuc970(第十六天)