Linux内核驱动入门-内核驱动

系统架构图
Linux内核驱动入门-内核驱动_第1张图片

//下载linux-4.19.tar.bz2
//解压
tar -xf linux-4.19.tar.bz2
cd linux-4.19
//配置内核
make ARCH=arm CROSS_COMPILE=arm--linux--gnueabihf-- bcm2709_defconfig
//编译内核
make ARCH=arm CROSS_COMPILE=arm--linux--gnueabihf-- zImage modules dtbs -j2

内核模块编译

#include 
#include 
// 指定开源协议

MODULE_LICENSE("Dual BSD/GPL");

// 没有参数,有一个int的返回值
// void代表没有参数,也就是对代码的编写要求更高
static int hello_init(void)
{
 // printk是内核提供的一个调试函数,
 // #define KERN_ALERT "alert"
 // printk("alert""Hello, world\n");
 printk(KERN_ALERT"Hello, world\n");
 return 0;
}
// 没有参数,没有返回值
static void hello_exit(void)
{
 printk(KERN_ALERT"Goodbye, cruel world\n");
}

// 声明入口函数,跟应用程序的main是一样的
// 声明入口函数是hello_init,insmod hello.ko的时候,内核会调用hello_init来初始化内核模块
// 初始化成功返回0,失败返回-1,或者其他的值
module_init(hello_init);

// 声明出口函数
// 声明出口函数是hello_exit,rmmod hello,内核就好调用hello_exit来清理资源
module_exit(hello_exit);
# If KERNELRELEASE is defined, we've been invoked from the
 # kernel build system and can use its language.
 # KERNELRELEASE在linux内核源码里的Makefile定义的
#如果代码是放在linux内核源码里编译,KERNELRELEASE就有定义,

ifneq ($(KERNELRELEASE),)
 obj-m := hello.o
 # Otherwise we were called directly from the command
 # line; invoke the kernel build system.
else
#定义一个KDIR变量,并赋值为/home/v/linux-4.19
 KDIR := /work/linux-4.19//linux系统所在的路径
 default:
 make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
 clean:
 rm -f *.ko *.o *.mod.o *.mod.c *.symvers modul*
endif

-C $ (KDIR) 将工作目前切换到/home/v/linux-4.19
M= $ (PWD) 在$(PWD)目录下寻找内核模块的代码
make modules
ARCH=arm,指定arm架构
CROSS_COMPILE=arm-linux-gnueabihf- , 指定交叉编译工具的前缀,用哪个交叉编译工具来编译代码
-C (change)选项的作用是指将当前工作目录转移到你所指定的位置。
“M=”选项的作用是,当用户需要以某个内核为基础编译一个外部模块的话,需要在make modules 命令中加
入“M=dir”,程序会自动到你所指定的dir目录中查找模块源码,将其编译,生成KO文件

你可能感兴趣的:(嵌入式)