返回 登录
0

怎么在Openwrt中开发自己的ipk固件

阅读428

之前写过一篇日志,是关于如何搭建自己的OpenWRT开发环境。经过最近一段时间的开发学习和实践,对OpenWRT环境的开发有了一定的了解。在这里将我的开发心得做个整理。

1、搭建开发环境 首先,我们需要一个为路由器定制的开发环境,具体可以参考我的另一篇日志:《搭建自己的OpenWrt开发环境》。这里只做一个简单的补充,在执行make menuconfig后,会出现下图:

其中,图中红框部分是我定制路由器的系统版本,大家可以根据不同的路由器进行不同的选择;绿框部分表示我们需要编译一个SDK开发环境(默认情况下,此项未勾选)。

编译过程中需要通过官网下载很多相关的软件包,所以必须保证能够顺利连上外网。由于下载速度的限制,编译过程大概需要数小时。编译结束后,所有的产品都会放在编译根目录下的bin/yourtarget/. 例如:我所编译的产物都放在./bin/brcm47xx/下,其中文件主要有几类:

(1).bin/.trx 文件: 这些都是在我们所选的target-system的类别之下,针对不同路由器型号、版本编译的路由器固件。这些不同路由器的型号和版本是openwrt预先设置好的,我们不需要更改。至于.bin和.trx的区别,一种说法是,第一次刷路由器的时候,需要用.bin文件,如果需要再升级,则不能再使用.bin文件,而需要用.trx文件。原因是,.bin是将路由器的相关配置信息和.trx封装在一起而生成的封包,也就是说是包含路由器版本信息的.trx。在第一次刷固件的时候,我们需要提供这样的信息,而在后续升级时,则不再需要,用.trx文件即可。

(2)packages文件夹: 里面包含了我们在配置文件里设定的所有编译好的软件包。默认情况下,会有默认选择的软件包。

(3)OpenWrt-SDK.**.tar.bz2: 这个也就是我们定制编译好的OpenWRT SDK环境。我们将用这个来进行OpenWrt软件包的开发。例如,我所编译好的SDK环境包为:/bin/brcm47xx/OpenWrt-SDK-brcm47xx-for-Linux-x8664-gcc-4.3.3+csuClibc-0.9.30.1.tar.bz2 可以从名称上看出,target system是brcm47xx,host system是Linux-x8664,使用的编译工具以及库是4.3.3+csuClibc-0.9.30.1。

(4)md5sums 文件: 这个文件记录了所有我们编译好的文件的MD5值,来保证文件的完整性。因为文件的不完整,很容易将路由器变成“砖头”。

需要主要的是,编译完成后,一定要将编译好的bin目录进行备份(如果里面东西对你很重要的话),因为在下次编译之前,执行make clean 会将bin目录下的所有文件给清除掉!!

2、 更改原有packages

在编译根目录下会有一个dl的目录,这个目录其实是“download”的简写,在编译前期,需要从网络下载的数据包都会放在这个目录下,这些软件包的一个特点就是,会自动安装在所编译的固件中,也就是我们make menuconfig的时候,为固件配置的一些软件包。如果我们需要更改这些源码包,只需要将更改好的源码包打包成相同的名字放在这个目录下,然后开始编译即可。编译时,会将软件包解压到build_dir目录下。 当然,你也可以自己在dl里面创建自己的软件包,然后更改相关的配置文件,让openwrt可以识别这个文件包。

由于我的项目更改的内容是底层的,需要跟固件一起安装。所以,我使用的方法就是直接更改dl目录下软件包,然后重新进行固件编译。感觉类似于Linux的内核编译。反复编过十多次,没有任何问题。

3、 新建自己的packages 对于自己新建的package,而这个package又不需要随固件一起安装,换句话说,就是可以当做一个可选软件包的话。我们可以利用我们的SDK环境来单独编译,编译后会生成一个ipk的文件包。然后利用 opkg install xxx.ipk 来安装这个软件。

