1.[Sprd]-(Sprd9820e安卓4.4平台user版开启长按power键开启sysdump分析)

1.sp9820e安卓4.4开启长按power开启sysdump

1.1uboot开启arm reset
u-boot15/include/configs/sp9820e_2h10.h
#if DEBUG
#define CONFIG_7S_RST_SW_MODE	1	//0:hw reset,1:arm reset,power keep on	//soft for debug version
#else
#define CONFIG_7S_RST_SW_MODE	0	//0:hw reset,1:arm reset,power keep on	//hard for user version
#endif
uboot sysdump源文件目录
./u-boot15/common/loader/sysdump.c
1.2 配置文件修改为on
vendor/sprd/proprietories-source/sprd_debug/systemDebugger/user/.sprd_debugger.conf
---off
+++on

2.kernel处源码分析:
./kernel/drivers/soc/sprd/debug/sysdump/sysdump.c

2.1初始化时创建了一个//proc/sprd_sysdump控制节点
int sysdump_sysctl_init(void)
{
	/*get_sprd_sysdump_info_paddr(); */
	unsigned long sprd_sysdump_info_paddr;
	struct proc_dir_entry *sysdump_proc;

	sprd_sysdump_info_paddr = get_sprd_sysdump_info_paddr();
	if (!sprd_sysdump_info_paddr)
		pr_emerg("get sprd_sysdump_info_paddr failed.\n");
	sprd_sysdump_info = (struct sysdump_info *)
	    phys_to_virt(sprd_sysdump_info_paddr);
	pr_emerg("vaddr is %p,paddr is %p\n",
		 sprd_sysdump_info, (void *)sprd_sysdump_info_paddr);

	sysdump_sysctl_hdr =
	    register_sysctl_table((struct ctl_table *)sysdump_sysctl_root);
	if (!sysdump_sysctl_hdr)
		return -ENOMEM;

	crash_notes = alloc_percpu(note_buf_t);
	if (crash_notes == NULL)
		return -ENOMEM;
	if (input_register_handler(&sysdump_handler))
		pr_emerg("regist sysdump_handler failed.\n");

	sysdump_proc = proc_create("sprd_sysdump", S_IWUSR | S_IRUSR, NULL, &sysdump_proc_fops);
	if (!sysdump_proc)
		return -ENOMEM;

	sprd_sysdump_init = 1;

	memset(g_ktxt_hash_data, 0x55, SHA1_DIGEST_SIZE);
	sg_init_one(&sg, _stext, _etext-_stext);
	desc.tfm = crypto_alloc_hash("sha1", 0, CRYPTO_ALG_ASYNC);
	crypto_hash_init(&desc);

	return 0;
}
2.2从代码中可以看出,往/proc/sprd_sysdump中写on就会打开sysdump,写off则关掉。
static ssize_t sprd_sysdump_write(struct file *file, const char __user *buf,
				size_t count, loff_t *data)
{
	char sysdump_buf[5] = {0};

	pr_emerg("sprd_sysdump_write: start!!!\n");
	if (count) {
		if (copy_from_user(sysdump_buf, buf, count)) {
			pr_emerg("sprd_sysdump_write: copy_from_user failed!!!\n");
			return -1;
		}
		sysdump_buf[count] = '\0';

		if (!strncmp(sysdump_buf, "on", 2)) {
			pr_emerg("sprd_sysdump_write: enable user version sysdump!!!\n");
			sysdump_status = 1;
			sprd_set_reboot_mode("dumpenable");
			set_sysdump_enable(1);
#ifndef CONFIG_SPRD_DEBUG
			sysdump_enable_watchdog(0);
#endif
		} else if (!strncmp(sysdump_buf, "off", 3)) {
			pr_emerg("sprd_sysdump_write: disable user version sysdump!!!\n");
			sysdump_status = 0;
			sprd_set_reboot_mode("dumpdisable");
			set_sysdump_enable(0);
#ifndef CONFIG_SPRD_DEBUG
			sysdump_enable_watchdog(1);
#endif
		}
	}

	pr_emerg("sprd_sysdump_write: end!!!\n");
	return count;
}
2.3 cat /proc/sprd_sysdump读取sysdump开启状态
static int sprd_sysdump_read(struct seq_file *s, void *v)
{
	seq_printf(s, "sysdump_status = %d\n", sysdump_status);
	return 0;
}

