您的位置:首页 > 其它

从零移植uboot 2017 到nuc970(第二天)

2017-03-02 18:34 423 查看
第二天继续

首先看,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

我还是目的为了移植我新塘的板子上,没必要过分追究细节,我的主要任务也不是这个。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  移植 u-boot