Android------recovery 模式启动进入流程

来源:互联网 发布:安卓游戏大作 知乎 编辑:程序博客网 时间:2024/05/17 05:06
 

Android------recovery 模式启动进入流程

 4433人阅读 评论(0) 收藏 举报
 分类:
1.  上层应用的设置->隐私权->恢复出厂设置对应的java代码在如下路径文件:
 packages/apps/Settings/src/com/android/settings/MasterClear.java
 MasterClear:mFinalClickListener()函数会发送一个广播出去:
 sendBroadcast(new Intent("android.intent.action.MASTER_CLEAR"));

2.  这个广播的接收者在收到广播之后会开启一个java服务线程:MasterClearReceiver:RebootThread
 frameworks/base/services/java/com/Android/server/MasterClearReceiver.java  -- TAG = "MasterClear"
 public void onReceive(Context context, Intent intent) {

[cpp] view plaincopy
  1.     RebootThread mThread = new RebootThread(context, intent);  
  2.     mThread.start();  
  3. }  


    在线程的run函数中会调用函数:RecoverySystem.rebootWipeUserData(mContext);这个方法是RecoverySystem类的静态方法。

3.  RecoverySystem类定义于文件:frameworks/base/core/java/android/os/RecoverySystem.java   --  TAG = "RecoverySystem"
 

[cpp] view plaincopy
  1. public class RecoverySystem {  
  2.   /** Used to communicate with recovery.  See bootable/recovery/recovery.c. */  
  3.       private static File RECOVERY_DIR = new File("/cache/recovery");  
  4.      private static File COMMAND_FILE = new File(RECOVERY_DIR, "command");  
  5.      private static File LOG_FILE = new File(RECOVERY_DIR, "log");  
  6.     
  7.   public static void rebootWipeUserData(Context context)  
  8.          throws IOException {  
  9.          bootCommand(context, "--wipe_data");  
  10.      }  
  11.        
  12.      private static void bootCommand(Context context, String arg) throws IOException {  
  13.          RECOVERY_DIR.mkdirs();  // In case we need it  
  14.          COMMAND_FILE.delete();  // In case it's not writable  
  15.          LOG_FILE.delete();  
  16.    
  17.          FileWriter command = new FileWriter(COMMAND_FILE);  
  18.          try {  
  19.              command.write(arg);  // 往文件/cache/recovery/command中写入recovery ELF的执行参数。  
  20.              command.write("\n");  
  21.          } finally {  
  22.              command.close();  
  23.          }  
  24.    
  25.          // Having written the command file, go ahead and reboot  
  26.          PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);  
  27.          pm.reboot("recovery");  // 调用PowerManager类中的reboot方法  
  28.    
  29.          throw new IOException("Reboot failed (no permissions?)");  
  30.      }  
  31.  }  


 
4.  PowerManager类定义于文件:frameworks/base/core/java/android/os/PowerManager.java  --  TAG = "PowerManager"
[cpp] view plaincopy
  1. public class PowerManager  
  2. {  
  3.  ...  
  4.  public void reboot(String reason)  
  5.     {  
  6.         try {  
  7.             mService.reboot(reason);  
  8.         } catch (RemoteException e) {  
  9.         }  
  10.     }  
  11.    
  12.   public PowerManager(IPowerManager service, Handler handler)  
  13.     {  
  14.         mService = service;  
  15.         mHandler = handler;  
  16.     }  
  17.    
  18.  IPowerManager mService;  
  19.     Handler mHandler;  
  20. }  


5.  mService指向的是PowerManagerService类,这个类定义于文件:

[cpp] view plaincopy
  1. frameworks/base/services/java/com/android/server/PowerManagerService.java  --  TAG = "PowerManagerService"  
  2. /** 
  3.     * Reboot the device immediately, passing 'reason' (may be null) 
  4.     * to the underlying __reboot system call.  Should not return. 
  5.     */  
  6.    public void reboot(String reason)  
  7.    {  
  8.        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);  
  9.   
  10.        if (mHandler == null || !ActivityManagerNative.isSystemReady()) {  
  11.            throw new IllegalStateException("Too early to call reboot()");  
  12.        }  
  13.   
  14.        final String finalReason = reason;  
  15.        Runnable runnable = new Runnable() {  
  16.            public void run() {  
  17.                synchronized (this) {  
  18.                    ShutdownThread.reboot(mContext, finalReason, false);  
  19.                } // 调用ShutdownThread服务中的reboot方法  
  20.                 
  21.            }  
  22.        };  
  23.        // ShutdownThread must run on a looper capable of displaying the UI.  
  24.        mHandler.post(runnable);  
  25.   
  26.        // PowerManager.reboot() is documented not to return so just wait for the inevitable.  
  27.        synchronized (runnable) {  
  28.            while (true) {  
  29.                try {  
  30.                    runnable.wait();  
  31.                } catch (InterruptedException e) {  
  32.                }  
  33.            }  
  34.        }  
  35.    }  

