1. 程式人生 > >Android系統啟動過程-uBoot+Kernel+Android

Android系統啟動過程-uBoot+Kernel+Android

轉載自:http://www.cnblogs.com/pngcui/p/4665106.html

摘要:本文是參考大量網上資源在結合自己檢視原始碼總結出來的,讓自己同時也讓大家加深對Android系統啟動過程有一個更加深入的瞭解!再次強調,本文的大多數功勞應歸功於那些原創者們,同時一些必要的參考連結我會一一附上。

注:由於本人採用Exynos4412開發板學習,所以本文大部分資料都是基於此處理器的

簡介:對於整個Android系統的啟動總的來說分為三個階段:

    BootLoader引導即uBoot.bin

    linux核心啟動即zImage

    Android系統啟動即ramdisk.img與system.img

    以上四個檔案都是經過自己編譯後生成的且通過燒寫測試,接下來開始說這三大部分的啟動過程。

目錄:一、BootLoader的啟動

     1.彙編部分

     2.c部分

     二、Kernel的啟動

      1.zImage解壓縮

      2.kernel的彙編啟動階段

      3.kernel的c啟動階段

   三、Android的啟動

      1.init程序

      2.init啟動的各種服務

      3.android啟動圖示

第一部分:BootLoader的啟動流程

uBoot的第一條指令從cpu/arm920t/start.S檔案開始

      1. 設定CPU進入SVC模式(系統管理模式),cpsr[4:0]=0xd3。

複製程式碼
 1 #include <common.h>
 2 #include <config.h>
 3 
 4 /*
 5  *************************************************************************
 6  *
 7  * Jump vector table as in table 3.1 in [1]
 8  *
 9  *************************************************************************
10 */ 11 12 13 .globl _start 14 _start: b start_code 15 ldr pc, _undefined_instruction 16 ldr pc, _software_interrupt 17 ldr pc, _prefetch_abort 18 ldr pc, _data_abort 19 ldr pc, _not_used 20 ldr pc, _irq 21 ldr pc, _fiq 22 23 _undefined_instruction: .word undefined_instruction 24 _software_interrupt: .word software_interrupt 25 _prefetch_abort: .word prefetch_abort 26 _data_abort: .word data_abort 27 _not_used: .word not_used 28 _irq: .word irq 29 _fiq: .word fiq 30 31 .balignl 16,0xdeadbeef
複製程式碼

        接著進入Start_code中:設定CPU進入SVC模式。

複製程式碼
 1 /*
 2  * the actual start code
 3  */
 4 
 5 start_code:
 6     /*
 7      * set the cpu to SVC32 mode
 8      */
 9     mrs    r0, cpsr
10     bic    r0, r0, #0x1f
11     orr    r0, r0, #0xd3
12     msr    cpsr, r0
13 
14     bl    coloured_LED_init
15     bl    red_LED_on
複製程式碼

        2.關看門狗,WTCON=0x0,並設定暫存器地址。

複製程式碼
 1 /* turn off the watchdog */
 2 
 3 # if defined(CONFIG_S3C2400)
 4 #  define pWTCON    0x15300000
 5 #  define INTMSK    0x14400008    /* Interupt-Controller base addresses */
 6 #  define CLKDIVN    0x14800014    /* clock divisor register */
 7 #else
 8 #  define pWTCON    0x53000000
 9 #  define INTMSK    0x4A000008    /* Interupt-Controller base addresses */
10 #  define INTSUBMSK    0x4A00001C
11 #  define CLKDIVN    0x4C000014    /* clock divisor register */
12 # endif
13 
14     ldr    r0, =pWTCON
15     mov    r1, #0x0
16     str    r1, [r0]
複製程式碼

        3.關中斷,INTMSK=0xFFFFFFFF, INTSUBMSK=0x3FF。

複製程式碼
 1 /*
 2      * mask all IRQs by setting all bits in the INTMR - default
 3      */
 4     mov    r1, #0xffffffff
 5     ldr    r0, =INTMSK
 6     str    r1, [r0]
 7 # if defined(CONFIG_S3C2410)
 8     ldr    r1, =0x3ff
 9     ldr    r0, =INTSUBMSK
10     str    r1, [r0]
11 # endif
複製程式碼

        4.時鐘設定CLKDIVN=0x3 , FCLK:HCLK:PCLK = 1:2:4

