Reading Files From The Linux Kernel Space (Module/Driver) (Fedora 14)

It seems like operations that communicate with userspace are really discouraged. And I am not arguing with that. Although it doesn't mean that they cannot be accomplished. A driver loads configuration that could be stored only on HDD. When MS Windows XP boots up it remembers that I have turned Bluetooth off so it is not powered on, unlike even the latest Linux (Fedora 14 at the moment of writing) – such functionality in many drivers was not implemented. When developer uses procfs or character devices there should be another software or script in boot sequence that is actually sending information from a file to particular device.

After some time looking over the internet I have managed to write such module that reads a file. And here it goes:

#include <linux/module.h>  // Needed by all modules
#include <linux/kernel.h>  // Needed for KERN_INFO
#include <linux/fs.h>      // Needed by filp
#include <asm/uaccess.h>   // Needed by segment descriptors

int init_module(void)
{
    // Create variables
    struct file *f;
    char buf[128];
    mm_segment_t fs;
    int i;
    // Init the buffer with 0
    for(i=0;i<128;i++)
        buf[i] = 0;
    // To see in /var/log/messages that the module is operating
    printk(KERN_INFO "My module is loaded\n");
    // I am using Fedora and for the test I have chosen following file
    // Obviously it is much smaller than the 128 bytes, but hell with it =)
    f = filp_open("/etc/fedora-release", O_RDONLY, 0);
    if(f == NULL)
        printk(KERN_ALERT "filp_open error!!.\n");
    else{
        // Get current segment descriptor
        fs = get_fs();
        // Set segment descriptor associated to kernel space
        set_fs(get_ds());
        // Read the file
        f->f_op->read(f, buf, 128, &f->f_pos);
        // Restore segment descriptor
        set_fs(fs);
        // See what we read from file
        printk(KERN_INFO "buf:%s\n",buf);
    }
    filp_close(f,NULL);
    return 0;
}

void cleanup_module(void)
{
    printk(KERN_INFO "My module is unloaded\n");
}

That is all that is needed to read the /etc/fedora-release file. Just in case, the following needs to be in Makefile if the source is saved as module.c:

obj-m += module.o



all:

    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:

    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

Issuing following:

$ make

$ su

# insmod module.ko

Then in the end of /var/log/messages I see following:

Dec 11 13:06:11 thinkpad kernel: [ 2410.431974] My module is loaded

Dec 11 13:06:11 thinkpad kernel: [ 2410.431993] buf:Fedora release 14 (Laughlin)

Dec 11 13:06:11 thinkpad kernel: [ 2410.431995]

The additional new line could be just from the file. But hey, that is exactly what is in that file!!!

It does looks like write functions are also there so if anyone feels like writing something from kernel space to a file – functionality is about there.

Share this page:

Suggested articles

8 Comment(s)

Add comment

Comments

By: Lawrence D'Oliveiro

The kernel should be small and support a basic core of general functionality, not be large and weighed down with features.

 A corollary of this is that the kernel should not implement policy, but only mechanisms to allow userland to implement policy.

An example of mechanism is userland being able to enable or disable the kernel Bluetooth driver. An example of policy is that the state at shutdown should be saved and restored on boot.

By: veena hosur

hi...i want to read file in kernel mode.i am using f->f_op->read (above code)to read the file.but its reading till size of buffer but i want to read till end of file.please tell me to read till end of file

By: Marvin

thanks , it worked perfectly to me.

By: eyal yehuda

there is an issue with checking

f = filp_open("/etc/fedora-release", O_RDONLY, 0); if(f == NULL)it is totaly incorrect it should be replaces with f = filp_open("/etc/fedora-release", O_RDONLY, 0); if (IS_ERR(f)) continue; Thanks Eyal Yehuda

By: Mike Ruano

Thank you so much... it worked..

By: sasna

I tried the same on fedora 24.But i am getting an error ./arch/x86/include/asm/uaccess.h:error:dereferencing pointer to type 'struct task-struct' .Where will have gone wrong? Could someone please help me out

By: sasna

THe erropr was fixed by changing the header file to <linux/uaccess.h> but when i tried to insmod, it displays "killed" what i sthe reason for that?

By: dikra

dont work