一.基础流程
1.有两种编译驱动程序的方法,我们选择第二种
1.将驱动程序放入Linux内核里面,然后编译Linux内核,将驱动编译到Linux内核里面
2.将驱动程序编译成内核模块,独立于Linux内核模块之外, .ko文件->内核模块
二.helloworld.c文件
cs#include <linux/module.h> #include <linux/init.h> static int helloworld_init(void) { printk("hello world\n"); return 0; } static void helloworld_exit(void) { printk("goodbye world\n"); } module_init(helloworld_init); module_exit(helloworld_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("qiuiuiu"); MODULE_VERSION("V1.0"); MODULE_DESCRIPTION("A simple hello world module")
驱动程序的基本框架,vscode编写
1.头文件,两个头文件都要写,module.h和init.h文件
2.模块加载函数,static int helloworld_init
3.模块卸载函数,static void helloworld_exit
4.模块许可证声明,MODULE_LICENSE("GPL");
5.(可选) 模块参数,作者,版本,以及相关信息
先创建目录 touch 01_helloworld,再创建文件,mkdir helloworld.c
三.Makefile
bashARCH := arm64 CROSS_COMPILE := aarch64-rockchip1031-linux-gnu- #这个环境变量要在外面声明 export ARCH CROSS_COMPILE #声明路径 KDIR := /home/alientek/rk3568_linux5.10_sdk/kernel #内核的路径 PWD := $(shell pwd) obj-m += helloworld.o #名字不要打错 all: make -C $(KDIR) M=$(PWD) modules #注意前面是个制表符TAB clean: make -C $(KDIR) M=$(PWD) clean #注意前面是个制表符TAB
ARCH = arm64:ARCH变量设置
CROSS_COMPILE := aarch64-linux-gnuobj-m:交叉编译器的前缀,路径在外面终端export,或者直接加入到./bashrc中
export ARCH CROSS_COMPILE :声明路径
KDIR := /home/alientek/rk3568_linux5.10_sdk/kernel:设备树内核的源码路径
PWD := $(shell pwd) :获取当前目录的变量
obj-m += helloworld.o : 将文件.o结尾的设置为 编译时以模块形式 编译
all:
make -C (KDIR) M=(PWD) modules #注意前面是个制表符TAB
编译make操作
clean:
make -C (KDIR) M=(PWD) clean #注意前面是个制表符TAB
clean操作,清除
四.问题解决
1.基础操作
vim: :set list 查看tab键为^I :set nolist 取消查看
vim: vim ./bashrc 可以设置tab键,set noexpandtab 将tab设置为制表符
vim: G跳转到文件结尾 o后新插入一行 d删除 区块注释
终端: ctrl+e 跳转最后
2.Makefile: :=和+=
3.内核编译系统的依赖关系: 编译一个外部模块,必须先保证内核源码本身时配置好,编译过的。kernel开发,得先编译
4.PATH环境变量:如何查找命令的真是路径,以及可以通过修改.bashrc来永久固化配置
5.遇到质量堪忧的SDK,设备树是坏的,可以通过menuconfig修改,/是选择