记录自己学习linux驱动的成长之旅。(2022/07/16 22:03)
再牛逼的梦想,也抵不住傻逼般的坚持!
(该篇文章算不上是原创,网上查找了其他多个同学的笔记,自己整理做了验证)
Makefile
(这里既可以用Makefile,也可以直接使用GCC进行编译,但GCC的话同样需要制定默认的kernel路径)
PWD := $(shell pwd)
CROSS_COMPILE = arm-sigmastar-linux-uclibcgnueabihf-
CC:=$(CROSS_COMPILE)gcc
all:
make -C $(KERN_DIR) M=$(PWD) CROSS_COMPILE=$(CROSS_COMPILE) modules
clean:
make -C $(KERN_DIR) M=$(PWD) CROSS_COMPILE=$(CROSS_COMPILE) modules clean
rm -rf modules.order
obj-m += hello.o
hello.c
#include <linux/init.h> //这个头文件包含了你的模块初始化与清除的函数
#include <linux/module.h> //这个头文件包含了许多符号与函数的定义,这些符号与函数多与加载模块有关
#include <linux/kernel.h>
//指定license版本 若不指定
// “GPL” 是指明了 这是GNU General Public License的任意版本
// “GPL v2” 是指明 这仅声明为GPL的第二版本
// “GPL and addtional”
// “Dual BSD/GPL”
// “Dual MPL/GPL”
// “Proprietary” 私有的
// 除非你的模块显式地声明一个开源版本,否则内核会默认你这是一个私有的模块(Proprietary)
MODULE_LICENSE(“GPL”);
#if 0 //如下非必要 需要可自行添加
MODULE_AUTHOR // 声明作者
MODULE_DESCRIPTION // 对这个模块作一个简单的描述,这个描述是"human-readable"的
MODULE_VERSION // 这个模块的版本
MODULE_ALIAS // 这个模块的别名
MODULE_DEVICE_TABLE // 告诉用户空间这个模块支持什么样的设备
#endif
//设置初始化入口函数
static int __init hello_world_init(void)
{
printk(“hello china!!!\n”);
return 0;
}
//设置出口函数
static void __exit hello_world_exit(void)
{
printk(“see you china!!!\n”);
}
//将上述定义的init()和exit()函数定义为模块入口/出口函数
module_init(hello_world_init);
module_exit(hello_world_exit);
ps: 调试过程中遇到使用printk 增加KERN_DEBUG打印不出,解决方法可查看 “linux基础知识积累” 第5点 ,链接如下:https://blog.youkuaiyun.com/Bgm_Nilbb/article/details/123652389