最近在学习Linux设备模型,前面几篇文章也是读这篇的时候遇到问题,然后为了搞清楚先转去摸索才写出来的。

当然了,刚开始是先读到《Linux那些事儿之我是Sysfs》,搞不清楚才去读的《Linux设备模型浅析之uevent》,结果那篇文章说要先读《Linux设备模型浅析之设备篇》。

而读《Linux那些事儿之我是Sysfs》之前是先读了《Linux那些事儿之我是U盘》,原因是当初在某培训机构培训后有一家公司去招聘,面试唯一的问题是,你搞过USB驱动吗?答:没搞过。然后面试就结束了。

另一个原因是自己买了一个USB无线网卡,用Linux内核带的驱动该网卡很不稳定,然后就跑到某国内操作系统论坛抱怨Linux下上网速度很慢,后来发现编译安装官方给的驱动就可以正常运行(发现自己的抱怨真的很笨)。为了搞懂这些都是为什么,于是决定学习USB驱动,并准备接下来学习网卡驱动。

USB的学习,这里必须推荐一下《圈圈教你玩USB》,我买了它的书和开发板之后,才能够快速的入门USB协议。看完了这本书之后才会有耐心开始看《Linux那些事儿之我是U盘》,然后才终于打开了Linux内核学习的大门。

好了,上面是闲扯,也是自己这一个月能够入门Linux内核的历程,结束了上面的闲扯之后,下面接着闲扯。

网上的这篇《Linux设备模型浅析之设备篇》我看2011年已经在网上传了,估计内核版本也比较老了,文章给出的 http://zhiqiang0071.cublog.cn 也打不开了。

我是升级控,把涉及到的代码用新版本的内核源码贴出来,也是为了保证自己学习的时候能够深入进去。

现在www.kernel.org最新稳定版本为3.14.5,这里源码就用这个内核版本

文件/arch/arm/plat-samsung/devs.c

static struct resource s3c_rtc_resource[] = {
        [0] = DEFINE_RES_MEM(S3C24XX_PA_RTC, SZ_256),
        [1] = DEFINE_RES_IRQ(IRQ_RTC),
        [2] = DEFINE_RES_IRQ(IRQ_TICK),
};

文件/include/linux/ioport.h

#define DEFINE_RES_MEM(_start, _size) \
        DEFINE_RES_MEM_NAMED((_start), (_size), NULL)

#define DEFINE_RES_MEM_NAMED(_start, _size, _name) \
        DEFINE_RES_NAMED((_start), (_size), (_name), IORESOURCE_MEM)

#define DEFINE_RES_NAMED(_start, _size, _name, _flags)\
        { \
                .start = (_start), \
                .end = (_start) + (_size) - 1, \
                .name = (_name), \
                .flags = (_flags), \
        }

#define DEFINE_RES_IRQ(_irq) \
        DEFINE_RES_IRQ_NAMED((_irq), NULL)

#define DEFINE_RES_IRQ_NAMED(_irq, _name) \
        DEFINE_RES_NAMED((_irq), 1, (_name), IORESOURCE_IRQ)

struct platform_device s3c_device_rtc = {
        .name = "s3c2410-rtc",
        .id = -1,
        .num_resources = ARRAY_SIZE(s3c_rtc_resource),
        .resource = s3c_rtc_resource,
};

文件/arch/arm/mach-s3c64xx/mach-smdk6410.c

static struct platform_device *smdk6410_devices[] __initdata = {
#ifdef CONFIG_SMDK6410_SD_CH0
        &s3c_device_hsmmc0,
#endif
#ifdef CONFIG_SMDK6410_SD_CH1
        &s3c_device_hsmmc1,
#endif
        &s3c_device_i2c0,
        &s3c_device_i2c1,
        &s3c_device_fb,
        &s3c_device_ohci,
        &samsung_device_pwm,
        &s3c_device_usb_hsotg,
        &s3c64xx_device_iisv4,
        &samsung_device_keypad,

#ifdef CONFIG_REGULATOR
        &smdk6410_b_pwr_5v,
#endif
        &smdk6410_lcd_powerdev,

&smdk6410_smsc911x,
        &s3c_device_adc,
        &s3c_device_cfcon,
        &s3c_device_rtc,
        &s3c_device_ts,
        &s3c_device_wdt,
};

struct bus_type platform_bus_type = {
        .name = "platform",
        .dev_groups = platform_dev_groups,
        .match = platform_match,
        .uevent = platform_uevent,
        .pm = &platform_dev_pm_ops,
};

