Search code examples
linux-kernellinux-device-driverdevice-driverkernel-modulekernel

Regarding how the parameters to the read function is passed in simple char driver


I am newbei to driver programming i am started writing the simple char driver . Then i created special file for my char driver mknod /dev/simple-driver c 250 0 .when it type cat /dev/simple-driver. it shows the string "Hello world from Kernel mode!". i know that function

static const char    g_s_Hello_World_string[] = "Hello world tamil_vanan!\n\0";
    static const ssize_t g_s_Hello_World_size = sizeof(g_s_Hello_World_string);


    static ssize_t device_file_read(
                   struct file *file_ptr
                , char __user *user_buffer
                , size_t count
                , loff_t *possition)
    {
       printk( KERN_NOTICE "Simple-driver: Device file is read at offset = 
           %i, read bytes count = %u", (int)*possition  , (unsigned int)count );

       if( *possition >= g_s_Hello_World_size )
          return 0;

       if( *possition + count > g_s_Hello_World_size )
          count = g_s_Hello_World_size - *possition;

        if( copy_to_user(user_buffer, g_s_Hello_World_string + *possition,         count) != 0              )
          return -EFAULT;   

       *possition += count;
       return count;
    }

is get called . This is mapped to (*read) in file_opreation structure of my driver .My question is how this function is get called , how the parameters like struct file,char,count, offset are passed bcoz is i simply typed cat command ..Please elabroate how this happening


Solution

  • In Linux all are considered as files. The type of file, whether it is a driver file or normal file depends upon the mount point where it is mounted. For Eg: If we consider your case : cat /dev/simple-driver traverses back to the mount point of device files.

    • From the device file name simple-driver it retrieves Major and Minor number.

    • From those number(especially from minor number) it associates the driver file for your character driver.

    • From the driver it uses struct file ops structure to find the read function, which is nothing but your read function:

    static ssize_t device_file_read(struct file *file_ptr, char __user *user_buffer, size_t count, loff_t *possition)

    • User_buffer will always take sizeof(size_t count).It is better to keep a check of buffer(In some cases it throws warning)
    • String is copied to User_buffer(copy_to_user is used to check kernel flags during copy operation).
    • postion is 0 for first copy and it increments in the order of count:position+=count.

    Once read function returns the buffer to cat. and cat flushes the buffer contents on std_out which is nothing but your console.