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

第17章 设备与模块

一、设备类型

1. Linux及Unix系统:

块设备

字符设备

网络设备

2.块设备:

通常缩写为blkdev,它是可寻址的,寻址以块为单位,块大小随设备不同而不同;块设备通常支持重定位操作,也就是对数据的随机访问。

块设备是通过称为“块设备节点”的特殊文件来访问的,井且通常被挂载为文件系统。

3.字符设备:

通常缩写为cdev,它是不可寻址的,仅提供数据的流式访问,就是一个个字符,或者一个个字节。

字符设备的例子有键盘、鼠标、打印机,还有大部分伪设备。字符设备是通过称为“字符设备节点”的特殊文件来访问的。与块设备不同,应用程序通过直接访问设备节点与字符设备交互。

4.网络设备:

最常见的类型有时也以以太网设备称呼,它提供了对网络〈例如Internet)的访问,这是通过-个物理适配器和一种特定的协议进行的

网络设备打破了Unix的“所有东西都是文件”的设计原则,它不是通过设备节点来访问,而是通过套接字API这样的特殊接口来访问。

5.伪设备:

大部分设备驱动是表示物理设备的,但并不是所有设备驱动都表示物理设备。有些设备驱动是虚拟的,仅提供访问内核功能而已。我们称为“伪设备”。

常见的如:

内核随机数发生器(通过/dev/random和/dev/urandom 访问)

空设备(通过/dev/null 访问)

零设备(通过/dev/zero 访问)

满设备(通过/dev/full 访问)

内存设备(通过/dev/mem 访问)

二、模块

1. 概述:

Linux 内核是模块化组成的,它允许内核在运行时动态地向其中插入或从中删除代码。这些代码(包括相关的子例程、数据、函数人口和函数出口)被一并组合在一个单独的二进制镜像中,即所谓的可装载内核模块中,或简称为模块。

支持模块的好处是基本内核镜像可以尽可能地小,因为可选的功能和驱动程序可以利用模块形式再提供。模块允许我们方便地删除和重新载入内核代码,也方便了调试工作。而且当热插拔新设备时,可通过命令载入新的驱动程序。

模块的所有初始化函数必须符合形式:int my _ init (void);

退出函数必须符合形式:void my_exit (void);

2.构建与安装

安装编译的模块: 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>中。

第19章 可移植性

一、可移植操作系统

有些操作系统在设计时把可移植性作为头等大事之一,尽可能减少涉及与机器相关的代码。汇编代码少之又少,这样做就是利用代码性能优化能力换取代码的可移植性。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.编写可移植性的代码需要考虑很多问题:字长、数据类型、填充、对齐、字节次序、符号、字节顺序、页大小以及处理器的加载/存储排序等。对于绝大多数的内核开发者来说,可能主要考虑的问题就是保证正确使用数据类型。

第20章 补丁,开发和社区

本章重点介绍了Linux编码风格:

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

20179203 《Linux内核原理与分析》第十周作业的相关文章

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

攥写人:李鹏举 学号:20179203 ( 原创作品转载请注明出处) ( 学习课程:<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ) 一.实验要求: 1.理解Linux系统中进程调度的时机,可以在内核代码中搜索schedule()函数,看都是哪里调用了schedule(),判断我们课程内容中的总结是否准确: 2.使用gdb跟踪分析一个schedule()函数 ,验证您对Linux系统进程调度与进程切换过程的理

20169217《Linux内核原理与分析》第二周作业

通过第二周的学习,我想把我的博客分为两部分,第一部分是实验楼linux内核分析实验一的实验报告,第二部分是看书第1,2,18章的内容和时间情况. 现在先说实验一 实验内容:将一段c语言程序反汇编成汇编程序. c语言程序代码:应实验要求我把其中部分数值进行了修改. int g(int x) { return x+6; } int f(int x) { return g(x); } int main(void) { return f(9)+3; } 实验过程: 首先创建一个main.c文件 将刚刚修

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

