背景

近日添加了一个包到openwrt中,在此过程中又对openwrt多了一些认识

这个包本身自带了kconfig,可直接在这个包里面执行make menuconfig进行配置,然后执行make

但要集成到openwrt中,就需要把这些配置项都集成到openwrt的配置中。

面对这种情况,当然是要找个现成的例子做参考,首先想到的就是busybox。

以下以busybox为例进行说明,源码摘自github https://github.com/openwrt/openwrt/tree/master/package/utils/busybox

如何集成配置项

busybox本身也自带了配置项,但实际上我们却可以在openwrt的总的配置项中对其进行配置,而无需进入busybox目录单独对其做配置。

通过查看busybox包的makefile,可以看到,这个集成是这么做的。

对于busybox原生的配置项不做改动,而是针对每个配置项都另外生成一个对应的配置项,用于集成到openwrt中。

这些配置项在 openwrt/package/utils/busybox/config目录中。并通过 openwrt/package/utils/busybox/Config.in 文件连接到openwrt配置项。下面结合代码分析下。

从Makefile中可以看到,对于openwrt来说,busybox包的配置,就来源于Config.in

文件 openwrt/package/utils/busybox/Makefile

define Package/busybox/config
source "$(SOURCE)/Config.in"
endef

先来看下openwrt/package/utils/busybox/Config.in这个总的配置文件。

文件 openwrt/package/utils/busybox/Config.in

if PACKAGE_busybox

config BUSYBOX_CUSTOM
bool "Customize busybox options"
default n
help
Enabling this allows full customization of busybox settings.
Note that there are many options here that can result in a build
that doesn't work properly. Enabling customization will mark your
build as "tainted" for the purpose of bug reports.
See the variables written to /etc/openwrt_release Unless you know what you are doing, you should leave this as 'n' source "Config-defaults.in" #引入默认配置项的值 if BUSYBOX_CUSTOM #当选择了自定义配置项时
source "config/Config.in" #引入对应于busybox原生配置项的配置文件,允许用户完全自定义
endif config BUSYBOX_USE_LIBRPC
bool
default y if BUSYBOX_CUSTOM && BUSYBOX_CONFIG_FEATURE_HAVE_RPC
default y if !BUSYBOX_CUSTOM && BUSYBOX_DEFAULT_FEATURE_HAVE_RPC endif

这里面定义了一个BUSYBOX_CUSTOM配置项,当不选中时,就只引入默认配置"Config-default.in",当选中时,就再引入config目录下对应于busybox原生配置项的配置文件,以允许用户完全自定义这些配置。

先看不自定义配置的情况。此时Config.in就只引入了Config-defaults.in,打开这个文件,可以看到,里面是一系列以BUSYBOX_DEFAULT开头的配置项,如

文件 openwrt/package/utils/busybox/Config-defaults.in

config BUSYBOX_DEFAULT_HAVE_DOT_CONFIG
bool
default y
config BUSYBOX_DEFAULT_DESKTOP
bool
default n
config BUSYBOX_DEFAULT_EXTRA_COMPAT
bool
default n

这些其实就是对应到busybox本身的所有配置项的。只是名字略有不同。最终,在Makefile中,会将这些配置项转换为busybox本身的配置文件。即

文件 openwrt/package/utils/busybox/Makefile

define Build/Configure
grep 'CONFIG_BUSYBOX_$(BUSYBOX_SYM)' $(TOPDIR)/.config | sed -e "s,\\(# \)\\?CONFIG_BUSYBOX_$(BUSYBOX_SYM)_\\(.*\\),\\1CONFIG_\\2,g" > $(PKG_BUILD_DIR)/.config
yes 'n' | $(MAKE) -C $(PKG_BUILD_DIR) $(MAKE_FLAGS) oldconfig
endef

从总的配置文件中,滤出所有CONFIG_BUSYBOX_$(BUSYBOX_SYM)开头的配置项,并通过sed将前缀CONFIG_BUSYBOX_$(BUSYBOX_SYM)去掉,生成用于busybox编译的.config文件。再执行一遍make oldconfig,以自动处理掉一些配置不合适的情况,修正最终的.config文件。

其中这个$(BUSYBOX_SYM)变量,也是在Makefile中赋值的。

文件 openwrt/package/utils/busybox/Makefile

BUSYBOX_SYM=$(if $(CONFIG_BUSYBOX_CUSTOM),CONFIG,DEFAULT)

