tiny4412--linux驱动学习(2)
在ubuntu下编写验证字符设备驱动
并移植到arm开发板上
1,准备工作
- uname -r 查看电脑版本信息
- 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)的更多相关文章
- linux 驱动学习笔记01--Linux 内核的编译
由于用的学习材料是<linux设备驱动开发详解(第二版)>,所以linux驱动学习笔记大部分文字描述来自于这本书,学习笔记系列用于自己学习理解的一种查阅和复习方式. #make confi ...
- linux驱动学习(二) Makefile高级【转】
转自:http://blog.csdn.net/ghostyu/article/details/6866863 版权声明:本文为博主原创文章,未经博主允许不得转载. 在我前一篇写的[ linux驱动学 ...
- Linux驱动学习步骤(转载)
1. 学会写简单的makefile 2. 编一应用程序,可以用makefile跑起来 3. 学会写驱动的makefile 4. 写一简单char驱动,makefile编译通过,可以insmod, ls ...
- 树莓派linux驱动学习之hello world
最近想学习一下linux驱动,看了一些书和教学视频,大概了解了一下,不过要想深入,肯定需要实践.手上有几块linux的板子,最终选择了树莓派作为我的实验平台,资料比较丰富,接口也比较简单. 程序员的入 ...
- Linux驱动学习1.hello world;
最近项目需要使用Linux系统开发,借此机会学习一下Linux驱动开发 hello word代码hello.c #include <linux/module.h> #include < ...
- 【Linux驱动学习】SD卡规范学习
摘要: 学习SD卡的相关规范,包括定义,硬件特性,数据传输,命令系统等.不涉及代码. 文章针对Linux驱动开发而写,以助于理解SD卡驱动,不会涉及过多硬件内容. 纲要: 1. SD卡介绍 2. SD ...
- linux驱动学习_1
目前项目需要,需要做linux驱动了,记录一下 学习驱动,大家一定都会写一个hello world代码,网上也有很多范例,但是记录一下遇到的问题. 1.make之后,使用insmod加载,终端没有打印 ...
- Linux驱动学习之常用的模块操作命令
1.常用的模块操作命令 (1)lsmod(list module,将模块列表显示),功能是打印出当前内核中已经安装的模块列表 (2)insmod(install module,安装模块),功能是向当前 ...
- Linux驱动学习之驱动开发准备工作
一.开启驱动开发之路 1.驱动开发的准备工作 (1)正常运行linux系统的开发板.要求开发板中的linux的zImage必须是自己编译的,不能是别人编译的.原因在于在安装模块的时候会进行安全性校验 ...
- Linux驱动学习之什么是驱动?
一.什么是驱动? 1: 驱动一词的字面意思 2: 物理上的驱动 3: 硬件中的驱动 4: linux内核驱动.软件层面上的驱动广义上是指:这一段代码操作了硬件去动,所以这一段代码就叫硬件的驱动程序. ...
随机推荐
- 自动化接口测试(java)
githup地址:https://github.com/SailFan/autoTestMock 包结构: common包 ExtentTestNGIReporterListener.java 为测试 ...
- 学习Xen
先找到两个大佬博客 进行学习 http://www.cnblogs.com/BloodAndBone/archive/2010/11/02/1866907.html https://www.cnblo ...
- Python unittest discover()方法与执行顺序补充
一.discover更多测试用例 可以根据不同的功能创建不同的测试文件,甚至是不同的测试目录,测试文件中还可以将不同的小功能划分为不同的测试类,在类下编写测试用例,让整体结构更加清晰 但通过addTe ...
- IE高级配置中,存在SSL支持协议,例如SSL TLS。
IE高级配置中,存在SSL支持协议,例如SSL TLS. 其在注册表的路径为:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\I ...
- Java ---- 链表逆序
public class LinkedListRevert { public static void main(String[] args) { Node next3 = new Node(4,nul ...
- Centos7上安装java
1.默认情况下,系统安装的有jdk1.8,但是使用javac测试时会不识别这个命令, 意味着,java还是未安装好. 2.把java升级即可,此时java已经可用. yum -y install ...
- 【HDFS API编程】删除文件
所有操作都是以fileSystem为入口进行,我们使用fileSystem下的delete方法进行删除文件操作,删除的时候必须慎重. 直接上代码: /** * 删除文件 * @throws Excep ...
- 【机器学习_8】pandas
背景 关于同一个话题,不同作者也有不同行文结构.但要真正理解并会用,在我的经验里,是必须要自己重新组织的. 本文是基于以往看过的资料,从自身数据处理应用的角度出发,重新组织pandas应用结构,希望能 ...
- 监控linux服务器是否能登陆 邮件报警
import smtplibfrom email.mime.text import MIMETextimport telnetlibimport timedef SendEmail(fromAdd,t ...
- 如何更改Audition的界面颜色
如何更改Audition的界面颜色_百度经验 https://jingyan.baidu.com/article/77b8dc7fce2c6a6174eab6f6.html