嵌入式linux 内核启动时动态加载驱动模块的方法

2019-07-12 16:58发布

前言

手头有个项目底层基本结束,所有的驱动都已经写好,并且调试通过了,但是考虑到每次使用时都手动加载驱动,岂不是很“蠢”,能自动的事怎么能手动呢?
于是开始折腾“linux开机自动加载驱动”,百度,谷歌了半天,怎么感觉说的都不清楚:为毛他们说的文件、文件夹我都没有?难道我用的是假的文件系统,假的内核?
唯一靠谱的就是:在 /etc/rcx.d 文件夹下添加shell脚本,再让脚本去 insmod或modeprob 自己的驱动。这时正常就要去查查这个rcx.d都是什么玩意了,但是作为共产主义的老司机怎么能走寻常路,于是打游戏去了,游戏打到一半,突然想到make menuconfig 后make modules 再make modules_install后的模块怎么就可以自动加载呢?于是赶紧退出游戏去看看内核源码下的Makefile。

分析

找到modules_install部分: # Target to install modules PHONY += modules_install modules_install: _modinst_ _modinst_post PHONY += _modinst_ _modinst_: @rm -rf $(MODLIB)/kernel @rm -f $(MODLIB)/source @mkdir -p $(MODLIB)/kernel @ln -s $(srctree) $(MODLIB)/source @if [ ! $(objtree) -ef $(MODLIB)/build ]; then rm -f $(MODLIB)/build ; ln -s $(objtree) $(MODLIB)/build ; fi @cp -f $(objtree)/modules.order $(MODLIB)/ @cp -f $(objtree)/modules.builtin $(MODLIB)/ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst # This depmod is only for convenience to give the initial # boot a modules.dep even before / is mounted read-write. However the # boot script depmod is the master version. PHONY += _modinst_post _modinst_post: _modinst_ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modinst $(call cmd,depmod) ////////////////////////////////////////////////////////// 其中“MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)” 总结下:
就是删除MODLIB下的kernel、source文件夹重新创建kernel等文件夹然后执行源码文件夹下 /scripts/Makefile.modinst和Makefile.fwinst,最后运行depmod命令。
而Makefile.modinst这个文件就是将之前编译好的模块复制到当前这个 $(MODLIB)/kernel 文件夹下。

解决步骤

  • 拷贝自己的驱动文件(mydriver.ko)到开发板上的 /lib/modules/内核版本/kernel/ 下,也可以在这个文件夹下穿件自己的文件夹(mydrv),把驱动拷贝进去。
cp ./mydriver.ko /lib/modules/3.14.26-gb9df364-dirty/kernel/mydrv
  • 进到 /lib/modules/内核版本/ 目录下运行depmod。
cd /lib/modules/3.14.26-gb9df364-dirty/ depmod
  • 完成上面的步骤重启设备就可以看见驱动自动加载了

深入

这时不妨来看看 /lib/modules/内核版本/ 目录下的文件 root:/lib/modules/3.14.26-gb9df364-dirty# ls -la drwxr-xr-x 5 root root 4096 Jul 29 2017 . drwxr-xr-x 3 root root 4096 Jul 1 2017 .. drwxr-xr-x 3 root root 4096 Apr 10 19:50 extra drwxr-xr-x 7 root root 4096 Apr 10 19:12 kernel -rw-r--r-- 1 root root 36015 Jul 29 2017 modules.alias -rw-r--r-- 1 root root 45727 Jul 29 2017 modules.alias.bin -rw-r--r-- 1 root root 10984 Apr 10 19:01 modules.builtin -rw-r--r-- 1 root root 12627 Jul 29 2017 modules.builtin.bin -rw-r--r-- 1 root root 12686 Jul 29 2017 modules.dep -rw-r--r-- 1 root root 19561 Jul 29 2017 modules.dep.bin -rw-r--r-- 1 root root 75 Jul 29 2017 modules.devname -rw-r--r-- 1 root root 4978 Apr 10 19:01 modules.order -rw-r--r-- 1 root root 131 Jul 29 2017 modules.softdep -rw-r--r-- 1 root root 42250 Jul 29 2017 modules.symbols -rw-r--r-- 1 root root 50259 Jul 29 2017 modules.symbols.bin drwxr-xr-x 5 root root 4096 Apr 10 19:09 updates 可以发现很多文件已经更新了,说明这些文件在depmod时重新生成了,这里我们着重看看modules.dep文件 ... kernel/drivers/usb/dwc3/dwc3.ko: kernel/drivers/usb/dwc3/dwc3-omap.ko: kernel/drivers/usb/dwc3/dwc3-pci.ko: kernel/drivers/usb/serial/usbserial.ko: kernel/drivers/usb/serial/pl2303.ko: kernel/drivers/usb/serial/usbserial.ko kernel/drivers/usb/musb/musb_hdrc.ko: kernel/drivers/usb/musb/omap2430.ko: kernel/drivers/usb/musb/musb_hdrc.ko kernel/drivers/usb/musb/musb_dsps.ko: kernel/drivers/usb/musb/musb_hdrc.ko kernel/drivers/usb/musb/musb_am335x.ko: kernel/drivers/input/keyboard/matrix_keypad.ko: kernel/drivers/input/touchscreen/pixcir_i2c_ts.ko: kernel/drivers/input/input-polldev.ko: ... 在这个文件中可以找到我们之前添加的驱动的路径。
man一下depmod depmod - Generate modules.dep and map files. Linux kernel modules can provide services (called "symbols") for other modules to use (using one of the EXPORT_SYMBOL variants in the code). If a second module uses this symbol, that second module clearly depends on the first module. These dependencies can get quite complex. depmod creates a list of module dependencies by reading each module under /lib/modules/version and determining what symbols it exports and what symbols it needs. By default, this list is written to modules.dep, and a binary hashed version named modules.dep.bin, in the same directory. If filenames are given on the command line, only those modules are examined (which is rarely useful unless all modules are listed). depmod also creates a list of symbols provided by modules in the file named modules.symbols and its binary hashed version, modules.symbols.bin. Finally, depmod will output a file named modules.devname if modules supply special device names (devname) that should be populated in /dev on boot (by a utility such as udev). If a version is provided, then that kernel version's module directory is used rather than the current kernel version (as returned by uname -r). depmod命令是用于生成模块之间的依赖关系的

总结

以上方法其实就是modules_install的过程,可以用来手动安装内核模块和自己编译的模块

提示

以上内容我目前仅测试了usb相关的驱动,启动前如果未安装对应的外设,则相应的驱动也不会加载,一旦插入设备,驱动会自动加载,生成相应的设备节点。 由于本人刚刚开始学习嵌入式linux,如有错误望指出,共同进步,谢谢!