android在sys目录下创建文件节点

本文介绍了一个在 Linux 内核中使用 sysfs 创建和管理文件节点的具体示例。通过 kobject_create_and_add 和 sysfs_create_group 函数,可以在 /sys 下创建目录及文件,并实现读写操作。

在网上找到一篇,专门用来创建节点的,还是比较清晰。但一般的内核中创建节点都是挂载在dts配置的设备节点中。

感谢作者大大:http://www.cnblogs.com/pengdonglin137/p/6217419.html

[root@tiny4412 mnt]# ls -R /sys/sysfs_demo/
/sys/sysfs_demo/:
node_one node_two sysfs_demo_2

/sys/sysfs_demo/sysfs_demo_2:
node_four node_three

这里用到的两个函数分别是: kobject_create_and_add 和 sysfs_create_group。前一个函数用于在/sys下面创建目录, 后一个函数用于创建文件。

示例驱动:

#define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kobject.h>
#include <linux/device.h>

static struct kobject *k_obj = NULL;
static struct kobject *k_obj_2 = NULL;

static char node_one_buf[20] = {0};

static ssize_t sysfs_demo_show_node_one(struct kobject *kobj, struct kobj_attribute *attr, char * buf)
{
    pr_info("enter, node: %s\n", attr->attr.name);
    return sprintf(buf, "%s: %s\n", attr->attr.name, node_one_buf);
}

static ssize_t sysfs_demo_store_node_one(struct kobject *kobj, struct kobj_attribute *attr, const char * buf, size_t n)
{
    pr_info("enter, node: %s\n", attr->attr.name);

    sprintf(node_one_buf, "%s", buf);

    return n;
}

static struct kobj_attribute node_one_attribute =
    __ATTR(node_one, S_IWUSR|S_IRUGO, sysfs_demo_show_node_one, sysfs_demo_store_node_one);

static ssize_t sysfs_demo_show_node_two(struct kobject *kobj, struct kobj_attribute *attr, char * buf)
{

    return sprintf(buf, "%s\n", attr->attr.name);
}

static struct kobj_attribute node_two_attribute =
    __ATTR(node_two, S_IWUSR|S_IRUGO, sysfs_demo_show_node_two, NULL);

static struct attribute *sysfs_demo_attributes[] = {
    &node_one_attribute.attr,
    &node_two_attribute.attr,
    NULL
};

static const struct attribute_group sysfs_demo_attr_group = {
    .attrs = sysfs_demo_attributes,
};

static char node_three_buf[20] = {0};

static ssize_t sysfs_demo_show_node_three(struct kobject *kobj, struct kobj_attribute *attr, char * buf)
{
    pr_info("enter, node: %s\n", attr->attr.name);
    return sprintf(buf, "%s: %s\n", attr->attr.name, node_three_buf);
}

static ssize_t sysfs_demo_store_node_three(struct kobject *kobj, struct kobj_attribute *attr, const char * buf, size_t n)
{
    pr_info("enter, node: %s\n", attr->attr.name);

    sprintf(node_three_buf, "%s", buf);

    return n;
}

static struct kobj_attribute node_three_attribute =
    __ATTR(node_three, S_IWUSR|S_IRUGO, sysfs_demo_show_node_three, sysfs_demo_store_node_three);

static ssize_t sysfs_demo_show_node_four(struct kobject *kobj, struct kobj_attribute *attr, char * buf)
{

    return sprintf(buf, "%s\n", attr->attr.name);
}

static struct kobj_attribute node_four_attribute =
    __ATTR(node_four, S_IWUSR|S_IRUGO, sysfs_demo_show_node_four, NULL);

static struct attribute *sysfs_demo2_attributes[] = {
    &node_three_attribute.attr,
    &node_four_attribute.attr,
    NULL
};

static const struct attribute_group sysfs_demo2_attr_group = {
    .attrs = sysfs_demo2_attributes,
};

static int __init sysfs_demo_init(void)
{
    if ((k_obj = kobject_create_and_add("sysfs_demo", NULL)) == NULL ) {
        pr_err("sysfs_demo sys node create error \n");
        goto out;
    }

    if(sysfs_create_group(k_obj, &sysfs_demo_attr_group) ) {
        pr_err("sysfs_create_group failed\n");
        goto out2;
    }

    if ((k_obj_2 = kobject_create_and_add("sysfs_demo_2", k_obj)) == NULL ) {
        pr_err("hwinfo sys node create error \n");
        goto out3;
    }

    if(sysfs_create_group(k_obj_2, &sysfs_demo2_attr_group) ) {
        pr_err("sysfs_create_group failed\n");
        goto out4;
    }

    pr_info("enter.\n");
    return 0;
out4:
    kobject_put(k_obj_2);
out3:
    sysfs_remove_group(k_obj, &sysfs_demo_attr_group);
out2:
    kobject_put(k_obj);
out:
    return -1;
}
module_init(sysfs_demo_init);

static void __exit sysfs_demo_exit(void)
{
    pr_info("enter.\n");

    if (k_obj) {
        sysfs_remove_group(k_obj, &sysfs_demo_attr_group);
        if (k_obj_2) {
            sysfs_remove_group(k_obj_2, &sysfs_demo2_attr_group);
            kobject_put(k_obj_2);
        }
        kobject_put(k_obj);
    }

}
module_exit(sysfs_demo_exit);

MODULE_LICENSE("GPL");

 

转载于:https://www.cnblogs.com/feifeiyuan/p/8206559.html

### 持久化保存 Android 系统文件创建文件Android 系统中,如果在 `/data` 或 `/tmp` 等临时文件系统路径中创建文件在设备重启后被删除,通常是因为这些路径位于内存文件系统(如 tmpfs)上,而非持久化存储介质中[^1]。要实现文件在重启后仍能保留,需要将文件写入持久化存储路径,并确保文件系统挂载方式允许持久化写入。 #### 1. 使用持久化存储路径 Android 系统提供了多个可用于持久化存储的目录,例如: - **应用私有目录**:`/data/data/<package-name>/files/`,该目录在应用卸载时才会被删除。 - **内部存储根目录**:`/data/media/` 或 `/storage/emulated/0/`,适用于需要跨应用访问的文件。 - **系统级持久目录**:如 `/system/etc/`、`/vendor/etc/`,适用于系统配置文件,但需 root 权限。 应避免在以下路径中写入需持久化的文件: - `/tmp/`:通常为 tmpfs 文件系统,重启后内容丢失。 - `/dev/`:设备节点目录,不用于持久化数据。 - `/proc/` 和 `/sys/`:虚拟文件系统,仅用于运行时信息。 #### 2. 使用文件写入方法实现持久化 在 Android 应用中,可以通过 `Context.MODE_PRIVATE` 模式将文件写入应用私有目录,例如: ```java try { FileOutputStream fos = openFileOutput("example.txt", Context.MODE_PRIVATE); fos.write("Persistent data".getBytes()); fos.close(); } catch (IOException e) { e.printStackTrace(); } ``` 该方式写入的文件位于 `/data/data/<package-name>/files/` 目录下,重启后不会丢失。 #### 3. 使用 SharedPreferences 持久化简单数据 对于键值对形式的轻量级数据,可以使用 `SharedPreferences`: ```java SharedPreferences sharedPref = getSharedPreferences("my_prefs", Context.MODE_PRIVATE); SharedPreferences.Editor editor = sharedPref.edit(); editor.putString("user_input", "Hello World"); editor.apply(); ``` 此方式将数据写入 `/data/data/<package-name>/shared_prefs/` 目录下的 XML 文件中,重启后仍保留。 #### 4. 系统级持久化写入 若为系统级开发,需确保文件写入 `/system` 或 `/vendor` 等分区时,分区已挂载为可写。例如: ```bash mount -o remount,rw /system echo "persistent data" > /system/etc/my_config.txt mount -o remount,ro /system ``` 此外,若使用 A/B 分区设备,需注意写入 `/data` 分区中的持久化文件可能不会在重启后保留,除非明确配置为保留数据分区。 #### 5. 避免 tmpfs 文件系统写入 某些 Android 设备将 `/tmp` 或 `/data/local/tmp` 挂载为 tmpfs,因此写入其中的文件仅在内存中存在,重启后会被清除。应避免将持久化文件写入这些路径。 #### 6. 确保文件系统挂载方式正确 检查 `/proc/mounts` 或 `/etc/fstab` 文件,确保目标目录挂载为持久化文件系统(如 ext4、f2fs)而非 tmpfs。例如: ```bash cat /proc/mounts | grep /data ``` 若 `/data` 挂载为 tmpfs,则需修改 fstab 文件,将其配置为挂载为持久化文件系统。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值