背景
项目有个心跳功能,在正常模式下5s一个心跳,超过30s未收到心跳系统强制重启。但是进入recovery升级模式后,没有心跳功能,造成升级失败,需要添加心跳的应用程序。添加过程如下。
打开串口log
Recovery的日志是调试的关键,默认会在cache/recovery下面看到,但是里面是空的,没查到原因。遂把串口log等级跳到7,也可以看到日志。
修改启动参数(dts里面,dts编译下载后会放在一个固定位置,uboot和kernel都可以访问):
bootargs = "earlycon=sprd_serial,0x70100000,115200n8 console=ttyS1,115200n8 loglevel=7 init=/init root=/dev/ram0 rw androidboot.hardware=sl8541e_1h10_go vmalloc=360M";
静态编译应用程序
修改应用程序的Android.mk,修改后应用程序实现静态编译,会大一点,主要是因为recovery模式下库文件很少,防止应用程序运行出错,都会用静态编译。
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS :=optional
LOCAL_C_INCLUDES := $(KERNEL_HEADERS)
LOCAL_STATIC_LIBRARIES := libcutils liblog
LOCAL_MODULE:= spitest
LOCAL_SRC_FILES:=spidev_test.c events.c
LOCAL_PRELINK_MODULE := false
LOCAL_CFLAGS := -Wno-unused-parameter
#标志该模块需要强制静态链接
LOCAL_FORCE_STATIC_EXECUTABLE := true
include $(BUILD_EXECUTABLE)
添加recovery模式自动运行应用程序
修改init.rc(device/sprd/sharkle/common / recovery/init.rc)
service spi0daemon /sbin/spitest
class recovery
seclabel u:r:recovery:s0
on property:ro.bootmode=recovery
chmod 666 /sbin/spitest
class_start recovery
trigger adb_enable
spi0daemon 会在recovery class启动时候开启。
拷贝应用程序到recovery根文件系统/sbin下
这个拷贝过程可以通过参考recovery 根文件系统中有个adbd,然后仿照添加拷贝指令:
修改build /make/core/Makefile
# Copy adbd from system/bin to recovery/root/sbin
$(hide) cp -f $(TARGET_OUT_EXECUTABLES)/adbd $(TARGET_RECOVERY_ROOT_OUT)/sbin/adbd
$(hide) cp -f $(TARGET_OUT_EXECUTABLES)/spitest $(TARGET_RECOVERY_ROOT_OUT)/sbin/spitest
$(hide) chmod 777 $(TARGET_RECOVERY_ROOT_OUT)/sbin/spitest
关掉selinux
Reboot recovery后发现日志里面应用程序运行没有selinux权限,增加权限太麻烦,干错关闭。修改recovery下的init.rc(device/sprd/sharkle/common / recovery/init.rc)
on property:ro.bootmode=recovery
chmod 666 /sbin/spitest
chmod 0666 /sys/fs/selinux/enforce
chown system system /sys/fs/selinux/enforce
write /sys/fs/selinux/enforce 0
setenforce 0
class_start recovery
trigger adb_enable
注意操作enforce 时候可能也需要selinux权限,要简单加一个读写enforce 的权限。
#add for setenforce 0
/sys/fs/selinux/enforce u:object_r:file_enforce:s0
type file_enforce, fs_type, sysfs_type;
allow init file_enforce:file {open read write};
allow init kernel:security {setenforce};
neverallow * kernel:security setenforce;
neverallow { domain -kernel } kernel:security setcheckreqprot;