下面具体说下,如何编译一个helloword的软件包。 (1)首先,编写helloworld程序 编写helloworld.c /**************** * Helloworld.c * The most simplistic C program ever written. * An epileptic monkey on crack could write this code. *****************/

include <stdio.h>

include <unistd.h>

int main(void) { printf("Hell! O' world, why won't my code compile?\n\n"); return 0; }

编写Makefile文件

build helloworld executable when user executes "make"

helloworld: helloworld.o $(CC) $(LDFLAGS) helloworld.o -o helloworld

helloworld.o: helloworld.c $(CC) $(CFLAGS) -c helloworld.c

remove object files and executable when user executes "make clean"

clean: rm *.o helloworld

在这两个文件的目录下,执行make 应该可以生成helloworld的可执行文件。执行helloworld后,能够打印出“Hell! O' world, why won't my code compile?”。 这一步,主要保证我们的源程序是可以正常编译的。下面我们将其移植到OpenWRT上。

(2)将OpenWrt-SDK-brcm47xx-for-Linux-x8664-gcc-4.3.3+csuClibc-0.9.30.1.tar.bz2解压 tar –xvf OpenWrt-SDK-brcm47xx-for-Linux-x8664-gcc-4.3.3+csuClibc-0.9.30.1.tar.bz2

(3)进入SDK cd OpenWrt-SDK-brcm47xx-for-Linux-x8664-gcc-4.3.3+csuClibc-0.9.30.1 可以看到里面的目录结构跟我们之前source的目录结构基本相同,所需要编译的软件包,需要放置在package目录下

(4)在package目录下创建helloworld目录 cd package mkdir helloworld cd helloworld

(5)创建src目录,拷贝 helloworld文件 mkdir src cp /home/wrt/test/helloworld.c src cp /home/wrt/test/Makefile src

(6)在helloworld目录下创建Makefile文件 这个Makefile文件是给OpenWRT读的,而之前写的那个Makefile文件是针对helloworld给编译其读的。两个Makefile不在同一层目录下。

touch Makefile vim Makefile

Makefile文件模板内容如下:

#

OpenWrt Makefile for helloworld program

# #

Most of the variables used here are defined in

the include directives below. We just need to

specify a basic description of the package,

where to build our program, where to find

the source files, and where to install the

compiled program on the router.

#

Be very careful of spacing in this file.

Indents should be tabs, not spaces, and

there should be no trailing whitespace in

lines that are not commented.

#

#

include $(TOPDIR)/rules.mk

Name and release number of this package

PKGNAME:=helloworld PKGRELEASE:=1

This specifies the directory where we're going to build the program.

The root build directory, $(BUILDDIR), is by default the buildmipsel

directory in your OpenWrt SDK directory

PKGBUILDDIR := $(BUILDDIR)/$(PKGNAME)

include $(INCLUDE_DIR)/package.mk

Specify package information for this program.

The variables defined here should be self explanatory.

If you are running Kamikaze, delete the DESCRIPTION

variable below and uncomment the Kamikaze define

directive for the description below

define Package/helloworld SECTION:=utils CATEGORY:=Utilities TITLE:=Helloworld -- prints a snarky message endef

Uncomment portion below for Kamikaze and delete DESCRIPTION variable above

define Package/helloworld/description If you can't figure out what this program does, you're probably brain-dead and need immediate medical attention. endef

Specify what needs to be done to prepare for building the package.

In our case, we need to copy the source files to the build directory.

This is NOT the default. The default uses the PKGSOURCEURL and the

PKG_SOURCE which is not defined here to download the source from the web.

In order to just build a simple program that we have just written, it is

much easier to do it this way.

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

We do not need to define Build/Configure or Build/Compile directives

The defaults are appropriate for compiling a simple program such as this one

Specify where and how to install the program. Since we only have one file,

the helloworld executable, install it by copying it to the /bin directory on

the router. The $(1) variable represents the root directory on the router running

