20169203《Linux内核原理与分析》第十一周作业

本周主要是对课本的学习
关于设备驱动和设备管理,讨论四种内核成分。
设备类型:在所有的linux系统中为了统一普遍设备的操作所分的类。
模块:Linux内核中用于按需加载和卸载目标码的机制。
内核对象:内核数据机构中支持面向对象的简单操作,还支持维护对象间的父子关系。
sysfs:表示系统中设备树的一个文件系统
对于设备类型主要有三中类型
字符设备:
字符(char)设备是个能够像字节流(类似文件)一样被访问的设备,由字符设备驱动程序来实现这种特性。字符设备驱动程序通常至少要实现open、close、read和write的系统调用。字符终端(/dev/console)和串口(/dev/ttyS0以及类似设备)就是两个字符设备,它们能很好的说明“流”这种抽象概念。字符设备可以通过FS节点来访问,比如/dev/tty1和/dev/lp0等。这些设备文件和普通文件之间的唯一差别在于对普通文件的访问可以前后移动访问位置,而大多数字符设备是一个只能顺序访问的数据通道。然而,也存在具有数据区特性的字符设备,访问它们时可前后移动访问位置。例如framebuffer就是这样的一个设备,app可以用mmap或lseek访问抓取的整个图像。

块设备:
和字符设备类似,块设备也是通过/dev目录下的文件系统节点来访问。块设备(例如磁盘)上能够容纳filesystem。在大多数的Unix系统中,进行I/O操作时块设备每次只能传输一个或多个完整的块,而每块包含512字节(或2的更高次幂字节的数据)。Linux可以让app像字符设备一样地读写块设备,允许一次传递任意多字节的数据。因此,块设备和字符设备的区别仅仅在于内核内部管理数据的方式,也就是内核及驱动程序之间的软件接口,而这些不同对用户来讲是透明的。在内核中,和字符驱动程序相比,块驱动程序具有完全不同的接口。