1 /* FCLK:HCLK:PCLK = 1:2:4 */
2     /* default FCLK is 120 MHz ! */
3     ldr    r0, =CLKDIVN
4     mov    r1, #3
5     str    r1, [r0]
6 #endif    /* CONFIG_S3C24X0 */

        5.詢問是否進行CPU初始化

1 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
2     bl    cpu_init_crit
3 #endif

        6.relocate函式

複製程式碼
 1 #ifndef CONFIG_SKIP_RELOCATE_UBOOT
 2 relocate:                /* relocate U-Boot to RAM        */
 3     adr    r0, _start        /* r0 <- current position of code   */
 4     ldr    r1, _TEXT_BASE        /* test if we run from flash or RAM */
 5     cmp    r0, r1            /* don't reloc during debug         */
 6     beq    stack_setup
 7 
 8     ldr    r2, _armboot_start
 9     ldr    r3, _bss_start
10     sub    r2, r3, r2        /* r2 <- size of armboot            */
11     add    r2, r0, r2        /* r2 <- source end address         */
12 
13 copy_loop:
14     ldmia    r0!, {r3-r10}        /* copy from source address [r0]    */
15     stmia    r1!, {r3-r10}        /* copy to   target address [r1]    */
16     cmp    r0, r2            /* until source end addreee [r2]    */
17     ble    copy_loop
18 #endif    /* CONFIG_SKIP_RELOCATE_UBOOT */
複製程式碼

        7.初始化堆疊

複製程式碼
 1 /* Set up the stack                            */
 2 stack_setup:
 3     ldr    r0, _TEXT_BASE        /* upper 128 KiB: relocated uboot   */
 4     sub    r0, r0, #CONFIG_SYS_MALLOC_LEN    /* malloc area              */
 5     sub    r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo                 */
 6 #ifdef CONFIG_USE_IRQ
 7     sub    r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
 8 #endif
 9     sub    sp, r0, #12        /* leave 3 words for abort-stack    */
10 
11 clear_bss:
12     ldr    r0, _bss_start        /* find start of bss segment        */
13     ldr    r1, _bss_end        /* stop here                        */
14     mov    r2, #0x00000000        /* clear                            */
15 
16 clbss_l:str    r2, [r0]        /* clear loop...                    */
17     add    r0, r0, #4
18     cmp    r0, r1
19     ble    clbss_l
複製程式碼

        8.CPU的初始化,即cpu_init_crit函式,完成以後回到主函式

複製程式碼
 1 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
 2 cpu_init_crit:
 3     /*
 4      * flush v4 I/D caches
 5      */
 6     mov    r0, #0
 7     mcr    p15, 0, r0, c7, c7, 0    /* flush v3/v4 cache */
 8     mcr    p15, 0, r0, c8, c7, 0    /* flush v4 TLB */
 9 
10     /*
11      * disable MMU stuff and caches
12      */
13     mrc    p15, 0, r0, c1, c0, 0
14     bic    r0, r0, #0x00002300    @ clear bits 13, 9:8 (--V- --RS)
15     bic    r0, r0, #0x00000087    @ clear bits 7, 2:0 (B--- -CAM)
16     orr    r0, r0, #0x00000002    @ set bit 2 (A) Align
17     orr    r0, r0, #0x00001000    @ set bit 12 (I) I-Cache
18     mcr    p15, 0, r0, c1, c0, 0
19 
20     /*
21      * before relocating, we have to setup RAM timing
22      * because memory timing is board-dependend, you will
23      * find a lowlevel_init.S in your board directory.
24      */
25     mov    ip, lr
26 
27     bl    lowlevel_init
28 
29     mov    lr, ip
30     mov    pc, lr
31 #endif /* CONFIG_SKIP_LOWLEVEL_INIT */
複製程式碼

        9.從這裡跳轉到第二階段C程式碼中去

