Lets say I have a kernel device driver xyz which is coming as an external module and needed to be integrated with the existing software tree. This can be achieved in various different ways. Not going into the details of it, we will try focus on how the external kernel module can be integrated as a new buildroot package. Lets call our new package xyz.

Create a new folder under buildroot/package folder.

cd buildroot
mkdir package/xyz

Now we need to create two files inside the newly created folder: Config.in and xyz.mk.

touch package/xyz/Config.in
touch package/xyz/xyz.mk

Now let’s populate these files with what will eventually add xyz as a new package.
Config.in

 config BR2_PACKAGE_XYZ
        bool "xyz"
        help
                This is sample package.

Please note in the above config BR2_PACKAGE_ should be left as it is for a new package, the name of the package should be added after this like in this case XYZ has been added. There is no significance whather the name of the config is in lower or upper case but usually the config option is specified in uppper case whereas the actual package name maybe in lower case. There is no strict rule as far as I know.

xyz.mk

XYZ_MODULE_VERSION = 1.0
XYZ_SITE = ../abc/third_party/pqr/xyz
XYZ_SITE_METHOD = local
XYZ_LICENSE = GPLv2
XYZ_LICENSE_FILES = COPYING
XYZ_MODULE_MAKE_OPTS = \
        CONFIG_DUMMY1= \
        CONFIG_DUMMY2=y

define KERNEL_MODULE_BUILD_CMDS
        $(MAKE) -C '$(@D)' LINUX_DIR='$(LINUX_DIR)' CC='$(TARGET_CC)' LD='$(TARGET_LD)' modules
endef

$(eval $(kernel-module))
$(eval $(generic-package))

Important thing to remember:
XYZ_SITE = ../abc/third_party/pqr/xyz – this can be any path in your local machine where the source code is located for the package XYZ. Here, the source code has been placed folder called project_overlay which sits one level above the buildroot directory. All the relative paths have to be with respect to the buildroot directory. Hence, in the xyz.mk file the path specified starts with a ../ to go one level above.

XYZ_SITE_METHOD = local – The method for getting the source code has been specified as local which means the source code is located in a local folder rather than in a web link.

XYZ_MODULE_MAKE_OPTS – this gives you an opportunity to pass a compile time parameter to the make system.

define KERNEL_MODULE_BUILD_CMDS – this is where you define your make command. This will eventually invoke the module top level Makefile and so on.

$(MAKE) -C ‘$(@D)’ LINUX_DIR=’$(LINUX_DIR)’ CC=’$(TARGET_CC)’ LD=’$(TARGET_LD)’ modules – this standard Kbuild Make. The LINUX_DIR, TARGET_CC and TARGET_LD are already define by buildroot, so you don’t need to define.

Now we have to tell the package system that we want to be added. Hence we do the below modification in the package config file:

buildroot/package/Config.in

menu "Menu-name whatever you like"
        source "package/xyz/Config.in"
endmenu

Now you should be able to see the new package option in the buildroot menuconfig. Invoke the buildroot menuconfig exactly same as for kernel menuconfig. I will not elaborate on that. Select your module, save the changes and you should be able to see the new config option for the package i.e. config BR2_PACKAGE_XYZ=y in the .cofig file of the buildroot. The .config file is located at the top level buildroot directory and is created after you save your menuconfig changes for the new package.

The last is to modify the top level Makefile of the actual source code.
Makefile Top level

obj-m += xxx/ yyy/

subdir-ccflags-y := -I$(src)/include
subdir-ccflags-y += -Wall -g

ifeq ($(KERNELRELEASE),)

PWD := $(shell pwd)

modules:
        $(MAKE) -C '$(LINUX_DIR)' M='$(PWD)' modules
#clean:
        $(MAKE) -C '$(LINUX_DIR)' M='$(PWD)' clean

Makefile sub-directory level

xxx-y                           := foo1.o
xxx-$(CONFIG_AAA_BBB) += foo2.o

ccflags-y += -D
ccflags-y += -I$(src)/nnn/
ccflags-y += -I$(src)//
ppp-y                           += /foo3.o
ppp-y                           += /foo4.o

Leave a Reply