`
mmdev
  • 浏览: 13242908 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

面对不断升级的内核,如何学习linux设备驱动

阅读更多

面对不断升级的linux内核、GNU开发工具、linux环境下的各种图形库,很多linux应用程序开发人员和linux设备驱动开发人员即兴奋,又烦躁。兴奋的是新的软件软件、工具给我提供了更强大的功能,烦躁的是适应新软件的特性、搭建新环境是一项非常繁琐的事情。本文想从以下3个方面探讨一下“面对不断升级的内核,如何学习linux设备驱动”。

内核发展的现状及其对技术人员的影响

Linux目前主要维护2.4和2.6两个内核版本。在http://www.kernel.org/ 网站上已经可 以下载到最新的2.6内核linux-2.6.31,及最新的2.4内核linux-2.4.37。稳定版本号基本上是1~3月更新一次,如:2.6.22至2.6.23。升级版本号每1~2周更新一次,如:2.6.23.1至2.6.23.2。

由于高版本内核并不完全兼容低版本内核,所以内核升级对从事linux开发的技术人员造成了一定的影响,特别对于linux入门人员。

内核的升级对应从事linux应用程序开发的人员来说影响较小,因为系统调用基本保持兼容。而影响比较大的是驱动开发人员。每次内核的更新都可以导致很多内核函数使用上的变化。其中有内核本身提供的函数,也有硬件平台代码提供的函数,后者变化的更加频繁。这一点让初学内核驱动的人很迷茫,因为当他们按照手里的经典著作,如:Alessandro的《linux设备驱动程序》,编写驱动时,发现并不能够成功的在你的linux平台上编译通过、或不能正常执行。你的朋友会告诉你,你用的内核和书里的不一致。那该怎么办呢?

我想从两个方面去解释这个问题,一方面是如何写好linux设备驱动,另一方面是如何应对不断升级的内核。

如何写好Linux设备驱动

Linux设备驱动是linux内核的一部分,是用来封装硬件细节,为上层提供标准接口的一种方法。为了能够编写出质量比较高的驱动,要求工程师必须具备以下几个方面的知识:

熟悉处理器的性能

如:处理器的体系结构、汇编语言、工作模式、异常处理等此项对于初学者来说,重要程度:***。也就是说还不熟悉驱动编写方法的情况下,可
以先不把重心放在这一项上,因为可能因为它的枯燥、抽象而影响到你对设备驱动的兴趣。

随着你不断的熟悉驱动的编写,你会很自然的意识到此项的重要性。

掌握驱动目标的硬件工作原理及通讯协议

如:串口控制器、显卡控制器、硬件编解码、存储卡控制器、I2C通讯、SPI通讯、USB通讯、SDIO通讯、I2S通讯、PCI通讯等

此项的重要程度应该不用多说了,编写设备驱动的前提就是知道设备的操作方法。但不是说要把所有设备的操作方法都熟悉了以后才可以驱动,你只需要了解你要驱动的硬件就可以了。所有这一项对于初学者来说重要程度都是:*****。

掌握硬件的控制方法

如:中断、轮询、DMA 通常一个硬件控制器会有多种控制方法,你需要根据系统性能的需要合理的选择操作方法。

此项对于初学者来说:重要程度:****。初学阶段以实现功能为目的。掌握的顺序应该是,轮询->中断->DMA。随着学习的深入,需要综合考虑系统的性能需求,采取合适的方法。

良好的GNU C语言编程基础

如:C语言的指针、结构体、内存操作、链表、队列、栈、C和汇编混合编程等。

这些编程语法是编写设备驱动的基础。

此项无论对于初学者还是熟手重要程度:*****。

良好的linux操作系统概念

如:多进程、多线程、进程调度、进程抢占、进程上下文、虚拟内存、原子操作、阻塞、睡眠、同步等概念及它们之间的关系。

这些概念及方法在设备驱动的使用是linux设备驱动区别单片机编程的最大特点。只有理解了它们才会编写出高质量的驱动。

此项对于初学者来说:重要程度:***。开始可以以实现功能为目的,逐步完善自己的驱动。

掌握linux内核中设备驱动的编写接口

如:字符设备的cdev、块设备的gendisk、网络设备的net_device,以及基于这些基本接口的framebuffer设备的fb_info、mtd设备的mtd_info、tty设备的tty_driver、usb设备的usb_driver、mmc设备的mmc_host等

Linux内核为设备驱动编写者留下了标准的接口。驱动编写者无需精通内核的各个部分,只需要明确内核留给我们的接口,并实现此接口就可以了。内核流出的接口采用的是面向对象的思路,即把目标设备看成一个对象,通常利用一个结构体来描述这个对象。驱动工程师的任务就是实现这个对象。这个结构体中会包含设备的属性(用变量表示)和操作方法(用函数指针表示)。如:字符设备的cdev

struct cdev {
struct kobject kobj;
struct module *owner;
const struct file_operations *ops; //操作方法结合,其它项都是属性
struct list_head list;
dev_t dev;
unsigned int count;
};

此项对于初学者来说:重要程度:****。开始阶段可以以模仿为主,即套用一些固定的模板。

如何应对不断升级的内核

内核升级对驱动的影响主要体现在,(1)驱动接口定义的变化(2)内核的一些功能函数的名称、参数、头文件、宏定义的变化(3)平台代码关于硬件操作方面封装的一些函数的变化(4)设备模型的影响。下面探讨一下,如何应对这几个方面的问题:

驱动接口定义的变化

如:2.4内核中字符设备驱动的注册接口是

int register_chrdev(unsigned int major, const char * name, struct file_operations *fops)

而2.6内核中已经不建议使用这种方法了,改为:

int cdev_add(struct cdev *p, dev_t dev, unsigned count)

又如:2.6.27内核中网卡接口的net_device结构成员和低版本的net_device结构成员也发生了一些变化。

这种接口定义及注册方法带来的变化,发生的并不频繁。解决方案是:参考内核中的代码。这种接口定义及注册方法在内核中非常容易找到,如:字符设备驱动的注册方法及接口定义可以参照内核driver/char/目录下的很多实例。

内核的一些功能函数的名称、参数、头文件、宏定义的变化

如:中断注册函数的格式及参数在2.4内核、2.6内核低版本和高版本之间都存在差别

在2.6.8中,中断注册函数的定义为:

int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),unsigned long irq_flags, const char * devname, void *dev_id)

irq_flags的取值主要为下面的某一种或组合:

SA_INTERRUPT、SA_SAMPLE_RANDOM、SA_SHIRQ

在2.6.26中,中断注册函数的定义为:

int request_irq(unsigned int irq, irq_handler_t handler,unsigned long irqflags, const char *devname, void *dev_id)
typedef irqreturn_t (*irq_handler_t)(int, void *);

irq_flags的取值主要为下面的某一种或组合:(功能和2.6.8的对应)

IRQF_DISABLED、IRQF_SAMPLE_RANDOM、IRQF_SHARED

当出现这些问题时,编译过程中,编译器会给我们比较明确的错误提示,根据这些提示你可以判断出是否是缺少头问题、是否是函数参数定义有误等。解决问题的最好办法还是到你的目标内核中找信息。此时找问题的方法可以借助于搜索,如:你可以在新的内核中搜索request_irq,看新内核中的驱动是如何使用它的。这种方法非常有效。

平台代码关于硬件操作方面封装的一些函数的变化

内核中,硬件平台相关的代码在内核更新过程中变化比较频繁。和我们的设备驱动也是息息相关。所以在针对一个新内核编写设备驱动前,一定要熟悉你的平台代码的结构。有时平台虽然提供了内核要求的接口函数,但使用起来功能却并不完善。下面还是先举个例子说明平台代码更新对设备驱动的影响。

如:在linux-2.6.8内核中,调用set_irq_type(IRQ_EINT0, IRQT_FALLING);去设置S3C2410的IRQ_EINT0的中断触发信号类型,你会发现不会有什么效果。跟踪代码发现内核的set_irq_type函数需要平台提供一个针对硬件平台的实现函数

static struct irqchip s3c_irqext_chip = {
.mask = s3c_irqext_mask,
.unmask = s3c_irqext_unmask,
.ack = s3c_irqext_ack,
.type = s3c_irqext_type
};
s3c_irqext_type就是linux内核需要的实现函数而s3c_irqext_type在2.6.8中的实现为:
static int s3c_irqext_type(unsigned int irq, unsigned int type)
{
irqdbf("s3c_irqext_type: called for irq %d, type %d\n", irq, type);
return 0;
}

原来并没有实现。而在较高版本的内核,如2.6.26内核中,这个函数是实现了的。所以你一定要小心。当平台函数不好用时,一定要查查原因,或者直接操作硬件寄存器来达到目的。

2.6内核设备模型对驱动的影响

在2.6内核中写设备驱动和在2.4内核中有着很大的不同,就是在设备驱动中融入了比设备驱动本身结构还复杂,难以理解的设备模型。初学驱动时你可以不理会设备模型,但你会发现内核里的驱动代码基本上都是融入了设备模型的了。所以很多时候你不得不面对现实,还是要弄懂它,并且它也的注册方法也会随着内核的升级而发生变化。解决此类问题的最好方法还是参考目标内核驱动代码。

总结:

开始学习设备驱动时,选择一个当前比较流行的内核版本和硬件平台。不着急追赶最新潮流。这样你可以找到的网络资源会比较多,不至于有孤军奋战的感觉。我想这个过程应该不低于1年。当过了这个过程后,尝试将你编写过的驱动移植到各个目标平台上。上面的一些建议、和应对方法是本人的一些经验总结,仅供参考。 (作者:刘洪涛,华清远见嵌入式学院金牌讲师

分享到:
评论

相关推荐

    嵌入式系统/ARM技术中的面对不断升级的内核如何学习linux设备驱动

    本文想从以下3个方面探讨一下“面对不断升级的内核,如何学习linux设备驱动”。  内核发展的现状及其对技术人员的影响  Linux目前主要维护2.4和2.6两个内核版本。在http://www.kernel.org/ 网站上已经可 以下载...

    面对不断升级的内核,我们该如何学习LINUX设备驱动!

    随着内核的不断演进,开发者需要持续学习,跟上技术的步伐,才能在Linux驱动开发领域保持竞争力。同时,适应内核升级的策略也是必不可少的,这将有助于开发者在快速变化的技术环境中保持敏捷和高效。

    suse Linux内核升级.doc

    在学习SUSE Linux的过程中,用户往往需要面对各种挑战,尤其是内核的编译升级。内核升级不仅能够提升系统的稳定性和效率,还能确保系统拥有最新的安全补丁和硬件支持。 ##### (二)声卡和显卡驱动安装 1. **声卡...

    第八章 Linux设备管理和内核升级.docx

    Linux驱动程序的安装通常包括下载驱动源码,解压,编译生成目标文件,然后将其复制到内核模块目录,并使用modprobe或insmod命令加载到内核中。例如,安装D-link 530tx网卡驱动需要下载驱动包,解压,编译,然后将...

    嵌入式Linux的DiskOnChip设备驱动开发.docx

    在嵌入式Linux系统开发中,DiskOnChip设备驱动的开发是至关重要的,尤其是在面对对存储性能和功耗有严格要求的嵌入式系统。DiskOnChip是由M-systems公司推出的一种高性能、低功耗的闪存存储解决方案,它采用了Flash...

    信息安全技术:升级Linux内核.pptx

    本文将深入探讨如何在Linux环境中升级内核,以提升系统的安全性。 首先,为了获取非官方的最新主线内核,我们需要添加额外的软件仓库。ELRepo是一个为RHEL及其克隆如CentOS提供最新驱动和内核的第三方软件仓库。...

    linux内核情景分析

    而面对大数据和机器学习的工作负载,Linux内核也加强了高性能计算的能力。 总之,Linux内核不仅承载着Unix的精神,更是现代信息技术发展的重要基石。其开放性、灵活性和强大功能,使其成为推动科技创新和产业升级不...

    Linux安装的几点经验,驱动安装

    Linux内核通常对硬件支持良好,但某些较新的或者专有设备可能需要额外的驱动。例如: 1. **NVIDIA/AMD显卡**:NVIDIA和AMD的闭源驱动通常能提供更好的性能,需要手动下载并安装。 2. **无线网卡**:有些无线网卡可能...

    嵌入式Linux与现代模具加工数控设备(一).pdf

    总之,嵌入式Linux以其开源、实时性、稳定性和跨平台的特性,正在逐步渗透到现代模具加工数控设备的研发中,有望推动我国模具制造业的技术升级和市场竞争力的提升。未来,随着Linux技术的持续发展和优化,我们可以...

    cpci_hotplug_pci.rar_CPCI_CPCI hotplug_PCI driver linux

    虽然Linux内核提供了丰富的API和工具来支持热插拔,但在实际应用中,开发者仍需面对如设备兼容性、稳定性、性能优化等挑战。例如,不同硬件平台的热插拔控制器可能有不同的接口,驱动需要适配这些差异;同时,为保证...

    记录xdd的Linux嵌入式开发折腾过程.zip

    在Linux内核源码树中使用`make menuconfig`进行配置,选择需要的驱动程序、文件系统支持和网络协议栈。 4. **文件系统制作**:创建根文件系统,包括基础命令、库文件、配置文件等。可以使用 BusyBox 构建一个精简的...

    redhat linux无线网卡技术知识

    在Linux环境中,无线网卡的驱动支持往往依赖于内核版本以及具体的硬件设备。对于一些不被标准Linux内核所直接支持的无线网卡,用户可以利用`ndiswrapper`工具来实现驱动的安装。`ndiswrapper`是一个允许在Linux下...

    linux_V4L2.zip

    Linux V4L2,全称为Video for Linux Two,是Linux内核中用于处理视频输入/输出设备的一个框架。它是Video for Linux(V4L)的升级版本,旨在提供更强大、更灵活的功能,并且能够支持现代多媒体硬件。V4L2不仅适用于...

    超经典运维指南之Linux系统诊断.pdf

    Linux系统诊断是运维工作中的一个重要环节,尤其在面对云服务核心产品如阿里云ECS(Elastic Compute Service)时,对Linux系统的诊断处理能力尤为重要。本文档作为“超经典运维指南之Linux系统诊断.pdf”的一部分,...

    内核配置参考

    Linux 2.6 内核配置是系统管理员和开发者们经常面对的任务之一。正确的配置能够极大地提高系统的性能、稳定性和安全性。以下是对“内核配置参考”文档中的关键配置选项进行的详细解读。 ### 代码成熟度选项 ...

    行业分类-设备装置-启动内存库选择、BIOS、基于Intel的平台中的升级和危机恢复.zip

    在IT行业中,设备装置的管理和维护是至关重要的环节,尤其是涉及到系统启动、内存库选择、BIOS设置以及硬件平台的升级和危机恢复。本资料主要关注的是基于Intel平台的计算机系统,这些主题对于理解计算机底层操作和...

    xf86-video-ati-6.7.191.zip_显卡

    在使用xf86-video-ati驱动时,用户可能需要面对的问题包括硬件兼容性、驱动版本与内核版本匹配、性能优化以及错误调试等。通过查阅文档、社区论坛和开发人员的指南,这些问题通常能得到解决。同时,持续关注官方更新...

    藏经阁-ECS 运维指南 之 Linux 系统诊断-96页

    【藏经阁-ECS 运维指南 之 Linux 系统诊断】这本书是阿里云技术专家杨牧原的著作,旨在帮助读者深入了解Linux系统诊断,...通过阅读本书,读者可以学习到实用的故障诊断方法,提高自己在面对复杂运维挑战时的应对能力。

Global site tag (gtag.js) - Google Analytics