TI OMAP平台BSP学习笔记之 - UBOOT(2)

本文详细介绍了TI OMAP平台的UBoot启动流程,包括代码分析、board detect和UBoot的执行步骤。在代码流程中,重点讲解了从lowlevel_init到board_init_f再到board_init_r的过程。board detect部分阐述了如何根据IC和Board版本信息识别硬件。在UBoot部分,讨论了常见bootargs和启动参数解析。文章适合嵌入式开发人员了解TI OMAP平台的启动机制。
摘要由CSDN通过智能技术生成

1. 代码流程分析

  1.     前面已经知道由于UBOOT同时编译两个镜像,代码有一部分重叠复用,需要关注CONFIG_SPL_BUILD宏控;
  2.     嵌入式中代码的逻辑通常是board->machine -> ARCH -> CPU,在UBOOT中的接口使用类似于重载的概念,使用WEAK修饰;比如在CPU定义一个API并用WEAK修饰,在board中可以重新定义该API并且覆盖前述API,而不会报错;
  3.     重点关注几个惯例API,如lowlevel_init, board_init_f, board_init_r等等;

    以编译am57xx_evm_config为例分析。首先看arch/arm/lib/Makefile

ifdef CONFIG_CPU_V7M
obj-y	+= vectors_m.o crt0.o
else ifdef CONFIG_ARM64
obj-y	+= crt0_64.o
else
obj-y	+= vectors.o crt0.o
endif

   我们并没有定义CONFIG_CPU_V7M,所以vectors.S和crt0.S被编译进我们的镜像;其中还会有ifndef CONFIG_SPL_BUILD的定义,即在UBOOT中才会被编译的镜像比如relocate等。而在ectors.S中会定义中断向量表,略过异常处理的中断处理暂不考虑,由于CONFIG_ARCH_K3没有定义,正常重启的处理是reset。

        .macro ARM_VECTORS
#ifdef CONFIG_ARCH_K3
	ldr     pc, _reset
#else
	b	reset
#endif
	ldr	pc, _undefined_instruction
	ldr	pc, _software_interrupt
	ldr	pc, _prefetch_abort
	ldr	pc, _data_abort
	ldr	pc, _not_used
	ldr	pc, _irq
	ldr	pc, _fiq
	.endm

    找到reset的定义,该代码入口位于 arch/arm/cpu/armv7/start.S,同样是查看其中的makefile

reset:
	/* Allow the board to save important registers */
	b	save_boot_params
save_boot_params_ret:
#ifdef CONFIG_ARMV7_LPAE
/*
 * check for Hypervisor support
 */
	mrc	p15, 0, r0, c0, c1, 1		@ read ID_PFR1
	and	r0, r0, #CPUID_ARM_VIRT_MASK	@ mask virtualization bits
	cmp	r0, #(1 << CPUID_ARM_VIRT_SHIFT)
	beq	switch_to_hypervisor
switch_to_hypervisor_ret:
#endif
	/*
	 * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
	 * except if in HYP mode already
	 */
	mrs	r0, cpsr
	and	r1, r0, #0x1f		@ mask mode bits
	teq	r1, #0x1a		@ test for HYP mode
	bicne	r0, r0, #0x1f		@ clear all mode bits
	orrne	r0, r0, #0x13		@ set SVC mode
	orr	r0, r0, #0xc0		@ disable FIQ and IRQ
	msr	cpsr,r0

/*
 * Setup vector:
 * (OMAP4 spl TEXT_BASE is not 32 byte aligned.
 * Continue to use ROM code vector only in OMAP4 spl)
 */
#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
	/* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */
	mrc	p15, 0, r0, c1, c0, 0	@ Read CP15 SCTLR Register
	bic	r0, #CR_V		@ V = 0
	mcr	p15, 0, r0, c1, c0, 0	@ Write CP15 SCTLR Register

#ifdef CONFIG_HAS_VBAR
	/* Set vector address in CP15 VBAR register */
	ldr	r0, =_start
	mcr	p15, 0, r0, c12, c0, 0	@Set VBAR
#endif
#endif

	/* the mask ROM code should have PLL and others stable */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
#ifdef CONFIG_CPU_V7A
	bl	cpu_init_cp15
#endif
#ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY
	bl	cpu_init_crit
#endif
#endif

	bl	_main
  1.   save_boot_params,保存ROM code中的parameters(有开机原因等);
  2.   switch_to_hypervisor, 切到hypervisor模式
  3.   cp15协处理器初始化,之后就可以使能MMU等功能;cpu_init_crit 初始化;这两个会调用到板级的定义中。在其中会调用lowlevel_init; lowlevel init设置临时stack,gdata 等;CONFIG_CPU_V7A被定义
  4.   bl _main

    前面的过程暂不具体学习,直接到_main函数,这时又回到crt0.S中; _main是一个通用函数,其中通过CONFIG_SPL_BUILD宏控区分SPL和UBOOT。

    头文件定义include/config.h

/* Automatically generated - do not edit */
#define CONFIG_BOARDDIR board/ti/am57xx
#include <config_defaults.h>
#include <config_uncmd_spl.h>
#include <configs/am57xx_evm.h>
#include <asm/config.h>
#include <linux/kconfig.h>
#include <config_fallbacks.h>

    _main最开始的部分:

    调用 board_init_f_alloc_reserve 和 board_init_f_init_reserve 分配并初始化GD; 设置堆栈等C环境,并最终从汇编世界切到C的世界。关于GD,global data,在系统启动

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值