1 ldr    pc, _start_armboot
2 
3 _start_armboot:    .word start_armboot

     C部分從檔案/lib_arm/board.c的start_armboot()函式開始

        1.定義一個struct global_data結構體指標gd,struct global_data結構體物件gd_data,

          定義一個struct bd_info結構體物件bd_data,定義一個指向函式的二級指標init_fnc_ptr,定義的全域性結構體物件都是放在堆疊中的,gd是放在暫存器中的。

        2. gd=&gd_data,gd->bd = &bd_data,並且全部空間清0。

        3.init_fnc_ptr = init_sequence(一個初始化函式指標陣列)。將會在接下來的for迴圈中提取出每一個函式來依次執行完。

        4.配置可用的flash空間,並且打印出相關資訊,flash_init()和display_flash_config()。

        5.mem_malloc_init()函式,分配堆空間.

        6.env_relocate該函式的作用是將0x33ef0000開始16K的環境引數拷貝到堆空間中去。

        7.gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr")通過這中方式獲得環境變數列表中的ipaddr引數(開發板ip),獲得環境變數中的MAC地址,設定到gd->bd->bi_enetaddr[reg]中。

        8.devices_init函式,建立了devlist,但是隻有一個串列埠設備註冊在內。

        9.console_init_r函式:控制檯完全初始化,此後可以使用函式serial_getc和serial_putc或者putc和getc來輸出log。

        10.使能中斷,如果有網絡卡裝置,設定網絡卡MAC和IP地址。

        11.main_loop ();定義於common/main.c。到此所有的初始化工作已經完成,main_loop在標準輸入裝置中接受命令,然後分析,查詢和執行。

        12.在上面的main_loop函式中,通常在開發完成的階段都會設定一個bootcmd的環境變數,然後將延時bootdelay設定成0,這樣當u-boot跑到這裡的時候就不會因為使用者按下了任意鍵就進入了命令列模式,

          可以直接執行bootcmd的命令來直接載入kernel的Image然後移交控制權。如果進入了命令列模式,我們也可以手動輸入命令來啟動系統,輸入的命令也是基本和bootcmd一樣

1 #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
2     s = getenv ("bootdelay");
3     bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
4 
5     debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);

     這個地方時設定bootdelay的地方,即在引導kernel時等待使用者命令,進入命令列模式,進行分割槽,格式化等操作。

        13.uBoot 引導核心啟動的最後一步是:通過一個函式指標 thekernel()帶三個引數跳轉到核心( zImage )入口點開始執行,此時, u-boot 的任務已經完成,控制權完全交給核心( zImage )。

          在 uBoot 的檔案lib_arm\bootm.c中定義了 thekernel, 並在 do_bootm_linux 的最後執行 thekernel。

            定義thekernel函式指標,獲取bootargs引數給commandline指標。

            theKernel (0, machid, bd->bi_boot_params);第一個引數必須為0,第二個引數為機器型別ID,第三個引數為傳遞給核心引數的起始地址0x30000100

複製程式碼
 1 int do_bootm_linux(
            
           

相關推薦

Android系統啟動過程-uBoot+Kernel+Android

轉載自:http://www.cnblogs.com/pngcui/p/4665106.html 摘要:本文是參考大量網上資源在結合自己檢視原始碼總結出來的,讓自己同時也讓大家加深對Android系統啟動過程有一個更加深入的瞭解!再次強調,本文的大多數功勞應

Android系統啟動過程

android 框架的示意圖: Linux核心啟動之後就到Android Init程序,進而啟動Android相關的服務和應用 啟動的過程如下圖所示: 一 Init程序的啟動   init程序,它是一個由核心啟動的使

Android系統啟動過程學習

使用 android 手機已經長時間了,同時,從大學學習 android 開發開始,也進行過多款 android app 專案的開發,但是對 android 內部的啟動過程,即當我們從按下電源鍵開機開始, android 系統內部是如何執行的,由於android

Android系統啟動過程分析

Android系統啟動過程分析 一、Android平臺架構 首先貼一張Android系統架構圖方便理解整個Android架構,這可以讓我們從整體上對整個啟動流程有個大概認知。 可以看出整個架構由5部分構成,從下到上分別為: 1. Linux核心層 Android 的核心繫統服務基於Linux 核心,在此基

Linux啟動流程-bootloader至kernel過程--android系統啟動流程

1 Bootloader 對於一般的ARM處理器,CPU上電或復位執行第一條指令所在地址,即第一段程式Bootloader的開始地址,Bootloader一般存於Nor-flash(XIP),支援晶片內執行。 Bootloader的功能可總結為:1)初始化CPU時鐘,記憶體

Android 的 ramdisk.img、system.img、userdata.img 作用說明,以及UBoot 系統啟動過程

一個分割槽影像檔案,它會在kernel 啟動的時候,以只讀的方式被 mount , 這個檔案中只是包含了 /init 以及一些配置檔案,這個ramdisk 被用來呼叫init,以及把真正的root file system mount 起來。 #其實ramdisk.img的內容就是/out/target/pro

Android系統啟動流程(一)解析init進程啟動過程

