随着网络技术的不断发展,网络现在已无处不在。Linux最大的好处在于其良好的网络功能,因此在该系统中,我们通过设计WEB服务器,使用户能通过浏览器访问设备上的Web服务器来远程控制现场设备。嵌入式Linux下,系统资源是非常有限的,因此我们选择Web服务器时,要考虑到其资源有限的特点;Boa是一种非常小巧的Web服务器,其可执行代码只有大约60KB左右。作为一种单任务Web服务器,Boa只能依次完成用户的请求,而不会fork出新的进程来处理并发连接请求。但Boa支持CGI,能够为CGI程序fork出一个进程来执行,Boa的设计目标是速度和安全。
现在,多数嵌入式Linux的代码中已经包含boa的源代码,在嵌入式Linux下实现Boa只需要对Boa做一些简单的配置和修改。这主要通过对boa.conf、boa.c、mime.types等文件进行修改来实现。服务器中主要包括boa和CGI两部分,其中Boa管理着返回客户端的WEB页面,而CGI控制着客户端和服务器端的信息交换,所以我们可以通过编写相应的CGI程序来实现所需要的功能。Boa服务器的实现主要分为两步,boa服务器的移植和CGI程序的设计。
1、boa服务器移植
Boa服务器的移植主要分为以下步骤进行:
(1)首先下载boa源代码,网上有很多关于boa的源码下载网站,官方网址为:http://www.boa.org/;
(2)根据目标平台修改boa的配置文件boa.conf,以及相关的源代码文件boa.c,log.c。(3)执行configure生成Makefile,并修改Makefile中CC和CPP等项,改成与目标平台对应的编译工具;
(4)交叉编译源代码,生成可执行文件boa;
(5)拷贝配置文件boa.conf和可执行程序boa到文件系统中。此时就可以在目标板中运行boa程序了。
下面具体介绍一下如何在ARM平台上移植boa服务器:
本系统中采用的boa源码是boa-0.94.13.tar.gz,将下载的源码拷贝到工作目录解压,#tarxzfboa-0.94.13.tar.gz
这里注意下系统中需要安装bison,flex等工具,如果在U-BOOT移植中已经在开发主机中安装过这些工具,则可以跳过这一步骤。如果没有,在UBUNTU系统中使用如下命令就可以自动安装:
#sudoapt-getinstallbisonflex
如果不安装这些工具,在执行make生成可执行文件时会出现如下错误make:yacc:commannotfoundmake:***[y.tab.c]error127make:lex:commannotfoundmake:***[lex.yy.c]error127
解压完源代码后,我们进入boa目录,boa的所有源代码及编译文件都放在都放在/src下面,进入该目录
#cd/source/boa-0.94.13/src
相关文件的修改:
此时,我们要做的就是对该目录下一些源代码做相应的修改,首先修改compat.h文件,打开文件找到下面的语句:
#defineTIMEZONE_OFFSET(foo)foo##->tm_gmtoff将其修改成
#defineTIMEZONE_OFFSET(foo)(foo)->tm_gmtoff否则会出现错误:
util.c:100:1:error:pasting"t"and"->"doesnotgiveavalidpreprocessingtokenmake:***[util.o]
修改log.c源文件,将以下语句注释掉:if(dup2(error_log,STDERR_FILENO)==-1){DIE("unabletodup2theerrorlog");}
否则会出现错误:
log.c:73unabletodup2theerrorlog:badfiledeor
boa.c文件的修改:注释掉下面两句话:if(passwdbuf==NULL){DIE(”getpwuid”);}
if(initgroups(passwdbuf->pw_name,passwdbuf->pw_gid)==-1){DIE(”initgroups”);}
否则会出现错误:boa.c:211-getpwuid:Nosuchfileordirectory注释掉下面语句:if(setuid(0)!=-1){
DIE(”ickyLinuxkernelbug!”);}
否则会出现问题:boa.c:228-ickyLinuxkernelbug!:Nosuchfileordirectory
生成可执行文件BOA:
首先进入src目录,并执行configure文件,生成Makefile文件#cd/source/boa-0.94.13/src#./configure
生成完Makefile后,接下来要做的就是对其做相应的修改,因为我们对应的目标平台是ARM,所以我们要查看我们用到的交叉编译器设置是否正确,本实验中所要修改的具体参数为:
修改CC=gcc为CC=arm-softfloat-linux-gnu-gcc
修改CPP=gcc-E为CC=arm-softfloat-linux-gnu-gcc-E
在确认以上修改正确后,我们在/src目录下就可以使用make命令来生成我们所需要的可执行文件boa了。#make
此时会在当前目录下生成一个名为boa的可执行文件,可以通过ls命令查看。
#ls-lboa:
-rwxr-xr-x1rootroot1872132009-07-1113:44boa
可以看到生成的可执行文件有180K,对于嵌入式系统来说,我们要尽可能的缩下其大小,因此,我们可以通过瘦身命令strip来删除其中的多余信息,达到缩下体积的目的。#arm-linux-stripboa#ls-lboa
-rwxr-xr-x1rootroot610522009-07-1113:49boa
可以看到,boa在瘦身前后的大小差距很大,这对嵌入式系统来说,节省了很大的空间。
Boa的配置
在生成好boa以后,还要对boa的配置文件boa.conf做修改,在boa-0.94.13目录下已有一个示例boa.conf,可以在其基础上进行修改。修改如下:#viboa.conf(1)Group的修改修改Groupnogroup
为Group0……(2)user的修改
修改Usernobody……为User0
(3)Alias的修改
修改Alias/cgi-bin//usr/lib/cgi-bin/……为Alias/cgi-bin//www/cgi-bin/(5)DocumentRoot的修改
修改DocumentRoot/var/www……为DocumentRoot/www(6)ServerName的设置
修改#ServerNamewww.your.org.here……为ServerNamewww.your.org.here
否则会出现错误“gethostbyname::Nosuchfileordirectory”(7)AccessLog修改
修改AccessLog/var/log/boa/access_log
为#AccessLog/var/log/boa/access_log……
否则会出现错误提示:“unabletodup2theerrorlog:Badfiledeor”
配置好boa.conf以后,我们将生成的boa以及修改好的boa.conf文件拷贝到文件系统中相应的目录中:
首先在目标板上创建目录/etc/boa并且把boa和boa.conf拷贝到这个目录下mkdir/etc/boa
创建HTML文档的主目录/wwwmkdir/www
创建CGI脚本所在录/www/cgi-binmkdir/www/cgi-bin
以下步骤在REDHAT下进行:
将boa.conf拷贝到开发板根文件系统的/etc/boa下#cpboa.conf/source/rootfs/etc/boa
将boa拷贝到开发板根文件系统的/etc/boa下#cpsrc/boa/source/rootfs/etc/boa
将ubuntu下/etc/mime.types拷贝到开发板根文件系统的/etc下,mime.types的主要功能是控制从网络上发给宿主机端的媒体文件的类型,并且告诉宿主机怎么去处理这些数据。#cp/etc/mime.types/source/rootfs_hw/etc
这时,我们可以将一个测试网页拷贝到/www目录下,并在开发板上启动boa服务器/etc/boa/boa
然后在宿主机下,打开浏览器输入开发板的IP地址,就可以看到存放在开发板中的测试主页了,但此时我们点击页面上的按钮时不会执行任何相应,因为现在只是实现了简单的连接,网页并没有相应的CGI程序。在boa服务器的设计中,最为关键的就是CGI程序的设计,通过CGI程序,就可以实现我们点击页面时所需要的功能。
2、CGI程序设计
该系统所要实现的功能是让客户端使用浏览器向服务器发送HTTP请求,服务器响应客户端的请求后,并引导到指定的脚本程序,对命令进行解析,将信息交给后台——CGI去处理。CGI解析信息后,向远程设备发出控制信息。设备响应后,返回给CGI控制信息,CGI再将信息解析成变量输出到WebServer上,最后客户端得到WebServer发回的页面消息(HTML),就能得到现场设备的运行状态,实现对现场设备的远程监控。该系统中设计的BOA服务器的的主要功能如下图所示:
图1系统功能实现流程图
CGI的程序编写包括两个部分:HTML代码和C代码;CGI程序与BoaWeb服务器之间通过环境变量、命令行参数和标准输入等方式进行通信。本设计中采用的表单编码信息通过环境变量QUERY_STRING传递。在编写CGI程序时,需要注意:◆REQUEST_METHOD
前面介绍过,请求方法有两种:GET和POST。在实验中,我选择GET方法,如在showsetip()中的代码:
<metahttp-equiv=pragmacontent=no-cache>
<metahttp-equiv=expirecontent=now>
<formmethod=getaction=/cgi-bin/config.cgi>◆环境变量
在选用不同的方法时,所对应的环境变量也不同。选择GET时,所对应的环境变量是QUERY_STRING,通过调用库函数getenv()来得到环境变量的具体值,即querystring=getenv(QUERY_STRING)。系统功能框架图如下:
3、Boa服务器测试