/dev/mem
是什么?
- 内核源码实现
- hack
Part.1
$ file /dev/mem
/dev/mem: character special (1/1)
➜ ~ man 4 mem
mem, kmem, port - system memory, kernel memory and system ports
/dev/mem is a character device file that is an image of the main memory
of the computer.
It may be used, for example, to examine (and even patch) the system.
Examining and patching is likely to lead to unexpected results
when read-only or write-only bits are present.
Since Linux 2.6.26, and depending on the architecture,
the CONFIG_STRICT_DEVMEM kernel configuration option limits the areas
which can be accessed through this file.
For example: on x86, RAM access is not allowed but accessing
memory-mapped PCI regions is.
/dev/mem
是一个字符设备
- 可以通过这个文件读写 main memory of the computer
- 读写权限受到目标内存页面 read,write-only bits 的影响
- 从 2.6.26 开始增加了
CONFIG_STRICT_DEVMEM
配置,默认只允许访问非常有限的区域
// drivers/char/mem.c
881 static const struct memdev {
...
882 const char *name;
883 umode_t mode;
884 const struct file_operations *fops;
885 fmode_t fmode;
886 } devlist[] = {
887 #ifdef CONFIG_DEVMEM
888 [1] = { "mem", 0, &**mem_fops**, FMODE_UNSIGNED_OFFSET },
889 #endif
890 #ifdef CONFIG_DEVKMEM
891 [2] = { "kmem", 0, &kmem_fops, FMODE_UNSIGNED_OFFSET },
892 #endif
...
}
823 static const struct file_operations __maybe_unused mem_fops = {
**824 .llseek = memory_lseek,
825 .read = read_mem,
826 .write = write_mem,**
827 .mmap = mmap_mem,
828 .open = open_mem,
829 #ifndef CONFIG_MMU
830 .get_unmapped_area = get_unmapped_area_mem,
831 .mmap_capabilities = memory_mmap_capabilities,
832 #endif
833 };
// drivers/char/mem.c
read_mem
page_is_allowed
devmem_is_allowed
xlate_dev_mem_ptr
memremap
copy_to_user
read_mem
先检查目标地址是否合法
- 然后通过
memremap
获取物理地址的虚拟地址
- 最后通过
copy_to_user
读取目标物理地址的内容