Linux驱动开发一:简单的驱动

本文详细介绍了如何使用Linux内核开发驱动程序,并通过测试程序验证其功能。包括驱动程序的注册、初始化、退出过程,以及如何解决加载驱动时出现的错误提示问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

first_drv.c

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
//#include <asm/arch/regs-gpio.h>
//#include <asm/hardware.h>

/* open函数  */
static int first_drv_open(struct inode *inode,struct file *file)
{
	printk("first_drv_open\n");
	return 0;
}
/* write函数  */
static ssize_t first_drv_write(struct file *file,const char __user *buf,size_t count,loff_t *ppos)
{
	printk("first_drv_write\n");
	return 0;
}

/* 结构体  */
static struct file_operations first_drv_fops={
	.owner = THIS_MODULE,/* 这是一个宏,推向编译模块时自动创建到__this_module变量  */
	.open = first_drv_open,
	.write = first_drv_write,
};

/* 入口函数  */	
int first_drv_init(void)
{
	/* 注册函数,把结构体告诉内核  */
	register_chrdev(111,"first_drv",&first_drv_fops);/* 把111该为0时,系统自动分配0~255中未被占用到设备号  */
	return 0;
}

/* 出口函数  */
void first_drv_exit(void)
{
	unregister_chrdev(111,"first_drv");

}

module_init(first_drv_init);
module_exit(first_drv_exit);
MODULE_LICENSE("GPL");


Makfile:

obj-m := first_drv.o

KER_DIR := /work/work/linux/


all:
	$(MAKE) -C $(KER_DIR) M=`pwd` modules
#	cp first_drv.ko /work/tftpboot/
	cp first_drv.ko /work/nfsroot/
	
clean:
	make -C $(KER_DIR) M=`pwd` modules clean
	


测试程序test.c

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

int main()
{
	int fd;
	int val = 1;
	
	fd = open("/dev/first_drv",O_RDWR);
	if(fd < 0)
	{
		printf("can't opent /dev/first_drv\n");
		return 0;
	}
	
	write(fd,&val,4);
	
	return 0;
	
}


1、先执行make生成驱动程序first_drv.ko

2、编译测试程序生成执行文件test

3、加载驱动insmod first_drv.ko

4、创建设备节点后测试程序才能使用

       mknod /dev/first_drv c 111 0

5、运行测试程序,结果如下:

    

/ # ./test 
first_drv_open
first_drv_write


在执行过程中遇到的问题:

1、-/bin/sh: 命令:not found的解决办法


  转载:

http://blog.chinaunix.net/uid-20539088-id-115759.htmlhttp://blog.chinaunix.net/uid-20539088-id-115759.html


按照mini2440的移植手册移植了linux内核和文件系统不同的是我用的交叉编译器是最新的4.4.1而没有用天嵌科技提供的交叉编译器,当我移植好了yaffs文件系统,想写个helloworld程序在开发板上测试下,我把编译好的helloworld文件放到yaffs文件系统的/usr/bin目录下,但当我运行/usr/bin/helloworld命令是提示“-/bin/sh: /usr/bin/helloworld: not found”,一开始我以为是helloworld没有运行权限,不过我给了它运行权限还是提示同样的错误。我在网上搜了下找到了原因:只所以提示“-/bin/sh: /usr/bin/helloworld: not found”这个,是因为我没有拷helloworld所需的库文件。那怎么才能知道helloworld需要哪些库文件呢,可以这样,在命令行输入arm-linux-readelf -a helloworld 命令然后在输出的内容中找到Program Headers:节这里就有helloworld所需的库文件(关于readelf可以参考这里<http://blog.youkuaiyun.com/eroswang/archive/2007/12/25/1967243.aspx>)如下图:


http://blogimg.chinaunix.net/blog/upfile2/100802113845.png

     看来我们需要ld-linux.so.3这个库,在你的交叉编译器中找到这个库文件把它拷到我们文件系统的/lib目录中然后烧到开发板中再次运行/usr/bin/helloworld结果提示“/usr/bin/helloworld: error while loadingshared libraries: libgcc_s.so.1: cannot open shared object file: No such fileor directory”有效果了,最起码不是前一个错误提示了,这就证明方法对头,我们看一下上面的错误这次直接提示所需的库文件了,我们按提示把libgcc_s.so.1拷到文件系统的/lib中,然后再次运行,又提示“/usr/bin/helloworld:error while loading shared libraries: libc.so.6: cannot open shared objectfile: No such file or directory”还是少库文件,我们再把这个也拷到文件系统的/lib中,这次总算是行了,终于看到“hello world”
参考文章:<http://www.cnblogs.com/nick123/archive/2009/12/01/1614919.html>


2、使用rmmod会出现 rmmod : chdir(/lib/modules): No such file ordirectory


   转自:

http://blog.youkuaiyun.com/feixue2588/article/details/5876518

使用rmmod会出现 rmmod : chdir(/lib/modules): No such file or directory 现在的内核模块在插入卸载时都会要转到/lib/modules/内核版本号/ 这个目录里。所以只要建立这个目录并且把要使用的模块.ko文件复制到这个目录就行了。 mkdir -p /lib/modules/`uname -r` 较新版本的busybox 1.13.1+ 要卸载模块必须要完全匹配模块名才行,原来在老标本的使用模块文件名就能卸载,现在发现不行了





 










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值