标签:eof 计时 串操作 操作 /dev/null 因子 root 依赖 核心
块设备
字符设备
网络设备
通常缩写为blkdev,它是可寻址的,寻址以块为单位,块大小随设备不同而不同;块设备通常支持重定位操作,也就是对数据的随机访问。
块设备是通过称为“块设备节点”的特殊文件来访问的,井且通常被挂载为文件系统。
通常缩写为cdev,它是不可寻址的,仅提供数据的流式访问,就是一个个字符,或者一个个字节。
字符设备的例子有键盘、鼠标、打印机,还有大部分伪设备。字符设备是通过称为“字符设备节点”的特殊文件来访问的。与块设备不同,应用程序通过直接访问设备节点与字符设备交互。
最常见的类型有时也以以太网设备称呼,它提供了对网络〈例如Internet)的访问,这是通过-个物理适配器和一种特定的协议进行的
网络设备打破了Unix的“所有东西都是文件”的设计原则,它不是通过设备节点来访问,而是通过套接字API这样的特殊接口来访问。
大部分设备驱动是表示物理设备的,但并不是所有设备驱动都表示物理设备。有些设备驱动是虚拟的,仅提供访问内核功能而已。我们称为“伪设备”。
常见的如:
内核随机数发生器(通过/dev/random和/dev/urandom 访问)
空设备(通过/dev/null 访问)
零设备(通过/dev/zero 访问)
满设备(通过/dev/full 访问)
内存设备(通过/dev/mem 访问)
Linux 内核是模块化组成的,它允许内核在运行时动态地向其中插入或从中删除代码。这些代码(包括相关的子例程、数据、函数人口和函数出口)被一并组合在一个单独的二进制镜像中,即所谓的可装载内核模块中,或简称为模块。
支持模块的好处是基本内核镜像可以尽可能地小,因为可选的功能和驱动程序可以利用模块形式再提供。模块允许我们方便地删除和重新载入内核代码,也方便了调试工作。而且当热插拔新设备时,可通过命令载入新的驱动程序。
模块的所有初始化函数必须符合形式:int my _ init (void);
退出函数必须符合形式:void my_exit (void);
安装编译的模块: make modules_install
产生依赖关系信息,而且在每次启动时更新。
产生内核依赖关系的信息,root用户可运行命令:depmod
只为新模块生成依赖信息,不生成所有的依赖关系,root用户可运行命令:depmod -A
模块依赖关系信息存放在/lib/modules/version/modules.dep文件中。
载入,root用户可运行命令:insmod module .ko
在内核via modprobe中插入模块,root用户可运行命令:zmodprobe module[module parameters] (参数 module 指定了需要载入的模块各称)。
从内核中卸载模块,root用户可运行命令:modprobe -r modules
1.kobject:
设备模型的核心部分。其中struct kobject 结构体表示,定义于头文件<linux/k,ρ1lij四t.b>中。通常是嵌入其他结构中的。
2.ktype:
kobject 对象被关联到一种特殊的类型:ktype。由kobj_type 结构体表示,定义于头文件<linux/kobject.h>中。为了描述一族kobject 所具有的普遍特性。
3.kset:
在Linux 内核中,只有少数一些的ktype,却有多个kset。由kset 结构体表示,定义于头文件<linux/kobject.h>中:
4.kobject、ktype、kset关系:
kobject,让那些包含它的结构具有了kobject 的特性。ktype 定义了一些kobject 相关的默认特性。kset 提供了两个功能:第一,其中嵌入的kobj创作为kobject 组的基类。第二, kset 将相关的kobject 集合在一起。
5.管理和操作kobject:
kobject 通过函数koject_init 进行初始化,该函数定义在文件<linux/kobject.h>中:void kobject_init(struct kobject kobj, struct kobj_type ktype);第一个参数就是需要初始化的kobject 对象;调用初始化函数前, kobject 必须清空;未被清空,调用memset() 即可:memset(kobj, 0, sizeof (*kobj ) );应该调用kobject_createO 创建koject。
6.计数:
kobject的主要功能:提供了一个统一的引用计数系统。初始化后,kobject的引用计数设置为1;引用计数不为零,该对象就会继续保留在内存中。引用计数跌到零时,对象可被撤销,相关内存也被释放。koject 的引用计数是通过kref结构体实现,该结构体定义在头文件<linux/kref.h>中。
有些操作系统在设计时把可移植性作为头等大事之一,尽可能减少涉及与机器相关的代码。汇编代码少之又少,这样做就是利用代码性能优化能力换取代码的可移植性。Minix,NetBSD和许多研究用的系统就是这种高度可移植的操作系统。
还有一些操作系统完全不顾及可移植性,尽最大可能追求代码的性能表现,尽可能多的使用汇编代码,这样就是利用代码的可移植性换取代码的性能优化能力。这样的系统比可移植的系统更难维护。DOS和Windows95就是这样的操作系统。
ANSIC标准规定,一个char的长度一定是1字节;尽管没有规定int类型的长度是32位,但在Linux当前支持的体系结构中,它都是32位的。short类型也类似,在当前所有支持的体系结构中,虽然没有明文规定,但是它都是16位的。绝对不应该假定指针和long的长度,在linux当前支持的体系结构中,它们可以在32位和64位中变化。对于不同的体系结构long的长度不同,决不应该假设sizeof(int)=sizeof(long)。类似的,也不要假设指针和int长度相等。
要想写出移植性好、简洁、合适的内核代码,要注意以下两点:
1.编码尽量选取最大公因子:假定任何事情都可能发生,任何潜在的约束都可能存在。编码尽量选取最小公约数:不要假定给定的内核特性是可用的,仅仅需要最小的体系结构功能。
2.编写可移植性的代码需要考虑很多问题:字长、数据类型、填充、对齐、字节次序、符号、字节顺序、页大小以及处理器的加载/存储排序等。对于绝大多数的内核开发者来说,可能主要考虑的问题就是保证正确使用数据类型。
本章重点介绍了Linux编码风格:
标签:eof 计时 串操作 操作 /dev/null 因子 root 依赖 核心
原文地址:http://www.cnblogs.com/20179203li/p/7931398.html