Linux Kernel学习笔记

转自:http://blog.sina.com.cn/s/blog_55465b470100eb8c.html

这里贴部分内容:

Chapter 2. 设备驱动程序开发

在编程思路上,机制表示需要提供什么功能,策略表示如何使用这些功能。区分机制和策略是UNIX设计最重要和最好的思想之一。如X系统就由X服务器和X客户端组成。X服务器实现机制,负责操作硬件,给用户程序提供一个统一的接口。而X客户端实现策略,负责如何使用X服务器提供的功能。设备驱动程序也是机制与策略分离的典型应用。在编写硬件驱动程序时,不要强加任何特定的策略。

Linux系统将设备分成三种类型,分别是字符设备、块设备和网络接口设备。

在linux中通过设备文件访问硬件,设备文件位于/dev目录下。设备文件是一种信息文件,普通文件的目的在于存储数据,设备文件的目的在于向内核提供控制硬件的设备驱动程序的信息。设备文件保存了多种信息,其中重要的有设备类型信息,主设备号(major),次设备号(minor)。主设备号与次设备号起到连接应用程序和设备驱动程序的作用。当应用程序利用open()函数打开设备文件时,内核从相应的设备文件中得到主设备号,从而查找到相应的设备驱动程序,由次设备号查找实际设备。所以主设备号对应设备驱动程序,次设备号对应由该驱动程序所驱动的实际设备。通过设备文件可以向硬件传送数据,也可从硬件接收数据。

设备文件使用mknod命令生成。mknod命令语法如下:

mknod [设备文件名] [设备文件类型] [主设备号] [次设备号]

字符设备用c表示,块设备用b表示,网络设备没有专门的设备文件。

读写设备文件时要使用低级输入输出函数,不要使用带缓冲的以f开头的流文件输入输出函数。但并不是所有低级输入输出函数都可以用在设备文件上,可以用在设备文件的低级输入输出函数有以下几个:

open() 打开文件或设备 close() 关闭文件 read() 读取数据 write() 写数据 lseek() 改变文件的读写位置 ioctl() 实现read(),write()外的特殊控制,该函数只在设备文件中使用 fsync() 实现写入文件上的数据和实际硬件的同步

Chapter 3. 字符设备驱动程序

3.1. 设备号

字符设备在系统中以设备文件的形式表示,位于/dev目录下。每个字符设备都有一个主设备号和次设备号,主设备号标识设备对应的驱动程序,次设备号标识设备文件所指的具体设备。

主次设备号的数据类型是dev_t,在/linux/types.h中定义。在2.6内核中,dev_t是一个32位的数,其中12位用来表示主设备号,其余20位用来表示次设备号。要获得设备的主次设备号可以使用内核提供的宏:

MAJOR(dev_t dev); #获得主设备号 MINOR(dev_t dev); #获得次设备号

这些宏定义位于linux/kdev_t.h中。如果要把主次设备号转换成dev_t类型,则可使用:

MKDEV(int major, int minor);

3.2. 设备号的分配和释放

在建立一个字符设备之前,需要为它分配一个或多个设备号。使用register_chrdev_region()函数完成设备号的分配。该函数在linux/fs.h中声明。原型如下:

int register_chrdev_region(dev_t first, unsigned int count, char *name); first:是要分配的主设备号范围的起始值,次设备号一般设置为0; count:是所请求的连续设备号的个数; name:是和该设备号范围关联的设备名称,它将出现在/proc/devices或/sysfs中。

如果分配成功则返回0,分配失败则返回一个负的错误码,所请求的设备号无效。

还有一个自动分配设备号的函数alloc_chrdev_region(),原型如下:

int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name); dev: 自动分配到设备号范围中的第一个主设备号; firstminor:自动分配的第一个次设备号,通常为0; count: 是所请求的连续设备号的个数; name: 是和该设备号范围关联的设备名称,它将出现在/proc/devices或/sysfs中。

如果我们不再使用设备号,则要使用unregister_chrdev_region()函数释放它。函数原型如下:

void unregister_chrdev_region(dev_t first, unsigned int count); 函数的参数作用同上

我们一般在模块的清除函数中调用设备号释放函数。

在内核源码目录的Documentation/devices.txt文件中列出了已静态分配给常用设备的主设备号。为了减少设备号分配的冲突,我们一般要使用alloc_chrdev_region()函数来自动分配设备号。

3.3. 重要的数据结构

文件操作结构:struct file_operations,在linux/fs.h中定义。它包含一组函数指针,实现文件操作的系统调用,如read、write等。每个打开的文件都和一个文件操作结构关联(通过file结构中指向file_operations结构的f_op字段进行关联)。

文件结构:struct file,在linux/fs.h中定义。file结构代表一个打开的文件,由内核在open时创建。指向文件结构的指针在内核中通常称为filp(文件指针)。当文件的所有实例都被关闭之后,内核会释放这个数据结构。

节点结构:struct inode,在linux/fs.h中定义。inode结构是内核表示文件的方法,而file结构是以文件描述符的方式表示文件的方法。结构中以下两个字段对编写驱动程序有用:

  • dev_t i_rdev,该字段包含了真正的设备编号。
  • struct cdev *i_cdev,该字段包含指向struct cdev结构的指针。

从设备的inode获取主次设备号的宏:

unsigned int iminor(struct inode *inode); unsigned int imajor(struct inode *inode);

3.4. 读和写

下面两个是字符设备读写操作最重要的内核函数。

