已阅读5页,还剩108页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
嵌入式系统导论课程组 嵌入式系统导论 第3章嵌入式开发环境的搭建 3 1嵌入式开发环境概述 1 建立开发环境2 配置开发主机 配置MINICOM3 建立引导装载程序bootloader4 下载别人已经移植好的linux操作系统5 建立根文件系统6 建立应用程序的falsh分区7 开发应用程序8 烧写内核 根文件系统 应用程序9 发布产品 第3章嵌入式开发环境的搭建 3 2Flash程序烧写 烧写 即利用特殊工具向开发板中下载代码 实例 向ARM板 裸机 上烧写BootLoader 内核 根文件系统前提 存在目录 img 其下有已经准备好的各个部分软件的映像文件 即用交叉编译器编译好的可执行文件 分别为 VIVI 针对S3C2410的BootLoader映像文件zImage 经裁剪的Linux内核映像文件root cramfs 根文件系统映像文件sjf2410 完成烧写的程序 3 2Flash程序烧写 具体烧写步骤1 安装JTAG驱动程序将整个giveoio目录 JTAG驱动所在目录 复制到c WINDOWS下 并将该目录下的giveio sys文件复制到系统盘驱动目录下 如c WINDOWS system32 drivers在控制面板中添加该驱动程序2 设置超级终端按照波特率115300 数据位8 无奇偶校验 停止位1 数据流控为无进行设置3 烧写引导程序使用sjf2410程序对vivi进行第一次烧写vivi启动后 使用bonpart命令对flash进行分区使用load命令对vivi进行第二次烧写4 烧写内核使用load命令对kernel进行烧写5 烧写根文件系统使用load命令对rootfs进行烧写 第3章嵌入式开发环境的搭建 3 3 1BootLoader程序原理 对于PC系统 引导加载程序BIOS 固件程序 和位于磁盘MBR 主引导记录 中系统引导程序 LILO和GRUB等 一起组成 BIOS完成硬件检测和资源分配后 将硬盘MBR中的引导程序读到系统的内存中 然后将控制权交给引导程序 引导程序的主要任务就是将内核映像从硬盘上读到内存中 然后跳转到内核的入口点去运行 即开始启动操作系统 在嵌入式系统中 主要使用flash作为系统的存储煤介 很少用磁盘 因此整个系统的加载启动任务就完全由引导程序 也称为Bootloader 来完成 就是在操作系统内核运行之前运行的一段小程序 通过这段小程序 可以初始化硬件设备 建立内存空间的映射图 从而将系统的软硬件环境带到一个合适的状态 以便为最终调用操作系统内核准备好正确的环境 嵌入式系统中的bootloader概念 Bootloader的功能 1 硬件设备初始化 CPU的主频 SDRAM 中断 串口等 2 内核启动参数3 启动内核4 与主机进行交互 从串口 USB口或者网络口下载映象文件 并可以对FLASH等存储设备进行管理 Bootloader特点 1 依赖于硬件 每种不同的CPU体系结构都有不同的bootloader2 bootloader还依靠具体的嵌入式板级设备的配置 BootLoader的安装媒介 1 系统加电或复位后 所有的处理器通常都从某个预先安排的地址上取指令 比如 ARM在复位时从地址0 x0取指 2 嵌入式系统中通常都有某种类型的固态存储设备 比如 ROM EEPROM或FLASH等 被映射到这个预先安排的地址上 因此在系统加电后 处理器将首先执行BootLoader程序3 Bootloader是最先被系统执行的程序 固态存储设备的典型空间分配结构 Bootloader的烧写方式 1 通过JTAG口2 通过以太网口3 通过串口4 其中前两种方式比后一种快得多 BootLoader的控制方式 1 主机和目标机之间一般通过串口建立连接 BootLoader软件在执行时通常会通过串口来进行通讯 比如 输出打印信息到串口 从串口读取用户控制字符2 也可以通过JTAG等其他接口通讯 BootLoader的操作模式 大多数BootLoader都包含两种不同的操作模式 1 启动加载模式2 下载模式从最终用户的角度看 BootLoader的作用就是用来加载操作系统 而并不存在所谓的启动加载模式与下载工作模式的区别 启动加载模式启动加载模式 称为 自主 Autonomous 模式BootLoader从目标机上的某个固态存储设备上将操作系统加载到RAM中运行 整个过程并没有用户的介入 这种模式是BootLoader的正常工作模式 因此在嵌入式产品发布的时侯 BootLoader显然必须工作在这种模式下 BootLoader的操作模式 下载模式在下载模式下 目标机上的BootLoader将通过串口连接或网络连接等通信手段从主机下载文件 如 下载内核映像和根文件系统映像等从主机下载的文件通常首先被BootLoader保存到目标机的RAM中 然后再被BootLoader写到目标机上的FLASH类固态存储设备中 这种模式通常在第一次安装内核与根文件系统时被使用 此外 以后的系统更新也会使用BootLoader的这种工作模式 工作于这种模式下的BootLoader通常都会向它的终端用户提供一个简单的命令行接口 BootLoader的操作模式 BL的典型结构框架 大多数BootLoader都分为stage1和stage2两大部分 依赖于处理器体系结构和板级初始化的代码 通常都放在stage1中 用汇编语言实现而stage2则通常用C语言来实现 这样可以实现更复杂的功能 而且代码会具有更好的可读性和可移植性 BootLoader的stage1通常包括以下步骤 以执行的先后顺序 硬件设备初始化 为加载BootLoader的stage2准备RAM空间 拷贝BootLoader的stage2到RAM空间中 设置好堆栈跳转到stage2的C入口点 BL的典型结构框架 BootLoader的stage2通常包括以下步骤 以执行的先后顺序 初始化本阶段要使用到的硬件设备 检测系统内存映射 memorymap 将kernel映像和根文件系统映像从flash上读到RAM空间中 为内核设置启动参数 调用内核 stage2的代码通常用C语言来实现 以便于实现更复杂的功能和取得更好的代码可读性和可移植性 与普通C语言应用程序不同的是 在编译和链接bootloader这样的程序时 我们不能使用glibc库中的任何支持函数 BL的典型结构框架 3 3 2几种流行的LinuxBootLoader 1 U Boot2 BLOB3 RedBoot4 VIVI 3 3 3S3C2410平台上的VIVI分析 vivi是由韩国Mizi公司开发的一种BootLoader 适合于ARM9处理器 支持S3C2410UP NETARM2410平台的引导程序启动模式和下载模式结构简单支持Linux内核引导 可以传递内核参数支持分区 bon 命令行 vivi的Stage1 文件head S 关WATCHDOG 上电后 WATCHDOG默认是开着的禁止所有中断初始化系统时钟初始化内存控制寄存器 一共13个 检查是否从掉电模式唤醒 若是 则调用WakeupStart函数进行处理点亮所有LED初始化UART0将vivi所有代码 包括阶段1和阶段2 从nandflash复制到SDRAM中跳到bootloader的阶段2运行 vivi的Stage1 文件head S vivi的Stage2 文件main c 1 打印vivi的信息 包括版本号等2 调用若干个初始化函数3 boot or vivi 判断是否有 r 回车或空格键按下 若有 则进入vivishell 若没有 则执行boot命令 启动内核4 boot命令执行后 找到kernel分区 找它的偏移量和大小 执行boot kernel 函数 拷贝内核映象5 设置linux启动参数 打印NowBootingLinux 6 调用call linux 函数 启动内核 第3章嵌入式开发环境的搭建 3 4 1内核的裁减 ARM上的linux内核移植准备工作1 下载linux2 6 0内核及其关于ARM平台的补丁 如 Patch 2 6 0 rmkl gz2 给linux2 6 0打补丁3 准备交叉编译环境4 修改内核目录下的makefile文件 Linux内核的编译菜单有好几个版本 1 makeconfig 进入命令行 可以一行一行的配置 2 makemenuconfig 开发人员比较熟悉的menuconfig菜单 3 makexconfig 在2 4 X以及以前版本中xconfig菜单是基于TCL TK的图形库的 3 4 1内核的裁减 2 4 X版本xconfig配置菜单 2 4 X版本menuconfig配置菜单 2 6 X版本xconfig配置菜单 内核模块处理方式 要增加对某部分功能的支持 可以把相应部分编译到内核中 也可以把该部分编译成模块 动态调用 如果编译到内核中 在内核启动时就可以自动支持相应部分的功能 这样的优点是方便 速度快 机器一启动 你就可以使用这部分功能了 缺点是会使内核变得庞大起来 经常使用的部分直接编译到内核中 比如网卡 如果编译成模块 就会生成对应的 o文件 在使用的时候可以动态加载 优点是不会使内核过分庞大 缺点是你得自己来调用这些模块 在选择相应的配置时 有三种选择方式 Y 将该功能编译进内核N 不将该功能编译进内核M 将该功能编译成可以在需要时动态插入到内核中的模块 Linux内核的编译菜单有好几个版本 1 makeconfig 进入命令行 可以一行一行的配置 2 makemenuconfig 开发人员比较熟悉的menuconfig菜单 3 makexconfig 在2 4 X以及以前版本中xconfig菜单是基于TCL TK的图形库的 3 4 2内核的编译 1 makeclean 清楚当前环境 2 makedep 设置变量依赖关系 3 makezImage 编译内核 生成zImage 编译命令 编译完成的Linux内核在哪里 vmlinux elf格式未压缩内核arch arm boot compressed vmlinux 压缩以后的elf格式内核 此文件是从非压缩的内核映像产生的 arch arm boot zImage 可自解压的压缩内核的映像文件 第3章嵌入式开发环境的搭建 3 5根文件系统的构建 Linux根文件系统目录结构使用busybox生成工具集构建根文件系统 Linux根文件系统目录结构 Linux根文件系统目录结构bin必要的用户命令 二进制文件 boot引导加载程序使用的静态文件dev设备文件及其他特殊文件etc系统配置文件 home用户主目录lib必要的链接库 例如 C链接库 内核模块mnt临时挂载的文件系统的挂载点注 目录在嵌入式Linux上为可选的 Linux根文件系统目录结构 opt附加软件的安装目录proc提供内核和进程信息的proc文件系统 rootroot用户主目录sbin必要的系统管理员命令tmp临时文件目录usr大多数用户使用的应用程序和文件目录var监控程序和工具程序存放的可变数据 Linux根文件系统目录结构 etc目录 系统配置文件fstab挂载文件系统的配置文件passwdPassword文件inetd confInetd守护进程的配置文件groupGroup文件init d rcS缺省的sysinit脚本 Linux根文件系统目录结构 使用Busybox生成工具集 很小的应用程序提供完整的工具集的功能Init进程Shell文件系统 网络系统等等的工具集 使用Busybox生成工具集 Busybox的配置和交叉编译 1 在下载Busybox busybox 1 1 0 tar bz2解压后 进入配置菜单 makemenuconfig 使用Busybox生成工具集 Busybox的配置和交叉编译 1 使用Busybox生成工具集 1 如果在开发板上使用devfs 则需要设置GereralConfiguration选项 Supportfordevfs2 配置交叉编译器 BuildOptions DoyouwanttobuildBusyBoxwithaCrossCompiler usr local arm 3 4 1 bin arm linux CrossCompilerprefix需要在接下来的输入栏中输入宿主机中交叉编译器安装的路径 如 opt host armv41 bin armv41 unknown linux Busybox的配置和交叉编译 2 使用Busybox生成工具集 3 选择Busybox的编译方式 BuildOptionsBuildBusyBoxasastaticbinary nosharedlibs 缺省配置为使用链接库 Busybox的配置和交叉编译 2 使用Busybox生成工具集 配置其他工具集 ArchivalUtilities工具 tar zip unzipCoreutils常用命令 basenamecatchgrpchmoddatedddfechoenvlnlsmkdirmknodmvpwdrmrmdirsleepsortsyncwcwhoami等等ConsoleUtilitiesDebianUtilitieEditors编辑命令 viawksed等FindingUtilities查找命令 findgrepxargs Busybox的配置和交叉编译 3 配置其他工具集 InitUtilities init Supportreadinganinittabfile Supportrunninginitfromwithinaninitrd Busybox的配置和交叉编译 3 使用Busybox生成工具集 配置其他工具集 Login PasswordManagementUtilitiesLogin gettyloginpasswdMiscellaneousUtilitiesLinuxModuleUtilitiesNetworkingUtilities网络命令集 hostnameifconfiginetdnetstatpingrouteProcessUtilities进程命令 freepssysctltopShellsshell工具 ash等SystemLoggingUtilities日志工具 syslogdklogdLinuxSystemUtilities系统工具 dmesgfdiskgetoptmoremountumount 使用Busybox生成工具集 Busybox的配置和交叉编译 3 编译Busybox 1 makedep 2 make 3 makeinstall 使用Busybox生成工具集 Busybox的配置和交叉编译 4 编译生成的目录结构 install bin linuxrc sbin usr usr bin usr sbin 使用Busybox生成工具集 Busybox的配置和交叉编译 5 构建根文件系统 在 install下创建其它的目录Dev 存放设备文件Proc Lib 库文件所在目录Mnt 临时挂载点Tmp 临时目录Usr 用户目录Var Etc 存放系统设置文件目录 在此目录下创建如下文件Inittab 指定运行级别文件Fstab 挂载文件系统的配置文件inetd conf Inetd守护进程配置文件profile shell配置脚本Passwd 用户管理文件Hosts 静态域名解析文件 利用cramfs工具创建根文件系统映象文件mkcramfs installroot cramfsroot cramfs即是最后根文件系统的可执行映像文件 构建根文件系统 第3章嵌入式开发环境的搭建 驱动开发简介设备驱动分类Linux下字符型设备管理Linux驱动编译和加载方式Linux内核模块结构介绍简单Linux字符型设备驱动程序驱动程序与应用程序的区别字符型设备驱动demo分析 3 6驱动程序原理与开发 驱动开发简介 驱动程序是应用程序与硬件之间的一个中间软件层 驱动程序应该为应用程序展现硬件的所有功能 不应该强加其他的约束 对于硬件使用的权限和限制应该由应用程序层控制 驱动程序有时会被多个进程同时使用 这时我们要考虑如何处理并发的问题 就需要调用一些内核的函数使用互斥量和锁等机制 概念 驱动开发简介 Linux输入 输出系统层次结构和功能 驱动开发简介 Linux驱动程序与外界的接口 设备驱动程序 接口 具体设备 驱动程序与设备间 接口 系统初始化 接口 操作系统内核 数据结构file operations 各设备 初始化 交互 进行 实现 驱动开发简介设备驱动分类Linux下字符型设备管理Linux驱动编译和加载方式Linux内核模块结构介绍简单Linux字符型设备驱动程序驱动程序与应用程序的区别字符型设备驱动demo分析 3 6驱动程序原理与开发 设备驱动分类 目前Linux支持的设备驱动大体可分为三种 字符设备 characterdevice 块设备 blockdeivce 网络接口设备 networkinterface 设备类型 设备驱动分类 所有能够像字节流一样访问的设备比如文件等在Linux中都通过字符设备驱动程序来实现 在Linux中它们也被映射为文件系统的一个节点 常在 dev目录下 应用程序对于字符设备的每一个I O操作 都会直接传递给系统内核对应的驱动程序 字符设备驱动程序一般要包含open close read write等几个系统调用 Eg 如串口 触摸屏 并口 虚拟控制台 AD等 字符设备 设备驱动分类 Linux的块设备通常是指可以容纳文件系统的存储设备 与字符设备类似 块设备也是通过文件系统来进行访问 它们之间的区别仅仅在于内核内部管理数据的方式不同 Linux中的块设备包含整数个块 每个块包含2的几次幂的字节 应用程序对于块设备的操作 要经过系统的缓冲区管理 间接传递给驱动程序处理 Eg 诸如磁盘 内存 Flash等 块设备 设备驱动分类 网络接口设备比较复杂 通常它们指的是硬件设备 但有时也可是一个软件设备 如回环接口loopback 由内核中网络子系统驱动 负责发送和接收数据包 而且它并不需要了解每一项事务是如何映射到实际传送的数据包的 在Linux中采用给网络接口设备分配一个唯一名字的方法来访问该设备 Eg eth0等 网络接口设备 驱动开发简介设备驱动分类Linux下字符型设备管理Linux驱动编译和加载方式Linux内核模块结构介绍简单Linux字符型设备驱动程序驱动程序与应用程序的区别字符型设备驱动demo分析 3 6驱动程序原理与开发 Linux下字符型设备管理 设备文件的概念来统一对设备的访问接口 在引入设备文件系统 devfs 之前Linux将设备文件放在 dev目录下 设备的命名一般为设备文件名 数字或字母表示的子类 例如 dev hda1 dev hda2 dev ttyS0等 在LINUX 2 4 2 6内核中引入了设备文件系统 devfs 所有的设备文件作为一个可以挂装的文件系统 这样就可以被文件系统进行统一管理 从而设备文件就可以挂装到任何需要的地方 命名规则也发生了变化 一般将主设备建立一个目录 再将具体的子设备文件建立在此目录下 Eg 串口1设备为 dev tts 0 设备文件及设备文件系统概念 Linux下字符型设备管理 传统方式中的设备管理中 除了设备类型外 内核还需要一对称作主次设备号的参数 才能唯一标识一个设备 主设备号相同的设备使用相同的驱动程序 次设备号用于区分具体设备的实例 设备操作宏MAJOR 和MINOR 可分别用于获取主次设备号 宏MKDEV 用于将主设备号和次设备号合并为设备号 这些宏定义在include linux kdev t h中 主设备号和对应的驱动程序系统会将其记录在 proc devices里 主设备号和次设备号 1 2 Linux下字符型设备管理 系统增加一个驱动程序就要赋予它一个主设备号 这一赋值过程在驱动程序的初始化过程中进行 对于字符设备 intregister chrdev unsignedintmajor constchar name structfile operations fops 主设备号和次设备号 2 2 Linux下字符型设备管理 mnt yaffs ls dev lcrw 1rootroot5 1Jan100 00consolecrw r 1rootroot1 4Jan100 00portcrw 1rootroot108 0Jan100 00pppcrw rw rw 1rootroot5 0Jan100 00ttycrw 1rootroot4 64Jan100 11ttyS0crw 1rootroot4 65Jan100 00ttyS1crw rw rw 1rootroot1 5Jan100 00zero 查看 dev目录下的设备的主次设备号 Linux下字符型设备管理 为该模块建立一个设备节点 命令 mknod dev tsc2540其中 dev ts表示我们的设备名是ts c 说明它是字符设备 254 是主设备号 0 是次设备号 一旦通过mknod创建了设备文件 它就一直保留下来 除非我们手工删除它 手工设备管理 Linux下字符型设备管理 动态分配 初始化时动态分配设备号 在Documentation devices txt文件中可以找到已经静态分配给大部分设备的列表由于许多数字已经分配了 为新设备选择一个唯一的号码是很困难的如果调用register chrdev时的major为零 函数就会选择一个空闲号码并做为返回值返回 动态管理 1 2 Linux下字符型设备管理 动态分配的主设备号不能保证总是一样的 无法事先创建设备节点可以从 proc devices读取cat proc devices利用脚本动态创建设备文件节点 动态管理 2 2 Linux下字符型设备管理 在Linux2 4的内核里引入了devfs来解决linux下设备文件管理的问题在驱动程序中通过devfs register 函数创建设备文件系统的节点其原型为 devfs register devfs handle tdir constchar name unsignedintflags unsignedintmajor unsignedintminor umode tmode void ops void info 系统启动的时候mount设备文件系统所有需要的设备节点都由内核自动管理 dev目录下只有挂载的设备注 在linux 2 6 12之后的内核的解决办法 udev文件系统http www kernel org pub linux utils kernel hotplug udev html 使用设备文件系统 devfs Linux下字符型设备管理 udev完全在用户态 userspace 工作 利用设备加入或移除时内核所发送的hotplug事件 event 来工作 关于设备的详细信息是由内核输出 export 到位于 sys的sysfs文件系统的 所有的设备命名策略 权限控制和事件处理都是在用户态下完成的 与此相反 devfs是作为内核的一部分工作的 使用设备文件系统 udev 驱动开发简介设备驱动分类Linux下字符型设备管理Linux驱动编译和加载方式Linux内核模块结构介绍简单Linux字符型设备驱动程序驱动程序与应用程序的区别字符型设备驱动demo分析 3 6驱动程序原理与开发 Linux驱动编译和加载方式 一种是直接编译到内核 当内核启动之后 新的驱动程序随之运行 二是编译为模块 动态加载运行对模块操作需要使用module utiles insmod将编译的模块直接插入内核rmmod从内核中卸载模块lsmod显示已安装的模块gcc编译参数 D KERNEL DMODULE I KERNELDIR INCLUDE 在调试的过程中一般使用模块动态加载的方式 它的调试效率较高 当驱动调试完成后 在发行的过程就集成进内核 但编译进内核是某些驱动运行的唯一方法 例如 console驱动 flash驱动和对至少一种文件系统的支持等等 Eg DA实验 insmodda o CAN实验 insmodcan o Linux驱动编译和加载方式 驱动开发简介设备驱动分类Linux下字符型设备管理Linux驱动编译和加载方式Linux内核模块结构介绍简单Linux字符型设备驱动程序驱动程序与应用程序的区别字符型设备驱动demo分析 3 6驱动程序原理与开发 Linux内核模块结构介绍 include 所有模块都需要的头文件 include init 内核模块的基本框架 1 2 Linux内核模块结构介绍 staticvoid exithello exit void printk Hellomoduleexit n module init hello init module exit hello exit 内核模块的基本框架 2 2 Linux内核模块结构介绍 gcc D KERNEL DMODULE DLINUX I usr src linux2 4 include c ohello ohello cinsmod hello o rmmodhello 内核模块的编译和加载 驱动开发简介设备驱动分类Linux下字符型设备管理Linux驱动编译和加载方式Linux内核模块结构介绍简单Linux字符型设备驱动程序驱动程序与应用程序的区别字符型设备驱动demo分析 3 6驱动程序原理与开发 简单Linux字符型设备驱动程序 驱动程序在Linux内核中往往是以模块形式出现的 与应用程序的执行过程不同 模块通常只是预先向内核注册自己 当内核需要时响应请求 内核模块的编译和加载 简单Linux字符型设备驱动程序 设备驱动程序流程图 简单Linux字符型设备驱动程序 重要的数据结构 file operations 1 3 说明 设备驱动程序接口 file operations数据结构通常所说的设备驱动程序接口是指结构file operations结构 它定义在include linux fs h中 file operations结构是整个Linux内核的重要数据结构 简单Linux字符型设备驱动程序 重要的数据结构 file operations 2 3 structfile operations structmodule owner ssize t read structfile char size t loff t ssize t write structfile constchar size t loff t int ioctl structinode structfile unsignedint unsignedlong int open structinode structfile int release structinode structfile 简单Linux字符型设备驱动程序 重要的数据结构 file operations 3 3 应用 标记化 方法为该结构进行初始化 staticstructfile operationss3c44b0 fops owner THIS MODULE open s3c44b0 ts open read s3c44b0 ts read release s3c44b0 ts release 简单Linux字符型设备驱动程序 重要的数据结构 file 说明 file结构定义在头文件linux fs h中 它代表一个打开的文件 由内核在调用open时创建 并传递给在该文件上进行操作的所有函数 直到最后的close函数被调用 在文件的所有实例都关闭时 内核释放这个数据结构 注 与inode的区别 inode表示磁盘文件 而file表示一个打开的文件 简单Linux字符型设备驱动程序 设备注册 驱动程序模块通过函数register chrdev来完成向内核注册的 intregister chrdev unsignedintmajor constchar name structfile operations fops 其中unsignedintmajor为主设备号 constchar name为设备名 structfile operations fops为文件操作结构指针 简单Linux字符型设备驱动程序 设备卸载 驱动程序模块通过函数unregister chrdev来完成向内核卸载的 intunregister chrdev unsignedintmajor constchar name 其中unsignedintmajor为主设备号 constchar name为设备名 简单Linux字符型设备驱动程序 打开设备 驱动程序模块通过函数open来完成打开设备的 提供给驱动程序初始化设备的能力 为后续的操作做准备此外一般会递增使用计数 防止文件关闭前模块被卸载通常情况下 open完成如下工作 递增使用计数检查特定设备错误如果设备是首次打开 则对其进行初始化识别次设备号 如有必要 则修改f op指针分配并填写filp private data中的数据 简单Linux字符型设备驱动程序 释放设备 驱动程序模块通过函数release来完成释放设备的 与open正好相反释放由open分配的filp private data中的数据在最后一次关闭操作时关闭设备使用计数减一 简单Linux字符型设备驱动程序 读写设备 1 3 read函数将数据从内核拷贝到应用程序空间 write函数则将数据从应用程序空间拷贝到内核 ssize tread structfile filp char user buff size tcount loff t offp ssize twrite structfile filp char user buff size tcount loff t offp 其中 filp是文件指针 count是请求传输的数据长度 参数buff是指向用户空间的缓存区 这个缓存区或者保存要写入的数据 或者是一个存放新读入数据的空缓冲区 最后的offp是一个指向 longoffsettype 长偏移量类型 对象的指针 这个对象指明用户在文件中进行存取操作的位置 简单Linux字符型设备驱动程序 读写设备 2 3 注 buff为用户空间的地址指针 内核代码不能直接引用其中的内容原因 用户空间的指针可能是无效的 该地址可能根本就无法映射到内核空间用户空间的内存可以被换出 因此可能会出现页面失效的问题从安全角度考虑解决办法 使用内核函数进行数据拷贝 简单Linux字符型设备驱动程序 解决函数 unsignedlongcopy to user void to constvoid from unsignedlongcount unsignedlongcopy from user void to constvoid from unsignedlongcount 其中 to表示数据目的缓冲区from表示数据源缓冲区count表示数据长度返回值 成功 返回数据长度失败 返回 EFAULT这两个函数不仅要拷贝数据 还要检查指针有效性 读写设备 3 3 简单Linux字符型设备驱动程序 ioctl函数 int ioctl structinode inode structfile filp unsignedintcmd unsignedlongarg 其中 inode和filp对应于应用程序传过来的文件描述符fd cmd是用户空间传递给驱动程序的命令 arg为附加的命令参数 读写以外的I O操作 简单Linux字符型设备驱动程序 printk函数 intprintk constchar fmt 其中 fmt为日志级别返回值 成功 返回1 失败 返回 1 如 printk KERN DEBUG HereIam s i n FILE LINE 打印信息 简单Linux字符型设备驱动程序 驱动程序的编译 加载及卸载 驱动程序的编译以demo c为例Makefile的形式命令行的形式 root RedHatAS gcc c D KERNEL DMODULE I usr src linux 2 4 includedemo c odemo o加载驱动 root RedHatAS insmoddemo o卸载驱动 root RedHatAS rmmoddemo o 简单Linux字符型设备驱动程序 驱动程序的编译 加载及卸载说明 依赖关系问题当模块与内核链接时 insmod会检查模块和当前内核版本是否匹配 每个内核版本都需要特定版本的编译器的支持 高版本的编译器并不适合低版本的内核 简单Linux字符型设备驱动程序 驱动程序的测试 test c include include includeintmain intfd fd open dev demo O RDWR if fd 0 exit fd yourcodehereread fd buffer size write fd buffer size close fd return0 驱动开发简介设备驱动分类Linux下字符型设备管理Linux驱动编译和加载方式Linux内核模块结构介绍简单Linux字符型设备驱动程序驱动程序与应用程序的区别字符型设备驱动demo分析 3 6驱动程序原理与开发 驱动程序与应用程序的区别 应用程序一般有一个main函数 从头到尾执行一个任务 驱动程序却不同 它没有main函数 通过使用宏module init 初始化函数名 将初始化函数加入内核全局初始化函数列表中 通过宏module exit 退出处理函数名 注册退出处理函数 驱动程序与应用程序的区别 1 2 驱动程序与应用程序的区别 应用程序可以和GLIBC库连接 因此可以包含标准的头文件 比如 等 在驱动程序中是不能使用标准C库的 因此不能调用所有的C库函数 只能调用内核的函数 eg 比如输出打印函数只能使用内核的printk函数 包含的头文件只能是内核的头文件 比如 驱动程序与应用程序的区别 2 2 驱动开发简介设备驱动分类Linux下字符型设备管理Linux驱动编译和加载方式Linux内核模块结构介绍简单Linux字符型设备驱动程序驱动程序与应用程序的区别字符型设备驱动demo分析 3 6驱动程序原理与开发 字符型设备驱动demo分析 include include include include printk include everything include errorcodes include size t include includ
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 租房合同物业管理协议
- 盛业保理协议签订合同
- 美甲店活动协议书范本
- 监理人员安全合同范本
- 眼镜模板购销合同范本
- 血清实验室检测协议书
- 福特汽车买卖合同范本
- 第一课 智能化的互联网教学设计-2025-2026学年初中信息科技西交大版2024七年级下册-西交大版2024
- 物业绿植养护合同范本
- 阀门成品采购合同范本
- 出库单模板电子版
- 木糖醇的生产工艺设计综述-课程设计
- 高血压的防治健康宣教
- MBEC项目管理标准手册
- WB/T 1087-2018煤炭仓储设施设备配置及管理要求
- GB/T 2566-2010低煤阶煤的透光率测定方法
- GB/T 13277.4-2015压缩空气第4部分:固体颗粒测量方法
- GB/T 11032-2020交流无间隙金属氧化物避雷器
- 社会保障概论讲义课件
- 三级安全培训记录表 (个人档案)
- 2023门球竞赛规则电子版图文并茂
评论
0/150
提交评论