Skip to content
Advertisement

How do we compile kernel code in C?

I am new to C and Linux. I am trying to compile the below code but it gives some fatal error while compiling. Any help on fixing this appreciated.

Here is the code measurecpu.c:

#include <linux/module.h>      
#include <linux/kernel.h>      
#include <linux/init.h>         
#include <linux/hardirq.h>
#include <linux/preempt.h>
#include <linux/sched.h>
#include<stdio.h>

int main() {

uint64_t start, end;
int i=0;
asm volatile ("CPUID  n  t" "RDTSC  n  t" "mov %%edx, %0  n  t" "mov %%eax, %1  n  t": "=r" (cycles_high), "=r" (cycles_low)::  "%rax", "%rbx", "%rcx", "%rdx");

for(i=0; i<200000;i++) {}

asm volatile ("RDTSCP  n  t" "mov %%edx, %0  n  t" "mov %%eax, %1  n  t" "CPUID  n  t": "=r" (cycles_high1), "=r" (cycles_low1)::  "%rax", "%rbx", "%rcx", "%rdx");


start = ( ((uint64_t)cycles_high << 32) | cycles_low );
 end = ( ((uint64_t)cycles_high1 << 32) | cycles_low1 );
printk(KERN_INFO "  n function execution time is %llu clock cycles",(end - start));

}

I am trying to compile it this way:

gcc -c -O2 -W -Wall -isystem /lib/modules/'uname -r'/build/include -D_KERNEL_ -DMODULE measurecpu.c

I get this error:

measurecpu.c:1:32: fatal error: linux/module.h: No such file or directory
 #include <linux/module.h>      
                                ^
compilation terminated.

Advertisement

Answer

I am trying to compile it this way gcc -c -O2 -W -Wall -isystem /lib/modules/’uname -r’/build/include -D_KERNEL_ -DMODULE measurecpu.c

Usually the way to compile a kernel module is to use the kernel build system – ie you use make instead of gcc directly. You need to create a Makefile and specify the object, which is the line obj-m := measurecpu.o in your case. After that in the same directory, issue the make command, which will yield the kernel object file measurecpu.ko

# If KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq ($(KERNELRELEASE),)
    obj-m := measurecpu.o

# Otherwise we were called directly from the command
# line; invoke the kernel build system.
else
    KERNELDIR ?= /lib/modules/$(shell uname -r)/build
    PWD := $(shell pwd)

default:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

clean:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules clean

endif

Note that kernel module is not user space program, so you cannot just run it. You will need to tell the kernel about that kernel module via insmod, and check the results via dmesg.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement