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、...)は、magic1とmagic2を区別します。一致する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アップグレードのプロセス全体が完了します。
再起動後、リカバリモードに入るプロセスについては、後のトピックで説明します。