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命令了