linux驱动学习(四)之module

📅 2026/8/11 16:57:01
linux驱动学习(四)之module
一、内核模块内核模块是一种可以动态加载到操作系统内核中并扩展其功能的软件。它们允许在运行的操作系统内核中增加新的功能或驱动程序而无需重新启动计算机。在linux系统中驱动程序是各自独立存在的而且驱动程序中包含一个moudle比如led驱动按键驱动lcd驱动。各个驱动程序是由应用程序来进行关联的利于linux系统对硬件的支持和管理。可以通过lsmod来查看当前系统中module的存在[rootGEC6818 /dev]#lsmodbuttons_drv 2882 0 - Live 0xbf000000 (O)二、内核模块设计一个module的框架:[1]初始化函数 ---- 根据自己驱动的要求来定义一个初始化---- 比如:LEDstatic int __init gec6818led_init(void) { printk(gec6818_led_init\n); //相当于应用程序的printf在驱动程序中不支持libc //所有的接口都来看于linux内核的接口:位于include/linux //初始化的工作 return 0; }[2]退出函数static void __exit gec6818led_exit(void) { printk(gec6818led_exit\n); }[3] moudle入口和出口module_init(gec6818led_init); //当用户执行insmod led_drv.ko时调用module_init然而 //gec6818led_init被调用 module_exit(gec6818led_exit); //当用户执行rmmod led_drv时调用moudle_exit[4] 关于一个驱动的说明MODULE_AUTHOR(12580.zhang3); MODULE_DESCRIPTION(GEC6818 LED Device Driver); MODULE_LICENSE(GPL);说明:1)驱动程序的入口是module_init,应用程序的入口是main2)驱动程序的出口是module_exit,应用程序没有出口3)驱动程序的头文件要依赖于linux内核源码应用程序的头文件依赖于libc所以编译驱动程序要关联内核的源码4)驱动程序的编译要用Makefile,应用程序可以用Makefile,也可以用一个命令三、Makefile文件编译的输出$ make --- 执行make命令make ARCHarm 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/GZ1853/linux_drvier/4module/code/led_drv modules make[1]: Entering directory /home/gec/6818GEC/kernel ---进入内核 CC [M] /mnt/hgfs/GZ1853/linux_drvier/4module/code/led_drv/led_drv.o Building modules, stage 2. MODPOST 1 modules CC /mnt/hgfs/GZ1853/linux_drvier/4module/code/led_drv/led_drv.mod.o LD [M] /mnt/hgfs/GZ1853/linux_drvier/4module/code/led_drv/led_drv.ko make[1]: Leaving directory /home/gec/6818GEC/kernel ---- 离开内核注意事项1)驱动程序的代码路径不能有中文或者空格2)编译驱动程序之前一定要先编译内核make ARCHarm 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/GZ1853/linux_drvier/4module/code/led_drv modules make[1]: Entering directory /home/gec/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/gec/6818GEC/kernel/Module.symvers is missing; modules will have no dependencies and modversions. CC [M] /mnt/hgfs/GZ1853/linux_drvier/4module/code/led_drv/led_drv.o In file included from command-line:0:0: /home/gec/6818GEC/kernel/include/linux/kconfig.h:4:32: fatal error: generated/autoconf.h: No such file or directory #include generated/autoconf.h ^ compilation terminated. scripts/Makefile.build:313: recipe for target /mnt/hgfs/GZ1853/linux_drvier/4module/code/led_drv/led_drv.o failed make[2]: *** [/mnt/hgfs/GZ1853/linux_drvier/4module/code/led_drv/led_drv.o] Error 1 Makefile:1365: recipe for target _module_/mnt/hgfs/GZ1853/linux_drvier/4module/code/led_drv failed make[1]: *** [_module_/mnt/hgfs/GZ1853/linux_drvier/4module/code/led_drv] Error 2 make[1]: Leaving directory /home/gec/6818GEC/kernel Makefile:16: recipe for target default failed make: *** [default] Error 2四、安装驱动#insmod led_drv.ko ---- 安装驱动 #lsmod ---- 查看驱动 #rmmod led_drv.ko ---- 删除驱动问题[rootGEC6818 /6818_driver]#insmod led_drv.koinsmod: cant insert led_drv.ko: File exists ---- 当前系统下已安装了该驱动解决办法利用lsmod查看系统已有的驱动如果有则先删除驱动再插入驱动[rootGEC6818 /6818_driver]#lsmod led_drv 747 0 - Live 0xbf000000 (O) [rootGEC6818 /6818_driver]#rmmod led_drv [ 392.193000] gec6818led_exit [rootGEC6818 /6818_driver]#lsmod [rootGEC6818 /6818_driver]#五、控制打印信息输出优先级在linux内核中对于控制台输出有优先级://kernel\kernel\printk.c int console_printk[4] { DEFAULT_CONSOLE_LOGLEVEL, /* console_loglevel */ 7 DEFAULT_MESSAGE_LOGLEVEL, /* default_message_loglevel */ 7 MINIMUM_CONSOLE_LOGLEVEL, /* minimum_console_loglevel */ 1 DEFAULT_CONSOLE_LOGLEVEL, /* default_console_loglevel */ 7 }; /* printks without a loglevel use this.. */ #define DEFAULT_MESSAGE_LOGLEVEL CONFIG_DEFAULT_MESSAGE_LOGLEVEL以CONFIG_的宏是需要配置内核时候来进行设置所有的配置项在.config文件中可以找到,当配置完成后经过编译内核会把.config配置文件自动生成一个.h文件。想要在控制台打印消息则default_message_loglevel(默认消息日志的等级) default_console_loglevel(默认控制台日志等级)。数值越小优先级越高。控制方法一查看当前系统控制台日志等级/proc/sys/kernel/printk [rootGEC6818 /6818_driver]#cat /proc/sys/kernel/printk 7 7 1 7 这四个数字是 Linux 内核 printk 日志等级的默认配置含义依次为 console_loglevel 7 default_message_loglevel 7 minimum_console_loglevel 1 default_console_loglevel 7 1)console_loglevel 7 只有优先级 7 的内核日志才会输出到控制台串口 / 终端。 2)default_message_loglevel 7 没有指定等级的 printk 信息默认按 7 级 处理。 3)minimum_console_loglevel 1 控制台日志等级最低只能设到 1不能更低更紧急。 4)default_console_loglevel 7 系统启动时控制台默认日志等级为 7。 修改当前控制台的日志等级 [rootGEC6818 /]#echo 7 4 1 7 /proc/sys/kernel/printk ---- 只当前一次有效 把设置的方法写到配置文件中:/etc/profile echo 7 4 1 7 /proc/sys/kernel/printk 保存并且退出重启开发板控制方法二修改printk函数打印消息的级别#define KERN_EMERG 0 /* system is unusable*/ #define KERN_ALERT 1 /* action must be taken immediately */ #define KERN_CRIT 2 /* critical conditions */ #define KERN_ERR 3 /* error conditions */ #define KERN_WARNING 4 /* warning conditions */ #define KERN_NOTICE 5 /* normal but significant condition */ #define KERN_INFO 6 /* informational */ #define KERN_DEBUG 7 /* debug-level messages */在驱动程序中设置printk函数的消息的级别 printk(4 gec6818led_exit\n); --- 消息的级别与消息之间用空格隔开 printk(KERN_WARNING gec6818led_exit\n);解决办法三在配置内核中进行修改Kernel hacking ----- CONFIG_DEFAULT_MESSAGE_LOGLEVEL7$ make menuconfig ---- 用菜单来进行内核配置 HOSTCC scripts/kconfig/lxdialog/checklist.o HOSTCC scripts/kconfig/lxdialog/inputbox.o HOSTCC scripts/kconfig/lxdialog/menubox.o HOSTCC scripts/kconfig/lxdialog/textbox.o HOSTCC scripts/kconfig/lxdialog/util.o HOSTCC scripts/kconfig/lxdialog/yesno.o HOSTCC scripts/kconfig/mconf.o HOSTLD scripts/kconfig/mconf scripts/kconfig/mconf Kconfig # # configuration written to .config ----- 把内核的配置写入到.config文件中 # *** End of the configuration. ---- 退出菜单配置完成内核配置 *** Execute make to start the build or try make help. $ cp .config arch/arm/configs/GEC6818_defconfig --- 把.config配置文件拷回给具体的硬件平台 $ cd .. $ ./mk -k ----重新编译内核 重新烧写内核到开发板----- boot.img六、驱动程序调试$ file led_drv.ko led_drv.ko: ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), BuildID[sha1]548395fe828e760c1cb522b67f93da3386efca21, not stripped $ size led_drv.ko text data bss dec hex filename 276 360 0 636 27c led_drv.ko $ modinfo led_drv.ko filename: /mnt/hgfs/GZ1853/linux_drvier/4module/led_drv/led_drv.ko license: GPL description: GEC6818 LED Device Driver author: 1853.zhang3 depends: vermagic: 3.4.39-gec SMP preempt mod_unload ARMv7 p2v8需要板子一起学习的可以这里购买含资料​​​​​​点击跳转觉得有帮助的话打赏一下呗。。