进程的切换和系统的一般执行过程 1.知识总结 (1)进程调度的时机: 中断处理过程直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule(). 内核线程是一个特殊的进程,只有内核态没有用户态,可以直接调用schedule()进行进程切换,也可以在中断处理过程中进行调度(内核线程可以直接访问内核函数,所以不会发生系统调用).内核线程作为一类的特殊的进程可以主动调度,也可以被动调度. 用户态进程无法实现主动调度,仅能在中断处理过程中进行调度(schedul

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

通过本周的学习,我更加具体的了解了计算机的工作原理,对于冯诺依曼体系结构主要为: (1)采用存储程序方式,指令和数据不加区别混合存储在同一个存储器中,(数据和程序在内存中是没有区别的,它们都是内存中的数据,当EIP指针指向哪 CPU就加载那段内存中的数据,如果是不正确的指令格式,CPU就会发生错误中断. 在现在CPU的保护模式中,每个内存段都有其描述符,这个描述符记录着这个内存段的访问权限(可读,可写,可执行).这就变相的指定了哪些内存中存储的是指令哪些是数据)指令和数据都可以送到运算器进行运算

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

一.学习笔记: 1.中断处理过程:包括时钟中断.I/O中断.系统调用和异常.直接调用schedule()函数,在队列中找到进程并分配CPU或返回用户态时根据need_resched标记调用schedule(). 2. 内核线程只有内核态没有用户态,可以直接调用schedule()进行进程之间的切换,也可以在中断处理过程中进行调度.用户态进程无法实现主动调度只能在中断处理过程中调度. 3.内核级别:ring0-3 4.进程上下文包含了进程执行所需要的信息 用户地址空间:包括程序代码,数据,用户堆栈

2017-2018-1 20179205《Linux内核原理与设计》第九周作业

<Linux内核原理与设计>第九周作业 视频学习及代码分析 一.进程调度时机与进程的切换 不同类型的进程有不同的调度需求,第一种分类:I/O-bound 会频繁的进程I/O,通常会花费很多时间等待I/O操作的完成:CPU-bound 是计算密集型,需要大量的CPU时间进行运算,使得其他交互式进程反应迟钝,因此需要不同的算法来使系统的运行更高效,以及CPU的资源最大限度的得到使用.第二种分类包括批处理进程(batch process):实时进程(real-time process)以及交互式进程

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

通过本周对Linux的学习,我对Linux的进程管理有了更加深入的了解大体来讲进程有五种状态,在五状态进程模型中,进程状态被分成下列五种状态.进程在运行过程中主要是在就绪.运行和阻塞三种状态间进行转换.创建状态和退出状态描述进程创建的过程和进程退出的过程. 1)运行状态(Running):进程占用处理器资源:处于此状态的进程的数目小于等于处理器的数目.在没有其他进程可以执行时(如所有进程都在阻塞状态),通常会自动执行系统的空闲进程. 2)就绪状态(Ready):进程已获得除处理器外的所需资源,等

《Linux内核原理与分析》教学进程

目录 2019-2020-1 <Linux内核原理与分析>教学进程 考核方案 第一周: 第二周: 第三周: 第四周: 第五周 第六周 第七周: 第八周 第九周 第十周 第十一周: 第十二周 第十三周 2019-2020-1 <Linux内核原理与分析>教学进程 考核方案 采取过程化考核,平时成绩占100分,成绩计算:30+30+15+25=100: 翻转课堂基础考核10次: 3*10 = 30 每次考试20-30道题目,考试成绩规格化成3分(比如总分30分就除以10) 翻转课堂测试

20169217 《Linux内核原理与分析》 课程总结

博客链接: 第一周作业 摘要:学习了实验楼linux基础入门课程. 第二周作业 摘要:实验楼实验一:反汇编一个简单的程序.书<linux内核设计与实现>:第1章,第2章,第18章内容. 第三周作业 摘要:自己对于为何要学习linux的感想. 第四周作业 摘要:实验二:分析精简内核源代码mymain.c和myinterrupt.c 书上第2章和第5章内容. 第五周作业 摘要:使用gdb跟踪调试内核从start_kernel到init进程启动 书上第4章和第6章内容. 第六周作业 摘要:使用库函数