国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

OpenHarmony 啟動流程優(yōu)化

這篇具有很好參考價值的文章主要介紹了OpenHarmony 啟動流程優(yōu)化。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

OpenHarmony 啟動流程優(yōu)化

平臺:潤和的rk3568

分支:openharmony release 3.2

? 目前rk3568的開機時間有21s,統(tǒng)計的是關(guān)機后從按下power按鍵到顯示鎖屏的時間,當對openharmony的系統(tǒng)進行了裁剪子系統(tǒng),系統(tǒng)app,禁用部分服務(wù)后發(fā)現(xiàn)開機時間僅僅提高到了20.94s 優(yōu)化微乎其微。在對init進程的log進行分析并解決其中的時間斷層后 開機時長優(yōu)化到了16.5s左右,可以說是一個非常大的進步了,下面詳細講一下優(yōu)化的過程。

一、定位log

? openharmony支持dmesg打印kernel log和hilog 打印openharony自己的log,所以需要在開機時抓取這兩種log來分析開機流程。openharony的開機流程可以參考

OpenHarmony Init進程的啟動流程

由于本人對于kernel了解比較少,所以對于kernel部分的優(yōu)化無法介紹。從上面的OpenHarmony init進程的啟動流程中我們可以知道openharmony的啟動和Android比較類似都是init進程去解析各種cfg文件啟動服務(wù),那么當kernel 內(nèi)核初始化完后,init進程也就是pid=1的這個進程就是開機過程的主線程。由于openharmny的dmesg log中都攜帶了pid和函數(shù)名稱,所以我們在開機時抓的dmesg log中搜索pid=1可以看到開機時主線程的打印log,先尋找是否有時間斷層的情況,比如我的設(shè)備中dmesg有一處時間斷層如下:

1515: [    4.396049] [pid=1][Init][INFO][init_cmds.c:291]Mount partitions from fstab file " /vendor/etc/fstab.rk3568 "1517: [    4.396782] [pid=1][BEGET][INFO][fstab.c:429]StoreFscryptPolicy:store fscrypt policy, 2:aes-256-cts:aes-256-xts
	行 1522: [    4.897721] [pid=1][BEGET][INFO][fstab_mount.c:78]Execute /system/bin/resize.f2fs begin
	行 1524: [    4.947110] [pid=1][BEGET][ERROR][fstab_mount.c:91]Command /system/bin/resize.f2fs failed with status 2551525: [    4.947141] [pid=1][BEGET][INFO][fstab_mount.c:93]Execute /system/bin/resize.f2fs end
	行 1526: [    4.947218] [pid=1][BEGET][ERROR][fstab_mount.c:394]Failed to resize.f2fs dir /dev/block/platform/fe310000.sdhci/by-name/userdata , ret = 2551527: [    4.947309] [pid=1][BEGET][INFO][fstab_mount.c:78]Execute /system/bin/fsck.f2fs begin
	行 1531: [    7.196164] [pid=1][BEGET][ERROR][fstab_mount.c:91]Command /system/bin/fsck.f2fs failed with status 11532: [    7.196179] [pid=1][BEGET][INFO][fstab_mount.c:93]Execute /system/bin/fsck.f2fs end
	行 1533: [    7.196225] [pid=1][BEGET][ERROR][fstab_mount.c:399]Failed to fsck.f2fs dir /dev/block/platform/fe310000.sdhci/by-name/userdata , ret = 11538: [    7.397003] [pid=1][BEGET][INFO][fstab_mount.c:421]Mount /dev/block/platform/fe310000.sdhci/by-name/userdata to /data successful
	行 1540: [    7.398757] [pid=1][BEGET][INFO][fstab_mount.c:421]Mount /dev/block/platform/fe310000.sdhci/by-name/chip-prod to /chip_prod successful
	行 1542: [    7.400545] [pid=1][BEGET][INFO][fstab_mount.c:421]Mount /dev/block/platform/fe310000.sdhci/by-name/sys-prod to /sys_prod successful
	行 1543: [    7.400598] [pid=1][Init][INFO][init_cmds.c:293]Mount partitions from fstab file " /vendor/etc/fstab.rk3568 " finish ret 0

