Android OTAアップグレード(2):アップグレードプロセスを開始します

Tian Haili @ CSDN

2013-3-31

 

OTAアップグレードパッケージをネットワーク経由またはローカルで直接取得した後、プログラムからAndroidアップグレードを開始できます。この記事では、このプロセスについて説明します。

 

OTAアップグレードパッケージを入手した後、android.os.RecoverySystem.installPackage()を介してOTAアップグレードを直接開始できます。

RecoverySystem.installPackage()はAPI-8の後に追加されました。これを使用するには、次の権限が必要です:android.Manifest.permission.REBOOT

 

1つは、RecoverySystem#installPackage()の実現です。

 

RecoverySystem.installPackage()は、受信ファイルのファイル名をarg "--update_package = <filename>" [<filename>は特定のファイルに置き換えられます]を介して渡し、bootCommand()を呼び出して実行します。

 

bootCommand()の実装:

        FileWriter command= new FileWriter(COMMAND_FILE);
        try {
           command.write(arg);
           command.write("\n");
        } finally {
           command.close();
        }
 
        // Having writtenthe command file, go ahead and reboot
        PowerManager pm =(PowerManager) context.getSystemService(Context.POWER_SERVICE);
       pm.reboot("recovery");

COMMAND_FILEは「/ cache / recovery / command」です。bootCommand()は、「-update_package = <filename>」を/ cache / recovery / commandに書き込み、BinderIPCを介してPowerManagerServiceのreboot()を呼び出し、「recovery」をパラメーターとして渡します。

 

第二に、PowerManagerService#rebootの実現


PowerManagerService.reboot(reason:String)は、ShutdownThread.reboot(mContext、finalReason、false)の実行を開始することによって実現されます。

 

実行シーケンス図を図に示します。値は次のとおりです。

-理由:「回復」;

-確認:false;

-rebootOrShutdownのパラメーターの値は次のとおりです。reboot<-mReboot; reason <-mRebootReason;

最後に、Power.reboot()が呼び出され、そのc実装がJNIを介して呼び出されます。

 

Power.javaのJNI実装は、android_os_power.cppにあります。


3.Power.rebootのネイティブ実装


Power.reboot()は、android_os_Power_reboot [frameworks / base / core / jni /android_os_power.cpp]を介して実装されます

static void android_os_Power_reboot(JNIEnv *env, jobject clazz,jstring reason)
{
    sync();
#ifdef HAVE_ANDROID_OS
    if (reason == NULL) {
       reboot(RB_AUTOBOOT);
    } else {
        const char *chars =env->GetStringUTFChars(reason, NULL);
       __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
}

システムは__rebootを呼び出し、カーネルを埋め込んで再起動を実現します。

 

カーネルモードで、sys_rebootシステム定義を入力します。

 

第四に、sys_rebootの定義と実装


sys_rebootの定義と実装は、カーネル内のコードによって異なります。 

// kernel/kernel/sys.c
SYSCALL_DEFINE4(reboot, int, magic1, int,magic2, unsigned int, cmd,
                                void__user *, arg)
 
//kernel/include/linux/syscalls.h
#define __SYSCALL_DEFINEx(x, name, ...)                                                                  \
                asmlinkagelong sys##name(__SC_DECL##x(__VA_ARGS__))
 
#define SYSCALL_DEFINEx(x, sname, ...)                                                     \
                __SYSCALL_DEFINEx(x,sname, __VA_ARGS__)
 
#define SYSCALL_DEFINE4(name, ...)SYSCALL_DEFINEx(4, _##name, __VA_ARGS__)

したがって、sys.cのSYSCALL_DEFINE4(reboot、...)はsys_reboot()を実装します。

 

SYSCALL_DEFINE4(reboot、...)はmagic1magic2を区別します。一致するmagic1とmagic2のみが処理され、それ以外の場合は直接返されます。

cmd LINUX_REBOOT_CMD_RESTART2の場合:再起動の理由をユーザーモードからカーネルモードにコピーし、kernel_restart()を呼び出して実行します。

 

kernel_restart(char * cmd)は最初にkernel_restart_prepare(cmd);を呼び出し、次にmachine_restart(cmd);を呼び出します。 

// kernel/kernel/sys.c
void kernel_restart_prepare(char *cmd)
{
                blocking_notifier_call_chain(&reboot_notifier_list,SYS_RESTART, cmd);
                system_state= SYSTEM_RESTART;
                device_shutdown();
                sysdev_shutdown();
}

 

//kernel/arch/arm/kernel/process.c
void machine_restart(char *cmd)
{
                arm_pm_restart(reboot_mode,cmd);
}

arm_pm_restartは、特定のプラットフォームによって定義されたマシン再起動の関数ポインターを指します。プロトタイプはvoid(* arm_pm_restart)(char str、const char * cmd)です。

特定の実装は、使用される特定のプラットフォームに関連しているため、ここでは説明しません。

 

総括する


この記事では、AndroidでフレームワークからJNI、次にカーネルレイヤーへのOTAアップグレードを開始するプロセスについて説明します。レイヤーごとの関係の分析は、いわゆるOTAアップグレードが/ cache / recovery / commandに「-」を入力することによって開始されることを示しています。 -update_package = <filename>」が書き込まれ、カーネルモードに転送されて、システム呼び出しを介してシステム呼び出しが実行され、マシンの再起動が実現され、OTAアップグレードのプロセス全体が完了します。

再起動後、リカバリモードに入るプロセスについては、後のトピックで説明します。

 

おすすめ

転載: blog.csdn.net/thl789/article/details/8743768