网站改版费用,兼职 网站建设,户网站开发的小公司,交钱做网站对方拿了钱不做该怎么办目前rk3568的开机时间有21s#xff0c;统计的是关机后从按下 power 按键到显示锁屏的时间#xff0c;当对openharmony的系统进行了裁剪子系统#xff0c;系统app#xff0c;禁用部分服务后发现开机时间仅仅提高到了20.94s 优化微乎其微。在对init进程的log进行分析并解决其…目前rk3568的开机时间有21s统计的是关机后从按下 power 按键到显示锁屏的时间当对openharmony的系统进行了裁剪子系统系统app禁用部分服务后发现开机时间仅仅提高到了20.94s 优化微乎其微。在对init进程的log进行分析并解决其中的时间断层后 开机时长优化到了16.5s左右可以说是一个非常大的进步了下面详细讲一下优化的过程。
一、定位 log
openharmony支持dmesg打印kernel log和hilog 打印openharony自己的log所以需要在开机时抓取这两种log来分析开机流程。openharony的开机流程可以参考
由于本人对于kernel了解比较少所以对于kernel部分的优化无法介绍。从上面的OpenHarmony init进程的启动流程中我们可以知道openharmony的启动和Android比较类似都是init进程去解析各种cfg文件启动服务那么当kernel 内核初始化完后init进程也就是pid1的这个进程就是开机过程的主线程。由于openharmny的dmesg log中都携带了pid和函数名称所以我们在开机时抓的dmesg log中搜索pid1可以看到开机时主线程的打印log先寻找是否有时间断层的情况比如我的设备中dmesg有一处时间断层如下 行 1515: [ 4.396049] [pid1][Init][INFO][init_cmds.c:291]Mount partitions from fstab file /vendor/etc/fstab.rk3568 行 1517: [ 4.396782] [pid1][BEGET][INFO][fstab.c:429]StoreFscryptPolicy:store fscrypt policy, 2:aes-256-cts:aes-256-xts行 1522: [ 4.897721] [pid1][BEGET][INFO][fstab_mount.c:78]Execute /system/bin/resize.f2fs begin行 1524: [ 4.947110] [pid1][BEGET][ERROR][fstab_mount.c:91]Command /system/bin/resize.f2fs failed with status 255行 1525: [ 4.947141] [pid1][BEGET][INFO][fstab_mount.c:93]Execute /system/bin/resize.f2fs end行 1526: [ 4.947218] [pid1][BEGET][ERROR][fstab_mount.c:394]Failed to resize.f2fs dir /dev/block/platform/fe310000.sdhci/by-name/userdata , ret 255行 1527: [ 4.947309] [pid1][BEGET][INFO][fstab_mount.c:78]Execute /system/bin/fsck.f2fs begin行 1531: [ 7.196164] [pid1][BEGET][ERROR][fstab_mount.c:91]Command /system/bin/fsck.f2fs failed with status 1行 1532: [ 7.196179] [pid1][BEGET][INFO][fstab_mount.c:93]Execute /system/bin/fsck.f2fs end行 1533: [ 7.196225] [pid1][BEGET][ERROR][fstab_mount.c:399]Failed to fsck.f2fs dir /dev/block/platform/fe310000.sdhci/by-name/userdata , ret 1行 1538: [ 7.397003] [pid1][BEGET][INFO][fstab_mount.c:421]Mount /dev/block/platform/fe310000.sdhci/by-name/userdata to /data successful行 1540: [ 7.398757] [pid1][BEGET][INFO][fstab_mount.c:421]Mount /dev/block/platform/fe310000.sdhci/by-name/chip-prod to /chip_prod successful行 1542: [ 7.400545] [pid1][BEGET][INFO][fstab_mount.c:421]Mount /dev/block/platform/fe310000.sdhci/by-name/sys-prod to /sys_prod successful行 1543: [ 7.400598] [pid1][Init][INFO][init_cmds.c:293]Mount partitions from fstab file /vendor/etc/fstab.rk3568 finish ret 0
可以看到上面在4.947309 到7.196164出现了断层这段时间主线程什么都没有输出并且查看log发现init主线程是在执行一个命令/system/bin/fsck.f2fs并且在执行了2.2s后还失败了但是设备是可以正常开机的。网上搜索发现fsckfile system check用来检查和维护不一致的文件系统。若系统掉电或磁盘发生问题可利用fsck命令对文件系统进行检查。由于这里是执行失败并且没有什么影响所以我这里将这个命令改成了异步执行。这样主线程就可以继续往下执行了。
在将fsck命令的执行修改成异步执行后发现这里的时间断层消失了但是又发现了新的时间断层如下
// fsck命令时间已经恢复
[ 4.894672] [pid1][BEGET][INFO][fstab_mount.c:102]Execute /system/bin/resize.f2fs begin
[ 4.896229] [pid1][BEGET][INFO][fstab_mount.c:118]Execute /system/bin/resize.f2fs end
[ 4.896445] [pid1][BEGET][INFO][fstab_mount.c:102]Execute /system/bin/fsck.f2fs begin
[ 4.898137] [pid1][BEGET][INFO][fstab_mount.c:118]Execute /system/bin/fsck.f2fs end
//新出现的时间断层行 1943: [ 5.236372] [pid1][BEGET][INFO][fstab.c:434]LoadFscryptPolicy start行 1944: [ 5.236398] [pid1][BEGET][INFO][fstab.c:449]LoadFscryptPolicy success行 1945: [ 5.236533] [pid1][Init][INFO][init_cmds.c:99]Sync exec: /system/bin/sdc行 1992: [ 8.223549] [pid1][Init][INFO][init_cmds.c:112]Sync exec: /system/bin/sdc result 0 1行 1993: [ 8.232997] [pid1][Init][INFO][fscrypt_control.c:217]Fscrypt policy init success行 1994: [ 8.233204] [pid1][Init][INFO][key_control.c:204]version 2 loaded行 1995: [ 8.233234] [pid1][Init][INFO][fscrypt_control.c:234]key path /data/service/el0/storage_daemon/sd, name /key_id行 1996: [ 8.233313] [pid1][Init][INFO][key_control.c:110]enter行 1997: [ 8.233447] [pid1][Init][INFO][key_control.c:78]success行 1998: [ 8.251213] [pid1][Init][INFO][fscrypt_control.c:186]Have been init行 1999: [ 8.251311] [pid1][Init][INFO][key_control.c:204]version 2 loaded行 2000: [ 8.251328] [pid1][Init][INFO][fscrypt_control.c:234]key path /data/service/el0/storage_daemon/sd, name /key_id行 2001: [ 8.251377] [pid1][Init][INFO][key_control.c:110]enter行 2002: [ 8.251453] [pid1][Init][INFO][key_control.c:78]success行 2004: [ 8.261900] [pid1][Init][INFO][fscrypt_control.c:186]Have been init行 2005: [ 8.261969] [pid1][Init][INFO][key_control.c:204]version 2 loaded行 2006: [ 8.262016] [pid1][Init][INFO][fscrypt_control.c:234]key path /data/service/el0/storage_daemon/sd, name /key_id行 2007: [ 8.262068] [pid1][Init][INFO][key_control.c:110]enter行 2008: [ 8.262149] [pid1][Init][INFO][key_control.c:78]success行 2009: [ 8.264017] [pid1][Init][INFO][init_cmds.c:99]Sync exec: /system/bin/sdc行 2011: [ 8.338298] [pid1][Init][INFO][init_cmds.c:112]Sync exec: /system/bin/sdc result 0 1
从上面可以知道是系统执行sdc命令导致耗时了将近3s那么这个命令又是做什么的为什么会耗费3s这个我们后面再去分析。
到这里init阶段的耗时基本就分析完了同样的我们需要接着去分析hilog我们知道hilog是需要hilogd启动才能打印所以dmesg的log中hilogd启动时间和hilog的打印时间应该不会错的太开。接着我们知道init服务启动了很多那么哪些服务是启动launcher的呢答案是foundation服务。foundation服务会启动AbilityManagerService在AbilityManagerService中当AccountManagerService发出切换user 100的请求时就会启动launcher。我在看dmesg和hilog的过程中发现了foundation和account的启动时间如下所示
[ 9.420796] [pid1][Init][INFO][init_service_manager.c:1084]Start service foundation
[ 9.457414] [pid1][Init][INFO][init_common_service.c:387]Service foundation(pid 536) started
[ 9.570249] [pid1][Init][INFO][init_service_manager.c:1084]Start service accountmgr
[ 9.571380] [pid1][Init][INFO][init_common_service.c:387]Service accountmgr(pid 553) started
可以看到foundation的启动时间在accountmagr之前但是在hilog中我看到了如下log
行 24030: 07-04 11:03:24.761 553 893 I C01b00/AccountMgrService: [SendToAMSAccountStart:53]:start
行 52650: 07-04 11:03:28.073 553 893 I C01b00/AccountMgrService: [SendToAMSAccountStart:63]:end, succeed!
Account向AMS发送消息竟然耗时长达3.3s原因是由于foundation内部包含的ability比较多当foundation服务启动时会逐个启动abilityopenharmony的原始设定是只开了4个线程去启动ability所以只有等上个ability启动完成后才能启动下个ability这样会延迟开机时间这里可以将线程池的线程扩为2倍这样就可以加速ability的启动。
在abilitymanagerserice启动launcher时发现会一直等待bootevent.bootanimation.started属性被置为ture后才会启动launcher这里也存在一定的耗时后面我们在代码分析中继续深入了解。
二、代码分析
2.1 fcsk的异步执行
首先我们先看一下fcsk如何修改成异步执行首先我们先看一下这个命令是在哪里执行的通过前后的相关log我们可以确定他是在挂载data分区时执行的代码时序图如下 init进程在启动时在pre_init阶段会去挂载系统的分区表这里在挂载data分区时会调用到DoFsckF2fs去执行文件检查如下
/base/startup/init/interfaces/innerkits/fs_manager/fstab_mount.c
static int DoFsckF2fs(const char* device)
{char *file /system/bin/fsck.f2fs;if (access(file, F_OK) ! 0) {BEGET_LOGE(fsck.f2fs is not exists.);return -1;}char *cmd[] {file, -a, (char *)device, NULL};int argc ARRAY_LENGTH(cmd);char **argv (char **)cmd;return ExecCommand(argc, argv);
}
static int ExecCommand(int argc, char **argv)
{if (argc 0 || argv NULL || argv[0] NULL) {return -1;}BEGET_LOGI(Execute %s begin, argv[0]);pid_t pid fork();if (pid 0) {BEGET_LOGE(Fork new process to format failed: %d, errno);return -1;}if (pid 0) {execv(argv[0], argv);exit(-1);}int status;//这里的waitpid 参数设置为0就会挂起调用进程(这里是init进程)知道子进程终止waitpid(pid, status, 0);if (!WIFEXITED(status) || WEXITSTATUS(status) ! 0) {BEGET_LOGE(Command %s failed with status %d, argv[0], WEXITSTATUS(status));}BEGET_LOGI(Execute %s end, argv[0]);return WEXITSTATUS(status);
}
想要DoFsckF2fs异步执行加入下面的修改即可
//add by yuwguideir.com for exec async commond start
static int AsyncExecCommand(int argc, char **argv)
{if (argc 0 || argv NULL || argv[0] NULL) {return -1;}BEGET_LOGI(AsyncExecute %s begin, argv[0]);pid_t pid fork();if (pid 0) {BEGET_LOGE(Fork new process to format failed: %d, errno);return -1;}if (pid 0) {execv(argv[0], argv);exit(-1);}int status;waitpid(pid, status, WNOHANG);if (!WIFEXITED(status) || WEXITSTATUS(status) ! 0) {BEGET_LOGE(Command %s failed with status %d, argv[0], WEXITSTATUS(status));}BEGET_LOGI(AsyncExecute %s end, argv[0]);return WEXITSTATUS(status);
}
//add by yuwguideir.com for exec async commond endint DoFormat(const char *devPath, const char *fsType){-192,7 217,9 static int DoResizeF2fs(const char* device, const unsigned long long size)};int argc ARRAY_LENGTH(cmd);char **argv (char **)cmd;
- ret ExecCommand(argc, argv);//modify by yuwguideir.com for optimize boot startup time startret AsyncExecCommand(argc, argv);//modify by yuwguideir.com for optimize boot startup time end} else {unsigned long long realSize size *((unsigned long long)RESIZE_BUFFER_SIZE * RESIZE_BUFFER_SIZE / FS_MANAGER_BUFFER_SIZE);-206,7 233,9 static int DoResizeF2fs(const char* device, const unsigned long long size)};int argc ARRAY_LENGTH(cmd);char **argv (char **)cmd;
- ret ExecCommand(argc, argv);//modify by yuwguideir.com for optimize boot startup time startret AsyncExecCommand(argc, argv);//modify by yuwguideir.com for optimize boot startup time end}return ret;}-224,7 253,9 static int DoFsckF2fs(const char* device)};int argc ARRAY_LENGTH(cmd);char **argv (char **)cmd;
- return ExecCommand(argc, argv);//modify by yuwguideir.com for optimize boot startup time startreturn AsyncExecCommand(argc, argv);//modify by yuwguideir.com for optimize boot startup time end}
其实很简单就是将ExecCommand拷贝一份修改成AsyncExecCommand后再将其中的waitpid的参数设置为WNOHANG这样子进程没有返回的时候父进程也可以继续执行其他工作了关于waitpid可以参考
2.2 sdc命令的耗时缩短
sdc命令是openharmony执行init_global_key命令时调用过来的流程如下 梳理流程后发现是init_global_key会调用到openssl的RAND_bytes去生成随机数经过调查发现linux在开机时由于系统开机时间太短可能会导致系统的随机熵不够当程序从dev/random获取随机数时系统会阻塞直到随机熵增长到一定程度才会返回。这里也是这个原因导致系统阻塞。并且由于这个流程是为了生成分区解密的随机key无法s使用类似于上面的异步方式去执行命令(可能会导致分区无法解密导致某些不可预置的异常)所以只能寻找其他的办法去解决。经过一番查找资料后发现这类随机熵不够的问题一般都是使用工具比如haveged或者rng-tools在开机时迅速增大随机熵来解决的。由于我的设备是aarch64版本的rng-tools无法编译aarch64版本的所以这里我选择了haveged将他预置到系统中后可以正常运行。预置完后再pre_init阶段执行“haveged -F”这条命令即可。预置完后烧录重启可以看到sdc命令从上面的3s左右降低到了0.5s左右也是很大的优化。haveged的编译可以参考下面的链接
获取到haveged的可执行文件后我们就可以考虑预置到系统中了
首先在系统源代码的base/startup/init/目录下新建haveged文件夹并在其创建一个BUILD.gn内容如下
import(//build/ohos.gni)
HAVEGED_DIR //base/startup/init/haveged
print(prebuilt haveged)
ohos_prebuilt_executable(haveged) {source $HAVEGED_DIR/bin/havegedinstall_enable trueinstall_images [ system ]part_name initsubsystem_name startup
}
然后将上面我们编译的可执行文件放到base/startup/init/haveged的bin目录下
最后还要在base/startup/init/bundle.json中添加我们的服务 service_group: [//base/startup/init/watchdog:watchdog,//base/startup/init/haveged:haveged,//base/startup/init/services/etc:watchdog.cfg,//base/startup/init/ueventd:startup_ueventd,//base/startup/init/services/etc:ueventd.cfg
这样haveged命令就预置到系统中了剩下的就是要在哪里执行了我这里是把他放到了pre_init阶段修改如下 a/base/startup/init/services/etc/init.cfgjobs : [{name : pre-init,cmds : [exec /system/bin/haveged -F,write /proc/sys/kernel/sysrq 0,start ueventd,start watchdog_service,mkdir /data,
最后要想让这条命令执行成功还需要关闭selinux的权限检查openharmony的selinux关闭修改如下
/base/security/selinux/selinux.gni
-- selinux_enforce trueselinux_enforce false
2.3 AbilityManagerService的启动
AbilityManagerService是作为foundation服务中的一个ability启动并且由于foundation的ability较多AbilityManagerService的启动较慢。要解决启动慢的问题可以通过增加ability启动的线程池的大小如下
diff --git a/safwk/services/safwk/src/local_ability_manager.cpp b/safwk/services/safwk/src/local_ability_manager.cpp
index 11f7a06..3f6fdf0 100644
--- a/safwk/services/safwk/src/local_ability_manager.cppb/safwk/services/safwk/src/local_ability_manager.cpp-680,7 680,7 bool LocalAbilityManager::Run(int32_t saId)HILOGD(TAG, success to add process name:%{public}s, Str16ToStr8(procName_).c_str());uint32_t concurrentThreads std::thread::hardware_concurrency();HILOGI(TAG, concurrentThreads is %{public}d, concurrentThreads);
- initPool_-Start(concurrentThreads);initPool_-Start(2*concurrentThreads);initPool_-SetMaxTaskNum(MAX_TASK_NUMBER);FindAndStartPhaseTasks(
2.4 launcher启动的耗时缩短
launcher的启动流程如下 简单说一下上面的流程就是account manager启动后会创建一个account启动这个account时会向abilityManagerService发送一条startUser的消息abilityManagerService在接收到消息后会启动launcher最终会调用到abiltiy_manager_service的StartHighestPriorityAbility去启动launcher。
/foundation/ability/ability_runtime/services/abilitymgr/src/ability_manager_service.cpp
void AbilityManagerService::StartHighestPriorityAbility(int32_t userId, bool isBoot)
{....
#ifdef SUPPORT_GRAPHICSabilityWant.SetParam(NEED_STARTINGWINDOW, false);// wait BOOT_ANIMATION_STARTED to start LAUNCHER//这边会等待bootevent.bootanimation.started属性被置为true后才能继续往下走WaitParameter(BOOTEVENT_BOOT_ANIMATION_STARTED.c_str(), true, amsConfigResolver_-GetBootAnimationTimeoutTime());
#endif/* note: OOBE APP need disable itself, otherwise, it will be started when restart system everytime */(void)StartAbility(abilityWant, userId, DEFAULT_INVAL_VALUE);
}
接下来看一下bootevent.bootanimation.started是在哪里设置为true的搜索代码后发现是在下面的函数中置为ture的
/foundation/graphic/graphic_2d/frameworks/bootanimation/src/boot_animation.cpp
void BootAnimation::CheckExitAnimation()
{LOGI(CheckExitAnimation enter);if (!setBootEvent_) {LOGI(CheckExitAnimation set bootevent parameter);system::SetParameter(bootevent.bootanimation.started, true);setBootEvent_ true;}std::string windowInit system::GetParameter(bootevent.boot.completed, false);if (windowInit true) {PostTask(std::bind(AppExecFwk::EventRunner::Stop, runner_));LOGI(CheckExitAnimation read windowInit is true);return;}
}
接着看一下CheckExitAnimation在哪里调用的
/foundation/graphic/graphic_2d/frameworks/bootanimation/src/boot_animation.cpp
void BootAnimation::Draw()
{if (picCurNo_ (imgVecSize_ - 1)) {picCurNo_ picCurNo_ 1;} else {CheckExitAnimation();return;}ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, BootAnimation::Draw RequestFrame);auto frame rsSurface_-RequestFrame(windowWidth_, windowHeight_);if (frame nullptr) {LOGE(Draw frame is nullptr);return;}ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);framePtr_ std::move(frame);auto canvas framePtr_-GetCanvas();OnDraw(canvas, picCurNo_);ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, BootAnimation::Draw FlushFrame);rsSurface_-FlushFrame(framePtr_);ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
}
从上面的代码可以看出来是当开机动画播放完成后才能被置为true。这里的意思就是只有当开机动画全部播放完成后才能启动launcherrk3568的开机动画有150张帧率被设置为了30hZ这样开机动画就需要5s才能播放完毕这样显然是不合理的开机画应该是用来给用户一个提示用来进行系统的初始化的工作的。所以我这边改成每播放一帧开机动画都去检查一下是否能够退出动画。这样也可以加速launcher的启动修改如下
diff --git a/graphic_2d/frameworks/bootanimation/src/boot_animation.cpp b/graphic_2d/frameworks/bootanimation/src/boot_animation.cpp
index 158469f..33e8bb3 100644
--- a/graphic_2d/frameworks/bootanimation/src/boot_animation.cppb/graphic_2d/frameworks/bootanimation/src/boot_animation.cpp-52,9 52,6 void BootAnimation::Draw(){if (picCurNo_ (imgVecSize_ - 1)) {picCurNo_ picCurNo_ 1;
- } else {
- CheckExitAnimation();
- return;}ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, BootAnimation::Draw RequestFrame);auto frame rsSurface_-RequestFrame(windowWidth_, windowHeight_);-69,6 66,9 void BootAnimation::Draw()ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, BootAnimation::Draw FlushFrame);rsSurface_-FlushFrame(framePtr_);ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);CheckExitAnimation();}
同时也需要修改开机动画让开机动画不要结束的太过突兀。至此rk3568的设备就从原来的21s优化到了现在的16.5s左右当然系统内部还有其他可以优化的部分。这里仍然需要持续优化。
三、错误修复
在打入上述修改后发现系统的data分区发生了改变查找原因发现是上面的fcsk的异步执行导致的resize.f2fs在系统第一次启动时会扩充data分区当data分区扩充后后面再重启时resize.f2fs的命令就会报错。所以解决方案如下
diff --git a/startup/init/interfaces/innerkits/fs_manager/fstab_mount.c b/startup/init/interfaces/innerkits/fs_manager/fstab_mount.c
index da4bf43c..fce50d64 100755
--- a/startup/init/interfaces/innerkits/fs_manager/fstab_mount.cb/startup/init/interfaces/innerkits/fs_manager/fstab_mount.c-43,6 43,11 extern C {
const off_t MISC_PARTITION_ACTIVE_SLOT_OFFSET 4096;
const off_t MISC_PARTITION_ACTIVE_SLOT_SIZE 4;//add by yuwguideir.com for fix data partition size error start
const char *DATA_RESIZE_KEY persist.sys.resize_data;
int data_resize 0;
//add by yuwguideir.com for fix data partition size error end#ifdef SUPPORT_HVB
__attribute__((weak)) int UeventdSocketInit(void)
{-210,6 215,11 static int DoResizeF2fs(const char* device, const unsigned long long size)return -1;} char values[2] {0};uint32_t len sizeof(values);int paramGetRet SystemGetParameter(DATA_RESIZE_KEY,values,len);int isResize atoi(values);
int ret 0;if (size 0) {char *cmd[] {-218,7 228,16 static int DoResizeF2fs(const char* device, const unsigned long long size)int argc ARRAY_LENGTH(cmd);char **argv (char **)cmd;//modify by yuwguideir.com for optimize boot startup time start
- ret AsyncExecCommand(argc, argv);if(paramGetRet ! 0 || isResize 0){ret ExecCommand(argc, argv);if(ret ! 0 ){data_resize 0;} else {data_resize 1;}} else {ret AsyncExecCommand(argc, argv);}//modify by yuwguideir.com for optimize boot startup time end} else {unsigned long long realSize size *-234,7 253,16 static int DoResizeF2fs(const char* device, const unsigned long long size)int argc ARRAY_LENGTH(cmd);char **argv (char **)cmd;//modify by yuwguideir.com for optimize boot startup time start
- ret AsyncExecCommand(argc, argv);if(paramGetRet ! 0 || isResize 0){ret ExecCommand(argc, argv);if(ret ! 0 ){data_resize 0;} else {data_resize 1;}} else {ret AsyncExecCommand(argc, argv);}//modify by yuwguideir.com for optimize boot startup time end}return ret;
diff --git a/startup/init/interfaces/innerkits/include/fs_manager/fs_manager.h b/startup/init/interfaces/innerkits/include/fs_manager/fs_manager.h
index 726ad3ed..73186707 100644
--- a/startup/init/interfaces/innerkits/include/fs_manager/fs_manager.hb/startup/init/interfaces/innerkits/include/fs_manager/fs_manager.h-42,6 42,8 extern C {
#define FM_MANAGER_REQUIRED_ENABLED(fsMgrFlags) FS_MANAGER_FLAGS_ENABLED((fsMgrFlags), REQUIRED)
#define FM_MANAGER_NOFAIL_ENABLED(fsMgrFlags) FS_MANAGER_FLAGS_ENABLED((fsMgrFlags), NOFAIL)extern int data_resize;
extern const char *DATA_RESIZE_KEY;
typedef enum MountStatus {MOUNT_ERROR -1,MOUNT_UMOUNTED 0,
diff --git a/startup/init/services/init/standard/init_cmds.c b/startup/init/services/init/standard/init_cmds.c
index 5d61fbda..c56033dc 100755
--- a/startup/init/services/init/standard/init_cmds.cb/startup/init/services/init/standard/init_cmds.c-290,6 290,9 static void DoMountFstabFile(const struct CmdArgs *ctx)
{INIT_LOGI(Mount partitions from fstab file \ %s \, ctx-argv[0]);int ret MountAllWithFstabFile(ctx-argv[0], 0);if(data_resize 1){^MSystemWriteParam(DATA_RESIZE_KEY, 1);^M}^MINIT_LOGI(Mount partitions from fstab file \ %s \ finish ret %d, ctx-argv[0], ret);
}原理时使用一个属性来表示第一次启动如果是第一次启动那么resize.f2fs将会同步执行否则使用异步执行。
为了能让大家更好的学习鸿蒙 (Harmony OS) 开发技术这边特意整理了《鸿蒙 (Harmony OS)开发学习手册》共计890页希望对大家有所帮助https://qr21.cn/FV7h05
《鸿蒙 (Harmony OS)开发学习手册》
入门必看https://qr21.cn/FV7h05
应用开发导读(ArkTS)应用开发导读(Java) HarmonyOS 概念https://qr21.cn/FV7h05
系统定义技术架构技术特性系统安全 如何快速入门https://qr21.cn/FV7h05
基本概念构建第一个ArkTS应用构建第一个JS应用…… 开发基础知识https://qr21.cn/FV7h05
应用基础知识配置文件应用数据管理应用安全管理应用隐私保护三方应用调用管控机制资源分类与访问学习ArkTS语言…… 基于ArkTS 开发https://qr21.cn/FV7h05
Ability开发UI开发公共事件与通知窗口管理媒体安全网络与链接电话服务数据管理后台任务(Background Task)管理设备管理设备使用信息统计DFX国际化开发折叠屏系列……