1. 程式人生 > >高通android bootloader

高通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

高通LK(little kernel)。 little kernel是bootloader,其作用是硬體初始化,讀取linux 核心和ramdisk到RAM裡,設定初始暫存器以及核心命令列引數,並跳轉到核心執行。 作用 硬體初始化:設定向量表,MMU,cache,初始化外設

[Android]平臺BootLoader啟動流程

一、什麼是BootLoader BootLoader程式碼是晶片復位後,進入作業系統之前執行的一段程式碼。主要用於完成由硬體啟動到作業系統啟動的過渡,從而為作業系統提供基本的執行環境。 BootLoder主要的啟動流程可以概括為:PBL階段、SBL階段、LK階段。之後會載入並啟動kern

android開發摘要

lun turn line 不同 ons subscribe master less ade 一部分是開源的。能夠從codeaurora.org上下載,另一部分是高通產權的。須要從高通的站點上下載。 將高通產權的代碼放到:vendor/qcom/proprietary1

android上模組編譯.ko

1.配置交叉編譯環境 # cd kernel-3.18 or # cp arch/arm/configs/msm_defconfig .config //arm32位配置方式 # make ARCH=a

平臺bootloader裡面串列埠log輸出配置方法

1:在modem端將相應的gpio設定成相應功能。 2:在/lk/project/xxx.mk開啟uart輸出log功能。 3:在platform/msm_shared/uart.c中定義uart幾輸出log, #if PLATFORM_MSM7X30 static uns

平臺BootLoader的流程

原文連結:http://www.codingblog.cn/blog/44451.html 注:很多內容和MTK  LK階段相同,可以借鑑學習。aboot.c內容差異很大。 本文以C6的bootlader程式碼為例, 1.

Android平臺 OTA差分包的生成方法

1、首先高通平臺的編譯流程與android原生態的編譯流程一樣,需要經歷以下幾步:    a. source build/envsetup.sh;    b. lunch 選擇專案    c. make -j24     編譯完之後    4.make otapackage

MSM8K bootloader 之四: ramdump

boot_procedure_func_type sbl1_pre_dload_procs[] = {  ............  /*-----------------------------------------------------------------------    * Ram dump

android平臺功耗優化方法

1、底電流除錯(Rock Bottom Current Optimization) 底電流在手機飛航模式下除錯。每個平臺的底電流資料可能不一樣,具體可以參考release出來的Current Consumption Data文件或者release note。一般情況下的底電流參考資料上限是: 512M

android 7.0彩信傳送流程

ComposeMessageActivity.java sendMessage WorkingMessage send private void prepareForSave(boolean notify) {         // Make sure our

android 7.0簡訊草稿儲存流程

簡訊應用,當輸入聯絡人並且簡訊內容不為空,在沒有傳送的情況下退出簡訊介面,則會進行簡訊草稿儲存,以便下次重新進入會話介面可以重新載入,進行重新編輯或者傳送。 我們現在就來分析其流程: ComposeMessageActivity.java 當點選退出會話介面,就會觸

Android平臺硬體除錯之Camera篇

Camera工作流程圖Camera的成像原理可以簡單概括如下:景物(SCENE)通過鏡頭(LENS)生成的光學影象投射到影象感測器(Sensor)表面上,然後轉為電訊號,經過A/D(模數轉換)轉換後變為數字影象訊號,再送到數字訊號處理晶片(DSP)中加工處理,再通過IO介面傳輸到CPU中處理,通過DISPLA

MSM8K bootloader 之二: SBL1

FROM:http://blog.csdn.net/fybon/article/details/37565227 續:高通 MSM8K bootloader 之一: SBL1 上篇將我重點關注SBL1的內容1和2基本說明完,本篇繼續內容3和4。 1、  

linux驅動由淺入深系列:PBL-SBL1-(bootloader)LK-Android啟動過程詳解之一(MSM8953啟動例項)【轉】

本文轉載自:https://blog.csdn.net/radianceblau/article/details/73229005 對於嵌入式工程師瞭解晶片啟動過程是十分有必要的,在分析、除錯各種問題的時候都有可能涉及到這方面的知識。同時這部分知識也是比較複雜的,因為其中涉及到晶片內部架構,啟動各個階段軟體

泛泰A820L (MSM8660 cpu) 3.4內核的CM10.1(Android 4.2.2) 測試版第二版

卸載 反饋 span lin clas wan 系統分區 漢化 sof 歡迎關註泛泰非盈利專業第三方開發團隊 VegaDevTeam (本team 由 syhost suky zhaochengw(z大) xuefy(大星星) tenfar(R大師) loogeo

方案的Android設備幾種開機模式的進入與退出

內容 熱啟動 boot 操作 com 刷機 安裝 tor min 高通方案的Android設備主要有以下幾種開機模式,Android、EDL、Fastboot、Recovery和FFBM,其進入及退出的方式如下表。 開機模式 屏幕表現 冷啟

Android Studio 使用Vuforia()開發AR

AR作為現在的前端新技術,在許多APP中運用到,那麼如何在Android studio開發環境下編譯執行AR專案呢,請按下面步驟走: 1.搭建Android studio android 開發環境 這個不做詳細說明,其他地方都可搜到 2.下載ndk 要進行AR開發

ar 匯出android apk報錯 Assets/Vuforia/Scripts/Utilities/VRIntegrationHelper.cs(99,29): error CS1061

問題:(錯誤在VRIntegrationHelper.cs指令碼中) error CS1061: Type UnityEngine.Camera' does not contain a definition forSetStereoProjectionMatrices’ and no ext

Android平臺下編譯時能生成(拷貝)預編譯的so到system的lib目錄

  參考hardware\qcom\display\libcopybit 通過編譯log可以知道編譯到這裡,生成的copybit.msm8937.so在out\target\product\msm8937_64\system\lib\hw下。libcopybit\Andr

Android預置apk可解除安裝,恢復出廠設定可恢復

https://blog.csdn.net/bathing_sunshine/article/details/78486133 沒什麼好說的,先上程式碼: copy_apps.sh 路徑:vendor/qcom/proprietary/qrdplus/Extension/config #!/