在Openwrt package Makefile章节里面提到了,要添加一个添加自定义模块的章节,这边就举两个简单的例子看下,其实我们自己看下已有的例子也大概可以模仿出来。


1.添加openwrt应用程序模块

如下,我们在package下面添加一个hello模块,有以下几个文件

linye@ubuntu:~/14.07/package/hello$ tree
.
├── Makefile
└── src
├── hello.c
└── Makefile

1 directory, 3 files

最外层的Makefile为openwrt的编译Makefile,每个定义的具体含义可以看Openwrt package Makefile章节进行查看。

include $(TOPDIR)/rules.mk

PKG_NAME:=hello
PKG_VERSION:=1.01
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)_$(PKG_VERSION)

include $(INCLUDE_DIR)/package.mk

define Package/$(PKG_NAME)
SUBMENU:=utils
CATEGORY:=Base system
TITLE:=hello test
endef

define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef

TARGET_CFLAGS += -D_GNU_SOURCE

define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/$(PKG_NAME) $(1)/usr/sbin
endef

$(eval $(call BuildPackage,$(PKG_NAME)))

src内部的Makefile是用来编译c函数用的

CFLAGS += -std=gnu99 -fstrict-aliasing -Iinclude -Wall -Werror
CFLAGS += -DRSA_VERIFY

all: hello

%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $^

zcheck: hello.o
$(CC) $(LDFLAGS) -o $@ $^

.PHONY: clean

clean:
rm -rf *.o hello

hello.c就是主函数了

#include <stdio.h>

int main()
{
printf("hello world\r\n");
}

代码编写完成后,使用make menuconfig就可以找到hello的选项,勾选起来

 Base system  --->
utils --->
<*> hello...

然后使用package编译方式,​​make package/hello/compile V=99​​即可编译模块

编译完可以在​​build_​​​下面看到多出来一个​​hello_1.01​​的模块

linye@ubuntu:~/14.07/build_dir/target-mipsel_1004kc_uClibc-0.9.33.2/hello_1.01$ tree
.
├── hello
├── hello.c
├── ipkg-mtk_1004kc
│   └── hello
│   ├── CONTROL
│   │   └── control
│   └── usr
│   └── sbin
│   └── hello
└── Makefile

5 directories, 5 files

将hello拷贝到板子上即可运行

root@openwrt:/tmp# chmod +x hello
root@openwrt:/tmp# ./hello
hello world

如果我们先在这个模块里面添加脚本/配置文件,一般做法是再新建一个files的目录,然后根据我们的rootfs结构进行对应的添加。

如下

linye@ubuntu:~/14.07/package/hello$ tree
.
├── files
│   ├── etc
│   │   ├── config
│   │   │   └── hello
│   │   └── init.d
│   │   └── autohello.sh
│   └── sbin
├── Makefile
└── src
├── hello.c
└── Makefile

6 directories, 5 files

然后在Makefile里面将这些文件拷贝到对应的文件夹即可

define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/$(PKG_NAME) $(1)/usr/sbin
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DATA) ./files/etc/config/hello $(1)/etc/config/hello
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/etc/init.d/autohello.sh $(1)/etc/init.d/hello
endef

然后使用make V=99重新编译,编译完成后在rootfs里面就可以看到我们需要的文件都已经跑到各自的目录了,进程就可以自动启动

linye@ubuntu:~/14.07/build_dir/target-mipsel_1004kc_uClibc-0.9.33.2/rootfs$ find ./ -name hello
./usr/sbin/hello
./etc/config/hello
./etc/init.d/hello

2.添加内核模块

添加内核模块和添加应用程序的框架类似,直接内部的实现函数不一样,如下,我们在package下面添加一个hello_kernel模块,有以下几个文件

linye@ubuntu:~/14.07/package/hello_kernel$ tree
.
├── Makefile
└── src
├── hello_kernel.c
└── Makefile

1 directory, 3 files

最外层的Makefile内容如下,区别的地方在于最下面的​​$(eval $(call KernelPackage,$(PKG_NAME)))​

include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk

PKG_NAME:=hello_kernel
PKG_VERSION:=1.01

include $(INCLUDE_DIR)/package.mk

define KernelPackage/$(PKG_NAME)
SUBMENU:=Kernel Modules
CATEGORY:=Base system
TITLE:=netfilter debug
DEPENDS:=kmod-ipt-conntrack
FILES:=$(PKG_BUILD_DIR)/hello_kernel.ko
AUTOLOAD:=$(call AutoLoad,66,hello_kernel)
endef

define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef

define Build/Compile
$(MAKE) -C "$(LINUX_DIR)" \
CROSS_COMPILE="$(TARGET_CROSS)" \
ARCH="$(LINUX_KARCH)" \
SUBDIRS="$(PKG_BUILD_DIR)" \
EXTRA_CFLAGS="$(BUILDFLAGS)" \
modules
endef

$(eval $(call KernelPackage,$(PKG_NAME)))

src里面的Makefile

obj-m += hello_kernel.o

src里面的hello_kernel.c

#include <linux/init.h>      /* __init and __exit macroses */
#include <linux/kernel.h> /* KERN_INFO macros */
#include <linux/module.h> /* required for all kernel modules */


static int __init hello_init(void)
{
printk("hello install\n");
return 0;
}

static void __exit hello_exit(void)
{

printk("hello uninstall\n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("hello Debug Module");

添加完上面信息后,在make menuconfig里面可以找到如下选择

Base system  --->
Kernel Modules --->
<*> kmod-hello_kernel.......

编译完再linux下面可以看到多出hello_kernel的模块内容

linye@ubuntu:~/14.07/build_dir/target-mipsel_1004kc_uClibc-0.9.33.2/linux-mtk_mt7621/hello_kernel-1.01$ tree
.
├── hello_kernel.c
├── hello_kernel.ko
├── hello_kernel.mod.c
├── hello_kernel.mod.o
├── hello_kernel.o
├── ipkg-mtk_1004kc
│   └── kmod-hello_kernel
│   ├── CONTROL
│   │   ├── control
│   │   └── postinst
│   ├── etc
│   │   └── modules.d
│   │   └── 66-hello_kernel
│   └── lib
│   └── modules
│   └── 3.10.49
│   └── hello_kernel.ko
├── Makefile
├── modules.order
└── Module.symvers

8 directories, 12 files

将hello_kernel.ko文件直接拷贝到板子上进行insmod安装

root@openwrt:/tmp# insmod hello_kernel.ko
root@openwrt:/tmp# lsmod | grep hello
hello_kernel 1888 0
root@openwrt:/tmp# rmmod hello_kernel

dmesg可以看到kernel打印信息

[67961.350000] hello install
[67969.390000] hello uninstall