当前课程知识点:Linux 内核分析与应用 > 第1章 概述 > 1.2 Linux内核结构以及内核模块编程 > Video
大家好 我们今天来介绍一下Linux的内核结构
以及内核模块的编程
呢么首先我们来看一下单内核与微内核结构
我们说Linux操作系统是一个单内核的结构
什么是单内核呢也就是说
操作系统的各个子系统比如说文件系统
内存管理 进程管理以及网络系统
进程通信它们互相之间可以直接调用
什么是微内核呢 也就是说
只有一些核心的
代码它放在微内核里头比如说
核心的进程间通信中断以及调度程序放在微内核
而其他的像这种文件系统内存管理呢可能以
服务器的方式放在外部
所以单内核和微内核在业界一直有争议的
那么它们各自有各自的特点
单内核因为它各个子系统之间可以直接调用
所以它的性能就比较高
但是它的可维护性比较差
而微内核的内核
与服务器之间是一种通信的关系
比如说当要发出一个请求的时候文件系统
可能要跟微内核进行通信
而这个通信是有代价的 所以微内核的效率比较低
但是因为这种架构各个服务器之间
它的可维护性比较好
前业界比如说Minix系统 QNX
L4
谷歌的最新的Fuchsia操作系统它们都是微内核
但是我们主要来讲Linux的单内核的结构
当我们了解Linux的内核的时候 我们直接进入源代码
在这里我们有一个Linux内核源码的目录结构
前面介绍的时候介绍过内存管理
在这个目录下 我们看到有MM的目录 在该目录下就存放的是
内存管理的代码
介绍过文件系统 那么看这个fs目录下
它存放的就是所有文件系统的代码
那么我们介绍过进程间的通信IPC 这个目录下存放的是
进程间通信的代码还有驱动程序还有
其他等等的代码它们都是以
各自目录的形式存放在它的目录下
那么通过这个源代码的结构呢
我们可以了解到Linux内核它的的确确是一个单内核的结构
我们在介绍Linux内核结构的时候说到
单内核的模块它有一个缺点什么样的缺点呢就是它的可维护性比较差
那么当我们想增加一个新的功能 比如说你要写一个驱动程序
写一个文件系统的时候怎么样才能够融入到内核里头
因为Linux内核现在非常的庞大 要编译一次内核要花很长的时间
能不能有一种办法让我们写的代码呢
不需要完全和Linux内核捆绑在一起
所以Linux内核提供了一种机制叫做
可加载的Linux内核模块
呢么所谓可加载的Linux内核模块是什么意思
就是说在Linux内核运行的过程中呢
可以把这个模块加载进Linux内核
当我不需要这个模块的时候 即使Linux内核在运行 我们可以把这个模块呢
取下来 就叫做卸载
如何来编写Linux内核模块呢
我们编写一个helloworld这样一个简单程序一样
我们来看一下如何进行入门
那么在我们普通用户下
我们要想输出的话用一条语句叫printf
printf那么在Linux内核下还能不能用printf这个函数 那告诉大家
不能再用了为什么 我们现在已经进入到Linux内核编程了
完全进入一个不同的世界了
你再不能使用我们的库函数了
而必须使用Linux内核的源代码
所以在这里 我们的printf函数呢
就换为叫printk k就是kernel的意思
那么这个时候我们想输出 输出到什么地方内核它是没有显示终端的
所以它的输出就输出到日志文件里头
那这个printk这个函数包含在哪个头文件里头呢
它有一个头文件叫kernel.h
所以我们在这里想写一个Linux内核模块
我们第一个要认识的函数就是printk
在这里我们看到这个函数 名字叫lkp_init
这个名字其实叫模块的初始化函数
关于这个函数的名字呢你完全可以自己来取
你可以取成任何一个名字
但是这个函数它所起的作用是叫做模块的入口函数
那么既然有入口就要有出口 我们看另外一个函数叫lkp_exit函数
那么这个函数它就相当于当我们卸载模块的时候 这个函数才执行
那么在这个简单的模块里头呢
我们还看到了一些代码
那么什么样的代码 我们看下面最后有两条语句叫module_init
它是什么意思 就是说我要来调用
这个初始化的函数 它的参数是一个函数名
那么这个函数它放在哪一个头文件里 我们看有一个module.h头文件
这里还有两个不认识的东西就是__init
那么这个呢叫做编译的修饰符
它是什么意思呢它告诉编译程序
那么这个__init修饰符起什么样的作用 它是告诉编译程序
当这个模块执行完后把这个内存空间回收回来
所以这两个函数它到底什么时候执行呢 那么
当我们给大家演示到模块插入进来的时候它执行的是
初始化的函数 当模块卸载的时候它执行的是退出函数
那么我们知道Linux模块它其实不是一个独立的可执行文件
那么是在内核运行期间它可以插入到内核中的
而且只有超级用户才能加载和卸载内核模块
那么如何编译内核模块呢我们不能用一般的编译方法
那么我们必须写一个Makefile文件
这个文件怎么样去写 其实是比较有讲究的
但是呢其实它的核心思想呢
是告诉编译程序我那些头文件都放在哪个地方
在这个文件里面我们看我们定义了三个变量 一个呢就是路径的变量
那么它指明我们的当前的路径是什么
第二个变量指明我们内核的它的版本号
那么第三个变量就指的我们的内核源代码所在的路径
这里给大家特别的强调 在编译Linux内核的时候
你一定要知道你在哪一个系统下 我们这种格式指的是在ubuntu下
如果你用的其他的系统的时候呢 在这里头就要特别的注意
所以Linux内核模块编译的时候是最容易出错的地方
Makefile格式也有严格的限定
一定要按教材上给大家说的详细的步骤来做
当我们把这个Linux内核模块编译好以后 就可以把它插入到内核里面去
那么如何进行插入呢 我们要以超级用户的权限来进行插入
insmod后面是我们模块形成的这个
.ko文件,模块名加.ko就可以插入进去
那么当我们不使用的时候可以把它卸载
用哪个命令可以卸载rmmod
后面跟我们模块的名字就可以把它卸载掉
当我们写一个Linux内核模块的时候 实际上我们在Linux内核态下编程
那么这与普通用户的编程到底有什么样的差别
有这么几个方面的差别 第一个我们使用的函数库是不一样的
在C语言里头用的是libc库 而模块中用的是内核的函数
那么它运行的空间也是不一样的 我们的模块运行在内核的空间
而我们的普通程序运行在用户的空间
权限也不一样当我们插入Linux内核模块一定要用root权限
入口函数和出口函数也是不一样的
编译链接运行调试都不一样
这个详细的内容通过这个表就可以看到
在这里就特别要强调是什么呢当我们进入到Linux内核的时候
我们相当于进了完全不同的一个世界了
虽然我们在用户态下编程的一些经验是可以用的 但是有很大的差异性
这个时候我们一定要对Linux内核的源代码逐渐的熟悉
前面给大家介绍了Linux内核的模块
那么你要自己真正的感觉Linux内核模块的话必须自己来动手
Linux内核模块的编写呢刚才说了它是和用户态下是很不一样的
所以说呢我们一定要严格先按我们介绍的步骤呢
写一个最简单的helloworld这样一个Linux内核模块
那么在这个基础上可以增加你的想象力
在初始化函数里可以增加一个比如说求最大数
那么当把这个模块插入到内核的时候呢 实际上你就已经第一步踏入的内核的世界
今天的讲座呢我们就讲到这里 谢谢大家
-1.1 Linux操作系统概述
-1.2 Linux内核结构以及内核模块编程
--Video
-1.3 Linux内核源码中的双链表结构
--Video
-1.4 源码分析-内核中的哈希表
--Video
-1.5 动手实践-Linux内核模块的插入和删除
--Video
-第1章 概述--章节测验
-2.1 内存管理之内存寻址
--Video
-2.2 段机制
--Video
-2.3分页机制
--Video
-2.4 动手实践-把虚拟地址转换成物理地址
--Video
-第2章 内存寻址--章节测验
-3.1 进程概述
--Video
-3.2 Linux进程创建
--Video
-3.3 Linux进程调度
--Video
-3.4 动手实践-打印进程描述符task_struct中的字段
--Video
-3.5工程实践-基于内核模块的负载监控
--Video
-第3章 进程管理--章节测验
-4.1 Linux内存管理机制
--Video
-4.2 进程用户空间管理机制
--Video
-4.3 物理内存分配与回收机制(上)
--Video
-4.4 物理内存分配与回收机制(下)
--Video
-4.5 动手实践-Linux内存映射基础(上)
--Video
-4.6 动手实践-Linux内存映射实现(中)
--Video
-4.7 动手实践-Linux内存映射测试(下)
--Video
-4.8 初学者对内存管理的常见疑惑
-第4章 内存管理--章节测验
-5.1 中断机制概述
--Video
-5.2 中断处理机制
--Video
-5.3 中断下半部处理机制
--Video
-5.4 时钟中断机制
--Video
-5.5 动手实践-中断上半部的代码分析及应用
--Video
-5.6 动手实践-中断下半部的代码分析及应用
--Video
-第5章 中断--章节测验
-6.1 Linux中的各种API
--Video
-6.2 系统调用机制
--Video
-6.3 动手实践-添加系统调用(系统调用日志收集系统)
--Video
-第6章 系统调用--章节测验
-7.1 内核同步概述
--Video
-7.2 内核同步机制
--Video
-7.3 动手实践-内核多任务并发实例(上)
--Video
-7.4 动手实践-内核多任务并发实例(下)
--Video
-第7章 内核同步--章节测验
-8.1 虚拟文件系统的引入
--Video
-8.2 虚拟文件系统的主要数据结构
--Video
-8.3 文件系统中的各种缓存
--Video
-8.4 页高速缓存机制以及读写
--Video
-8.5 动手实践-编写一个文件系统(上)
--Video
-8.6 动手实践-编写一个文件系统(中)
--Video
-8.7 动手实践-编写一个文件系统(下)
--Video
-第8章 文件系统--章节测验
-9.1 设备驱动概述
--Video
-9.2 I/O空间管理
--Video
-9.3 设备驱动模型
--Video
-9.4 字符设备驱动程序简介
--Video
-9.5 块设备驱动程序简介
--Video
-9.6 动手实践-编写字符设备驱动程序
--Video
-9.7工程实践-编写块设备驱动的基础(上)
--Video
-9.8 工程实践-块设备驱动程序分析(中)
--Video
-9.9 工程实践-块设备驱动程序实现(下)
--Video
-第9章 设备驱动--章节测验
-致谢与说明
--Video