- 1、本文档共48页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
[第四章Linux驱动程序设计
教学内容 第一章 嵌入式系统概述 第二章 学习板硬件及开发环境的建立 第三章 构建嵌入式Linux系统 第四章 嵌入式Linux设备驱动 第五章 嵌入式Linux串口和网络编程 第六章 嵌入式Linux图形编程 第四章 嵌入式Linux驱动程序 4.1 嵌入式Linux设备驱动简介 4.2 设备的分类及特点 4.3 构造和运行驱动程序模块 驱动程序的作用 内核态和用户态 大多数OS(包括Linux)把内核和运行在其上的应用程序分为两个层次管理,即用户态和内核态 内核态有较高的权限,可以控制处理器内存的映射和分配方式等等————对应于ARM的svc模式 用户态:只能运行系统上的应用程序————对应于ARM的usr模式 内核态与用户态切换:可通过软件中断实现 内核态和用户态 驱动程序作为系统内核的一部分,其工作在内核态,而应用程序工作在用户态,即不能直接通过指针,把用户空间的数据地址传递给内核(MMU映射地址不一样)。 需要经过转换,把用户态“看到的空间”转换成内核态可访问的地址。Linux系统提供了一系列方便的函数实现这种转换,如:__get_user、__put_user、 __copy_from_user、__copy_to_user Linux内核结构 Linux内核结构 应用程序、库、内核、驱动程序的关系 4层软件关系说明 (1)应用程序使用库函数提供的open函数打开设备文件 (2)库根据open函数传入的参数执行“swi”指令,引起CPU异常,进入内核 (3)内核的异常处理函数根据这些参数找到相应的驱动程序,返回一个文件描述符给库,进而返回给应用程序 (4)应用程序得到文件描述符后,使用库提供的write或ioclt函数发出控制命令 (5)库根据write或ioclt函数传入的参数执行“swi”指令,这条指令会引起CPU异常,再次进入内核 (6)内核的异常处理函数根据参数调用驱动程序的相关函数,控制硬件 打印调试printk 指示日志级别的宏 KERN_EMERG 用于紧急事件消息,一般是系统崩溃前提示0 KERN_ALERT 用于需要立即采取动作1 KERN_CRIT 临界状态,通常涉及到严重的硬件或软件操作失败2 KERN_ERR 用于报告错误状态,设备驱动程序会经常使用其来报告来自硬件的问题3 KERN_WARNING 用于对可能出现的问题进行警告4 KERN_NOTICE 用于有必要进行提示的正常情况5 KERN_INFO 提示性信息6 KERN_DEBUG 用于调试信息7 打印调试printk 每个宏表示一个 中的整数(0~7),数值越小,优先级越高 未指定优先级在内核2.6版本中就是KENR_WARNING 简单的内核模块编译(内核2.4) 编译内核模块 #gcc –O -DMODULE -D__KERNEL__ -c hello.c -I /usr/src/linux/include (x86 or ARM ? ) 生成hello.o 加载内核模块:insmod 模块文件名 #insmod hello.o #dmesg Hello,world 查看内核中使用的模块 #lsmod | grep hello 卸载内核模块:rmmod 模块名称 #rmmod hello.o #dmesg Goodbye world 简单的内核模块编译(内核2.6) obj-m := led_drv.o KDIR:=/home/at9200/kernel/linux-2.6.38/ PWD :=$(shell pwd) all: make -C $(KDIR) M=$(PWD) modules clean: make -C $(KDIR) M=$(PWD) clean 简单的内核模块编译(内核2.6) obj-m := led_drv.o表示编译后生成led_drv.ko模块 $(KDIR) 指定了target内核源码的路径,“M=”表示这是个外部模块,M=$(PWD) 指定了该模块文件所在的路径。 简单的内核模块编译(内核2.6) 如果是多个源文件编译出一个模块,假设模块名是test.ko,那么源文件名不能有test.c obj-m := test.o test-objs := file1.o file2.o file3.o KDIR := /home/at9200/kernel/linux-2.6.38/ PWD
文档评论(0)