option 寫入 android change failed miss 通知 target sna 前言 作為“Android框架層”這個大系列中的第一個系列,我們首先要了解的是Android系統啟動流程,在這個流程中會涉及到很多重要的知識點,這個系列我們就來一一講解它們

Android系統啟動流程(一)解析init程序啟動過程

前言 作為“Android框架層”這個大系列中的第一個系列,我們首先要了解的是Android系統啟動流程,在這個流程中會涉及到很多重要的知識點,這個系列我們就來一一講解它們,這一篇我們就來學習init程序。 1.init簡介 init程序是An

android原始碼4.4.2----系統啟動過程分析

public class SystemServer {   private static final String TAG = "SystemServer";   public static final int FACTORY_TEST_OFF = 0;   public static final int F

Android系統啟動流程(二)解析Zygote程序啟動過程

前言 上一篇文章我們分析了init程序的啟動過程,啟動過程中主要做了三件事,其中一件就是建立了Zygote程序,那麼Zygote程序是什麼,它做了哪些事呢?這篇文章會給你這些問題的答案。 1.Zygote簡介 在Android系統中,DVM(D

Android系統啟動流程——解析init程序啟動過程

最近主要是在看android關機充電流程,對android啟動有些迷惑,結合網上部落格專家的文章,加一些自己的理解。 1.init簡介 init程序是Android系統中使用者空間的第一個程序,作為第一個程序,它被賦予了很多極其重要的工作職責,比如建立zygote(孵化器

Android原始碼學習之八—系統啟動過程

Android原始碼數量龐大,雖然對它的學習從未停止,但是整理成這樣的文字,實在是費時費力的一件事情,不過好在前文已經對其基本機制加以分析,相信以此為基礎,其他的內容學習起來就沒那麼困難了。 今天是20

Android系統啟動流程(四)Launcher啟動過程系統啟動流程

相關文章  Android系統架構與系統原始碼目錄  Android系統啟動流程(一)解析init程序啟動過程  Android系統啟動流程(二)解析Zygote程序啟動過程  Android系統啟動流程(三)解析SyetemServer程序啟動過程 前言

Android系統啟動流程(三)解析SyetemServer程序啟動過程

相關文章  Android系統架構與系統原始碼目錄  Android系統啟動流程(一)解析init程序啟動過程  Android系統啟動流程(二)解析Zygote程序啟動過程 前言 上一篇我們學習了Zygote程序,並且知道Zygote程序啟動了SyetemServ

Android編譯過程總結及android中各種img檔案的作用以及系統啟動過程

編譯環境:ubuntu 10.04(或者更高)(windows平臺目前不被支援) 本文以編譯android2.3為例,64位作業系統 1、編譯環境的準備  (1)確保安裝有ubuntu系統或者虛擬機器 (2)安裝JDK1.6(對於Android2.3以上程式碼) $ sud

為什麽要有uboot?帶你全面分析嵌入式linux系統啟動過程uboot的作用

統一 一次 fail 進入 是我 臺式機 平板 配置 webp 1.為什麽要有uboot 1.1、計算機系統的主要部件 (1)計算機系統就是以CPU為核心來運行的系統。典型的計算機系統有:PC機(臺式機+筆記本)、嵌入式設備(手機、平板電腦、遊戲機)、單片機(家用電器像

Android系統啟動流程

包名 more dev ted androi cap 執行 ons 開始 當系統引導程序啟動Linux內核,內核會記載各種數據結構,和驅動程序,加載完畢之後,Android系統開始啟動並加載第一個用戶級別的進程:init(system/core/init/Init.c)

為什麼要有uboot?帶你全面分析嵌入式linux系統啟動過程uboot的作用

為什麼要有uboot?帶你全面分析嵌入式linux系統啟動過程中uboot的作用 2017-08-24 18:19作業系統 1.為什麼要有uboot 1.1、計算機系統的主要部件 (1)計算機系統就是以CPU為核心來執行的系統。典型的計算機系統有:PC機(桌上型電腦+筆記

Android系統啟動-Init篇

基於Android 6.0的原始碼剖析, 分析Android啟動過程程序號為1的init程序的工作內容 /system/core/init/ - init.cpp - init_parser.cpp - signal_handler.cpp 一、概述 init

Android系統啟動流程——init程序

配置檔案:system/rootdir/init.rc     init程序是一個由核心啟動的使用者級程序。核心自行啟動之後(已經被載入記憶體,開始執行並已初始化所有裝置驅動程式和資料結構等),通過啟動一個使用者級程式init的方式完成引導過程。Init始終是第一個程序,可