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來到核心
__reboot在arm架構的實現是這樣的(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_reboot的syscall函式對映,即
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
- /**
- * Reboot the device. Will not return if the reboot is
- * successful. Requires the {@link android.Manifest.permission#REBOOT}
- * permission.
- *
- * @param reason code to pass to the kernel (e.g., "recovery") to
- * request special boot modes, or null.
- */
- publicvoid reboot(String reason)
- {
- try {
- mService.reboot(reason);
- } catch (RemoteException e) {
- }
- }
mService為IPowerManagerBinder介面服務。
- /**
- * {@hide}
- */
- public PowerManager(IPowerManager service, Handler handler)
- {
- mService = service;
- mHandler = handler;
- }
2.frameworks/base/core/java/android/os/IPowerManager.aidl
- interface IPowerManager
- {
- ...
- void reboot(String reason);
- ...
- }
3.frameworks/base/services/java/com/android/server/PowerManagerService.java
- /**
- * Reboot the device immediately, passing 'reason' (may be null)
- * to the underlying __reboot system call. Should not return.
- */
- publicvoid reboot(String reason)
- {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
- if (mHandler == null || !ActivityManagerNative.isSystemReady()) {
- thrownew IllegalStateException("Too early to call reboot()");
- }
- final String finalReason = reason;
- Runnable runnable = new Runnable() {
- publicvoid run() {
- synchronized (this) {
- ShutdownThread.reboot(getUiContext(), finalReason, false);
- }
- }
- };
- // ShutdownThread must run on a looper capable of displaying the UI.
- mHandler.post(runnable);
- // PowerManager.reboot() is documented not to return so just wait for the inevitable.
- synchronized (runnable) {
- while (true) {
- try {
- runnable.wait();
- } catch (InterruptedException e) {
- }
- }
- }
- }
4.frameworks/base/services/java/com/android/server/pm/ShutdownThread.java
- /**
- * Request a clean shutdown, waiting for subsystems to clean up their
- * state etc. Must be called from a Looper thread in which its UI
- * is shown.
- *
- * @param context Context used to display the shutdown progress dialog.
- * @param reason code to pass to the kernel (e.g. "recovery"), or null.
- * @param confirm true if user confirmation is needed before shutting down.
- */
- publicstaticvoid reboot(final Context context, String reason, boolean confirm) {
- mReboot = true;
- mRebootSafeMode = false;
- mRebootReason = reason;
- shutdownInner(context, confirm);
- }
這裡說明是需要重啟,且不是安全模式,重啟引數為傳遞下來的reason,shutdownInner的confirm引數是用來設定是否有確認提示框的,通過reboot介面呼叫重啟是沒有的,為false。
重啟的實現在run()中,因為ShutdownThread是Thread的擴充套件,所以run會自動執行。
- /**
- * Makes sure we handle the shutdown gracefully.
- * Shuts off power regardless of radio and bluetooth state if the alloted time has passed.
- */
- publicvoid run() {
- BroadcastReceiver br = new BroadcastReceiver() {
- @Overridepublicvoid onReceive(Context context, Intent intent) {
- // We don't allow apps to cancel this, so ignore the result.
- actionDone();
- }
- };
- /*
- * Write a system property in case the system_server reboots before we
- * get to the actual hardware restart. If that happens, we'll retry at
- * the beginning of the SystemServer startup.
- */
- {
- String reason = (mReboot ? "1" : "0") + (mRebootReason != null ? mRebootReason : "");
- SystemProperties.set(SHUTDOWN_ACTION_PROPERTY, reason);
- }
- /*
- * If we are rebooting into safe mode, write a system property
- * indicating so.
- */
- if (mRebootSafeMode) {
- SystemProperties.set(REBOOT_SAFEMODE_PROPERTY, "1");
- }
- ...
- rebootOrShutdown(mReboot, mRebootReason);
- }
在重啟前會將重啟原因寫入sys.shutdown.requested,如果沒有則為空,如果是安全模式還會將persist.sys.safemode置1,之後會進行一些關機前的預處理,關閉ActivityManager以及MountService,最終呼叫rebootOrShutdown進行關機操作。
- /**
- * Do not call this directly. Use {@link #reboot(Context, String, boolean)}
- * or {@link #shutdown(Context, boolean)} instead.
- *
-
相關推薦
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開發環境&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中鎖屏密碼算法,然後用一種高效的方式