• How to make a system call using device drivers aka Linux loadable modul

    From Shahin Ansari@21:1/5 to All on Tue Aug 18 11:34:20 2015
    I created a sample device driver, and validated its functionality. Now I like to issue a system command, and be able to the result, and I do not know exactly what function to call and how. What I mean by that is my understanding of how to implement a
    device driver is as follows:

    1- You create a module and add it to your build system

    2- You compile the module and flash your device ( In my case: SM-N900P )

    3- You write another program to run on the user space, which would call your module.

    4- You flash the phone to get the new module on the phone

    5- You move the user program executable to the phone also

    6- Use insmod to load the module

    7- use mknod to activate it I guess

    8- Then run the user program

    My question stems from not knowing what each part of the moduel does, and how to interface with it from the user program. If someone could give me a few lines of code to explain how to issue a system command that would be great. I believe what most of
    what I need goes in the user program, but I am not sure. The following is what I have in my test module:

    #include <linux/module.h>
    #include <linux/fs.h>

    static int debug_enable = 0;
    module_param(debug_enable, int, 0);
    MODULE_PARM_DESC(debug_enable, "Enable module debug mode.");
    struct file_operations hello_fops;

    static int hello_open(struct inode *inode, struct file *file)
    {
    .../* Do some stuff */
    printk("hello_open: message from Sean \n");
    return 0;
    }

    static int hello_release(struct inode *inode, struct file *file)
    {
    printk("hello_release: successful\n");
    return 0;
    }

    static ssize_t hello_read(struct file *file, char *buf, size_t count,
    loff_t *ptr)
    {
    printk("hello_read: returning zero bytes\n");
    return 0;
    }

    static ssize_t hello_write(struct file *file, const char *buf,
    size_t count, loff_t * ppos)
    {
    printk("hello_read: accepting zero bytes\n");
    return 0;
    }

    static long hello_ioctl(struct file *filep,
    unsigned int cmd, unsigned long arg)
    {
    printk("hello_ioctl: cmd=%u, arg=%ld\n", cmd, arg);
    return 0;
    }

    static int __init hello_init(void)
    {
    int ret;
    printk("Hello Example Init - debug mode is %s\n",
    debug_enable ? "enabled" : "disabled");
    ret = register_chrdev(HELLO_MAJOR, "hello1", &hello_fops);

    if (ret < 0)
    {
    printk("Error registering hello device\n");
    goto hello_fail1;
    }

    printk("Hello: registered module successfully!\n");
    /* Init processing here... */
    return 0;

    hello_fail1:
    return ret;
    }

    static void __exit hello_exit(void)
    {
    printk("Hello Example Exit\n");
    }

    struct file_operations hello_fops =
    {
    owner: THIS_MODULE,
    read: hello_read,
    write: hello_write,
    unlocked_ioctl: hello_ioctl,
    open: hello_open,
    release: hello_release,
    };

    module_init(hello_init);
    module_exit(hello_exit);

    Currently I have my system call in the region marked as `/*do some stuff*/`. I am asking this to speed up the process of my effort.

    Here is my user program:

    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>

    int main(int argc, char **argv)
    {
    /* Our file descriptor */
    int fd;
    int rc = 0;
    char *rd_buf[16];
    printf("%s: entered\n", argv[0]);

    /* Open the device */
    fd = open("/dev/tbt", O_RDWR);
    if ( fd == -1 )
    {
    perror("open failed");
    rc = fd;
    exit(-1);
    }

    printf("%s: open: successful\n", argv[0]);
    /* Issue a read */

    rc = read(fd, rd_buf, 0);
    if ( rc == -1 )
    {
    perror("read failed");
    close(fd);
    exit(-1);
    }

    printf("%s: read: returning %d bytes!\n", argv[0], rc);
    close(fd);
    return 0;
    }

    Thanks

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jens Thoms Toerring@21:1/5 to Shahin Ansari on Fri Aug 21 22:04:03 2015
    Shahin Ansari <persspolice@gmail.com> wrote:
    I created a sample device driver, and validated its functionality. Now I
    like to issue a system command, and be able to the result, and I do not know exactly what function to call and how. What I mean by that is my understanding of how to implement a device driver is as follows:

    1- You create a module and add it to your build system

    Which build system do you mean? Unless your moduld is going to
    become incorporated into the kernel you normally write some
    Makefile to compile it.

    2- You compile the module and flash your device ( In my case: SM-N900P )

    A module interacts with the device. "Flashing" the device would
    mean that you have written some firmware for the devive, but
    that's not a device driver that gets loaded into the kernel
    for communicating with the device.

    3- You write another program to run on the user space, which would call your module.

    You can't "call" a module. A module typically implements some
    of the system calls (open/close/read/write/poll etc.) you call
    with the device file and then the file desriptor for it as
    their first argument. And you do ioctl() calls for functio-
    nalities not possible via the "normal" system calls.

    4- You flash the phone to get the new module on the phone

    Now things get really confusing. Is your "phone" running
    Linux and the kernel running on it allows you to load
    all kinds of modules? Do you have a full cross-compile
    environmenr set up that allows you to compile modules for
    the processor running on the phone? "Flashing" sounds like
    completely replacing an operating system stored in some
    EPROM and that's definitely how you get just a module
    on the device. If "flashing" is really necessary for
    that then there's a lot more to consider (and a lot of
    things that can go wrong and brick the device;-)

    If you're just getting into writing kernel modules I think
    it would be a lot simpler to start with writing them for
    your "normal" computer" first to get the necessary experience,
    and after you got that to work, try to deal with the addi-
    tional complications of compiling a module on a non-native
    system, get it to the target system and install it there.
    Getting a module to work can be difficult enough, you don't
    need the additional complexities of compiling them on a system
    they're not targeted at at the very start.

    5- You move the user program executable to the phone also

    6- Use insmod to load the module

    That is one of the commands you can use to load a module into
    the kernel.

    7- use mknod to activate it I guess

    You use mknod to create the device file for the module.

    8- Then run the user program

    My question stems from not knowing what each part of the moduel does, and
    how to interface with it from the user program. If someone could give me a few lines of code to explain how to issue a system command that would be great. I believe what most of what I need goes in the user program, but I am not sure. The following is what I have in my test module:

    I've not looked into the details of your source code. But
    obvioulsy your module support open/read/write/close (as to
    be seen in the file_operations structure). So, if it works
    you can do in your user land program, given that the module
    is bound to a device file like, for exaple '/dev/my_phone'
    (created with 'mknod') things like


    int fd = open( "/dev/myphome", O_RDWR );
    write( fd, "something", 9 )
    char buf[ 10 ];
    read( fd, buf, 10 );
    close( fd );

    That looks mostly similar to what you seem to be doing.

    Please don't be annoyed for asking: your "module" and program
    looks a lot like something you've found as an example some-
    where. And from your questions ("flashing your phone", "not
    knowing what each part of the module does" etc.) I suspect
    that you're not yet aware of some fundamental things. If
    that's the case then please consider that writing device
    drivers isn't a simple thing of copying some example code
    and hoping that it works out of the box. You definitely
    will have to consult a good book (like "Linux Device Drivers")
    and read it carefully, at least in parts, before you'll be
    able to write your first, very simple module. And make that
    one for the computer you know very well. Cross-compiling and
    getting it to run on a very different device like a phone
    (assuming that it's possible at all) is then another big
    step.
    Best regards, Jens
    --
    \ Jens Thoms Toerring ___ jt@toerring.de
    \__________________________ http://toerring.de

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)