uboot——start_armboot——init_sequence——board_init

board_init函数的作用:

1.对时钟进行初始化

2.对GPIO进行初始化

3.设置arch number和boot params的地址

4.使能数据缓存和指令缓存


代码的位置:

kangear-u-boot-2009.11\board\tekkamanninja\mini2440\mini2440.c

/*
 * Miscellaneous platform dependent initialisations
 */

int board_init (void)
{
	struct s3c24x0_clock_power * const clk_power =
					s3c24x0_get_base_clock_power();
	struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();

	/* to reduce PLL lock time, adjust the LOCKTIME register */
	clk_power->LOCKTIME = 0xFFFFFF;

	/* configure MPLL */
	clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);

	/* some delay between MPLL and UPLL */
	delay (4000);

	/* configure UPLL */
	clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);

	/* some delay between MPLL and UPLL */
	delay (8000);

	/* set up the I/O ports */
	gpio->GPACON = 0x007FFFFF;

#if defined(CONFIG_MINI2440) 
	gpio->GPBCON = 0x00295551;
#else
	gpio->GPBCON = 0x00044556;
#endif

	gpio->GPBUP = 0x000007FF;

#if defined(CONFIG_MINI2440) 
	gpio->GPCCON = 0xAAAAA6AA;
	gpio->GPCDAT &= ~(1<<5);
#else
	gpio->GPCCON = 0xAAAAAAAA;
#endif
	gpio->GPCUP = 0xFFFFFFFF;
	gpio->GPDCON = 0xAAAAAAAA;
	gpio->GPDUP = 0xFFFFFFFF;

    gpio->GPECON = 0xAAAAAAAA;
	gpio->GPEUP = 0x0000FFFF;
	gpio->GPFCON = 0x000055AA;
	gpio->GPFUP = 0x000000FF;
	gpio->GPGCON = 0xFF95FF3A;
	gpio->GPGUP = 0x0000FFFF;
	gpio->GPHCON = 0x0016FAAA;
	gpio->GPHUP = 0x000007FF;

	gpio->EXTINT0=0x22222222;
	gpio->EXTINT1=0x22222222;
	gpio->EXTINT2=0x22222222;

#if defined(CONFIG_S3C2440)
/* arch number of S3C2440-Board */
	gd->bd->bi_arch_number = MACH_TYPE_MINI2440 ;
#endif


	/* adress of boot parameters */
	gd->bd->bi_boot_params = 0x30000100;

	icache_enable();
	dcache_enable();
#if	defined(CONFIG_MINI2440_LED)
	gpio->GPBDAT = 0x00000180;
#endif
	return 0;
}


分析代码

1.初始化时钟

首先定义了一个struct s3c24x0_clock_power结构体指针,该结构体类型定义在:
kangear-u-boot-2009.11\include\s3c24x0.h :
/* CLOCK & POWER MANAGEMENT (see S3C2400 manual chapter 6) */
/*                          (see S3C2410 manual chapter 7) */
struct s3c24x0_clock_power {
	S3C24X0_REG32	LOCKTIME;
	S3C24X0_REG32	MPLLCON;
	S3C24X0_REG32	UPLLCON;
	S3C24X0_REG32	CLKCON;
	S3C24X0_REG32	CLKSLOW;
	S3C24X0_REG32	CLKDIVN;
#if defined (CONFIG_S3C2440)
	S3C24X0_REG32	CAMDIVN;
#endif
};
每个结构体成员占4个字节。
struct s3c24x0_clock_power * const clk_power =
					s3c24x0_get_base_clock_power();
 该函数位于kangear-u-boot-2009.11\include\s3c2410.h,返回S3C24X0_CLOCK_POWER_BASE,是几个时钟寄存器的的起始地址。
static inline struct s3c24x0_clock_power *s3c24x0_get_base_clock_power(void)
{
	return (struct s3c24x0_clock_power *)S3C24X0_CLOCK_POWER_BASE;
}
 该宏位于kangear-u-boot-2009.11\include\s 3c2410.h
#define S3C24X0_CLOCK_POWER_BASE	0x4C000000
所以clk_power指向0x4C000000,接下来开始进行时钟方面的设置:
	/* to reduce PLL lock time, adjust the LOCKTIME register */
	clk_power->LOCKTIME = 0xFFFFFF;

	/* configure MPLL */
	clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);

	/* some delay between MPLL and UPLL */
	delay (4000);

	/* configure UPLL */
	clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);

	/* some delay between MPLL and UPLL */
	delay (8000);
数据手册上LOCKTIME的默认值是0xFFFFFFFF,这里的设置值是 0xFFFFFF。
然后设置MPLLCON
#if defined(CONFIG_S3C2440)
/* Fout = 405MHz */
#define M_MDIV 0x7f	
#define M_PDIV 0x2
#define M_SDIV 0x1
#endif
所以MDIV = 127,PDIV = 2,SDIV=1.
m = ( MDIV + 8 ) = 135, p = ( PDIV + 2 ) = 4, s = SDIV = 1,Fin = 12M
Mpll = ( 2 × m × Fin ) / ( p × 2s ) = 405M
即CPU运行在405MHz。
接下来设置UPLLCON,MPLLCON和UPLLCON的设置之间要有一些delay。
Upll的值算下来是48

2.对GPIO进行初始化

