第一天
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第一天相关的知识,希望对你有一定的参考价值。
一 模块化编程
1.入口
module_init(xxx_init);
2.出口
module_exit(xxx_exit);
3.头文件
#include <linux/init.h>
#include <linux/module.h>
4.声明许可
MODULE_LICENSE("GPL");
MODULE_AUTHOR("GNB");
二 编译模块Makefile
KERNEL_DIR = /lib/modules/$(shell uname -r)/build
PWD = $(shell pwd)
ifeq ($(KERNELRELEASE), )
.PHONY:module clean
module:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean
else
obj-m := xxx.o
endif
三 模块加载/卸载/查看
(1)加载模块
sudo insmod xxx.ko
(2)查看模块
sudo lsmod | grep xxx
(3)卸载模块
sudo rmmod xxx
注意:
Linux 不允许有同名的模块
练习:
编写一个模块,加载的时候,计算:1 + ... + 100 ,卸载的时候,输出 : 累加的结果
四、符号导出
目的:将自己实现的函数或全局变量,导出给别的模块使用
(1)EXPORT_SYMBOL(函数名或全局变量名)
(2)EXPORT_SYMBOL_GPL(函数名或全局变量名) ->导出的符号只允许遵从GPL协议的模块使用
编译模块的时候,如何寻找使用符号?
(1)自己的模块
(2)编译内核生成的Module.symvers(内核导出的所有符号)中寻找
(3)在模块目录下的Module.symvers下寻找
练习:
A模块调用B模块中实现的sum()函数
五 Linux 支持的设备类型
(1)字符设备 : 每次按字节访问
(2)块设备 : 每次按块访问(需要文件系统)
(3)网络设备 : 支持网络通信
注意:字符设备和块设备在/dev/目录有对应的设备文件与他们的驱动程序对应
网络设备在Linux系统中,其驱动程序对应的网络接口(ifconfig命令查看)\
学生 老师 工人
struct student struct teacher struct worker
{ { {
struct people; struct people struct people
.... ... ....
} } }
六 Linux 驱动添加流程
(1)描述设备 =>用结构体分装{自己的特性 + 通用的部分}
(2)初始化设备 =>内核提供 (通用部分)
(3)注册设备 =>内核提供
我们添加设备的时候,只需要告诉内核,你的设备是什么类型和你的设备操作方法。
七 设备号
主设备号(12bit) + 次设备号(20bit)
主设备号:驱动程序
次设备号:代表同一类的设备中哪一个设备
例如:
4个LED灯,只需要一个驱动程序,通过次设备号区分是那一个LED.
mknod /dev/led c 252 0 =>在/dev目录生成一个led的设备文件,这个文件中记录主设备号是252
八 字符设备驱动函数接口
1.初始化cdev结构体
void cdev_init(struct cdev * cdev, const struct file_operations * fops)
功能:初始化cdev结构体
参数:
@cdev cdev结构体
@fops 操作函数的结构体
2.申请设备号
int register_chrdev_region(dev_t from, unsigned count, const char * name);
参数:
@from 包含主设备号的数字
@count 设备号的个数
@name 设备的名字 (在cat /proc/devices看到它)
返回值:
成功返回0,失败返回负的错误码
3.添加字符设备
int cdev_add(struct cdev *p, dev_t dev, unsigned count);
参数:
@p cdev结构体
@dev 设备号(第一个设备号)
@count 次设备的个数
返回值:
成功返回0,失败返回负的错误码
以上是关于第一天的主要内容,如果未能解决你的问题,请参考以下文章