[cpp] view plaincopy
  1. frameworks/base/services/java/com/android/server/PowerManagerService.java  --  TAG = "PowerManagerService"  
  2. /** 
  3.     * Reboot the device immediately, passing 'reason' (may be null) 
  4.     * to the underlying __reboot system call.  Should not return. 
  5.     */  
  6.    public void reboot(String reason)  
  7.    {  
  8.        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);  
  9.   
  10.        if (mHandler == null || !ActivityManagerNative.isSystemReady()) {  
  11.            throw new IllegalStateException("Too early to call reboot()");  
  12.        }  
  13.   
  14.        final String finalReason = reason;  
  15.        Runnable runnable = new Runnable() {  
  16.            public void run() {  
  17.                synchronized (this) {  
  18.                    ShutdownThread.reboot(mContext, finalReason, false);  
  19.                } // 调用ShutdownThread服务中的reboot方法  
  20.                 
  21.            }  
  22.        };  
  23.        // ShutdownThread must run on a looper capable of displaying the UI.  
  24.        mHandler.post(runnable);  
  25.   
  26.        // PowerManager.reboot() is documented not to return so just wait for the inevitable.  
  27.        synchronized (runnable) {  
  28.            while (true) {  
  29.                try {  
  30.                    runnable.wait();  
  31.                } catch (InterruptedException e) {  
  32.                }  
  33.            }  
  34.        }  
  35.    }  


6.  ShutdownThread类在下列文件中实现:
[cpp] view plaincopy
  1. frameworks/base/core/java/com/android/internal/app/ShutdownThread.java   -- TAG = "ShutdownThread"  
  2. public final class ShutdownThread extends Thread {  
  3.  ...  
  4.  public static void reboot(final Context context, String reason, boolean confirm) {  
  5.         mReboot = true;  
  6.         mRebootReason = reason;  
  7.         shutdown(context, confirm);  
  8.     }  
  9.      
  10.     ...  
  11.     public void run() {  
  12.      ...  
  13.      if (mReboot) {  
  14.             Log.i(TAG, "Rebooting, reason: " + mRebootReason);  
  15.             try {  
  16.                 Power.reboot(mRebootReason);  
  17.             } catch (Exception e) {  
  18.                 Log.e(TAG, "Reboot failed, will attempt shutdown instead", e);  
  19.             }  
  20.         } else if (SHUTDOWN_VIBRATE_MS > 0) {  
  21.             ...  
  22.         }  
  23.         ...  
  24.     }  
  25. }  


 流程:reboot() --> shutdown() --> beginShutdownSequence() --> sInstance.start() --> run() --> Power.reboot(mRebootReason).
 最后调用Power类的reboot方法。

7.  Power类定义于文件: frameworks/base/core/java/android/os/Power.java    --- 

[cpp] view plaincopy
  1. public class Power  
  2. {  
  3.  ...  
  4.  public static void reboot(String reason) throws IOException  
  5.     {  
  6.         rebootNative(reason);  
  7.     }  
  8.   
  9.     private static native void rebootNative(String reason) throws IOException ;  
  10. }  


[cpp] view plaincopy
  1. frameworks/base/core/java/android/os/Power.java    ---  
  2. public class Power  
  3. {  
  4.  ...  
  5.  public static void reboot(String reason) throws IOException  
  6.     {  
  7.         rebootNative(reason);  
  8.     }  
  9.   
  10.     private static native void rebootNative(String reason) throws IOException ;  
  11. }  

调用本地JNI接口rebootNative().

8. Power类对应的JNI接口函数定义于文件:

[cpp] view plaincopy
  1. frameworks/base/core/jni/android_os_Power.cpp  
  2. static void android_os_Power_reboot(JNIEnv *env, jobject clazz, jstring reason)  
  3. {  
  4.     sync();  
  5. #ifdef HAVE_ANDROID_OS  
  6.     if (reason == NULL) {  
  7.         reboot(RB_AUTOBOOT);  
  8.     } else {  
  9.         const char *chars = env->GetStringUTFChars(reason, NULL);  
  10.         __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,  
  11.                  LINUX_REBOOT_CMD_RESTART2, (char*) chars);  
  12.         env->ReleaseStringUTFChars(reason, chars);  // In case it fails.  
  13.     }  
  14.     jniThrowIOException(env, errno);  
  15. #endif  
  16. }  


 上面的各种宏定义于文件:bionic/libc/kernel/common/linux/reboot.h
[cpp] view plaincopy
  1. #define LINUX_REBOOT_MAGIC1 0xfee1dead  
  2. #define LINUX_REBOOT_MAGIC2 672274793  
  3. #define LINUX_REBOOT_MAGIC2A 85072278  
  4. #define LINUX_REBOOT_MAGIC2B 369367448  
  5. #define LINUX_REBOOT_MAGIC2C 537993216  
  6.   
  7. /* 
  8.  * Commands accepted by the _reboot() system call. 
  9.  * 
  10.  * RESTART     Restart system using default command and mode. 
  11.  * HALT        Stop OS and give system control to ROM monitor, if any. 
  12.  * CAD_ON      Ctrl-Alt-Del sequence causes RESTART command. 
  13.  * CAD_OFF     Ctrl-Alt-Del sequence sends SIGINT to init task. 
  14.  * POWER_OFF   Stop OS and remove all power from system, if possible. 
  15.  * RESTART2    Restart system using given command string. 
  16.  * SW_SUSPEND  Suspend system using software suspend if compiled in. 
  17.  * KEXEC       Restart system using a previously loaded Linux kernel 
  18.  */  
  19. #define LINUX_REBOOT_CMD_RESTART 0x01234567  
  20. #define LINUX_REBOOT_CMD_HALT 0xCDEF0123  
  21. #define LINUX_REBOOT_CMD_CAD_ON 0x89ABCDEF  
  22. #define LINUX_REBOOT_CMD_CAD_OFF 0x00000000  
  23. #define LINUX_REBOOT_CMD_POWER_OFF 0x4321FEDC  
  24. #define LINUX_REBOOT_CMD_RESTART2 0xA1B2C3D4  
  25. #define LINUX_REBOOT_CMD_SW_SUSPEND 0xD000FCE2  
  26. #define LINUX_REBOOT_CMD_KEXEC 0x45584543  
  27.   
  28. bionic/libc/include/sys/reboot.h  
  29. #define RB_AUTOBOOT     LINUX_REBOOT_CMD_RESTART  
  30. #define RB_HALT_SYSTEM  LINUX_REBOOT_CMD_HALT  
  31. #define RB_ENABLE_CAD   LINUX_REBOOT_CMD_CAD_ON  
  32. #define RB_DISABLE_CAD  LINUX_REBOOT_CMD_CAD_OFF  
  33. #define RB_POWER_OFF    LINUX_REBOOT_CMD_POWER_OFF  


9.  libc中__reboot的实现
 bionic/libc/arch-arm/syscalls/__reboot.S

[cpp] view plaincopy
  1.  #include <sys/linux-syscalls.h>  
  2.   
  3.     .text  
  4.     .type __reboot, #function  
  5.     .globl __reboot  
  6.     .align 4  
  7.     .fnstart  
  8.   
  9. __reboot:  
  10.     .save   {r4, r7}  
  11.     stmfd   sp!, {r4, r7}  
  12.     ldr     r7, =__NR_reboot // 系统调用号 88, binoic/libc/include/sys/linux-syscalls.h  
  13.     swi     #0       
  14.     ldmfd   sp!, {r4, r7}  
  15.     movs    r0, r0  
  16.     bxpl    lr  
  17.     b       __set_syscall_errno  
  18.     .fnend  

10. reboot系统调用实现
 kernel/kernel/sys.c
 

