在ubuntu下编写验证字符设备驱动

并移植到arm开发板上

1,准备工作

  1.   uname -r  查看电脑版本信息
  2. apt-get  install  linux-source  安装相应版本的linux内核

2,编写驱动程序

    Global CharDev.c

/* GlobalCharDev.c */
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h> #include <asm/uaccess.h> #define DEV_NAME "GlobalChar" static ssize_t GlobalRead(struct file *, char *, size_t, loff_t *);
static ssize_t GlobalWrite(struct file *, const char *, size_t,loff_t *); static int char_major = ;
static int GlobalData = ; /* "GlobalChar"设备的全局变量 */ /* 初始化字符设备驱动的 file_operations 结构体 */
struct file_operations globalchar_fops =
{
.read = GlobalRead,
.write = GlobalWrite
}; /* 模块初始化 */
static int __init GlobalChar_init(void)
{
int ret; ret = register_chrdev(char_major, DEV_NAME, &globalchar_fops);/* 注册设备驱动,_driver_char_misc.c 第290行参考 */
if(ret < )
printk(KERN_ALERT "GlobalChar Reg Fail\n");
else
{
printk(KERN_ALERT "GlobalChar Reg Success\n");
char_major = ret;
printk(KERN_ALERT "Major = %d\n", char_major);
}
return ret;
} /* 模块卸载函数 */
static void __exit GlobalChar_exit(void)
{
unregister_chrdev(char_major, DEV_NAME); /* 注销设备驱动 */
return;
} /* 模块驱动读函数 */
static ssize_t GlobalRead(struct file *file, char *buf, size_t len, loff_t *off)
{
if (copy_to_user(buf, &GlobalData ,sizeof(int)))
{
/* 从内核复制 GlobalData 到用户空间*/
return -EFAULT;
}
return sizeof(int);
}
/* 模块驱动写函数 */
static ssize_t GlobalWrite(struct file *file, const char *buf, size_t len, loff_t *off)
{
if (copy_from_user(&GlobalData, buf, sizeof(int)))
{
/* 从用户复制 GlobalData 到内核 */
return -EFAULT;
}
return sizeof(int);
} module_init(GlobalChar_init);
module_exit(GlobalChar_exit); MODULE_LICENSE("GPL");
MODULE_AUTHOR("dongjin");

  Makefile

ifneq ($(KERNELRELEASE),)
obj-m := GlobalCharDev.o
else # KERNELDIR ?= /lib/modules/$(shell uname -r)/build
KERNELDIR ?= /usr/src/linux-headers-$(shell uname -r) //这两个都可以 PWD := $(shell pwd) default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules clean:
rm -rf rm -rf *.ko *.mod* *.o* *.sy*
endif

  理解:

      pwd-->  驱动文件目录

      kerneldir -->  内核源码目录

      default -->  表示到内核源码目录中去编译pwd下的驱动文件

——————————————————————————————————————————————————————

make 编译

root@ubuntu:/home/arm/data/char_driver# make
make -C /usr/src/linux-headers-4.4.--generic M=/home/arm/data/char_driver modules
make[]: 正在进入目录 `/usr/src/linux-headers-4.4.--generic'
CC [M] /home/arm/data/char_driver/GlobalCharDev.o
Building modules, stage .
MODPOST modules
LD [M] /home/arm/data/char_driver/GlobalCharDev.ko
make[]:正在离开目录 `/usr/src/linux-headers-4.4.--generic'

出现Global CharDev.ko文件

2,insmod Global CharDev.ko  将模块加入内核

3,cat  /proc/devices  查看驱动设备

4,mknod  /dev/GlobalChar   c  247  0      根据相应的设备号,建立设备节点。

5,测试文件

/* GlobaiCharText.c 测试文件*/

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h> #define DEV_NAME "/dev/GlobalChar" int main()
{
int fd, num; /* 打开设备文件 */
fd = open(DEV_NAME, O_RDWR, S_IRUSR | S_IWUSR);
if(fd < )
{
printf("Open Device Fail!\n");
return -;
} /* 读取当前设备数值 */
read(fd, &num, sizeof(int));
printf("The GlobalChar is %d\n", num); printf("Please input a numble written to GlobalChar: ");
scanf("%d", &num); /* 写入新的数值 */
write(fd, &num, sizeof(int)); /* 重新读取数值 */
read(fd, &num, sizeof(int));
printf("The GlobalChar is %d\n", num); close(fd);
return ; }

  gcc -o  GlobalCharText  GlobalCharText.c      编译出可执行文件

   执行:

root@ubuntu:/home/arm/data/char_driver# ./a.out
The GlobalChar is
Please input a numble written to GlobalChar:
The GlobalChar is

——————————————————————————————————————————————————————————————————————

通过NFS我们可以建立共享目录,将编写好的驱动加载到arm板,当然也需要配置环境变量。

1,驱动文件:需要将Make file中KERNLDIR 改成 自己下载内核的地址,如:

    KERNELDIR ?= /home/arm/linux-4.4

2,测试文件:理所当然我们需要使用交叉编译去编译出可执行文件。

注意:首先我们要知道自己制作的做小系统是采用静态编译还是动态编译,我的采用静态编译

  1,静态:

  2,动态:

需要在制作最小系统时,在  /lib  下加入所需的动态交叉编译库(所选交叉编译工具目录下的链接库),但是我在制作randisk的过程中,提示内存不足,暂没查找其原因。

如果在静态根文件系统内使用动态编译链所编译的elf,会提示:-sh:./test:no found  (这里 not found 指的是 链接库)