网络设备:
任何网络事物都需要经过一个网络接口形成,网络接口是一个能够和其他主机交换数据的设备。接口通常是一个硬件设备,但也可能是个纯软件设备,比如回环(loopback)接口。网络接口由内核中的网络子系统驱动,负责发送和接收数据包。许多网络连接(尤其是使用TCP协议的连接)是面向流的,但网络设备却围绕数据包的传送和接收而设计。网络驱动程序不需要知道各个连接的相关信息,它只要处理数据包即可。由于不是面向流的设备,因此将网络接口映射到filesystem中的节点(比如/dev/tty1)比较困难。Unix访问网络接口的方法仍然是给它们分配一个唯一的名字(比如eth0),但这个名字在filesystem中不存在对应的节点。内核和网络设备驱动程序间的通信,完全不同于内核和字符以及块驱动程序之间的通信,内核调用一套和数据包相关的函数而不是read、write等。
关于模块
传统的用户程序需要编译为可执行程序才能执行,而模块程序只需要编译为目标文件的形式便可以加载到内核,有内核实现模块的链接,将之转化为可执行代码。同时,在内核加载和卸载的过程中,会通过函数回调用户定义的模块入口函数和模块出口函数,实现相应的功能。
设备模型
设备模型的核心部分就是kobject,类似于c#或Java这些面向对象语言中的对象类,提供了诸如引用计数、名称和父指针等字段,可以创建对象的层次结构。
kobject对象被关联到一种特殊的类型,即ktype。ktype的存在是为了描述一族kobject所具有的普遍特性。如此一来,不再需要每个kobject都分别定义自己的特性,而是将这些普遍特性在ktype结构中一次定义,然后所有同类的kobject都能共享一样的特性。
kset是kobject对象的集合体。kset可把kobject集中到一个集合中,而ktype描述相关类型kobject所共有的特性,它们之间的重要区别在于:具有相同的ktype的kobject可以被分组到不同的kset。就是说,在Linux内核中,只有少数的ktype,却有多个kset。
sysfs
sys文件系统是一个处于内存中的虚拟文件系统,它为我们提供了kobject对象层次结构的视图。sysfs的诀窍是把kobject对象与目录项紧密联系起来,这点是通过kobject对象中的denty字段实现的。
对于Linux的可移植性
可移植操作系统指可运行在不同计算机上的操作系统。95%以上的Linux操作系统都是用C语言编写的。由于C语言是一种与计算机无关的高级语言,因此它是可移植的(C编译器用C语言编写),因而Linux操作系统也是可移植的。
因为Linux可移植,所以它适用于(被移植到)不同的计算机,而且可以满足某些特殊需求。例如,Linux可应用在手机、PDA和电视机顶盒等许多嵌入式系统中。它的文件结构可以充分利用大容量的快速硬盘。同时,Linux最初就是作为多用户操作系统设计的,而不是通过后来修改才支持多用户的。在多个用户之间共享计算机的功能,从而使他们能够共享数据和程序是Linux操作系统的关键特性。
因为Linux适应性好,并且能充分利用现有的硬件,所以Linux运行在大量不同的基于微处理器的系统上,包括在大型机上。基于微处理器硬件的流行推动了Linux的发展;而且微处理器在保持价格基本不变的情况下,速度正变得越来越快。Linux适用于那些不愿意为使用某些供应商的硬件而去学习一种新操作系统的用户,也适用于那些喜欢软件环境一致的系统管理员。
要想写出移植性好、简洁、合适的内核代码,要注意以下两点:
编码尽量选取最大公因子:假定任何事情都可能发生,任何潜在的约束都可能存在。
编码尽量选取最小公约数:不要假定给定的内核特性是可用的,仅仅需要最小的体系结构功能。
编写可移植性的代码需要考虑很多问题:字长、数据类型、填充、对齐、字节次序、符号、字节顺序、页大小以及处理器的加载/存储排序等。对于绝大多数的内核开发者来说,可能主要考虑的问题就是保证正确使用数据类型。
inux的最大优势就是它有一个紧密团结了众多使用者和开发者的社区。社区能帮你检查代码,社区的专家给你提出忠告,社区中的用户能帮你进行测试,用户还能反馈存在的问题。
Linux的编码风格
1.缩进--缩进风格是用制表位每次缩进8个字符长度。

2.switch语句--switch语句下属的case标记应该缩进到和switch声明对齐,这样有助于减少8个字符的tab键带来的排版缩进。

3.空格--Linux编码风格规定,空格放在关键字周围,函数名和圆括号之间无空格。

4.花括号--内核选定的风格是左括号紧跟在语句的最后,与语句在相同的一行。

5.每行代码的长度--源代码中要尽可能地保证每行代码长度不超过80个字符,因为这样做可能使代码最合适在标准的80*24的终端上显示。

6.命名规范--命名中不允许使用骆驼拼写法、studly caps或者其他混合的大小写字符。

8.函数--根据经验,函数的代码长度不应该超过两屏,局部变量不应超过10个。

9.注释--代码的注释非常重要,但注释必须按照正确的方式进行。

10.typedef--内核的开发者们强烈反对使用typedef语句。

11.多用现成的东西--请勿闭门造车。内核本身就提供了字符串操作函数,压缩函数和一个链表接口,所以请使用他们。

12.在源码中减少使用ifdef--我们不赞成在源码中使用ifdef预处理指令。

13.结构初始化--结构初始化的时候必须在他的成员前加上结构标识符。

14.代码的事后修正--即使你得到了一段与内核编码风格风马牛不相及的代码,也不用发愁。只消抬抬手,indent工具就能帮你解决它。
对于实验部分在http://www.cnblogs.com/littletang/p/6123918.html中

posted @ 2016-12-04 19:42  李学生  阅读(136)  评论(0编辑  收藏  举报