高通android bootloader
高通LK(little kernel)。
little kernel是bootloader,其作用是硬件初始化,读取linux 内核和ramdisk到RAM里,设置初始寄存器以及内核命令行参数,并跳转到内核运行。
作用
- 硬件初始化:设置向量表,MMU,cache,初始化外设
- 从存储器加载boot.img
- 支持flash和recovery
即使在64bit架构,LK依然运行在32bit模式
kernel授权
- 签名的boot.img生成
a.使用用户的私有key生成加签名的boot镜像
b.计算原始boot.img的SHA256的哈希值,并使用用户的私有key(定义于device/qcom/common/common.mk)对哈希值镜像加签。将最终的哈希值和签名添加到原始的boot.img的末尾。
c.用户必须用PRODUCT_PRIVATE_KEY设置自己的私有key文件,当前该宏定义于device/qcom/common/qcom.key,目前使用的是一个测试key。
d.校验签名启动目前用于kernel和recovery镜像。
- LK授权kernel(boot.img)
a.如果在目标平台的BoardConfig.mk中设置了TARGET_BOOTIMG_SIGNED= true,LK先校验boot.img,然后在启动kernel。
b.在启动过程中,LK提取原始的boot.img镜像并计算其SHA26的哈希值,并将其编译生成的哈希值对比,如果相对,则成功授权。这一过程中涉及到的函数如下:
verify_signed_bootimg()→image_verify()
c.如果成功授权,则LK传递给kernel的命令行中有”androidboot.authorized_kernel=true“
d.用户需要用公钥放到bootable/bootloader/lk/platform/msm_shared/certificate.cfile,LK将会使用该公钥解密boot.img最后的签名哈希值。
LK调用流程
- 启动序列起始于arch/arm/crt0.S: _start:
a.设置cpu
b.如果需要调用__cpu_early_init(),
c.如果需要代码重定位
d.设置栈
e.调用kmain()
- kmain的调用流程如下:
- bootstrap2()的调用流程
a.arch/arm/arch.c –arch_init()
b.platform/<platform>/(platform.c)--platform_init()
c.target/<target>/(init.c) –target_init()
初始化SPMI
初始化keypad
设置驱动能力以及配置SDCpin脚功能
初始化SD主机控制器;确认MMC卡,设置时钟。
mmc_init()初始化
从emmc读取分区表
partition_read_table()
- app/init.c –apps_init()
初始化APP_START 和 APP_END两个宏定义的apps,aboot_init()被调用;
如果有.entry字段,则app运行在在一个独立的线程中。
- app/aboot/aboot.c –aboot_init()
根据设置和环境启动
- 常规启动
- fastboot模式接收镜像
- recovery模式恢复固件
LK常规启动
- recovery和fastboot标志没有设置
- 将boot.img从emmc中读取到内存中,读取地址由target/msmXXX/rules.mk的base address指定。
- 将kernel加载到KERNEL_ADDR(该地址源于boot image头)
- 类似kernel,加载RAM disk到RAMDISK_ADDR
- 找到正确的设备树,加载到TAGS_ADDR
- 跟新设备树
a.获得/memory和/chosen的偏移
b.添加HLOS内存范围
c.将cmdline添加到/chosen节点
d.禁止cache,中断,跳转到kernel
代码片段
- boot_linux_from_mmc() {
boot_linux_from_mmc() {structboot_img_hdr*hdr=(void*)buf; // boot image header
/* Read boot image header from emmcpartition into buf*/if(mmc_read(ptn+offset,(unsignedint*)buf,page_size)){... }/* Read image without signature to the scratch address */if (mmc_read(ptn+ offset, (void *)image_addr, imagesize_actual)) { .... }/* Read signature to the scratch address */if(mmc_read(ptn+ offset, (void *)(image_addr+ offset), page_size))/* Kernel image authentication */verify_signed_bootimg(image_addr, imagesize_actual);/* Move kernel, ramdiskand device tree to correct address */memmove((void*) hdr->kernel_addr, (char *)(image_addr+ page_size), hdr->kernel_size);memmove((void*) hdr->ramdisk_addr, (char *)(image_addr+ page_size+kernel_actual), hdr->ramdisk_size);/* Find the DT table address */dt_table_offset = ((uint32_t)image_addr + page_size + kernel_actual +ramdisk_actual + second_actual);table = (struct dt_table*) dt_table_offset;/* Calculate the index of device tree within device tree table */if(dev_tree_get_entry_info(table, &dt_entry) != 0){ }/* boot_linux : update device tree and jump to kernel */boot_linux((void *)hdr->kernel_addr, (unsigned *) hdr->tags_addr, (const char *)cmdline, board_machtype(),(void *)hdr->ramdisk_addr, hdr->ramdisk_size);
- void boot_linux()
update_device_tree((void *)tags, final_cmdline, ramdisk, ramdisk_size); /*
shown on the next slide */
.....
if (IS_ARM64(kptr))
scm_elexec_call((paddr_t)kernel, tags_phys); /* Jump to a 64bit kernel */
else
entry(0, machtype, (unsigned*)tags_phys); /* Jump to a 32 bitkernel */
}
- 跟新设备树
Int update_device_tree(constvoid*fdt,char*cmdline,
void*ramdisk,unsignedramdisk_size)
{ .........
uint32_t*memory_reg;
/*Checkthedevicetreeheader*/
offset=fdt_check_header(fdt);
..........
/*Getoffsetofthe”memory”node*/
offset=fdt_path_offset(fdt,”/memory”);
/* Update “memory” node* /
ret=target_dev_tree_mem(fdt,offset);
/*Getoffsetofthe”chosen”node*/
ret=fdt_path_offset(fdt,”/chosen”);
/*Addingthecmdlinetothe”chosen”node*/
ret=fdt_setprop_string(fdt,offset,(constchar*)”bootargs”,(constvoid*)cmdlin
e);
/*Addingtheinitrd-start tothechosennode*/
ret=fdt_setprop_u32(fdt,offset,”linux,initrd-start”,(uint32_t)ramdisk);
/*Addingtheinitrd-end tothechosennode*/
ret=fdt_setprop_u32(fdt,offset,”linux,initrd-
end”,((uint32_t)ramdisk+ramdisk_size));
.... }
LK fastboot模式
- aboot_init检查boot.img是否存在,音量减键是否被按住
- 检查reboot的原因--check_reboot_mode
- 注册fastboot模式的函数方法--fastboot_register(cmd_list[i].name,cmd_list[i].cb);
- 初始化fastboot
fastboot_init(void *base, unsigned size) 为 fastboot_handler()创建线程 线程等待USB事件
- 设置USB--udc_start()
fastboot命令
- 在用户模式fastboot命令被disable了,这出于安全考虑
ifeq($(TARGET_BUILD_VARIANT),user)
CFLAGS += -DDISABLE_FASTBOOT_CMDS=1
endif
- 启动user版本的镜像,如果要支持特定命令,需要按如下做
bootable/bootloader/lk/app/aboot/aboot.c
structfastboot_cmd_desccmd_list[] = {
/* By default the enabled list is empty. */
{““, NULL},
/* move commands enclosed within the below ifndefto here
* if they need to be enabled in user build.
*/
#ifndefDISABLE_FASTBOOT_CMDS
/* Register the following commands only for non-user builds */
{“flash:”, cmd_flash},
{“erase:”, cmd_erase},
{“boot”, cmd_boot},
{“continue”, cmd_continue},
{“reboot”, cmd_reboot},
{“reboot-bootloader”, cmd_reboot_bootloader},
{“oemunlock”, cmd_oem_unlock},
{“oemlock”, cmd_oem_lock},
{“oemverified”, cmd_oem_verified},
{“oemdevice-info”, cmd_oem_devinfo},
{“oemenable-charger-screen”, cmd_oem_enable_charger_screen},
{“oemdisable-charger-screen”, cmd_oem_disable_charger_screen},
{“oem-select-display-panel”, cmd_oem_select_display_panel},
#endif
};
LK recovery模式
- aboot_init检查KEY_HOME or VOLUME UP是否被按压了
- 检查重启的原因--check_reboot_mode(),如果是RECOVERY_MODE原因,则设置boot_into_recovery = 1.
- boot_linux_from_mmc检查
if (!boot_into_recovery) {
.........
...
else {
index = partition_get_index(“recovery”);
ptn = partition_get_offset(index);
...........
......
}
- 从recovery分区获取镜像
gned int target_freq, unsigned int relation);
高通android bootloader相关推荐
- android加载efi分区,高通Android UEFI XBL 代码流程分析
高通Android UEFI XBL 代码流程分析 背景 之前学习的lk阶段点亮LCD的流程算是比较经典,但是高通已经推出了很多种基于UEFI方案的启动架构. 所以需要对这块比较新的技术进行学习.在学 ...
- 高通Android平台开发
问题描述: 对于有过开发高通android系统的人来说,获取代码构建开发环境并不是难事,但对于刚刚接触这一块内容的人,如果没有详细的说明很容易走弯路,本文档就是根据本人的实践总结的一 ...
- 高通Android智能平台环境搭建_编译流程分析
高通Android智能平台环境搭建_编译流程分析 高通平台环境搭建,编译,系统引导流程分析 TOC \o \h \z \u 1. 高通平台android开发总结. 7 1.1 搭建高通平台环境开发环境 ...
- 高通Android智能平台开发总结
高通Android智能平台开发总结 1. 高通平台android开发总结. 7 1.1 搭建高通平台环境开发环境. 7 1.2 搭建高通平台环境开发环境. 7 1.2.1 高通android智能平台概 ...
- 高通Android display架构分析
目录(?)[-] Kernel Space Display架构介绍 函数和数据结构介绍 函数和数据结构介绍 函数和数据结构介绍 数据流分析 初始化过程分析 User Space display接口 K ...
- 高通android平台修改开机小企鹅logo
高通平台修改开机画面 小企鹅LOGO 高通android平台修改开机小企鹅logo 方法一 方法二 高通android平台修改开机小企鹅logo 高通android平台开机lk阶段默认使用小企鹅log ...
- 高通linux内核目录,高通 android 源代码以及目标系统目录结构
下面为高通android源代码结构 build/ – Build 环境建立和makefiles生成4 bionic/ – Android C 库 dalvik/ – Android Java 虚拟机 ...
- 高通android开源代码下载
高通android开源代码下载 开源网站https://www.codeaurora.org/projects/all-active-projects/android-msm,选择wiki,在Wiki ...
- 高通 MSM8K bootloader : SBL1 .
一. MSM8K Boot Flow 图1: 高通MSM8K平台bootloader启动流程基本类似,但具体各平台,比如MSM8974.MSM8916.MSM8994等,会有微小区别. 从上图,可以看 ...
最新文章
- hexo绑定个人域名
- 高效程序猿之(四)VS2010其他技巧
- 2018年东北农业大学春季校赛 E 阶乘后的0【数论】
- 什么是RosBE及其安装使用、第一次生成ReactOS的VS工程失败
- web 埋点实现原理了解一下
- Altium designer快捷键汇总
- 【poj2114】点分治(离线)
- Unity3D 与 objective-c 之间数据交互。iOS SDK接口封装Unity3D接口
- python调用系统命令_linux里面python调用系统命令问题
- 【洛谷 P3304】[SDOI2013]直径(树的直径)
- 运维工程师必备之负载均衡集群及LVS详解
- keil uVision4 创建项目
- BroadcastReceiver广播
- 联想服务器虚拟化解决方案,联想虚拟化解决方案
- Python库安装注意事项
- linux查看已安装的软件
- Inception-V3论文翻译——中文版
- 麦克劳林级数与麦克劳林公式(泰勒公式)
- 识破面试官的套路:十个典型的面试问题剖析
- 基本的信号——冲激信号与冲激序列
热门文章
- 通过例子学TLA+(十一)--命题逻辑与实例
- android 开发工程师 高级面试题
- 骁龙660是32位还是64位_高通骁龙660、653、652、650、626、625手机处理器区别是什么?...
- 解决高度塌陷4种方法
- 程序员是不是青春饭?
- 如何将Simulink应用于ISO 26262项目
- 六级词汇天天练(11.11)
- Elasticsearch高级搜索排序( 中文+拼音+首字母+简繁转换+特殊符号过滤)(示例代码)
- SSM文件上传封装工具类
- [转帖]一个关于国密SM4的故事