以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 **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)
int kern)
sock->ops = &hci_sock_ops;
到目前为止,AF_BLUETOOTH注册完成,socket也创建完了,所有对socket的读写操作都能定位到hci_cock.c中。