且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何将Linux内核驱动程序模块添加为Buildroot软件包?

更新时间:2023-11-22 17:44:34

完全自动化-tree QEMU示例

https://github.com/******/linux-kernel-module-cheat/tree/753cbe68ff50bea0982e1791c8a2178a999d8377/buildroot_packages/kernel_modules

源代码树:


  • buildroot / :Buildroot 2017.02,理想情况下是git子模块

  • kernel_module / :带有某些模块的外部软件包

    • Config.in

    • external.mk

    • Makefile

    • hello.c :hello world模块

    • buildroot/: Buildroot 2017.02, ideally as a git submodule
    • kernel_module/: external package with some modules
      • Config.in
      • external.mk
      • Makefile
      • hello.c: hello world module

      kernel_module / Config.in

      kernel_module/Config.in

      config BR2_PACKAGE_KERNEL_MODULE
              bool "kernel_module"
              depends on BR2_LINUX_KERNEL
              help
                      Linux Kernel Module Cheat.
      

      kernel_module / external.mk

      kernel_module/external.mk

      KERNEL_MODULE_VERSION = 1.0
      KERNEL_MODULE_SITE = $(BR2_EXTERNAL_KERNEL_MODULE_PATH)
      KERNEL_MODULE_SITE_METHOD = local
      $(eval $(kernel-module))
      $(eval $(generic-package))
      

      内核模块/ Makefile

      kernel_module/Makefile

      obj-m += $(addsuffix .o, $(notdir $(basename $(wildcard $(BR2_EXTERNAL_KERNEL_MODULE_PATH)/*.c))))
      ccflags-y := -DDEBUG -g -std=gnu99 -Wno-declaration-after-statement
      
      .PHONY: all clean
      
      all:
          $(MAKE) -C '$(LINUX_DIR)' M='$(PWD)' modules
      
      clean:
          $(MAKE) -C '$(LINUX_DIR)' M='$(PWD)' clean
      

      内核模块/hello.c

      kernel_module/hello.c

      #include <linux/module.h>
      #include <linux/kernel.h>
      
      MODULE_LICENSE("GPL");
      
      static int myinit(void)
      {
          printk(KERN_INFO "hello init\n");
          return 0;
      }
      
      static void myexit(void)
      {
          printk(KERN_INFO "hello exit\n");
      }
      
      module_init(myinit)
      module_exit(myexit)
      

      用法:

      cd buildroot
      make BR2_EXTERNAL="$(pwd)/../kernel_module" qemu_x86_64_defconfig
      echo 'BR2_PACKAGE_KERNEL_MODULE=y' >> .config
      make BR2_JLEVEL="$(($(nproc) - 2))" all
      qemu-system-x86_64 -M pc -kernel output/images/bzImage -drive file=output/images/rootfs.ext2,if=virtio,format=raw -append root=/dev/vda -net nic,model=virtio -net user
      

      QEMU打开,然后运行:

      QEMU opens up, then run:

      root
      modprobe hello
      modprobe -r hello
      

      dmesg 显示:

      hello init
      hello exit
      

      关键行是 $(eval $(kernel-module)) c> external.mk ,它为我们进行了所有设置,并安装了模块,其中 modprobe 将在其中找到它们( / lib / modules / * / extra / hello.ko ),包括 modules.dep 用于模块间的依赖关系:如何从另一个模块调用导出的内核模块函数?

      The key line is $(eval $(kernel-module)) in external.mk, which sets everything up for us, and installs the modules where modprobe will find them (/lib/modules/*/extra/hello.ko), including modules.dep for inter-module dependencies: How to call exported kernel module functions from another module?

      如何GDB逐步调试内核模块:如何使用QEMU调试Linux内核模块?

      How to GDB step debug the kernel modules: How to debug Linux kernel modules with QEMU?

      To在启动时自动加载模块,请使用 BR2_ROOTFS_OVERLAY = ../ rootfs_overlay rootfs_overlay / etc / init.d / S99modules 执行 modprobe 的文件。

      To autoload modules at startup, use BR2_ROOTFS_OVERLAY="../rootfs_overlay" and a rootfs_overlay/etc/init.d/S99modules file that does the modprobe.

      树内示例: https://github.com/******/buildroot/tree/9580078b98f885ca94e4dfc896265a8a491f6ae1

      In-tree example: https://github.com/******/buildroot/tree/9580078b98f885ca94e4dfc896265a8a491f6ae1 It is less clean, but also works.

      在Ubuntu 16.04主机上进行了测试。

      Tested on a Ubuntu 16.04 host.