1.自定义rc文件

自定义一个标签,找一个可以执行的rc文件赋值进去。我是保存在/device///init.target.rc中。

1
2
3
4
5
6
7
8
9
10
service firewalldaemon /vendor/bin/firewalldaemon
class main
user system
group system inet net_admin
disabled
capabilities NET_ADMIN NET_RAW
socket firewall stream 0660 root system

on zygote-start
start firewalldaemon
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// Android.mk文件
LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

#LOCAL_PROPRIETARY_MODULE := true
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE := firewalldaemon
LOCAL_INIT_RC := firewalldaemon.rc

LOCAL_MODULE_TAGS := optional

LOCAL_CPPFLAGS := -Wall \
-Werror \
-Wno-unused-parameter \
-DLOG_TAG=\"FirewallDaemon\"

LOCAL_SRC_FILES := src/ServerSocket.cpp \
src/Socket.cpp \
src/main.cpp

LOCAL_C_INCLUDES := src/

LOCAL_SHARED_LIBRARIES := \
liblogwrap \
libcutils \
libutils \
liblog

include $(GEN_PREBUILT_PACKAGE)
include $(BUILD_EXECUTABLE)

编译出来一个firewalldaemon可执行文件。

将firewalldaemon PUSH到/vendor/bin目录下。

然后修改/vendor/etc/init/hw/init.qcom.rc,将上面rc标签复制到这个文件末尾,重启车机会发现我们标签声明的文件根本没有执行。

2.调查问题

2.1 Selinux权限问题

猜测是不是selinux没有给权限

1
2
msmnile_gvmq:/ # getenforce
Permissive

发现是在兼容模式,讲道理应该只是有日志输出来,不会拦截呀。排除这个可能。

2.2 ramdisk介绍与定制

randisk介绍.png

内存磁盘镜像.png

烧写镜像.png

最后发现车机高通的系统修改了RC文件,重启之后RC文件并没有被替换成boot.img中的文件。说明修改是生效了的。但是服务还是无法启动。

2.3启动指令启动服务

1
2
msmnile_gvmq:/ # setprop ctl.start firewalldaemon
setprop ctl.start firewalldaemon

我写的firewalldaemon是一个while(1)不会退出程序,结果通过指令也无法启动,查看dmesg信息,报如下问题。

1
2
3
4
msmnile_gvmq:/ # dmesg|grep -ie firewall
dmesg|grep -ie firewall
[ 6592.467286] init: Received control message 'start' for 'firewalldaemon' from pid: 29798 (setprop ctl.start firewalldaemon)
[ 6592.467412] init: Could not ctl.start for service firewalldaemon: File /vendor/bin/firewalldaemon(labeled "u:object_r:vendor_file:s0") has incorrect label or no domain transition from u:r:init:s0 to another SELinux domain defined. Have you configured your service correctly? https://source.android.com/security/selinux/device-policy#label_new_services_and_address_denials

此消息说明即使Selinux是Permissive模式也不行,因为进程还没有起来,进程起来之后才可以通过Permissive模式配置规则。

于是开始配置规则。

  • step 1: 为/vendor/bin/firewalldaemon 添加标签
1
2
3
//在device/qcom/sepolicy/vendor/common/file_contexts 添加

/vendor/bin/firewalldaemon u:object_r:firewalldaemon_exec:s0
  • step 2: 创建一个新网域“firewalldaemon”
1
2
3
4
5
6
7
// 创建device/qcom/sepolicy/vendor/common/firewalldaemon.te

# firewalldaemon service
type firewalldaemon, domain;
type firewalldaemon_exec, vendor_file_type, exec_type, file_type;

init_daemon_domain(firewalldaemon)
  • step 3: 在init.target.rc中添加需要启动的服务
1
2
3
4
5
6
7
8
9
//device/qcom/msmnile_gvmq/init.target.rc

service firewalldaemon /vendor/bin/firewalldaemon
class main
user system
group system inet net_admin
disabled
capabilities NET_ADMIN NET_RAW
socket tsfirewall stream 0660 root system
  • 重新编译系统并且烧写img

2.4 编译问题

1
2
// 编译日志输出:
make -j4 2>&1 | tee android_build_log.txt

编译报错.png

报错原因.png

报错信息:执行文件需要vendor file域,需要在firewalldaemon.te中添加vendor_file_type

2.5 生成vendor.img

使用fastboot烧写img

进入fastboot模式按住“Q”开机启动,但是串口无法输入。查看USB驱动是否有,查看串口工具配置,记得关闭“流控”。

串口配置.png

连接成功,进入到fastboot模式

使用电脑CMD查看连接设备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 查看设备
fastboot devices -l

// 烧写img
fastboot flash la_vendor_a C:\Users\81566\Desktop\vendor.img

// 可刷写的img
fastboot flash la_system_a system.img
fastboot flash la_vendor_a vendor.img
fastboot flash la_userdata userdata.img
fastboot flash la_persist persist.img
fastboot flash vbmeta_a vbmeta.img
fastboot flash dtbo_a dtbo.img


// 重启车机
fastboot reboot

烧写成功.png

2.6 重启车机见证奇迹的时刻

firewall服务自启动.png

3.编译报缺少classes-head.jar

编译缺少classes-header.png

解决办法:将工程移入到/vendor/ts/proprietary

然后正常编译即可