背景

近日添加了一个包到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. 解决Lenovo(ldeapad)笔记本F1-F12功能键操作无效的问题

    1.操作条件:Lenovo笔记本自带的“一键恢复”按钮 2.操作方法:上下键为切换选项,回车键(Enter)为确定选择 (1)在笔记本电脑关机状态下,使用曲别针或其他物件按下笔记本自带的“一键恢复按钮 ...

  2. Struts的xml包必须继承Struts-default 不然不能使用拦截器与返回类型的功能

    Struts的xml包必须继承Struts-default 不然不能使用拦截器与返回类型的功能

  3. HDFS集中式的缓存管理原理与代码剖析--转载

    原文地址:http://yanbohappy.sinaapp.com/?p=468 Hadoop 2.3.0已经发布了,其中最大的亮点就是集中式的缓存管理(HDFS centralized cache ...

  4. Luogu4926 倍杀测量者(二分答案+差分约束)

    容易想到二分答案.问题变为判断是否所有条件都被满足,可以发现这是很多变量间的相对关系,取个log之后就是经典的差分约束模型了.特殊的地方在于某些人的分数已被给定,从每个人开始跑一遍最短路判断一下是否能 ...

  5. 二分图匹配模板(dfs+bfs)

    dfs版: bool dfs(int u) { for(int i = head[u]; ~i; i = e[i].next) { int v = e[i].v; if(!vis[v]) { vis[ ...

  6. ubuntu adduser

    ubuntu adduser 添加用户 hexan 到目录 /home/hexan 下.$ sudo adduser hexan -home /home/hexan 添加一个普通用户adduser [ ...

  7. [NOI2016]优秀的拆分 后缀数组

    题面:洛谷 题解: 因为对于原串的每个长度不一定等于len的拆分而言,如果合法,它将只会被对应的子串统计贡献. 所以子串这个限制相当于是没有的. 所以我们只需要对于每个位置i求出f[i]表示以i为开头 ...

  8. NOIP模拟

    1.要选一个{1,2,...n}的子集使得假如a和b在所选集合里且(a+b)/2∈{1,2,...n}那么(a+b)/2也在所选集合里 f[i]=2*f[i-1]-f[i-2]+g[i] g[n]:选 ...

  9. 洛谷 U14472 数据结构【比赛】 【差分数组 + 前缀和】

    题目描述 蒟蒻Edt把这个问题交给了你 ---- 一个精通数据结构的大犇,由于是第一题,这个题没那么难.. edt 现在对于题目进行了如下的简化: 最开始的数组每个元素都是0 给出nnn,optopt ...

  10. python学习(十七) 爬取MM图片

    这一篇巩固前几篇文章的学到的技术,利用urllib库爬取美女图片,其中采用了多线程,文件读写,目录匹配,正则表达式解析,字符串拼接等知识,这些都是前文提到的,综合运用一下,写个爬虫示例爬取美女图片.先 ...