2016-11-16 184 views
0

我试图创建一个将禁用数据缓存的Linux内核模块。我正在尝试使用arch/arm/include/asm/cacheflush.h中的v7_exit_coherency_flush(all)函数,并且此函数调用了我在arch/arm/mm/arch-v7.S中找到的v7_flush_dcache_all。模块中的未知符号/ v7_flush_dcache_all在Linux内核模块中未定义

我的问题是,当我试图让自己的模块,我得到一个警告

WARNING: "v7_flush_dcache_all [/home/pi/Documents/ARMHammer/kern/my_kernel/cache_disable.ko] undefined! 

,当我尝试插入模块我得到一个错误

insmod: ERROR: could not insert module cache_disable.ko: Unknown symbol in module 

所以它看起来像ach-v7.S文件没有被读取。我试图简单地将它包含在我的主文件中,但是这产生了很多错误,可能是因为它是一个汇编文件。

我几乎坚持在这一点上,有没有办法将汇编文件包含在Makefile中,或者我没有包含所有必需的.h文件?

为了什么它的价值,这是我的主文件

#include <linux/kernel.h> 
#include <linux/module.h> 
#include <linux/init.h> 
#include <linux/sched.h> /* For current */ 
#include <linux/tty.h>  /* For the tty declarations */ 
#include <linux/version.h> /* For LINUX_VERSION_CODE */ 
#include <linux/mm.h> 

#include <asm/cp15.h> 
#include <asm/cacheflush.h> 
#include <asm/glue-cache.h> 
#include <asm/shmparam.h> 
#include <asm/cachetype.h> 
#include <asm/outercache.h> 

// #include "my_cache-v7.h" 


MODULE_LICENSE("GPL"); 
MODULE_AUTHOR("Peter Jay Salzman"); 


static void print_string(char *str) 
{ 
    struct tty_struct *my_tty; 
    #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,5)) 
     my_tty = current->tty; 
    #else 
     my_tty = current->signal->tty; 
    #endif 

     if (my_tty != NULL) { 
      ((my_tty->ops)->write) (my_tty, /* The tty itself */ 
    #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,9))  
          0, /* Don't take the string 
           from user space  */ 
    #endif 
          str, /* String     */ 
          strlen(str)); /* Length */ 
    #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,9))  
      ((my_tty->ops)->write) (my_tty, 0, "\015\012", 2); 
    #else 
      ((my_tty->ops)->write) (my_tty, "\015\012", 2); 
    #endif 
    } 
} 

static int __init print_string_init(void) 
{ 
    v7_exit_coherency_flush(all); 

    print_string("The module has been inserted. Hello world!"); 
    return 0; 
} 

static void __exit print_string_exit(void) 
{ 
    print_string("The module has been removed. Farewell world!"); 
} 

module_init(print_string_init); 
module_exit(print_string_exit); 

和我的Makefile

obj-m += cache_disable.o 
KDIR = /home/pi/linux/ 
all: 
    make -C $(KDIR) M=$(PWD) modules 

clean: 
    make -C $(KDIR) M=$(PWD) clean 

而且,如果有人知道更简单的方法来禁用缓存,我所有的耳朵!

+0

看起来像'v7_exit_coherency_flush'宏不适合被模块调用。只有编译进它的内核和驱动程序可以使用该宏。请注意,可以从模块函数调用需要导出('EXPORT_SYMBOL')。至于包含,'.S'文件不打算包含在内。相反,您可以复制它并与您的模块一起编译。 – Tsyvarev

+0

这是一个内部函数,通常只能通过[proc]调用(https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/arm/mm/proc- v7.S?id = refs/tags/v4.9-rc5#n542)机制。特定的ARM版本将绑定到特定的ARM CPU类型。 Linux驱动程序/模块是为了在所有硬件上运行。 –

回答

1

v7_exit_coherency_flush()用于电源管理代码,将CPU从内核中彻底清除以关闭电源 - 由于非常好的原因,无法从随机模块调用CPU。如果你真的想丢失数据并以奇怪的方式使机器崩溃,那么你可能完全绕过内核函数,并使用一个简单的内联asm直接命中SCTLR *

我不敢想象你想达到什么目的,但是如果你真的想在缓存关闭的情况下运行Linux(痛苦缓慢),你需要重建内核,关闭CONFIG_SMP以打开CONFIG_CPU_DCACHE_DISABLE。这是唯一可能有效的方法。

*我甚至不会解释,这是一个可怕的想法。