代码改变世界

随笔分类 - Linux内核

DKMS简介

2011-06-21 23:33 by wwang, 26591 阅读, 收藏, 编辑
摘要:我们都知道,如果要使用没有集成到内核之中的Linux驱动程序需要手动编译。当然,这并不是一件什么难事,即使是对于没有编程经验的Linux使用者,只要稍微有点hacker的意识,努力看看代码包里的Readme或者INSTALL文件,按部就班的执行几条命令还是很容易办到的。但这里还有一个问题,Linux模块和内核是有依赖关系的,如果遇到因为发行版更新造成的内核版本的变动,之前编译的模块是无法继续使用的,我们只能手动再编译一遍。这样重复的操作有些繁琐且是反生产力的,而对于没有内核编程经验的使用者来说可能会造成一些困扰,使用者搞不清楚为什么更新系统之后,原来用的好好的驱动程序突然就不能用了。这里,就是 阅读全文

如何向Linux内核提交驱动

2011-04-01 00:00 by wwang, 6315 阅读, 收藏, 编辑
摘要:当Linux驱动程序开发到一定阶段,向kernel.org提交代码是一个很好的选择。对于很多没有向上游提交过代码的开发者来说,还是有很多疑问需要解决的。比如,究竟我们向哪里提交驱动程序?提交时我们的代码应该处于什么状态?提交的过程又如何呢? 阅读全文

小议Linux staging tree

2011-03-08 23:14 by wwang, 9299 阅读, 收藏, 编辑
摘要:很多人对staging tree建立的必要性有些疑问的,毕竟,在此之前我们已经有了linux-next tree。Greg对这些疑问解释到,staging tree只是收留新增的驱动程序和文件系统,并不接收对已有代码的修改补丁。因此可以说,Greg的staging tree在很大程度上分担了Stephen Rothwell身上的压力,但并不意味着linux-next tree的角色定位发生了变化。 阅读全文

谈谈Linux内核驱动的coding style

2011-02-24 00:07 by wwang, 12959 阅读, 收藏, 编辑
摘要:最近在向Linux内核提交一些驱动程序,在提交的过程中,发现自己的代码离Linux内核的coding style要求还是差很多。当初自己对内核文档里的CodingStyle一文只是粗略的浏览,真正写代码的时候在很多细节上会照顾不周。不过,在不遵守规则的程序员队伍里,我并不是孤独的。如果去看drivers/staging下的代码,就会发现很多驱动程序都没有严格遵守内核的coding style,而且在很多驱动程序的TODO文件里,都会把"checkpatch.pl fixes"作为自己的目标之一(checkpatch.pl是用来检查代码是否符合coding style的脚本) 阅读全文

Linux内核里的DebugFS

2011-01-17 23:52 by wwang, 36502 阅读, 收藏, 编辑
摘要:DebugFS,顾名思义,是一种用于内核调试的虚拟文件系统,内核开发者通过debugfs和用户空间交换数据。类似的虚拟文件系统还有procfs和sysfs等,这几种虚拟文件系统都并不实际存储在硬盘上,而是Linux内核运行起来后才建立起来。通常情况下,最常用的内核调试手段是printk。但printk并不是所有情况都好用,比如打印的数据可能过多,我们真正关心的数据在大量的输出里不是那么一目了然;或者我们在调试时可能需要修改某些内核变量,这种情况下printk就无能为力,而如果为了修改某个值重新编译内核或者驱动又过于低效,此时就需要一个临时的文件系统可以把我们需要关心的数据映射到用户空间。在过去 阅读全文

用make-kpkg简化Ubuntu系统的内核编译过程

2011-01-07 19:41 by wwang, 15645 阅读, 收藏, 编辑
摘要:本文介绍的make-kpkg可以用于所有Debian系的发行版如Debian、Ubuntu、Linux Mint等。传统编译方式通常,如果我们需要编译Linux内核,大概要经历以下几个步骤:1、配置内核最常用的配置内核的方法是“make menuconfig”。“make config”太简陋,“make xconfig”虽然更加直观,但需要庞大的qt类库支持,menuconfig应该是最佳的折中。2、编译内核和模块依次执行“make”、“make modules”、“make modules_install”、“make install”,如果前面的配置没有问题的话,耐心等待一段时间就可以得 阅读全文

Linux设备模型 (4)

2010-12-27 19:55 by wwang, 5465 阅读, 收藏, 编辑
摘要:《Linux设备模型 (2)》和《Linux设备模型 (3)》主要通过一些简单的实作介绍了kobject、kset、kobj_type、attribute等数据结构的用法,但这些实作并没有涉及到实际环境下的设备模型和sysfs。本文将以/sys下的module子目录为例,看看内核是如何构建sysfs这棵大树的。(注:本文的分析基于2.6.36内核)module的创建当module被insmod到内核空间时,/sys/module目录下会相应创建一个和模块同名的目录。我们以usb_storage为例,在执行完sudo modprobe usb_storage之后,sysfs里会产生一个名为usb 阅读全文

Linux设备模型 (3)

2010-12-21 19:51 by wwang, 12354 阅读, 收藏, 编辑
摘要:在上文中,我们介绍到如何使用default attribute。Default attribute使用很方便,但不够灵活。比如上篇文章在Kobject一节中提到的那个例子,name和val这两个attribute使用同一个show/store函数来访问,如果attribute非常多,show/store函数里的分支就会很凌乱。为了解决这个问题,我们可以参考内核提供的kobj_attribute。在内核里,kobj_attibute是这样定义的:每一个attribute会对应自己的show/store函数,这样就极大的提高了灵活性。可是,在上一篇文章中我们的认知是,sysfs是通过kobject 阅读全文

Linux设备模型 (2)

