天天看點

MTK平台android recovery模式不删除FAT分區

原理:在android系統的recovery模式下,系統将進入data分區的格式化,而不是mount data分區後進入檔案的删除,是以我們需要将系統進入recovery模式下格式化data分區修改成mount data分區,然後進入檔案以及目錄的删除。而MTK平台正常情況下MTK_SHARED_SDCARD = yes 這種模式下,系統編譯後運作時FAT和data分區時合并在一起共享的,是以FAT的實體空間在data分區的範圍内。在格式化data分區時會一并将FAT分區給格式化掉。是以需要進行mount後目錄的删除。

方法如下:

1、項目全局配置:

device\autochips\ac8257_demo\ProjectConfig.mk

AUTO_ADD_GLOBAL_DEFINE_BY_NAME = xxx xxxx ATC_RECOVERY_NOERASE_DATA

ATC_RECOVERY_NOERASE_DATA = yes

2、selinux的修改

主要是在recovery系統進入重新開機的時候修改在recovery模式将selinux關閉,否則在recovery模式下mount data分區時将會失敗。導緻後面進入data分區删除不了檔案目錄。

2.1) 第一種修改方法

修改:vendor\mediatek\proprietary\bootable\bootloader\lk\target\ac8257_demo\rules.mk檔案:

ifeq ($(ATC_RECOVERY_NOERASE_DATA),yes)
DEFINES += ATC_RECOVERY_NOERASE_DATA
endif
           

vendor\mediatek\proprietary\bootable\bootloader\lk\project\ac8257_demo.mk 檔案中添加

ATC_RECOVERY_NOERASE_DATA = yes

修改vendor\mediatek\proprietary\bootable\bootloader\lk\app\mt_boot\mt_boot.c檔案,如下:

int boot_linux_from_storage(void)
{
	int ret = 0;
	uint32_t kernel_target_addr = 0;
	uint32_t ramdisk_target_addr = 0;
	uint32_t tags_target_addr = 0;
	uint32_t ramdisk_addr = 0;
	uint32_t ramdisk_real_sz = 0;
	........................................
	#ifdef SELINUX_STATUS
#if SELINUX_STATUS == 1
	cmdline_append("androidboot.selinux=disabled");
#elif SELINUX_STATUS == 2
	cmdline_append("androidboot.selinux=permissive");
#endif
#endif
+#if defined(ATC_AOSP_ENHANCEMENT) && defined(ATC_RECOVERY_NOERASE_DATA)
+	if(RECOVERY_BOOT == g_boot_mode) {
+		cmdline_append("androidboot.selinux=permissive");
+}
.................................
}
           

2.2 修改/system/core/init.cpp中selinux的權限

方法如下:

bootable/recovery/recovery.cpp

