2

I'm going to implement my custom module in which information for CPU is printed using print_cpu_info(). In order to call print_cpu_info(), I have included the needed header file, but it doesn't work. Here is my module.

#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");

After compiling this module, I get

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'

any idea?

inherithandle
  • 2,614
  • 4
  • 31
  • 53

2 Answers2

6

"print_cpu_info" is not exported symbol, so it can not be used by modules. However, you can use "kallsyms_lookup_name", which is exported, to get the address of "print_cpu_info" and execute the function call using a function pointer.

Gyan Gupta
  • 986
  • 8
  • 15
  • you said that calling `kallsyms_lookup_name("print_cpu_info")` give me the address of the function `print_cpu_info()`, Right? – inherithandle Oct 31 '13 at 03:24
0
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 *);

How to use it:

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);
    }
Access Denied
  • 8,723
  • 4
  • 42
  • 72