[cpp] view plaincopy
  1. SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, void __user *, arg)  
  2.  {  
  3.   char buffer[256];  
  4.   int ret = 0;  
  5.    
  6.   /* We only trust the superuser with rebooting the system. */  
  7.   if (!capable(CAP_SYS_BOOT))  
  8.    return -EPERM;  
  9.    
  10.   /* For safety, we require "magic" arguments. */  
  11.   if (magic1 != LINUX_REBOOT_MAGIC1 ||  
  12.       (magic2 != LINUX_REBOOT_MAGIC2 &&  
  13.                   magic2 != LINUX_REBOOT_MAGIC2A &&  
  14.     magic2 != LINUX_REBOOT_MAGIC2B &&  
  15.                   magic2 != LINUX_REBOOT_MAGIC2C))  
  16.    return -EINVAL;  
  17.    
  18.   if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)  
  19.    cmd = LINUX_REBOOT_CMD_HALT;  
  20.    
  21.   lock_kernel();  
  22.   switch (cmd) {  
  23.    ...  
  24.    case LINUX_REBOOT_CMD_POWER_OFF:  
  25.     kernel_power_off();  
  26.     unlock_kernel();  
  27.     do_exit(0);  
  28.     break;  
  29.     
  30.    case LINUX_REBOOT_CMD_RESTART2:  
  31.     if (strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1) < 0) {  
  32.      unlock_kernel();  
  33.      return -EFAULT;  
  34.     }  
  35.     buffer[sizeof(buffer) - 1] = '\0';  
  36.     
  37.     kernel_restart(buffer);  
  38.     break;  
  39.     
  40.     ...  
  41.     
  42.    default:  
  43.     ret = -EINVAL;  
  44.     break;  
  45.   }  
  46.   unlock_kernel();  
  47.   return ret;  
  48.  }  
  49.   
  50.  void kernel_restart(char *cmd)  
  51.  {  
  52.   kernel_restart_prepare(cmd);  
  53.   if (!cmd)  
  54.    printk(KERN_EMERG "Restarting system.\n");  
  55.   else  
  56.    printk(KERN_EMERG "Restarting system with command '%s'.\n", cmd);  
  57.   machine_restart(cmd);  
  58.  }  
  59.  void kernel_restart_prepare(char *cmd)  
  60.  {  
  61.   blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd); // 调用通知链reboot_notifier_list上的函数  
  62.   system_state = SYSTEM_RESTART;  
  63.   device_shutdown(); // shutdown设备  
  64.   sysdev_shutdown(); // 系统设备shutdoen  
  65.  }  
  66.   
  67.  @kernel/arch/arm/kernel/process.c  
  68.  void (*arm_pm_restart)(char str, const char *cmd) = arm_machine_restart;  
  69.  void machine_restart(char *cmd)  
  70.  {  
  71.   arm_pm_restart(reboot_mode, cmd);  
  72.  }  
  73.  void arm_machine_restart(char mode, const char *cmd)  
  74.  {  
  75.   /* 
  76.    * Clean and disable cache, and turn off interrupts 
  77.    */  
  78.   cpu_proc_fin();  
  79.    
  80.   /* 
  81.    * Tell the mm system that we are going to reboot - 
  82.    * we may need it to insert some 1:1 mappings so that 
  83.    * soft boot works. 
  84.    */  
  85.   setup_mm_for_reboot(mode);  
  86.    
  87.   /* 
  88.    * Now call the architecture specific reboot code. 
  89.    */  
  90.   arch_reset(mode, cmd);   // reset硬件系统,写reboot标记,供bootloader中判断  
  91.    
  92.   /* 
  93.    * Whoops - the architecture was unable to reboot. 
  94.    * Tell the user! 
  95.    */  
  96.   mdelay(1000);  
  97.   printk("Reboot failed -- System halted\n");  
  98.   while (1);  
  99.  }  
  100.   
  101. 11. arch_reset()  
  102.  文件:kernel/arch/arm/mach-mt6516/system.c  
  103.  void arch_reset(char mode, const char *cmd)  
  104.  {  
  105.   printk("arch_reset: cmd = %s\n", cmd ? : "NULL");  
  106.    
  107.   if (cmd && !strcmp(cmd, "charger")) {  
  108.    /* do nothing */  
  109.   } else if (cmd && !strcmp(cmd, "recovery")) {  
  110.    rtc_mark_recovery();  // 写recovery的标记到寄存器中去。  
  111.   } else {  
  112.    rtc_mark_swreset();  
  113.   }  
  114.    
  115.   DRV_WriteReg32(RGU_USRST1,0xbb1f);   
  116.     
  117.   printk("MT6516 SW Reset\n");  
  118.   DRV_WriteReg32(WDT_MODE, 0x2221);  
  119.   DRV_WriteReg32(WDT_RESTART, 0x1971);  
  120.   DRV_WriteReg32(WDT_SWRST, 0x1209);  
  121.    
  122.   /* enter loop waiting for restart */  
  123.   while (1);  
  124.  }  
  125.  @ kernel/driver/ret/ret-mt6516.c  
  126.  /* used in arch_reset() */  
  127.  void rtc_mark_recovery(void)  
  128.  {  
  129.   u16 pdn1;  
  130.    
  131.   spin_lock_irq(&rtc_lock);  
  132.   pdn1 = rtc_read(RTC_PDN1) & ~0x0030;  
  133.   pdn1 |= 0x0010;  
  134.   rtc_writeif_unlock();  
  135.   rtc_write(RTC_PDN1, pdn1);  
  136.   rtc_writeif_lock();  
  137.   spin_unlock_irq(&rtc_lock);  
  138.  }  
  139.  /* used in arch_reset() */  
  140.  void rtc_mark_swreset(void)  
  141.  {  
  142.   u16 pdn1;  
  143.    
  144.   spin_lock_irq(&rtc_lock);  
  145.   pdn1 = rtc_read(RTC_PDN1) & ~0x0030;  
  146.   pdn1 |= 0x0020;  
  147.   rtc_writeif_unlock();  
  148.   rtc_write(RTC_PDN1, pdn1);  
  149.   rtc_writeif_lock();  
  150.   spin_unlock_irq(&rtc_lock);  
  151.  }  


 可以看出,recovery和reset都是往RTC_PDN1的bit5:bit4上分别写01和10来标识。
 
 
