我是
靠谱客的博主
心灵美秀发,最近开发中收集的这篇文章主要介绍
Android启动流程分析之二:内核的引导,觉得挺不错的,现在分享给大家,希望可以做个参考。
继续以c6(mido)的代码为例
由于目前大部分手机不再使用nand flash,取而代之的是emmc,因此启动内核的实现以boot_linux_from_mmc为例分析。
- 一 boot_linux_from_mmc
- 二 boot_linux
- 三 scm_elexec_call
一 boot_linux_from_mmc
boot_linux_from_mmc函数主要负责根据boot_into_xxx从对应的分区内读取相关信息并传给kernel,然后引导kernel。
boot_linux_from_mmc()函数的工作主要有:
1).程序会从boot分区或者recovery分区的header中读取地址等信息,然后把kernel、ramdisk加载到内存中。
2).程序会从misc分区中读取bootloader_message结构体,如果有boot-recovery,则进入recovery模式
3).更新cmdline,然后把cmdline写到tags_addr地址,把参数传给kernel,kernel起来以后会到这个地址读取参数。
执行到boot_linux_from_mmc函数这里,说明这次启动不进入fastboot模式,可能的情况有:正常启动,进入recovery,开机闹钟启动。
int
boot_linux_from_mmc(
void
)
{
struct
boot_img_hdr *hdr = (
void
*) buf;
struct
boot_img_hdr *uhdr;
unsigned offset = 0;
int
rcode;
unsigned
long
long
ptn = 0;
int
index = INVALID_PTN;
unsigned
char
*image_addr = 0;
unsigned kernel_actual;
unsigned ramdisk_actual;
unsigned imagesize_actual;
unsigned second_actual = 0;
unsigned
int
dtb_size = 0;
unsigned
int
out_len = 0;
unsigned
int
out_avai_len = 0;
unsigned
char
*out_addr = NULL;
uint32_t dtb_offset = 0;
unsigned
char
*kernel_start_addr = NULL;
unsigned
int
kernel_size = 0;
int
rc;
#if DEVICE_TREE
struct
dt_table *table;
struct
dt_entry dt_entry;
unsigned dt_table_offset;
uint32_t dt_actual;
uint32_t dt_hdr_size;
unsigned
char
*best_match_dt_addr = NULL;
#endif
struct
kernel64_hdr *kptr = NULL;
if
(check_format_bit())
boot_into_recovery = 1;
if
(!boot_into_recovery) {
memset
(ffbm_mode_string,
' |