virt_to_phys only works for kmalloc

This commit is contained in:
Ciro Santilli
2017-07-16 12:49:09 +01:00
parent 2eca9280e1
commit 0677dbd4b5
3 changed files with 32 additions and 15 deletions

View File

@@ -54,7 +54,11 @@ BR2_PACKAGE_HOST_DTC=y
# #
# xp/4 0x101e9000 # 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://superuser.com/questions/71389/what-is-dev-mem/1214662#1214662
# - https://unix.stackexchange.com/questions/4948/shell-command-to-read-device-registers # - https://unix.stackexchange.com/questions/4948/shell-command-to-read-device-registers

View File

@@ -3,7 +3,7 @@ Also try on QEMU monitor:
xp 0x<vaddr> xp 0x<vaddr>
x86 docs say it only works for kmalloc. Only works for kmalloc.
static inline phys_addr_t virt_to_phys(volatile void *address) 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 <linux/seq_file.h> /* single_open, single_release */ #include <linux/seq_file.h> /* single_open, single_release */
#include <linux/slab.h> /* kmalloc, kfree */ #include <linux/slab.h> /* kmalloc, kfree */
static volatile u32 *i; static volatile u32 *k;
static volatile u32 i;
static struct dentry *debugfs_file; static struct dentry *debugfs_file;
static int show(struct seq_file *m, void *v) static int show(struct seq_file *m, void *v)
{ {
seq_printf(m, seq_printf(m,
"*i 0x%llx\n" "k 0x%llx\n"
"i %p\n" "addr_k %p\n"
"virt_to_phys 0x%llx\n", "virt_to_phys_k 0x%llx\n"
(unsigned long long)*i, "i 0x%llx\n"
i, "addr_i %p\n"
(unsigned long long)virt_to_phys((void *)i) "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; return 0;
} }
@@ -53,8 +60,9 @@ static const struct file_operations fops = {
static int myinit(void) static int myinit(void)
{ {
i = kmalloc(sizeof(i), GFP_KERNEL); k = kmalloc(sizeof(k), GFP_KERNEL);
*i = 0x12345678; *k = 0x12345678;
i = 0x12345678;
debugfs_file = debugfs_create_file( debugfs_file = debugfs_create_file(
"lkmc_virt_to_phys", S_IRUSR, NULL, NULL, &fops); "lkmc_virt_to_phys", S_IRUSR, NULL, NULL, &fops);
return 0; return 0;
@@ -63,7 +71,7 @@ static int myinit(void)
static void myexit(void) static void myexit(void)
{ {
debugfs_remove(debugfs_file); debugfs_remove(debugfs_file);
kfree((void *)i); kfree((void *)k);
} }
module_init(myinit) module_init(myinit)

View File

@@ -3,10 +3,15 @@ set -ex
insmod /virt_to_phys.ko insmod /virt_to_phys.ko
cd /sys/kernel/debug cd /sys/kernel/debug
cat lkmc_virt_to_phys cat lkmc_virt_to_phys
# *i = 0x12345678 # k = 0x12345678
addr=$(grep virt_to_phys lkmc_virt_to_phys | cut -d ' ' -f 2) # 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"
devmem2 "$addr" w 0x9ABCDEF0 devmem2 "$addr" w 0x9ABCDEF0
cat lkmc_virt_to_phys cat lkmc_virt_to_phys
# *i = 0x9ABCDEF0 # k = 0x9ABCDEF0
# i = 0x12345678
rmmod virt_to_phys rmmod virt_to_phys