2010-12-16 00:11 by wwang, 9797 阅读, 收藏, 编辑
摘要:上一篇文章《Linux设备模型 (1)》主要介绍了Linux设备模型在用户空间的接口sysfs,用户通过这个接口可以一览内核设备的全貌。本文将从Linux内核的角度来看一看这个设备模型是如何构建的。在Linux内核里,kobject是组成Linux设备模型的基础,一个kobject对应sysfs里的一个目录。从面向对象的角度来说,kobject可以看作是所有设备对象的基类,因为C语言并没有面向对象的语法,所以一般是把kobject内嵌到其他结构体里来实现类似的作用,这里的其他结构体可以看作是kobject的派生类。Kobject为Linux设备模型提供了很多有用的功能,比如引用计数,接口抽象, 阅读全文

Linux设备模型 (1)

2010-12-09 00:21 by wwang, 13793 阅读, 收藏, 编辑
摘要:随着计算机的周边外设越来越丰富,设备管理已经成为现代操作系统的一项重要任务,这对于Linux来说也是同样的情况。每次Linux内核新版本的发布,都会伴随着一批设备驱动进入内核。在Linux内核里,驱动程序的代码量占有了相当大的比重。下图是我在网络上搜索到的一幅Linux内核代码量的统计图,对应的内核版本是2.6.29。我们可以很明显的看到,在Linux内核中驱动程序的比例已经非常高了。Linux 2.6内核最初为了应付电源管理的需要,提出了一个设备模型来管理所有的设备。在物理上,外设之间是有一种层次关系的,比如把一个U盘插到笔记本上,实际上这个U盘是接在一个USB Hub上,USB Hub又是 阅读全文

Linux内核里的“智能指针” (续)

2010-12-03 22:13 by wwang, 4312 阅读, 收藏, 编辑
摘要:在上一篇文章《Linux内核里的智能指针》里介绍了Linux内核如何使用引用计数来更加安全的管理内存,本文承接前篇,主要介绍几点使用kref时的注意事项。Linux内核文档kref.txt罗列了三条规则,我们在使用kref时必须遵守。规则一:If you make a non-temporary copy of a pointer, especially if it can be passed to another thread of execution, you must increment the refcount with kref_get() before passing it off 阅读全文

Linux内核里的“智能指针”

2010-12-02 22:22 by wwang, 16739 阅读, 收藏, 编辑
摘要:众所周知,C/C++语言本身并不支持垃圾回收机制,虽然语言本身具有极高的灵活性,但是当遇到大型的项目时,繁琐的内存管理往往让人痛苦异常。现代的C/C++类库一般会提供智能指针来作为内存管理的折中方案,比如STL的auto_ptr,Boost的Smart_ptr库,QT的QPointer家族,甚至是基于C语言构建的GTK+也通过引用计数来实现类似的功能。Linux内核是如何解决这个问题呢?同样作为C语言的解决方案,Linux内核采用的也是引用计数的方式。如果您更熟悉C++,可以把它类比为Boost的shared_ptr,或者是QT的QSharedPointer。在Linux内核里,引用计数是通过 阅读全文

Ubuntu的内核转储工具

2010-11-19 22:02 by wwang, 8528 阅读, 收藏, 编辑
摘要:在我的上一篇博文《Linux内核的Oops》的最后介绍到一个Linux内核转储工具Kdump,这个工具可以在发生kernel panic时把现场dump到一个文件里,以供后续分析之用。本文主要介绍在Ubuntu下如何使用kdump。Kdump是一个通用的Linux内核转储工具,详细的用法说明可以参考这篇Kdump Tutorial。这篇教程洋洋洒洒几十页(链接里有pdf文件可以下载),详细介绍了内... 阅读全文

Linux内核的Oops

2010-11-14 23:13 by wwang, 49054 阅读, 收藏, 编辑
摘要:什么是Oops?从语言学的角度说,Oops应该是一个拟声词。当出了点小事故,或者做了比较尴尬的事之后,你可以说"Oops",翻译成中国话就叫做“哎呦”。“哎呦,对不起,对不起,我真不是故意打碎您的杯子的”。看,Oops就是这个意思。在Linux内核开发中的Oops是什么呢?其实,它和上面的解释也没什么本质的差别,只不过说话的主角变成了Linux。当某... 阅读全文

制作initramfs/initrd镜像

2010-10-27 10:22 by wwang, 24565 阅读, 收藏, 编辑
摘要:Linux kernel在自身初始化完成之后,需要能够找到并运行第一个用户程序(这个程序通常叫做“init”程序)。用户程序存在于文件系统之中,因此,内核必须找到并挂载一个文件系统才可以成功完成系统的引导过程。在grub中提供了一个选项“root=”用来指定第一个文件系统,但随着硬件的发展,很多情况下这个文件系统也许是存放在USB设备,SCSI设备等等多种多样的设备之上,如果需要正确引导,USB或者SCSI驱动模块首先需要运行起来,可是不巧的是,这些驱动程序也是存放在文件系统里,因此会形成一个悖论。为解决此问题,Linux kernel提出了一个RAM disk的解决方案,把一些启动所必须的用 阅读全文

Linux中的工作队列

2010-10-27 10:09 by wwang, 32414 阅读, 收藏, 编辑
摘要:工作队列(work queue)是Linux kernel中将工作推后执行的一种机制。这种机制和BH或Tasklets不同之处在于工作队列是把推后的工作交由一个内核线程去执行,因此工作队列的优势就在于它允许重新调度甚至睡眠。工作队列是2.6内核开始引入的机制,在2.6.20之后,工作队列的数据结构发生了一些变化,因此本文分成两个部分对2.6.20之前和之后的版本分别做介绍。I、2.6.0~2.6.... 阅读全文