您的位置  > 互联网

pos文件文件的读写位置和数据应用程序空间分析

#

#

#

#

#

#

#

#

#

#

#

#“演示.h”

(“fgj”);

(“双 BSD/GPL”);

//很郁闷的是,即使移植到开发板上,还是说这个驱动污染了内核。

*;

//声明自己定义的设备结构体的指针

字符=0;

//统计并记录该设备被打开的次数

u8[256];

//内核中的数据结构和数据类型真是奇怪。 这个u8确实让人费解。 结果是一个无符号的8位数据类型。

//

int(索引节点*索引节点,文件*filp)

*开发;

//只允许设备打开一次

如果(>0)-;

++;

/* 宏通过结构体中的变量获取结构体本身的指针

%CE%DA%D1%BB%C3%F7/blog/item/ade3.html

太高级了,我看不懂。

*/

dev = (inode->, , cdev);

filp-> = dev;

0;

int(索引节点*索引节点,文件*filp)

--;

0;

(文件*filp,字符*buf,计数,*f_pos)

整数;

位置=*f_位置; /* 文件的读写位置*/

如果(位置>=256)

=0;

转到出去;

if(计数>(256-位置))

计数=256位;

pos += 计数;

if ((buf,+*f_pos,计数))

计数=-; /* 向应用程序空间写入数据*/

转到出去;

*f_pos = pos; /* 改变文件的读写位置 */

出去:

数数;

(文件 *filp,const char *buf,计数,*f_pos)

=-; /* “goto out” 中使用的值 */

位置=*f_位置;

如果(位置>=256)

转到出去;

//如果要写入的输入大于剩余内存空间,则只写入剩余空间,防止溢出。

if(计数>(256-位置))

计数=256位;

//如果C语言扎实的话,剩下的代码不难理解。 抱歉我的表达能力不好。

pos += 计数;

// 原文说的是复制数据到用户空间。 我认为它应该将数据复制到内核空间。 这应该是作者的笔误。 没什么大不了的。

if ((+*f_pos, buf, 计数)) {

=-;

转到出去;

*f_pos = pos;

数数;

出去:

;

/*这几天我才粗略了解了ioctl的作用。 ioctl 用于控制设备。 int cmd 是发送到设备的命令。

ioctl()可能是Linux中最复杂的函数*/

int(inode *inode,文件*filp,int cmd,长arg)

如果(cmd==)

(“ioctl /n”);

0;

如果(cmd==)

(“ioctl /n”);

0;

(“ioctl错误/n”);

-;

// 为了实现随机访问,这段代码应该是一个无符号整数来记录文件指针偏移量。 参考用户态的seek()就不难理解了。

(文件*filp,关闭,int)

位置;

pos = filp->f_pos;

()

案例0:

位置=关闭;

休息;

情况1:

pos += 关闭;

休息;

案例2:

:

-;

如果 ((pos>256) || (pos {

-;

filp->f_pos=pos;

//这个结构体非常重要,我们需要了解它的作用

= {

.所有者 = ,

。 = ,

.读=,

.写=,

.ioctl = ,

.打开=,

。 = ,

};

/******************************************************** ***** *****

****************************************************** * *****/

无效(无效)

//下面入口函数讲MKDEV

dev_t devno = MKDEV(, );

如果()

(&->cdev);

//内核下的内存操作函数确实很奇怪,习惯就好

kfree();

//调用gion()函数释放一系列分配的设备号

祗园(devno,1);

整数(空)

整数;

// 在内核中,dev_t类型(定义于)用于保存设备号——包括主设备号和次设备号

dev_t dev = 0;

/*内核中定义了三个宏来处理主次设备号:MAJOR和MINOR宏可以从16位数字中提取主次设备号,MKDEV宏可以将主次设备号组合成16位数字数字。 。

高8位用于主设备号,低8位用于次设备号。

%E7%AC%AC%E5%8D%81%E4%B8%80%E7%AB%A0%20%20%E8%AE%BE%E5%A4%87%E9%A9%B1%E5%8A %A8%E7%A8%8B%E5%BA%8F/11.2.3.htm*/

dev = MKDEV(, );

/*获取一个或多个要使用的设备号

如果分配成功,on的返回值为0。如果分配错误,则返回负的错误码,并且无法访问所请求的区域。 */

= on(dev, 1, "演示");

如果(<0)

(“DEMO: 无法获取主要%d/n”,);

;

//为自定义设备结构申请空间

= (( ), );

如果 (!)

=-;

走向失败;

//清除新申请的空间。 我的水平只能理解这些简单的功能。

(, 0, ( ));

//初始化字符驱动程序。 我不明白这一点。 我只能做一个粗略的猜测。

//而且,一旦理解了这个结构体的功能,你就会明白为什么Linux驱动只需要实现很少的驱动。

(&->cdev, &);

->cdev.owner = ;

->cdev.ops = &;

//将字符驱动添加到内核中

= (&->cdev, dev, 1);

如果()

(“错误%d演示/n”,);

走向失败;

0;

失败:

//如果失败,调用exit函数并擦除pp。

();

;

//这两个是内核驱动指示程序进入和退出所必需的。

();

();

demo.c 文件结尾

我还不知道如何编写make文件。 我使用构建内核项目来编译该驱动程序。

下面用于编译ko文件并移植到arm9开发板()

AR=ar

ARCH = 手臂

CC = ARM-Linux-GCC

+= $() -墙

+= -I$()

= - -rpath-link /usr/local/arm/3.4.1/lib/gcc/arm-linux/3.4.1

ifneq ($(),)

obj-m:= demo-.o #模块名称

别的

KDIR:= /root/linux-2.6.12

PWD:= $(shell 密码)

:

$(MAKE) -C $(KDIR) =$(PWD)

万一

加载驱动程序

# 演示.ko

然后使用lsmod或者cat /proc/检查驱动是否加载

# mknod /dev/fgj c 224 0 创建设备节点

然后你可以使用下面的代码来测试驱动程序

/*

* 此文件符合 GNU 的条款和

*。 请参阅此文件的主要部分“”

* 了解更多。