操作系统——linux文件系统初实现——为fileSystem添加驱动,让linux可以识别。

0、我的理解,所为驱动,就是用户可以通过自己的应用程序访问你的文件系统。而我恰恰相反。

1、我是谢了字符驱动,让我的fileSystem去做应用程序,同样可以被linux系统识别。

2、其实我对驱动理解也不深,暂且贴代码。

3、驱动程序:

/*chardev.c 驱动程序*/
#include <linux/kernel.h>
#include <linux/fs.h>/*for file-f_op*/
#include <linux/module.h>
#include <asm/uaccess.h>/*for copy_to_user()*/
#include <linux/cdev.h>/*for cdev ,cdev_init,cdev_add....*/

MODULE_AUTHOR("MMC");
MODULE_LICENSE("GPL");

#define DP_MAJOR 250  /*the major number of the chardev*/
#define DP_MINOR 0    /*the minor number of the chardev*/
#define CHARDEV_SIZE 512*500

static int chropen;/*the chardev open or not*/
struct cdev *chardev;/*define a char device*/

char char_dev_data[CHARDEV_SIZE];

static int char_read(struct file *filp, char __user *buffer, size_t, loff_t *);
/*read the data from kernel*/
static int char_write(struct file *filp, const char __user *buffer, size_t, loff_t *);
/*write data to kernel*/
static int char_open(struct inode *,struct file *);
/*open the chardev*/
static int char_release(struct inode *, struct file *);
/*release the chardev*/
static loff_t char_llseek(struct file *filp, loff_t offset, int whence);

/*文件操作结构体*/
static const struct file_operations char_fops =
{
.owner = THIS_MODULE,
.llseek = char_llseek,
.read = char_read,
.write = char_write,
.open = char_open,
.release = char_release,
};

static int __init char_init(void)
{
    dev_t devno;
    printk(KERN_ALERT"Initing......\n");
    devno=MKDEV(DP_MAJOR,DP_MINOR);
    chardev=cdev_alloc( );

    if(chardev==NULL)
    {
        return -1;
    }
    if(register_chrdev_region(devno,10,"chardev"))//注册设备号
    {
        printk(KERN_ALERT"Register char dev error\n");
        return -1;
    }
    chropen=0;
    cdev_init(chardev,&char_fops);//初始化cdev
    if(cdev_add(chardev,devno,1))//添加cdev到系统
    {
        printk(KERN_ALERT"Add char dev error\n");
    }

    memset(char_dev_data, 0, CHARDEV_SIZE);//set data 

    return 0;
}

/*文件打开函数*/
static int char_open(struct inode *inode, struct file *file)
{
    if(chropen==0)
    {
        chropen++;
    }
    else
    {
        printk(KERN_ALERT"Another process open the char device\n");
        return -1;
    }
    try_module_get(THIS_MODULE);
    return 0;
}

/*读函数*/
static ssize_t char_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
{
    unsigned long p = *ppos;/*记录文件指针偏移位置*/
      unsigned int count = size;/*记录需要读取的字节数*/
    int ret = 0;/*返回值*/

    /*判断读位置是否有效*/
      if (p >= CHARDEV_SIZE)/*要读取的偏移大于设备的内存空间*/
        return -1;
    if (count > CHARDEV_SIZE - p)/*要读取的字节大于设备的内存空间*/
        count = CHARDEV_SIZE - p;

    /*读数据到用户空间:内核空间->用户空间交换数据*/
    if (copy_to_user(buf, char_dev_data + p, count))
    {
        ret = -EFAULT;
    }
    else
    {
        *ppos += count;
        ret = count;
        printk(KERN_INFO "read %d bytes(s) from %d\n", count, p);
    }
      return ret;
}

/*写函数*/
static ssize_t char_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos)
{
    unsigned long p = *ppos;
    unsigned int count = size;
    int ret = 0;

    /*分析和获取有效的写长度*/
    if (p >= CHARDEV_SIZE)
        return -1;
    if (count > CHARDEV_SIZE - p)/*要写入的字节大于设备的内存空间*/
        count = CHARDEV_SIZE - p;

    /*从用户空间写入数据*/
    if (copy_from_user(char_dev_data + p, buf, count))
        ret = -EFAULT;
    else
    {
        *ppos += count;      /*增加偏移位置*/
        ret = count;      /*返回实际的写入字节数*/
            printk(KERN_INFO "written %d bytes(s) from %d\n", count, p);
    }

      return ret;
}

