【问题标题】:Unknown symbol in module / v7_flush_dcache_all undefined in linux kernel module模块中的未知符号/Linux内核模块中未定义的v7_flush_dcache_all
【发布时间】:2017-03-31 03:15:32
【问题描述】:

我正在尝试创建一个禁用数据缓存的 linux 内核模块。我正在尝试使用arch/arm/include/asm/cacheflush.h中的v7_exit_coherency_flush(all)函数,这个函数调用v7_flush_dcache_all,我发现它在arch/arm/mm/arch-v7.S中。

我的问题是,当我尝试制作我的模块时,我收到了警告

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

另外,如果有人知道禁用缓存的更简单方法,我会全力以赴!

【问题讨论】:

  • 看起来宏 v7_exit_coherency_flush 不适合被模块调用。只有编译到其中的内核和驱动程序可以使用该宏。请注意,为了可从模块函数调用,需要导出 (EXPORT_SYMBOL)。至于包含,.S 文件不打算包含在内。相反,您可以复制它并与您的模块一起编译。
  • 它是一个内部函数,通常只能通过proc机制调用。特定的 ARM 版本将与特定的 ARM CPU 类型相关联。 Linux 驱动程序/模块旨在在所有硬件上运行。

标签: linux linux-kernel arm kernel kernel-module


【解决方案1】:

v7_exit_coherency_flush() 用于电源管理代码,以便将 CPU 从内核中干净地取出以将其关闭 - 出于很好的理由,它不能从随机模块调用。如果您真的想以奇怪而微妙的方式丢失数据并使机器崩溃,您不妨完全绕过内核函数并使用简单的内联汇编直接命中 SCTLR*

我不敢想象你想要实现什么,但如果你真的想在缓存关闭的情况下运行 Linux(非常缓慢),你需要重建内核,关闭 CONFIG_SMP 以打开 CONFIG_CPU_DCACHE_DISABLE .这是唯一可能有效的模糊支持的方法。

* 我什至不打算解释,这是一个可怕的想法。

【讨论】:

    猜你喜欢
    • 2012-08-06
    • 1970-01-01
    • 1970-01-01
    • 2018-12-09
    • 1970-01-01
    • 1970-01-01
    • 2021-06-13
    • 1970-01-01
    • 2020-09-30
    相关资源
    最近更新 更多