原理:在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
.....................................