Tiny6410开发板下块设备驱动程序的编写驱动之用内存模拟磁盘(一)
来源:互联网 发布:阿城 作家 知乎 编辑:程序博客网 时间:2024/06/07 09:27
开发平台:友善Tiny6410开发板 内核版本linux-2.6.38
参考韦东山老师二期视频
1th : 驱动程序框架
/* 参考:
* drivers\block\xd.c
* drivers\block\z2ram.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/mutex.h>
#include <linux/blkpg.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/gfp.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/dma.h>
static struct gendisk *ramblock_disk;
struct request_queue *ramblock_queue;
static int major;
static DEFINE_SPINLOCK(ramblock_lock);
static const struct block_device_operations ramblock_fops = {
.owner = THIS_MODULE,
};
#define RAMBLOCK_SIZE (1024*1024)
static void do_ramblock_request (struct request_queue * q)
{
static int cnt = 0;
printk("do_ramblock_request %d\n",++cnt);
}
static int ramblock_init(void)
{
/* 1. 分配一个gendisk结构体 */
ramblock_disk = alloc_disk(16); /* 次设备号个数: 分区个数+1 */
/* 2. 设置 */
/* 2.1 分配/设置队列: 提供读写能力 */
ramblock_queue = blk_init_queue(do_ramblock_request, &ramblock_lock);
ramblock_disk->queue = ramblock_queue;
/* 2.2 设置其他属性: 比如容量 */
major = register_blkdev(0, "ramblock"); /* cat /proc/devices */
ramblock_disk->major = major;
ramblock_disk->first_minor = 0;
sprintf(ramblock_disk->disk_name, "ramblock");
ramblock_disk->fops = &ramblock_fops;
set_capacity(ramblock_disk, RAMBLOCK_SIZE / 512);
/* 3. 注册 */
add_disk(ramblock_disk);
return 0;
}
static void ramblock_exit()
{
unregister_blkdev(major, "ramblock");
del_gendisk(ramblock_disk);
put_disk(ramblock_disk);
blk_cleanup_queue(ramblock_queue);
}
module_init(ramblock_init);
module_exit(ramblock_exit);
测试1th 此时由于do_ramblock_request() 函数没有做任何操作,加载模块后没有返回
2th
要参照自己的linux内核源代码来改动韦老师的驱动程序,主要是改动do_ramblock_request()函数
韦老师代码:
static void do_ramblock_request(request_queue_t * q)
{
static int cnt = 0;
struct request *req;
printk("do_ramblock_request %d\n", ++cnt);
while ((req = elv_next_request(q)) != NULL) {
end_request(req, 1);
}
}
改动之后:
static void do_ramblock_request (struct request_queue * q)
{
static int cnt = 0;
struct request *req;
printk("do_ramblock_request %d\n",++cnt);
req = blk_fetch_request(q);
while(req)
{
/* wrap up, 0 = success, -errno = fail */
if (!__blk_end_request_cur(req, 0))
req = blk_fetch_request(q);
}
将elv_next_request()改成blk_fetch_request() ; end_request(req,1)改成blk_end_request_cur(req,0)
此时可以正常退出
- Tiny6410开发板下块设备驱动程序的编写驱动之用内存模拟磁盘(一)
- Tiny6410开发板下块设备驱动程序的编写驱动之用内存模拟磁盘(二)
- Linux驱动开发----块设备驱动(内存模拟)Tiny6410
- 快设备驱动程序之是内存模拟的磁盘支持格式化
- 快设备驱动程序之是内存模拟的磁盘支持格式化
- 块设备驱动1—用内存模拟磁盘
- Linux驱动程序开发之三----按键驱动(Tiny6410)
- 编写块设备驱动之内存模拟磁盘
- linux块设备驱动程序分析之 nor flash驱动分析 以及使用内存模拟 nor flash
- Linux设备驱动开发基础---字符设备驱动程序开发之基于中断的按键驱动
- Hasen的linux设备驱动开发学习之旅--增加了并发控制的设备驱动程序
- linux设备驱动开发学习之旅--增加了并发控制的设备驱动程序
- Windows之磁盘的设备驱动堆叠
- Linux驱动程序开发 - 设备驱动模型初探(一)
- 基于VxBus设备驱动程序架构的设备驱动开发
- Tiny6410 简单的设备驱动helloworld_driver
- Tiny6410 简单的LED字符设备驱动
- Tiny6410 简单的LED字符设备驱动
- <Win32 API> 发送消息 SendMessage/PostMessage
- LeetCode OJ 之 Majority Element (“大部分”元素)
- C++中的类所占内存空间总结
- autolayout
- 动态链接库的路径及依赖
- Tiny6410开发板下块设备驱动程序的编写驱动之用内存模拟磁盘(一)
- 堆栈溢出问题
- 如何对某项知识进行深入学习——从《程序员的思维修炼》中SQ3R阅读法想到的
- 选择排序与冒泡排序
- Emmet快捷键
- 双链表示例
- 字符串匹配--Sunday算法
- Linux 字符驱动设备的测试案例
- [ACM] HDU 5137 How Many Maos Does the Guanxi Worth(去掉一个点使得最短路最大化)