内核中socket address family的注册过程

来源:互联网 发布:南风知我意txt下载 编辑:程序博客网 时间:2024/06/05 18:52
以AF_BLUETOOTH为例,梳理内核中socket address family的注册过程。
linux内核启动之时,会初始化各subsystem(子系统),bluetooth就是这样的一个子系统之一
bluetooth/af_bluetooth.c
     subsys_initcall(bt_init);
          subsys_initcall是一个宏定义,在include/linux/init.h中:
          #define subsys_initcall(fn)     __define_initcall("4",fn,4)
                #define __define_initcall(level,fn,id) \
                      static initcall_t __initcall_##fn##id __used \
                     __attribute__((__section__(".initcall" level ".init"))) = fn //这里bt_initcall的代码,定义在.initcall段内。

bluetooth/af_bluetooth.c
static int __init bt_init(void)
     bt_sysfs_init();//初始化蓝牙虚拟文件系统
     sock_register(&bt_sock_family_ops);//注册蓝牙地址协议簇
     hci_sock_init();//初始化蓝牙地址协议簇
     l2cap_init();//初始化逻辑链路控制与适配协议,由CONFIG_BT_L2CAP控制
     sco_init();//初始化同步定向链接协议,有CONFIG_BT_SCO控制

这里主要关注的是蓝牙地址协议族的过程的实现
net/socket.c
     int sock_register(const struct net_proto_family *ops)
          rcu_assign_pointer(net_families[ops->family], ops);  //rcu(Read-Copy Update),无锁的赋值方式(下次研究),其实就是把bt_sock_family_ops赋值给net_families[AF_BLUETOOTH]

接下来,看hci_sock_init的实现:
net/bluetooth/hci_sock.c
     int __init hci_sock_init(void);//初始化hci_sock
           proto_register(&hci_sk_proto, 0); //将hci_sk_proto(struct proto *)加入全局proto_list列表
           bt_sock_register(BTPROTO_HCI, &hci_sock_family_ops);//注册socket ops回调
                bt_proto[proto] = ops;//将hci_sock_family_ops存进bt_proto数组里面,
                      bt所有的协议如下:
                      #define BTPROTO_L2CAP   0
                      #define BTPROTO_HCI 1
                      #define BTPROTO_SCO 2
                      #define BTPROTO_RFCOMM  3
                      #define BTPROTO_BNEP    4
                      #define BTPROTO_CMTP    5
                      #define BTPROTO_HIDP    6
                      #define BTPROTO_AVDTP   7

在执行系统调用 socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)的时候,会调用到内核net/socket.c的__sock_create方法:
net/socket.c
SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
      int __sock_create(struct net *net, int family, int type, int protocol,
             struct socket **res, int kern)
          struct socket *sock = sock_alloc();//构造一个socket结构
          sock->type = type; //SOCK_RAW
          const struct net_proto_family *pf = rcu_dereference(net_families[family]);//取出AF_BLUETOOTH协议结构体
          pf->create(net, sock, protocol, kern);  //调用刚刚注册的net_proto_family,也就是bt_sock_family_ops的create方法,
          查看bt_sock_family_ops,知道create是bt_sock_create方法
af_bluetooth.c
static int bt_sock_create(struct net *net, struct socket *sock, int proto,
              int kern)  //proto=BTPROTO_HCI
     bt_proto[proto]->create(net, sock, proto, kern); //调用刚刚注册的hci_sock_family_ops的create方法,也就是hci_sock_create

hci_sock.c
static int hci_sock_create(struct net *net, struct socket *sock, int protocol,
               int kern) 
     sock->ops = &hci_sock_ops;
到目前为止,AF_BLUETOOTH注册完成,socket也创建完了,所有对socket的读写操作都能定位到hci_cock.c中。
原创粉丝点击