在Openwrt package Makefile章节里面提到了,要添加一个添加自定义模块的章节,这边就举两个简单的例子看下,其实我们自己看下已有的例子也大概可以模仿出来。
如下,我们在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
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
添加内核模块和添加应用程序的框架类似,直接内部的实现函数不一样,如下,我们在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 /* __init and __exit macroses */
#include /* KERN_INFO macros */
#include /* 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