测试:

卸载:

1,删除  /dev  下的设备节点

  rm /dev/GlobalChar

2,卸载驱动

  rmmod  GlopbalCharDev.ko 

出现问题:

——————————————————————————————————————————————————————

参考:

http://tieba.baidu.com/p/3645403366

https://blog.csdn.net/Ultraman_hs/article/details/53239455

解决移植到arm上不兼容的问题

https://blog.csdn.net/zqj6893/article/details/48439711

解决驱动卸载问题

tiny4412--linux驱动学习(2)的更多相关文章

  1. linux 驱动学习笔记01--Linux 内核的编译

    由于用的学习材料是<linux设备驱动开发详解(第二版)>,所以linux驱动学习笔记大部分文字描述来自于这本书,学习笔记系列用于自己学习理解的一种查阅和复习方式. #make confi ...

  2. linux驱动学习(二) Makefile高级【转】

    转自:http://blog.csdn.net/ghostyu/article/details/6866863 版权声明:本文为博主原创文章,未经博主允许不得转载. 在我前一篇写的[ linux驱动学 ...

  3. Linux驱动学习步骤(转载)

    1. 学会写简单的makefile 2. 编一应用程序,可以用makefile跑起来 3. 学会写驱动的makefile 4. 写一简单char驱动,makefile编译通过,可以insmod, ls ...

  4. 树莓派linux驱动学习之hello world

    最近想学习一下linux驱动,看了一些书和教学视频,大概了解了一下,不过要想深入,肯定需要实践.手上有几块linux的板子,最终选择了树莓派作为我的实验平台,资料比较丰富,接口也比较简单. 程序员的入 ...

  5. Linux驱动学习1.hello world;

    最近项目需要使用Linux系统开发,借此机会学习一下Linux驱动开发 hello word代码hello.c #include <linux/module.h> #include < ...

  6. 【Linux驱动学习】SD卡规范学习

    摘要: 学习SD卡的相关规范,包括定义,硬件特性,数据传输,命令系统等.不涉及代码. 文章针对Linux驱动开发而写,以助于理解SD卡驱动,不会涉及过多硬件内容. 纲要: 1. SD卡介绍 2. SD ...

  7. linux驱动学习_1

    目前项目需要,需要做linux驱动了,记录一下 学习驱动,大家一定都会写一个hello world代码,网上也有很多范例,但是记录一下遇到的问题. 1.make之后,使用insmod加载,终端没有打印 ...

  8. Linux驱动学习之常用的模块操作命令

    1.常用的模块操作命令 (1)lsmod(list module,将模块列表显示),功能是打印出当前内核中已经安装的模块列表 (2)insmod(install module,安装模块),功能是向当前 ...

  9. Linux驱动学习之驱动开发准备工作

    一.开启驱动开发之路 1.驱动开发的准备工作 (1)正常运行linux系统的开发板.要求开发板中的linux的zImage必须是自己编译的,不能是别人编译的.原因在于在安装模块的时候会进行安全性校验 ...

  10. Linux驱动学习之什么是驱动?

    一.什么是驱动? 1: 驱动一词的字面意思 2: 物理上的驱动 3: 硬件中的驱动 4: linux内核驱动.软件层面上的驱动广义上是指:这一段代码操作了硬件去动,所以这一段代码就叫硬件的驱动程序. ...

随机推荐

  1. 自动化接口测试(java)

    githup地址:https://github.com/SailFan/autoTestMock 包结构: common包 ExtentTestNGIReporterListener.java 为测试 ...

  2. 学习Xen

    先找到两个大佬博客 进行学习 http://www.cnblogs.com/BloodAndBone/archive/2010/11/02/1866907.html https://www.cnblo ...

  3. Python unittest discover()方法与执行顺序补充

    一.discover更多测试用例 可以根据不同的功能创建不同的测试文件,甚至是不同的测试目录,测试文件中还可以将不同的小功能划分为不同的测试类,在类下编写测试用例,让整体结构更加清晰 但通过addTe ...

  4. IE高级配置中,存在SSL支持协议,例如SSL TLS。

    IE高级配置中,存在SSL支持协议,例如SSL TLS. 其在注册表的路径为:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\I ...

  5. Java ---- 链表逆序

    public class LinkedListRevert { public static void main(String[] args) { Node next3 = new Node(4,nul ...

  6. Centos7上安装java

    1.默认情况下,系统安装的有jdk1.8,但是使用javac测试时会不识别这个命令,   意味着,java还是未安装好. 2.把java升级即可,此时java已经可用. yum -y install ...

  7. 【HDFS API编程】删除文件

    所有操作都是以fileSystem为入口进行,我们使用fileSystem下的delete方法进行删除文件操作,删除的时候必须慎重. 直接上代码: /** * 删除文件 * @throws Excep ...

  8. 【机器学习_8】pandas

    背景 关于同一个话题,不同作者也有不同行文结构.但要真正理解并会用,在我的经验里,是必须要自己重新组织的. 本文是基于以往看过的资料,从自身数据处理应用的角度出发,重新组织pandas应用结构,希望能 ...

  9. 监控linux服务器是否能登陆 邮件报警

    import smtplibfrom email.mime.text import MIMETextimport telnetlibimport timedef SendEmail(fromAdd,t ...

  10. 如何更改Audition的界面颜色

    如何更改Audition的界面颜色_百度经验  https://jingyan.baidu.com/article/77b8dc7fce2c6a6174eab6f6.html