文件/drivers/base/core.c

/**
 * device_initialize - 初始化device结构
 * @dev: device.
 *
 * 这里初始化其区域来为其他层使用该设备准备。
 * 这里是device_register()的前一半, 如果是被那个方法调用的话,
 * 可是它也可以被单独调用, so one may use @dev's fields. In particular, 
 * 尤其在调用本方法后可以使用get_device()/put_device()修改引用次数。
 *
 * 除了一些被明确赋值为其他值的项外,@dev的所有区域必须被调用方
 * 初始化为0.  最简单的方法是使用kzalloc()来分配一个包含@dev的结构。
 *
 * 注意: 一旦你调用了该方法,就要使用put_device()来放弃你的引用,
 * 而不是直接释放@dev。
 */
void device_initialize(struct device *dev)
{
        dev->kobj.kset = devices_kset;
        kobject_init(&dev->kobj, &device_ktype);
        INIT_LIST_HEAD(&dev->dma_pools);
        mutex_init(&dev->mutex);
        lockdep_set_novalidate_class(&dev->mutex);
        spin_lock_init(&dev->devres_lock);
        INIT_LIST_HEAD(&dev->devres_head);
        device_pm_init(dev);
        set_dev_node(dev, -1);
}

文件/drivers/base/core.c

/**
 * platform_device_add - 添加platform设备到设备层
 * @pdev: 正在添加的platform设备
 *
 * 这是platform_device_register()的第二部分, though may be called
 * separately _iff_ pdev was allocated by platform_device_alloc().
 */
int platform_device_add(struct platform_device *pdev)
{
        int i, ret;

if (!pdev)
                return -EINVAL;

if (!pdev->dev.parent)
                pdev->dev.parent = &platform_bus;

pdev->dev.bus = &platform_bus_type;

switch (pdev->id) {
        default:
                dev_set_name(&pdev->dev, "%s.%d", pdev->name,  pdev->id);
                break;
        case PLATFORM_DEVID_NONE:
                dev_set_name(&pdev->dev, "%s", pdev->name);
                break;
        case PLATFORM_DEVID_AUTO:
                /*
                 * 自动分配设备ID。我们把他标记为这样,来保证我们可以记住它
                 * 必须被释放,而且我们追加一个后缀来避免命名空间显示ID冲突。
                 */
                ret = ida_simple_get(&platform_devid_ida, 0, 0, GFP_KERNEL);
                if (ret < 0)
                        goto err_out;
                pdev->id = ret;
                pdev->id_auto = true;
                dev_set_name(&pdev->dev, "%s.%d.auto", pdev->name, pdev->id);
                break;
        }

for (i = 0; i < pdev->num_resources; i++) {
                struct resource *p, *r = &pdev->resource[i];

if (r->name == NULL)
                        r->name = dev_name(&pdev->dev);

p = r->parent;
                if (!p) {
                        if (resource_type(r) == IORESOURCE_MEM)
                                p = &iomem_resource;
                        else if (resource_type(r) == IORESOURCE_IO)
                                p = &ioport_resource;
                }

if (p && insert_resource(p, r)) {
                        dev_err(&pdev->dev, "failed to claim resource %d\n", i);
                        ret = -EBUSY;
                        goto failed;
                }
        }

pr_debug("Registering platform device '%s'. Parent at %s\n",
                 dev_name(&pdev->dev), dev_name(pdev->dev.parent));

ret = device_add(&pdev->dev);
        if (ret == 0)
                return ret;

failed:
        if (pdev->id_auto) {
                ida_simple_remove(&platform_devid_ida, pdev->id);
                pdev->id = PLATFORM_DEVID_AUTO;
        }

while (--i >= 0) {
                struct resource *r = &pdev->resource[i];
                unsigned long type = resource_type(r);

if (type == IORESOURCE_MEM || type == IORESOURCE_IO)
                        release_resource(r);
        }

err_out:
        return ret;
}

