The specific implementation of character device driver from system call to driver in user program

Source: Internet
Author: User

Citation: We know that every character device has a CDEV structure in the kernel that describes it, and one of the more important members of this structure is

Const struct file_operations *ops;

The function of this structure is to match the system call in the user program with the specific implementation function one by one in the driver. When invoking a system call to a character device file in a user program, you know which specific function to invoke for this character device, but the problem is that the following two function prototypes are shown:

// This is the prototype of the read system call ssize_t Read (intvoid *buf, size_t count);
// This is the function prototype ssize_t (*read) that corresponds to read in file_operations (structchar __user *, size_t, loff_t *);

As can be seen, the interface of the two functions is not the same, so from the system call to the specific implementation of the driver, the kernel must have done some hands and feet, the following we will be through the code to analyze from the system call to drive the implementation of the actual function of the process.

//This is a simple program to read the data from the file, we mainly through it to analyze the process of the read system call#include <stdio.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<unistd.h>intMainintargcChar Const*argv[]) {    intFD; inttemp; if(FD = open ("/dev/memdev0", o_rdwr)) = =-1) printf ("Open failed at line%d\n", __line__); Read (FD,&temp,sizeof(int)); printf ("Read failed at line%d\n", __line__); printf ("buffer is%d\n", temp);    Close (FD); return 0;}

Compile the above code, note that you must use static compilation, otherwise you will lose important information in later disassembly.

Then disassembly, import a dump file below is the assembly code corresponding to the Read function

sizeof (int));     8268:    e24b300c     Sub    R3, FP, #    0xc    826c:    e51b0008     Ldr    r0, [FP, #-8]    8270:    e1a01003     mov    R1, R3    8274:    e3a02004     mov    r2, #4    0x4     8278:    eb0028e8     bl    12620 <__libc_read>

Start is the parameter, the last sentence to jump to the __libc_read label, continue to follow

00012620<__libc_read>:12620: e51fc028 ldr IP, [PC, #- +];12600 <__libc_close+0x70>   12624: e79fc00c ldr IP, [PC, IP]12628: e33c0000 TEQ IP, #0    ;0x01262C:1a000006 bne 1264c <__libc_read+0x2c>12630: e1a0c007movIP, R712634: e3a07003movR7, #3    ;0x3   12638: ef000000 svc 0x00000000 1263C:e1a0700cmovR7, IP12640: E3700a01 cmn R0, #4096    ;0x1000   12644: 312fff1e bxcc LR12648: Ea0008b4 b14920<__syscall_error> 1264C:e92d408fPush{r0, r1, R2, R3, R7, LR}12650: eb0003b9 bl 1353c <__libc_enable_asynccancel>12654: e1a0c000movIP, R012658: e8bd000fPop{r0, r1, R2, R3} 1265 c:e3a07003 mov r7, #3; 0x3 12660:ef000000 svc 0x0000000012664: e1a07000movR7, R012668: e1a0000cmovr0, IP 1266C:eb000396 bl 134cc <__libc_disable_asynccancel>12670: e1a00007movR0, R712674: e8bd4080Pop{R7, LR}12678: E3700a01 cmn R0, #4096    ;0x10001267C:312fff1e bxcc LR12680: Ea0008a6 b14920<__syscall_error>12684: e1a00000NOP(movr0,r0)12688: e1a00000NOP(movr0,r0) 1268C:e1a00000NOP(movR0,R0)

A lot of code, but only two important lines, has been highlighted in red, the specific thing is to put 3 into the R7 register, and then through the SVC instructions to the PC pointer from a fixed entrance to the kernel space, after the kernel according to the number in the R7, check the table after the corresponding system call. In the linux2.6.39 version of the kernel, the table is located in the Calls.s file

0 */call        (sys_restart_syscall        )call(sys_exit        )call  (sys_fork_wrapper)        call (sys_read)        Call (sys_write)

Read in user space is actually called the kernel space in the Sys_read function, the implementation code of the function is as follows

 Syscall_define3 (read, unsigned int , FD,  __user * struct     file *file;    ssize_t ret  =-EBADF;     int   fput_needed;    File  = Fget_light (fd, &fput_needed);  if   (file) {loff_t pos  = File_pos_read (file);        RET  = vfs_read (file, buf, Count, &pos);        File_pos_write (file, POS);    Fput_light (file, fput_needed);  return   ret;}  

Analysis: We know that none of the open files have a file structure in the kernel to maintain, this calls fget_light through the Read function provided by the FD to get the file structure, and then called the Vfs_read function

ssize_t Vfs_read (structFile *file,Char__user *buf, size_t count, loff_t *POS)    {ssize_t ret; if(! (File->f_mode &fmode_read)) return-EBADF; if(!file->f_op | | (!file->f_op->read &&!file->f_op->aio_read)) return-EINVAL; if(Unlikely (!Access_ok (Verify_write, buf, Count))) return-Efault; RET=Rw_verify_area (READ, file, POS, count); if(Ret >=0) {Count=ret; if(file->f_op->Read) ret = file->f_op->read (file, buf, Count, POS); Elseret=do_sync_read (file, buf, Count, POS); if(Ret >0) {fsnotify_access (file);        Add_rchar (current, ret);    } INC_SYSCR (current); }    returnret;}

Again, the most important code has been highlighted, which is the most important sentence of the whole process, which calls the member function f_op->read in file. at the time of the driver initialization, the file_operations struct is assigned to the member F_op of the device file, so the specific implementation function in the final driver is dropped: Xxx_read. In fact, the red words I can not find the kernel code to prove that, but the logic is this, and as a novice in the learning-driven period do not overdo to see the kernel code, not worth the candle. But if the great God can find the relevant code, thank you!

If you have any questions or errors, you are welcome to discuss! Reprint please specify the source!

The specific implementation of character device driver from system call to driver in user program

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.