资源描述
课 设 报 告
课程名称 嵌入式系统课程设计
实验项目 web远程控制系统设计
指导教师 周金和 、 王勇
学 院 信息与通信工程
专 业 电子信息工程
班级/学号 电信1101/
学生姓名
实验日期
成 绩 ____________________
实验步骤
一、搭建及移植web服务器
搭建及移植boa服务器是本次课题的要点所在,为了能够顺利搭建服务器,前期做了大量工作对其进行学习以及研究,在基本掌握boa服务器的搭建和移植的具体操作方法还有该服务器的工作方式、流程之后,才着手进行搭建和移植,即便如此,在搭建和移植的过程中还是遇到了不少问题,下文也进行了分析和解决。
1.1 下载及配置BOA服务器
1.1.1 下载安装boa服务器
首先在http://www.boa.org/下载BOA服务器的源码:boa-0.94.13.tar.gz版本为0.94.13。
对其进行解压:
$ tar xzf boa-0.94.13.tar.gz
还要安装必要的工具bison,flex。否则会出现:
make: yacc:命令未找到
make: *** [y.tab.c] 错误 127。
$ sudo apt-get install bison flex
在输入上一条命令之前需要保证虚拟机联网,虚拟机联网方式如下
首先把主机联上网,虚拟机网络设置桥接改成nat
$ sudo vim /etc/network/interfaces
static改成dhcp ,在address,netmask, gateway加#注释
用:wq保存并退出
重启网路配置
$sudo /etc/init.d/networking restart
1.1.2 修改相关配置文件
修改src/compat.h文件:
打开compat.h找到这一条语句:
#define TIMEZONE_OFFSET(foo) foo##->tm_gmtoff
将其修改为:
#define TIMEZONE_OFFSET(foo) (foo)->tm_gmtoff
这是由于本机所使用的交叉编译版本对语句用法的不同。
修改 src/log.c文件。
打开log.c注释掉下列语句:
/*if (dup2(error_log, STDERR_FILENO) == -1) {
DIE("unable to dup2 the error log");
}*/
否则会出现错误:
log.c:73 unable to dup2 the error log:bad file descriptor。
修改src/boa.c文件。
打开src/boa.c注释掉下面两句话:
#if 0
if (passwdbuf == NULL) {
DIE(”getpwuid”);
}
if (initgroups(passwdbuf->pw_name, passwdbuf->pw_gid) == -1) {
DIE(”initgroups”);
}
#endif
否则会出现错误:boa.c:211 - getpwuid: No such file or directory。
#if 0
if (setuid(0) != -1) {
DIE(”icky Linux kernel bug!”);
}
#endif
否则会出现问题:boa.c:228 - icky Linux kernel bug!: No such file or directory。
1.1.3 生成boa可执行文件
进入相关目录生成makefile文件:
$ cd boa-0.94.13/src
$ ./configure
修改makefile文件。
$sudo vim Makefile
修改CC = gcc 为 CC = arm-linux-gnueabihf-gcc
修改CPP = gcc -E 为 CPP = arm-linux-gnueabihf-gcc -E
接下来进行编译。
$ make
然后为刚刚生成的二进制文件boa瘦身删除其调试信息。
$ arm-linux-gnueabihf-strip boa
1.1.4 修改配置
找到配置文件boa.conf并进行如下修改:
$ sudo gedit boa-conf
以下步骤需要在计算机上完成:
(1)对Group的修改
将Group nogroup(这是修改程序所属的组)。
修改为 Group 0
(2)对user的修改
将User nobody(这里是修改程序所属的用户)。
修改为 User 0
(3)对ScriptAlias的修改
将ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/(这里是配置服务器读取cgi程序的目录,需要在SD卡中同样的位置建立同样的目录)。
修改为 ScriptAlias /cgi-bin/ /www/cgi-bin/
(5)对DoucmentRoot的修改
将DoucmentRoot /var/www (这里是服务器初始网页放置的位置同样需要在SD卡同样的位置建立同样的文件夹并将名为index.html的网页放置在其中)。
修改为DoucmentRoot /www
(6)对ServerName的修改
将#ServerName www.your.org.here(取消掉注释否则提示没有服务器名)。
修改为 ServerName www.your.org.here
否则会出现错误“gethostbyname::No such file or directory”
(7)对AccessLog修改
将AccessLog /var/log/boa/access_log(在SD卡相应位置建立同名文件夹以存放日志文件,否则提示找不到文件夹)。
修改为#AccessLog /var/log/boa/access_log
否则会出现错误提示:“unable to dup2 the error log: Bad file descriptor”
修改完成后直接点击文件左上方的保存按钮进行保存。
在目标板上需要做的配置:
创建目录/etc/boa并且把boa 和 boa.conf拷贝到这个目录下:
$ mkdir /etc/boa
$ sudo cp boa.conf /media/rootfs/etc/boa
创建HTML文档的主目录/www:
$ mkdir /www
创建CGI脚本所在的目录 /www/cgi-bin:
$ mkdir /www/cgi-bin
1.2. 测试服务器动态网页功能
到此为止服务器已经搭建完成了,接下来就要测试服务器是否能够成功运行动态网页了,为了顺利完成测试,首先要做的是让目标板和主机能够通过交叉网线通信:
在虚拟机菜单栏中安照:虚拟机--设置--网络适配器--网络连接中选择桥街模式,这样就可以直接连接主机的物理网络。有时会出现无论怎样配置都无法联通的情况这时就需要使用虚拟机中的虚拟网络编辑器来重置网络配置。前面的设置完成后,先将windows下的ipv4设置为:IP地址:181.168.1.10,子网掩码:255.255.255.0,默认网关:181.168.1.1。然后设置Ubuntu下的ip地址:
sudo vi /etc/network/interfaces
将主机的ip地址设置为这一网段:address 181.168.1.11 netmask:255.255.255.0 gateway:181.168.1.1
重启主机的网络服务:
sudo /etc/init.d/networking restart
再去配置目标板,同样将其置于同一网段:
sudo gedit /etc/network/interfaces
将目标板的ip地址设置为同一网段:address 181.168.1.12 netmask:255.255.255.0 gateway:181.168.1.1
重启目标板的网络服务:
sudo /etc/init.d/networking restart
配置完后在目标板上输入ifconfig可以查看到如下内容
这时就可以测试主机与目标板之间的连通性了:
分别在主机和目标板上使用ping命令去测试相互之间的连通性:
图 1.1 测试连通性
出现上图所示信息就便表示着主机与目标板已经联通了,可以进行通信了。
接下来要做的就是编译一个cgi程序,因为只是测试用所以就用最简单的hello world来测试:
首先建立一个hello.c文件:
$sudo gedit hello.c
编写hello world代码:
#include<stdio.h>
int main(int argc, char** argv)
{
printf("Content-type:text/html\n\n");
printf("<html>\n");
printf("<head><title>cgiCHello.c</title></head>\n");
printf("<body>\n");
printf("<h1>Hello World! <font color=\"blue\">\"CGI C\"</font> </h1>\n");
printf("</body>\n");
printf("</html>\n");
return 0;
}
保存。然后再对其进行编译,使之成为一个cgi文件:
arm-linux-gnueabihf-gcc -o hello.cgi hello.c
在当前文件夹下便会生成hello.cgi,为这个文件添加权限,使其可执行:
chmod +X hello.cgi
将这个文件移动到SD卡中之前所指定的服务器中的文件夹:
sudo cp hello.cgi /media/rootfs/www/cgi-bin/
现在可以打开浏览器在地址栏中输入181.168.1.12/cgi-bin/hello.cgi出现下图所示页面说明cgi功能可以使用,可以进行下一步工作了:(首先应在目标板中启动Boa服务器,步骤如下:在目标板中找到文件boa的目录,用cd命令进入,输入$sudo ./boa ,然后用ps -ef查看进程中是否有boa。或者用ps -ef|grep boa直接查找进程Boa更加简便。接下来才能访问服务器。否则会出现连接不到服务器的错误)
图 boa的运行与进程查看
图 1.2 动态网页测试
二、实现嵌入式web远程控制功能
目前为止,服务器的搭建以及数据的传输等基本功能已经实现了,为了能够实现嵌入式web远程控制的功能,就需要让控制者进入到其主页来进行编辑提交,所以在这个页面中就要让控制者能够对目标板进行各种控制和修改,而html只是单方向的,不能进行信息的交互,这时候就需要cgi程序来完成交互的任务。
2.1 静态网页的配置
首先建立一个index.html文件:
sudo gedit index.html
编写index.html代码:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
<script type="text/javascript">
function MM_jumpMenu(targ,selObj,restore){ //v3.0
eval(targ+".location='"+selObj.options[selObj.selectedIndex].value+"'");
if (restore) selObj.selectedIndex=0;
}
</script>
</head>
<body>
<p> </p>
<p> </p>
<form id="form1" name="form1" method="get" action="/cgi-bin/reboot.cgi">
<input type="submit" value="重启">
</form>
<a href="http://181.168.1.10/cgi-bin/hello.cgi#tips" target="_blank">hello~</a><pre>
<form action="/cgi-bin/allroot.cgi" method="post">
<input type="text" name="var_ip">
<input type="submit" value="更换">
</form>
</p>
</html>
其实每个标记都是一一对应的。每个网页文件都是以<html>开始和以</html>结束。<title>与</title>之间的内容是网页的标题。会显示在浏览器的标题栏上。<body>与</body>之间放的是网页内容。
<p> </p> 语句能够实现空行功能,以便使网页整体结构不会过于紧凑,
<a href="http://181.168.1.10/cgi-bin/hello.cgi#tips" target="_blank">hello~</a><pre>
将index.html拷贝到目标板HTML文档的主目录/www里。
sudo cp index.html /media/rootfs/www
该语句表示了在网页中加入一个超链接,该链接指向http://181.168.1.12/cgi-bin/hello.cgi 显示为hello用于测试服务器的cgi功能。效果如图所示:
在虚拟机浏览器中输入181.168.1.12显示如下图所示
图 2.1 HTML超链接
点击hello~之后服务器跳转,页面显示的内容:
图 2.2 超链接hello.cgi
2.2 动态网页的配置
2.2.1 HTML表单
<form action="/cgi-bin/allroot.cgi" method="post"> /表单动作指向allroot.cgi 传送方式为post
<input type="text" name="var_ip"> /插入文本框,赋值名为var_ip
<input type="submit" > /插入提交按钮
</form> /表单结束
上面的语句表示了以post的方式将表单内容发送给allroot.cgi,同时定义了一个按键和一个输入文本框,按钮的属性为提交按钮,文本框内的值为var_ip的值。
2.2.2 cgi功能的实现
为了能够实现更改ip的的功能就需要写一个shell脚本调用interfaces并对其进行修改,然而修改这个文件需要root权限,可是单单给shell脚本加上权限并不能达到目的,这时就需要借用一个c程序来提升其权限.
首先建立一个allroot.c文件:
sudo gedit allroot.c
编写allroot.c代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
printf("Content-type: text/html\n\n"); //输出类型
uid_t uid ,euid;
uid = getuid() ;
euid = geteuid();
if(setreuid(euid, uid)) //交换这两个id
perror("setreuid");
system("sudo sh /www/cgi-bin/changeip.sh"); //调用程序,原来的指导书没有sudo sh,不能成功的调用changeip.sh,因此在前面加上相应调用的语句才执行成功
return 0;
}
保存。然后再对其进行编译,使之成为一个cgi文件:
arm-linux-gnueabihf-gcc -o allroot.cgi allroot.c
在当前文件夹下便会生成allroot.cgi,为这个文件添加权限,使其可执行:
chmod +X allroot.cgi
将这个文件移动到SD卡中之前所指定的服务器中的文件夹:
sudo cp allroot.cgi /media/rootfs/www/cgi-bin/
这个c程序所做的便是提升changip.sh脚本的权限。
当在网页中输入ip地址181.168.1.12后,进入changip.sh
将通过awk截取变量$f 以-为分隔符的第二个域($2)的值,并赋值给var_ip这个变量:
var_ip=`echo $QUERY_STRING | awk -F '&' '{print $1}' | awk -F '=' '{print $2}'`
将得到的var_ip这个值写入interfaces:
eth0_cfg="/etc/network/interfaces"
sed -i '/^address/d' $eth0_cfg
echo "address $var_ip" >> $eth0_cfg
这样就完成了ip的更改。
changeip.sh:
#!/bin/bash
#if the program what called this cgi isn't sysconf.php, this script will refuse to run!!!!
#如果不是通过sysconf.php调用这个脚本,则拒绝执行,以保证安全性,避免直接通过http加参数的get
#方式直接运行
#if [ -z `echo $HTTP_REFERER | sed -n '/sysconf.php/p'` ] ; then
# exit
#fi
if [ $REQUEST_METHOD = "POST" ]; then
QUERY_STRING=`cat /dev/stdin`
fi
echo "Content-type:text/html"
echo ""
eth0_cfg="/etc/network/interfaces"
var_ip=`echo $QUERY_STRING | awk -F '&' '{print $1}' | awk -F '=' '{print $2}'`
var_mask=`echo $QUERY_STRING | awk -F '&' '{print $2}' | awk -F '=' '{print $2}'`
var_gateway=`echo $QUERY_STRING | awk -F '&' '{print $3}' | awk -F '=' '{print $2}'`
sed -i '/^netmask/d' $eth0_cfg
sed -i '/^address/d' $eth0_cfg
sed -i '/^gateway/d' $eth0_cfg
echo "address $var_ip" >> $eth0_cfg
echo "netmask $var_mask" >> $eth0_cfg
echo "gateway $var_gateway" >> $eth0_cfg
#ifconfig eth0 $var_ip netmask $var_mask
#route add default gw $var_gateway
为了能够使开发板重启同样需要一个提升权限的reboot.c程序,考虑到cgi的原理是需要将主机提交的数据提供给相应程序来执行,所以这样编写C语言.
首先建立一个reboot.c文件:
sudo gedit reboot.c
编写reboot.c代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc,char **argv,void)
{
printf("Content-type: text/html\n\n");
int a;
if (a=1)
{printf("The system is goging to reboot .......\n\n");
system("sudo reboot"); //原来的代码中没有sudo,因此在点击重启之后屏幕印出The system is goging to reboot ......但是没有真正的重启系统,是因为重启系统需要有root的权限,因此加入sudo 之后便可以正常的实现功能
}
else
return(0);//原来的代码没有加;在编译的时候会报错,因此把分号加上了
}
保存。然后再对其进行编译,使之成为一个cgi文件:
arm-linux-gnueabihf-gcc -o reboot.cgi reboot.c
在当前文件夹下便会生成reboot.cgi,为这个文件添加权限,使其可执行:
chmod +X reboot.cgi
将这个文件移动到SD卡中之前所指定的服务器中的文件夹:
sudo cp reboot.cgi /media/rootfs/www/cgi-bin/
三、 测试与调试
3. 1 测试远程控制功能
3.1.1 配置ip地址功能
首先将主机与开发板用网线串口线连好,打开SecureCRT连接进入开发板,如果是上电之前就连接好电脑的话,还可以看到一些启动信息。
在开发板上启动boa服务器,之所以使用root权限进入是因为,如果用普通用户权限进入的话,会有端口被占用的提示,然而如果使用8080端口的话,对于本设计后面的进行会带来很多不必要的麻烦。
启动boa服务器后,会显示启动信息,服务器版本,服务器创建时间以及服务器所占用的端口号,占用的端口号为80。
在主机上打开浏览器,地址栏内输入开发板服务器的ip(181.168.1.12)这样就进入了服务器的主页,主页的内容很直接,两个按钮,一个超链接,一个文本框:
boa服务器主页
3.1.2 重启功能
在开发板上测试重启功能的具体过程如下:
打开服务器初始的页面找到并点击重启按钮,重启这个功能看起来比改变ip要容易的多,但是如果使用c语言来编写cgi程序的时候往往会因为权限的问题带来很多的麻烦。因此要注意加sudo给到系统root权限。
重启按钮
浏览器中的显示,目标板自动重启
图 服务器重启
3.1.3 更改ip功能
为了确定ip是否更改首先查看开发板当前ip地址,输入ifconfig命令后可以看到当前的连接,硬件地址,ipv4和ipv6地址,广播地址,以及子网掩码,其中ip地址是181.168.1.12,由于开发板只有一个以太网卡,所以就没有选择以太网卡的问题了,eth0便是当前唯一的以太网卡。
由于开始设计的思路是这样,输入一个ip地址点击后替换当前开发板的ip地址,所以只有一个文本框,在网页中输入想要修改的ip(比如181.168.1.20):
图 输入ip地址
输入完成后点击更换按钮,浏览器页面跳转。
图 服务器提示成功
这时开发板的IP地址就应该改变了。由于目标板IP发生变化因此在输入$sudo /etc/init.d/networking restart重启网络配置之后通过ifconfig命令查看目标板ip配置发现ip地址被清空。因此程序出现错误。
对错误的猜测:
最终觉得没有实现的原因在changeip.sh中。
因为之前的不能成功调用changeip.sh等错误都经过了改动从而成功实现,然而输入的要改的IP地址不但没有成功改掉反而IP配置全被清空。因此判断是changeip.sh中提取输入数据的语句或赋值语句出现错误。
然而由于学习的东西有限,目前还没有透彻研究出shell脚本的语句内容,因此还没有解决掉这个问题。因此没能实现改变IP的功能。我们组成员都在努力学习shell脚本中,希望能通过修改来成功实现IP改变的功能。
实验心得
通过本次嵌入式系统课程设计温习了前面实验中用到的系统的烧写等步骤。在对Linux系统了解的基础上进行了进一步深入的了解。并且在做实验的过程中对实验指导书进行了进一步的完善,希望可以通过这个过程使自己记忆更加深刻。(加黑字体均为根据个人理解对课设进行的修改。)
在实验过程中遇到了一系列的问题,从一开始的虚拟机的联网问题。再到编译的时候由于编不同导致的一些无法运行的错误。在下来就遇到了重启目标板系统时只能在浏览器上显示系统正在重启却不能真正的重启系统,通过加入sudo 给到root权限从而实现了应有的功能。在一次次的困难中通过自己的查看与老师的帮助都得到了解决,给自己的学习带来了乐趣,更加巩固了所学到的知识。
实验中还通过帮助它组同学了解到了许多不是我们本组所用到的东西,收货了很多。
THANKS !!!
致力为企业和个人提供合同协议,策划案计划书,学习课件等等
打造全网一站式需求
欢迎您的下载,资料仅供参考
展开阅读全文