Android系统启动过程由以下几个大步骤组成:
BootRom, Bootloader, Linux Kernel, android启动
BootRom没有源代码
Bootloader代码主要在/bootable下,包括对normal startup, 及recovery mode, fastboot mode的处理
Linux主要是linux kernel启动
Android从porcess init (process 1)开始,带动其他process/service启动
下面主要讲Bootloader 及linux调用过程
1.Bootloader调用过程
kernel/arch/arm/crt0.S _start call kmain() in bootable/bootloader/lk/kernel/main.c
kmain() 依次调用
thread_init_early()
arch_early_init()
platform_early_init()
target_early_init()
bs_set_timestamp()
call_constructors()
heap_init()
thread_init()
dpc_init()
timer_init()
create thread bootstrap2
其中 target_early_init() 定义在 bootable/bootloader/lk/target/msm8226/init.c ,会对uart初始化 uart_dm_init(1, 0, BLSP1_UART2_BASE);
bootstrap2() 又会调用
arch_init()
platform_init()
target_init()
apps_init()
target_init()定义在具体平台下,通常初始化些用到总线,keyboard, display等
apps_init() 定义在 bootable/bootloader/lk/app/app.c ,会调用bootable/bootloader/lk/app/aboot/aboot.c 里的 aboot_init()
aboot_init() 首先判断按键是recovery mode还是fastboot mode.
如果是fastboot mode,则调用fastboot_init() ,该函数定义在bootable/bootloader/lk/app/aboot/fastboot.c。
如果是正常启动模式或recovery模式,则调用
emmc_recovery_init())
boot_linux_from_mmc()
boot_linux_from_mmc()定义在recovery/normal mode bootable/bootloader/lk/app/aboot/aboot.c
首先根据不同模式读出/boot, /recovery分区索引及偏移,接着会调用boot_linux() 进入linux kernel.
2. Kernel启动调用过程
进入linux kernel首先是解压缩zimage,初始化MMU等硬件,进入到start_kernel()
是由kernel/arch/arm/kernel/head-common.S里的__INIT调用过来
start_kernel()定义在 kernel/init/main.c,会调用
boot_cpu_init();
page_address_init();
mm_init_owner(&init_mm, &init_task);
mm_init_cpumask(&init_mm);
setup_command_line(command_line);
setup_nr_cpu_ids();
setup_per_cpu_areas();
smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */
setup_log_buf(0);
vfs_caches_init_early();
mm_init();
sched_init();
…….
rest_init();
rest_init() create two threads,
在第一个线程执行函数kernel_init(),
if (!ramdisk_execute_command)
ramdisk_execute_command = "/init";
接着调用init_post(),
run_init_process(ramdisk_execute_command);
->kernel_execve
-> do_execve
process init就这样被创建了
3. 调试
Bootloader调试:
串口,T32, 写到文件里,打印到屏幕,设置硬件(GPIO, LED,vibrate)
Kernel: printk, cat proc/kmsg, dmesg
Init process: ERROR or change LOG_DEFAULT_LEVEL to 6