Android系統的reboot之我見

近段時間關注Android系統的reboot部分,在應用程序調用reboot函數可以實現重啓。順着流程看看reboot如何運作。

在Watchdog.java文件裏,有一例:

    void rebootSystem(String reason) {

        Slog.i(TAG, "Rebooting system because: " + reason);

        //註冊PowerManager服務

PowerManagerService pms = (PowerManagerService) ServiceManager.getService("power");

//調用reboot()方法

        pms.reboot(reason);

    }

下面順着往下走,

Step1:

在PowerManagerService.java文件

    public void reboot(String reason)

    {

       // REBOOT權限

     mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);

      final String finalReason = reason;

      Runnable runnable = new Runnable() {

         public void run() {

                synchronized (this) {

                    //這裏執行reboot

                    ShutdownThread.reboot(mContext, finalReason, false);

                }

               

            }

        };

           …..

    }

Step2:

    在ShutdownThread.java文件:

    public final class ShutdownThread extends Thread {

                            …

      //這裏是reboot函數

      public static void reboot(final Context context, String reason, boolean confirm) {

        mReboot = true;// mReboot爲true

          ….

    }

     public void run() {

      

       …

        rebootOrShutdown(mReboot, mRebootReason);//其實這裏執行是reboot

    }

    public static void rebootOrShutdown(boolean reboot, String reason) {

        // reboot爲真,執行Power.reboot()方法

        if (reboot) {

            Log.i(TAG, "Rebooting, reason: " + reason);

            try {

                Power.reboot(reason);

            } catch (Exception e) {

                Log.e(TAG, "Reboot failed, will attempt shutdown instead", e);

            }

        } else if (SHUTDOWN_VIBRATE_MS > 0) {

            …

        // Shutdown power

        Log.i(TAG, "Performing low-level shutdown...");

        Power.shutdown();//執行Power類的shutdown方法

    }

}

 

Step3:

在Power.java文件:

public class Power{

    …

    public static void reboot(String reason) throws IOException

    {

        rebootNative(reason);//調用JNI的reboo方法

    }

    //聲明rebootNative

    private static native void rebootNative(String reason) throws IOException ;

    …

}

 

Step4:

在android_os_Power.cpp文件:

// #define HAVE_ANDROID_OS 1

static void android_os_Power_reboot(JNIEnv *env, jobject clazz, jstring reason)

{

    sync();

#ifdef HAVE_ANDROID_OS

    // 字符reason爲空的話,執行自動重起

    if (reason == NULL) {

        reboot(RB_AUTOBOOT);

    } else {

    //有原因的重啓

        const char *chars = env->GetStringUTFChars(reason, NULL);

        //調用__reboot()

        __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,

                 LINUX_REBOOT_CMD_RESTART2, (char*) chars);

        env->ReleaseStringUTFChars(reason, chars);  // In case it fails.

    }

    jniThrowIOException(env, errno);

#endif

}

 

Step5:

關於reboot()方法的來頭,在bionic\libc\unistd\reboot.c文件裏:

int reboot (int  mode)

{

    //傳NULL到__reboot函數

    return __reboot( LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, mode, NULL );

}

總的來說,歸結一點是__reboot()函數。

 

Step6:

看看__reboot()的來由,在bionic\libc\arch-arm\syscalls\__reboot.S文件裏:

//  # define __NR_SYSCALL_BASE  0x900000

//#define __NR_reboot  (__NR_SYSCALL_BASE + 88)

.text

    .type __reboot, #function

    .globl __reboot

    .align 4

    .fnstart

__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

    .fnend

這是__reboot函數用匯編實現,用C語言來調用。關機部分可以這樣來分析。

發佈了18 篇原創文章 · 獲贊 5 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章