/*初始化IRQ/FIQ模式的栈*/
int cpu_init (void)
{
return 0;
}
/*初始化网口,设置机器码及标记启动参数起始地址*/
int board_init(void)
{
/*#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8") DECLARE_GLOBAL_DATA_PTR定义一个gd_t全局数据结构的指针,这个指针存放在指定的寄存器r8中。这个声明也避免编译器把r8分配给其它的变量。任何想要访问全局数据区的代码,只要代码开头加入“DECLARE_GLOBAL_DATA_PTR”一行代码,然后就可以使用gd指针来访问全局数据区了 */
DECLARE_GLOBAL_DATA_PTR;
dm9000_pre_init();//初始化函数
gd->bd->bi_arch_number = MACH_TYPE;//机器码,要与内核arch/arm/tools/mach_types中定义相同
gd->bd->bi_boot_params = (PHYS_SDRAM_1+0x100);//启动参数标记列表在RAM中的起始地址
return 0;
}
/*初始化定时器4为系统时钟,使用timer4来作为系统clock, 即时钟滴答,10ms一次,到点就产生一个中断*/
int interrupt_init(void)
{
S5PC11X_TIMERS *const timers = S5PC11X_GetBase_TIMERS(); // timer位PWM寄存器数组,并指定起始地址即timers = 0xE2500000
/* use PWM Timer 4 because it has no output */
/* prescaler for Timer 4 is 16 */
timers->TCFG0 = 0x0f00; //设置预分频值为16
if (timer_load_val == 0) {
/*
* for 10 ms clock period @ PCLK with 4 bit divider = 1/2
* (default) and prescaler = 16. Should be 10390
* @33.25MHz and @ 66 MHz
*/
timer_load_val = get_PCLK() / (16 * 100); //#define __REG(x) (*(vu_long *)(x))取出X地址内的值,设置Timer Input Clock Frequency
}
/* load value for 10 ms timeout */
lastdec = timers->TCNTB4 = timer_load_val;
/* auto load, manual update of Timer 4 */
timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO | TCON_4_UPDATE;
/* auto load, start Timer 4 */
timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO | COUNT_4_ON;
timestamp = 0;
return (0);
}
/*检查FLASH上环境参数是否有效*/.
int env_init(void)
{
size_t total;
int crc1_ok = 0, crc2_ok = 0;
env_t *tmp_env1, *tmp_env2;
total = CFG_ENV_SIZE; //0x4000,环境变量大小
tmp_env1 = env_ptr; //tmp_env1指向environment[0]起始地址
tmp_env2 = (env_t *)((ulong)env_ptr + CFG_ENV_SIZE); // tmp_env2指向environment[0]起始地址+0x4000地址处
crc1_ok = (crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc);
crc2_ok = (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc);
if (!crc1_ok && !crc2_ok)
gd->env_valid = 0;
else if(crc1_ok && !crc2_ok)
gd->env_valid = 1;
else if(!crc1_ok && crc2_ok)
gd->env_valid = 2;
else {
/* both ok - check serial */
if(tmp_env1->flags == 255 && tmp_env2->flags == 0)
gd->env_valid = 2;
else if(tmp_env2->flags == 255 && tmp_env1->flags == 0)
gd->env_valid = 1;
else if(tmp_env1->flags > tmp_env2->flags)
gd->env_valid = 1;
else if(tmp_env2->flags > tmp_env1->flags)
gd->env_valid = 2;
else /* flags are equal - almost impossible */
gd->env_valid = 1;
}
if (gd->env_valid == 1)
env_ptr = tmp_env1;
else if (gd->env_valid == 2)
env_ptr = tmp_env2;
return (0);
}
/*串口模特率设置*/
static int init_baudrate (void)
{
char tmp[64]; /* long enough for environment variables */
int i = getenv_r ("baudrate", tmp, sizeof (tmp)); //从环境中取字符串,获取环境变量的值,即将字符串baudrate的值存储在tmp中,i为得到的环境变量的长度
/*将波特率的值存储进gd->bd->bi_baudrate 与gd->baudrate 中*/
gd->bd->bi_baudrate = gd->baudrate = (i > 0) ? (int) simple_strtoul (tmp, NULL, 10) : CONFIG_BAUDRATE;
return (0);
}
/*串口初始化,此处没有做任何设置,猜测是因为之前已经初始化了串口*/
int serial_init(void)
{
serial_setbrg();
return (0);
}
void serial_setbrg(void)
{
DECLARE_GLOBAL_DATA_PTR;
int i;
for (i = 0; i < 100; i++);
}
/* Called before relocation - use serial functions,将串口初始化标志置1 */
int console_init_f (void)
{
gd->have_console = 1;
return (0);
}
/* 打印u-boot信息*/
static int display_banner (void)
{
/*version_string=U_BOOT_VERSION" (" __DATE__ " - " __TIME__ ")"CONFIG_IDENT_STRING;即打印出U-Boot 1.1.5 (Sep 22 2008 - 12:30:34),DATE为编译的日期,TIME为编译的时间*/
printf ("\n\n%s\n\n", version_string);
debug ("U-Boot code: %08lX -> %08lX BSS: -> %08lX\n",
_armboot_start, _bss_start, _bss_end);
debug("\t\bMalloc and Stack is above the U-Boot Code.\n");
return (0);
}
/*打印CPU信息*/
int print_cpuinfo(void)
{
uint set_speed;
uint tmp;
uchar result_set;
set_speed = 100000;
tmp = (set_speed / (get_ARMCLK()/1000000));
if((tmp < 105) && (tmp > 95)){
result_set = 1;
} else {
result_set = 0;
}
printf("\nCPU: S5PV210@%ldMHz(%s)\n", get_ARMCLK()/1000000, ((result_set == 1) ? "OK" : "FAIL"));
#if 1
printf(" MPLL = %ldMHz, EPLL = %ldMHz\n",
get_MPLL_CLK()/1000000, get_PLLCLK(EPLL)/1000000);
printf(" HclkDsys = %ldMHz, PclkDsys = %ldMHz\n",
get_HCLKD()/1000000, get_PCLKD()/1000000);
printf(" HclkPsys = %ldMHz, PclkPsys = %ldMHz\n",
get_HCLKP()/1000000, get_PCLKP()/1000000);
printf(" SCLKA2M = %ldMHz\n", get_SCLKA2M()/1000000);
#endif
puts("Serial = CLKUART ");
return 0;
}
/*初始化I2C*/
static int init_func_i2c (void)
{
puts ("I2C: ");
i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
puts ("ready\n");
return (0);
}
/*检测系统内存映射*/
int dram_init(void)
{
DECLARE_GLOBAL_DATA_PTR;
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
#if defined(PHYS_SDRAM_2)
gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
#endif
return 0;
}
/*打印内存信息*/
static int display_dram_config (void)
{
int i;
#ifdef DEBUG
puts ("RAM Configuration:\n");
for(i=0; i<CONFIG_NR_DRAM_BANKS; i++) {
printf ("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start);
print_size (gd->bd->bi_dram[i].size, "\n");
}
for (i=0; i<CONFIG_NR_DRAM_BANKS; i++) {
size += gd->bd->bi_dram[i].size;
}
#endif
return (0);
}