/* seek文件定位函数 */
static loff_t char_llseek(struct file *filp, loff_t offset, int whence)
{
    loff_t newpos;

    switch(whence)
    {
    case 0: /* SEEK_SET */    /*相对文件开始位置偏移*/
        newpos = offset;    /*更新文件指针位置*/
            break;

          case 1: /* SEEK_CUR */
            newpos = filp->f_pos + offset;
            break;

          case 2: /* SEEK_END */
            newpos = CHARDEV_SIZE -1 + offset;
            break;

          default: /* can‘t happen */
            return -EINVAL;
        }
        if ((newpos<0) || (newpos>CHARDEV_SIZE))
            return -EINVAL;

        filp->f_pos = newpos;
        return newpos;
}

/*文件释放函数*/
static int char_release(struct inode *inode, struct file *file)
{
    chropen--;
    module_put(THIS_MODULE);
    return 0;
}

static void __exit char_exit(void)
{
    printk(KERN_ALERT"Unloading..........\n");

    unregister_chrdev_region(MKDEV(DP_MAJOR,DP_MINOR),10);//注销cdev设备号
    cdev_del(chardev);//从系统删除设备cdev
}

module_init(char_init);
module_exit(char_exit);

4、Makefile:

ifneq ($(KERNELRELEASE),)

obj-m := chardev.o

else

KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

default:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

endif

5、配置命令:

1)创建Makefile文件:

2)执行make命令:
[email protected]-vm:/usr/mmc/dirPro/charDri# make

3)将生成的驱动模块插入内核:
[email protected]-vm:/usr/mmc/dirPro/charDri# insmod ./chardev.ko

4)查看插入后的情况:
[email protected]-vm:/usr/mmc/dirPro/charDri# lsmod

5)设备节点的创建:
[email protected]-vm:/usr/mmc/dirPro/charDri# mknod /dev/chardev0 c 250 0

6)编译用户程序gcc -o chardev_test main.c
[email protected]-vm:/usr/mmc/dirPro/charDri# gcc -o test test.c -std=c99

7)运行chmod 666 /dev/chardev0 使其它用户也可以对这个设备进行读写操作,否则只有root用户可以对它进行读写。
[email protected]-vm:/usr/mmc/dirPro/charDri# chmod 666 /dev/chardev0

8)运行test
[email protected]-vm:/usr/mmc/dirPro/charDri# ./test

9)删除设备节点,就像删除普通文件一样:
[email protected]-vm:/usr/mmc/dirPro/charDri# rm /dev/chardev0

10)卸载内核驱动模块
[email protected]-vm:/usr/mmc/dirPro/charDri# rmmod chardev.ko

11)重新运行test,观察结果

12)重新插入内核驱动模块和设备节点,又可以正常显示结果

6、测试程序:

刚才说了,就是filesystem的程序,但是需要把之前的fopen、fclose、fwrite、fread、fseek改为系统调用函数open、close、write、read、lseek即可。

//fileSystemPointer=fopen(fileSystemName,"wb");//读写打开一个二进制文件
fileSystemPointer=open(fileSystemName, O_RDWR, S_IRUSR|S_IWUSR);

//fseek(fileSystemPointer,0,SEEK_SET);
lseek(fileSystemPointer,0,SEEK_SET);
//fwrite(&superBlock,sizeof(struct SuperBlock),1,fileSystemPointer);//4个BLOCK
write(fileSystemPointer,&superBlock,sizeof(struct SuperBlock));//4个BLOCK

7、参考资料:

LINUX设备驱动程序(第3版)(完整版).pdf

操作系统——linux文件系统初实现——为fileSystem添加驱动,让linux可以识别。,布布扣,bubuko.com

时间: 2024-11-03 22:38:37

操作系统——linux文件系统初实现——为fileSystem添加驱动,让linux可以识别。的相关文章

操作系统——linux文件系统初实现

简述: 0.ext2格式. 1.包括权限管理,精确到角色. 2.数据块采用连续分配(离散分配大家来弄吧). 3.为实现间接索引,相信实现了目录,简介索引也不是问题吧.. 4.删除目录不支持递归删除.自己写去吧. 5.整体结构: 6.主要数据结构: //超级块 struct SuperBlock { int s_block_count;//block总个数 int s_block_size;//block块的大小 int s_inode_count;//inode总个数 int s_datablo

Vs2012在Linux开发中的应用(13): 添加对x86 Linux的支持

