Goahead是一款适合嵌入式的web Server, 支持asp,cgi,embedded JavaScrip等脚本语言 基本上在windows下或者在redhat9下面只要make一下就能运行了. 体积小巧的嵌入式服务器:GoAhead GoAhead Web服务器,小巧,精致,提供了值得称道的性能。 GoAhead Web 服务器是一款主要面向嵌入式系统的WEB服务器,它的目标也许不在于目前的WEB服务器市场,而是面向当嵌入式系统深入我们的工作与生活的明天,那时,它也许会成为使用最广泛的WEB服务器。 GoAhead Web服务器是GoAhead公司的Embedded Management Framework产品的一部分,这个软件包主要用于解决未来嵌入式系统开发的相关问题。这款WEB服务器非常小巧,它的WIN CE版本编译后的大小还不到60k,它的输出通常也是面向一些小屏幕设备。在性能方面,使用一颗24MHz的68040处理器,它的响应速度为20次/秒,使用266MHz的Pentium处理器可以达到50次/秒的响应速度。 仅管它的体积非常小巧,GoAhead WEB服务器提供了不少的服务特性。它支持ASP,嵌入的JAVASCRPT与内存CGI处理。不过有人也许会置疑对嵌入式系统而言,对ASP的支持有否有这个必要。而嵌入的JAVASCRIPT解释引擎则是不得不然的选择,因为得用它创建动态服务器内容,而且ASP也要用到它。 到目前为止,GoAhead的源码完全免费,使用它无需交纳版税或者许可证费用。对一些硬件开发者而言,这种做法比较普遍,例如SUN旗下的众多开源系统。这样作的主要原因是GoAhead公司希望它成力未来嵌入式环境下的WEB服务器标准平台并看好日益增长的更智能化嵌入式设备的市场。 因为GoAhead发行包中包含C语言的源码和makefile,理论上,你可以在非嵌入式环境下很好的使用GoAhead Web服务器(正如我写这篇文章时所做的)。它的参考平台有Windows CE, Wind River VxWorks, Linux, Lynx, QNX,与Windows 95/98/NT。它基本上属于一个HTTP1.0标准的WEB服务器,对一些HTTP1.1的特性如(持久连接)也提供了支持。 无可否认,GoAhead WEB服务器是一款面向特定细分市场的产品,也许目前对于这个市场外的大多数人来说很难对它投以太多的专注。但众多的分析家和计算机产业领导者(包括LINUX之父Linus Torvalds)都相信在未来的计算机世界,智能化嵌入式系统将会扮演一个极在重要的角色,当这个市场成熟起来的时候,就是GoAhead大展站拳脚之时。 优点:免费,体积小巧,支持多平台,完全针对嵌入式系统设计,嵌入的JavaScript与动态数据页支持。 缺点:对ASP的支持意味着要依靠微软平台,很少的安全方面的考虑。 笔者移植的是目前官方网站发布的最新版本(截至2008-11-26)。webs218.tar.gz 网址为: http://www.goahead.com/products/webserver/download.aspx 值得高兴的是,笔者在移植最新的版本前,也按着各种文档尝试移植以前的版本,但由于各种各样奇怪的问题都没有成功,一气之下直接移植最新的版本,没有想到是如此容易。 首先是解压: [root@localhost /]# Tar zxvf webs218.tar.gz 改名为goahead [root@localhost /]# mv ws031202/ goahead 可以看到,goahead支持很多的操作系统,如LINUX,VXWORKs,Windows CE等。 修改Goahead/LINUX/Makefile文件 修改Goahead/LINUX/Makefile文件,在 Goahead/LINUX/makefile 开头添加如下的黑斜体部分的文字。 # CROSS_COMPILE为交叉编译器所在路径,如果为uCLinux,则为CROSS_COMPILE = arm-elf-,如果为MIPS,则为CROSS_COMPILE = mipsel-linux-,如果为2410,则为armv4l-unknown-linux-,注意,在/root/.bash_profile中要指明路径,具体为加入export PATH=$PATH:/xxxxxxx/bin ################################################################ CROSS_COMPILE = armv4l-unknown-linux- AS = $(CROSS_COMPILE)as LD = $(CROSS_COMPILE)ld CC = $(CROSS_COMPILE)gcc CPP = $(CC) -E AR = $(CROSS_COMPILE)ar NM = $(CROSS_COMPILE)nm STRIP = $(CROSS_COMPILE)strip OBJCOPY = $(CROSS_COMPILE)objcopy OBJDUMP = $(CROSS_COMPILE)objdump all: compile ARCH = libwebs.a NAME = webs # User Management switch UMSW = -DUSER_MANAGEMENT_SUPPORT # Digest Access switch DASW = -DDIGEST_ACCESS_SUPPORT ………….(省略) main.o: main.c ../wsIntrn.h ../webs.h ../ej.h ../ejIntrn.h ../uemf.h # # Transition rules (add -o to put object in right directory) # .c.o: #cc -c -o $@ $(DEBUG) $(CFLAGS) $(IFLAGS) $ $(CC) -c -o $@ $(DEBUG) $(CFLAGS) $(IFLAGS) $ #################################################################### 然后在goahead/LINUX目录下直接 make 修改一个危险函数,消除警告 此时会出现如下错误 mipsel-linux-gcc -o webs -g -Wall \ -DWEBS -DUEMF -DOS="LINUX" -DLINUX -DUSER_MANAGEMENT_SUPPORT -DDIGEST_ACCESS_SUPPORT -I.. \ main.o libwebs.a main.o: In function `websGetCgiCommName': /goahead/LINUX/main.c:325: warning: the use of `tempnam' is dangerous, better use `mkstemp' 解决办法: 找到main.c (goahead/LINUX目录) 文件,在函数websGetCgiCommName(..)函数中 char_t *websGetCgiCommName() { char_t *pname1, *pname2; //pname1 = tempnam(NULL, T("cgi")); pname1 = (char_t *)mkstemp(T("cgi")); pname2 = bstrdup(B_L, pname1); free(pname1); #ifdef Wreturn pname2;T } 此时将能够编译通过。下一步就是安装到嵌入式开发板上运行。 解决无法连接问题 但发现还是无法运行,经分析原来是名称无法解析造成的,因此,建议直接改为IP地址方式。 web初始化的时候有这样的 code: if (gethostname(host, sizeof(host)) error(E_L, E_LOG, T("Can't get hostname")); return -1; } if ((hp = gethostbyname(host)) == NULL) { error(E_L, E_LOG, T("Can't get host address")); return -1; } gethostname得到的host为"(none)";gethostbyname则调用失败,返回NULL;我用printf("Error:%s\n",hstrerror(h_errno));查看错误,得到的是Error:Host Name Lookup failure! 而且我用hostname khy;设置主机名后,gethostname能得到名字为khy,但下面gethostbyname函数调用仍然返回失败。这样webserver没办法运行。 main.c(linux) 文件 initwebs(...) 函数中: /* if ((hp = gethostbyname(host)) == NULL) { error(E_L, E_LOG, T("Can't get host address")); fprintf(stderr,"initWebs: host name %s\r ",host); return -1; } memcpy((char *) &intaddr, (char *) hp->h_addr_list[0], (size_t) hp->h_length); */ intaddr.s_addr = inet_addr("10.2.2.14"); // 44B0的网卡IP gethostbyname函数在此处无效,我屏蔽了这段,不得已只能直接写入IP地址给intaddr了。非常重要。 直接注意的是,如果在开发板上输入hostname ,显示hostname 10.2.2.14和ifconfig 显示的IP 一致时,上述代码不用修改。除此之外,都需要修改,否则会提示如下错误。 十分头疼的`GLIBC_2.3' not found问题 本人目前所在的课题组都基于龙芯CPU核,该核采用MIPS指令集,目前已有的交叉编译环境虽有两个版本。 [root@srv3 bin]# ./mipsel-linux-gcc -v Reading specs from ./../lib/gcc-lib/mipsel-linux/2.96/specs gcc version 2.96 20000731 (Red Hat Linux 7.3 2.96-113.2) neon [root@srv3 bin]# mipsel-unknown-linux-gnu-gcc -v Reading specs from /Cross/cross_gcc3.4.3/bin/../lib/gcc/mipsel-unknown-linux-gnu/3.4.3/specs Configured with: ../gcc-3.4.3/configure --target=mipsel-unknown-linux-gnu --prefix=/opt/cross_gcc3.4.3 --enable-languages=c --without-headers --disable-shared --disable-threads : (reconfigured) ../gcc-3.4.3/configure --target=mipsel-unknown-linux-gnu --prefix=/opt/cross_gcc3.4.3 --enable-languages=c --without-headers --disable-shared --disable-threads -with-newlib : (reconfigured) ../gcc-3.4.3/configure --target=mipsel-unknown-linux-gnu --prefix=/opt/cross_gcc3.4.3 --enable-languages=c,c++ : (reconfigured) ../gcc-3.4.3/configure --target=mipsel-unknown-linux-gnu --prefix=/opt/cross_gcc3.4.3 --enable-languages=c Thread model: posix gcc version 3.4.3 但有一个很致命的问题是,它们所使用的GLIBC的版本都是libc-2.2.5.so,低于2.3,很多高版本软件的编译不仅对GCC编译器有高版本要求,而且对GLIBC库也要求高于2.3 版本,因此 /lib/libc.so.6: version `GLIBC_2.3' not found (required by webs) 的错误提示就是这个意思,只要高于所指定的2.3版本即可,并不要求必须等于该版本。 解决办法:重新找一个 高版本GLIBC库(ftp://ftp.gnu.org/)重新编译,或重新找一个已经编译好的工具链,作者尝试前者时遇到了很多莫名其妙的错误,尚未成功,后来在下面所列的网站上找到了已经编译好的版本较高的交叉编译器mipseltools-gcc412-lnx26.tar.gz。 http://www.ingenic.cn/pfwebplus/productServ/kfyd/linux/pfFixedPage.aspx 下载后直接解压缩即可。 当提示以上错误时,只需要将libc相关库文件从mipseltools-gcc412-lnx26/lib拷贝到嵌入式开发板根文件系统的lib下,覆盖低版本glibc即可,注意符号连接不能丢失,用cp –raf xxx yyy方式拷贝,再次运行,此时会提示更莫名其妙的错误segmentation fault,一时让笔者心灰意冷,通过ldd webs(在开发板上输入)发现webs不仅依赖libc库,而且还依赖ld,于是想到可能还是版本问题,于是将ld相关库也从mipseltools-gcc412-lnx26/lib拷贝到嵌入式开发板根文件系统的lib下,重新运行就ok了。