12. 正常的log如下:
[html] view plaincopy
  1. #logcat ShutdownThread:D *:S &  
  2. # --------- beginning of /dev/log/system  
  3. --------- beginning of /dev/log/main  
  4. D/ShutdownThread(  127): !!! Request to shutdown !!!  
  5. D/ShutdownThread(  127): Notifying thread to start radio shutdown  
  6. D/ShutdownThread(  127): shutdown acquire partial WakeLock 2  
  7. I/ShutdownThread(  127): Sending shutdown broadcast...  
  8. I/ShutdownThread(  127): Shutting down activity manager...  
  9. W/ShutdownThread(  127): Turning off radio...  
  10. I/ShutdownThread(  127): Waiting for Bluetooth and Radio...  
  11. I/ShutdownThread(  127): Radio and Bluetooth shutdown complete.  
  12. I/ShutdownThread(  127): Shutting down MountService  
  13. W/ShutdownThread(  127): Result code 0 from MountService.shutdown  
  14. [  127.981918] save exit: isCheckpointed 1  
  15. [  127.985002] save exit: isCheckpointed 1  
  16. I/ShutdownThread(  127): Rebooting, reason: recovery  
  17. [  128.081532] [lizhiguo reboot1] LINUX_REBOOT_CMD_RESTART2.  
  18. [  128.082357] GPS: mt3326_gps_shutdown: Shutting down  
  19. [  128.083011] GPS: mt3326_gps_power: Switching GPS device off  
  20. [  128.083741] GPS: mt3326_gps_power: null pointer!!  
  21. [  128.084376] GPIO Shut down  
  22. [  128.089814] [MATV] shutdown  
  23. [  128.090193] [H264_DEC] h264_dec_shutdown  
  24. [  128.090710] JPEG Codec shutdown  
  25. [  128.091248] ----MT6516 M3D shutdown----  
  26. [  128.091839] m2d_shutdown() is called  
  27. [  128.092320] ******** MT6516 WDT driver shutdown!! ********  
  28. [  128.093040] [MM_QUEUE] mm_queue_shutdown  
  29. [  128.094333] [lizhiguo reboot2] kernel_restart.  
  30. [  128.094955] Restarting system with command 'recovery'.  
  31. [  128.097483] [lizhiguo reboot3] arm_machine_restart.  
  32. [  128.099275] arch_reset: cmd = recovery  
  33. [  128.100917] MT6516 SW Reset  
  34. u516 EVBgetflashID ADBC successful!!!  
  35. [MEM] complex R/W mem test pass  