--- a/bootable/recovery/recovery.cpp
+++ b/bootable/recovery/recovery.cpp
@@ -1085,7 +1085,7 @@ int
 main(int argc, char **argv) {
     time_t start = time(NULL);
 
-    redirect_stdio(TEMPORARY_LOG_FILE);
+    redirect_stdio(LOG_TO_USART); //日志列印到UART口
           

system/core/init/Android.mk

--- a/system/core/init/Android.mk
+++ b/system/core/init/Android.mk
@@ -11,8 +11,7 @@ else
 ifeq ($(strip $(MTK_BUILD_ROOT)),yes)
 init_options += -DALLOW_LOCAL_PROP_OVERRIDE=1 -DALLOW_DISABLE_SELINUX=1
 else
-#added by lzt for reset /data except media
-init_options += -DALLOW_LOCAL_PROP_OVERRIDE=0 -DALLOW_DISABLE_SELINUX=1
+init_options += -DALLOW_LOCAL_PROP_OVERRIDE=0 -DALLOW_DISABLE_SELINUX=0
 endif
 endif
           

system/core/init/init.cpp

--- a/system/core/init/init.cpp
+++ b/system/core/init/init.cpp
@@ -964,6 +964,12 @@ static void security_failure() {
     while (true) { pause(); }  // never reached
 }
 
+/***add by lzt for recovery mode to disable selinux***/
+static bool inline IsRecoveryMode() {
+    return access("/sbin/recovery", F_OK) == 0;
+}
+/***************************************************/
+
 static void selinux_initialize(bool in_kernel_domain) {
     Timer t;
 
@@ -973,6 +979,13 @@ static void selinux_initialize(bool in_kernel_domain) {
     cb.func_audit = audit_callback;
     selinux_set_callback(SELINUX_CB_AUDIT, cb);
 
+    /**add by lzt for recovery mode**/
+    //這裡判斷recovery系統重新啟動時是否是recovery模式,是的話直接傳回,不設定selinux模式
+    if(IsRecoveryMode())
+    {
+        return;
+    }
+    /*******************************/
+
     if (selinux_is_disabled()) {
         return;
     }
           

vendor/mediatek/proprietary/bootable/bootloader/lk/app/mt_boot/mt_boot.c

--- a/vendor/mediatek/proprietary/bootable/bootloader/lk/app/mt_boot/mt_boot.c
+++ b/vendor/mediatek/proprietary/bootable/bootloader/lk/app/mt_boot/mt_boot.c
@@ -1416,9 +1416,9 @@ int boot_linux_from_storage(void)
 #endif
 
 //add by lzt for reset /data except media
-    if(g_boot_mode == RECOVERY_BOOT){
-        cmdline_append("androidboot.selinux=disabled");
-    }else{		
+    //if(g_boot_mode == RECOVERY_BOOT){
+      //  cmdline_append("androidboot.selinux=disabled");
+  //  }else{		
 #ifdef SELINUX_STATUS
 #if SELINUX_STATUS == 1
 	cmdline_append("androidboot.selinux=disabled");
@@ -1426,7 +1426,7 @@ int boot_linux_from_storage(void)
 	cmdline_append("androidboot.selinux=permissive");
 #endif
 #endif
-}
+//}
 
 #ifdef MTK_POWER_ON_WRITE_PROTECT
 #if MTK_POWER_ON_WRITE_PROTECT == 1
           

vendor/mediatek/proprietary/system/core/multi_init/Android.mk

--- a/vendor/mediatek/proprietary/system/core/multi_init/Android.mk
+++ b/vendor/mediatek/proprietary/system/core/multi_init/Android.mk
@@ -16,15 +16,10 @@ else
 ifeq ($(strip $(MTK_BUILD_ROOT)),yes)
 init_options += -DALLOW_LOCAL_PROP_OVERRIDE=1 -DALLOW_DISABLE_SELINUX=1
 else
-#added by lzt for protect media from factory reset
-init_options += -DALLOW_LOCAL_PROP_OVERRIDE=0 -DALLOW_DISABLE_SELINUX=1
+init_options += -DALLOW_LOCAL_PROP_OVERRIDE=0 -DALLOW_DISABLE_SELINUX=0
 endif
 endif
 
-#added by lzt for protect media from factory reset
-#ifeq ($(strip $(TARGET_BUILD_VARIANT)),user)
-#LOCAL_CFLAGS += -DALLOW_DISABLE_SELINUX=1
-#endif
 
 # add mtk fstab flags support
 init_options += -DMTK_FSTAB_FLAGS
           

2、recovery程序的mount data分區并删除除FAT檔案目錄之外的data分區中的檔案

bootable\recovery\recovery.cpp

static const char *TEMPORARY_INSTALL_FILE = "/tmp/last_install";
static const char *LAST_KMSG_FILE = "/cache/recovery/last_kmsg";
static const char *LAST_LOG_FILE = "/cache/recovery/last_log";
static const char *LOG_TO_USART = "dev/ttyMT0";
static const int KEEP_LOG_COUNT = 10;

+/*added by lzt for resetting /data except media*/
+static const int  MAX_PATH = 512;
+static const char *DATA_ROOT = "/data";
+/***added by lzt*/
..................................................
#ifdef ATC_AOSP_ENHANCEMENT
bool erase_volume(const char* volume)
#else
static bool erase_volume(const char* volume)
#endif
{
  bool is_cache = (strcmp(volume, CACHE_ROOT) == 0);
  +bool is_data = (strcmp(volume, DATA_ROOT) == 0);

  ui->SetBackground(RecoveryUI::ERASING);
  ui->SetProgressType(RecoveryUI::INDETERMINATE);
  ....................................................
   #if defined(ATC_AOSP_ENHANCEMENT) && defined(ATC_RECOVERY_NOERASE_DATA)
  /* Add format data/ with del files for shared sdcard */
  if (is_data) {
      if(reason && !strcmp(reason,"wipe_data_via_recovery")){
          ui->Print("this wipe data reason is %s . need format /data .\n", reason);
          }else{
              ensure_path_mounted(volume);
              DIR * dir;
              struct dirent* file;
              dir = opendir(DATA_ROOT);
              if(dir) {
                  LOGE("opendir %s success\n", DATA_ROOT);
                  char dir_path[MAX_PATH];
                  while((file = readdir(dir)) != NULL) {
                      memset(dir_path, 0, sizeof(char)*MAX_PATH);
                      if ((!strcmp(file->d_name, "..")) ||
                              (!strcmp(file->d_name, ".")) ||
                              (!strcmp(file->d_name, "lost+found")) ||
                              (!strcmp(file->d_name, "media")) ||
                              (!strcmp(file->d_name, ".layout_version")))
                      continue;
                      /* Del other files */
                      snprintf(dir_path, sizeof(dir_path),"%s/%s",DATA_ROOT, file->d_name);
                      LOGE("Del dir : %s\n", dir_path);
                      dirUnlinkHierarchy(dir_path);
                  }
                  /* imotor add: modify /data/.layout_version for installd */
                  FILE *fp = fopen_path("/data/.layout_version", "w");
                  if (fp){
                      LOGE("write /data/.layout_version 2\n");
                      fwrite("2", 1, 1, fp);
                      fclose(fp);
                  }
              } else {
                  LOGE("opendir failed: %s\n", strerror(errno));
                  return false;
              }
               LOGE("### format data true ###\n");
               closedir(dir);
               ensure_path_unmounted(volume);
               return true;
           }
        }
#endif
.....................................