提交 e3847332 编写于 作者: S sun_fan

init: add boot up logo

Signed-off-by: Nsun_fan <sun_fan1@hoperun.com>
上级 93c3e264
......@@ -6,7 +6,8 @@
"//base/startup/init_lite/services:startup_init",
"//base/startup/init_lite/ueventd:ueventd",
"//base/startup/init_lite/ueventd:ueventd.config",
"//base/startup/init_lite/watchdog:watchdog"
"//base/startup/init_lite/watchdog:watchdog",
"//base/startup/init_lite/services/cmds/misc:misc_daemon"
],
"test_list": [
"//base/startup/init_lite/services/test/unittest:init_test"
......
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos.gni")
ohos_executable("misc_daemon") {
sources = [ "misc_daemon.cpp" ]
include_dirs = [
"//base/update/updater/interfaces/kits/include/misc_info",
"//base/startup/init_lite/interfaces/innerkits/include",
"//base/startup/syspara_lite/interfaces/innerkits/native/syspara/include",
]
deps = [
"//base/startup/init_lite/interfaces/innerkits/fs_manager:libfsmanager_shared",
"//base/startup/syspara_lite/interfaces/innerkits/native/syspara:syspara",
]
install_images = [ "system" ]
install_enable = true
part_name = "init"
}
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cerrno>
#include <cstdint>
#include <fcntl.h>
#include <getopt.h>
#include <iostream>
#include <string>
#include <sys/stat.h>
#include "fs_manager/fs_manager.h"
#include "misc_info.h"
#include "param_wrapper.h"
constexpr int PARTITION_INFO_POS = 1144;
constexpr int PARTITION_INFO_MAX_LENGTH = 256;
constexpr int BLOCK_SZIE_1 = 512;
constexpr uint64_t LOGO_MAGIC = 0XABCABCAB;
struct option g_options[] = {
{ "write_logo", required_argument, nullptr, 0 },
{ nullptr, 0, nullptr, 0 },
};
static std::string GetMiscDevicePath()
{
std::string miscDev {};
// Get misc device path from fstab
std::string hardwareVal {};
int ret = OHOS::system::GetStringParameter("ohos.boot.hardware", hardwareVal, "");
if (ret != 0) {
std::cout << "get ohos.boot.hardware failed\n";
return "";
}
std::string fstabFileName = std::string("fstab.") + hardwareVal;
std::string fstabFile = std::string("/vendor/etc/") + fstabFileName;
Fstab *fstab = ReadFstabFromFile(fstabFile.c_str(), false);
if (fstab == nullptr) {
std::cout << "Failed to read fstab\n";
return miscDev;
}
FstabItem *misc = FindFstabItemForMountPoint(*fstab, "/misc");
if (misc == nullptr) {
std::cout << "Cannot find misc partition from fstab\n";
return miscDev;
}
miscDev = misc->deviceName;
ReleaseFstab(fstab);
return miscDev;
}
static void ClearLogo(int fd)
{
if (fd < 0) {
return;
}
char buffer[8] = {0}; // logo magic number + logo size is 8
int addrOffset = (PARTITION_INFO_POS + PARTITION_INFO_MAX_LENGTH + BLOCK_SZIE_1 -1) / BLOCK_SZIE_1;
if (lseek(fd, addrOffset * BLOCK_SZIE_1, SEEK_SET) < 0) {
std::cout << "Failed to clean file\n";
return;
}
if (write(fd, &buffer, sizeof(buffer)) != sizeof(buffer)) {
std::cout << "clean misc failed\n";
return;
}
}
static void WriteLogoContent(int fd, const std::string &logoPath, uint32_t size)
{
if (fd < 0 || logoPath.empty() || size <= 0) {
std::cout << "path is null or size illegal\n";
return;
}
FILE* rgbFile = fopen(logoPath.c_str(), "rb");
if (rgbFile == nullptr) {
std::cout << "cannot find pic file\n";
return;
}
char* buffer = (char*)malloc(size);
if (buffer == nullptr) {
return;
}
uint32_t ret = fread(buffer, 1, size, rgbFile);
if (ret < 0) {
return;
}
ret = write(fd, buffer, size);
if (ret != size) {
return;
}
if (buffer != nullptr) {
free(buffer);
buffer = nullptr;
}
(void)fclose(rgbFile);
}
static int WriteLogo(int fd, const std::string &logoPath)
{
if (fd < 0 || logoPath.empty()) {
std::cout << "Invalid arguments\n";
return -1;
}
int addrOffset = (PARTITION_INFO_POS + PARTITION_INFO_MAX_LENGTH + BLOCK_SZIE_1 - 1) / BLOCK_SZIE_1;
if (lseek(fd, addrOffset * BLOCK_SZIE_1, SEEK_SET) < 0) {
std::cout << "Failed to seek file\n";
return -1;
}
uint32_t magic = 0;
if (read(fd, &magic, sizeof(uint32_t)) != sizeof(uint32_t)) {
std::cout << "Failed to read magic number\n";
return -1;
}
if (magic == LOGO_MAGIC) {
std::cout << "Get matched magic number, logo already written\n";
return 0;
}
struct stat st {};
magic = LOGO_MAGIC;
lseek(fd, addrOffset * BLOCK_SZIE_1, SEEK_SET);
if (write(fd, &magic, sizeof(magic)) != sizeof(magic)) {
std::cout << "Write magic number failed\n";
return -1;
}
if (stat(logoPath.c_str(), &st) < 0) {
if (errno == ENOENT) {
std::cout << logoPath << " is not exist\n";
} else {
std::cout << "Failed to get " << logoPath << " stat\n";
}
ClearLogo(fd);
return -1;
}
if (st.st_size < 0 || st.st_size > updater::MAX_LOGO_SIZE) {
std::cout << "Invalid logo file with size \n";
ClearLogo(fd);
return -1;
}
uint32_t logoSize = static_cast<uint32_t>(st.st_size);
if (write(fd, &logoSize, sizeof(logoSize)) != sizeof(logoSize)) {
std::cout << "Write logo size failed\n";
ClearLogo(fd);
return -1;
}
WriteLogoContent(fd, logoPath, logoSize);
return 0;
}
static void WriteLogoToMisc(const std::string &logoPath)
{
if (logoPath.empty()) {
std::cout << "logo path is empty\n";
return;
}
std::string miscDev = GetMiscDevicePath();
if (miscDev.empty()) {
return;
}
int fd = open(miscDev.c_str(), O_RDWR | O_CLOEXEC, 0644);
if (fd < 0) {
std::cout << "Failed to open " << miscDev << ", err = " << errno << std::endl;
return;
}
if (WriteLogo(fd, logoPath) < 0) {
std::cout << "Write logo to " << miscDev << " failed" << std::endl;
}
close(fd);
int addrOffset = (PARTITION_INFO_POS + PARTITION_INFO_MAX_LENGTH + BLOCK_SZIE_1 - 1) / BLOCK_SZIE_1;
int fd1 = open(miscDev.c_str(), O_RDWR | O_CLOEXEC, 0644);
if (lseek(fd1, addrOffset * BLOCK_SZIE_1, SEEK_SET) < 0) {
std::cout << "Failed to seek file\n";
return;
}
uint32_t magic = 0;
uint32_t size = 0;
if (read(fd1, &magic, sizeof(uint32_t)) != sizeof(uint32_t)) {
std::cout << "Failed to read magic number\n";
return;
}
if (read(fd1, &size, sizeof(uint32_t)) != sizeof(uint32_t)) {
std::cout << "Failed to read magic number\n";
return;
}
close(fd1);
}
int main(int argc, char **argv)
{
int rc = -1;
int optIndex = -1;
while ((rc = getopt_long(argc, argv, "", g_options, &optIndex)) != -1) {
switch (rc) {
case 0: {
std::string optionName = g_options[optIndex].name;
if (optionName == "write_logo") {
std::string logoPath = optarg;
WriteLogoToMisc(logoPath);
}
break;
}
case '?':
std::cout << "Invalid arugment\n";
break;
default:
std::cout << "Invalid arugment\n";
break;
}
}
}
......@@ -188,6 +188,7 @@
}, {
"name" : "post-fs-data",
"cmds" : [
"start misc",
"chown system system /data",
"chmod 0771 /data",
"mkdir /data/bootchart 0755 shell shell",
......@@ -410,6 +411,10 @@
"disabled" : 1,
"uid" : "root",
"gid" : ["shell", "log", "readproc"]
}, {
"name" : "misc",
"path" : ["/system/bin/misc_daemon", "--write_logo", "/vendor/logo.rgb"],
"once" : 1
}
]
......
......@@ -190,6 +190,7 @@
}, {
"name" : "post-fs-data",
"cmds" : [
"start misc",
"chown system system /data",
"chmod 0771 /data",
"mkdir /data/bootchart 0755 shell shell",
......@@ -412,7 +413,10 @@
"disabled" : 1,
"uid" : "root",
"gid" : ["shell", "log", "readproc"]
}, {
"name" : "misc",
"path" : ["/system/bin/misc_daemon", "--write_logo", "/vendor/logo.rgb"],
"once" : 1
}
]
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册