在MTK軟件平臺中,如果將:device\mediateksample\k61v1_demo_64_bsp\ProjectConfig.mk中的MTK_SHARED_SDCARD = yes,那麼系統啓動之後內部存儲的FAT分區和data分區將自動合併成一個分區,對用戶看到的是比原來data分區大小還大的存儲空間,這個時候我們將在內核SDCARD(內核存儲區)中拷貝進入地圖,如果進行恢復出廠設置,這個時候對/data分區的格式化將內部存儲區也格式化掉,用什麼方法可以達到不格式化內部存儲區呢???以下提供這種方法:
需要修改:
修改:bootable/recovery/recovery.cpp 針對data分區恢復出廠設置的時候將mount data分區,將data分區文件刪除即可。不對data分區進行ext4fs格式化。
bootable/recovery/recovery.cpp
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);
std::vector<saved_log_file> log_files;
if (is_cache) {
// If we're reformatting /cache, we load any past logs
// (i.e. "/cache/recovery/last_*") and the current log
// ("/cache/recovery/log") into memory, so we can restore them after
// the reformat.
ensure_path_mounted(volume);
struct dirent* de;
std::unique_ptr<DIR, decltype(&closedir)> d(opendir(CACHE_LOG_DIR), closedir);
if (d) {
while ((de = readdir(d.get())) != nullptr) {
if (strncmp(de->d_name, "last_", 5) == 0 || strcmp(de->d_name, "log") == 0) {
std::string path = android::base::StringPrintf("%s/%s", CACHE_LOG_DIR, de->d_name);
struct stat sb;
if (stat(path.c_str(), &sb) == 0) {
// truncate files to 512kb
if (sb.st_size > (1 << 19)) {
sb.st_size = 1 << 19;
}
std::string data(sb.st_size, '\0');
FILE* f = fopen(path.c_str(), "rbe");
fread(&data[0], 1, data.size(), f);
fclose(f);
log_files.emplace_back(saved_log_file{ path, sb, data });
}
}
}
} else {
if (errno != ENOENT) {
PLOG(ERROR) << "Failed to opendir " << CACHE_LOG_DIR;
}
}
}
ui->Print("Formatting %s...\n", volume);
//添加以下代碼:
//modiy by wanneng
#if 1
/* 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;
}
}
//modiy by wanneng end
#endif
//結束添加代碼
ensure_path_unmounted(volume);
........................................
修改:system/core/init/Android.mk 設置成PERMISSIVE模式
system/core/init/Android.mk
ifeq ($(strip $(MTK_BUILD_ROOT)),yes)
init_options += \
-DALLOW_LOCAL_PROP_OVERRIDE=1 \
-DALLOW_PERMISSIVE_SELINUX=1 \
-DREBOOT_BOOTLOADER_ON_PANIC=1 \
-DDUMP_ON_UMOUNT_FAILURE=1
else
init_options += \
-DALLOW_LOCAL_PROP_OVERRIDE=0 \
-DALLOW_PERMISSIVE_SELINUX=0 \ ####修改這裏
-DREBOOT_BOOTLOADER_ON_PANIC=0 \
-DDUMP_ON_UMOUNT_FAILURE=0
endif
endif
修改成:
ifeq ($(strip $(MTK_BUILD_ROOT)),yes)
init_options += \
-DALLOW_LOCAL_PROP_OVERRIDE=1 \
-DALLOW_PERMISSIVE_SELINUX=1 \
-DREBOOT_BOOTLOADER_ON_PANIC=1 \
-DDUMP_ON_UMOUNT_FAILURE=1
else
init_options += \
-DALLOW_LOCAL_PROP_OVERRIDE=0 \
-DALLOW_PERMISSIVE_SELINUX=1 \ ####修改這裏
-DREBOOT_BOOTLOADER_ON_PANIC=0 \
-DDUMP_ON_UMOUNT_FAILURE=0
endif
endif
修改:vendor/mediatek/proprietary/bootable/bootloader/lk/app/mt_boot/mt_boot.c 在recovery過程中系統重啓時,將selinux權限修改成PERMISSIVE模式,否則後面的recovery掛載data分區權限失敗。導致文件無法刪除。
vendor/mediatek/proprietary/bootable/bootloader/lk/app/mt_boot/mt_boot.c
int boot_linux_from_storage(void)
{
int ret = 0;
#define CMDLINE_TMP_CONCAT_SIZE 110 //only for string concat, 200 bytes is enough
char cmdline_tmpbuf[CMDLINE_TMP_CONCAT_SIZE];
unsigned int kimg_load_addr;
#ifdef MTK_AB_OTA_UPDATER
load_bootimg_by_suffix();
#else
switch (g_boot_mode) {
case NORMAL_BOOT:
case META_BOOT:
case ADVMETA_BOOT:
case SW_REBOOT:
case ALARM_BOOT:
#ifdef MTK_KERNEL_POWER_OFF_CHARGING
case KERNEL_POWER_OFF_CHARGING_BOOT:
case LOW_POWER_OFF_CHARGING_BOOT:
#endif
......................................
// 2 weak function for mt6572 memory preserved mode
platform_mem_preserved_load_img();
platform_mem_preserved_dump_mem();
custom_port_in_kernel(g_boot_mode, cmdline_get());
if (g_boot_hdr != NULL) {
snprintf(cmdline_tmpbuf, CMDLINE_TMP_CONCAT_SIZE, "%s", g_boot_hdr->cmdline);
cmdline_append(cmdline_tmpbuf);
}
// add by Wanneng //代碼添加
printf(" Jugement g_boot_mode,add by wanneng\n");
if(g_boot_mode == RECOVERY_BOOT)
{
cmdline_append("androidboot.selinux=permissive");
printf("g_boot_mode = %d\n",g_boot_mode);// add by wanneng
}
else{ //代碼添加,主要是針對之前的正常啓動
#ifdef SELINUX_STATUS
#if SELINUX_STATUS == 1
#ifdef ATC_AOSP_ENHANCEMENT
//Android O don't support disabled in init proccess. Regard it as permissive.
cmdline_append("androidboot.selinux=permissive");
#else
cmdline_append("androidboot.selinux=disabled");
#endif
#elif SELINUX_STATUS == 2
cmdline_append("androidboot.selinux=permissive");
#endif
#endif
} //添加括號
/* set verity mode to 'enforcing' in order to make dm-verity work. */
/* after verity mode handling is implemented, please remove this line */
cmdline_append("androidboot.veritymode=disabled");
#if defined(MTK_POWER_ON_WRITE_PROTECT) && !defined(MACH_FPGA)
#if MTK_POWER_ON_WRITE_PROTECT == 1
#if defined(MTK_EMMC_SUPPORT) || defined(MTK_UFS_BOOTING)
write_protect_flow();
#endif
#endif
#endif
#ifdef ATC_AOSP_ENHANCEMENT
get_config_from_metazone();
cmdline_append(" ");
strcat((char *)cmdline_tmpbuf, " ");
if (g_usb0_speed == PROTOCOL_USB11)
cmdline_append("usbo=full");
else if (g_usb0_speed == PROTOCOL_USB20)
cmdline_append("usbo=high");
else
cmdline_append("usbo=null");
cmdline_append(" ");
strcat((char *)cmdline_tmpbuf, " ");
if (g_usb1_speed == PROTOCOL_USB11)
cmdline_append("usb1=full");
else if (g_usb1_speed == PROTOCOL_USB20)
cmdline_append("usb1=high");
else
cmdline_append("usb1=null");
cmdline_append(" ");
if (g_usb0_mode == USB_DEVICE_MODE)
cmdline_append("otg=dev");
else if (g_usb0_mode == USB_HOST_MODE)
cmdline_append("otg=host");
else
cmdline_append("otg=otg");
cmdline_append(" ");
if (g_usb0_dvr_mode == USB_DVR_MODE_ENABLE)
cmdline_append("usb0=dvre");
else if (g_usb0_dvr_mode == USB_DVR_MODE_DISABLE)
cmdline_append("usb0=dvrd");
else
cmdline_append("usb0=dvrn");
cmdline_append(" ");
if (g_usb1_dvr_mode == USB_DVR_MODE_ENABLE)
cmdline_append("usb1=dvre");
else if(g_usb1_dvr_mode == USB_DVR_MODE_DISABLE)
cmdline_append("usb1=dvrd");
else
cmdline_append("usb1=dvrn");
dprintf(0, "[yl] cmdline = %s\n", cmdline_get());
#endif
/* pass related root of trust info via SMC call */
if (send_root_of_trust_info != NULL)
send_root_of_trust_info();
if (g_boot_hdr != NULL) {
boot_linux((void *)g_boot_hdr->kernel_addr, (unsigned *)g_boot_hdr->tags_addr,
board_machtype(), (void *)g_boot_hdr->ramdisk_addr, g_rimg_sz);
} else {
boot_linux((void *)CFG_BOOTIMG_LOAD_ADDR, (unsigned *)CFG_BOOTARGS_ADDR,
board_machtype(), (void *)CFG_RAMDISK_LOAD_ADDR, g_rimg_sz);
}
while (1) ;
return 0;
}// end of boot_linux_from_storage //修改這個函數