1. 程式人生 > >Android fastboot下載模式或reboot流程解析

Android fastboot下載模式或reboot流程解析

解析目的,使用天嵌開發板,發現用adbreboot bootloader機器沒有進入uboot fastboot模式下而是直接重啟;經發現,天嵌不是使用reboot bootloader,而是使用rebootfastboot。

因此我們從底層往上次分析(uboot -kernel - Android)。

深入分析:

uboot:

程式碼分析:

uboot-imx\lib_arm\board.c

void start_armboot (void)   uboot入口函式

{

-----------

#ifdef CONFIG_FASTBOOT

         check_fastboot_mode();

#endif

         /*main_loop() can return to retry autoboot, if so just run it again. */

         for(;;) {

                   main_loop();

         }

----------

}

uboot-imx\drivers\fastboot\ fastboot.c

void check_fastboot_mode(void)

{

         if(fastboot_check_and_clean_flag())

                   do_fastboot(NULL,0, 0, 0);

}

uboot-imx\cpu\arm_cortexa8\mx6\generic.c

int fastboot_check_and_clean_flag(void)

{

         intflag_set = 0;

         u32reg;

         reg= readl(SNVS_BASE_ADDR + SNVS_LPGPR);

         flag_set= !!(reg & ANDROID_FASTBOOT_BOOT);

         /*clean it in case looping infinite here.... */

         if(flag_set) {

                   reg&= ~ANDROID_FASTBOOT_BOOT;

                   writel(reg,SNVS_BASE_ADDR + SNVS_LPGPR);

         }

         returnflag_set;

}

uboot-imx\include\asm-arm\arch-mx6\mx6.h

MX6Q_SNVS_BASE_ADDR   = 0x02000000 + 0x4C000

SNVS_LPGPR = 0x68

fastboot_check_and_clean_flag函式主要是從暫存器中讀取標誌位,以判斷是否需要進入fastboot模式。該標誌位在kernel中進行設定,在下一步會進行解析。

我回到do_fastboot(NULL, 0,0, 0);函式,該函式直接呼叫fastboot服務。

uboot-imx\common\cmd_fastboot.c fastboot服務具體做的工作就是下載燒寫,具體就不再這裡描述了。

注意:這裡必須開啟fastboot下載功能,巨集定義位於:uboot-imx\include\configs\ mx6q_sabresd_android.h (CONFIG_FASTBOOT)

kernel:

1.reboot入口

__reboot通過syscall來到核心

