0

Is there an example package somewhere on how you might go about statically compiling in a device driver?

I know that obj-y is used for static compilation vs obj-m. I have a dynamically loadable module being built in my buildroot package right now. That dynamic module works exactly as I would expect. I even figured out that I could change the module makefile to use obj-y, and add a buildroot option where, if I clicked it it would append a line in the drivers/Makefile. The output appeared to show that my module got built. But it didn't at all seem to me that my driver's init function was being executed at startup, because I don't see my device file in /dev.

Adam Miller
  • 1,756
  • 1
  • 25
  • 44
  • There is a problem in your driver. Perhaps initialization order is wrong when you compile in. And seems you didn't do your homework, i.e. check how to debug initcalls in kernel documentation. – 0andriy Jan 23 '16 at 12:42
  • 1
    I got it working fully, I'll answer my own question with a post to an example. – Adam Miller Jan 23 '16 at 16:12
  • Dynamic external kernel module: https://stackoverflow.com/questions/40307328/how-to-add-a-linux-kernel-module-driver-as-a-buildroot-package – Ciro Santilli OurBigBook.com Jun 23 '17 at 07:15

2 Answers2

2

Supposing you have a driver in driver.c, and a buildroot package called STATICDRVR, you can use the following Config.in and STATICDRVR.mk files to add a static module to be built when the kernel is built:

Config.in

config BR2_PACKAGE_STATICDRVR
       bool "Build & link static driver?"
       help
         This is a driver that blah blah greatness whatever

STATICDRVR.mk

STATICDRVR_VERSION = master
STATICDRVR_SITE =  /location/to/STATICDRVR_containing_src
STATICDRVR_SITE_METHOD = local
STATICDRVR_MODULE_SUBDIRS = src
STATICDRVR_INSTALL_TARGET = YES
STATICDRVR_LICENSE = GPLv2
STATICDRVR_LICENSE_FILES = COPYING
STATICDRVR_NAME = STATICDRVR

STATICDRVR_DEPENDENCIES = linux


define STATICDRVR_BUILD_CMDS
    #make sure that obj-y += STATICDRVR/ is only in the build makefile once
    sed -i '/obj-y += STATICDRVR/d' $(BUILD_DIR)/linux-$(LINUX_VERSION)/drivers/Makefile
    echo "obj-y += STATICDRVR/" >> $(BUILD_DIR)/linux-$(LINUX_VERSION)/drivers/Makefile
    rm -rf $(BUILD_DIR)/linux-$(LINUX_VERSION)/drivers/STATICDRVR
    cp -r $(@D)/src $(BUILD_DIR)/linux-$(LINUX_VERSION)/drivers/STATICDRVR
    echo "obj-y += driver.o" > $(BUILD_DIR)/linux-$(LINUX_VERSION)/drivers/STATICDRVR/Makefile
endef

define STATICDRVR_INSTALL_STAGING_CMDS
endef


define STATICDRVR_INSTALL_TARGET_CMDS
endef

endif

define STATICDRVR_DEVICES
endef

define STATICDRVR_PERMISSIONS
endef

define STATICDRVR_USERS
endef

$(eval $(kernel-module))
$(eval $(generic-package))
Adam Miller
  • 1,756
  • 1
  • 25
  • 44
1

It is not possible to statically link an external module with the kernel. To do that, you have to patch the kernel itself and add your module there.

Arnout
  • 2,927
  • 16
  • 24
  • I'll provide an example, I've solved my own problem. You're technically correct, but its probably more benefit to acknowledge that I mean I have driver code and I want it to be statically linked into the kernel, because I know better than to think that a .ko file can be statically linked to the vmlinux file. – Adam Miller Jan 24 '16 at 14:06
  • Related: http://stackoverflow.com/questions/7353851/insert-linux-kernel-module-statically – Ciro Santilli OurBigBook.com Aug 03 '16 at 22:59