bootloaderandroid
『壹』 android bootloader lk階段能讀取文件嗎
1.主要功能,紅色部分是android特有的一些功能,如fastboot,recovery模式等:
* Variety of nand devices for bootup
* USB driver to enable upgrading images over usb ring development
* Keypad driver to enable developers enter 『fastboot』 mode for image upgrades
* Display driver for debugging and splash screen
* Enable Android recovery image and image upgrades
2.配置dram內存大小,供linux kernel使用
The memory tags can be customized inlk/target/<target_name>/atags.c
3.fastboot模式,可以自行打開或者關閉
如,在boot中關閉按鍵或者usb 驅動,都可以達到此目的
相關文件
k/app/aboot/fastboot.c
lk/app/aboot/aboot.c
4.MTD block setting
可以配置各個mtd image 分區在如下 文件中
lk\target\tcc8900_evm\init.c
static struct ptentry board_part_list[]
5.打開或者關閉splash screen in the bootloader
DISPLAY_SPLASH_SCREEN功能可以來打開關閉
開機時候,boot會從』splash』 MTD分區中讀取原始的文件到framebuffer中顯示,所以也需要載入display 的驅動
入口函數在 kernel/main.c 中的 kmain(), 以下就來讀讀這一段 code.
void kmain(void)
{
// get us into some sort of thread context
thread_init_early();
// early arch stuff
arch_early_init();
// do any super early platform initialization
platform_early_init();
// do any super early target initialization
target_early_init();
dprintf(INFO, "welcome to lk/n/n");
// deal with any static constructors
dprintf(SPEW, "calling constructors/n");
call_constructors();
// bring up the kernel heap
dprintf(SPEW, "initializing heap/n");
heap_init();
// initialize the threading system
dprintf(SPEW, "initializing threads/n");
thread_init();
// initialize the dpc system
dprintf(SPEW, "initializing dpc/n");
dpc_init();
// initialize kernel timers
dprintf(SPEW, "initializing timers/n");
timer_init();
#if (!ENABLE_NANDWRITE)
// create a thread to complete system initialization
dprintf(SPEW, "creating bootstrap completion thread/n");
thread_resume(thread_create("bootstrap2", &bootstrap2, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
// enable interrupts
exit_critical_section();
// become the idle thread
thread_become_idle();
#else
bootstrap_nandwrite();
#endif
}
In include/debug.h: 我們可以看到 dprintf 的第一個參數是代表 debug level.
/* debug levels */
#define CRITICAL 0
#define ALWAYS 0
#define INFO 1
#define SPEW 2
In include/debug.h:
view plainprint?
#define dprintf(level, x...) do { if ((level) <= DEBUGLEVEL) { _dprintf(x); } } while (0)
所以 dprintf 會依 DEBUGLEVEL 來判斷是否輸出信息.
來看第一個 call 的函數: thread_init_early, define in thread.c
view plainprint?
void thread_init_early(void)
{
int i;
/* initialize the run queues */
for (i=0; i < NUM_PRIORITIES; i++)
list_initialize(&run_queue[i]);
/* initialize the thread list */
list_initialize(&thread_list);
/* create a thread to cover the current running state */
thread_t *t = &bootstrap_thread;
init_thread_struct(t, "bootstrap");
/* half construct this thread, since we're already running */
t->priority = HIGHEST_PRIORITY;
t->state = THREAD_RUNNING;
t->saved_critical_section_count = 1;
list_add_head(&thread_list, &t->thread_list_node);
current_thread = t;
}
#define NUM_PRIORITIES 32 in include/kernel/thread.h
list_initialize() defined in include/list.h: initialized a list
view plainprint?
static inline void list_initialize(struct list_node *list)
{
list->prev = list->next = list;
}
run_queue 是 static struct list_node run_queue[NUM_PRIORITIES]
thread_list 是 static struct list_node thread_list
再來要 call 的函數是: arch_early_init() defined in arch/arm/arch.c
view plainprint?
void arch_early_init(void)
{
/* turn off the cache */
arch_disable_cache(UCACHE);
/* set the vector base to our exception vectors so we dont need to double map at 0 */
#if ARM_CPU_CORTEX_A8
set_vector_base(MEMBASE);
#endif
#if ARM_WITH_MMU
arm_mmu_init();
platform_init_mmu_mappings();
#endif
/* turn the cache back on */
arch_enable_cache(UCACHE);
#if ARM_WITH_NEON
/* enable cp10 and cp11 */
uint32_t val;
__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));
/* set enable bit in fpexc */
val = (1<<30);
__asm__ volatile("mcr p10, 7, %0, c8, c0, 0" :: "r" (val));
#endif
}
現代操作系統普遍採用虛擬內存管理(Virtual Memory Management)機制,這需要處理器中的MMU(Memory Management Unit,
內存管理單元)提供支持。
CPU執行單元發出的內存地址將被MMU截獲,從CPU到MMU的地址稱為虛擬地址(Virtual Address,以下簡稱VA),而MMU將這個地
址翻譯成另一個地址發到CPU晶元的外部地址引腳上,也就是將VA映射成PA
MMU將VA映射到PA是以頁(Page)為單位的,32位處理器的頁尺寸通常是4KB。例如,MMU可以通過一個映射項將VA的一頁
0xb7001000~0xb7001fff映射到PA的一頁0x2000~0x2fff,如果CPU執行單元要訪問虛擬地址0xb7001008,則實際訪問到的物理地
址是0x2008。物理內存中的頁稱為物理頁面或者頁幀(Page Frame)。虛擬內存的哪個頁面映射到物理內存的哪個頁幀是通過頁
表(Page Table)來描述的,頁表保存在物理內存中,MMU會查找頁表來確定一個VA應該映射到什麼PA。
操作系統和MMU是這樣配合的:
1. 操作系統在初始化或分配、釋放內存時會執行一些指令在物理內存中填寫頁表,然後用指令設置MMU,告訴MMU頁表在物理內存中
的什麼位置。
2. 設置好之後,CPU每次執行訪問內存的指令都會自動引發MMU做查表和地址轉換操作,地址轉換操作由硬體自動完成,不需要用指令
控制MMU去做。
MMU除了做地址轉換之外,還提供內存保護機制。各種體系結構都有用戶模式(User Mode)和特權模式(Privileged Mode)之分,
操作系統可以在頁表中設置每個內存頁面的訪問許可權,有些頁面不允許訪問,有些頁面只有在CPU處於特權模式時才允許訪問,有些頁面
在用戶模式和特權模式都可以訪問,訪問許可權又分為可讀、可寫和可執行三種。這樣設定好之後,當CPU要訪問一個VA時,MMU會檢查
CPU當前處於用戶模式還是特權模式,訪問內存的目的是讀數據、寫數據還是取指令,如果和操作系統設定的頁面許可權相符,就允許訪
問,把它轉換成PA,否則不允許訪問,產生一個異常(Exception)
常見的 segmentation fault 產生的原因:
用戶程序要訪問一段 VA, 經 MMU 檢查後無權訪問, MMU 會產生異常, CPU 從用戶模式切換到特權模式, 跳轉到內核代碼中執行異常服務程序.
內核就會把這個異常解釋為 segmentation fault, 將引發異常的程序終止.
『貳』 安卓系統上的解鎖bl,BL是什麼意思
BL鎖即BootLoader,就是在操作系統內核運行之前運行的一段小程序,它負責在開機時載入硬體的初始化程序,並啟動系統進程,就像電腦的bios一樣。、
BootLoader對於手機很重要,如果BootLoader不能正常載入,手機就無法正常啟動和使用。這也就是為什麼BootLoader被鎖的手機必須要破解,如果不破解BootLoader,就無法初始化手機硬體,手機也就無法使用。
(2)bootloaderandroid擴展閱讀
手機兩種啟動模式下bootloader的作用:
1、自啟動模式
在這種模式下,bootloader從目標機上的某個固態存儲設備上將操作系統載入到RAM中運行,整個過程並沒有用戶的介入。
2、交互模式
在這種模式下,目標機上的bootloader將通過串口或網路等通行手段,從開發主機(Host)上下載內核映像等到RAM中。可以被bootloader寫到目標機上的固態存儲媒質,或者直接進入系統的引導,也可以通過串口接收用戶的命令。