13. uboot中会先后检查三种方式进入recovery是否成立:第一种是kernel直接写一个寄存器来标记下次启动将进入recovery模式;第二种是快捷键:powerkey+downVOL;第三中就是上层应用发送下来的回复出厂设置的命令,这个命令在restart之前kernel会往MISC分区中写command(boot-recovery)。这项工作在文件:bootable/bootloader/uboot/board/mt6516/mt6516_recovery.c完成。
recovery_check_key_trigger()
recovery_check_command_trigger()

[cpp] view plaincopy
  1. BOOL recovery_check_command_trigger(void)  
  2. {  
  3.  struct misc_message misc_msg;  
  4.  struct misc_message *pmisc_msg = &misc_msg;  
  5.  const unsigned int size = NAND_WRITE_SIZE * MISC_PAGES;  
  6.  unsigned char *pdata;  
  7.      int ret;  
  8.   
  9.  pdata = (uchar*)malloc(sizeof(uchar)*size);  
  10.   
  11.  ret = mboot_recovery_load_misc(pdata, size);  
  12.    
  13.     if (ret < 0)  
  14.     {  
  15.      return FALSE;   
  16.     }   
  17.    
  18. #ifdef LOG_VERBOSE  
  19.     MSG("\n--- get_bootloader_message ---\n");  
  20.     dump_data(pdata, size);  
  21.     MSG("\n");  
  22. #endif  
  23.   
  24.  memcpy(pmisc_msg, &pdata[NAND_WRITE_SIZE * MISC_COMMAND_PAGE], sizeof(misc_msg));   
  25.  MSG("Boot command: %.*s\n"sizeof(misc_msg.command), misc_msg.command);  
  26.  MSG("Boot status: %.*s\n"sizeof(misc_msg.status), misc_msg.status);  
  27.  MSG("Boot message\n\"%.20s\"\n", misc_msg.recovery);  
  28.   
  29.  if(strcmp(misc_msg.command, "boot-recovery")==0)  
  30.  { g_boot_mode = RECOVERY_BOOT;  
  31.  }  
  32.   
  33.  return TRUE;  
  34. }  
  35. // recovery模式检测  
  36. BOOL recovery_detection(void)  
  37. {  
  38.  if ((DRV_Reg16(RTC_PDN1) & 0x0030) == 0x0010) { /* factory data reset */  
  39.   g_boot_mode = RECOVERY_BOOT;  
  40.   return TRUE;  
  41.  } // 读取寄存器的值  
  42.   
  43.     if(recovery_check_key_trigger())  
  44.     {  
  45.      return TRUE;  
  46.     }  
  47.     // 检测是否有快捷键按下  
  48.      
  49.     #ifdef CFG_NAND_BOOT  
  50.  recovery_check_command_trigger();  
  51.  #endif  
  52.  // 检测是否通过将忘MISC分区写命令的方式  
  53.  // 以上如果都不是,那么最后一次检查模式全局量是够是RECOVERY_BOOT  
  54.  if (g_boot_mode == RECOVERY_BOOT)  
  55.  { return TRUE;  
  56.  }  
  57.  else  
  58.  { return FALSE;  
  59.  }  
  60. }  


14. g_boot_mode = RECOVERY_BOOT这个成立之后,uboot将会从RECOVERY分区加载recovery.img进SDRAM来运行。
 其实这个recovery.img和boot.img结构类似,zImage一样,所不同的是ramdisk.img不同而已。
 在运行recovery这个elf的时候会从/cache/recovery/comamnd中读取参数,这个参数是android的上层应用写进入的,--wipe-data,
 之后会清除USERDATA和CACHE分区,在将recovery的log文件放在/cache/recovery/下,将原来的command文件删除,最后
 调用函数reboot(RB_AUTOBOOT)来重新启动系统。
 bootable/recovery/recovery.c
 
 最后需要注意的一个问题是,recovery这个elf在编译user-release版本软件的时候没有copy到/system/bin下面去,需要修改
 bootable/recovery/Android.mk文件中的如下地方:
 /* BENGIN: lizhiguo 2011-07-27, copy recovery to /system/bin for user builds.*/
 #LOCAL_MODULE_TAGS := eng
 /* END: lizhiguo 2011-07-27 */
 如果放开这行,将只会在eng版本软件中有copy到/system/bin的动作。

0 0
原创粉丝点击