linux 设备 探测,linux内核启动设备探测过程

前段时间研究nandflash驱动,很好奇,到底是怎么探测nandflash,以及驱动等等。好吧,现在开始不说了。

首先在板级文件里面必须添加设备信息,

static struct resource s5pv210_nand_resource[] = {

[0] = {

.start = 0xB0E00000,

.end   = 0xB0E00000 + 0x00100000 - 1,

.flags = IORESOURCE_MEM,

}

};

struct platform_device s5pv210_device_nand = {

.name    = "s5pv210-nand",

.id      = -1,

.num_resources    = ARRAY_SIZE(s5pv210_nand_resource),

.resource = s5pv210_nand_resource,

};

并将s5pv210_device_nand添加到struct platform_device *smdkv210_devices[] ,

在smdkv210_machine_init会调用platform_add_devices(smdkv210_devices, ARRAY_SIZE(smdkv210_devices));

该函数会将所有的设备注册。以后注册相应的driver时会查找对应设备的信息,此时设备早已注册。

先看s5pv210_nand.c文件,这个不是官方内核源码的文件,不过也差不多。

static int __init s3c_nand_init(void)

{

printk("S3C NAND Driver, (c) 2008 Samsung Electronics\n");

return platform_driver_register(&s5pc110_nand_driver);

}

在内核初始化后肯定有S3C NAND Driver, (c) 2008 Samsung Electronics 这个信息输出。

这个函数被放在init节,会被调用。进而调用关键的platform_driver_register(&s5pc110_nand_driver);

进入platform_driver_register会调用driver_register(&drv->driver)(相当重要的设备驱动架构的函数)

driver_register->bus_add_driver(struct device_driver *drv),这个就是在/sys/ bus里面添加该driver的信息。

总之一系列的操作,要和内核驱动架构对接。下面来到了重要的地方,

if (drv->bus->p->drivers_autoprobe) {

error = driver_attach(drv);

if (error)

goto out_unregister;

}

显然如果drivers_autoprobe为真的话就会自动探测设备。进入driver_attach,该函数很简单调用bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);

bus_for_each_dev就是迭代寻找该bus下的设备,进行匹配。用这个函数__driver_attach进行判断。

static int __driver_attach(struct device *dev, void *data)

{

struct device_driver *drv = data;

/*

* Lock device and try to bind to it. We drop the error

* here and always return 0, because we need to keep trying

* to bind to devices and some drivers will return an error

* simply if it didn't support the device.

*

* driver_probe_device() will spit a warning if there

* is an error.

*/

if (!driver_match_device(drv, dev))

return 0;

if (dev->parent)/* Needed for USB */

device_lock(dev->parent);

device_lock(dev);

if (!dev->driver)

driver_probe_device(drv, dev);

device_unlock(dev);

if (dev->parent)

device_unlock(dev->parent);

return 0;

}

driver_match_device会调用drv->bus->match(dev, drv),即该总线的match函数,如果成功,并且dev没有绑定,

则会调用driver_probe_device(drv, dev)  --》really_probe(dev, drv);

static int really_probe(struct device *dev, struct device_driver *drv)

{

int ret = 0;

atomic_inc(&probe_count);

pr_debug("bus: '%s': %s: probing driver %s with device %s\n",

drv->bus->name, __func__, drv->name, dev_name(dev));

WARN_ON(!list_empty(&dev->devres_head));

dev->driver = drv;  //将driver和dev真正绑定

if (driver_sysfs_add(dev)) {

printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",

__func__, dev_name(dev));

goto probe_failed;

}

if (dev->bus->probe) {

ret = dev->bus->probe(dev);

if (ret)

goto probe_failed;

} else if (drv->probe) {

ret = drv->probe(dev);  //调用设备探测函数,相当关键

if (ret)

goto probe_failed;

}

driver_bound(dev);

ret = 1;

pr_debug("bus: '%s': %s: bound device %s to driver %s\n",

drv->bus->name, __func__, dev_name(dev), drv->name);

goto done;

probe_failed:

devres_release_all(dev);

driver_sysfs_remove(dev);

dev->driver = NULL;

if (ret != -ENODEV && ret != -ENXIO) {

/* driver matched but the probe failed */

printk(KERN_WARNING

"%s: probe of %s failed with error %d\n",

drv->name, dev_name(dev), ret);

}

/*

* Ignore errors returned by ->probe so that the next driver can try

* its luck.

*/

ret = 0;

done:

atomic_dec(&probe_count);

wake_up(&probe_waitqueue);

return ret;

}

最后我们来看看设备探测函数是哪个

static struct platform_driver s5pc110_nand_driver = {

.probe          = s5pc110_nand_probe,

.remove         = s3c_nand_remove,

.suspend        = s3c_nand_suspend,

.resume         = s3c_nand_resume,

.driver         = {

.name   = "s5pv210-nand",

.owner  = THIS_MODULE,

},

};

即最终会调用s5pc110_nand_probe--->>s3c_nand_probe

在s3c_nand_probe里面,会读取s5pv210_device_nand(板级文件里面定义的)结构信息,该结构包括nand分区信息,访问io的地址等等。

根据这些信息,访问io,获得nand的设备信息

tmp = readb(nand->IO_ADDR_R); /* Maf. ID */

tmp = readb(nand->IO_ADDR_R); /* Device ID */

会进行匹配,成功则,继续进行nand的初始化。这个可以自己去看看该文件。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值