本来应该说说kernel中的input子系统和上层的对应关系的,但是碰到了开机的一些问题,下定决心把这个过程搞清楚。
U-boot之前的SPL的启动暂且不提,我们从U-boot在上电后被SPL从NAND中拷贝至SDRAM,然后执行board_init_f 跳转到board_init_r开始。
u-boot里的流程大家可以通过打串口log来看。
u-boot\arch\arm\lib\board.c
void board_init_r(gd_t *id, ulong dest_addr)
{
//.....初始化设备
stdio_init(); /* get the devices list going.*/ 此中会初始化各种设备,包括LCD
do_cboot(NULL, 0, 1, NULL); // 进入启动函数。
}
u-boot\property\cmd_cboot.c
int do_cboot(cmd_tbl_t *cmdtp,int flag, int argc, char *const argv[])
{
uint32_t key_mode = 0;
uint32_t key_code = 0;
volatile int i;
if(argc > 2)
goto usage;
#ifdef CONFIG_AUTOBOOT
normal_mode(); //如果down的是autopoweron的uboot,这里会直接去正常开机
#endif
boot_pwr_check();
#ifndef CONFIG_SC8810
CHG_ShutDown();
if(charger_connected()){
mdelay(10);
CHG_TurnOn();
}else{
if(is_bat_low()){
printf("shut down again forlow battery\n");
power_down_devices();
while(1)
;
}
}
#else
CHG_Init();
if(is_bat_low()){
printf("shutdown again for low battery\n");
power_down_devices();
while(1)
;
} //根据sp8810.h里的LOW_BAT_VOL,如果电压低于3.5V,则直接power down
#endif
boot_pwr_check();
board_keypad_init(); //初始化键盘。
boot_pwr_check();
unsigned check_reboot_mode(void);
unsigned rst_mode= check_reboot_mode(); //获取寄存器里HW的rest标志位,得到当前的开机模式,此处主要是异常重启,恢复出厂设置,关机闹钟等(没有按power键导致的开机)
if(rst_mode == RECOVERY_MODE){
DBG("func: %s line: %d\n",__func__, __LINE__);
recovery_mode();
}
else if(rst_mode == FASTBOOT_MODE){
DBG("func: %s line: %d\n",__func__, __LINE__);
fastboot_mode();
}else if(rst_mode == NORMAL_MODE){
normal_mode();
}else if(rst_mode == ALARM_MODE &&alarm_flag_check()){
alarm_mode();
}else if(rst_mode == SLEEP_MODE){
sleep_mode();
}
#ifdef CONFIG_SC8810
// normal_mode();
#endif
DBG("func: %s line: %d\n",__func__, __LINE__);
int recovery_init(void);
int ret =0;
ret = recovery_init();
if(ret == 1){ //检查是否是recovery模式
DBG("func: %s line: %d\n",__func__, __LINE__);
recovery_mode();
}
//find the power up trigger
if(boot_pwr_check() >=get_pwr_key_cnt()){ //如果按power键的“次数”达标了,认为这个是一次长按事件
DBG("%s: power buttonpress\n", __FUNCTION__);
//go on to check other keys
mdelay(50);
for(i=0; i<10;i++){
key_code = board_key_scan(); //获取另外一个按键
if(key_code != KEY_RESERVED){
key_mode= check_key_boot(key_code);//查找对应的按键码对应的开机模式
if(key_mode!= 0)
break;
}
}
switch(key_mode){
case BOOT_FASTBOOT:
fastboot_mode();
break;
case BOOT_RECOVERY:
recovery_mode();
break;
case BOOT_UPDATE:
update_mode();
break;
case BOOT_CALIBRATE:
engtest_mode();
return; //back to normal boot
break;
case BOOT_DLOADER:
dloader_mode();
break;
default:
break;//如果是正常开机模式,因为没有
}
}
elseif(charger_connected()){
DBG("%s: chargerconnected\n", __FUNCTION__);
charge_mode(); //如果没有按power键,且插入了充电器,则进入充电模式
}else if(alarm_triggered() &&alarm_flag_check()){
DBG("%s: alarm triggered\n",__FUNCTION__);
alarm_mode(); //如果是闹钟触发导致的开机,则进入关机闹钟模式
}else{
calibration_detect(0);
//if calibrate success, it will here
DBG("%s: power done again\n",__FUNCTION__);
power_down_devices();
while(1)
;
}
if(argc == 1){
DBG("func: %s line:%d\n", __func__, __LINE__);
normal_mode(); //如果只按了power键。
return 1;
}
if(argc == 2){
DBG("func: %s line: %d\n", __func__,__LINE__);
if(strcmp(argv[1],"normal") == 0){
normal_mode(); //如果只按了power键
return 1;
}
DBG("func: %s line: %d\n", __func__,__LINE__);
if(strcmp(argv[1],"recovery") == 0){
recovery_mode();
return 1;
}
DBG("func: %s line: %d\n",__func__, __LINE__);
if(strcmp(argv[1],"fastboot")