假设我们编写应用程序有一个read系统调用,下面来看看是如何从很多file_operations结构中寻找到对应的read。
我们可以利用反汇编arm-Linux-objdump -D -S xxx >dump,输出到dump文件,打开dump文件,定位到read汇编处,有下面一句:
bl <_libc_read>
好,接着去_libc_read汇编处,发现最重要的两行汇编语句:
mov r7,#3 //read的系统调用号是3
svc 0x00000000 //系统调用入口
Linux有一个固定的系统调用的入口ENTRY(vector_swi),{可在entry-common.s文件 }
我们看看ENTRY(vector_swi)做了哪些事:
1)获得系统调用号,就是之前 mov r7,#3
2)跳转到sys_call_table表
adr tbl, sys_call_table @ load syscall table pointer
找到sys_call_table表入口
ENTRY(sys_call_table)
#include "calls.S" 表定义在calls.S 文件中
打开calls.S,
call(sys_read)来调用,而sys_read在read-write.c里面通过宏定义的:
SYSCALL_DEFINE3宏定义作用,将read前面加sys变成sys_read
应用程序调用的open函数会创建一个file结构,然后下面的函数会通过fd,寻找对应file结构
file = fget_light(fd, &fput_needed); //寻找对应file结构
--------------------------------------------------------------
loff_t pos = file_pos_read(file); //读取fops,文件指针位置
--------------------------------------------------------------
ret = vfs_read(file, buf, count, &pos); //调用vfs_read
最有用的是:
if (file->f_op->read)
ret = file->f_op->read(file, buf, count, pos);
找到file结构里面的file_operations函数结构的read
调用完,最后 file_pos_write(file, pos);回写fops保存