日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android 开发之 ---- bootloader (LK)

發布時間:2025/7/14 Android 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android 开发之 ---- bootloader (LK) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

LK是什么

???????????LK 是 Little Kernel 它是 appsbl (Applications ARM Boot Loader)流程代碼? ,little kernel 是小內核小操作系統。

?????????? LK 代碼 在 bootable/bootloadler/lk 目錄下

?????????? LK 代碼結構

?????????? +app??????????? // 應用相關

?????????? +arch?????????? // arm 體系?

?????????? +dev??????????? // 設備相關

?????????? +include????? // 頭文件

?????????? +kernel??????? // lk系統相關???

?????????? +platform??? //?相關驅動

?????????? +projiect???? // makefile文件

?????????? +scripts????? // Jtag 腳本

?????????? +target??????? // 具體板子相關

?

LK 流程分析

????????? 在?bootable/bootloadler/lk/arch/arm/ssystem-onesegment.ld 連接文件中 ENTRY(_start)指定 LK 從_start 函數開始,_start 在 lk/arch/crt0.S中 。crt0.S 主要做一些基本的 CPU 的初始化再通過 bl? kmain ;跳轉到 C 代碼中。

????????? kmain 在 lk/kernel/main.c 中

?

kmain()

??????????? kmain 主要做兩件事:1、本身 lk 這個系統模塊的初始化;2、boot 的啟動初始化動作。

??????????? kmain 源碼分析:

???????????? void kmain()

????????? {

???????????1.初始化進程(lk 中的簡單進程)相關結構體。

?????? ? ? ? thread_init_early();

???????????2.做一些如 關閉 cache,使能 mmu 的 arm 相關工作。

??????????? arch_early_init();

?????????? 3.相關平臺的早期初始化

??????????? platform_early_init();

???????????4.現在就一個函數跳轉,初始化UART(板子相關)

??????????? target_early_init();

???????????5.構造函數相關初始化

??????? ? ? call_constructors();

???????????6.lk系統相關的堆棧初始化

??????????? heap_init();

?????????? 7.簡短的初始化定時器對象

??????????? thread_init();

???????????8.lk系統控制器初始化(相關事件初始化)

??????????? dpc_init();

???????????9.初始化lk中的定時器

??????????? timer_init();
???????????
10.新建線程入口函數?bootstrap2 用于boot 工作(重點)
?????????? thread_resume(thread_create("bootstrap2", &bootstrap2, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));

?????????}

???以上與 boot 啟動初始化相關函數是?arch_early_init、? platform_early_init 、bootstrap2,這些是啟動的重點,我們下面慢慢來看。

?

arch_early_init()

?????????體系架構相關的初始化我們一般用的 ARM 體系

?????????1.關閉cache

???????? arch_disable_cache(UCACHE);

?????????2.設置向量基地址(中斷相關)

???????? set_vector_base(MEMBASE);

?????????3.初始化MMU

???????? arm_mmu_init();

?????????4.初始化MMU映射__平臺相關

???????? platform_init_mmu_mappings();

? ? ? ???5.開啟cache ????????

???????? arch_enable_cache(UCACHE)

?????????6.使能 cp10 和 cp11

???????? __asm__ volatile("mrc?? ?p15, 0, %0, c1, c0, 2" : "=r" (val));

???????? val |= (3<<22)|(3<<20);

?????? ? __asm__ volatile("mcr?? ?p15, 0, %0, c1, c0, 2" :: "r" (val));
?

?? ? ???7.設置使能 fpexc 位?(中斷相關)

??? ??? __asm__ volatile("mrc? p10, 7, %0, c8, c0, 0" : "=r" (val));

??????? val |= (1<<30);

??????? __asm__ volatile("mcr? p10, 7, %0, c8, c0, 0" :: "r" (val));

? ? ? ??8.使能循環計數寄存器

??????? __asm__ volatile("mrc?? ?p15, 0, %0, c9, c12, 0" : "=r" (en));

??????? en &= ~(1<<3);?/*循環計算每個周期*/

??????? en |= 1;?

??????? __asm__ volatile("mcr?? ?p15, 0, %0, c9, c12, 0" :: "r" (en));

???????9.使能循環計數器

?????? en = (1<<31);
?????? __asm__ volatile("mcr?? ?p15, 0, %0, c9, c12, 1" :: "r" (en));

?

platform_early_init()

???????平臺相關初始化不同平臺不同的初始化下面是msm7x30

? ? ? ??1.初始化中斷

?? ?? ??platform_init_interrupts();

????????2.初始化定時器

????????platform_init_timer();

?

bootstrap2?

?????????bootstrap2?在kmain的末尾以線程方式開啟。主要分三步:platform_init、target_init、apps_init。

????????1.platform_init

???????????????platform_init 中主要是函數 acpu_clock_init。

?????????????? 在 acpu_clock_init?對 arm11 進行系統時鐘設置,超頻?

????????2.target_init

??????????? ? 針對硬件平臺進行設置。主要對 arm9 和 arm11 的分區表進行整合,初始化flash和讀取FLASH信息

? ? ? ??3.apps_init??

???????????? apps_init 是關鍵,對 LK 中所謂 app 初始化并運行起來,而 aboot_init 就將在這里開始被運行,Android?Linux?內核的加載工作就在 aboot_init 中完成的 。

?

aboot_init

????????1.設置NAND/?EMMC讀取信息頁面大小
????????if (target_is_emmc_boot())

??????? {

????????????????? page_size = 2048;

????????????????? page_mask = page_size - 1;

??????? }

?????? else

?????? {

???????????????? page_size = flash_page_size();

???????????????? page_mask = page_size - 1;

??????? }

????? 2.讀取按鍵信息,判斷是正常開機,還是進入 fastboot ,還是進入recovery 模式

?????? 。。。。。。。。。

??????通過一系列的 if (keys_get_state() == XXX) 判斷

?????? 。。。。。。。。。

????? 3.從 nand 中加載 內核

??????boot_linux_from_flash();

?

????? partition_dump();

????? sz = target_get_max_flash_size();

????? fastboot_init(target_get_scratch_address(), sz);

????? udc_start(); // 開始 USB 協議

?

boot_linux_from_flash

???????????? 主要是內核的加載過程,我們的 boot.img 包含:kernel 頭、kernel、ramdisk、second stage(可以沒有)。

???????????1.讀取boot 頭部

?????????? flash_read(p, offset, raw_header, 2048)?

?????????? offset += 2048;
? ? ? ? ???
2.讀取 內核 ???
?????????? memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)
?????????? n = (hdr->kernel_size + (FLASH_PAGE_SIZE - 1)) & (~(FLASH_PAGE_SIZE - 1));

? ? ? ? ?? flash_read(p, offset, (void*) hdr->kernel_addr, n)

?? ? ? ? ? offset += n;
???????????
3.讀取 ramdisk
? ? ? ? ?? n = (hdr->ramdisk_size + (FLASH_PAGE_SIZE - 1)) & (~(FLASH_PAGE_SIZE - 1));

?????????? flash_read(p, offset, (void*) hdr->ramdisk_addr, n)

?????????? offset += n;

????????????4.啟動內核

????????????? ??boot_linux();//在boot_linux 中entry(0,machtype,tags);從kernel加載在內核中的地址開始運行了。

??????

????????到這里LK的啟動過程就結束了。

總結

以上是生活随笔為你收集整理的Android 开发之 ---- bootloader (LK)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。