OpenWrt. The $(INSTALL_DIR) variable contains a command to prepare the install

directory if it does not already exist. Likewise $(INSTALL_BIN) contains the

command to copy the binary file from its current location (in our case the build

directory) to the install directory.

define Package/helloworld/install $(INSTALLDIR) $(1)/bin $(INSTALLBIN) $(PKGBUILDDIR)/helloworld $(1)/bin/ endef

This line executes the necessary commands to compile our program.

The above define directives specify all the information needed, but this

line calls BuildPackage which in turn actually uses this information to

build a package.

$(eval $(call BuildPackage,helloworld))

(7)返回到SDK的根目录 执行make进行编译 会报错

解决办法: 百度 openwrt-mt7620/bin/ralink/OpenWrt-SDK-ralink-for-linux-i486-gcc-4.6-linaro_uClibc-0.9.33.2# vi include/prereq-build.mk 第十五行:注释掉

再make 不要在helloworld/src中执行make,如果执行了make那就make clean一下再在SDK根目录中执行make V=s。 编译过程会在builddir目录下完成 编译结果会放在 bin/[yourtarget]/package目录下helloworld1_bcm47xx.ipk

(8)上传helloworld1bcm47xx.ipk 使用sftp软件上传helloworld1bcm47xx.ipk至路由器 执行 opkg install helloworld1bcm47xx.ipk 输入hello然后按Tab键,发现openwrt中已经有helloworld可执行命令。 执行 helloworld 查看程序的效果。

Hell! O' world, why won't my code compile?

【End】

怎么上传helloworld1bcm47xx.ipk到路由器 一、 由于一般路由器的IP地址为192.168.1.1,所以可以用串口设置secureCRT通过命令设置路由器的IP地址 命令:ifconfig br-lan 192.168.1.20 a、如果自己的电脑IP和开发用的路由器IP不在同一个网段,即IP地址不是192.168.1.x。那么必须添加这个网段的IP地址。 电脑添加IP的方法 打开网络和共享中心(win7)

点击属性

选中IPV4属性

高级

添加

b、如果是办公网络,到你电脑前面只有一根网线,可以通过路由器做交换机,方法 用路由器的LAN口,通过LAN口可以把路由器当做交换机,将一根网线分成两个。 C、路由器刷OPENWRT时碰到的IPK其实是OPENWRT的软件、就像是Windows下的软件一样、但是安装的话就麻烦点了、 方法/步骤 1. 用winscp连接路由 需要自行下载winscp 2. 把已经下载好的软件包,放到/tmp里 3. ssh连接路由命令安装或者用ssh软件PuTTY连接路由器 4. 登陆路由 输入命令opkg install /tmp/xxx.ipk回车(这个命令代表安装,注意带空格的.XXX是您的软件名) 或者输入命令opkg install /tmp/xxx.ipk --force-depends回车(这个命令 --force-depends代表强制安装,注意强制安装是对于一些安装不了,或是安装错误,才使用,强制安装有可能会引起软件不匹配或者不稳定,或者不能用,但是也有好处,有的安装不了,用强制安装命令来安装,安装完成,全部正常) 执行这个安装命令的时候,会出错,出错信息为 * verifypkginstallable: Only have 0kb available on filesystem /overlay, pkg helloworld needs2 * opkginstallcmd: Cannot install package helloworld 需要通过串口发送命令设置 mount -t tmpfs none /overlay/ 再安装ipk就不会出问题了 然后再查找程序安装在哪里了,其实makefile已经确定程序安装在那个目录了 find . -name helloworld D、怎么使用winscp将ipk程序下载进路由器 对于现在MT7620N的内核,其数据全是保存在SDRAM中的,所以路由器重启以后,设置的数据无法保存,比如用户密码,IP地址 所以在用winscp访问路由器时,要先用IE登录路由器,然后在

修改一下密码 用winscp访问路由器,要将sftp协议修改为scp协议

评论