• socket套接字和驱动绑定分析


    1. socket()系统调用

    socket系统调用是哪个:socket()有3个参数,因此搜索SYSCALL_DEFINE3,然后在检索socket即可。

    SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
        sock_create(family, type, protocol, &sock);
            __sock_create
                sock_alloc
                    struct inode *inode;
                    inode->i_op = &sockfs_inode_ops;
            struct net_proto_family *pf = rcu_dereference(net_families[family]); //获取之前注册的协议的pf
            pf->create(net, sock, protocol, kern); //创建指定协议的套接字
        sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK)); // net/socket.c 把套接字映射成fd
            newfile=sock_alloc_file(sock, flags, NULL);  //返回一个struct file *newfile;
                file = alloc_file(&path, FMODE_READ | FMODE_WRITE, &socket_file_ops); //此file的file_operations是全局socket_file_ops
                sock->file = file;
                file->private_data = sock;
            fd_install(fd, newfile);    // net/socket.c 若成功就向用户空间返回这个fd
                __fd_install(current->files, fd, file); // fs/files.c 放到当前进程的打开文件中
                    struct fdtable *fdt;
                    fdt = rcu_dereference_sched(files->fdt); //fs/files.c 放到当前进程的fd符号表中。

    2. PF_BLUETOOTH协议族的注册过程

    /* ①定义net_proto_family */
    static const struct net_proto_family bt_sock_family_ops = { // net/bluetooth/af_bluetooth.c
        .owner    = THIS_MODULE,
        .family    = PF_BLUETOOTH,
        .create    = bt_sock_create,
    };
    
    bt_sock_create
        err = bt_proto[proto]->create(net, sock, proto, kern); // 调用全局数组bt_proto[proto]->create()
    
    /* ②调用sock_register注册此协议族 */
    sock_register(&bt_sock_family_ops);
    
    sock_register(const struct net_proto_family *ops) // net/socket.c
        rcu_assign_pointer(net_families[ops->family], ops); // 将注册的协议族放到net_proto_family类型的全局数组net_families中

    3.PF_BLUETOOTH协议族中的协议的注册过程

    static const struct proto_ops hidp_sock_ops = {
        .family       = PF_BLUETOOTH,
        .owner        = THIS_MODULE,
        .release    = hidp_sock_release,
        .ioctl        = hidp_sock_ioctl,
    #ifdef CONFIG_COMPAT
        .compat_ioctl    = hidp_sock_compat_ioctl,
    #endif
        .bind        = sock_no_bind,
        .getname    = sock_no_getname,
        .sendmsg    = sock_no_sendmsg,
        .recvmsg    = sock_no_recvmsg,
        .poll        = sock_no_poll,
        .listen        = sock_no_listen,
        .shutdown    = sock_no_shutdown,
        .setsockopt    = sock_no_setsockopt,
        .getsockopt    = sock_no_getsockopt,
        .connect    = sock_no_connect,
        .socketpair    = sock_no_socketpair,
        .accept        = sock_no_accept,
        .mmap        = sock_no_mmap
    };
    
    static struct proto hidp_proto = {
        .name        = "HIDP",
        .owner        = THIS_MODULE,
        .obj_size    = sizeof(struct bt_sock)
    };
    
    /* ①定义net_proto_family */
    static const struct net_proto_family hidp_sock_family_ops = {
        .family    = PF_BLUETOOTH,
        .owner    = THIS_MODULE,
        .create    = hidp_sock_create
    };
    
    hidp_sock_create
        sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hidp_proto, kern);
        sock->ops = &hidp_sock_ops;
    
    
    /* ②注册函数不同 */
    bt_sock_register(BTPROTO_HIDP, &hidp_sock_family_ops);
    
    bt_sock_register
        proto_register(&hidp_proto, 0); //将hidp_proto.node挂接在全局链表proto_list中
        bt_sock_register(BTPROTO_HIDP, &hidp_sock_family_ops);
            bt_proto[proto] = &hidp_sock_family_ops;  //只是将hidp_sock_family_ops放到全局数组bt_proto中

    由上可知,当应用程序调用:sock_fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HIDP);时,驱动先调用bt_sock_create(),它再调用hidp_sock_create(),从而此sock_fd会绑定到函数集合hidp_sock_ops。对比于设备文件的操作,这里只是换汤不换药而已。

  • 相关阅读:
    onpropertychange与onchange事件应用
    HttpWorkerRequest实现大文件上传asp.net
    JQuery中对option的添加、删除、取值
    "分析 EntityName 时出错"的解决方法
    asp.net断点续传
    直接在ASP.net中上传大文件的方法
    ASP.NET中文件上传下载方法集合
    asp.net .ashx文件使用Server.MapPath解决方法
    FF与IE下javascript计算屏幕尺寸
    处理顶点——为赛道创建顶点
  • 原文地址:https://www.cnblogs.com/hellokitty2/p/10188376.html
Copyright © 2020-2023  润新知