Web服务移植 thttpd在ARM移植.docx
《Web服务移植 thttpd在ARM移植.docx》由会员分享,可在线阅读,更多相关《Web服务移植 thttpd在ARM移植.docx(11页珍藏版)》请在冰豆网上搜索。
Web服务移植thttpd在ARM移植
thttpd在ARM移植
1下载并解压:
下载地址为:
下载的是最新的2.25b
解压:
[root@Binnarysource]#tar-xvzfthttpd-2.25b.tar.gz
2交叉编译thttpd
[root@Binnarysource]#cdthttpd-2.25b
[root@Binnarythttpd-2.25b]#CC=/armtools/bin/arm-linux-gcc./configure--host=arm-linux
[root@Binnarythttpd-2.25b]#make
3安装与配置
3.1拷贝thttpd二进制可执行文件到根文件系统/usr/sbin/目录中
[root@Binnarythttpd-2.25b]#cpthttpd/fs/usr/sbin/
3.2拷贝thttpd配置文件
[root@Binnarythttpd-2.25b]#cpcontrib/redhat-rpm/thttpd.conf/fs/etc/
3.3在开发板上为thttpd创建一个独立的用户:
httpd,并用此用户创建httpd服务的根目录html
[root@/root]#adduserhttpd(在ARM开发板上去添加用户)
Changingpasswordforhttpd
Enterthenewpassword(minimumof5,maximumof8characters)
Pleaseuseacombinationofupperandlowercaselettersandnumbers.
Enternewpassword:
Badpassword:
tooshort.
Warning:
weakpassword(continuing).
Re-enternewpassword:
passwd[786]:
passwordfor`httpd'changedbyuser`root'
Passwordchanged.
[root@/root]#exit
process'-/bin/login'(pid787)exited.Schedulingitforrestart.
startingpid790,tty'':
'/bin/login'
192.168.1.2login:
httpd
Password:
Processing/etc/profile...
Setsearchlibrarypathin/etc/profile
Setuserpathin/etc/profile
SetPS1in/etc/profile
Done
[httpd@/home/httpd]#mkdirhtml
3.4拷贝测试网页到httpd服务的根目(可选,测试之用):
[root@Binnarythttpd-2.25b]#cpindex.html/fs/home/httpd/html/
我是动态编译所以查看一下需要的动态库
[root@Binnarythttpd-2.25b]#/armtools/bin/arm-linux-readelf-dthttpd
Dynamicsectionatoffset0x12014contains21entries:
TagTypeName/Value
0x00000001(NEEDED)Sharedlibrary:
[libcrypt.so.1]
0x00000001(NEEDED)Sharedlibrary:
[libc.so.6]
0x0000000c(INIT)0x9548
0x0000000d(FINI)0x16564
0x00000004(HASH)0x8128
0x00000005(STRTAB)0x8c14
0x00000006(SYMTAB)0x8494
0x0000000a(STRSZ)1066(bytes)
0x0000000b(SYMENT)16(bytes)
0x00000015(DEBUG)0x0
0x00000003(PLTGOT)0x220e4
0x00000002(PLTRELSZ)872(bytes)
0x00000014(PLTREL)REL
0x00000017(JMPREL)0x91e0
0x00000011(REL)0x91a0
0x00000012(RELSZ)64(bytes)
0x00000013(RELENT)8(bytes)
0x6ffffffe(VERNEED)0x9130
0x6fffffff(VERNEEDNUM)2
0x6ffffff0(VERSYM)0x903e
0x00000000(NULL)0x0
虽然这里只列出了需要libcrypt和libc这两个动态库,但是想要运行thttpd还需要libnss_files动态库,具体原因如下解释:
[root@Binnarythttpd-2.25b]$cp-d/armtools/arm-linux/lib/libnss_files*/fs/lib/
你可以在启动文件里增加thttpd的启动命令:
thttpd-C/etc/thttpd.conf
注意只有root有启动权限!
4、增加对CGI的支持
默认配置下,thttpd不可以运行GCI(特别是动态编译的CGI程序)要想使用CGI支持功能,必须更改thttpd.conf的配置:
#Thissectionoverridesdefaults
dir=/home/httpd/html
#chroot
#屏蔽chroot是为了运行动态编译的CGI
user=httpd#default=nobody
logfile=/var/log/thttpd.log
pidfile=/var/run/thttpd.pid
#Thissection_documents_defaultsineffect
port=80
#port参数用于更改端口号(可不改,若还运行了别的WEB服务器,则需用不同端口)
#nosymlink#default=!
chroot
#symlinks
#novhost
cgipat=/cgi-bin/*
#声明CGI程序的目录,是以dir为根目录的路径
#nothrottles
#host=0.0.0.0
#charset=iso-8859-1
移植完成,可以测试了(只需在WEB浏览器中键入开发板的IP地址即可)。
在建立embeddedLinux系统(rootfilesystem)时,链接库相依(librarydependencies)是相当重要的目。
当rootfilesystem缺少必要的library时,程序当然是无法执行的,甚致系统也会无法顺利启动。
在建构embeddedLinux系统时,应具备的正确观念与基本能力。
我们把「如何找出所需的library」方法整理出3项的基本要点,依照这3种基本款来加入library将能解决几乎所有的librarydependency问题,这3种项基本要点为:
(1)先利用crosstoolchain的objdump观察「NEEDED」的项目,加入library。
(2)再检查这些library是否相依其它library。
(3)最后要检视应用程序是否使用到需要特定library的「service」。
要点1.跟2.对大家来说没有什么问题,要点3.在我们的training课程里,我们以建构thttpd(embeddedWebserver)的实际案例来做讲解。
关于建构thttpd的案例
thttpd使用到NSS(NameServiceSwitch),因此若没有将libnss_SERVICE.so加到rootfilesystem,thttpd在执行时可能会遇到一些奇怪的问题。
举个例子,当thttpd透过/etc/passwd去寻找(查询)UNIXuser时,会用到libnss_files.so(不读/etc/shadow),因此会看到以下的错误讯息:
unknownuser-root
出现这个错误的原因是thttpd读不到'root'使用者,要深入探讨这个问题的原理,必须从以下的程序代码片断开始探讨:
403/*Ifwe'rerootandwe'regoingtobecomeanotheruser,gettheuid/gid
404**now.
405*/
406if(getuid()==0)
407{
408pwd=getpwnam(user);
409if(pwd==(structpasswd*)0)
410{
411syslog(LOG_CRIT,"unknownuser-'%.80s'",user);
412(void)fprintf(stderr,"%s:
unknownuser-'%s'\n",argv0,user);
413exit
(1);
414}
415uid=pwd->pw_uid;
416gid=pwd->pw_gid;
417}
这段程序代码是thttpd2.25b的程序片断,位于thttpd.c的main()函数里。
关于libnss_SERVICE.so的议题,Jollen打算另外再做讨论,因为还会与libc有关系。
在这里我们由系统建构的角度来看这个问题。
因为我们已经习惯用objdump来观察程序的相依library,所以当objdump的画面跟我们预期的不同时,经常一时无法反应过来。
例如,以下的讯息是我们所「预期」的:
#/armtools/bin/arm-linux-objdump-xthttpd|more
...
DynamicSection:
NEEDEDlibcrypt.so.1
NEEDEDlibnss_files.so.2
NEEDEDlibc.so.6
...
但是实际的讯息却是像这样的:
#/armtools/bin/arm-linux-objdump-xthttpd|more
...
DynamicSection:
NEEDEDlibcrypt.so.1
NEEDEDlibc.so.6
...
我们可以用一知半解的思考逻辑来解决问题:
thttpd呼叫到getpwnam()函数,此函数由libnss_compat提供,因此解决方案是把libnss_files.so加到rootfilesystem里即可。
且慢!
前面才讲到libnss_compat,怎么后面是把libnss_files加到rootfilesystem?
是这样的,libnss_compat用来读/etc/shadow,但是现在我们只需要由/etc/passwd读Unixuser,所以使用libnss_files.so就行了。
执行thttpd的话,再加上指定username的参数来执行:
#thttpd-p80-d/var/www-uroot
libnss_SERVICE.so是包含在glibc里的链接库,因此可以直接由crosstoolchain里取得,不必再另行建置。
有关NSS(NameServiceSwitch)可参考以下网页:
http:
//www.gnu.org/software/libc/manual/html_node/Name-Service-Switch.html
http:
//mirrors.usc.edu/pub/gnu/Manuals/glibc-2.2.3/html_chapter/libc_28.html
此处我们以「service」的角度来探讨这个问题:
因为thttpd使用到NameServiceSwitch,所以需要加入libnss_SERVICE.so。
另外一种探讨的角度是:
由programming的角度来思考。
如果要读shadowpasswd的话,是使用libnss_compat.so。
Boa程序的移植
1、下载Boa源码
下载地址:
http:
//www.boa.org/
目前最新发行版本:
0.94.13 (几年没更新版本了)
下载boa-0.94.13.tar.gz,
注意:
若从boa上下载的是boa-0.94.13.tar.tar,解压方式一样
解压:
[root@Binnarysource]#tarxzfboa-0.94.13.tar.gz
2、生成Makefile文件
进入boa-0.94.13,直接运行src/configure文件
[root@Binnarysrc]#CC=/armtools/bin/arm-linux-gcc./configure
#3、修改Makefile文件(注意:
必须用cross-2.95.3,如使用3.4.1、4.1.1等等会出错)
#CC=/armtools/bin/arm-linux-gcc
#CPP=/armtools/bin/arm-linux-gcc-E
4、交叉编译
[root@Binnarysrc]#make
5、去除调试信息,减小体积。
(可选)
[root@Binnarysrc]#/armtools/bin/arm-linux-stripboa
6、将编译好的程序放入根文件系统的/bin目录下。
[root@Binnarysrc]#cpboa/fs/bin/
二、配置Boa
Boa需要在/etc目录下建立一个boa目录,里面放入Boa的主要配置文件boa.conf。
在Boa源码目录下已有一个示例boa.conf,可以在其基础上进行修改。
[root@Binnarysrc]#cd../..
[root@Binnarysource]#cd../fs/etc/
[root@Binnaryetc]#mkdirboa
[root@Binnaryetc]#chmod777boa/
[root@Binnaryetc]#cdboa
[root@Binnaryboa]#kwriteboa.conf
1、Group的修改
修改Groupnogroup
为Groupuser(开发板上有的组)
修改Usernobody
为Userboa(user组中的一个成员)
根据你的开发板的情况设定。
一定要存在的组和用户。
以下是我在开发板上的操作:
[root@localhosts~]#adduser-guserboa
Changingpasswordforboa
Enterthenewpassword(minimumof5,maximumof8characters)
Pleaseuseacombinationofupperandlowercaselettersandnumbers.
Enternewpassword:
Badpassword:
tooshort.
Warning:
weakpassword(continuing).
Re-enternewpassword:
passwd[820]:
passwordfor`boa'changedbyuser`root'
Passwordchanged.
[root@~]#
2、ScriptAlias的修改
修改ScriptAlias/cgi-bin/ /usr/lib/cgi-bin/
为ScriptAlias/cgi-bin/ /var/www/cgi-bin/
这是在设置CGI的目录,你也可以设置成别的目录。
比如用户文件夹下的某个目录。
3、ServerName的设置
修改#ServerNamewww.your.org.here
为ServerNamewww.your.org.here
注意:
该项默认为未打开,执行Boa会异常退出,提示“gethostbyname:
:
Nosuchfileordirectory”,所以必须打开。
其它默认设置即可。
你也可以设置为你自己想要的名字。
比如我设置为:
ServerNamebinnary2410
此外,还需要:
将mime.types文件复制/etc目录下,通常可以从linux主机的/etc目录下直接复制即可。
(以下配置和boa.conf的配置有关)
创建日志文件所在目录/var/log/boa
创建HTML文档的主目录/var/www
创建CGI脚本所在录/var/www/cgi-bin
[root@Binnarylog]#mkdir-m777boa
[root@Binnarylog]#cd..
[root@Binnaryvar]#mkdir-m777www
[root@Binnaryvar]#mkdir-m777www/cgi-bin
[root@Binnaryvar]#cd..
[root@Binnaryrootfs]#cp/etc/mime.typesetc/
三、运行Boa
开发板操作:
[root@~]#boa
如果发现boa没有运行,则可以在开发板的/var/log/boa/error_log文件中找原因。
比如端口已被其他程序占用:
[root@~]#cat/var/log/boa/error_log
[20/Feb/2008:
21:
21:
57+0000]boa.c:
194-unabletobind:
Addressalreadyinuse
或是用户设置错误等等,都可以查到。
四、功能测试
静态网页测试
将静态网页存入根文件系统的/var/www目录下(可以将主机/usr/share/doc/HTML/目录下的index.html、homepage.css和img、stylesheet-images目录复制到/var/www目录下)
在根文件系统的/var目录下
[root@Binnaryvar]#cp/usr/share/doc/HTML/index.htmlwww/
[root@Binnaryvar]#cp-r/usr/share/doc/HTML/imgwww/
[root@Binnaryvar]#cp/usr/share/doc/HTML/homepage.csswww/
[root@Binnaryvar]#cp-r/usr/share/doc/HTML/stylesheet-imageswww/
直接在浏览器中输入开发板的IP地址(比如我的是http:
//192.168.10.240),出现linux的欢迎网页。
静态HTML调试成功。
CGI功能测试
1、编写HelloworldCGI.c程序
[root@Binnarysource]$vihelloworldCGI.c
(主程序的程序开头一定要用Tab,而不是空格,不然编译可能不通过)
#include
#include
intmain(void)
{
printf("Content-type:
text/html\n\n");
printf("\n");
printf("
CGIOutput\n");
printf("
\n");
printf("
Hello,world.
\n");
printf("
\n");
printf("\n");
exit(0);
}
2.交叉编译生成CGI程序
[root@Binnarysource]$/armtools/bin/arm-linux-gcc-ohelloworldCGIhelloworldCGI.c
将helloworldCGI拷贝至根文件系统的/var/www/cgi-bin/下
[root@Binnarysource]$cphelloworldCGI../nfs/rootfs/var/www/cgi-bin/
3.测试
浏览器输入
http:
//192.168.10.240/cgi-bin/helloworldCGI
网页出现Hello,world.调试成功!