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:

8 Comment(s)