当前位置: 首页 > article >正文

devmem命令之自定义/dev/mem

环境

rk3576_u:/data/local/tmp # cat /proc/version
Linux version 6.1.78-android14-11-gcb6c9fcea75d-ab12054834 (build-user@build-host) (Android (10087095, +pgo, +bolt, +lto, -mlgo, based on r487747c) clang version 17.0.2 (https://android.googlesource.com/toolchain/llvm-project d9f89f4d16663d5012e5c09495f3b30ece3d2362), LLD 17.0.2) #1 SMP PREEMPT Fri Jul  5 00:54:02 UTC 2024

mymem.c

$ cat mymem.c
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/io.h>
#include <linux/uaccess.h>
#include <linux/mm.h>


#define TAG "HELLO# "

#define COUNT 1
static dev_t my_devt;
static struct class *my_class;
static struct cdev *my_cdev;
struct device *my_device[COUNT];

static int my_cdev_open(struct inode *inode, struct file *file)
{
        printk(TAG "%s called\n", __func__);
        return 0;
}
static int my_cdev_release(struct inode *inode, struct file *file)
{
        printk(TAG "%s called\n", __func__);
        return 0;
}

static int my_cdev_mmap(struct file *file, struct vm_area_struct *vma)
{
        unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
        unsigned long size = vma->vm_end - vma->vm_start;

        printk(TAG "%s called\n", __func__);

        printk(KERN_INFO "My Mem: Mapped physical address 0x%lx with size 0x%lx\n", offset, size);

        vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);

        if (io_remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT, size, vma->vm_page_prot)) {
                printk(KERN_ERR "My Mem: Failed to remap I/O memory\n");
                return -EAGAIN;
        }

        return 0;
}

static const struct file_operations my_cdev_fops = {
        .owner          = THIS_MODULE,
        .open           = my_cdev_open,
        .release        = my_cdev_release,
        .mmap           = my_cdev_mmap,
};

static int my_char_dev_init(void)
{
        int err;
        int i;
        printk(TAG "%s called\n", __func__);

        /* create /sys/class/my_class */
        my_class = class_create(THIS_MODULE, "my_class");
        my_cdev = cdev_alloc();

        cdev_init(my_cdev, &my_cdev_fops);

        err = alloc_chrdev_region(&my_devt, 0, COUNT, "dont'care");
        err = cdev_add(my_cdev, my_devt, COUNT);

        /* create /sys/dev/char/major:minor */
        for(i = 0; i < COUNT; i++)
        {
                my_device[i] = device_create(my_class, NULL, my_devt + i, NULL, "mem");
        }

        return err;
}
static void my_char_dev_exit(void)
{
        int i;
        printk(TAG "%s called\n", __func__);

        for(i = 0; i < COUNT; i++)
        {
                device_destroy(my_class, my_devt + i);
        }

        unregister_chrdev_region(my_devt, COUNT);
        cdev_del(my_cdev);
        class_destroy(my_class);
}

module_init(my_char_dev_init);
module_exit(my_char_dev_exit);
MODULE_LICENSE("GPL");

 

Makefile 

$ cat Makefile
obj-m := mymem.o
modules:
        $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
clean:
        rm -f *.o *.ko *.mod *.mod.c *.order *.symvers
 

export KERNEL_DIR=/home/xxxxx/projects/yyyyy/code/android/kernel-6.1
make CROSS_COMPILE=aarch64-linux-gnu- LLVM=1 LLVM_IAS=1 ARCH=arm64
 

最后就可以使用devmem or io命令了

 

 

 


http://www.kler.cn/a/537911.html

相关文章:

  • 软件工程的熵减:AI如何降低系统复杂度
  • 网络安全:挑战、技术与未来发展
  • 2025年02月08日Github流行趋势
  • 宝诗龙(Boucheron):于芳登广场 26 号(26 Place Vendôme)的百年珠宝传奇(中英双语)
  • LVGL4种输入设备详解(触摸、键盘、实体按键、编码器)
  • C++ Primer 递增和递减运算符
  • sip协议如何与isdn协议进行通信
  • 【LeetCode Hot100 动态规划】
  • MySQL第五次作业
  • 【Linux】29.Linux 多线程(3)
  • RUST项目编译
  • Java 大视界 -- Java 大数据在智能金融监管中的应用与实践(77)
  • 基于FreeSurfer 7.1、6.0和5.3版本的脑部指标在多站点重测信度和兼容性研究
  • 黑马 Linux零基础快速入门到精通 笔记
  • stm32-wifi模块
  • ARM嵌入式学习--第十四天(SPI)
  • 自然语言处理NLP_[1]-NLP入门
  • flask实现用户名查重,重复的用户名阻止注册,以及如何优化
  • 单调栈题目
  • 如何让虚拟机联上网
  • windows通过网络向Ubuntu发送文件/目录
  • 在大型语言模型(LLM)框架内Transformer架构与混合专家(MoE)策略的概念整合
  • 算法基础——容错
  • 蛋糕商城 Rust 版介绍二
  • 网络安全 | 保护智能家居和企业IoT设备的安全策略
  • 【AI】通过修改用户环境变量优化Ollama模型加载与访问