可以看到上面在4.947309 到7.196164出現(xiàn)了斷層,這段時間主線程什么都沒有輸出,并且查看log發(fā)現(xiàn)init主線程是在執(zhí)行一個命令/system/bin/fsck.f2fs,并且在執(zhí)行了2.2s后還失敗了,但是設(shè)備是可以正常開機的。網(wǎng)上搜索發(fā)現(xiàn)fsck(file system check)用來檢查和維護不一致的文件系統(tǒng)。若系統(tǒng)掉電或磁盤發(fā)生問題,可利用fsck命令對文件系統(tǒng)進行檢查。由于這里是執(zhí)行失敗并且沒有什么影響,所以我這里將這個命令改成了異步執(zhí)行。這樣主線程就可以繼續(xù)往下執(zhí)行了。

在將fsck命令的執(zhí)行修改成異步執(zhí)行后發(fā)現(xiàn)這里的時間斷層消失了但是又發(fā)現(xiàn)了新的時間斷層如下:

// fsck命令時間已經(jīng)恢復(fù)
[    4.894672] [pid=1][BEGET][INFO][fstab_mount.c:102]Execute /system/bin/resize.f2fs begin
[    4.896229] [pid=1][BEGET][INFO][fstab_mount.c:118]Execute /system/bin/resize.f2fs end
[    4.896445] [pid=1][BEGET][INFO][fstab_mount.c:102]Execute /system/bin/fsck.f2fs begin
[    4.898137] [pid=1][BEGET][INFO][fstab_mount.c:118]Execute /system/bin/fsck.f2fs end
//新出現(xiàn)的時間斷層
	行 1943: [    5.236372] [pid=1][BEGET][INFO][fstab.c:434]LoadFscryptPolicy start
	行 1944: [    5.236398] [pid=1][BEGET][INFO][fstab.c:449]LoadFscryptPolicy success
	行 1945: [    5.236533] [pid=1][Init][INFO][init_cmds.c:99]Sync exec: /system/bin/sdc
	行 1992: [    8.223549] [pid=1][Init][INFO][init_cmds.c:112]Sync exec: /system/bin/sdc result 0 11993: [    8.232997] [pid=1][Init][INFO][fscrypt_control.c:217]Fscrypt policy init success
	行 1994: [    8.233204] [pid=1][Init][INFO][key_control.c:204]version 2 loaded
	行 1995: [    8.233234] [pid=1][Init][INFO][fscrypt_control.c:234]key path /data/service/el0/storage_daemon/sd, name /key_id
	行 1996: [    8.233313] [pid=1][Init][INFO][key_control.c:110]enter
	行 1997: [    8.233447] [pid=1][Init][INFO][key_control.c:78]success
	行 1998: [    8.251213] [pid=1][Init][INFO][fscrypt_control.c:186]Have been init
	行 1999: [    8.251311] [pid=1][Init][INFO][key_control.c:204]version 2 loaded
	行 2000: [    8.251328] [pid=1][Init][INFO][fscrypt_control.c:234]key path /data/service/el0/storage_daemon/sd, name /key_id
	行 2001: [    8.251377] [pid=1][Init][INFO][key_control.c:110]enter
	行 2002: [    8.251453] [pid=1][Init][INFO][key_control.c:78]success
	行 2004: [    8.261900] [pid=1][Init][INFO][fscrypt_control.c:186]Have been init
	行 2005: [    8.261969] [pid=1][Init][INFO][key_control.c:204]version 2 loaded
	行 2006: [    8.262016] [pid=1][Init][INFO][fscrypt_control.c:234]key path /data/service/el0/storage_daemon/sd, name /key_id
	行 2007: [    8.262068] [pid=1][Init][INFO][key_control.c:110]enter
	行 2008: [    8.262149] [pid=1][Init][INFO][key_control.c:78]success
	行 2009: [    8.264017] [pid=1][Init][INFO][init_cmds.c:99]Sync exec: /system/bin/sdc
	行 2011: [    8.338298] [pid=1][Init][INFO][init_cmds.c:112]Sync exec: /system/bin/sdc result 0 1

從上面可以知道是系統(tǒng)執(zhí)行sdc命令導(dǎo)致耗時了將近3s那么這個命令又是做什么的為什么會耗費3s,這個我們后面再去分析。

