源码平台:rk3399
摘要:
1.拷贝cameraserver.rc编译拷贝到system/etc/init目录
2.启动cameraserver服务
摘要1:cameraserver.rc编译拷贝到system/etc/init目录
android 系统启动完bootloader后,会启动内核,内核启动完后,会启动文件系统,很多服务也是在这时候启动起来,CameraService的启动在frameworks/av/camera/cameraserver/cameraserver.rc文件
service cameraserver /system/bin/cameraserver
class main
user cameraserver
group audio camera input drmrpc readproc
ioprio rt 4
writepid /dev/cpuset/camera-daemon/tasks /dev/stune/top-app/tasks
这个文件会在Android.mk文件里面编译到指定位置:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
main_cameraserver.cpp
LOCAL_SHARED_LIBRARIES := \
libcameraservice \
libcutils \
libutils \
libbinder \
libcamera_client
LOCAL_MODULE:= cameraserver
LOCAL_32_BIT_ONLY := true
LOCAL_CFLAGS += -Wall -Wextra -Werror -Wno-unused-parameter
LOCAL_INIT_RC := cameraserver.rc #这里指定编译为LOCAL_INIT_RC
include $(BUILD_EXECUTABLE)
其中LOCAL_INIT_RC := cameraserver.rc这个LOCAL_INIT_RC在编译的时候,build/core/base_rules.mk会将这个文件直接拷贝到/system/etc/init目录下,
# Rule to install the module's companion init.rc.
my_init_rc := $(LOCAL_INIT_RC_$(my_32_64_bit_suffix))
my_init_rc_src :=
my_init_rc_installed :=
ifndef my_init_rc
my_init_rc := $(LOCAL_INIT_RC)
# Make sure we don't define the rule twice in multilib module.
LOCAL_INIT_RC :=
endif
ifdef my_init_rc
my_init_rc_src := $(LOCAL_PATH)/$(my_init_rc)
my_init_rc_installed := $(TARGET_OUT$(partition_tag)_ETC)/init/$(notdir
$(my_init_rc_src)) #这里指定的install路径就是/system/etc/init/目录
$(my_init_rc_installed) : $(my_init_rc_src) | $(ACP)
@echo "Install: $@"
$(copy-file-to-new-target)
$(my_register_name) : $(my_init_rc_installed)
endif # my_init_rc
endif # !LOCAL_UNINSTALLABLE_MODULE
摘要2.启动cameraserver服务
system/core/init/init.cpp根据/init.rc启动一个无限循环的进程,也就是init进程,init进程会等待一些命令抛进来执行.加载到fstab.rk30board后,这个文件会挂载各个分区,挂载分区的后,会扫描执行分区下的指定目录,在system/core/init/builtins.cpp,do_mount_all函数会根据fstab.rk30board文件挂载各个分区,具体怎么挂载这里不描述,最终会导入并解析rc文件
/* mount_all <fstab> [ <path> ]* [--<options>]*
*
* This function might request a reboot, in which case it will
* not return.
*/
static int do_mount_all(const std::vector<std::string>& args) {
std::size_t na = 0;
bool import_rc = true;
bool queue_event = true;
int mount_mode = MOUNT_MODE_DEFAULT;
const char* fstabfile = args[1].c_str();
std::size_t path_arg_end = args.size();
for (na = args.size() - 1; na > 1; --na) {
if (args[na] == "--early") {
path_arg_end = na;
queue_event = false;
mount_mode = MOUNT_MODE_EARLY;
} else if (args[na] == "--late") {
path_arg_end = na;
import_rc = false;
mount_mode = MOUNT_MODE_LATE;
}
}
/* 这里会先读取根目录的fstab.rk30board 文件
这个文件指定了要挂载的各个分区,包括system分区 */
int ret = mount_fstab(fstabfile, mount_mode);
/* 分区挂载出来后,开始搜索导入rc文件 */
if (import_rc) {
/* Paths of .rc files are specified at the 2nd argument and beyond */
import_late(args, 2, path_arg_end);
}
if (queue_event) {
/* queue_fs_event will queue event based on mount_fstab return code
* and return processed return code*/
ret = queue_fs_event(ret);
}
return ret;
}
/* Imports .rc files from the specified paths. Default ones are applied if none is given.
*
* start_index: index of the first path in the args list
*/
static void import_late(const std::vector<std::string>& args, size_t start_index, size_t end_index) {
Parser& parser = Parser::GetInstance();
if (end_index <= start_index) {
// Use the default set if no path is given
static const std::vector<std::string> init_directories = {
"/system/etc/init",
"/vendor/etc/init",
"/odm/etc/init"
};
for (const auto& dir : init_directories) {
parser.ParseConfig(dir);
}
} else {
for (size_t i = start_index; i < end_index; ++i) {
parser.ParseConfig(args[i]);
}
}
}
其中也会解析到/system/etc/init/cameraserver.rc文件.具体的解析过程可以看init目录下的源码,这里直接简单讲解下过程
1.init.cpp会实例一个Parser,这个Parser添加了service,on,import三个SectionParser,这三个SectionParser解析出是否是server,还是on的section时,就用对应的解析器解析了
2.上面说的解析器具体有3个,但import实际上导入后,还是调用service或者action的解析器,service和action的解析器都是继承SectionParser的
3.service的解析器会针对每个选项进行解析,比如:
Service::OptionHandlerMap::Map& Service::OptionHandlerMap::map() const {
constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();
static const Map option_handlers = {
{"class", {1, 1, &Service::HandleClass}},
{"console", {0, 0, &Service::HandleConsole}},
{"critical", {0, 0, &Service::HandleCritical}},
{"disabled", {0, 0, &Service::HandleDisabled}},
{"group", {1, NR_SVC_SUPP_GIDS + 1, &Service::HandleGroup}},
{"ioprio", {2, 2, &Service::HandleIoprio}},
{"keycodes", {1, kMax, &Service::HandleKeycodes}},
{"oneshot", {0, 0, &Service::HandleOneshot}},
{"onrestart", {1, kMax, &Service::HandleOnrestart}},
{"seclabel", {1, 1, &Service::HandleSeclabel}},
{"setenv", {2, 2, &Service::HandleSetenv}},
{"socket", {3, 6, &Service::HandleSocket}},
{"user", {1, 1, &Service::HandleUser}},
{"writepid", {1, kMax, &Service::HandleWritepid}},
};
return option_handlers;
}
所以对于cameraserver
service cameraserver /system/bin/cameraserver
class main
user cameraserver
group audio camera input drmrpc readproc
ioprio rt 4
writepid /dev/cpuset/camera-daemon/tasks /dev/stune/top-app/tasks
每一行的都有对于的处理函数../service.cpp 的start函数根据配置启动服务,启动服务时在内核打印
NOTICE("Starting service '%s'...\n", name_.c_str());
rk3399-x24:/ # dmesg | grep "Starting service"
[ 3.351255] init: Starting service 'ueventd'...
[ 3.900692] init: Starting service 'healthd'...
[ 3.902384] init: Starting service 'zygote'...
[ 3.903117] init: Starting service 'zygote_secondary'...
[ 3.903727] init: Starting service 'lmkd'...
[ 3.904320] init: Starting service 'servicemanager'...
[ 3.905270] init: Starting service 'surfaceflinger'...
[ 3.906341] init: Starting service 'vold'...
[ 3.957724] init: Starting service 'debuggerd'...
[ 3.958596] init: Starting service 'debuggerd64'...
[ 4.259461] init: Starting service 'exec 1 (/system/bin/tzdatacheck)'...
[ 4.286239] init: Starting service 'logd'...
[ 4.287204] init: Starting service 'logd-reinit'...
[ 4.304512] init: Starting service 'console'...
[ 4.305094] init: Starting service 'adbd'...
[ 4.306347] init: Starting service 'ril-daemon'...
[ 4.307179] init: Starting service 'drmservice'...
[ 4.308131] init: Starting service 'akmd'...
[ 4.317428] init: Starting service 'audioserver'...
[ 4.321919] init: Starting service 'cameraserver'... cameraserver服务
[ 4.322659] init: Starting service 'drm'...
[ 4.323364] init: Starting service 'installd'...
[ 4.324265] init: Starting service 'keystore'...
[ 4.327250] init: Starting service 'mediacodec'...
[ 4.327986] init: Starting service 'mediadrm'...
[ 4.328601] init: Starting service 'mediaextractor'...
[ 4.329469] init: Starting service 'media'...
[ 4.330048] init: Starting service 'netd'...
[ 4.331389] init: Starting service 'gatekeeperd'...
[ 4.342622] init: Starting service 'perfprofd'...
[ 5.409223] init: Starting service 'bootanim'...
[ 11.399632] init: Starting service 'mode_switch'...
[ 11.402586] init: Starting service 'exec 3 (/system/bin/bootstat)'...
[ 11.421041] init: Starting service 'exec 4 (/system/bin/bootstat)'...
[ 11.430231] init: Starting service 'exec 5 (/system/bin/bootstat)'...
[ 11.441745] init: Starting service 'exec 6 (/system/bin/bootstat)'...
至此,cameraserver的服务就启动起来了
来源:CSDN
作者:kiazhu
链接:https://blog.csdn.net/kiazhu/article/details/84643769