代码改变世界

2017-2018-1 20179226《Linux内核原理与分析》第十周作业

2017-12-03 21:11  20179226任逸飞  阅读(171)  评论(0编辑  收藏  举报

阅读教材17、19、20章

第17章 设备与模块

1.关于设备驱动和设备管理,讨论四种内核成分。
1)设备类型:在所有的linux系统中为了统一普遍设备的操作所分的类。
2)模块:Linux内核中用于按需加载和卸载目标码的机制。
3)内核对象:内核数据机构中支持面向对象的简单操作,还支持维护对象间的父子关系。
4)sysfs:表示系统中设备树的一个文件系统
2.Unix系统中,设备被分为三类
1)块设备:通常缩写为blkdev,它是可寻址的,寻址以块为单位,块大小随设备不同而不同;通常支持重定位操作,也就是对数据的随机访问。
2)字符设备:通常缩写为cdev,它是不可寻址的,仅提供数据的流式访问。
3)网络设备:最常见的类型有时也以以太网设备来称呼,他提供了对网络的访问,这是通过一个物理适配器和一种特定的协议进行的。网络设备是通过套接字API这样的特殊接口来访问的。
3.并不是所有设备驱动都表示物理设备。有些设备驱动是虚拟的,仅提供访问内核功能而已,我们称为“伪设备”
4.Linux内核是模块化组成的,它允许内核在运行时动态地向其中插入或删除代码。这些代码被一并组合在一个单独的二进制镜像中,称为模块。支持模块的好处是基本内核镜像可以尽可能的小,因为可选的功能和驱动程序可以利用模块形式再提供。模块允许我们方便地删除和重新载入内核代码,也方便了调试工作。
5.内核模块Hello,World中,hello_init()函数是模块的入口点,调用module_init()实际上不是真正的函数调用。hello_exit()函数是模块的出口函数。
6.构建模块第一步是决定在哪里管理模块源码,可以把模块源码加入到内核源代码树中,也可以在内核源代码树之外维护和构建你的模块源码。
7.载入模块最简单的方法是通过insmod命令,类似的卸载一个模块可以使用rmmod命令。modprobe命令不但会加载指定的模块而且会自动加载任何它所依赖的有关模块。参数modules指定一个或多个需要卸载的模块。
8.定义一个模块参数可通过宏module_param()完成:module_param(name,type,perm);参数name是参数名,参数type则存放了参数的类型,参数perm指定了模块在sysfs文件系统下对应文件的权限。
9.设备类型提供了一个独立的机制专门来表示设备,并描述其在系统中的拓扑结构。
10.设备模型的核心部分就是kobject,类似于c#或Java这些面向对象语言中的对象类,提供了诸如引用计数、名称和父指针等字段,可以创建对象的层次结构。
12.kobject对象被关联到一种特殊的类型,即ktype。ktype的存在是为了描述一族kobject所具有的普遍特性。如此一来,不再需要每个kobject都分别定义自己的特性,而是将这些普遍特性在ktype结构中一次定义,然后所有同类的kobject都能共享一样的特性。
13.kset是kobject对象的集合体。kset可把kobject集中到一个集合中,而ktype描述相关类型kobject所共有的特性,它们之间的重要区别在于:具有相同的ktype的kobject可以被分组到不同的kset。就是说,在Linux内核中,只有少数的ktype,却有多个kset。
14.kobject的主要功能之一就是为我们提供了一个统一的引用计数系统,增加引用计数称为获得(getting)对象的引用,减少引用计数称为释放(putting)对象的引用。
15.sys文件系统是一个处于内存中的虚拟文件系统,它为我们提供了kobject对象层次结构的视图。sysfs的诀窍是把kobject对象与目录项紧密联系起来,这点是通过kobject对象中的denty字段实现的。
16.为了保持sysfs干净和直观,开发者必须遵从以下约定:首先sysfs属性应该保证每个文件只导出一个值,该值应该是文本形式而且映射为简单C类型。其次在sysfs中要以一个清晰的层次组织数据。最后记住sysfs提供内核到用户空间的服务,这多少有些用户空间的ABI的作用。

第19章 可移植性

1.关于字长和数据类型的一些准则:
1)ANSIC标准规定,一个char的长度一定是1字节
2)尽管没有规定int类型的长度是32位,但在Linux当前支持的体系结构中,它都是32位的。
3)short类型也类似,在当前所有支持的体系结构中,虽然没有明文规定,但是它都是16位的。
4)绝对不应该假定指针和long的长度,在linux当前支持的体系结构中,它们可以在32位和64位中变化。
5)对于不同的体系结构long的长度不同,决不应该假设sizeof(int)=sizeof(long)。
6)类似的,也不要假设指针和int长度相等。
2.要想写出移植性好、简洁、合适的内核代码,要注意以下两点:
1)编码尽量选取最大公因子:假定任何事情都可能发生,任何潜在的约束都可能存在。
2)编码尽量选取最小公约数:不要假定给定的内核特性是可用的,仅仅需要最小的体系结构功能。
3.编写可移植性的代码需要考虑很多问题:字长、数据类型、填充、对齐、字节次序、符号、字节顺序、页大小以及处理器的加载/存储排序等。对于绝大多数的内核开发者来说,可能主要考虑的问题就是保证正确使用数据类型

第20章 补丁,开发和社区

1.Linux编码风格:
1)缩进——缩进风格是用制表位每次缩进8个字符长度。
2)switch语句——switch语句下属的case标记应该缩进到和switch声明对齐,这样有助于减少8个字符的tab键带来的排版缩进。
3)空格——Linux编码风格规定,空格放在关键字周围,函数名和圆括号之间无空格。
4)花括号——内核选定的风格是左括号紧跟在语句的最后,与语句在相同的一行。而右括号要新起一行,作为该行的第一个字符。
5)每行代码的长度——源代码中要尽可能地保证每行代码长度不超过80个字符,因为这样做可能使代码最合适在标准的80*24的终端上显示。
6)命名规范——命名中不允许使用骆驼拼写法、Studly Caps或者其他混合的大小写字符。
7)函数——根据经验,函数的代码长度不应该超过两屏,局部变量不应超过10个。一个函数应该功能单一而且实现精确。
8)注释——一般情况下应该描述的是你的代码要做什么和为什么要这样做,而不是具体通过什么方式实现的。
9)typedef——使用typedef要谨慎,只有在确实需要的时候再使用它。
10)多用现成的东西——请勿闭门造车。内核本身就提供了字符串操作函数,压缩函数和一个链表接口,所以请使用他们。
11)在源码中减少使用ifdef——不赞成在源码中使用ifdef预处理指令。
12)结构初始化——结构初始化的时候必须在他的成员前加上结构标识符。
13)代码的事后修正——indent是一个在大多数Linux系统中都能找到的好工具,它可以按照指定的方式对源代码进行格式化。