到這里init階段的耗時基本就分析完了,同樣的我們需要接著去分析hilog,我們知道hilog是需要hilogd啟動才能打印,所以dmesg的log中hilogd啟動時間和hilog的打印時間應(yīng)該不會錯的太開。接著我們知道init服務(wù)啟動了很多,那么哪些服務(wù)是啟動launcher的呢?答案是foundation服務(wù)。foundation服務(wù)會啟動AbilityManagerService,在AbilityManagerService中當AccountManagerService發(fā)出切換user 100的請求時就會啟動launcher。我在看dmesg和hilog的過程中發(fā)現(xiàn)了foundation和account的啟動時間如下所示

[    9.420796] [pid=1][Init][INFO][init_service_manager.c:1084]Start service foundation
[    9.457414] [pid=1][Init][INFO][init_common_service.c:387]Service foundation(pid 536) started
[    9.570249] [pid=1][Init][INFO][init_service_manager.c:1084]Start service accountmgr
[    9.571380] [pid=1][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發(fā)送消息竟然耗時長達3.3s,原因是由于foundation內(nèi)部包含的ability比較多,當foundation服務(wù)啟動時,會逐個啟動ability,openharmony的原始設(shè)定是只開了4個線程去啟動ability所以只有等上個ability啟動完成后才能啟動下個ability,這樣會延遲開機時間,這里可以將線程池的線程擴為2倍這樣就可以加速ability的啟動。

在abilitymanagerserice啟動launcher時發(fā)現(xiàn)會一直等待bootevent.bootanimation.started屬性被置為ture后才會啟動launcher,這里也存在一定的耗時,后面我們在代碼分析中繼續(xù)深入了解。

二、代碼分析

2.1 fcsk的異步執(zhí)行

? 首先我們先看一下fcsk如何修改成異步執(zhí)行,首先我們先看一下這個命令是在哪里執(zhí)行的,通過前后的相關(guān)log我們可以確定他是在掛載data分區(qū)時執(zhí)行的,代碼時序圖如下:
openharmony 啟動流程,c++,harmonyos

init進程在啟動時在pre_init階段會去掛載系統(tǒng)的分區(qū)表,這里在掛載data分區(qū)時會調(diào)用到DoFsckF2fs去執(zhí)行文件檢查如下:

/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 參數(shù)設(shè)置為0就會掛起調(diào)用進程(這里是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異步執(zhí)行,加入下面的修改即可

+//add by yuw@guideir.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 yuw@guideir.com for exec async commond end
 
 int 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 yuw@guideir.com for optimize boot startup time start
+        ret = AsyncExecCommand(argc, argv);
+        //modify by yuw@guideir.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 yuw@guideir.com for optimize boot startup time start
+        ret = AsyncExecCommand(argc, argv);
+        //modify by yuw@guideir.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 yuw@guideir.com for optimize boot startup time start
+    return AsyncExecCommand(argc, argv);
+    //modify by yuw@guideir.com for optimize boot startup time end
 }

其實很簡單就是將ExecCommand拷貝一份修改成AsyncExecCommand后再將其中的waitpid的參數(shù)設(shè)置為WNOHANG,這樣子進程沒有返回的時候父進程也可以繼續(xù)執(zhí)行其他工作了,關(guān)于waitpid可以參考

waitpid()函數(shù)詳解

2.2 sdc命令的耗時縮短

sdc命令是openharmony執(zhí)行init_global_key命令時調(diào)用過來的,流程如下:
openharmony 啟動流程,c++,harmonyos

梳理流程后發(fā)現(xiàn)是init_global_key會調(diào)用到openssl的RAND_bytes去生成隨機數(shù),經(jīng)過調(diào)查發(fā)現(xiàn)linux在開機時由于系統(tǒng)開機時間太短可能會導(dǎo)致系統(tǒng)的隨機熵不夠當程序從dev/random獲取隨機數(shù)時,系統(tǒng)會阻塞直到隨機熵增長到一定程度才會返回。這里也是這個原因?qū)е孪到y(tǒng)阻塞。并且由于這個流程是為了生成分區(qū)解密的隨機key,無法s使用類似于上面的異步方式去執(zhí)行命令(可能會導(dǎo)致分區(qū)無法解密導(dǎo)致某些不可預(yù)置的異常),所以只能尋找其他的辦法去解決。經(jīng)過一番查找資料后發(fā)現(xiàn)這類隨機熵不夠的問題一般都是使用工具比如haveged或者rng-tools在開機時迅速增大隨機熵來解決的。由于我的設(shè)備是aarch64版本的,rng-tools無法編譯aarch64版本的,所以這里我選擇了haveged將他預(yù)置到系統(tǒng)中后可以正常運行。預(yù)置完后再pre_init階段執(zhí)行“haveged -F”這條命令即可。預(yù)置完后燒錄重啟可以看到sdc命令從上面的3s左右降低到了0.5s左右,也是很大的優(yōu)化。haveged的編譯可以參考下面的鏈接:

