日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

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

發布時間:2023/11/27 生活经验 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 学习《Linux设备模型浅析之设备篇》笔记(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近在學習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设备模型浅析之设备篇》笔记(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。