Linux Platform Bus(1) - 总线初始化

0. 前言

        kernel版本号为 2.6.35

1. 初始化概述

        platform bus初始化过程,即平台总线的建立过程。

start_kernel()
    -->rest_init()                       //start_kernel函数最后调用的一个函数
        -->kernel_thread(kernel_init)    //创建系统进程
            -->kernel_init()
                -->do_basic_setup()
                    -->driver_init()
                        --> platform_bus_init()
                            -->device_register(&platform_bus)          //注册总线设备(总线也是一种设备,先注册总线设备)
                                -->device_initialize(&platform_bus);   //初始化设备
                                -->device_add(&platform_bus);         //添加设备
                            -->bus_register(&platform_bus_type)       //注册platform总线                                                                                       

        start_kernel() 函数是Linux系统启动过程中调用的第一个C函数,在它之前还有一段汇编代码,想知道它是被谁调用,它之前有哪些初始化操作,可以看我的博客《Linux kernel启动过程》

2. 具体代码分析

        platform总线的实现在drivers/base/platform.c 文件中,这里重点分析platform bus在初始化过程中注册的两个结构体。

int __init platform_bus_init(void)
{
	error = device_register(&platform_bus);  //注册总线设备(总线也是一种设备,先注册总线设备)
	error =  bus_register(&platform_bus_type); //注册platform总线  
}

2.1 注册platform bus设备

struct device platform_bus = {
	.init_name	= "platform",
};

int device_register(struct device *dev)
{
	device_initialize(dev);
	return device_add(dev);
}

        看到这里,device_add()是不是很眼熟?

        对,没错,这是Linux设备模型中用于添加设备的接口,而device_register() 函数就是设备模型对外提供的,用于添加设备的接口。所以呢,这里就是单纯地添加名为“platform” 的设备,是属于设备模型下添加设备的一个常规操作。

2.2 注册platform bus总线

        注意platform_bus_type 这个结构体,它提供了match函数,但是没有提供probe函数,这对于注册到platform 总线上的devices 和drivers 很重要,后面分析平台设备和平台驱动的注册时会和这里相呼应。

struct bus_type platform_bus_type = {
	.name		= "platform",
	.dev_attrs	= platform_dev_attrs,
	.match		= platform_match,      //注意这里提供了match函数
	.uevent		= platform_uevent,     
	.pm		= &platform_dev_pm_ops,
};

int bus_register(struct bus_type *bus)
{
	struct bus_type_private *priv;

	priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL);
	priv->bus = bus;       //互相指向对方
	bus->p = priv;         //以便于由bus可以找到其对应的priv,和由priv可以找到其对应的bus
    ······
	//初始化两个链表,用于管理挂接在该总线上的devices和drivers
	klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);  //初始化platform bus上的devices链表的链表头
	klist_init(&priv->klist_drivers, NULL, NULL);   //初始化platform bus上的drivers链表的链表头
}    

        bus_register() 也是设备模型对外提供的,用于注册bus 的接口,这里注册了一个名为“platform” 的总线。

3. 总结

        可以看到,向内核注册device 和driver 最终都是填充为设备模型下的对象(即 kobject)进行管理,所以设备模型是Linux 内核的一个重要组成部分,所以还是有必要了解一下什么是设备模型,之所以说的是了解,而不是深入理解,是因为这个东西作为Linux核心内容之一,深入理解还是有些难度的。

        我也写过一篇博客《设备模型》,有个大概的介绍,应对日常的基本工作应该没什么问题,当然也可能是我太菜了,还轮不到我来解决高难度的问题,遇到再说吧!

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值