Openharmony 交叉編譯haveged

獲取到haveged的可執(zhí)行文件后,我們就可以考慮預(yù)置到系統(tǒng)中了

首先在系統(tǒng)源代碼的base/startup/init/目錄下新建haveged文件夾并在其創(chuàng)建一個BUILD.gn,內(nèi)容如下:

import("http://build/ohos.gni")
HAVEGED_DIR = "http://base/startup/init/haveged"
print("prebuilt haveged")
ohos_prebuilt_executable("haveged") {
  source = "$HAVEGED_DIR/bin/haveged"
  install_enable = true
  install_images = [ "system" ]
  part_name = "init"
  subsystem_name = "startup"
}

然后將上面我們編譯的可執(zhí)行文件放到base/startup/init/haveged的bin目錄下

最后還要在base/startup/init/bundle.json中添加我們的服務(wù):

                "service_group": [
                    "http://base/startup/init/watchdog:watchdog",
++                    "http://base/startup/init/haveged:haveged",
                    "http://base/startup/init/services/etc:watchdog.cfg",
                    "http://base/startup/init/ueventd:startup_ueventd",
                    "http://base/startup/init/services/etc:ueventd.cfg"

這樣haveged命令就預(yù)置到系統(tǒng)中了,剩下的就是要在哪里執(zhí)行了,我這里是把他放到了pre_init階段,修改如下:

+++ a/base/startup/init/services/etc/init.cfg

    "jobs" : [{
            "name" : "pre-init",
            "cmds" : [
++                "exec /system/bin/haveged -F",
                "write /proc/sys/kernel/sysrq 0",
                "start ueventd",
                "start watchdog_service",
                "mkdir /data",

最后要想讓這條命令執(zhí)行成功還需要關(guān)閉selinux的權(quán)限檢查,openharmony的selinux關(guān)閉修改如下:

/base/security/selinux/selinux.gni
-- selinux_enforce = true
++ selinux_enforce = false

2.3 AbilityManagerService的啟動

AbilityManagerService是作為foundation服務(wù)中的一個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.cpp
+++ b/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的啟動流程如下:

openharmony 啟動流程,c++,harmonyos

簡單說一下上面的流程就是account manager啟動后會創(chuàng)建一個account啟動這個account時會向abilityManagerService發(fā)送一條startUser的消息,abilityManagerService在接收到消息后會啟動launcher,最終會調(diào)用到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_GRAPHICS
    abilityWant.SetParam(NEED_STARTINGWINDOW, false);
    // wait BOOT_ANIMATION_STARTED to start LAUNCHER
    //這邊會等待bootevent.bootanimation.started屬性被置為true后才能繼續(xù)往下走
    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是在哪里設(shè)置為true的,搜索代碼后發(fā)現(xiàn)是在下面的函數(shù)中置為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在哪里調(diào)用的

/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。這里的意思就是只有當開機動畫全部播放完成后才能啟動launcher,rk3568的開機動畫有150張,幀率被設(shè)置為了30hZ這樣開機動畫就需要5s才能播放完畢,這樣顯然是不合理的,開機畫應(yīng)該是用來給用戶一個提示,用來進行系統(tǒng)的初始化的工作的。所以我這邊改成每播放一幀開機動畫都去檢查一下是否能夠退出動畫。這樣也可以加速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.cpp
+++ b/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();
 }

同時也需要修改開機動畫讓開機動畫不要結(jié)束的太過突兀。至此rk3568的設(shè)備就從原來的21s優(yōu)化到了現(xiàn)在的16.5s左右,當然系統(tǒng)內(nèi)部還有其他可以優(yōu)化的部分。這里仍然需要持續(xù)優(yōu)化。

三、錯誤修復(fù)

在打入上述修改后發(fā)現(xiàn)系統(tǒng)的data分區(qū)發(fā)生了改變,查找原因發(fā)現(xiàn)是上面的fcsk的異步執(zhí)行導(dǎo)致的,resize.f2fs在系統(tǒng)第一次啟動時會擴充data分區(qū),當data分區(qū)擴充后后面再重啟時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.c
+++ b/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 yuw@guideir.com for fix data partition size error start
+const char *DATA_RESIZE_KEY = "persist.sys.resize_data";
+int data_resize = 0;
+//add by yuw@guideir.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 yuw@guideir.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 yuw@guideir.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 yuw@guideir.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 yuw@guideir.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.h
+++ b/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.c
+++ b/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){^M
+        SystemWriteParam(DATA_RESIZE_KEY, "1");^M
+    }^M
    INIT_LOGI("Mount partitions from fstab file \" %s \" finish ret %d", ctx->argv[0], ret);
}

原理時使用一個屬性來表示第一次啟動,如果是第一次啟動那么resize.f2fs將會同步執(zhí)行,否則使用異步執(zhí)行。文章來源地址http://www.zghlxwxcb.cn/news/detail-753893.html

到了這里,關(guān)于OpenHarmony 啟動流程優(yōu)化的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • OpenHarmony/HarmonyOS如何獲取系統(tǒng)時間戳

    作者:堅果 團隊:堅果派 公眾號:“大前端之旅” 潤開鴻生態(tài)技術(shù)專家,華為HDE,InfoQ簽約作者,OpenHarmony布道師,擅長HarmonyOS應(yīng)用開發(fā)、熟悉服務(wù)卡片開發(fā),在“戰(zhàn)碼先鋒”活動中作為大隊長,累計培養(yǎng)三個小隊長,帶領(lǐng)100+隊員完成Pr的提交合入。 歡迎通過主頁或者私信

    2024年02月11日
    瀏覽(28)
  • OpenHarmony/HarmonyOS基礎(chǔ)組件之XComponent

    作者:堅果 團隊:堅果派 公眾號:“大前端之旅” 潤開鴻技術(shù)專家,華為HDE,InfoQ簽約作者,OpenHarmony布道師,擅長HarmonyOS應(yīng)用開發(fā)、熟悉服務(wù)卡片開發(fā),在“戰(zhàn)碼先鋒”活動中作為大隊長,累計培養(yǎng)三個小隊長,帶領(lǐng)100+隊員完成Pr的提交合入。 歡迎通過主頁或者私信聯(lián)系

    2024年02月07日
    瀏覽(16)
  • 搭建HarmonyOS開發(fā)環(huán)境(OpenHarmony3.2)

    搭建HarmonyOS開發(fā)環(huán)境(OpenHarmony3.2)

    目前HarmonyOS的熱度愈演愈烈,本文將介紹如何搭建HarmonyOS嵌入式開發(fā)環(huán)境,幫助想要使用HarmonyOS進行嵌入式開發(fā)的人員進行入門。 其實博主以前已經(jīng)介紹過如何搭建HarmonyOS開發(fā)環(huán)境了,但是當時還是HarmonyOS1.0,目前開源版本,OpenHarmony已經(jīng)更新到OpenHarmony3.2了,開發(fā)也相比于

    2024年02月03日
    瀏覽(22)
  • OpenHarmony/HarmonyOS訂閱系統(tǒng)環(huán)境變量的變化

    OpenHarmony/HarmonyOS訂閱系統(tǒng)環(huán)境變量的變化

    系統(tǒng)環(huán)境變量是指:在應(yīng)用程序運行期間,終端設(shè)備的系統(tǒng)設(shè)置(例如系統(tǒng)的語言環(huán)境、屏幕方向等)發(fā)生變化。 開發(fā)者通過訂閱系統(tǒng)環(huán)境變化,可以使應(yīng)用程序及時感知這種變化,并作出相應(yīng)處理,從而提供更好的用戶體驗。例如,用戶更改系統(tǒng)語言設(shè)置時,應(yīng)用程序可以

    2024年01月18日
    瀏覽(16)
  • 鴻蒙應(yīng)用開發(fā)學(xué)習(xí)路線(OpenHarmony/HarmonyOS)

    鴻蒙應(yīng)用開發(fā)學(xué)習(xí)路線(OpenHarmony/HarmonyOS)

    作者:堅果 團隊:堅果派 公眾號:“大前端之旅” 潤開鴻技術(shù)專家,華為HDE,InfoQ簽約作者,OpenHarmony布道師,擅長HarmonyOS應(yīng)用開發(fā)、熟悉服務(wù)卡片開發(fā),在“戰(zhàn)碼先鋒”活動中作為大隊長,累計培養(yǎng)三個小隊長,帶領(lǐng)100+隊員完成Pr的提交合入。 歡迎通過主頁或者私信聯(lián)系

    2024年02月15日
    瀏覽(97)
  • HarmonyOS/OpenHarmony元服務(wù)開發(fā)-卡片生命周期管理

    創(chuàng)建ArkTS卡片,需實現(xiàn)FormExtensionAbility生命周期接口。 1.在EntryFormAbility.ts中,導(dǎo)入相關(guān)模塊。 2.在EntryFormAbility.ts中,實現(xiàn)FormExtensionAbility生命周期接口,其中在onAddForm的入?yún)ant中可以通過FormParam取出卡片的相關(guān)信息。 說明:FormExtensionAbility進程不能常駐后臺,即在卡片生命周

    2024年02月15日
    瀏覽(20)
  • HarmonyOS/OpenHarmony元服務(wù)開發(fā)-配置卡片的配置文件

    HarmonyOS/OpenHarmony元服務(wù)開發(fā)-配置卡片的配置文件

    卡片相關(guān)的配置文件主要包含F(xiàn)ormExtensionAbility的配置和卡片的配置兩部分: 1.卡片需要在module.json5配置文件中的extensionAbilities標簽下,配置FormExtensionAbility相關(guān)信息。FormExtensionAbility需要填寫metadata元信息標簽,其中鍵名稱為固定字符串“ohos.extension.form”,資源為卡片的具體配

    2024年02月14日
    瀏覽(19)
  • 【HarmonyOS開發(fā)】OpenHarmony如何實現(xiàn)?次開發(fā),多端部署

    【HarmonyOS開發(fā)】OpenHarmony如何實現(xiàn)?次開發(fā),多端部署

    OpenHarmony提供用戶程序框架、Ability框架以及UI框架,能夠保證開發(fā)的應(yīng)用在多終端運行時保證一致性。一次開發(fā)、多端部署。? 多終端軟件平臺API具備一致性,確保用戶程序的運行兼容性。 HarmonyOS提供了用戶程序框架、 Ability 框架以及UI框架,支持應(yīng)用開發(fā)過程中多終端的業(yè)

    2024年02月03日
    瀏覽(22)
  • HarmonyOS/OpenHarmony元服務(wù)開發(fā)-ArkTS卡片運行機制

    HarmonyOS/OpenHarmony元服務(wù)開發(fā)-ArkTS卡片運行機制

    一、實現(xiàn)原理 圖1?ArkTS卡片實現(xiàn)原理 ? 卡片使用方:顯示卡片內(nèi)容的宿主應(yīng)用,控制卡片在宿主中展示的位置,當前僅系統(tǒng)應(yīng)用可以作為卡片使用方。 卡片提供方:提供卡片顯示內(nèi)容的應(yīng)用,控制卡片的顯示內(nèi)容、控件布局以及控件點擊事件。 卡片管理服務(wù):用于管理系統(tǒng)

    2024年02月16日
    瀏覽(23)
  • HarmonyOS/OpenHarmony應(yīng)用開發(fā)-HDC環(huán)境變量設(shè)置

    HarmonyOS/OpenHarmony應(yīng)用開發(fā)-HDC環(huán)境變量設(shè)置

    hdc(HarmonyOS Device Connector)是 HarmonyOS 為開發(fā)人員提供的用于調(diào)試的命令行工具,通過該工具可以在 windows/linux/mac 系統(tǒng)上與真實設(shè)備或者模擬器進行交互。 hdc 工具通過 HarmonyOS SDK 獲取,存放于 /Huawei/Sdk/openharmony/版本號/toolchains/ 目錄下。 1、打開環(huán)境變量 2、新建系統(tǒng)變量 3、

    2024年04月15日
    瀏覽(62)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包