本文转载自:http://blog.csdn.net/fang_first/article/details/49615631
====================基本知识=======================
LK是(L)ittle (K)ernel的缩写。
高通平台android普遍采用LK作为其bootloader,LK是一个开源项目。但是,LK只是整个系统的引导部分,所以它不是独立存在。LK是一个功能及其强大的bootloader,但现在只支持arm和x86平台。
LK的一个显著的特点就是它实现了一个简单的线程机制(thread),和对高通处理器的深度定制和使用。
====================源码架构=======================
app //主函数启动app执行的目录,第一个app在app/aboot/aboot.c中
arch //体系代码包含x86和arm
dev //设备目录,包含显示器,键盘,net,usb等设备的初始化代码
include //头文件
kernel //kernel/main.c主函数以及kernel/thread.c线程函数
lib //库文件
make //编译规则
platform //不同平台代码mdmxxx,msmxxx,apqxxx,qsdxxx,还有共享的目录msm_shared
project //整个工程的编译规则
target //通用init.c,具体目标板的初始化(主要为板子设备资源init.c代码中),编译规则代码(一级s810.mk二级hdc8094.mk)
====================程序执行流程============================
主函数lk/kernel/main.c
1 /* called from crt0.S */ 2 void kmain(void) __NO_RETURN __EXTERNALLY_VISIBLE; 3 void kmain(void) //从kmain函数开始执行 4 { 5 thread_init_early(); //线程初始化 6 arch_early_init(); //平台体系x86或者arm初始化,类似uboot的第一阶段汇编,在arch/arm下面实现 7 实现功能:关闭cache,设置异常向量,mmu初始化,打开cache 8 // do any super early platform initialization 9 platform_early_init();----> //开始涉及到具体平台 10 void platform_early_init(void) 11 { 12 board_init(); //目标平台板的初始化 13 platform_clock_init(); //平台时钟初始化msm8994_clock 14 qgic_init(); //通用IO通道初始化 15 qtimer_init(); //时钟初始化 16 scm_init(); //单片机初始化 17 } 18 19 // do any super early target initialization 20 target_early_init(); //只初始化串口为了打印信息,与后面的target_init对应 21 以上采用层层递进的关系进行初始化 22 23 dprintf(INFO, "welcome to lk "); //开始进入LK,INFO级别在console打印 24 25 // initialize the threading system 26 dprintf(SPEW, "initializing threads "); //SPEW级别在console口不打印 27 thread_init(); 28 29 // initialize the dpc system 30 dprintf(SPEW, "initializing dpc "); 31 dpc_init(); 32 33 // initialize kernel timers 34 dprintf(SPEW, "initializing timers "); 35 timer_init(); 36 37 // create a thread to complete system initialization -->创建线程完成系统初始化,跳转到第二阶段 38 dprintf(SPEW, "creating bootstrap completion thread "); 39 /*jump to bootstrap2*/ 40 thread_resume(thread_create("bootstrap2", &bootstrap2, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); 41 42 // become the idle thread //变成空闲线程 43 thread_become_idle(); 44 } 45 46 static int bootstrap2(void *arg) 47 { 48 platform_init(); --->void platform_init(void) //msm8994 49 { 50 dprintf(INFO, "platform_init() "); 51 #if ENABLE_XPU_VIOLATION 52 scm_xpu_err_fatal_init(); 53 #endif 54 } 55 target_init(); //各种板子资源初始化,mmc,sdc,usb,volumn等----> 56 //里面最重要的是mmc的初始化 target_sdc_init(); 57 //还有RPM rpm_smd_init(); 58 59 dprintf(SPEW, "calling apps_init() ");//app初始化以及启动app 60 apps_init();//开始执行app/aboot.c中的aboot_init函数 61 }
接下来开始执行app/aboot/aboot.c
1 在amboot.c的源码最底端: 2 APP_START(aboot) //可以看出上述的app启动的第一个就是aboot_init 3 .init = aboot_init, 4 APP_END 5 6 /* each app needs to define one of these to define its startup conditions */每个app需要的定义 7 struct app_descriptor { 8 const char *name; 9 app_init init; 10 app_entry entry; 11 unsigned int flags; 12 }; 13 开始研究aboot_init函数: 14 void aboot_init(const struct app_descriptor *app) 15 { 16 /* Setup page size information for nv storage */首先判断从哪启动emmc还是flash 17 if (target_is_emmc_boot()) 18 { 19 page_size = mmc_page_size(); 20 page_mask = page_size - 1; 21 } 22 else 23 { 24 page_size = flash_page_size(); 25 page_mask = page_size - 1; 26 } 27 read_device_info(&device); //读取设备信息 28 29 /* Display splash screen if enabled */ 30 #if DISPLAY_SPLASH_SCREEN //初始化显示屏 31 dprintf(SPEW, "Display Init: Start "); 32 target_display_init(device.display_panel); 33 dprintf(SPEW, "Display Init: Done "); 34 #endif 35 36 37 target_serialno((unsigned char *) sn_buf); //获取串口号 38 dprintf(SPEW,"serial number: %s ",sn_buf); 39 40 memset(display_panel_buf, '