先看一下struct s3c24x0_gpio 结构体
/* I/O PORT (see manual chapter 9) */
struct s3c24x0_gpio {
#if defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)
	S3C24X0_REG32	GPACON;
	S3C24X0_REG32	GPADAT;
	S3C24X0_REG32	res1[2];
	S3C24X0_REG32	GPBCON;
	S3C24X0_REG32	GPBDAT;
	S3C24X0_REG32	GPBUP;
	S3C24X0_REG32	res2;
	S3C24X0_REG32	GPCCON;
	S3C24X0_REG32	GPCDAT;
	S3C24X0_REG32	GPCUP;
	S3C24X0_REG32	res3;
	S3C24X0_REG32	GPDCON;
	S3C24X0_REG32	GPDDAT;
	S3C24X0_REG32	GPDUP;
	S3C24X0_REG32	res4;
	S3C24X0_REG32	GPECON;
	S3C24X0_REG32	GPEDAT;
	S3C24X0_REG32	GPEUP;
	S3C24X0_REG32	res5;
	S3C24X0_REG32	GPFCON;
	S3C24X0_REG32	GPFDAT;
	S3C24X0_REG32	GPFUP;
	S3C24X0_REG32	res6;
	S3C24X0_REG32	GPGCON;
	S3C24X0_REG32	GPGDAT;
	S3C24X0_REG32	GPGUP;
	S3C24X0_REG32	res7;
	S3C24X0_REG32	GPHCON;
	S3C24X0_REG32	GPHDAT;
	S3C24X0_REG32	GPHUP;
	S3C24X0_REG32	res8;

	S3C24X0_REG32	MISCCR;
	S3C24X0_REG32	DCLKCON;
	S3C24X0_REG32	EXTINT0;
	S3C24X0_REG32	EXTINT1;
	S3C24X0_REG32	EXTINT2;
	S3C24X0_REG32	EINTFLT0;
	S3C24X0_REG32	EINTFLT1;
	S3C24X0_REG32	EINTFLT2;
	S3C24X0_REG32	EINTFLT3;
	S3C24X0_REG32	EINTMASK;
	S3C24X0_REG32	EINTPEND;
	S3C24X0_REG32	GSTATUS0;
	S3C24X0_REG32	GSTATUS1;
	S3C24X0_REG32	GSTATUS2;
	S3C24X0_REG32	GSTATUS3;
	S3C24X0_REG32	GSTATUS4;
#if defined (CONFIG_S3C2440)
	S3C24X0_REG32	res9[3];
	S3C24X0_REG32	MSLCON;
	S3C24X0_REG32	GPJCON;
	S3C24X0_REG32	GPJDAT;
	S3C24X0_REG32	GPJUP;

#endif
#endif
};
结构体指针gpio最后获得的值是0x56000000,指向GPIO所有寄存器中的第一个寄存器。
接下来是对GPIO寄存器的设置。
#if defined(CONFIG_MINI2440) 
	gpio->GPBCON = 0x00295551;
#else
	gpio->GPBCON = 0x00044556;
#endif

	gpio->GPBUP = 0x000007FF;

#if defined(CONFIG_MINI2440) 
	gpio->GPCCON = 0xAAAAA6AA;
	gpio->GPCDAT &= ~(1<<5);
#else
	gpio->GPCCON = 0xAAAAAAAA;
#endif
	gpio->GPCUP = 0xFFFFFFFF;
	gpio->GPDCON = 0xAAAAAAAA;
	gpio->GPDUP = 0xFFFFFFFF;

   <span style="white-space:pre">	</span>gpio->GPECON = 0xAAAAAAAA;
	gpio->GPEUP = 0x0000FFFF;
	gpio->GPFCON = 0x000055AA;
	gpio->GPFUP = 0x000000FF;
	gpio->GPGCON = 0xFF95FF3A;
	gpio->GPGUP = 0x0000FFFF;
	gpio->GPHCON = 0x0016FAAA;
	gpio->GPHUP = 0x000007FF;

	gpio->EXTINT0=0x22222222;
	gpio->EXTINT1=0x22222222;
	gpio->EXTINT2=0x22222222;

3.设置arch number和boot params的地址

#if defined(CONFIG_S3C2440)
/* arch number of S3C2440-Board */
	gd->bd->bi_arch_number = MACH_TYPE_MINI2440 ;
#endif
	/* adress of boot parameters */
	gd->bd->bi_boot_params = 0x30000100;
gd->bd->bi_arch_number是机器码,对于mini2440是1999
gd->bd->bi_boot_params 存放参数的地址,这些参数用来启动 Linux 内核

4.使能数据缓存和指令缓存

	icache_enable();
	dcache_enable();




















  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
uboot是一种常用的开源引导加载程序,用于嵌入式系统的引导启动。其中,board_init_r和board_init_f是uboot中的两个重要函数。 board_init_r函数是在uboot启动过程中执行的第一个函数。它负责执行一系列的初始化工作,例如初始化系统时钟、设置内存映射等。此函数被用于配置和初始化各个硬件模块,包括中断控制器、串口控制器、定时器等,以确保系统正常运行。该函数还读取并解析配置文件,加载设备树等操作,为后续的引导加载准备好必要的条件。 board_init_f函数是在board_init_r函数之后调用的。它用于进一步初始化系统,并执行一些与硬件相关的操作。例如,该函数可能会初始化网络接口、USB接口、存储设备等,并设置系统的默认环境变量。此外,board_init_f函数还负责将uboot的控制权交给操作系统的引导加载程序,从而完成uboot的使命。 通过调用board_init_r和board_init_f函数,uboot能够在系统启动时完成各种硬件的初始化和配置工作。这两个函数是uboot启动过程中的重要环节,确保系统能够顺利地加载操作系统并运行。同时,它们也为开发者提供了扩展uboot的接口,可以在这两个函数中添加自定义的初始化代码,以满足系统特定的需求。 总结来说,board_init_r和board_init_f是uboot中两个重要的函数,用于初始化和配置嵌入式系统的硬件,并为操作系统的加载做好准备。它们是uboot启动过程中不可或缺的一部分,保证系统的正常启动和运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值