学习《Linux设备模型浅析之设备篇》笔记(一)相关推荐

  1. 【web编程技术学习笔记】因特网与万维网简介

    目录 Client客户端 Server服务器端 TCP/IP五层协议 IP 查看IP地址的的两种方法 TCP URL 样式一 样式二 DNS URL&DNS HTTP 与因特网有关的组织 IE ...

  2. 程序员编程技术学习笔记

    程序员编程技术学习笔记     看july的博客也有好久了,一直没能好好整理一下自己的学习笔记,开了博客之后更加愿意好好整理一番了.其中不免有些内容在july那里可以找到原文,但是更多的加入了我个人的 ...

  3. JAVA 网络编程技术学习笔记

    目录 一.网络编程基本概念(了解) 1.1 计算机网络 1.2 网络通信协议 1.2.1什么是网络通信协议 1.2.2 OSI七层协议模型 1.2.3网络协议的分层 1.3数据的封装和解封 1.4 I ...

  4. 《ASP.NET MVC4 WEB编程》学习笔记------Web API 续

    目录 ASP.NET WEB API的出现缘由 ASP.NET WEB API的强大功能 ASP.NET WEB API的出现缘由 随着UI AJAX 请求适量的增加,ASP.NET MVC基于Jso ...

  5. java网络编程技术学习笔记(b站【狂神说Java】网络编程实战讲解)

    b站视频链接:[狂神说Java]网络编程实战讲解 文章目录 网络编程 1.1.概述 1.2.网络通信的要素 1.3.IP 1.4.端口 1.5.通信协议 1.6.TCP 文件发送 1.7.UDP 1. ...

  6. SpringBoot整合第三方技术学习笔记(自用)

    SpringBoot整合第三方技术学习笔记 搬运黑马视频配套笔记 KF-4.数据层解决方案 KF-4-1.SQL 回忆一下之前做SSMP整合的时候数据层解决方案涉及到了哪些技术?MySQL数据库与My ...

  7. java mvc框架代码_JAVA技术学习笔记:SpringMVC框架(内附入门程序开发代码)

    原标题:JAVA技术学习笔记:SpringMVC框架(内附入门程序开发代码) JavaEE体系结构包括四层,从上到下分别是应用层.Web层.业务层.持久层.Struts和SpringMVC是Web层的 ...

  8. ssm 转发请求_千呼万唤!阿里内部终于把这份SSM框架技术学习笔记分享出来了...

    SSM SSM(Spring+SpringMVC+MyBatis)框架集由Spring.MyBatis两个开源框架整合而成(SpringMVC是Spring中的部分内容).常作为数据源较简单的web项 ...

  9. 【C#编程基础学习笔记】6---变量的命名

    2013/7/24 技术qq交流群:JavaDream:251572072  教程下载,在线交流:创梦IT社区:www.credream.com [C#编程基础学习笔记]6---变量的命名 ----- ...

  10. 【C#编程基础学习笔记】4---Convert类型转换

    2013/7/24 技术qq交流群:JavaDream:251572072  教程下载,在线交流:创梦IT社区:www.credream.com [C#编程基础学习笔记]4---Convert类型转换 ...

最新文章

  1. iOS底层原理 - 常驻线程
  2. 人人都是架构师: 约束和原则
  3. 【对讲机的那点事】节日出游对讲机选择你了解多少?
  4. image转pixmap qt_Qt 编程指南10 QImage Mat QPixmap转换
  5. 漫谈C#编程语言在游戏领域的应用
  6. java面试题六 float变量合法声明
  7. 生活大爆炸版石头剪刀布
  8. 计算机真正管理的文件名是什么,计算机题,请大家多多帮忙,谢谢
  9. 通俗易懂,先来认识一下Vuex
  10. Faster R-CNN原理
  11. ShuttleFlow 2.0版本跨链协议上线,同时支持OKExChain、Heco及BSC双向互操作
  12. 面试题(4)--基础篇
  13. 【HASPDOG】卸载
  14. 栈解决中缀表达式转后缀表达式_第3章栈和队列,中缀表达式转换成后缀表达式...
  15. protoc java out_protoc 命令参数
  16. 计算机的神奇小游戏,电脑课我们常玩的13个小游戏
  17. 01英语语法-基本句型及补语
  18. win10文件服务器ssd当缓存盘,Win10开启写入缓存策略来提高SSD固态硬盘性能
  19. python123货币转换器_python货币转换
  20. Postman教程-Pre-request Script和Tests脚本进阶

热门文章

  1. Failed to resolve:com.gtihub (android引入库的时候提示这样的错误)
  2. JavaWeb——jsp-config
  3. 简析平衡树(三)——浅谈Splay
  4. 并发编程的那些事。(二)
  5. commander.js
  6. C#基础——数组(冒泡排序)
  7. detection in video and image
  8. Java for LeetCode 067 Add Binary
  9. GPS部标平台的架构设计(十)-基于Asp.NET MVC构建GPS部标平台
  10. 做技术到底可以做到哪种地步-技术为什么越走越窄 (转)