內核中socket address family的註冊過程

以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中。
發佈了102 篇原創文章 · 獲贊 35 · 訪問量 40萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章