在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 //修改这个函数