kernel中bluetooth的初始化

我们大家都知道,Android其实是基于linux之上进行运行的。在Android系统的运行之初,首先是kernel层的一系列的初始化。今天晓东就先和大家来简单分析一下在开机之后,kernel中和bluetooth的初始化相关的内容有哪些。

我们仍然还是才kernel/net/bluetooth下面的代码开始查看,搜索一下initcall相关的内容也就只有在af_bluetooth.c中看到了这样一句话:

subsys_initcall(bt_init);

毫无疑问,我们肯定要从这里开始看了,若是有同学要问晓东为什么会是这里,我就不给您详细解释了,若是您有打破砂锅问到底的精神,晓东推荐你去google或者百度一下这个函数,就会看到一堆讲解linux启动的文章,我想您一定会有所收获的。

废话不多说了,直接看代码了:

1bt_init的实现。

static int __init bt_init(void)
{
	int err;
/*
*这会是在kernel中打印的第一个和蓝牙相关的内容,这里的版本是2.16
*/
	BT_INFO("Core ver %s", VERSION);	
/*
*新建两个目录,不深入去看了
*新建一个sys/kernel/debug/bluetooth
*新建一个sys/class/bluetooth
*这连个目录可以再adb shell的时间进去看到了
*/
	err = bt_sysfs_init();
	/*
	*向协议族数组中加入PF_BLUETOOTH=31
	*/
	err = sock_register(&bt_sock_family_ops);
	BT_INFO("HCI device and connection manager initialized");
	//hci socket的初始化
	//注册HCI的proto,还有PROTO_HCI对应的ops
	//然后注册了一个hci_notifier的监听,后面1.1会详细说明
	err = hci_sock_init();
	//l2cap相关的初始化,详细见1.2说明
	err = l2cap_init();
	//和L2CAP的注册流程是一样的,只是注册的是sco而已
	err = sco_init();
……
}

1.1 hci_sock_init的实现

下面,我们来看一下hci_sock_init函数的实现:

int __init hci_sock_init(void)
{
	int err;
//注册HCI的proto,即加入到proto_list中去
//proto_list是一个全局的静态链表,无多大用途,仅供查询使用
	err = proto_register(&hci_sk_proto, 0);
	//初始化BTPROTO_HCI对应的ops
	err = bt_sock_register(BTPROTO_HCI, &hci_sock_family_ops);
	//注册一个hci_notifier的监听吧
	hci_register_notifier(&hci_sock_nblock);
	BT_INFO("HCI socket layer initialized");
	return 0;
……
}

这里的关键是调用了bt_sock_registerhci_register_notifier函数。下面,我们来着重分析一下这两个函数

1.1.1 bt_sock_register函数的实现

int bt_sock_register(int proto, const struct net_proto_family *ops)
{
	int err = 0;
/*
*在目前的版本中,共有一下bt相关的proto定义
*#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
*需要注意的是,BT_MAX_PROTO的定义和这些proto的定义不是在一个地方
*所以若是想加入新的proto,一定要注意修改BT_MAX_PROTO的值
*/
	if (proto < 0 || proto >= BT_MAX_PROTO)
		return -EINVAL;
/*
* bt_proto_lock是一个全局的静态的读写锁
*主要用于保护bt_proto数组的读写
*/
	write_lock(&bt_proto_lock);
	//所有bt相关的proto,都是在一个bt_proto的数组中
	//找到对应的初始化即可
	if (bt_proto[proto])
		err = -EEXIST;
	else
		bt_proto[proto] = ops;
	write_unlock(&bt_proto_lock);
	return err;
}

1.1.2 hci_register_notifier的分析

代码很简答,就是注册了hci_notifiercallbackhci_sock_nblock

int hci_register_notifier(struct notifier_block *nb)
{
	return atomic_notifier_chain_register(&hci_notifier, nb);
}

1.2 l2cap_init的分析

l2cap相关的初始化,位于l2cap_sock.c

int __init l2cap_init(void)
{
	int err;
	//l2cap相关的初始化,见1.2.1
	err = l2cap_init_sockets();
	if (err < 0)
		return err;
	//hci的proto
	//0--L2CAP
	//1—SCO
//详见1.2.2
	err = hci_register_proto(&l2cap_hci_proto);
	if (err < 0) {
		BT_ERR("L2CAP protocol registration failed");
		bt_sock_unregister(BTPROTO_L2CAP);
		goto error;
	}
	//就是建sys/kernel/debug/bluetooth/l2cap
	if (bt_debugfs) {
		l2cap_debugfs = debugfs_create_file("l2cap", 0444,
					bt_debugfs, NULL, &l2cap_debugfs_fops);
		if (!l2cap_debugfs)
			BT_ERR("Failed to create L2CAP debug file");
	}
……
}

1.2.1 l2cap_init_sockets

这个函数和hci_sock_init的内容就差不多了

int __init l2cap_init_sockets(void)
{
	int err;
	//把l2cap加入到proto_list中去
	err = proto_register(&l2cap_proto, 0);
	if (err < 0)
		return err;
	//再加入BTPROTO_L2CAP到bt_proto中
	err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
	if (err < 0)
		goto error;
……
}

1.2.2 hci_register_proto

我们知道l2capsco其实并不是和hci层平齐的,他们都是位于hci之上的,所以,这里会继续在hci之上初始化l2capsco相关的内容。

int hci_register_proto(struct hci_proto *hp)
{
	int err = 0;
	BT_DBG("%p name %s id %d", hp, hp->name, hp->id);
	//其实只有0和1,分别为L2CAP和SCO
	if (hp->id >= HCI_MAX_PROTO)
		return -EINVAL;
//hci_task_lock是一个全局锁
	write_lock_bh(&hci_task_lock);
	//hci_proto对应的id初始化
	//这也是一个全局变量
	if (!hci_proto[hp->id])
		hci_proto[hp->id] = hp;
	else
		err = -EEXIST;
	write_unlock_bh(&hci_task_lock);
	return err;
}

至此bt_init函数的分析就结束了,我们来总结一下,他主要做了以下几个工作:

1) 新建了几个debug的文件夹/文件:

sys/kernel/debug/bluetooth

sys/class/bluetooth

sys/kernel/debug/bluetooth/l2cap

sys/kernel/debug/bluetooth/sco

2) 向协议族数组中加入了PF_BLUETOOTH=31的协议

3) proto_list中加入了HCI,L2CAP,SCO

4) bt_proto数组中加入了BTPROTO_L2CAPBTPROTO_HCI, BTPROTO_SCO

5) hci_proto数组中加入了L2CAPSCO

6) hci_notifier注册了一个callbackhci_sock_nblock

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值