实验手册样本.docx
《实验手册样本.docx》由会员分享,可在线阅读,更多相关《实验手册样本.docx(31页珍藏版)》请在冰豆网上搜索。
![实验手册样本.docx](https://file1.bdocx.com/fileroot1/2023-3/30/7a8257df-b41f-466d-9124-b85a72986057/7a8257df-b41f-466d-9124-b85a729860571.gif)
实验手册样本
嵌入式Linux内核编程与驱动开发
实验手册
李国斌
合肥学院计算机科学与技术系
实验环节课时安排
实验大类
课时
子实验标题
内容
1.内核编译
入门
(必做)
2
1.1内核浏览。
Sourceinsight工具浏览
1.2内核编译实验
内核编译
2.内核模块
驱动实验
(必做)
4
2.1简单模块实验
(1)
模块基础
2.2简单模块实验
(2)
module_init,
module_exit宏
2.3简单模块实验(3)
MODULE_LICENSE
MODULE_AUTHOR等宏
2.4简单模块实验(4)
模块参数的传递功能
2.5简单模块实验(5)
多文件模块的编译
3.简单字符
驱动实验
(必做)
6
3.1简单字符设备实验
(1)
添加设备号的注册
3.2简单字符设备实验
(2)
添加设备的注册
3.3简单字符设备实验(3)
open、release功能
3.4简单字符设备实验(4)
read功能
3.5简单字符设备实验(5)
Write功能
3.6简单字符设备实验(6)
DEBUG控制
3.7简单字符设备实验(7)
创立PROC结点
3.8简单字符设备实验(8)
添加ioctl功能
4.高级字符
驱动实验
(必做)
6
4.1PIPE实验
PIPE
4.2Poll实验
Poll
4.3异步通知实验
异步通知
4.4秒表字符设备
秒表字符设备
4.5Tasklet实验
Tasklet实验
4.6工作队列实验
工作队列
5.嵌入式
驱动实验
(选做)
2
5.1LED灯驱动程序编写实验
GPIO
5.2按键中断字符驱动程序编写实验
按键中断
5.3编写一个sbull驱动
将一段ram空间模拟为DISK使用。
实验1.1、内核浏览实验
【实验内容】
利用工具查看内核代码。
【实验目的】
了解Linux内核源代码的目录结构及各目录的相关内容。
【实验平台】
Ubantu10.10
【工具介绍】
SourceInsight实质上是一个支持多种开发语言(java,c,c 等等)的编辑器,只不过由于其查找、定位、彩色显示等功能的强大,常被我们当成源代码阅读工具使用。
【实验练习】:
(1)使用sourceinsight浏览内核源码。
熟悉内核中代码的结构。
了解内核中KCONFIG和Makefile的作用及含义。
(2)参考其它资料,分析内核中链表的相关代码,熟悉内核中链表的函数及使用。
【实验步骤】
1.SourceInsight安装及内核代码工程配置
安装SourceInsight并启动程序,能够进入图1界面。
在工具条上有几个值得注意的地方,如图所示,图中内凹左边的是工程按钮,用于显示工程窗口的情况;右边的那个按钮按下去将会显示一个窗口,里边提供光标所在的函数体内对其它函数的调用图,经过点击该窗体里那些函数就能够进入该函数所在的地方。
图1SourceInsight界面图
由于SourceInsight实质上是一个支持多种开发语言(Java,C,C++等等)的编辑器,只不过由于其查找、定位、彩色显示等功能的强大,而被我们当成源代码阅读工具使用。
因此,为了有效的阅读源程序,首先必须选择功能菜单上的”Project”选项的子菜单”NewProject”新建一个项目,项目名称能够自由选定,当然也能够选择删除(Remove)一个项目。
当删除一个项目的时候,并不删除原有的源代码文件,只是将该软件生成的那些工程辅助文件删除。
设定之后,将会弹出一个对话框如图2,接受默认选择,如果,硬盘空间足够,能够将第一个复选框选上,该选项将会需要与源代码大致同等的空间来建立一个本地数据库以加快查找的速度。
图2工程设置
点击”OK”按钮,接受选择后,将会有一个新的对话框弹出,在这个对话框里,能够选择将要阅读的文件加入工程,一种方式是经过在FileName中输入要阅读源代码文件的名称,点击”Add”按钮将其加入,也能够经过其中”AddAll”和”AddTree”两个按钮能够将选中目录的所有文件加入到工程中,其中”AddAll”选项会提示加入顶层文件和递归加入所有文件两种方式,而”AddTree”相当于”AddAll”选项的递归加入所有文件,能够根据需要使用,就我来说,更喜欢”AddTree”一些。
由于该程序采用了部分打开文件的方式,没有用到的文件不会打开,因此,加入数千个文件也不用担心加入的文件超出程序的所能容忍的最大值,我就是采用”AddTree”的方式将Linux2.4内核的四千五百九十一个文件加入的。
图3添加文件
加入文件后,点击一个文件,能够出现使用界面,如图4所示,其中,右边的那个窗口(LinuxProject,即工程窗口)缺省按照字母顺序列出当前工程中所有的文件。
图4工作窗口
点击一个文件就能够打开该文件,显示如图5所示,进入到右边的那个窗口分别能够以文件列表的方式,列出所有的文件,每个窗体下边有一排按钮,左边的窗口(21142.c)从左至右分别为:
按字母顺序排列所有标记、按照文件中行数顺序排列标记、按照类型排列标记、浏览本地文件标记、标记窗口属性。
右边的窗口(LinuxProject)从左至右分别为:
按字母顺序文件列表、显示文件夹、按照文件类型归类文件、全部文件的所有标记列表、按照标记类型归类标记、跳转到定义处、显示标记信息、浏览工程标记、查找函数调用、工程属性,其中全部文件的所有标记列表选项可能要一段时间抽取标记,同步到数据库去,如果开始选择了建立标记数据库,将会在今后节省同步时间,最有用的莫过于浏览标记信息和查找函数调用,前者能够经过”Jump”按钮在不同的地方查找同样的标志,还能够经过”Reference”按钮结合后者进行全局的标记查找。
Reference功能是SourceInsight的特色之一,它能够在速度极快的在整个工程中找到所有的标记,而且在该行程序的前边加上红色箭头的小按钮链接上。
图6是一个Reference搜索后的结果,它能够有两种模式,一种集中显示结果,图6显示的就是这种模式,在这种模式下,能够经过前边的红色箭头小按钮进入另外一种模式,该标记的具体的所在处,也能够经过标记的具体所在处点击红色箭头小按钮进入警种模式,还能够经过工具条上的两个红色小箭头直接在第二种模式下前后移动,察看相应信息。
它的这个强大的功能使得阅读Linux源程序有如神助。
可是要注意的是,当进行了第二次”Reference”时,它会提示你将结果集附加在第一个结果集的后边还是取代第一个结果集。
如果选择前者,不能对结果集根据前后两次搜索结果进行分类,然后在其子类里进行移动,只能在整个结果集里移动;如果,选择后者,结果集将会被替换为第二次搜索的结果,略微有些不方便。
图6Reference的搜索结果
SourceInsight设置
1、背景色选择
要改变背景色Options->preference->windowsbackground->color设置背景色
2、解决字符等宽对齐问题。
SIS默认字体是VERDANA,很漂亮。
这网页上应该也是用的VERDANA字体。
但由于美观的缘故,VERDANA字体是不等宽的。
比如下面两行
Llllllllll
MMMMMMMMMM
同样10个字符,长度差多了.用VERDANA来看程序,有些本应该对齐的就歪了。
解放方法是使用等宽的字体,但肯定比较丑。
比较推荐的是用CourierNew。
3、解决TAB键缩进问题
Options->DocumentOptions里面的右下角EditingOptions栏里,把Expandtabs勾起来,然后确定。
OK,现在TAB键的缩进和四个空格的缩进在SIS里面看起来就对齐咯。
4、SI中的自动对齐设置:
在C程序里,如果遇到行末没有分号的语句,如IF,WHILE,SWITCH等,写到该行末按回车,则新行自动相对上一行缩进两列。
Option->Documentoption下的AutoIndient中AutoIndientType有三种类型None,Simple,Smart。
个人推荐选用Simple类型。
5、向项目中添加文件时,只添加特定类型的文件(文件类型过滤器)
编辑汇编代码时,在SIS里建立PROJECT并ADDTREE的时候,根据默认设置并不会把该TREE里面所有汇编文件都包含进来。
只加了.inc和.asm后缀的,.s后缀的没有。
而且用SIS打开.s的文件,一片黑白没有色彩,感觉回到DOS的EDIT时代了……
解决方法是在Options->DocumentOptions里面,点左上的DocumentType下拉菜单,选择x86AsmSourceFile,
然后在右边的Filefilter里*.asm;*.inc;的后面加上*.s;接着CLOSE就能够了。
上面问题解决了,但注意加入*.s后还需要重新ADDTREE一遍才能把这些汇编加到PROJECT里面。
6、添加文件类型
用户能够定义自己的类型,Options->DocumentOptions->addtype,定义文件类型名以及文件名后缀。
勾选includewhenaddingtoprojects在添加目录下文件到工程是该类文件就会添加进SI的工程。
如果需要将所有文件添加进SI的工程,能够定义一种文件类型*.*。
7、恢复ctrl+a的全选功能
经过关键词save找到saveall,更改为ctrl+shift+a,经过关键词select找到selectall,更改为ctrl+a
SourceInsight常见的快捷键:
Ctrl+=:
Jumptodefinition
Alt+/:
Lookupreference
F3:
searchbackward
F4:
searchforward
F5:
gotoLine
F7:
Lookupsymbols
F8:
Lookuplocalsymbols
F9:
Identleft
F10:
Identright
Alt+,:
Jumpbackword
Alt+.:
Jumpforward
Shift+F3:
searchthewordundercusorbackward
Shift+F4:
searchthewordundercusorforward
F12:
incrementalsearch
Shift+Ctrl+f:
searchinproject
shift+F8:
hilightword
【思考题】
1.内核中的链表是如何实现的。
请查阅资料分析链表的实现细节,给出分析报告。
实验1.2、内核编译实验
【实验内容】
尝试编译内核、新增内核代码加入到Linux内核结构。
【实验目的】
1、了解Linux内核各配置选项内容和作用
2、掌握Linux内核配置文件.config的作用
3、掌握Linux内核的编译过程
4、掌握将新增内核代码加入到Linux内核结构中的方法
【实验平台】
Ubantu10.10
【实验步骤】
1.内核源码下载解压。
2.配置内核
3、内核编译过程
(1)makemrproper:
删除所有以前在构核过程所产生的所有文件
(2)makemenuconfig:
内核配置
(3)makedep:
寻找依存关系(2.4内核需要)
(4)makezImage:
产生压缩的核心映像文件
内核编译完毕之后,生成zImage内核映象文件保存在源代码的arch/arm/boot/目录下
时间很长,建议熟悉过程。
【实验练习】:
(课本P67)
对于一个开发者来说,将自己开发的内核代码添加到Linux内核中,需要有三个步骤。
(1)确定把自己的开发代码放入到内核的位置;
(2)把自己开发的功能增加到Linux内核的配置选项中,使用户能够选择此功能
(3)构建子目录Makefile,根据用户的选择,将相应的代码编译Linux内核中。
DIY:
向内核添加自己的程序
A.在Linux内核中增加自己的程序步骤(注意这里只是程序文件):
1.将编写的源代码复制到Linux内核源代码的相应目录中。
2.在目录的Kconfig文件中增加新源代码对应项目的编译配置选项
3.在目录的Makefile文件中增加对新源代码的编译条目。
B.在Linux内核drivers/目录中增加目录和子目录步骤:
1.所加目录为daiq,文件如下:
[daiq@localhostdaiq]$tree
|--Kconfig
|--Makefile
|--led
| |--Kconfig
| |--Makefile
| --led.c
--test.c
#注意此时各个目录中的Makefile和Kconfig文件是空的
2.在新增的相应目录添加Kconfig和Makefile文件,上面的目录中已经添加。
3.修改新增目录的父目录的Kconfig和Makefile文件,以便新增的Kconfig和Makefile能被引用。
向父目录中的Makefile添加:
obj-y +=daiq/
表示在编译过程中包含子目录daiq目录。
然后修改Kconfig文件,添加:
source”drivers/daiq/Kconfig”
表示在配置时引用子目录daiq中的配置文件Kconfig。
4.实际上,要让drivers/daiq/Kconfig有效,要在arch/arm/Kconfig文件中添加:
source”drivers/daiq/Kconfig”
父目录drivers/Kconfig的修改能够不要。
5.经过上面一步,内核就能够找到所加的目录daiq了,然后就是编辑各个目录中的Makefile和Kconfig文件,在你添加的目录daiq中的Makefile加入:
obj-$(CONFIG_TEST)+=test.o#因为在daiq目录中要编译test.c文件
#因此会根据CONFIG_TEST来决定编译选项
obj-y+=led/#编译daiq目录中的子目录led
然后Kconfig文件是:
menu"DaiQdevicesupport" #在makemenuconfig时要显示的菜单入口
configDAIQ_TEST
bool"Test"
help
DaiQdevicesupport
source"drivers/daiq/led/Kconfig"
endmenu
注意:
menu和endmenu的前后要加回车,不然makemenuconfig的时候会出错。
再看led目录下的Makefile和Kconfig:
Makefile为文件:
obj-$(CONFIG_LED)+=led.o
Kconfig文件:
configLED
tristate”ledsupport”
5.现在能够makemenuconfig来配置添加自己目录daiq的驱动了!
【附录】:
编译内核的常见命令
精简Linux内核常见命令包括:
MakeConfig,dep,clean,mrproper,zImage,bzImage,
Modules,Modules_Install
(1)、Makeconfig:
内核配置,调用./scripts/Configure按照arch/i386/config.in来进行配置。
命令执行后产生文件.config,其中保存着配置信息。
下次在做makeconfig时将产生新
的.config文件,原文件config更名为config.old
(2)、makedep:
寻找依存关系。
产生两个文件.depend和.hdepend,其中.hdepend表示每
个.h文件都包含其它哪些嵌入文件。
而.depend文件有多个,在每个会产生目标文件(.o)文件的目录下均有,它表示每个目标文件都依赖于哪些嵌入文件(.h)
(3)、makeclean:
清除以前构核所产生的所有的目标文件,模块文件,核心以及一些临时文件等,不产生任何文件
(4)、makermproper:
删除所有以前在构核过程所产生的所有文件,及除了做makeclean外,还要删除.config,.depend等文件,把核心源码恢复到最原始的状态。
下次构核时必须进行重新配置;
(5)、make,makezImage,makebzImage:
(a)make:
构核。
经过各目录的Makefile文件进行,会在各个目录下产生一大堆目标文件,如核心代码没有错误,将产生文件vmlinux,这就是所构的核心。
并产生映像文件system.map经过各目录的makefile文件进行。
.version文件中的数加1,表示版本号的变化。
(b)makezImage:
在make的基础上产生压缩的核心映像文件./arch/$(ARCH)/boot/zImage以及./arch/$(ARCH)/boot/compressed目录下产生一些临时文件。
(c)makebzImage:
在make的基础上产生压缩比例更大的的核心映像文件./arch/$(ARCH)/boot/bzImage以及./arch/$(ARCH)/boot/compressed目录下产生一些临时文件。
在核心太大时进行
【思考题】
1.内核内核编译的流程是怎样的?
内核代码中的KCONFIG和Makefile文件起到什么样的作用?
2..Config文件起到什么作用?
如何在内核中添加新的驱动模块?
3.Linux内核编译完成结果有有哪些?
各有什么作用?
4.内核目录的结构是怎样的,关键目录的含义是什么?
实验2.1简单模块实验
(1)
【实验内容】
编写一个最基本的模块,加载模块,观察结果
【实验目的】
掌握模块的基本要素及加载、卸载、查看工具的使用。
【实验平台】
Ubantu10.10
【实验步骤】
1.将文件夹ex1-hello-world复制到Linux环境中,如:
/home/linux/test
$suroot
$cpex1-hello-world/home/linux/test–a
2.$cd/home/linux/test/ex1-hello-world
3.$make
4.经过insmod命令将模块加入内核
$insmodhello.ko
5.经过lsmod查看内核模块
$lsmod|grephello
6.经过rmmod删除内核中的模块
$rmmodhello
7.查看源码,适当修改,掌握实验内容
【思考题】
1.内核模块的组成部分有哪些组成部分?
那些是必须的?
那些是可选的?
2.内核模块代码中Pintk函数打印的消息存放在什么位置?
需要使用什么命令查看内核打印消息?
3.模块加载和卸载时分别执行的函数是哪个?
为什么?
4.
实验2.2、简单模块实验
(2)
【实验内容】
在实验一的基础上,加入module_init,module_exit的支持
加载模块,观察结果。
【实验目的】
掌握module_init,module_exit的使用。
【实验平台】
Ubantu10.10
【实验步骤】
1.将文件夹ex2-init-exit复制到Linux环境中,如:
/home/linux/test
$suroot
$cpex2-init-exit/home/linux/test–a
2.$cd/home/linux/test/ex2-init-exit
3.$make
4.经过insmod命令将模块加入内核
$insmodhello.ko
5.经过lsmod查看内核模块
$lsmod|grephello
6.经过rmmod删除内核中的模块
$rmmodhello
7.查看源码,适当修改,掌握实验内容
实验2.3、简单模块实验(3)
【实验内容】
在实验二的基础上,加入模块描述信息的支持
【实验目的】
掌握MODULE_LICENSE\MODULE_AUTHOR等宏的使用。
【实验平台】
Ubantu10.10
【实验步骤】
1.将文件夹ex3-doc-license复制到Linux环境中,如:
/home/linux/test
$suroot
$cpex3-doc-license/home/linux/test–a
2.$cd/home/linux/test/ex3-doc-license
3.$make
4.经过insmod命令将模块加入内核
$insmodhello.ko
5.经过lsmod查看内核模块
$lsmod|grephello
6.经过rmmod删除内核中的模块
$rmmodhello
7.查看源码,适当修改,掌握实验内容
8.经过modinfo查看模块信息
$modinfohell.ko
实验2.4、简单模块实验(4)
【实验内容】
在实验三的基础上,加入模块参数的传递功能
【实验目的】
掌握模块的模块参数的传递功能的使用。
【实验平台】
Ubantu10.10
【实验步骤】
1.将文件夹ex4-param复制到Linux环境中,如:
/home/linux/test
$suroot
$cpex4-param/home/linux/test–a
2.$cd/home/linux/test/ex4-param
3.$ma