这样就清楚了。busybox的makefile中,在未选中CONFIG_BUSYBOX_CUSTOM的情况下,BUSYBOX_SYM的值为DEFAULT,则将CONFIG_BUSYBOX_DEFAULT_xxx过滤出来,处理为busybox最终的配置项。这些CONFIG_BUSYBOX_DEFAULT_xxx是在Config-defaults.in文件中配置好的。

在选中了CONFIG_BUSYBOX_CUSTOM的情况下,则最终将CONFIG_BUSYBOX_CONFIG_xxx过滤出来使用。

接下来看自定义的情况。自定义的情况其实也很清晰,就是引入了config目录下的配置项。

这些配置项,跟busybox源码中的布局和内容完全一致,区别只是配置项的名字都为BUSYBOX_CONFIG开头,且默认值均为对应的BUSYBOX_DEFAULT_开头的配置项。记得吗,这些BUSYBOX_DEFAULT_开头的配置项都是在Config-default.in中配置的。如下例子

文件 openwrt/package/utils/busybox/config/init/Config.in

config BUSYBOX_CONFIG_INIT
bool "init"
default BUSYBOX_DEFAULT_INIT
select BUSYBOX_CONFIG_FEATURE_SYSLOG
help
init is the first program run when the system boots.

也就是说,当用户需要自定义的时候,引入了BUSYBOX_CONFIG_xxx的配置项,但其默认值还是用的已经配置好的。此时要自定义的就是在这个基础上做修改。

最终用户的配置就体现在BUSYBOX_CONFIG_xxx的配置项上。

如上文所述,在选中了CONFIG_BUSYBOX_CUSTOM的情况下,BUSYBOX_SYM的值为CONFIG,则将CONFIG_BUSYBOX_CONFIG_xxx过滤出来,处理为busybox最终的配置项。

配置项文件的生成

搞清楚了如何集成之后,接下来的问题就是,这些BUSYBOX_DEFAULT_xxx 和 BUSYBOX_CONFIG_xxx 的配置文件,是怎么来的,如此多的配置项,肯定不可能时手工修改的,必然有自动化处理。

是的,这些BUSYBOX_CONFIG_xxx配置项,就是从busybox本身的配置项生成而来。而这些BUSYBOX_DEFAULT_xxx的默认配置值,其实就是从一份配置好的busybox.config文件生成而来。在busybox的包中,就提供了两个脚本 convert_defaults.pl 和 convert_menuconfig.pl,用来生成配置项和默认配置值

使软件包随配置项改变而重新编译

一般软件包在编译过一次之后,如果源码没有改动,则下次make无须重新编译。

但对于busybox这种包,源码未变,配置改变了的话,也是需要重新编译的。

现在的问题在于,用户修改配置项,是在openwrt的.config修改,根本不会改动到busybox这个目录下的文件。

那么busybox包就需要有一个方法,来监控配置项的变动。如果配置项变化,则需要重新编译。如何监控呢?从makefile中也可以找到答案


文件 openwrt/package/utils/busybox/Makefile ifeq ($(DUMP),)
STAMP_CONFIGURED:=$(strip $(STAMP_CONFIGURED))_$(shell grep '^CONFIG_BUSYBOX_' $(TOPDIR)/.config | mkhash md5)
endif

此处设置了STAMP_CONFIGURED变量,这个变量的值,是将.config中所有CONFIG_BUSYBOX_滤出,再做md5得到的值。一旦这些配置项发生变化,则md5的值会改变,STAMP_CONFIGURED的值也会改变。编译包的时候,就能判断出需要重新编译。

具体的,STAMP_CONFIGURED值是在package.mk中使用。这里还有其他的类似变量,只要改变了,就说明需要重新执行对应的操作。如STAMP_CONFIGURED,STAMP_BUILT,STAMP_INSTALLED等。

这个配置项,也会在软件包的编译目录体现出来。如果没有对其赋值,则在编译目录下,可看到名字类似 .configured_yyy 的隐藏文件。

对其进行赋值之后,这个文件的形式会变成 .configured_yyy_622f380fff06dde988852308f044653b 这种形式,后面跟着的就是由配置项生产的md5值。

结语

分析清楚了busybox的套路之后,修改下 convert_defaults.pl 和 convert_menuconfig.pl ,就可以套用到其他软件包上了。