static int sprd_sysdump_open(struct inode *inode, struct file *file)
{
	return single_open(file, sprd_sysdump_read, NULL);
}

3.用户层开启sysdump
vendor/sprd/proprietories-source/sprd_debug/systemDebugger/

3.1 Android.mk中对userdebug和user版作了区分
LOCAL_MODULE := .sprd_debugger.conf
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
ifneq ($(TARGET_BUILD_VARIANT),user)
LOCAL_SRC_FILES := userdebug/$(LOCAL_MODULE)
else
LOCAL_SRC_FILES := user/$(LOCAL_MODULE)
endif
3.2查看user/user版的配置文件、
user/.sprd_debugger.conf
root@root:systemDebugger$ cat user/.sprd_debugger.conf 
off
userdebug/.sprd_debugger.conf
root@root:systemDebugger$ cat user/.sprd_debugger.conf 
on
3.3 用户层代码,读取配置文件中的值,将on/off 写入SPRD_SYSDUMP_CONFIG
#define SPRD_CONFIG_PATH      "data/sprd_debug/.sprd_debugger.conf"
#define SPRD_CONFIG_ORIG      "/system/etc/.sprd_debugger.conf"
#define SPRD_SYSDUMP_CONFIG   "/proc/sprd_sysdump"

#define SOCKET_NAME "SystemDebugger"
static int do_server(){
  FILE* fp;
  int result;

  if ((fp = fopen(SPRD_CONFIG_PATH, "r"))== NULL) {
     result = copyConfFile();
     if(result==-1) {
        ALOGE(" Unable to open %s : %s\n", SPRD_CONFIG_PATH, strerror(errno));
        return -1;
     }
     ALOGD("Initial config %s ", sysdumpconfig);
  } else {
    sysdumpconfig = fgets(configBuffer, sizeof(configBuffer), fp);
    fclose(fp);
  }

  ALOGD("sysdumpconfig = %s",sysdumpconfig);
  if(sysdumpconfig == NULL){
    if ((fp = fopen(SPRD_SYSDUMP_CONFIG, "r"))){
        sysdumpconfig = fgets(configBuffer, sizeof(configBuffer), fp);
        ALOGD("gets config from %s = %s", SPRD_SYSDUMP_CONFIG,sysdumpconfig);
        if(strstr(sysdumpconfig,"1")) {
           writeConfig("on");
           strcpy(sysdumpconfig, "on");
        } else {
           writeConfig("off");
           strcpy(sysdumpconfig, "off");
        }
        ALOGD("set sysdumpconfig = %s",sysdumpconfig);
    } else {
        ALOGE(" Unable to open %s : %s\n", SPRD_SYSDUMP_CONFIG, strerror(errno));
        return -1;
    }
  }
  if(strstr(sysdumpconfig,"on")) {
    if(writeFile(SPRD_SYSDUMP_CONFIG, "on") == -1) {
       property_set("persist.sys.sysdump", "-1");
    } else {
       property_set("persist.sys.sysdump", "on");
       ALOGD("Initial sysdump on");
    }
  } else if(strstr(sysdumpconfig,"off")){
    if(writeFile(SPRD_SYSDUMP_CONFIG, "off") == -1) {
       property_set("persist.sys.sysdump", "-1");
    } else {
       property_set("persist.sys.sysdump", "off");
       ALOGD("Initial sysdump off");
    }
  }


猜你喜欢

转载自blog.csdn.net/qq_16919359/article/details/106136202