Android15借助Linux proc虚拟文件系统调试用户态实现

背景介绍

下面介绍一种Android系统调试方法,借助Linux proc虚拟文件系统将Android用户态的调试数据放到内核态进行显示,用于logcat不可用情况下调试Android系统。

主要是介绍Linux Kernel中如何实现这样一个/proc/debugprof节点供用户态访问。

环境描述:

  • ARM CotexA 64bit
  • Android15 Linux 6.6

具体实现

Android15 Linux Kernel(非GKI)Driver中实现一个proc节点,包括三个内容:

  1. debugprof模块驱动源码
  2. debugprof模块构建脚本
  3. debugprof模块设备树配置

debugprof目录结构大概是这个样子:

bash 复制代码
drivers/Xxx/Xxx_debug/
├── debugprof.c
├── Kconfig
└── Makefile

Linux Kernel实现debugprof

debugprof模块实现源码

cpp 复制代码
//drivers/xx/debugprof.c
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2026 Xxx Inc.
 */

#include <linux/proc_fs.h>
#include <linux/sched/clock.h>
#include <linux/seq_file.h>
#include <linux/kallsyms.h>
#include <linux/utsname.h>
#include <asm/uaccess.h>
#include <linux/syscore_ops.h>
#include <linux/io.h>
#include <linux/workqueue.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/tracepoint.h>
#include <trace/events/initcall.h>
#include <linux/delay.h>
#include <linux/soc/xx/boot_param.h>
#include <linux/console.h>

#define SEQ_printf(m, x...)	    \
do {			    \
	if (m)		    \
		seq_printf(m, x);	\
	else		    \
		printk(x);	    \
} while (0)

//注意:这个是debugprof数据缓存大小,不能分配太大
#define DEBUG_BUF_SIZE (512)

typedef struct dg_debugprof {
    int data_size;
    char debug_buf[DEBUG_BUF_SIZE];  //用于存用户态传过来的数据
} dg_debugprof;

dg_debugprof dg_debug_stat;

static int dg_debugprof_show(struct seq_file *m, void *v)
{
	SEQ_printf(m, "----------------------------------------\n");
	SEQ_printf(m, "debug : %s\n", dg_debug_stat.debug_buf);
	SEQ_printf(m, "----------------------------------------\n");

	return 0;
}

static int dg_debug_open(struct inode *inode, struct file *file)
{
	return single_open(file, dg_debugprof_show, inode->i_private);
}

static ssize_t dg_debug_write(struct file *filp, const char __user *ubuf,
           size_t cnt, loff_t *data)
{
    char buf[DEBUG_BUF_SIZE];
    size_t copy_size = cnt;

    if (cnt >= sizeof(buf))
        copy_size = DEBUG_BUF_SIZE - 1;

    if (copy_from_user(&buf, ubuf, copy_size))
        return -EFAULT;

    buf[copy_size] = 0;
    strcpy((char *)&dg_debug_stat.debug_buf, buf);
	return cnt;
}

static const struct proc_ops dg_debug_fops = {
	.proc_open = dg_debug_open,
	.proc_write = dg_debug_write,  //重点实现这个接口,Android程序走这个接口将数据传过来
	.proc_read = seq_read,
	.proc_lseek = seq_lseek,
	.proc_release = single_release,
};

static int debugprof_probe(struct platform_device *pdev)
{
    struct proc_dir_entry *pe;

    //创建proc debugprof节点,dg_debug_fops是接口函数
	pe = proc_create("debugprof", 0664, NULL, &dg_debug_fops);
    if (!pe) {
        pr_err("debugprof_probe fail.");
        return -ENOMEM;
    }
    pr_info("debugprof_probe success.");
	return 0;
}

static int debugprof_remove(struct platform_device *pdev)
{
	return 0;
}

static const struct dev_pm_ops debugprof_pm_ops = {
};

static const struct of_device_id debugprof_match[] = {
	{.compatible = "Xxx,debugprof",},
	{},
};

static struct platform_driver debugprof_drv = {
	.driver = {
		.owner = THIS_MODULE,
		.name  = "debugprof",
		.of_match_table = debugprof_match,
		.pm = &debugprof_pm_ops,
	},

	.probe = debugprof_probe,
	.remove = debugprof_remove,
};

static int __init debugprof_init(void)
{
	return platform_driver_register(&debugprof_drv);
}

static void __exit debugprof_exit(void)
{
	platform_driver_unregister(&debugprof_drv);
}

core_initcall(debugprof_init);
module_exit(debugprof_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Xxx Boot Chart driver");
MODULE_AUTHOR("yuxi@Xxx.com");

debugprof模块构建

cpp 复制代码
//drivers/Xxx/Kconfig
source "drivers/Xxx/Xxx_debug/Kconfig"

//drivers/Xxx/Xxx_debug/Kconfig
config Xxx_DEBUGPROF
    tristate "Xxx debug info"
    default n
    help
        This option help you to debug

//arch/arm64/configs/Xxx.fragment
CONFIG_Xxx_DEBUGPROF=y
bash 复制代码
//drviers/Xxx/Makefile
obj-y += Xxx_debug/

debugprof模块dts

cpp 复制代码
//arch/arm64/boot/dts/Xxx/Xxx_platform.dts
{
    ...
    debugprof: debugprof {
        compatible = "Xxx,debugprof";
        status = "okay";
    };
    ...
}

Android15中访问/proc/debugprof

cpp 复制代码
//frameworks/base/tools/aapt2/cmd/Link_test.cpp
TEST_F(LinkTest, NoCompressAssets) {
    ...
    if (auto result = 
        WriteFile("/proc/debugprof", "^-^##;/odm/etc/init;/product/etc/init");
        !result.ok()) {
        //write fail
    }
}

实现效果

相关推荐
千里马学框架3 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台3 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone3 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc3 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo3 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077003 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼3 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone3 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen3 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone3 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui