MTK6735 lk流程分析
参考
http://blog.chinaunix.net/uid-27875-id-3913070.html
一.从preload跳转到lk,MTK的LK相当于UBOOT
preload跳转到LK,先进入bootable/bootloader/lk/arch/arm/crt0.S,然后再跳转到Main.c (bootable\bootloader\lk\kernel)的kmain函数
crt0.S. 此文件 把原有 Start.S 部分代码进行封装, 一般此文件无需修改. Start.S 中 最后一条执行代码 bl kmain 语句跳到此处运行
二.kmain函数
Main.c (bootable\bootloader\lk\kernel)
boot_time = get_timer(0); //得到时间
thread_init_early //Initialize threading system
/* initialize the run queues */
for (i=0; i < NUM_PRIORITIES; i++) //这里是NUM_PRIORITIES是32
list_initialize(&run_queue[i]); //初始化链表
/* initialize the thread list */
list_initialize(&thread_list);
/* create a thread to cover the current running state */
thread_t *t = &bootstrap_thread;
init_thread_struct(t, "bootstrap");
list_add_head(&thread_list, &t->thread_list_node); //把软件引导程序放入线程链表
arch_early_init
/* turn off the cache */
arch_disable_cache(UCACHE);
config_L2_size ///* config L2 cache and sram to its size */
arm_mmu_init(); //初始化MMU
platform_init_mmu_mappings //映射MMU
/* turn the cache back on */
arch_enable_cache(UCACHE);
// do any super early platform initialization
platform_early_init();
platform_init_interrupts //设置一些中断
mt_gic_dist_init
mt_gic_cpu_init
platform_early_init_timer //初始化timer
gpt_power_on
/* initialize the uart */
uart_init_early(); //设置串口
platform_k64_check //检测是否是64系统
mtk_wdt_init(); //初始化看门狗
//i2c init
i2c_hw_init(); //这里是空,preload已经做了
mtk_wdt_disable(); // WDT will be triggered when uncompressing linux image on FPGA
pmic_init(); //初始化PMIC,与preload一样
// deal with any static constructors
call_constructors(); //处理静态构造函数
// bring up the kernel heap
heap_init(); //堆初始化
// set the heap range
theheap.base = (void *)HEAP_START;
theheap.len = HEAP_LEN;
// initialize the free list
list_initialize(&theheap.free_list);
// create an initial free chunk
heap_insert_free_chunk(heap_create_free_chunk(theheap.base, theheap.len));
// initialize the threading system
thread_init(); //什么都没有做
// initialize the dpc system
dpc_init //数据处理初始化
event_init(&dpc_event, false, 0);
thread_resume(thread_create("dpc", &dpc_thread_routine, NULL, DPC_PRIORITY, DEFAULT_STACK_SIZE)); //唤醒dpc_thread,单独分析1
// initialize kernel timers
list_initialize(&timer_queue);
/* register for a periodic timer tick */
platform_set_periodic_timer(timer_tick, NULL, 10); /* 10ms */
// create a thread to complete system initialization
thread_resume(thread_create("bootstrap2", &bootstrap2, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); //单独分析,第二章
// enable interrupts
exit_critical_section();
critical_section_count--;
if (critical_section_count == 0)
arch_enable_ints();
// become the idle thread
thread_become_idle();
static int dpc_thread_routine(void *arg)
{
for (;;) {
event_wait(&dpc_event);
enter_critical_section();
struct dpc *dpc = list_remove_head_type(&dpc_list, struct dpc, node);
if (!dpc)
event_unsignal(&dpc_event);
exit_critical_section();
if (dpc) {
//dprintf("dpc calling %p, arg %p\n", dpc->cb, dpc->arg);
dpc->cb(dpc->arg);
free(dpc);
}
}
return 0;
}
三.bootstrap2
Main.c (bootable\bootloader\lk\kernel)
arch_init //为空
// initialize the rest of the platform
platform_init(); //单独分析platform_init();
target_init(); //空
apps_init
/* call all the init routines */
for (app = &__apps_start; app != &__apps_end; app++)
if (app->init)
app->init(app);
mt_boot_init
mt_boot_init
sec_ret = sec_func_init(3); //安全模块初始化
seclib_set_oemkey(g_oemkey, OEM_PUBK_SZ); //设置安全模块大小
if (g_boot_mode == FASTBOOT) //快速启动,单独分析1
goto fastboot;
sec_boot_check(0) //启动模式安全检查
/* Will not return */
boot_linux_from_storage();
switch(g_boot_mode)
case NORMAL_BOOT:
case META_BOOT:
case ADVMETA_BOOT:
case SW_REBOOT:
case ALARM_BOOT:
case KERNEL_POWER_OFF_CHARGING_BOOT:
case LOW_POWER_OFF_CHARGING_BOOT:
strlen += sprintf(commandline, "%s%s%x%s%x",
commandline, NAND_MANF_CMDLINE, nand_flash_man_code, NAND_DEV_CMDLINE, nand_flash_dev_id); //命令行参数设置
mboot_android_load_bootimg_hdr("boot", CFG_BOOTIMG_LOAD_ADDR); //加载bootd的信息
mboot_android_load_bootimg("boot", kimg_load_addr); //加载boot的内容
case RECOVERY_BOOT:
mboot_android_load_recoveryimg_hdr("recovery", CFG_BOOTIMG_LOAD_ADDR);
mboot_android_load_recoveryimg("recovery", kimg_load_addr);
case FACTORY_BOOT:
case ATE_FACTORY_BOOT:
mboot_android_load_factoryimg_hdr(CFG_FACTORY_NAME, CFG_BOOTIMG_LOAD_ADDR);
mboot_android_load_bootimg_hdr("boot", CFG_BOOTIMG_LOAD_ADDR);
mboot_android_load_bootimg("boot", kimg_load_addr);
case FASTBOOT:
case DOWNLOAD_BOOT:
case UNKNOWN_BOOT:
break;
yl_params_read(YL_PRODUCTLINE, buf);
boot_linux((void *)g_boot_hdr->kernel_addr, (unsigned *)g_boot_hdr->tags_addr,
(char *)commanline, board_machtype(), (void *)g_boot_hdr->ramdisk_addr, g_rimg_sz); //启动内核
enter_critical_section
arch_disable_ints //关闭中断
/* do any platform specific cleanup before kernel entry */
platform_uninit();
leds_deinit(); //关闭led
platform_deinit_interrupts //清除中断
arch_disable_cache //关闭cache
arch_disable_mmu(); //关闭MMU
entry(0, machtype, tags); //进入内核
单独分析1
fastboot:
target_fastboot_init(); //空
target_get_max_flash_size(); //得到flash的大小
fastboot_init(target_get_scratch_address(), sz);
fastboot_register("getvar:", cmd_getvar, TRUE);
fastboot_publish("version", "0.5");
fastboot_register("signature", cmd_install_sig, FALSE);
。。。。。其他注册。。。。。
四. /单独分析platform_init();
platform_init();
vibr_Enable_HW(); //open Vibration;added by zhoumaiyun 2015.05.19,打开震动马达
mmc_legacy_init(1); //初始化mmc
err = mmc_init(id, MSDC_MODE_DEFAULT);
workqueue = alloc_ordered_workqueue("kmmcd", 0);
ret = mmc_register_bus();
ret = mmc_register_host_class();
ret = sdio_register_bus();
if((g_boot_arg->boot_reason == BR_USB) && (upmu_is_chr_det() == KAL_FALSE)) //如果是usb,但是不能充电
mt6575_power_off();
env_init //环境变量的初始化
ret = read_env_area(env_buffer);
print_env //打印环境初始化
g_fb_size = mt_disp_get_vram_size(); //得到显存大小
g_fb_base =mblock_reserve(&g_boot_arg->mblock_info, g_fb_size, 0x10000, 0x100000000, RANKMAX); //保留内存给显存
vibr_Disable_HW(); //close Vibration;added by zhoumaiyun 2015.05.19 ,关闭震动
mt_disp_init((void *)g_fb_base); //初始化显存
/* show black picture fisrtly in case of backlight is on before nothing is drawed*/
mt_disp_fill_rect(0, 0, CFG_DISPLAY_WIDTH, CFG_DISPLAY_HEIGHT, 0x0); //填充
mt_disp_update(0, 0, CFG_DISPLAY_WIDTH, CFG_DISPLAY_HEIGHT); //更新
drv_video_init //视频方面的初始化
video_lk_init
video_hw_init
video_set_cursor(CFB_ROW - 1, CFB_COL);
mboot_common_load_logo((unsigned long)mt_get_logo_db_addr_pa(), "logo"); //加载logo,logo_db_addr_pa是加载logo的地址
mboot_common_load_part("logo", logo_addr);
mt_part_get_device(); //得到显示设备
part = mt_part_get_partition(part_name); //得到分区
part_hdr = (part_hdr_t*)malloc(sizeof(part_hdr_t)); //分配内存
len = mboot_common_load_part_info(dev, part_name, part_hdr); //加载进内存
len = dev->read(dev, start_addr + sizeof(part_hdr_t), (uchar*)addr, part_hdr->info.dsize, part->part_id); //读取到显存
/*for kpd pmic mode setting*/
set_kpd_pmic_mode();
mtk_kpd_gpio_set();
boot_mode_select //选择启动模式,单独分析1
/* initialize security library */
sec_ret = sec_func_init(3);
seclib_set_oemkey(g_oemkey, OEM_PUBK_SZ); //设置
sec_logo_check() //检测logo
/*Show download logo & message on screen */
if (g_boot_arg->boot_mode == DOWNLOAD_BOOT) //如果是下载模式,单独分析2
mt65xx_bat_init //初始化电池,分析在preload和LK电源管理
if(kernel_charging_boot() == 1) //如果是充电启动模式
CHR_Type_num = hw_charging_get_charger_type();
if ((g_boot_mode != LOW_POWER_OFF_CHARGING_BOOT) || ((CHR_Type_num != STANDARD_HOST) && (CHR_Type_num != NONSTANDARD_CHARGER))) //如果不是低电量充电启动
mt_disp_power(TRUE); //显示设备上电
mt_disp_show_low_charge(); //显示低电量logo
mt65xx_leds_brightness_set(6, 110); //设置亮度
else if(g_boot_mode != KERNEL_POWER_OFF_CHARGING_BOOT && g_boot_mode != LOW_POWER_OFF_CHARGING_BOOT) //如果不是充电启动
if (g_boot_mode != ALARM_BOOT && (g_boot_mode != FASTBOOT))
这是什么都不做
if(!is_low_battery(0)) //如果电池不是低电量
mt65xx_backlight_on(); //开背光
单独分析1
boot_mode_select //选择启动模式
/*We put conditions here to filer some cases that can not do key detection*/
if (kedump_mini) {
return;
meta_detection //如果不是NORMAL_BOOT,返回
/*Check RTC to know if system want to reboot to Fastboot*/
if(Check_RTC_PDN1_bit13())
g_boot_mode = FASTBOOT;
/*Check RTC to know if system want to reboot to Recovery*/
if(Check_RTC_Recovery_Mode())
g_boot_mode = RECOVERY_BOOT;
yl_params_read(YL_PRODUCTLINE, buf);
panic_read(YL_DYNAMIC, buf);
FST_flag = buf[0x10];
if(FST_flag)
if(g_boot_arg->boot_reason == BR_USB || g_boot_arg->boot_reason == BR_WDT)
g_boot_mode = KERNEL_POWER_OFF_CHARGING_BOOT;
if((Cloud_flag == 0 || Cloud_flag == 0x30) && (RP_flag == 0))
g_boot_mode = FACTORY_BOOT; //fastmmi mode
key_val = mtk_detect_key(MT65XX_FACTORY_KEY)<<1 | mtk_detect_key(MT65XX_RECOVERY_KEY);
switch(key_val)
case 1: g_boot_mode = RECOVERY_BOOT;
case 2: g_boot_mode = FACTORY_BOOT;
case 3: g_boot_mode = FASTBOOT;
if(kernel_power_off_charging_detection()) //检测是不是关机充电模式
off_mode_status = get_off_mode_charge_status();
if(upmu_is_chr_det() == KAL_TRUE)
if (off_mode_status)
g_boot_mode = KERNEL_POWER_OFF_CHARGING_BOOT;
else
g_boot_mode = NORMAL_BOOT;
单独分析2
if (g_boot_arg->boot_mode == DOWNLOAD_BOOT) //如果是下载模式
/* verify da before jumping to da*/
if (sec_usbdl_enabled()) //usb使能
sec_usbdl_verify_da(da_addr, (da_len - sig_len), sig_addr, sig_len) //证明这个da
mt_disp_show_boot_logo(); //显示logo,Show first boot logo when phone boot up
init_fb_screen();
fill_animation_logo(BOOT_LOGO_INDEX, mt_get_fb_addr(), mt_get_tempfb_addr(), logo_addr, phical_screen);
mt_disp_update(0, 0, CFG_DISPLAY_WIDTH, CFG_DISPLAY_HEIGHT);
mt65xx_backlight_on //亮背光
mt65xx_leds_brightness_set(MT65XX_LED_TYPE_LCD, backlight_level);
mtk_wdt_disable(); //Disable wdt before jump to DA
platform_uninit
platform_deinit_interrupts //对中断反初始化
arch_disable_cache(UCACHE); //关闭缓存
arch_disable_mmu(); //关闭MMU
jump_da(g_boot_arg->da_info.addr, g_boot_arg->da_info.arg1, g_boot_arg->da_info.arg2);