Board.c
· #ifdefined(CONFIG_ARCH_CPU_INIT)
· arch_cpu_init,
· #endif
· board_init,
· #ifdefined(CONFIG_USE_IRQ)
· interrupt_init,
· #endif
· timer_init,
· #ifdef CONFIG_FSL_ESDHC
· get_clocks,
· #endif
· env_init,
· init_baudrate,
· serial_init,
· console_init_f,
· display_banner,
· #if defined(CONFIG_DISPLAY_CPUINFO)
· print_cpuinfo,
· #endif
· #if defined(CONFIG_DISPLAY_BOARDINFO)
· checkboard,
· #endif
· dram_init,
· arch_usb_init,
· NULL,
· };
//入口
· void start_armboot (unsigned *pRunning, unsigned startup_flag, unsigned resume_code)
· {
· init_fnc_t ** init_fnc_ptr; /*双重指针*/
· 全局数据变量分配空间
· gd = (gd_t*)(_armboot_start – CONFIG_BOOTHEAD_GAP
· - CONFIG_SYS_MALLOC_LEN – sizeof(gd_t));
/*先在内存中为gd_t分配了空间,然后让前面定义的gd指针指向它的首地址*/
· /* 接着也分配了bd_t结构体的空间,这个空间在gd_t之下,然后将gd_t中的bd指针赋值为它的首地址。*/
·
· memset ((void*)gd, 0, sizeof (gd_t));
//开发板的数据变量 分配空间
· gd->bd =(bd_t*)((char*)gd-sizeof(bd_t));
· memset(gd->bd,0,sizeof (bd_t));
· insert_ddr_layout((unsigned int)gd->bd,
· (unsigned int)((char *)gd+sizeof(gd_t)),"globaldata");
· gd->flags|=GD_FLG_RELOC;
//结构体 具体内容
gd 全局数据变量指针,它保存了u-boot运行需要的全局数据,类型定义:
Typedef struct global_data {
bd_t *bd; //board data pointor 开发板数据指针
unsigned long flags; //指示标志,如设备已经初始化标志等。
unsigned long baudrate; //串口波特率
unsigned long have_console; /* 串口初始化标志*/
unsigned long reloc_off;
/* 重定位偏移,就是实际定向的位置与编译连接时指定的位置之差,一般为0 */
unsigned long env_addr; /* 环境参数地址*/
unsigned long env_valid; /* 环境参数CRC检验有效标志 */
unsigned long fb_base; /* base address of frame buffer */
#ifdef CONFIG_VFD
unsigned char vfd_type; /* display type */
#endif
void **jt; /* 跳转表,函数调用地址登记 */
} gd_t;
typedef struct bd_info {
int bi_baudrate /* 串口波特率 */
unsigned long bi_ip_addr; /* IP 地址 */
unsigned char bi_enetaddr[6]; /* MAC地址*/
struct environment_s *bi_env;
ulong bi_arch_number; /* unique id for this board */
ulong bi_boot_params; /* 启动参数 */
struct /* RAM 配置 */
{
ulong start;
ulong size;
}bi_dram[CONFIG_NR_DRAM_BANKS];
} bd_t;
· /*init_sequence就是一个双重指针*/
· /*init_fnc_t *init_sequence[]*/
· /* *init_fnc_ptr是判断函数指针是否存在*/
· /*++init_fnc_ptr是指向数组的下一个元素,即指向下一个函数指针*/
· for (init_fnc_ptr =init_sequence;*init_fnc_ptr; ++init_fnc_ptr){
· if ((*init_fnc_ptr)() != 0) { /*用双重函数指针调用数组中的这些函数*/
· hang ();/*如果函数返回为非0,则调用hang()
· }
· }
//设置GPIO
HI_DRV_GPIO_Init();
· /* for USB power off,GPIO9_3*/
· HI_DRV_GPIO_SetDirBit(75, 0);
· HI_DRV_GPIO_WriteBit(75,0);
· /* for SATA power off ,GPIO10_4*/
· HI_DRV_GPIO_SetDirBit(84, 0);
· HI_DRV_GPIO_WriteBit(84,0);
....
· ReSwitch:
· switch (startup_flag & 0xff)
· {
· case 0xce: /* recovery */
· udelay (1000000); //1000ms
· HI_DRV_GPIO_ReadBit(47,&power_detect);
· if(power_detect == 0){
· printf(". Mode RECOVERY\n.\n");
· standby_before_get_kernel(1); //待机
· recovery_flag = 0x87921111;
· break;
· }else{
· printf(". Mode FAKE RECOVERY, Go On with COLD RESET!\n.\n");
· startup_flag = 0xbb;
· goto ReSwitch;
· }
·
· case 0xba: /*resume*/
· printf(".mode %s\n.\n",pRunning<0xf0000000?"RESUME":"GO FROM RAM");
· startmce_before_boot_kernel();
· break;
·
· case 0xbb: /* cold reset*/
· //printf("g_runnning_addr=%p\n", g_running_addr);
· printf(".mode%s\n.\n",pRunning>0xf0000000?"COLD RESET":"ROM XMODEM");
· standby_before_get_kernel(pRunning<0xf0000000);
· break;
·
· case 0xbc: /*power off*/
· printf(".Mode POWER OFF\n.\n");
· standby_before_get_kernel(0);
· break;
·
· case 0xbd: /*usb updatefail*/
· printf(".Mode UPDATE FAIL\n.\n");
· HI_DRV_GPIO_WriteBit(42,0);//5_2
· HI_DRV_GPIO_WriteBit(44,1);//5_4
· HI_DRV_GPIO_WriteBit(72,1);//9_0
· for (;;);
· break;
·
· case 0xbe:/* usb update success */
· printf(". Mode UPDATED\n.\n");
· HI_DRV_GPIO_WriteBit(42,0);
· HI_DRV_GPIO_WriteBit(44,1);
· HI_DRV_GPIO_WriteBit(73,1);
· for(;;);
· break;
·
· default:
· hang();
· }
env_relocate();
drv_vfd_init();
serial_initialize();
gd->bd->bi_ip_addr=getenv_IPaddr("ipaddr"); //IP地址
enable_interrupts();
· if((s=getenv("loadaddr"))!=NULL) {
· load_addr = simple_strtoul (s, NULL,16); /*内核加载地址*/
· }
eth_initialize(gd->bd);
//初始化网卡,这之前,全局变量区已经从保存好了ip地址和mac地址
#ifdef CONFIG_PRODUCT_WITH_BOOT
fastapp_entry(0, NULL);
#endif
show_boot_env();
· for (;;) {
· main_loop (); /*进入main_loop()函数准备启动内核*/
· }
· void hang (void)
· {
· puts ("### ERROR ### Please RESET the board###\n");
· for(;;);
· }
· static void startmce_before_boot_kernel()
· {
·
· size=MCU_CODE_MAXSIZE;
· dwPtr= (unsigned int*)(0xf8400000);
· for(i=0;i<(size>>2);i++)
· {
· *(volatile unsigned int *)(dwPtr + I) = lu32vC51Code2[i];
/*加载单片机程序*/
· }
·
...
· //Set GPIO port param
· *(volatile unsigned int *)(dwPtr+24) = gpio_port;
· ...
· //单片机启动 CPU休眠
· ret= readl(0xf840f000); 8051 Local RAM
· ret |=0x1;
· writel(ret,0xf840f000);
· }
· static void standby_before_get_kernel (unsigned set_code_only)
· {
·
·
· for(i = 0; I < (size >> 2);i++)
· {
· *(volatile unsigned int *)(dwPtr + I) = lu32vC51Code[i];
/*加载单片机程序*/
· }
·
·
· //设置IR的参数
· *(volatile unsigned int *)(dwPtr+10) = irtype;
· *(volatile unsigned int *)(dwPtr+11) = irpmocnum;
· for(i = 0;i < irpmocnum; i++)
· {
· *(volatile unsigned int *)(dwPtr+12 + 2*i) = irVallow[i];
· *(volatile unsigned int *)(dwPtr+13 + 2*i) = irValhigh[i];
· }
· //GPIO 参数
· *(volatile unsigned int *)(dwPtr+24) = gpio_port;
· if (set_code_only)
· {
· printf("C51: code seted, go on booting ...\n");
· }
· else
· {
· printf("C51:Cortex-A9 is sleeping here.\n");
·
· //使能8051
· ret=readl(0xf840f000);
· ret|=0x1;
· writel(ret,0xf840f000);
· for (;;); //不会执行
· }
· }
//product/main.c
int fastapp_entry(int argc, char *argv[])
{
#ifdef HI_ANDROID_BOOT_SUPPORT
Android_Main(); //环境参数设置
#endif
#ifndef HI_ADVCA_SUPPORT
#ifdef HI_LOADER_SUPPORT
Loader_Main();
#else
HI_INFO_PRINT(HI_ID_SYS, "not support hisi loader!\n");
#endif
#endif
#ifdef HI_ADVCA_SUPPORT
c51_loadCode();
#endif
return 0;
}· #ifdefined(CONFIG_ARCH_CPU_I