uclinux和arm s3c4510b
正在移植boa-0.94.13到uclinux上,几点笔记,大家分享。
编译一个linux下的c系统,包含词法和语法分析模块,Linux上用bison和flex。 yacc是一个文法分析器的生成器,bison即是yacc的GNU版本.Lex和YACC是用于构造词法分析机和语法解释器的工具,利用Lex和YACC你可以轻松的构造一个语法解释器。
1. 解压boa-0.94.13.tar.gz,进入boa-0.94.13/src目录 2. ./configure,回车,生成Makefile 一开始make 错误1: debian:/home/a/boa-0.94.13/src# make yacc -d boa_grammar.y make: yacc: Command not found make: *** [y.tab.c] Error 127 解决方法: debian:/home/a/boa-0.94.13/src# apt-get install bison
错误2: debian:/home/a/boa-0.94.13/src# make lex boa_lexer.l make: lex: Command not found make: *** [lex.yy.c] Error 127
解决方法: debian:/home/a/boa-0.94.13/src# apt-get install flex 错误3: debian:/home/a/sss/boa-0.94.13/src# make gcc -g -O2 -pipe -Wall -I. -c -o util.o util.c util.c:100:1: error: pasting "t" and "->" does not give a valid preprocessing token make: *** [util.o] Error 1 解决方法: 修改 src/compat.h 找到 #define TIMEZONE_OFFSET(foo) foo##->tm_gmtoff 修改成 #define TIMEZONE_OFFSET(foo) (foo)->tm_gmtoff
然后 debian:/home/a/sss/boa-0.94.13/src# make clean debian:/home/a/sss/boa-0.94.13/src# make
不过还有一个警告:
request.c: In funtion 'get_request':
request.c:84:warning: pointer targets in passing argument 3 of 'accept' differ in signedness
看着不爽,没关系
到request.c中的84行看看。
int accept(int socket, struct sockaddr *address, size_t *address_len) 原型。这里的参数类型不对。把int改为size_t 就可以了。
这里我说的不对,这个警告要看自己的内核是那个版本了,
原型int accept(int socket, struct sockaddr *address, socklen_t *address_len)
这是因为POSIX开始的时候用的是size_t,但后来有换成了socklen_t, 也就是int型,
debian:/home/a/sss/boa-0.94.13/src# make 基本就没有问题了。
不过在运行boa的时候,能运行,ps没有这个进程
解决:
注销掉
if (setuid(0) != -1) {
DIE(”icky Linux kernel bug!”);
}
就可了,重新编译。这样生成的boa在pc机上测试没有问题
----------------------------------------------------------------------
这是网友在论坛上分享的,我刚开始测试还没有遇到过.... 希望对大家有用
(2)修改 src/log.c
注释掉
if (dup2(error_log, STDERR_FILENO) == -1) {
DIE("unable to dup2 the error log");
}
为:
/*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
(3)修改src/boa.c
注释掉下面两句话:
if (passwdbuf == NULL) {
DIE(”getpwuid”);
}
if (initgroups(passwdbuf->pw_name, passwdbuf->pw_gid) == -1) {
DIE(”initgroups”);
}
为
#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
-----------------------------------------------------------------------------
交叉编译器,uclinux需要使用arm-elf-gcc编译工具,(内核2.4)
二、用arm-elf-gcc交叉编译了
1. vim Makefile,修改编译器,如下: 当然需要确认已经安装了arm-elf工具(sh arm-elf-tools-20030314.sh) CC = arm-elf-gcc -elf2flt CPP =arm-elf-gcc -E 保存退出 2. make 出现如下错误 util.c: In function `get_commonlog_time': util.c:100: structure has no member named `tm_gmtoff' 首先会想到的是查看util.c:100附近的代码, if (use_localtime) { t = localtime(¤t_time); time_offset = TIMEZONE_OFFSET(t);/* util.c:100 */ } else { t = gmtime(¤t_time); time_offset = 0; } 并看不出有什么问题。 使用Source Insight工具查找TIMEZONE_OFFSET,找到compat.h #ifdef HAVE_TM_GMTOFF #define TIMEZONE_OFFSET(foo) foo##->tm_gmtoff /* 尝试将##去掉 */ #else #define TIMEZONE_OFFSET(foo) timezone #endif
还是这个地方,依照去掉## 3. 保存退出,make 错误和上面一样 4. 尝试别的办法,将util.c:100处的代码屏蔽,保存退出 make 编译成功 但是这样很可能照成boa使用过程中的错误
(这里我只是猜测,但是编译都没有使用tm_gmtoff,错误很可能发生) 5. 最终解决办法 可以思考一下,当使用arm-linux-gcc编译boa时,基本都能正常编译成功, 而使用arm-elf-gcc编译boa则会出现错误,那最可能有问题的地方,必然是 交叉编译工具的问题,本人使用的是arm-elf-tools-20030314.sh 找到arm-elf安装目录: /usr/local/arm-elf/ 利用source Insight工具可以搜索“tm_gmtoff”,找到/usr/local/arm-elf/include/time.h vim time.h 将time.h:130的条件编译代码修改为“#if 1” 保存退出。 进入boa-0.94.13/src目录,建议make clean一下 make 编译成功(掌声)
(注:这只是编译成功了。没有测试)
三、移植到uclinux中,替换的原来的boa文件夹,最主要的就是修改makefile文件,boa主目录里放一个Makefile, src里面那个Makefile.in 不要动,src里面那个Makefile删掉,自己写个Makefile放里面,下面是我的Makefile(千万不要再用configure生产Makefile文件了,这样通不过uclinux的编译)
---------------------------------------------------
Makefile(boa主目录里的)
.EXPORT_ALL_VARIABLES:
DIRS = src
all romfs: for i in $(DIRS) ; do make -C $$i $@ || exit $?; done
clean: for i in $(DIRS) ; do make -C $$i clean ; done
-----------------------------------------------------
Makefile(src里的)
EXEC = boa OBJS = alias.o boa.o buffer.o cgi.o cgi_header.o config.o escape.o get.o \ hash.o ip.o log.o mmap_cache.o pipe.o queue.o read.o request.o \ response.o select.o signals.o timestamp.o util.o sublog.o y.tab.o\ lex.yy.o
FLTFLAGS += -s 8192
EXTRALIBS = $(LIBCRYPT)
ifdef CONFIG_USER_BOA_WITH_SSL CFLAGS += $(INCSSL) -DSERVER_SSL=1 EXTRALIBS += $(LIBSSL) $(LIBCRYPTO) endif
ifdef CONFIG_USER_TINYLOGIN_SHADOWPASSWDS CFLAGS += -DSHADOW_AUTH endif
ifdef CONFIG_USER_OLD_PASSWORDS CFLAGS += -DOLD_CONFIG_PASSWORDS endif
all: $(EXEC)
$(EXEC): $(OBJS) $(CC) $(LDFLAGS) -o $@ $(OBJS) $(EXTRALIBS) $(LDLIBS) -lcrypt_old
romfs: $(ROMFSINST) /bin/$(EXEC)
clean: -rm -f $(EXEC) *.gdb *.elf *.o
----------------------------------------------------------
完毕之后,编译,就会出现没有移植时的那个错误,
出现如下错误 util.c: In function `get_commonlog_time': util.c:100: structure has no member named `tm_gmtoff' 该改的都改了,这个问题真难了我了,
1、再次尝试,将util.c:100处的代码屏蔽,保存退出 make user_only 编译通过(掌声)(这样可能会出项想不到问题)
为了彻底解决这个问题,不让有什么后遗症,我把源码看了一遍,发现util.c: 100
if (use_localtime) { t = localtime(¤t_time); time_offset = TIMEZONE_OFFSET(t); } else { t = gmtime(¤t_time); time_offset = 0; }
这个变量use_localtime没什么用处,就这一个地方使用,boa.conf里这么介绍
#是否使用本地时间。如果没有注释掉,则使用本地时间。注释掉则使用UTC 时间 #UseLocaltime
一般是把它注掉的,所以, time_offset = TIMEZONE_OFFSET(t);我就直接注掉了,理论上是没有问题。
2、编译是通过了,可是问题又来了,编译好的uimage.rom 烧到板子上,发现boa死了,没有运行起来,看了下启动信息,启动了了呀,怎么就死了呢?
在板子上手动启动boa
# boa &
出现错误
Fork:pars.........(不好意思,这里的错误没有记住)
(我把fork改成vfork了啊,怎么还会出这样的错误),找半天,终于找到出错的地方boa.c: 138,
/* background ourself */ if (do_fork) { switch(fork()) { case -1: /* error */ perror("fork"); //就只这里了 exit(1); break; case 0: /* child, success */ break; default: /* parent, success */ exit(0); break; } }
我发现这个段落无非是background ourself ,我的启动脚本里做了这样工作,我直接不要了,注掉。
编译以后,再烧到板子上,测试,正常(掌声)。(不正常的还没测出来,哈哈)
共同学习
|