unsigned long copy_to_user (void __user * to, const void * from, unsigned long n); 读操作,把数据从内核空间复制到用户空间,返回不能复制的字节数,如果成功则返回0。 to 目的地址,在用户空间中; from 源地址,在用户空间; n 要复制的字节数。 unsigned long copy_from_user (void * to, const void __user * from, unsigned long n); 写操作,把数据从用户空间复制到内核空间,返回不能复制的字节数,如果成功则返回0。 to 目的地址,在内核空间中; from 源地址,在用户空间; n 要复制的字节数。

Linux Kernel学习笔记,布布扣,bubuko.com

时间: 2024-10-12 17:03:19

Linux Kernel学习笔记的相关文章

linux kernel学习笔记-5内存管理(转)

http://blog.sina.com.cn/s/blog_65373f1401019dtz.htmllinux kernel学习笔记-5 内存管理1. 相关的数据结构 相比用户空间而言,在内核中分配内存往往受到更多的限制,比如内核中很多情况下不能睡眠,此外处理内存分配失败也不像用户空间那么容易.内核使用了页和区两种数据结构来管理内存: 1.1 页 内核把物理页作为内存管理的基本单位.尽管CPU的最小可寻址单位通常为字(甚至字节),但是MMU(内存管理单元,管理内存并把虚拟地址转换为物理地址的

ubuntu: qemu+gdb 调试linux kernel 学习笔记

声明: 本笔记内容并非本人原创,90%来自网络资料的整合.同时,由于自己是刚刚接触qemu & gdbserver remote debug,本文也就算不得教程,仅供有缘人参考而已. ------------------------------------------------------------------------------------------------分割线-----------------------------------------------------------

Linux程序设计学习笔记----网络通信编程API及其示例应用

转载请注明出处, http://blog.csdn.net/suool/article/details/38702855. BSD Socket 网络通信编程 BSD TCP 通信编程流程 图为面向连接的Socket通信的双方执行函数流程.使用TCP协议的通信双方实现数据通信的基本流程如下 建立连接的步骤 1.首先服务器端需要以下工作: (1)调用socket()函数,建立Socket对象,指定通信协议. (2)调用bind()函数,将创建的Socket对象与当前主机的某一个IP地址和TCP端口

Linux程序设计学习笔记----进程间通信——管道

转载请注明出处: http://blog.csdn.net/suool/article/details/38444149, 谢谢! 进程通信概述 在Linux系统中,进程是一个独立的资源管理单元,但是独立而不孤立,他们需要之间的通信,因此便需要一个进程间数据传递.异步.同步的机制,这个机制显然需要由OS来完成管理和维护.如下: 1.同一主机进程间数据交互机制:无名管道(PIPE),有名管道(FIFO),消息队列(Message Queue)和共享内存(Share Memory).无名管道多用于亲

Linux netfilter 学习笔记 之十二 ip层netfilter的NAT模块代码分析

本节主要是分析NAT模块相关的hook函数与target函数,主要是理清NAT模块实现的原理等. 1.NAT相关的hook函数分析 NAT模块主要是在NF_IP_PREROUTING.NF_IP_POSTROUTING.NF_IP_LOCAL_OUT.NF_IP_LOCAL_IN四个节点上进行NAT操作,在上一节中我们知道nat表中只有PREROUTING.POSTROUTING.LOCAL_OUT三条链,而没有NF_IP_LOCAL_IN链,所以不能创建在LOCAL_IN hook点的SNAT

Linux 操作系统学习笔记

一,unix 1.unix 特点 伸缩性强,开放性好, 2.基本原则 所有对象,硬件都是文件 配置数据以文本形式保存 短小的单目的程序构成 多个程序合作完成复杂任务 3.gnu 基本原则是共享,建立自由开放的unix系统 1984年 richard stallman 发起 基本体系是micro kernel 4.gpl Copyleft 原作者所有权 5.linux起源 Linustorvalds, 自由的类unix操作系统, 遵循gnu和gpl 6.linux 可以实现unix功能 遵循开源许

linux基础学习笔记——操作大全

作者:liaoyi 更新时间:2014-6-2 ****************基本操作***************** 关机 shutdown -h now    root用户               init 0              root用户halt      root+一般用户poweroff 重启shutdown -r now    root用户init6     root用户reboot            root+一般用户 注意:1.shutdown 比较灵活,可

linux 驱动学习笔记01--Linux 内核的编译

由于用的学习材料是<linux设备驱动开发详解(第二版)>,所以linux驱动学习笔记大部分文字描述来自于这本书,学习笔记系列用于自己学习理解的一种查阅和复习方式. #make config(基于文本的最为传统的配置界面,不推荐使用)#make menuconfig(基于文本菜单的配置界面)#make xconfig(要求 QT 被安装)#make gconfig(要求 GTK+被安装)在配置 Linux 2.6 内核所使用的 make config. make menuconfig. mak

Linux程序设计学习笔记----System V进程通信(共享内存)

转载请注明出处:http://blog.csdn.net/suool/article/details/38515863 共享内存可以被描述成内存一个区域(段)的映射,这个区域可以被更多的进程所共享.这是IPC机制中最快的一种形式,因为它不需要中间环节,而是把信息直接从一个内存段映射到调用进程的地址空间. 一个段可以直接由一个进程创建,随后,可以有任意多的进程对其读和写.但是,一旦内存被共享之后,对共享内存的访问同步需要由其他 IPC 机制,例如信号量来实现.象所有的System V IPC 对象