快乐虾 http://blog.csdn.net/lights_joy/ 欢迎转载,但请保留作者信息 因为马上要进入Debugger的研究,为了方便对GDB的学习,先添加对虚拟机中的x86 linux的平台支持.按照先前的做法,很容易就看到结果了: 突然发现,原来的修改注册表似乎并不是必须的!! 在交叉编译器参数中直接留空: 看编译结果: 搞定!!! 

Linux内核驱动学习(二)----根文件系统的构成 (root filesystem)

1.建立根文件系统目录和文件 1.1创建目录 1.2创建设备文件(命令mknod):必须创建设备文件---consle\null 1.3创建配置文件---复制已有的/etc目录下的文件 1.4添加内核模块 进入Linux内核目录下,(注意,应该先编译内核,即命令make uImage ARCH=arm  CROSS_COMPILE=arm-linux-) 1.4.1.编译内核模块---命令 make modules ARCH=arm CROSS_COMPILE=arm-linux- 1.4.2.

【转】LINUX文件系统剖析

引自:http://www.ibm.com/developerworks/cn/linux/l-linux-filesystem/   在文件系统方面,Linux? 可以算得上操作系统中的 "瑞士军刀".Linux 支持许多种文件系统,从日志型文件系统到集群文件系统和加密文件系统.对于使用标准的和比较奇特的文件系统以及开发文件系统来说,Linux 是极好的平台.本文讨论 Linux 内核中的虚拟文件系统(VFS,有时候称为虚拟文件系统交换器),然后介绍将文件系统连接在一起的主要结构.

磁盘、分区及Linux文件系统

1.磁盘基础知识 1.1 物理结构 硬盘的物理结构一般由磁头与碟片.电动机.主控芯片与排线等部件组成:当主电动机带动碟片旋转时,副电动机带动一组(磁头)到相对应的碟片上并确定读取正面还是反面的碟面,磁头悬浮在碟面上画出一个与碟片同心的圆形轨道(磁轨或称柱面),这时由磁头的磁感线圈感应碟面上的磁性与使用硬盘厂商指定的读取时间或数据间隔定位扇区,从而得到该扇区的数据内容.所有的盘片都固定在一个旋转轴上,这个轴即盘片主轴.而所有盘片之间是绝对平行的,在每个盘片的存储面上都有一个磁头,磁头与盘片之间的距

Linux文件系统详解(文件系统层次、分类、存储结构、存储介质、文件节点inode)

从操作系统的角度详解Linux文件系统层次.文件系统分类.文件系统的存储结构.不同存储介质的区别(RAM.ROM.Flash).存储节点inode. 本文参考:http://blog.chinaunix.net/uid-8698570-id-1763151.html http://www.iteye.com/topic/816268 http://soft.chinabyte.com/os/142/12315142.shtml http://www.ibm.com/developerworks/

linux文件系统相关资料

linux下文件系统通常是通过虚拟文件系统(VFS)蔽下层具体文件系统操作的差异,为上层的操作提供一个统一的接口.文件系统底层都是用系统IO缓存层提供的块读写接口,实现逻辑块到物理块的映射.作为应用程序底层的存储逻辑,通用文件系统的目的是提供目录/文件形式的逻辑到物理磁盘的映射.  文件系统本质上是磁盘块的逻辑组织方式. ext2文件系统使用组描述符,块位图,索引节点位图,索引节点表,数据区等组织磁盘空间,每个索引节点代表一个文件,存有该文件占用的磁盘块的位置.在Ext2中,目录是一种特殊的文件

Linux 文件系统的目录结构

 Linux下的文件系统为树形结构,入口为/ 树形结构下的文件目录: 无论哪个版本的Linux系统,都有这些目录,这些目录应该是标准的.各个Linux发行版本会存在一些小小的差异,但总体来说,还是大体差不多. 1. / 文件系统的入口,最高一级目录: 2. /bin 基础系统所需要的命令位于此目录,是最小系统所需要的命令,如:ls, cp, mkdir等.这个目录中的文件都是可执行的,一般的用户都可以使用. 3. /boot 包含Linux内核及系统引导程序所需要的文件,比如 vmlinuz i

[转] Linux文件系统详解

从操作系统的角度详解Linux文件系统层次.文件系统分类.文件系统的存储结构.不同存储介质的区别(RAM.ROM.Flash).存储节点inode.本文参考: http://blog.chinaunix.net/uid-8698570-id-1763151.html http://www.iteye.com/topic/816268 http://soft.chinabyte.com/os/142/12315142.shtml http://www.ibm.com/developerworks/