From 0677dbd4b582d1a913462d75caad0abf21e87f32 Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Sun, 16 Jul 2017 12:49:09 +0100 Subject: [PATCH] virt_to_phys only works for kmalloc --- buildroot_config_fragment | 6 +++++- kernel_module/virt_to_phys.c | 30 +++++++++++++++++++----------- rootfs_overlay/virt_to_phys.sh | 11 ++++++++--- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/buildroot_config_fragment b/buildroot_config_fragment index 7578b79..153164d 100644 --- a/buildroot_config_fragment +++ b/buildroot_config_fragment @@ -54,7 +54,11 @@ BR2_PACKAGE_HOST_DTC=y # # xp/4 0x101e9000 # -# Uses /dev/mem: +# Uses /dev/mem. +# +# Upstream: http://free-electrons.com/pub/mirror/devmem2.c +# +# See also: # # - https://superuser.com/questions/71389/what-is-dev-mem/1214662#1214662 # - https://unix.stackexchange.com/questions/4948/shell-command-to-read-device-registers diff --git a/kernel_module/virt_to_phys.c b/kernel_module/virt_to_phys.c index 5433827..2cd5438 100644 --- a/kernel_module/virt_to_phys.c +++ b/kernel_module/virt_to_phys.c @@ -3,7 +3,7 @@ Also try on QEMU monitor: xp 0x -x86 docs say it only works for kmalloc. +Only works for kmalloc. static inline phys_addr_t virt_to_phys(volatile void *address) @@ -21,19 +21,26 @@ static inline phys_addr_t virt_to_phys(volatile void *address) #include /* single_open, single_release */ #include /* kmalloc, kfree */ -static volatile u32 *i; +static volatile u32 *k; +static volatile u32 i; static struct dentry *debugfs_file; static int show(struct seq_file *m, void *v) { seq_printf(m, - "*i 0x%llx\n" - "i %p\n" - "virt_to_phys 0x%llx\n", - (unsigned long long)*i, - i, - (unsigned long long)virt_to_phys((void *)i) + "k 0x%llx\n" + "addr_k %p\n" + "virt_to_phys_k 0x%llx\n" + "i 0x%llx\n" + "addr_i %p\n" + "virt_to_phys_i 0x%llx\n", + (unsigned long long)*k, + k, + (unsigned long long)virt_to_phys((void *)k), + (unsigned long long)i, + &i, + (unsigned long long)virt_to_phys((void *)&i) ); return 0; } @@ -53,8 +60,9 @@ static const struct file_operations fops = { static int myinit(void) { - i = kmalloc(sizeof(i), GFP_KERNEL); - *i = 0x12345678; + k = kmalloc(sizeof(k), GFP_KERNEL); + *k = 0x12345678; + i = 0x12345678; debugfs_file = debugfs_create_file( "lkmc_virt_to_phys", S_IRUSR, NULL, NULL, &fops); return 0; @@ -63,7 +71,7 @@ static int myinit(void) static void myexit(void) { debugfs_remove(debugfs_file); - kfree((void *)i); + kfree((void *)k); } module_init(myinit) diff --git a/rootfs_overlay/virt_to_phys.sh b/rootfs_overlay/virt_to_phys.sh index b0ab00e..801df46 100755 --- a/rootfs_overlay/virt_to_phys.sh +++ b/rootfs_overlay/virt_to_phys.sh @@ -3,10 +3,15 @@ set -ex insmod /virt_to_phys.ko cd /sys/kernel/debug cat lkmc_virt_to_phys -# *i = 0x12345678 -addr=$(grep virt_to_phys lkmc_virt_to_phys | cut -d ' ' -f 2) +# k = 0x12345678 +# i = 0x12345678 +addr=$(awk '$1 == "virt_to_phys_k" { print $2 }' lkmc_virt_to_phys) +devmem2 "$addr" +devmem2 "$addr" w 0x9ABCDEF0 +addr=$(awk '$1 == "virt_to_phys_i" { print $2 }' lkmc_virt_to_phys) devmem2 "$addr" devmem2 "$addr" w 0x9ABCDEF0 cat lkmc_virt_to_phys -# *i = 0x9ABCDEF0 +# k = 0x9ABCDEF0 +# i = 0x12345678 rmmod virt_to_phys