zoukankan      html  css  js  c++  java
  • 块设备驱动框架

    以RAM模拟一个分区为例

    框架入口源文件:armblock.c

    (可根据入口源文件,再按着框架到内核走一遍)

    内核版本:linux_2.6.22.6     硬件平台:JZ2440

    以下是驱动代码  armblock.c :

    #include <linux/module.h>
    #include <linux/errno.h>
    #include <linux/interrupt.h>
    #include <linux/mm.h>
    #include <linux/fs.h>
    #include <linux/kernel.h>
    #include <linux/timer.h>
    #include <linux/genhd.h>
    #include <linux/hdreg.h>
    #include <linux/ioport.h>
    #include <linux/init.h>
    #include <linux/wait.h>
    #include <linux/blkdev.h>
    #include <linux/blkpg.h>
    #include <linux/delay.h>
    #include <linux/io.h>
    
    #include <asm/system.h>
    #include <asm/uaccess.h>
    #include <asm/dma.h>
    
    
    // ram_block_disk  独立的磁盘设备或则分区
    static struct gendisk *ram_block_disk;
    
    //定义一个request_queue 结构体
    static struct request_queue *ram_block_req;
    
    //定义一个自旋锁
    static DEFINE_SPINLOCK(ramblock_lock);
    
    
    //定义一个主设备号
    static int major;
    
    //磁盘大小
    #define GENDISK_SIZE (1024*1024)  
    
    //缓存起始地址
    static unsigned char *gendisk_buffer;
    
    //getgeo 获得驱动器信息
    static int gendisk_getgeo(struct block_device *dev, struct hd_geometry *geo)
    {
      geo->heads = 2;
      geo->cylinders = 32;
      geo->sectors = (GENDISK_SIZE/2/32/512);
      return 0;
    }
    
    
    static struct block_device_operations gendisk_fops=
    {
       .owner = THIS_MODULE,
       .getgeo = gendisk_getgeo,
    };
    
    //请求函数
    static void ram_block_req_fn(request_queue_t * q)
    {
        struct request *req;
        unsigned long offset=0, len=0;
        
        while((req =  elv_next_request(q))!=NULL)
        {
           offset = req->sector*512;
           len = req->current_nr_sectors*512;
           
           if(rq_data_dir(req) == READ)  memcpy( req->buffer,gendisk_buffer+offset,len  );  //read   dest src len
            else                    memcpy( gendisk_buffer+offset, req->buffer, len ); // write
    
          end_request(req,1);
        }
    }
    
    
    static int ram_block_init(void)
    {
       //申请gendisk
       ram_block_disk = alloc_disk(16);
    
       //设置gendisk
           //绑定请求函数
           ram_block_req = blk_init_queue(ram_block_req_fn,&ramblock_lock);
           ram_block_disk->queue = ram_block_req;
           //设置gendisk参数       注册blk
           major = register_blkdev(0, "armblock" );   /* cat /proc/devices */
           sprintf(ram_block_disk->disk_name, "armblock");
           ram_block_disk->fops  = &gendisk_fops;
           ram_block_disk->first_minor   = 0;
           ram_block_disk->major         = major;
           set_capacity(ram_block_disk, GENDISK_SIZE/512);
           gendisk_buffer = kzalloc(GENDISK_SIZE,GFP_KERNEL);    //磁盘起始地址
           
       //添加gendisk
       add_disk(ram_block_disk);
       return 0;
    }
    
    
    
    static void ram_block_exit(void)
    {
        del_gendisk(ram_block_disk);
        put_disk(ram_block_disk);
    
        blk_cleanup_queue(ram_block_req);
    
        unregister_blkdev(major,"armblock");
        
        kfree(gendisk_buffer);
    }
    
    module_init(ram_block_init);
    module_exit(ram_block_exit);
    
    MODULE_LICENSE("GPL");

    以下是编译驱动的Makefile:

    KERN_DIR = /work/systems/kernel/linux-2/linux-2.6.22.6
    
    all:
        make -C $(KERN_DIR) M=`pwd` modules 
    
    clean:
        make -C $(KERN_DIR) M=`pwd` modules clean
        rm -rf modules.order
    
    obj-m    += armblock.o
  • 相关阅读:
    springboot将接口内容快速生成接口文档导出,swagger将api文档以表格文档导出
    IDEA2019.2或2019.3激活码失效后重新激活教程
    Java代码自动生成,生成前端vue+后端controller、service、dao代码,根据表名自动生成增删改查功能
    百度网盘下载慢解决办法,最新.浏览器下载速度突破方法
    smartGit 版本19.1没有settings文件如何破解
    arp欺骗软件(来自互联网)
    关闭学生端v1.0(附链接)
    [TODO]multiaet/set/multimap/map
    树状数组【洛谷3374】
    luoguP1439
  • 原文地址:https://www.cnblogs.com/zsy12138/p/10392758.html
Copyright © 2011-2022 走看看