我要实现我的自定义模块,其中使用print_cpu_info()
打印CPU的信息。 为了调用print_cpu_info(),我已经包含了所需的头文件,但是不起作用。 这是我的模块。
#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <asm/alternative.h> #include <asm/bugs.h> #include <asm/processor.h> #include <asm/mtrr.h> #include <asm/cacheflush.h> extern struct cpuinfo_x86 boot_cpu_data; int cpuinfox86_init(void) { print_cpu_info(&boot_cpu_data); return 0; } void cpuinfox86_exit(void) { printk("good bye cpu\n"); } module_init(cpuinfox86_init); module_exit(cpuinfox86_exit); MODULE_LICENSE("GPL");
编译完这个模块之后,我得到了
make -C /lib/modules/3.2.28-2009720166/build SUBDIRS=/home/tracking/1031_oslab modules make[1]: Entering directory `/usr/src/linux-3.2.28' CC [M] /home/tracking/1031_oslab/module.o Building modules, stage 2. MODPOST 1 modules WARNING: "print_cpu_info" [/home/tracking/1031_oslab/module.ko] undefined! CC /home/tracking/1031_oslab/module.mod.o LD [M] /home/tracking/1031_oslab/module.ko make[1]: Leaving directory `/usr/src/linux-3.2.28'
任何想法?
“print_cpu_info”不是导出的符号,所以它不能被模块使用。 但是,可以使用导出的“kallsyms_lookup_name”来获取“print_cpu_info”的地址,并使用函数指针执行函数调用。
static void* find_sym( const char *sym ) { // find address kernel symbol sym static unsigned long faddr = 0; // static !!! // ----------- nested functions are a GCC extension --------- int symb_fn( void* data, const char* sym, struct module* mod, unsigned long addr ) { if( 0 == strcmp( (char*)data, sym ) ) { faddr = addr; return 1; } else return 0; }; // -------------------------------------------------------- kallsyms_on_each_symbol( symb_fn, (void*)sym ); return (void*)faddr; } static void (*cpuInfo)(struct cpuinfo_x86 *);
如何使用它:
unsigned int cpu = 0; struct cpuinfo_x86 *c; cpuInfo = find_sym("print_cpu_info"); for_each_online_cpu(cpu) { c = &cpu_data(cpu); cpuInfo(c); }