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);
                
 
    
            
       
 
 
 
 
 
 
 
 
 
    
        
posted @ 2020-11-25 10:52  luoyuna  阅读(1689)  评论(0编辑  收藏  举报