zoukankan      html  css  js  c++  java
  • 嵌入式Linux驱动学习之路(九)Linux系统调用、驱动程序框架

    应用程序通过open  read  write close 等函数来操作计算机硬件。类似是一个接口。

    当应用程序调用这些接口程序时,计算机是如何进入内核的呢?这是经过了系统调用。

    实际上当调用接口函数时,会引发一个swi异常(附带参数,软中断),通过这个异常就进入了内核空间。在内核空间的异常处理函数中就会处理传入的值。

    而C库中的open如何对应上内核空间中相应的函数呢?这是由驱动程序框架来完成的。

    linux对所用到的系统调用进行了编号。

    例如:

    NO1. open

    NO2. read

    NO3. write

     ......

    在Linux内核代码中的entry-common.S中有ENTRY(vector_swi),来响应系统调用指令。编号放在了R7寄存器中。

    在entry-common.S中有一个sys_call_table。而其在calls.s中。r7中的编号就和这个表中对应。

    同时、头文件unistd.h中的编号也和上面对应。

    对应用程序进行反汇编

    在read的反汇编代码中,将read的三个参数传入r0,r1,r2

    然后调用libc_read

    把3传入r7寄存器,然后使用svc指令。

    svc为系统调用指令。

    使用之后pc指针会从用户空间进入内核空间。而入口是固定的ENTRY(vector_swi)。

    进入内核后,首先去r7中的值3。

    根据3来查sys_call_table表。

    从而调用sys_read函数。

    asmlinkage ssize_t sys_read(unsigned int fd, char __user * buf, size_t count)

    在read_wrtie.c文件中。

    asmlinkage ssize_t sys_read(unsigned int fd, char __user * buf, size_t count)
    {
        struct file *file;
        ssize_t ret = -EBADF;
        int fput_needed;
    
        file = fget_light(fd, &fput_needed);      //先找到struct file
        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;
    }

    在vfs_read有这个代码:ret = file->f_op->read(file, buf, count, pos);这就是在调用我们驱动中写的那个函数。

    sd

  • 相关阅读:
    做一个:网页请求数据库数据 流程
    开始一个Django项目的简单方法
    Django模板系统
    Python Django 中的STATIC_URL 设置和使用解析
    Django框架(一)-Django初识
    bootstrap
    jQuery
    js(jquery)鼠标移入移出事件时,出现闪烁、隐藏显示隐藏显示不停切换的情况
    PHPCMS快速建站系列之网站迁移(本地到服务器,服务器迁移,更换域名等)
    PHPCMS快速建站系列之在线留言
  • 原文地址:https://www.cnblogs.com/ynxf/p/5992576.html
Copyright © 2011-2022 走看看