视频及资料链接地址:(上传中)
链接:https://pan.baidu.com/s/1avZjYyQGr2ljfPhEZjPumA
提取码:qgox
一、linux驱动的分类
1、字符设备驱动
1)设备:
LED、KEY、BEEP、声卡、显卡、摄像头、鼠标、键盘、触摸屏、手写板、USB、.....
[root@GEC6818 /]#ls /dev -l
crw-rw---- 1 root root 29, 0 Jan 1 1970 fb0
crw-rw---- 1 root root 14, 3 Jan 1 1970 dsp
crw-rw---- 1 root root 14, 19 Jan 1 1970 dsp1
crw-rw---- 1 root root 204, 64 Jan 1 1970 ttySAC0
crw-rw---- 1 root root 204, 65 Jan 1 1970 ttySAC1
2)特点:
设备类型是c。应用程序和驱动程序之间交互数据的时候,数据是以字节为单位,不同的设备类型,交互的数据格式不一样的。字符设备驱动数据是实时传递的,按照固定的格式传递。字符设备是没有缓存的,字符设备是没有文件系统的。
3)应用程序访问方法
linux系统IO函数:open()、read()、write()、ioctl()、close()、mmap()
触摸屏:
struct input_event ts_ev;
int fd=open("/dev/input/event0", O_RDONLY);
read(fd, &ts_ev, sizeof(struct input_event));
close(fd);
---------------------------------------------------------------------------------------------------------
2、块设备驱动
1)设备:
大容量的存储设备。如:eMMC(nand flash:8GB)、SD卡、U盘、移动硬盘、....
[root@GEC6818 /]#ls /dev -l
brw-rw---- 1 root root 179, 0 Jan 1 1970 mmcblk0
brw-rw---- 1 root root 179, 16 Jan 1 1970 mmcblk0boot1
brw-rw---- 1 root root 179, 1 Jan 1 1970 mmcblk0p1
brw-rw---- 1 root root 179, 8 Jan 1 1970 mmcblk0boot0
brw-rw---- 1 root root 179, 2 Jan 1 1970 mmcblk0p2
brw-rw---- 1 root root 179, 4 Jan 1 1970 mmcblk0p4
brw-rw---- 1 root root 179, 3 Jan 1 1970 mmcblk0p3
brw-rw---- 1 root root 179, 5 Jan 1 1970 mmcblk0p5
brw-rw---- 1 root root 179, 6 Jan 1 1970 mmcblk0p6
brw-rw---- 1 root root 179, 7 Jan 1 1970 mmcblk0p7
brw-rw-rw- 1 root root 8, 0 Jan 1 00:06 sda
brw-rw-rw- 1 root root 8, 1 Jan 1 00:06 sda1
2)特点:
块设备是带有缓存的,当缓存满了(刷新缓存)这些数据才会写到块设备上去。块设备是有文件系统的(根文件系统的格式是ext4)。数据是以块(block)为为单位的,1block=1024B。
3)应用程序访问方法
例:
U盘中有一个文件test.txt,编写一个程序,读取test.txt文件中的内容,并将该内容通过串口2发送出去。
如何访问U盘?
挂载-----将块设备以某一种文件系统的格式挂载到根文件系统的某个目录上,在根据该目录访问块设备。
有些嵌入式平台可以自动挂载U盘(做了配置文件):
[root@GEC6818 /]#mount
sda1 on /mnt/udisk type vfat (rw,relatime,fmask=0000,dmask=0000,allow_utime=0022,codepage=cp437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro)
U盘就自动挂载到/mnt/udisk/,文件系统的类型vfat。
[root@GEC6818 /]#ls /mnt/udisk/
1-STM32???? 5-tiny210
2-?????? System Volume Information
3-GEC6818 ???????
4-GEC210
访问方法:
fd = open("/mnt/udisk/test.txt", O_RDONLY);
read()
close()
手动挂载:
[root@GEC6818 /]#mount -t vfat /dev/sda1 /data
[root@GEC6818 /]#ls /data
如何访问串口
fd = open("/dev/ttySAC2", O_RDWR);
初始化串口2
write(fd, buf, sizeof(buf));
close(fd);
-----------------------------------------------------------------------------------------------------
3、网络设备驱动
1)设备:网卡(有线网卡、无线网卡)
如何查看网络设备??
[root@GEC6818 /]#ifconfig -a
eth0 Link encap:Ethernet HWaddr 0E:72:C9:E8:03:96
inet addr:192.168.22.180 Bcast:192.168.22.255 Mask:255.255.255.0
inet6 addr: fe80::c72:c9ff:fee8:396/64 Scope:Link
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:238 (238.0 B)
Interrupt:80
ip6tnl0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
NOARP MTU:1452 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
LOOPBACK MTU:16436 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
sit0 Link encap:IPv6-in-IPv4
NOARP MTU:1480 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
2)特点:
网卡----物理层
网络驱动-----数据链路层
3)应用程序访问网络设备
socket套接字:字节流---TCP;数据报---UDP;原始套接字---开发网络协议
地址信息: IP地址和端口号
TCP的服务器
socket()/bind()/listen()/accept()/read()/recv()/write()/send()/close()
TCP的客户端
socket()/connect()//read()/recv()/write()/send()/close()
======================================================================================================
二、linux驱动模型
以字符设备驱动为例。
一、linux驱动的分类
1、字符设备驱动
1)设备:
LED、KEY、BEEP、声卡、显卡、摄像头、鼠标、键盘、触摸屏、手写板、USB、.....
[root@GEC6818 /]#ls /dev -l
crw-rw---- 1 root root 29, 0 Jan 1 1970 fb0
crw-rw---- 1 root root 14, 3 Jan 1 1970 dsp
crw-rw---- 1 root root 14, 19 Jan 1 1970 dsp1
crw-rw---- 1 root root 204, 64 Jan 1 1970 ttySAC0
crw-rw---- 1 root root 204, 65 Jan 1 1970 ttySAC1
crw-rw---- 1 root root 204, 66 Jan 1 1970 ttySAC2
crw-rw---- 1 root root 204, 67 Jan 1 1970 ttySAC3
2)特点:
设备类型是c。应用程序和驱动程序之间交互数据的时候,数据是以字节为单位,不同的设备类型,交互的数据格式不一样的。字符设备驱动数据是实时传递的,按照固定的格式传递。字符设备是没有缓存的,字符设备是没有文件系统的。
3)应用程序访问方法
linux系统IO函数:open()、read()、write()、ioctl()、close()、mmap()
触摸屏:
struct input_event ts_ev;
int fd=open("/dev/input/event0", O_RDONLY);
read(fd, &ts_ev, sizeof(struct input_event));
close(fd);
---------------------------------------------------------------------------------------------------------
2、块设备驱动
1)设备:
大容量的存储设备。如:eMMC(nand flash:8GB)、SD卡、U盘、移动硬盘、....
[root@GEC6818 /]#ls /dev -l
brw-rw---- 1 root root 179, 0 Jan 1 1970 mmcblk0
brw-rw---- 1 root root 179, 16 Jan 1 1970 mmcblk0boot1
brw-rw---- 1 root root 179, 1 Jan 1 1970 mmcblk0p1
brw-rw---- 1 root root 179, 8 Jan 1 1970 mmcblk0boot0
brw-rw---- 1 root root 179, 2 Jan 1 1970 mmcblk0p2
brw-rw---- 1 root root 179, 4 Jan 1 1970 mmcblk0p4
brw-rw---- 1 root root 179, 3 Jan 1 1970 mmcblk0p3
brw-rw---- 1 root root 179, 5 Jan 1 1970 mmcblk0p5
brw-rw---- 1 root root 179, 6 Jan 1 1970 mmcblk0p6
brw-rw---- 1 root root 179, 7 Jan 1 1970 mmcblk0p7
brw-rw-rw- 1 root root 8, 0 Jan 1 00:06 sda
brw-rw-rw- 1 root root 8, 1 Jan 1 00:06 sda1
2)特点:
块设备是带有缓存的,当缓存满了(刷新缓存)这些数据才会写到块设备上去。块设备是有文件系统的(根文件系统的格式是ext4)。数据是以块(block)为为单位的,1block=1024B。
3)应用程序访问方法
例:
U盘中有一个文件test.txt,编写一个程序,读取test.txt文件中的内容,并将该内容通过串口2发送出去。
如何访问U盘?
挂载-----将块设备以某一种文件系统的格式挂载到根文件系统的某个目录上,在根据该目录访问块设备。
有些嵌入式平台可以自动挂载U盘(做了配置文件):
[root@GEC6818 /]#mount
sda1 on /mnt/udisk type vfat (rw,relatime,fmask=0000,dmask=0000,allow_utime=0022,codepage=cp437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro)
U盘就自动挂载到/mnt/udisk/,文件系统的类型vfat。
[root@GEC6818 /]#ls /mnt/udisk/
1-STM32???? 5-tiny210
2-?????? System Volume Information
3-GEC6818 ???????
4-GEC210
访问方法:
fd = open("/mnt/udisk/test.txt", O_RDONLY);
read()
close()
手动挂载:
[root@GEC6818 /]#mount -t vfat /dev/sda1 /data
[root@GEC6818 /]#ls /data
如何访问串口
fd = open("/dev/ttySAC2", O_RDWR);
初始化串口2
write(fd, buf, sizeof(buf));
close(fd);
-----------------------------------------------------------------------------------------------------
3、网络设备驱动
1)设备:网卡(有线网卡、无线网卡)
如何查看网络设备??
[root@GEC6818 /]#ifconfig -a
eth0 Link encap:Ethernet HWaddr 0E:72:C9:E8:03:96
inet addr:192.168.22.180 Bcast:192.168.22.255 Mask:255.255.255.0
inet6 addr: fe80::c72:c9ff:fee8:396/64 Scope:Link
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:238 (238.0 B)
Interrupt:80
ip6tnl0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
NOARP MTU:1452 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
LOOPBACK MTU:16436 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
sit0 Link encap:IPv6-in-IPv4
NOARP MTU:1480 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
2)特点:
网卡----物理层
网络驱动-----数据链路层
3)应用程序访问网络设备
socket套接字:字节流---TCP;数据报---UDP;原始套接字---开发网络协议
地址信息: IP地址和端口号
TCP的服务器
socket()/bind()/listen()/accept()/read()/recv()/write()/send()/close()
TCP的客户端
socket()/connect()//read()/recv()/write()/send()/close()
======================================================================================================
二、linux驱动模型
以字符设备驱动为例。
一、linux驱动的分类
1、字符设备驱动
1)设备:
LED、KEY、BEEP、声卡、显卡、摄像头、鼠标、键盘、触摸屏、手写板、USB、.....
[root@GEC6818 /]#ls /dev -l
crw-rw---- 1 root root 29, 0 Jan 1 1970 fb0
crw-rw---- 1 root root 14, 3 Jan 1 1970 dsp
crw-rw---- 1 root root 14, 19 Jan 1 1970 dsp1
crw-rw---- 1 root root 204, 64 Jan 1 1970 ttySAC0
crw-rw---- 1 root root 204, 65 Jan 1 1970 ttySAC1
crw-rw---- 1 root root 204, 66 Jan 1 1970 ttySAC2
crw-rw---- 1 root root 204, 67 Jan 1 1970 ttySAC3
2)特点:
设备类型是c。应用程序和驱动程序之间交互数据的时候,数据是以字节为单位,不同的设备类型,交互的数据格式不一样的。字符设备驱动数据是实时传递的,按照固定的格式传递。字符设备是没有缓存的,字符设备是没有文件系统的。
3)应用程序访问方法
linux系统IO函数:open()、read()、write()、ioctl()、close()、mmap()
触摸屏:
struct input_event ts_ev;
int fd=open("/dev/input/event0", O_RDONLY);
read(fd, &ts_ev, sizeof(struct input_event));
close(fd);
---------------------------------------------------------------------------------------------------------
2、块设备驱动
1)设备:
大容量的存储设备。如:eMMC(nand flash:8GB)、SD卡、U盘、移动硬盘、....
[root@GEC6818 /]#ls /dev -l
brw-rw---- 1 root root 179, 0 Jan 1 1970 mmcblk0
brw-rw---- 1 root root 179, 16 Jan 1 1970 mmcblk0boot1
brw-rw---- 1 root root 179, 1 Jan 1 1970 mmcblk0p1
brw-rw---- 1 root root 179, 8 Jan 1 1970 mmcblk0boot0
brw-rw---- 1 root root 179, 2 Jan 1 1970 mmcblk0p2
brw-rw---- 1 root root 179, 4 Jan 1 1970 mmcblk0p4
brw-rw---- 1 root root 179, 3 Jan 1 1970 mmcblk0p3
brw-rw---- 1 root root 179, 5 Jan 1 1970 mmcblk0p5
brw-rw---- 1 root root 179, 6 Jan 1 1970 mmcblk0p6
brw-rw---- 1 root root 179, 7 Jan 1 1970 mmcblk0p7
brw-rw-rw- 1 root root 8, 0 Jan 1 00:06 sda
brw-rw-rw- 1 root root 8, 1 Jan 1 00:06 sda1
2)特点:
块设备是带有缓存的,当缓存满了(刷新缓存)这些数据才会写到块设备上去。块设备是有文件系统的(根文件系统的格式是ext4)。数据是以块(block)为为单位的,1block=1024B。
3)应用程序访问方法
例:
U盘中有一个文件test.txt,编写一个程序,读取test.txt文件中的内容,并将该内容通过串口2发送出去。
如何访问U盘?
挂载-----将块设备以某一种文件系统的格式挂载到根文件系统的某个目录上,在根据该目录访问块设备。
有些嵌入式平台可以自动挂载U盘(做了配置文件):
[root@GEC6818 /]#mount
sda1 on /mnt/udisk type vfat (rw,relatime,fmask=0000,dmask=0000,allow_utime=0022,codepage=cp437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro)
U盘就自动挂载到/mnt/udisk/,文件系统的类型vfat。
[root@GEC6818 /]#ls /mnt/udisk/
1-STM32???? 5-tiny210
2-?????? System Volume Information
3-GEC6818 ???????
4-GEC210
访问方法:
fd = open("/mnt/udisk/test.txt", O_RDONLY);
read()
close()
手动挂载:
[root@GEC6818 /]#mount -t vfat /dev/sda1 /data
[root@GEC6818 /]#ls /data
如何访问串口
fd = open("/dev/ttySAC2", O_RDWR);
初始化串口2
write(fd, buf, sizeof(buf));
close(fd);
-----------------------------------------------------------------------------------------------------
3、网络设备驱动
1)设备:网卡(有线网卡、无线网卡)
如何查看网络设备??
[root@GEC6818 /]#ifconfig -a
eth0 Link encap:Ethernet HWaddr 0E:72:C9:E8:03:96
inet addr:192.168.22.180 Bcast:192.168.22.255 Mask:255.255.255.0
inet6 addr: fe80::c72:c9ff:fee8:396/64 Scope:Link
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:238 (238.0 B)
Interrupt:80
ip6tnl0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
NOARP MTU:1452 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
LOOPBACK MTU:16436 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
sit0 Link encap:IPv6-in-IPv4
NOARP MTU:1480 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
2)特点:
网卡----物理层
网络驱动-----数据链路层
3)应用程序访问网络设备
socket套接字:字节流---TCP;数据报---UDP;原始套接字---开发网络协议
地址信息: IP地址和端口号
TCP的服务器
socket()/bind()/listen()/accept()/read()/recv()/write()/send()/close()
TCP的客户端
socket()/connect()//read()/recv()/write()/send()/close()
======================================================================================================
二、linux驱动模型
以字符设备驱动为例。
====================================================================================================
一、移植设备驱动:
(1)总体思路:搭建编译设备驱动环境:即编译linux内核,需要注意内核版本的选择-------->建立设备驱动demo:两个文件(xx.c,Makefile);注意Makefile编写格式,驱动程序
也有框架------->下载到嵌入式设备安装,查询检测。
(2)详细步骤:如下。
======================================================================================================
二、linux内核模块是什么?
linux kernel module----linux内核模块
在linux内核中,每个驱动程序都是独立的module。每设计一个驱动程序,首先需要设计一个module。module相当于驱动程序的盒子。
module会编译成ko文件。module可以安装,可以卸载。
=======================================================================================================
三、编译驱动的内核源码
1.内核源码的版本要与目标平台上运行的linux内核的版本要一致
GEC6818 :#uname -r
内核源码:
gec@ubuntu:~/6818GEC/kernel$ pwd
/home/gec/6818GEC/kernel
gec@ubuntu:~/6818GEC/kernel$ vi Makefile
1 VERSION = 3
2 PATCHLEVEL = 4
3 SUBLEVEL = 39
4 EXTRAVERSION =
5 NAME = Saber-toothed Squirrel
2.内核源码要针对目标平台正确的配置过:
gec@ubuntu:~/6818GEC/kernel$ make menuconfig
System Type --->
ARM system type (SLsiAP S5P6818) --->
3.内核源码要正确的编译过
gec@ubuntu:~/6818GEC$ ls
buildroot GEC6818uboot kernel linux mk out prebuilts prototype tools
gec@ubuntu:~/6818GEC$ ./mk -k
===============================================================================
四。设计一个最简单的module
查看linux内核源码,内核源码中有驱动程序设计的案例。
sourceinsight-----内核源码工程
例子:
/kernel/drivers/watchdog/nxp_wdt.c
#include
#include
static int __init gec6818_led_init(void)
{
printk(KERN_WARNING "gec6818 led init\n");
return 0;
}
static void __exit gec6818_led_exit(void)
{
printk(KERN_WARNING "gec6818 led exit");
}
//驱动程序的入口和出口
module_init(gec6818_led_init);
module_exit(gec6818_led_exit);
//module的描述
MODULE_AUTHOR("[email protected]");
MODULE_DESCRIPTION("GEC6818 LED Device Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION("V1.0");
=======================================================================================================
五、驱动程序的特点
1、驱动程序是运行在linux内核中的,而应用程序是运行在linux的用户空间的。
2、每个硬件都需要有一个驱动程序,驱动程序是独立的。在一个应用程序中可以访问多个驱动程序
视频播放器 ---->显卡 + 声卡 + 鼠标
3、应用程序是有入口函数的,main()是入口。而应用程序是没有出口。
驱动程序有入口、有出口。
入口函数:module_init(gec6818_led_init);
出口函数:module_exit(gec6818_led_exit);
安装驱动:
#insmod led_drv.ko ---->自动调用入口函数module_init()---->gec6818_led_init()--->从内核申请资源、向内核注册驱动、建立驱动模型、....
卸载驱动:
#rmmod led_drv.ko
---->自动调用出口函数module_exit()---->gec6818_led_exit()--->释放申请的资源,注销驱动。
4、编写应用程序的时候,我们可以使用库函数和系统调用函数。
应用程序使用的头文件是哪里来的:
stdio.h stdlib.h string.h ------>
gcc : /usr/include/stdio.h
arm-linux-gcc : /usr/local/arm/5.4.0/usr/arm-none-linux-gnueabi/sysroot/usr/include/stdio.h
编写驱动程序的时候,使用的头文件是哪里来的?
linux/kernel.h /linux/module.h ------->
来自于linux内核源码:/kernel/linux/module.h
5、函数区别
应用程序:printf() 、malloc()、sleep()
驱动程序:printk()、kmalloc()、ssleep()
6、static 的作用?
应用程序:static修饰局部变量
驱动程序:static修饰全局变量和函数
7、__init和__exit关键字
__init用来修饰初始化函数,一般情况下初始化函数只运行一次,运行结束以后,就会将该函数占用的内存释放掉。
[ 0.000000] Memory: 1024MB = 1024MB total
[ 0.000000] Memory: 810820k/810820k available, 237756k reserved, 272384K highmem
..............................
[ 0.000000] .init : 0xc0a52000 - 0xc0a8f100 ( 245 kB)
[ 0.000000] .data : 0xc0a90000 - 0xc0b297d8 ( 614 kB)
..............................
[ 4.218000] devtmpfs: mounted
[ 4.221000] Freeing init memory: 244K
8、程序的编译
应用程序:
#arm-linux-gcc -o test test.c
驱动程序:
使用Makefile文件,并利用内核源码的Makefile和内核源码中的头文件来编译驱动程序。
gec@ubuntu:/mnt/hgfs/14嵌入式系统驱动/2module/demo1$ ls
led_drv.c Makefile
gec@ubuntu:/mnt/hgfs/14嵌入式系统驱动/2module/demo1$ make
------------------------------------------------------------------------------------------
出错信息如果是:表明没有编译内核,请按照上面 “三、编译驱动的内核源码”编译内核即可,再次make
make[1]: Entering directory '/home/wgh/6818GEC/kernel'
ERROR: Kernel configuration is invalid.
include/generated/autoconf.h or include/config/auto.conf are missing.
Run 'make oldconfig && make prepare' on kernel src to fix it.
WARNING: Symbol version dump /home/wgh/6818GEC/kernel/Module.symvers
is missing; modules will have no dependencies and modversions.
-------------------------------------------------------------------------------------------
成功编译信息输出如下:
make ARCH=arm CROSS_COMPILE=/home/gec/6818GEC/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin/arm-eabi- -C /home/gec/6818GEC/kernel M=/mnt/hgfs/14嵌入式系统驱动/2module/demo1 modules
make[1]: Entering directory '/home/gec/6818GEC/kernel'
CC [M] /mnt/hgfs/14嵌入式系统驱动/2module/demo1/led_drv.o
Building modules, stage 2.
MODPOST 1 modules
CC /mnt/hgfs/14嵌入式系统驱动/2module/demo1/led_drv.mod.o
LD [M] /mnt/hgfs/14嵌入式系统驱动/2module/demo1/led_drv.ko
make[1]: Leaving directory '/home/gec/6818GEC/kernel'
9、驱动程序安装好以后,驱动程序不是一直运行的;而是安装到内核中的一个程序,只有应用程序去调用驱动程序,这个驱动程序才开始工作。
=======================================================================================================
六、驱动的调试
1.查看ko的信息:modinfo
gec@ubuntu:xxx/demo1$ modinfo led_drv.ko
2、查看ko的格式
gec@ubuntu:xxx/demo1$ file led_drv.ko
3、下载 led_drv.ko 到开发板上
4、安装驱动
[root@GEC6818 /test]#insmod led_drv.ko
[ 3488.195000] gec6818 led init
5、查看安装好的ko
[root@GEC6818 /test]#lsmod
led_drv 748 0 - Live 0xbf000000 (O)
6、卸载驱动
[root@GEC6818 /test]#rmmod led_drv.ko
[ 3621.975000] gec6818 led exit
===============================================================================================================
七、编译驱动的Makefile
obj-m += led_drv.o
KERNELDIR:=/home/gec/6818GEC/kernel
CROSS_COMPILE:=/home/gec/6818GEC/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin/arm-eabi-
PWD:=$(shell pwd)
default:
$(MAKE) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o *.order .*.cmd *.ko *.mod.c *.symvers *.tmp_versions
1)obj-m += led_drv.o
----m是module的意思,+= 追加赋值。?= 或 := 区别。led_drv.o---驱动远程序的目标文件。
2)KERNELDIR:=/home/gec/6818GEC/kernel
----->内核源码的路径
3)CROSS_COMPILE:=/home/gec/6818GEC/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin/arm-eabi-
-----交叉编译器的路径
4)PWD:=$(shell pwd)
-----当前路径,即编译驱动程序的Makefile文件所在的路径。
5)$(MAKE) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) -C $(KERNELDIR) M=$(PWD) modules
去内核源码目录下,找到内核源码的Makefile文件,并将ARCH和CROSS_COMPILE变量传递给Makefile文件。利用内核源码的Makefile文件来编译当前路径下的驱动源文件,将驱动源文件编译成一个ko。
============================================================================================================
九、printk()