__rebootarm架構的實現是這樣的(bionic/libc/arch-arm/syscalls/__reboot.S:

ENTRY(__reboot)

    .save   {r4, r7} 

    stmfd   sp!, {r4, r7}

    ldr     r7, =__NR_reboot

    swi     #0  

    ldmfd   sp!, {r4, r7}

    movs    r0, r0

    bxpl    lr  

    b       __set_syscall_errno

END(__reboot)

2.reboot實現入口

__NR_reboot實現部分:

kernel_imx\arch\arm\include\asm\unistd.h

#define __NR_swapon                       (__NR_SYSCALL_BASE+ 87)

#define __NR_reboot                         (__NR_SYSCALL_BASE+ 88)

其被指定了一個固定的偏移量,在被呼叫的時候就是通過這個偏移量去核心中尋找對應的入口的,由此可見,核心中一定有著相同的定義,否則將不能成功呼叫。核心中對syscall偏移量的定義在核心原始碼中的arch/arm/include/asm/unistd.h,相關資訊完全一致。

已經找到了核心中的對應對映,那麼下一步就要去找尋真正的實現函數了,在include/asm-generic/unistd.h中可以找到核心對__NR_rebootsyscall函式對映,即

kernel_imx\include\asm-generic\unistd.h

/* kernel/sys.c */

#define __NR_setpriority 140

__SYSCALL(__NR_setpriority,sys_setpriority)

#define __NR_getpriority 141

__SYSCALL(__NR_getpriority, sys_getpriority)

#define __NR_reboot 142

__SYSCALL(__NR_reboot, sys_reboot)

kernel_imx\kernel\sys.c 入口函式

SYSCALL_DEFINE4(reboot, int, magic1, int,magic2, unsigned int, cmd,void __user *, arg)

通過kernel_imx\include\linux\syscalls.h巨集定義解析之後呈現函式為:

asmlinkage long sys_reboot(intmagic1, int magic2, unsigned int cmd,void __user *arg);

具體實現:

#define SYSCALL_DEFINE4(name, ...)SYSCALL_DEFINEx(4, _##name, __VA_ARGS__)

----------------

#define SYSCALL_DEFINEx(x, sname, ...)                                     \

----------------------

__SYSCALL_DEFINEx(x, sname, __VA_ARGS__)

---------------------

#define __SYSCALL_DEFINEx(x, name, ...)

----------------------

asmlinkage longsys##name(__SC_DECL##x(__VA_ARGS__))

回到SYSCALL_DEFINE4函式呼叫kernel_restart(buffer);

void kernel_restart(char *cmd)

{

         kernel_restart_prepare(cmd);

         if(!cmd)

                   printk(KERN_EMERG"Restarting system.\n");

         else

                   printk(KERN_EMERG"Restarting system with command '%s'.\n", cmd);

         kmsg_dump(KMSG_DUMP_RESTART);

         machine_restart(cmd);

}

kernel_imx\arch\arm\kernel\process.c

void machine_restart(char *cmd)

{

         machine_shutdown();

         arm_pm_restart(reboot_mode,cmd);

}

定義指標函式

void (*arm_pm_restart)(char str, const char*cmd) = arm_machine_restart;

EXPORT_SYMBOL_GPL(arm_pm_restart);

void arm_machine_restart(char mode, constchar *cmd)

{

         /*Flush the console to make sure all the relevant messages make it

          * out to the console drivers */

         arm_machine_flush_console();

         /*Disable interrupts first */

         local_irq_disable();

         local_fiq_disable();

         /*

          * Tell the mm system that we are going toreboot -

          * we may need it to insert some 1:1 mappingsso that

          * soft boot works.

          */

         setup_mm_for_reboot(mode);

         /*Clean and invalidate caches */

         flush_cache_all();

         /*Turn off caching */

         cpu_proc_fin();

         /*Push out any further dirty data, and ensure cache is empty */

         flush_cache_all();

         /*

          * Now call the architecture specific rebootcode.

          */

         arch_reset(mode,cmd);

         /*

          * Whoops - the architecture was unable toreboot.

          * Tell the user!

          */

         mdelay(1000);

         printk("Rebootfailed -- System halted\n");

         while(1);

}

arch_reset  函式為rebootBootLoader實現的最後位置,這裡紅色部分fastboot其實標準應該為bootLoader。cpu_reset(0);該函式跳轉到機器地址起始位,執行重啟。

kernel_imx\arch\arm\plat-mxc\system.c

static void arch_reset_special_mode(charmode, const char *cmd)

{

         if(strcmp(cmd, "download") == 0)

                   do_switch_mfgmode();

         elseif (strcmp(cmd, "recovery") == 0)

                   do_switch_recovery();

         elseif (strcmp(cmd, "fastboot") == 0)

                   do_switch_fastboot();

}

void arch_reset(char mode, const char *cmd)

{

         unsignedint wcr_enable;

         arch_reset_special_mode(mode,cmd);

    --------------------------------------

         if(cpu_is_mx1()) {

                   wcr_enable= (1 << 0);

         }else {

                   structclk *clk;

                   clk= clk_get_sys("imx2-wdt.0", NULL);

                   if(!IS_ERR(clk))

                            clk_enable(clk);

                   wcr_enable= (1 << 2);

         }

         /*Assert SRS signal */

         __raw_writew(wcr_enable,wdog_base);

         /*wait for reset to assert... */

         mdelay(500);

         printk(KERN_ERR"Watchdog reset failed to assert reset\n");

         /*delay to allow the serial port to show the message */

         mdelay(50);

         /*we'll take a jump through zero as a poor second */

         cpu_reset(0);

}

fastboot標誌寫入暫存器中。

kernel_imx\arch\arm\mach-mx6\system.c

void do_switch_fastboot(void)

{

         u32reg;

         reg= __raw_readl(MX6Q_SNVS_BASE_ADDR + SNVS_LPGPR);

         reg|= ANDROID_FASTBOOT_BOOT;

         __raw_writel(reg,MX6Q_SNVS_BASE_ADDR + SNVS_LPGPR);

}

arch_reset函式操作完後直接重啟機器。

Android:

該層與安卓系統通用,這裡引用網路解析。

1.frameworks/base/core/java/android/os/PowerManager.java

  1. /**  
  2.  * Reboot the device.  Will not return if the reboot is 
  3.  * successful.  Requires the {@link android.Manifest.permission#REBOOT} 
  4.  * permission. 
  5.  * 
  6.  * @param reason code to pass to the kernel (e.g., "recovery") to 
  7.  *               request special boot modes, or null. 
  8.  */
  9. publicvoid reboot(String reason)  
  10. {     
  11.     try {  
  12.         mService.reboot(reason);  
  13.     } catch (RemoteException e) {  
  14.     }     

mServiceIPowerManagerBinder介面服務。

  1. /** 
  2.  * {@hide} 
  3.  */
  4. public PowerManager(IPowerManager service, Handler handler)  
  5. {  
  6.     mService = service;  
  7.     mHandler = handler;  
  8. }  

2.frameworks/base/core/java/android/os/IPowerManager.aidl

  1. interface IPowerManager  
  2. {  
  3. ...  
  4. void reboot(String reason);  
  5. ...  
  6. }  

3.frameworks/base/services/java/com/android/server/PowerManagerService.java

  1. /**   
  2.  * Reboot the device immediately, passing 'reason' (may be null) 
  3.  * to the underlying __reboot system call.  Should not return. 
  4.  */
  5. publicvoid reboot(String reason)  
  6. {      
  7.     mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);  
  8.     if (mHandler == null || !ActivityManagerNative.isSystemReady()) {  
  9.         thrownew IllegalStateException("Too early to call reboot()");  
  10.     }      
  11.     final String finalReason = reason;  
  12.     Runnable runnable = new Runnable() {  
  13.         publicvoid run() {  
  14.             synchronized (this) {  
  15.                 ShutdownThread.reboot(getUiContext(), finalReason, false);  
  16.             }      
  17.         }      
  18.     };     
  19.     // ShutdownThread must run on a looper capable of displaying the UI.
  20.     mHandler.post(runnable);  
  21.     // PowerManager.reboot() is documented not to return so just wait for the inevitable.
  22.     synchronized (runnable) {  
  23.         while (true) {  
  24.             try {  
  25.                 runnable.wait();  
  26.             } catch (InterruptedException e) {   
  27.             }      
  28.         }      
  29.     }      
  30. }  

4.frameworks/base/services/java/com/android/server/pm/ShutdownThread.java

  1. /** 
  2.  * Request a clean shutdown, waiting for subsystems to clean up their 
  3.  * state etc.  Must be called from a Looper thread in which its UI 
  4.  * is shown. 
  5.  * 
  6.  * @param context Context used to display the shutdown progress dialog. 
  7.  * @param reason code to pass to the kernel (e.g. "recovery"), or null. 
  8.  * @param confirm true if user confirmation is needed before shutting down. 
  9.  */
  10. publicstaticvoid reboot(final Context context, String reason, boolean confirm) {  
  11.     mReboot = true;  
  12.     mRebootSafeMode = false;  
  13.     mRebootReason = reason;  
  14.     shutdownInner(context, confirm);  
  15. }  

這裡說明是需要重啟,且不是安全模式,重啟引數為傳遞下來的reason,shutdownInner的confirm引數是用來設定是否有確認提示框的,通過reboot介面呼叫重啟是沒有的,為false。

重啟的實現在run()中,因為ShutdownThreadThread的擴充套件,所以run會自動執行。

  1. /** 
  2.  * Makes sure we handle the shutdown gracefully. 
  3.  * Shuts off power regardless of radio and bluetooth state if the alloted time has passed. 
  4.  */
  5. publicvoid run() {  
  6.     BroadcastReceiver br = new BroadcastReceiver() {  
  7.         @Overridepublicvoid onReceive(Context context, Intent intent) {  
  8.             // We don't allow apps to cancel this, so ignore the result.
  9.             actionDone();  
  10.         }  
  11.     };  
  12.     /* 
  13.      * Write a system property in case the system_server reboots before we 
  14.      * get to the actual hardware restart. If that happens, we'll retry at 
  15.      * the beginning of the SystemServer startup. 
  16.      */
  17.     {     
  18.         String reason = (mReboot ? "1" : "0") + (mRebootReason != null ? mRebootReason : "");  
  19.         SystemProperties.set(SHUTDOWN_ACTION_PROPERTY, reason);  
  20.     }  
  21.     /* 
  22.      * If we are rebooting into safe mode, write a system property 
  23.      * indicating so. 
  24.      */
  25.     if (mRebootSafeMode) {  
  26.         SystemProperties.set(REBOOT_SAFEMODE_PROPERTY, "1");  
  27.     }  
  28.     ...  
  29.     rebootOrShutdown(mReboot, mRebootReason);  
  30. }  

在重啟前會將重啟原因寫入sys.shutdown.requested,如果沒有則為空,如果是安全模式還會將persist.sys.safemode1,之後會進行一些關機前的預處理,關閉ActivityManager以及MountService,最終呼叫rebootOrShutdown進行關機操作。

  1. /** 
  2.      * Do not call this directly. Use {@link #reboot(Context, String, boolean)} 
  3.      * or {@link #shutdown(Context, boolean)} instead. 
  4.      * 
  5. 相關推薦

    Android fastboot下載模式reboot流程解析

    解析目的,使用天嵌開發板,發現用adbreboot bootloader機器沒有進入uboot fastboot模式下而是直接重啟;經發現,天嵌不是使用reboot bootloader,而是使用rebootfastboot。 因此我們從底層往上次分析(uboot

    Android中system server程序啟動流程原始碼解析 系統服務啟動

    system server 前言 System Server fork SystemServer SystemServer.main() SystemServer.createSystemContext SystemSe

    Android Framework學習(四)之Launcher啟動流程解析

    在之前的部落格中,我們學習了init程序、Zygote程序和SyetemServer程序的啟動過程,我們知道SystemServer程序主要用於啟動系統的各種服務,二者其中就包含了負責啟動Launcher的服務,LauncherAppService,本篇部落格我

    Android 觸控事件傳遞流程解析

    android中的Touch事件都是從ACTION_DOWN開始的: 單手指操作:ACTION_DOWN---ACTION_MOVE----ACTION_UP 多手指操作:ACTION_DOWN---ACTION_POINTER_DOWN---ACTION_MOV

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

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

    android app 快取 ---- android 檔案快取使用流程解析

    在度娘那裡搜尋了一下,關於android 快取的資源介紹,發現都是泛泛而談,沒有給出詳細的使用方法。看各路大神的介紹,快取一般分為兩種形式(1.資料庫快取,2.檔案快取)。 資料庫快取,看到這個名字,想必都知道怎麼回事了,將網路請求的資料,一一對應存入本地資料庫中,來達到

    Android 筆記-Linux Kernel SMP (Symmetric Multi-Processors) 開機流程解析 Part(4) Linux 多核心啟動流程-kthreadd 與相關的

    by  loda [email protected] Loda's Blog kthread第一次出現在LinuxKernel中是在Kernel版本2.6.4時,一開始的實作尚未有本文提到的kthreaddTask的具體架構,隨著版本的演進,除了這部份的設計完整外,需要

    Android原始碼設計模式解析與實戰(第一章面向物件的六大原則)

        買了很多書,也看了很多,但有一個毛病就是看的時候很明白,但是看過不久就忘了,可見溫故而知新是很重要的,所以想重拾上學時的習慣,記筆記好了,經常來看看,記錄下看的時候的心得、體會。鼓勵自己堅持下去     OOP在java中很重要,提到OOP就會想到面向物件的六大原則

    Android Fastboot 模式下刷機教程

    1.進入fastboot模式,一般是電源加音量上下鍵然後10s左右. 2.fastboot devices 看看有沒有許可權訪問 .如果沒有lsusb檢視你的手機埠資訊: 例如: Bus 002 Device 001: ID 1d6b:0003 Li

    Android原始碼設計模式解析與實戰》讀書筆記

    1.定義 將物件組合成樹形結構以表示“部分-整體”的層次結構,使得使用者對單個物件和組合物件的使用具有一致性。 2.使用場景 (1)表示物件的部分-整體層次結構時。 (2)從一個整體中能夠獨立出部分模組或功能的場景。 3.UML類圖 (1)Componen

    Android USB相關流程解析(android4.4)

    前言: 對於USB的一些常量屬性,比如:UsbManager. USB_FUNCTION_RNDIS(USB的模式)等,現在也是一個比較模糊的概念,只能具體問題具體分析,我們重點說的是類結構,與USB整個框架(僅限於framework層)的邏輯。本來想畫一張流程圖呢。畫來

    Android TV】按鍵事件KeyEvent的分發處理流程解析

    這次打算來梳理一下 Android Tv 中的按鍵點選事件 KeyEvent 的分發處理流程。一談到點選事件機制,網上資料已經非常齊全了,像什麼分發、攔截、處理三大流程啊;或者dispatchTouchEvent、onInterceptTouchEvent、

    Android 多執行緒下載檔案原理霸氣解析介紹 -----檔案的下載(3)

    1、首先我們先建立好下載的位置–根據url建立檔案。 /** * <p>Title: FlieStorageManager</p > * <p>Description: TODO</p > * <

    Android Init流程解析

    ***************************************************************************         ******************************************************

    Android的init過程:init.rc解析流程

    這幾天打算看下安卓的程式碼,看優秀的原始碼也是一種學習過程,看原始碼的過程就感覺到,安卓確實是深受linux核心的影響,不少資料結構的用法完全一致。花了一中午時間,研究了下init.rc解析過程,做個記錄。 init.rc 檔案並不是普通的配置檔案,而是由一種被稱為“A

    關於Android手機MTP模式連接的一些設置(win7和ubuntu下,以紅米1s為例)

    sta start .net eno bcm htm web date ati 有些手機的MTP模式在電腦上識別不了,須要一些設置才幹夠,以下就網上收集來的一些設置方法集中貼過來: 一、 win7下 參考:http://blog.ammrli.com/?p=11

    PHP開發環境&amp;MySQL下載安裝及配置流程

    str gb2312 sni _array 連接 login log res apache2 PHP開發環境&MySQL下載安裝及配置流程 因工作須要,從0開始學PHP,前幾天看完視頻教程後開始搞開發環境,到今天才好。這裏把安裝配置流程梳理一下分享

    Android提示版本號更新操作流程

    star reader ets set cto ade positive don bject Android提示版本號更新操作流

    BAT Androidproject師面試流程解析+還原最真實最完整的一線公司面試題

    需要 綜合 沒有機會 渠道 考核 XML 升級 通訊 這也 尊重原創,轉載請寫明原文出處:http://blog.csdn.net/sk719887916/article/details/47040931 (skay) 求職和我

    Android中鎖屏密碼算法解析以及破解方案

    .net water mda 介紹 數據 watermark 悲劇 ids 界面 一、前言 最近玩王者榮耀,下載了一個輔助樣本,結果被鎖機了,當然破解它很簡單,這個後面會詳細分析這個樣本,但是因為這個樣本引發出的欲望就是解析Android中鎖屏密碼算法,然後用一種高效的方式