浅析busybox如何集成到openwrt的更多相关文章

  1. busybox内置ftp服务器用法

    参考:http://blog.chinaunix.net/uid-20564848-id-74041.html 最新的busybox已集成ftp服务器层需ftpd,使用方法如下: 方法一:# tcps ...

  2. Android平台的一些常用命令

    一.Android常见目录结构 1.  apk文件在/data/app目录下 2.  /data/data/[package.name]目录,存放程序数据缓存等等 3.SD卡安装方式的,则在/mnt/ ...

  3. shell手册--笨鸟杰作

    ==================================================================================================== ...

  4. linux快速复制大量小文件方法 nc+tar【转】

    1,在需要对大量小文件进行移动或复制时,用cp.mv都会显得很没有效率,可以用tar先压缩再解压缩的方式.  2,在网络环境中传输时,可以再结合nc命令,通过管道和tcp端口进行传输.  nc和tar ...

  5. 用Qemu模拟vexpress-a9 (七) --- 嵌入式设备上安装telnet服务

    转载: http://blog.csdn.net/liuqz2009/article/details/6921789 Telnet协议是登陆远程网 络主机最简单的方法之一,只是安全性非常低.对targ ...

  6. ARM板卡ftp客户端应用

    BusyBox已集成命令tftp,可通过tftp上传或下载文件: Usage: tftp [OPTIONS] HOST [PORT] Transfer a file from/to tftp serv ...

  7. 一、Linux 设备驱动介绍及开发环境搭建

    1.1 Linux 设备驱动介绍 1.1.1 分类及特点 计算机系统的硬件主要由 CPU.存储器和外设组成. 当前 CPU 内部都集成有存储器和外设适配器. 外设适配器有入 UART.IIC 控制器. ...

  8. 《自拍教程14》Linux的常用命令

    Linux操作系统, 包括我们大家熟知的Android, Ubuntu, Centos, Red Hat, UOS等. 这些常用命令先大概了解下,当然能熟练掌握并运用到实际工作中那最好不过了. 后续技 ...

  9. 使用Linux Deploy将闲置的安卓手机改造简易服务器

    本文将介绍我在自己闲置的小米4手机安装CentOS系统的过程.手机配置信息:MIUI 9开发板(方便ROOT).Android 6.架构 ARMv7(arm32) 准备工作 1.手机必须ROOT!!! ...

随机推荐

  1. 第92天:CSS3中颜色和文本属性

    一.颜色的表示方式 1. rgba(255,0,0,0.1)  rgba是代表Red(红色) Green(绿色) Blue(蓝色)和 Alpha透明度.虽然它有的时候被描述为一个颜色空间 新增了RGB ...

  2. 运维朋友们,别再问需不需要学 Python 了!

    运维人员需不需要学开发?需不需要学 Python?PythonN 和 Shell 有什么区别?天天问这种好水的问题,我实在受不了,决定帮大家扫扫盲. 现阶段,掌握一门开发语言已经成为高级运维工程师的必 ...

  3. QT样式表

    QT样式表 一.QT样式表简介 1.QT样式表简介 QSS的主要功能是使界面的表现与界面的元素分离,使得设计皮肤与界面控件分离的软件成为可能. QT样式表是允许用户定制widgets组件外观的强大机制 ...

  4. Quartz-作业调度框架

    简介 Quartz 是个开源的作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制.Quartz 允许开发人员根据时间间隔(或天)来调度作业.它实现了作业和触发器的多对多关系,还 ...

  5. 【ZJOI2005】沼泽鳄鱼 题解报告

    题目描述 潘塔纳尔沼泽地号称世界上最大的一块湿地,它地位于巴西中部马托格罗索州的南部地区.每当雨季来临,这里碧波荡漾.生机盎然,引来不少游客. 为了让游玩更有情趣,人们在池塘的中央建设了几座石墩和石桥 ...

  6. cin/cout与scanf/printf的比较

    转自http://www.cnblogs.com/penelope/articles/2426577.html  cin .cout   基本说明: cin是标准输入流对象,代表标准输入设备(键盘), ...

  7. 基础学习笔记之opencv(24):imwrite函数的使用

    http://www.cnblogs.com/tornadomeet/archive/2012/12/26/2834336.html 前言 OpenCV中保存图片的函数在c++版本中变成了imwrit ...

  8. Virtual Box虚拟机下CentOS网络设置

    VirtualBox中有4中网络连接方式: a. NAT                          网络地址转换模式(Network Address Translation)b. Bridge ...

  9. array_uintersect、array_uintersect_assoc、array_uintersect_uassoc 的使用方法

    和 array_intersect 类似,只不过 array_uintersect* 系列函数的值比较使用自定义函数: 键的比较,array_uintersect.array_uintersect_a ...

  10. VLFeat在matlab和vs中安装

    转:http://blog.csdn.net/u011718701/article/details/51452011 博主最近用vlfeat库做课题,网上搜索使用方法,一大片都会告诉你说:run(/v ...