bluecolour
personality test update
bluecolour 发表于 2008-11-05 15:04:52
嵌入式Linux操作系统CGI程序设计技术
bluecolour 发表于 2008-07-15 09:47:14
嵌入式Linux操作系统CGI程序设计技术
随着互联网应用的普及,越来越多的信息化产品需要接入互联网通过Web页面进行远程访问。嵌入式Web系统提供了一种经济、实用的互联网嵌入式接入方案。这里结合一种嵌入式Web Server BOA来介绍嵌入式Linux系统下的CGI程序设计技术。
2 Web Server BOA的实现与配置
2.1 uClinux下,主要有三个Web Server:HTTPD、THTTPD和BOA。
HTTPD是最简单的一个Web Server,它的功能最弱,不支持认证,不支持CGI。THTTPD和BOA都支持认证、CGI等,功能都比较全。BOA是一个单任务的小型HTTP服务器,源代码开放、性能优秀,特别适合应用在嵌入式系统中。目前的uClinux的代码中已经包含BOA的源代码。在uClinux下实现BOA,只需要对BOA做一些配置和修改。以下是配置的过程。
(1)编译BOA到内核
首先,需要把BOA编译到内核,即执行make menuconfig,在应用程序选单中network application项下面选择boa。该操作需要重新编译内核。
(2)编制配置文件boa.conf
在Linux操作系统下,应用程序的配置都是以配置文件的形式提供的,一般都是放在目标板/etc/目录下或者/etc/config目录下。但boa的配置文件boa.cont一般都旋转在目标板/home/httpd/目录下。
例如,一个典型的boa.conf文件格式如下:
ServerName Samsung-ARM
DocumentRoot/home/httpd
ScriptAlias/cgi-bin/home/httpd/cgi-bin/
ScriptAlias/index.html/home/httpd/index.html
它指定了HTML页面必须放到/home/httpd目录下,cgi外部扩展程序必须放到/home/httpd/cgi-bin目录下。
(3)编译烧写内核
重新编译内核后,通过烧写工具烧写内核,就可以在PC上通过IE浏览器访问开发板上的Web Server。例如,输入开发板的IP地址http://192.168.0.101,即可访问到自己做的网页index.html了。并且,通过编写 CGI外部扩展程序,可以实现动态Web技术,下面将详细介绍。
2.2 具有MMU平台的Linux下B0A的实现与配置
对于有MMU(内存管理单元)的平台,如armlinux和ppclinux,可以到网上下载一个主流版本的boa发行包。因为是运行在目标系统,所以要用交叉编译工具编译,即需要修改boa/src/Makefile里面的编译器。例如:
CC=/LinuxPPC/CDK/bin/powerpc-linux-gcc
CPP=/LinuxPPC/CDK/bin/powerpc-linux-g++
然后直接在boa/src目录下执行make,即可生成BOA可执行文件;将其编译入内核,并烧写到存储设备,就可以实现访问BOA服务器。
3 CGI程序设计技术
CGI(Common Gateway Interface)是外部应用扩展应用程序与WWW服务器交互的一个标准接口。按照CGI标准编写的外部扩展应用程序可以处理客户端浏览器输入的数据,从而完成客户端与服务器的交互操作。而CGI规范就定义了Web服务器如何向扩展应用程序发送消息,在收到扩展应用程序的信息后又如何进行处理等内容。通过CGI可以提供许多静态的HTML网页无法实现的功能,比如搜索引擎、基于Web的数据库访问等等。
3.1 工作原理
(1)WWW和CGI的工作原HTTP协议是WWW的基础,它基于客户/服务器模型,一个服务器可以为分布在网络中处的客户提供服务;它是建立在TCP/IP协议之上的“无连接”协议,每次连接只处理一个请求。在服务器上,运行产着一个守护进程对端口进行监听,等待来自客户的请求。当一个请求到来时,将创建一个子进程为用户的连接服务。根据请求的不同,服务器返回HTML文件或者通过 CGI调用外部应用程序,返回处理结果。服务器通过CGI与外部程序和脚本之间进行交互,根据客户端在进行请求时所采取的方法,服务器会收集客户所提供的信息,并将该部分信息发送给指定的CGI扩展程序。CGI扩展程序进行信息处理并将结果返回服务器,然后服务器对信息进行分析,并将结果发送回客户端。
外部CGI程序与WWW服务器进行通信、传递有关参数和处理结果是通过环境变量、命令行参数和标准输入来进行的。服务器提供了客户端(浏览器)与CGI扩展程序之间的信息交换的通道。CGI的标准输入是服务器的标准输出,而CGI的标准输出是服务器的标准输入。客户的请求通过服务器的标准输出传送给CGI的标准输入,CGI对信息进行处理后,将结果发送到它的标准输入,然后由服务器将处理结果发送给客户端。
(2)URL编码
客户端浏览器向服务器发送数据采用编码的形式进行。该编码就是CRL编码。编码的主要工作是表单域的名字和值的转义,具体的做法为:每一对域和值里的空格都会被替换为一个加号(+)字符,不是字母或数字的字符将被替换为它们的十六进制数字形式,格式为%HH。HH是该字符的ASCII十六进制值。
标签将被替换为“%0D%0A”。
信息是按它们在表单里出现的顺序排列的。数据域的名字和数据域的值通过等号(=)字符连在一起。各对名/值再通过“&”字符连接在一起。经过这些编码处理之后,表单信号就整个成为一个连续的字符流,里面包含着将被送往服务器的全部信息。
因为表单输入信息都是经过编码后传递给脚本程序的,所以CGI扩展程序在使用这些参数之前必须对它们进行解码。
3.2 CGI外部扩展程序编制
服务器程序可以通过三种途径接收信息:环境变量、命令行和标准输入。具体使用哪一种方法要由
标签的METHOD属性来决定。
在“METHOD=GET”时,向CGI程序传递表单编码信息的正常做法是通过命令来进行的。大多数表单编码信息都是通过 QUERY_STRING的环境变量来传递的。如果“METHOD=POST”,表单信息将通过标准输入来读取。还有一种不使用表单就可以向CGI传送信息的方法,那就是把信息直接追回在URL地址后面,信息和URL之间用问号(?)来分隔。
下面结合Web远程监控ARM芯片的GPIO(通用输入/输出)的应用实例详细介绍。
(1)GET方法
GET方法是对数据的一个请求,被用于获得静态文档。当使用GET方法时,CGI程序将会从环境变量QUERY_STRING获取数据。为了处理客户端的请求,CGI必须对QUERY_STRING中的字符串进行分析。当需要从服务器获取数据并且不改变服务器上的数据时,应该选用GET方法;但是如果请求中包含的字符串超过了一定长度,一般是1024字节,那么就只能选用POST方法。 GET方法通过附加在URL后面的参数发送请求信息。这些参数将被放在环境变量QUERY_STRING中传给CGI程序。GET方法的表单格式和CGI 解码程序可以参考POST方法的实现。
(2)POST方法
当浏览器将数据从一个填写的表单传给服务器时一般采用POST方法,而且在发送的数据超过1024字节时也必须采用POST方法。当使用 POST方法时,Web服务器向CGI程序的标准输入STDIN传送数据。发送的数据长度存在环境变量CONTENT_LENGTH中,并且,POST方法的数据格式为:
variable1=value1&variable2=value2&etc
CGI程序必须检查REQUEST_METHOD环境变量以确定是否采用了POST方法,并决定是否要读取STDIN。POST方法在HTML文档中定义的表单如下:
<FORM METHOD=POST ACTION="/cgi-bin/cgi_gpio.cgi">
<INPUT TYPE="RADIO"NAME=rb VALUE="0">Operate P0<BR>
<INPUT TYPE="RADIO"NAME=rb VALUE="1">Operate P1<BR>
<INPUT TYPE="RADIO"NAME=rb VALUE="2">Operate P2<BR>
<INPUT NAME="ok"TYPE=submit VALUE="OK">
<INPUT>NAME="cancel"TYPE=reset VALUE="RESET">
</FORM>
它调用的服务器脚本程序是/cgi/bin/cgi_gpio.cgi。CGI扩展程序中FORM表单的解码可参考如下程序:
/*function getPOSTvars*/
char **getPOSTvars()
{
int i;
int content_length;
char **postvars;
char *postinput;
char **pairlist;
int paircount=0;
chr *nvpair;
char *eqpos;
postinput=getenv("CONTENT_LENGTH");//获取传送给程序数据的字节数
if(!postinput)
exit();
if (!content_length=atoi(postinput))) //获取信息长度
exit(1);
if (!(postinput=(char*)malloc(content_length+1)))
exit(1);
if (!fread(postinput,content_length,1,stadin))
exit(1);
postinput[content_length]='0';
for(i=0;postinput[i];i++)
if(postinput[i]=='+')
postinput[i]=''; //对加易进行处理
pairlist=(char **)malloc(256*sizeof(char **));
paircount=0;
nvpair=strtok(postinput,"&");//从出现“&”字符的位置把信息分段,然后对结果依次处理
while (nvpair)
{
pairlist[paircount++]=strdup(nvpair);
if (!(paircount%256))
pairlist=(char**)realloc(pairlist,(paircount+256)*sizeof(char**));
nvpair=strtok(NULL,"&");
}
pairlist[paircount]=0;
postvars=(char**)malloc((paircount*2+1)*sizeof(char **));
for(i=0;i<paircount;i++)
{
if (eqpos=strchr(pairlist[i],'='))
{
*eqpos='0';
unescape_url(postvars[i*2+1]=strdup(eqpos+1));//调用unescape_url函数继续解码
}
else
{
unescape_url(postvars[i*2+1])=strdup(""));
}
postvars[paircount*2]=0;
for(i=0;pairlist[i];i++)
free(pairlist[i]);
free(pairlist);
free(postinput);
return postvars;
}
}
其中,unescape_url函数再调用x2c函数,把(不是字节或数字的)特殊字符从其%HH表示方式解码为文本字符。
/*unescape_url function*/
static void unescape_url(char *url)
{
int x,y;
for(x=0,y=0;url[y];++x,++y)
{
if((url[x]=url[y])=='%')
{
url[x]=x2c(&url[y+1]);
y+=2;
}
}
url[x]='0';
}
(3)直接URL加参数传递方法
这是一种不使用表单就可以向CGI传送信息的方法。它把信息直接追加在URL地址后面,信息和URL之间用号号(?)来分隔。例如,对于一个cgi_gpio.cgi的脚本,可以从如下的链接启动:
<A HREF=/cgi-gpio.cgi!?flag=0 Operate P0</A>
<A HREF>/*cgi-bin/cgi_gpio.cgi?flag=1 Operate P1</A>
<A HREF=/cgi-bin_gpio.cgi?flag=2 Operate P2</A>
.
.
.
CGI扩展程序中可使用如下代码接收信息:char *get_input;//用于接收环境变量:
.
.
.
get_input=getenv(“QUERY_STRING”);
if(get_input)
{
get_input=strdup(get_input);
printf("QUERY_STRING if %s",get_input);
}
/*判断flag=x信息*/
if (!strcmp(get_input,"flag=0")
...//Operate p0
else if(!strcmp(get_input,"flag=1")
...//Operate P1
else
...//Operate P2
对于上述三种方法,可以 根据不同的应用场合和应用要求进行选取。
结语
嵌入式Web Server系统方案可以广泛应用在许多领域,如自动化设备的远程监控、嵌入式GSM短消息 平台以及远程家庭医疗等。并且,随着互联网应用领域的不断深入,嵌入式Internet技术将得到更为广泛的应用和发展。
文章来源: www.gd-emb.org 文章作者: 郑伟 徐荣华 王钦若 发布时间: 2006-09-26
剖析Linux系统启动过程
bluecolour 发表于 2008-05-26 15:02:33
内容提要
本文以RedHat9.0和i386平台为例,剖析了从用户打开电源直到屏幕出现命令行提示符的整个Linux启动过程。并且介绍了启动中涉及到的各种文件。
阅读Linux源代码,无疑是深入学习Linux的最好方法。在本文对Linux启动过程的介绍中,我们也尝试从源代码的视角来更深入的剖析Linux的启动过程,所以其中也简单涉及到部分相关的Linux源代码,Linux启动这部分的源码主要使用的是C语言,也涉及到了少量的汇编。而启动过程中也执行了大量的shell(主要是bash shell)所写脚本。为了方便读者阅读,笔者将整个Linux启动过程分成以下几个部分逐一介绍,大家可以参考下图:
当用户打开PC的电源,BIOS开机自检,按BIOS中设置的启动设备(通常是硬盘)启动,接着启动设备上安装的引导程序lilo或grub开始引导 Linux,Linux首先进行内核的引导,接下来执行init程序,init程序调用了rc.sysinit和rc等程序,rc.sysinit和rc 当完成系统初始化和运行服务的任务后,返回init;init启动了mingetty后,打开了终端供用户登录系统,用户登录成功后进入了Shell,这样就完成了从开机到登录的整个启动过程。
下面就将逐一介绍其中几个关键的部分:
第一部分:内核的引导(核内引导)
Red Hat9.0可以使用lilo或grub等引导程序开始引导Linux系统,当引导程序成功完成引导任务后,Linux从它们手中接管了CPU的控制权,然后CPU就开始执行Linux的核心映象代码,开始了Linux启动过程。这里使用了几个汇编程序来引导Linux,这一步泛及到Linux源代码树中的“arch/i386/boot”下的这几个文件:bootsect.S、setup.S、video.S等。
其中bootsect.S是生成引导扇区的汇编源码,它完成加载动作后直接跳转到setup.S的程序入口。setup.S的主要功能就是将系统参数(包括内存、磁盘等,由BIOS返回)拷贝到特别内存中,以便以后这些参数被保护模式下的代码来读取。此外,setup.S还将video.S中的代码包含进来,检测和设置显示器和显示模式。最后, setup.S将系统转换到保护模式,并跳转到 0x100000。
那么0x100000这个内存地址中存放的是什么代码?而这些代码又是从何而来的呢?
0x100000这个内存地址存放的是解压后的内核,因为Red Hat提供的内核包含了众多驱动和功能而显得比较大,所以在内核编译中使用了“makebzImage”方式,从而生成压缩过的内核,在RedHat中内核常常被命名为vmlinuz,在Linux的最初引导过程中,是通过"arch/i386/boot/compressed/"中的head.S利用 misc.c中定义的decompress_kernel()函数,将内核vmlinuz解压到0x100000的。
当CPU跳到0x100000时,将执行"arch/i386/kernel/head.S"中的startup_32,它也是vmlinux的入口,然后就跳转到start_kernel()中去了。start_kernel()是"init/main.c"中的定义的函数,start_kernel ()中调用了一系列初始化函数,以完成kernel本身的设置。start_kernel()函数中,做了大量的工作来建立基本的Linux核心环境。如果顺利执行完start_kernel(),则基本的Linux核心环境已经建立起来了。
在start_kernel()的最后,通过调用init()函数,系统创建第一个核心线程,启动了init过程。而核心线程init()主要是来进行一些外设初始化的工作的,包括调用do_basic_setup()完成外设及其驱动程序的加载和初始化。并完成文件系统初始化和root文件系统的安装。
当 do_basic_setup()函数返回init(),init()又打开了/dev/console设备,重定向三个标准的输入输出文件stdin、 stdout和stderr到控制台,最后,搜索文件系统中的init程序(或者由init=命令行参数指定的程序),并使用 execve()系统调用加载执行init程序。到此init()函数结束,内核的引导部分也到此结束了,
第二部分:运行init
init的进程号是1,从这一点就能看出,init进程是系统所有进程的起点,Linux在完成核内引导以后,就开始运行init程序,。init程序需要读取配置文件/etc/inittab。inittab是一个不可执行的文本文件,它有若干行指令所组成。在Redhat系统中,inittab的内容如下所示(以“###"开始的中注释为笔者增加的):
#
# inittab This file describes how the INIT process should set up
# the system in a certain run-level.
#
# Author: Miquel van Smoorenburg, 〈miquels@drinkel.nl.mugnet.org〉
# Modified for RHS Linux by Marc Ewing and Donnie Barnes
#
# Default runlevel. The runlevels used by RHS are:
# 0 - halt (Do NOT set initdefault to this)
# 1 - Single user mode
# 2 - Multiuser, without NFS (The same as 3, if you do not havenetworking)
# 3 - Full multiuser mode
# 4 - unused
# 5 - X11
# 6 - reboot (Do NOT set initdefault to this)
#
###表示当前缺省运行级别为5(initdefault);
id:5:initdefault:
###启动时自动执行/etc/rc.d/rc.sysinit脚本(sysinit)
# System initialization.
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
###当运行级别为5时,以5为参数运行/etc/rc.d/rc脚本,init将等待其返回(wait)
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6
###在启动过程中允许按CTRL-ALT-DELETE重启系统
# Trap CTRL-ALT-DELETE
ca::ctrlaltdel:/sbin/shutdown -t3 -r now
# When our UPS tells us power has failed, assume we have a few minutes
# of power left. Schedule a shutdown for 2 minutes from now.
# This does, of course, assume you have powerd installed and your
# UPS connected and working correctly.
pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down"
# If power was restored before the shutdown kicked in, cancel it.
pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"
###在2、3、4、5级别上以ttyX为参数执行/sbin/mingetty程序,打开ttyX终端用于用户登录,
###如果进程退出则再次运行mingetty程序(respawn)
# Run gettys in standard runlevels
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6
###在5级别上运行xdm程序,提供xdm图形方式登录界面,并在退出时重新执行(respawn)
# Run xdm in runlevel 5
x:5:respawn:/etc/X11/prefdm -nodaemon
以上面的inittab文件为例,来说明一下inittab的格式。其中以#开始的行是注释行,除了注释行之外,每一行都有以下格式:
id:runlevel:action:process
对上面各项的详细解释如下:
1. id
id是指入口标识符,它是一个字符串,对于getty或mingetty等其他login程序项,要求id与tty的编号相同,否则getty程序将不能正常工作。
2. runlevel
runlevel是init所处于的运行级别的标识,一般使用0-6以及S或s。0、1、6运行级别被系统保留:其中0作为shutdown动作,1作为重启至单用户模式,6为重启;S和s意义相同,表示单用户模式,且无需inittab文件,因此也不在inittab中出现,实际上,进入单用户模式时,init直接在控制台(/dev/console)上运行/sbin/sulogin。在一般的系统实现中,都使用了2、3、4、5几个级别,在 Redhat系统中,2表示无NFS支持的多用户模式,3表示完全多用户模式(也是最常用的级别),4保留给用户自定义,5表示XDM图形登录方式。7- 9级别也是可以使用的,传统的Unix系统没有定义这几个级别。runlevel可以是并列的多个值,以匹配多个运行级别,对大多数action来说,仅当runlevel与当前运行级别匹配成功才会执行。
3. action
action是描述其后的process的运行方式的。action可取的值包括:initdefault、sysinit、boot、bootwait等:
initdefault是一个特殊的action值,用于标识缺省的启动级别;当init由核心激活以后,它将读取inittab中的 initdefault项,取得其中的runlevel,并作为当前的运行级别。如果没有inittab文件,或者其中没有initdefault项, init将在控制台上请求输入runlevel。
sysinit、boot、bootwait等action将在系统启动时无条件运行,而忽略其中的runlevel。
其余的action(不含initdefault)都与某个runlevel相关。各个action的定义在inittab的man手册中有详细的描述。
4. process
process为具体的执行程序。程序后面可以带参数。
第三部分:系统初始化
在init的配置文件中有这么一行:
si::sysinit:/etc/rc.d/rc.sysinit
它调用执行了/etc/rc.d/rc.sysinit,而rc.sysinit是一个bash shell的脚本,它主要是完成一些系统初始化的工作,rc.sysinit是每一个运行级别都要首先运行的重要脚本。它主要完成的工作有:激活交换分区,检查磁盘,加载硬件模块以及其它一些需要优先执行任务。
rc.sysinit约有850多行,但是每个单一的功能还是比较简单,而且带有注释,建议有兴趣的用户可以自行阅读自己机器上的该文件,以了解系统初始化所详细情况。由于此文件较长,所以不在本文中列出来,也不做具体的介绍。
当rc.sysinit程序执行完毕后,将返回init继续下一步。
第四部分:启动对应运行级别的守护进程
在rc.sysinit执行后,将返回init继续其它的动作,通常接下来会执行到/etc/rc.d/rc程序。以运行级别3为例,init将执行配置文件inittab中的以下这行:
l5:5:wait:/etc/rc.d/rc 5
这一行表示以5为参数运行/etc/rc.d/rc,/etc/rc.d/rc是一个Shell脚本,它接受5作为参数,去执行 /etc/rc.d/rc5.d/目录下的所有的rc启动脚本,/etc/rc.d/rc5.d/目录中的这些启动脚本实际上都是一些链接文件,而不是真正的rc启动脚本,真正的rc启动脚本实际上都是放在/etc/rc.d/init.d/目录下。而这些rc启动脚本有着类似的用法,它们一般能接受 start、stop、restart、status等参数。
/etc/rc.d/rc5.d/中的rc启动脚本通常是K或S开头的链接文件,对于以以S开头的启动脚本,将以start参数来运行。而如果发现存在相应的脚本也存在K打头的链接,而且已经处于运行态了(以/var/lock/subsys/下的文件作为标志),则将首先以stop为参数停止这些已经启动了的守护进程,然后再重新运行。这样做是为了保证是当init改变运行级别时,所有相关的守护进程都将重启。
至于在每个运行级中将运行哪些守护进程,用户可以通过chkconfig或setup中的"System Services"来自行设定。常见的守护进程有:
amd:自动安装NFS守护进程
apmd:高级电源管理守护进程
arpwatch:记录日志并构建一个在LAN接口上看到的以太网地址和IP地址对数据库
autofs:自动安装管理进程automount,与NFS相关,依赖于NIS
crond:Linux下的计划任务的守护进程
named:DNS服务器
netfs:安装NFS、Samba和NetWare网络文件系统
network:激活已配置网络接口的脚本程序
nfs:打开NFS服务
portmap:RPC portmap管理器,它管理基于RPC服务的连接
sendmail:邮件服务器sendmail
smb:Samba文件共享/打印服务
syslog:一个让系统引导时起动syslog和klogd系统日志守候进程的脚本
xfs:X Window字型服务器,为本地和远程X服务器提供字型集
Xinetd:支持多种网络服务的核心守护进程,可以管理wuftp、sshd、telnet等服务
这些守护进程也启动完成了,rc程序也就执行完了,然后又将返回init继续下一步。
第五部分:建立终端
rc执行完毕后,返回init。这时基本系统环境已经设置好了,各种守护进程也已经启动了。init接下来会打开6个终端,以便用户登录系统。通过按Alt+Fn(n对应1-6)可以在这6个终端中切换。在inittab中的以下6行就是定义了6个终端:
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6
从上面可以看出在2、3、4、5的运行级别中都将以respawn方式运行mingetty程序,mingetty程序能打开终端、设置模式。同时它会显示一个文本登录界面,这个界面就是我们经常看到的登录界面,在这个登录界面中会提示用户输入用户名,而用户输入的用户将作为参数传给login程序来验证用户的身份。
第六部分:登录系统,启动完成
对于运行级别为5的图形方式用户来说,他们的登录是通过一个图形化的登录界面。登录成功后可以直接进入KDE、Gnome等窗口管理器。而本文主要讲的还是文本方式登录的情况:
当我们看到mingetty的登录界面时,我们就可以输入用户名和密码来登录系统了。
Linux的账号验证程序是login,login会接收mingetty传来的用户名作为用户名参数。然后login会对用户名进行分析:如果用户名不是root,且存在/etc/nologin文件,login将输出nologin文件的内容,然后退出。这通常用来系统维护时防止非root用户登录。只有/etc/securetty中登记了的终端才允许root用户登录,如果不存在这个文件,则root可以在任何终端上登录。 /etc/usertty文件用于对用户作出附加访问限制,如果不存在这个文件,则没有其他限制。
在分析完用户名后,login将搜索/etc/passwd以及/etc/shadow来验证密码以及设置账户的其它信息,比如:主目录是什么、使用何种shell。如果没有指定主目录,将默认为根目录;如果没有指定shell,将默认为/bin/bash。
login程序成功后,会向对应的终端在输出最近一次登录的信息(在/var/log/lastlog中有记录),并检查用户是否有新邮件(在 /usr/spool/mail/的对应用户名目录下)。然后开始设置各种环境变量:对于bash来说,系统首先寻找/etc/profile脚本文件,并执行它;然后如果用户的主目录中存在.bash_profile文件,就执行它,在这些文件中又可能调用了其它配置文件,所有的配置文件执行后后,各种环境变量也设好了,这时会出现大家熟悉的命令行提示符,到此整个启动过程就结束了。
希望通过上面对Linux启动过程的剖析能帮助那些想深入学习Linux用户建立一个相关Linux启动过程的清晰概念,进而可以进一步研究Linux接下来是如何工作的。
【转】构建 arm-linux 仿真运行环境 (skyeye + arm-linux + NFS)
bluecolour 发表于 2008-05-15 11:31:03
构建 arm-linux 仿真运行环境 (skyeye + arm-linux + NFS)
Posted on http://www.cppblog.com/jb8164/archive/2008/04/17/47369.html 2008-04-17 11:53 Normandy 阅读(1335) 评论(8) 编辑 收藏 引用 所属分类: ARM embeded一 前言
本文旨在将 arm-linux 在 skyeye 上搭建起来,并在 arm-linux 上能成功 mount
NFS 为目标, 最终我们能在 arm-linux 里运行我们自己的应用程序. 其实在 skyeye 上移
植 arm-linux 并非难事,网上也有不少资料, 只是大都遗漏细节, 以致细微之处卡壳,所以本
文力求详实清析, 希望能对大家有点用处。
二 安装 Skyeye
我们选定 skyeye 的 1.2.4 这个版本, 为了能让它上面运行的 arm-linx 能挂接 NFS,我
们需要修改 device/net/dev_net_cs8900a.c (修改后的文件在附件里), 再编译 skyeye。
操作如下, 先解压源码包:
#tar xzf skyeye-1.2.4_Rel.tar.gz
#cd skyeye-1.2.4
请用附件里的 dev_net_cs8900a.c 替换 device/net/dev_net_cs8900a.c 后执行编译:
#make NO_DBCT=1 NO_BFD=1
编译完后生成的 skyeye 在 binary 下,将其拷贝至 /usr/local/bin/ 下:
#cp binary/skyeye /usr/local/bin
三 编译内核
我们选定 linux-2.6.14.tar.bz2 这个版本, 交叉编译器用 arm-linux-gcc 3.4.1 (对
2.6 内核用 3.4 以下的版本编译经常会出现问题)。操作步骤如下:
1.假定内核源码包在 /root 下, 首先解压源码:
#cd /root
#tar xjf linux-2.6.14.tar.bz2
2.进入内核目录:
#cd linux-2.6.14
修改此目录下的 Makefile, 将
ARCH ?= $(SUBARCH)
CROSS_COMPILE ?=
改为
ARCH ?= arm
CROSS_COMPILE ?= /usr/local/arm/3.4.1/bin/arm-linux-
3.生成默认的内核配置文件(for s3c2410):
#make smdk2410_defconfig
4.为内核添加 cs8900(见附件) 网卡驱动,以支持 NFS 挂接:
(1)复制 cs8900 驱动到 drivers/net/arm 目录
#cp cs8900.c drivers/net/arm
#cp cs8900.h drivers/net/arm
(2)修改 drivers/net/arm 目录下的 Kconfig 文件, 在最后添加:
config ARM_CS8900
tristate "CS8900 support"
depends on NET_ETHERNET && ARM && ARCH_SMDK2410
help
Support for CS8900A chipset based Ethernet cards. If you have a network
(Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available
from as well as .To compile this driver as a module, choose M here and read.
The module will be called cs8900.o.
注:在运行 make menuconfig 命令时就会出现: [ ] CS8900 support 这一选项
(3)修改 drivers/net/arm 目录下的Makefile文件,在最后添加如下内容:
obj-$(CONFIG_ARM_CS8900) += cs8900.o
注:2.6 版本内核的 Makefile 也与 2.4 的有所不同, 添加以上语句, 就会使内核在
编译的时候根据配置将cs8900A的驱动程序以模块或静态的方式编译到内核当中。
(4)修改 arch/arm/mach-s3c2410/mach-smdk2410.c
在此文件中找到 smdk2410_iodesc[] 结构数组,添加如下如下内容:
{vSMDK2410_ETH_IO,pSMDK2410_ETH_IO, SZ_1M, MT_DEVICE}
修改之后变成:
static struct map_desc smdk2410_iodesc[] __initdata = {
/* nothing here yet */
/* Map the ethernet controller CS8900A */
{vSMDK2410_ETH_IO,pSMDK2410_ETH_IO, SZ_1M, MT_DEVICE}
};
并且添加一个头文件引用:
#include <asm-arm/arch-s3c2410/smdk2410.h>
(5)在 include/asm-arm/arch-s3c2410 目录下创建文件 smdk2410.h
#ifndef _INCLUDE_SMDK2410_H_
#define _INCLUDE_SMDK2410_H_
#include <linux/config.h>
#define pSMDK2410_ETH_IO 0x19000000
#define vSMDK2410_ETH_IO 0xE0000000
#define SMDK2410_ETH_IRQ IRQ_EINT9
#endif
5.参照 http://skyeye.wiki.sourceforge.net/Linux 修改内核文件
修改 include/asm-arm/arch-s3c2410/map.h
#define S3C2410_CS6 (0x30000000UL)
to
#define S3C2410_CS6 (0xC0000000UL)
修改 include/asm-arm/arch-s3c2410/memory.h
#define PHYS_OFFSET (0x30000000UL)
to
#define PHYS_OFFSET (0xC0000000UL)
6.裁剪/定制内核
(1)#make menuconfig
(2)设置内核启动参数
Boot options ---> Default kernel command string:
mem=32M console=ttySAC0 root=/dev/ram initrd=0xc0800000,0x00800000 ramdisk_size=8192 rw
(3)设置 CS8900 的支持
Device Drivers --->
Network device support --->
Ethernet (10 or 100Mbit) ---> [] CS8900 support
选中 [*] CS8900 support
(4)设置 initrd 的支持
Device Drivers ---> Block devices ---> [ ] RAM disk support
下面三项必须设置:
1.确保 RAM disk support 被选中
2.相应的将默认的 (4096) Default RAM disk size (kbytes) 改成 8192;
3.Initial RAM disk (initrd) support 一定要选中, 切记!
(5)设置 NFS 的支持
File systems ---> Network File Systems --->
至少确保下面两项被选中:
[*] NFS file system support
[*] Provide NFSv3 client support
(6)设置 ROM file system 的支持
File systems ---> [*] ROM file system support
确保 [*] ROM file system support 被选中
(7)设置 ext2 的支持
File systems ---> [*] Second extended fs support
确保 [*] Second extended fs support 被选中
7.编译
#make
编译完成后会有个 vmlinux 在当前目录下, 这就是我们要的 arm-linux 内核了
四 制作根文件系统 initrd.img(Initial RAM disk)
我们选定 busybox-1.9.2.tar.bz2 这个版本, 以静态方式编译, 即生成的 busybox 不需
要共享库的支持就能运行。这样做我们就不需要布署程序库了。缺点是自己写的 arm-linux 程序在
这个根文件系统中是不能运行的,因为缺少共享程序库的支持。不过别担心,我们会解决这个问题的,稍
后你将看到,通过在 arm-linux 里以挂接 NFS 的方式, 将宿主机的 arm-linux-gcc 编译器的
库文件挂到 arm-linux 的 /lib 下, 就可完美的运行我们自己的程序了。好,一步步来,先来看看
根文件系统的制作:
1.解压源码包
#tar xjf busybox-1.9.2.tar.bz2
#cd busybox-1.9.2
2.修改 Makefile, 将
ARCH ?= $(SUBARCH)
CROSS_COMPILE ?=
改为
ARCH ?= arm
CROSS_COMPILE ?= /usr/local/arm/3.3.2/bin/arm-linux-
注:这个版本的 busybox 用 3.4.1 的 arm-linux-gcc 编译有些问题, 用 3.3.2 版则可顺利编译。
3.定制 busybox
#make menuconfig
设置静态编译方式
Busybox Settings ---> Build Options ---> [*] Build BusyBox as a static binary (no shared libs)
确保 [*] Build BusyBox as a static binary (no shared libs) 被选中
4.执行 make 编译
#make
编译出错, 信息如下:
applets/applets.c:15:2: warning: #warning Static linking against glibc produces buggy executables
applets/applets.c:16:2: warning: #warning (glibc does not cope well with ld --gc-sections).
applets/applets.c:17:2: warning: #warning See sources.redhat.com/bugzilla/show_bug.cgi?id=3400
applets/applets.c:18:2: warning: #warning Note that glibc is unsuitable for static linking anyway.
applets/applets.c:19:2: warning: #warning If you still want to do it, remove -Wl,--gc-sections
applets/applets.c:20:2: warning: #warning from scripts/trylink and remove this warning.
applets/applets.c:21:2: error: #error Aborting compilation.
make[1]: *** [applets/applets.o] Error 1
按照提示,修改 scripts/trylink, 将此文件里面有 -Wl,--gc-sections 的行都删除掉,
然后重新 make
#make
还是出错, 信息如下:
root@hukq-desktop:~/busybox/busybox-1.9.2# make
CC applets/applets.o
applets/applets.c:15:2: warning: #warning Static linking against glibc produces buggy executables
applets/applets.c:16:2: warning: #warning (glibc does not cope well with ld --gc-sections).
applets/applets.c:17:2: warning: #warning See sources.redhat.com/bugzilla/show_bug.cgi?id=3400
applets/applets.c:18:2: warning: #warning Note that glibc is unsuitable for static linking anyway.
applets/applets.c:19:2: warning: #warning If you still want to do it, remove -Wl,--gc-sections
applets/applets.c:20:2: warning: #warning from scripts/trylink and remove this warning.
applets/applets.c:21:2: error: #error Aborting compilation.
make[1]: *** [applets/applets.o] Error 1
make: *** [applets] Error 2
修改文件 applets/applets.c 第 21 行, 将
#error Aborting compilation.
注释掉:
/*#error Aborting compilation.*/
执行 make 重新编译
#make
编译通过, busybox 被生成了, 然后执行
#make install
busybox 就被安装到默认的临时目录 _install 下了
5.制作 initrd.img
有了 busybox 后制作 initrd.img 就容易多了,只是说起来比较烦琐。以命令演示如下:
创建映像文件并挂到 initrd 目录
#mkdir initrd
#dd if=/dev/zero of=initrd.img bs=1k count=4096
#mke2fs -F -v initrd.img
#mount -o loop initrd.img initrd
将添加 busybox 到此映像文件
#cd initrd
#cp -r ../_install/* .
#创建必要的目录
#mkdir proc lib etc dev root home var tmp
#chmod 777 tmp
建立设备文件
#cd dev
#mknod -m 644 console c 5 1
#mknod -m 644 null c 1 3
#mknod -m 640 ram b 1 1
#mknod -m 644 mem c 1 1
#cd ..
创建脚本文件 etc/inittab, 内容如下:
::sysinit:/etc/init.d/rcS
::askfirst:-/bin/sh
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a
设置此脚本执行权限
#chmod 644 etc/inittab
创建脚本文件 etc/init.d/rcS, 内容如下:
#!/bin/sh
/bin/mount -t proc none /proc
/sbin/ifconfig lo 127.0.0.1 up
/sbin/ifconfig eth0 10.0.0.2 netmask 255.0.0.0 up
hostname skyeye
mkdir /var/tmp
mkdir /var/log
mkdir /var/run
mkdir /var/lock
/bin/ash
设置此脚本执行权限
#chmod 755 etc/init.d/rcS
最后一步,执行实际的写入操作,生成 initrd.img
cd ..
umount initrd
五 运行 arm-linux
现在我们有了内核 vmlinux, 映像文件 initrd.img, 模拟程序 skyeye, 我们还需要一个
配置文件 skyeye.conf 进行 arm-linux 的仿真运行。
#mkdir /root/test
#cd /root/test
将 vmlinux, initrd.img 都拷贝到此目录, 在此目录下建立一个 skyeye 的配制文件
skyeye.conf, 文件内容如下:
cpu: arm920t
mach: s3c2410x
# physical memory
mem_bank: map=M, type=RW, addr=0xc0000000, size=0x00800000
mem_bank: map=M, type=RW, addr=0xc0800000, size=0x00800000, file=./initrd.img
mem_bank: map=M, type=RW, addr=0xc1000000, size=0x01000000
# all peripherals I/O mapping area
mem_bank: map=I, type=RW, addr=0x48000000, size=0x20000000
mem_bank: map=I, type=RW, addr=0x19000300, size=0x00000020
net: type=cs8900a, base=0x19000300, size=0x20,int=9, mac=0:4:3:2:1:f, ethmod=tuntap, hostip=10.0.0.1
lcd: type=s3c2410x, mod=gtk
#dbct:state=on
好了,试运行吧:
skyeye -e vmlinux
看到你的 arm-linux 运行了吗 :-)
六 在 arm-linux 里运行我们自己的程序
现在 arm-linux 在 skyeye 上跑起来了, 我们能运行里面的命令, 但这些都是 busybox
的,是系统程序。怎样才能在 arm-linux 里运行我们自己的程序呢? 有两种方案,我们不妨讨论一
下,择优而录之:
1.在制作根文件系统 initrd.img 的时候把我们自己的程序加进去,比如放在 /usr/bin 里
目录下,然后重新生成 initrd.img,并用这个新的根文件系统来运行 arm-linux。其实这
是我们的产品在 arm-linux 上发布的最终方式,但这有个缺点: 在产品开发/调试阶段这么
做比较麻烦,每修改一次代码就得 build 一次根文件系统。
2.利用挂接 NFS(Network file system) 的方式,我们访问/执行一个网络文件系统上的文件
就像它在本地一样,显然这么做能避免第一种方案的弊端! 如何实现呢? 随我来:
(1)在 arm-linux 的宿主机里配置 NFS Server (我用是 ubuntu,而且是在 vmware 里)
#apt-get install nfs-kernel-server
#apt-get install nfs-common
(2)编辑文件 /etc/exports, 内容如下(具体需求由你而定):
/test *(rw,sync,no_root_squash)
/usr/local/arm/3.3.2/lib *(ro,sync,no_root_squash)
(3)配置宿主机的 ip
#ifconfig eth1 down
#ifconfig eth1 10.0.0.1 netmask 255.0.0.0 up
注:你的可能是 eth0, 另外 ip 地址你也可自己定义,只要能和 arm-liux 通信
(4)重启 nfs server
#/usr/sbin/exportfs -r
#/etc/init.d/nfs-kernel-server restart
#/etc/init.d/portmap restart
注:可用 showmount -e 来验证你的配置是否成功
(5)在 skyeye 运行 arm-linux,为其配置 ip
#ifconfig lo down
#ifconfig eth0 down
#ifconfig lo 127.0.0.1 up
#ifconfig eth0 10.0.0.2 netmask 255.0.0.0 up
注:可将这几个命令加到 rcS 脚本里,让 arm-linux 启动时帮你做
(6)在 skyeye 上运行 arm-linux,演示 nfs 挂接
#mount -o nolock 10.0.0.1:/usr/local/arm/3.3.2/lib /lib
#export LD_LIBRARY_PATH=/lib
#mount -o nolock 10.0.0.1:/test /tmp
在宿主机的 /test 下建立文件 hello.c,用 arm-linux-gcc 3.3.2 编译
#cd /test
#arm-linux-gcc -o hello hello.c
在 arm-linux 的 /tmp 下看看,是不是有 hello.c 和 hello 这两个文件了? 试着运行看看:
#cd /tmp
#./hello
注:为了确认 arm-linux 能和宿主机通信, 可尝试以下手段:
(1)在宿主机上 ping 你的 arm-linux
#ping 10.0.0.2 -c 2
(2)在 arm-linux 里 ping 你的宿主机
#ping 10.0.0.1 -c 2
(3)如果相互都 ping 不通过,可这样做:
重新设置一下 arm-linux 的网络:
#ifconfig eth0 down
#ifconfig eth0 up
再重新设置一下宿主机的网络:
#ifconfig eth1 down
#ifconfig eth1 up
【转】Cross ToolsChain-交叉编译工具
bluecolour 发表于 2008-03-12 11:45:25
来源:CSDN 作者:GoT_FoX 发布时间:2007-9-6
读者可能会有疑问,为什么要用交叉编译器?交叉编译通俗地讲就是在一种平台上编译出能运 行在体系结构不同的另一种平台上的程序,比如在PC平台(X86 CPU)上编译出能运行在以ARM为内核的CPU平台上的程序,编译得到的程序在X86 CPU平台上是不能运行的,必须放到ARM CPU平台上才能运行,虽然两个平台用的都是Linux系统。这种方法在异平台移植和嵌入式开发时非常有用。相对与交叉编译,平常做的编译叫本地编译,也 就是在当前平台编译,编译得到的程序也是在本地执行。用来编译这种跨平台程序的编译器就叫交叉编译器,相对来说,用来做本地编译的工具就叫本地编译器。所 以要生成在目标机上运行的程序,必须要用交叉编译工具链来完成。在裁减和定制Linux内核用于嵌入式系统之前,由于一般嵌入式开发系统存储大小有限,通 常都要在性能优越的PC上建立一个用于目标机的交叉编译工具链,用该交叉编译工具链在PC上编译目标机上要运行的程序。交叉编译工具链是一个由编译器、连 接器和解释器组成的综合开发环境,交叉编译工具链主要由binutils、gcc和glibc 3个部分组成。有时出于减小 libc 库大小的考虑,也可以用别的 c 库来代替 glibc,例如 uClibc、dietlibc 和 newlib。建立交叉编译工具链是一个相当复杂的过程,如果不想自己经历复杂繁琐的编译过程,网上有一些编译好的可用的交叉编译工具链可以下载,但就以 学习为目的来说读者有必要学习自己制作一个交叉编译工具链。本章通过具体的实例讲述基于ARM的嵌入式Linux交叉编译工具链的制作过程。
|
安装包
|
下载地址
|
安装包
|
下载地址
|
|
linux-2.6.10.tar.gz
|
ftp.kernel.org
|
glibc-2.3.2.tar.gz
|
ftp.gnu.org
|
|
binutils-2.15.tar.bz2
|
ftp.gnu.org
|
glibc-linuxthreads-2.3.2.tar.gz
|
ftp.gnu.org
|
|
gcc-3.3.6.tar.gz
|
ftp.gnu.org
|

|
安装包
|
下载地址
|
|
crosstool-0.42.tar.gz
|
http://kegel.com/crosstool
|
|
linux-2.6.10.tar.gz
|
ftp.kernel.org
|
|
binutils-2.15.tar.bz2
|
ftp.gnu.org
|
|
gcc-3.3.6.tar.gz
|
|
|
glibc-2.3.2.tar.gz
|
|
|
glibc-linuxthreads-2.3.2.tar.gz
|
|
|
linux-libc-headers-2.6.12.0.tar.bz2
|

【转】Adding a new disk to a VMWare Virtual Machine in Linux
bluecolour 发表于 2008-03-05 00:08:31
I’ve been using VMWare for a while now and I always get asked some common questions about it. One of those is how to add a new virtual disk to a Linux virtual machine. So in response to that, here are the steps to adding a new SCSI based virtual disk to a CentOS Linux virtual machine. The steps for adding a disk to a Windows machine is very much the same except you would use the Disk Management utility from the Control Panel.
Step 1: Open virtual machine settings
Select your virtual machine, as you can see from the photo I selected the Infrastructure virtual machine. Next press the “Edit virtual machine settings’ to open the Virtual Machine Settings dialog.

Step 2: Add new hardware
From the “Virtual Machine Settings” dialog select the “Add…” button at the bottom of the screen. From this dialog you can also modify how much memory you dedicate to the machine when it boots.

Step 5: Create the virtual disk
In the next screen we see the three options for adding a new disk. We can “Create a new virtual disk”, this will create a brand new disk on the guest operating system. The second option, “Use an existing virtual disk”, allows you to mount a disk from another virtual machine. I like to do this with my “source” drive. I have one virtual disk that I’ve made that has all the Oracle and Linux CDs on it, that way I can just mount it to the machine I need when I have to do a new install instead of copying the binaries I need across disks, its definitely a big time saver. The last option is to “Use a physical disk”, this allows you to mount a local physical disk to the operating system. This option is akin to NFS mounting a drive to a virtual machine. To add a new disk we select the “Create a new virtual disk” option and select the “Next >” button.

Step 6: Select type of disk
Next we want to select the type of disk. I’ve been using VMWare for a long time and agree that the recommended Virtual Disk Type should be SCSI. I don’t know why, but I’ve had much better success with the SCSI virtual disks than the IDE ones. So in this step we want to select “SCSI (Recommended)” and the “Next >” button.

Step 7: Set disk size and options
Now we want to set the size of the disk we are creating. One of the nice features of VMWare is that you don’t have to allocate all of the disk when you create it. So if you create a 40 GB disk it doesn’t have to take it all right away, the disk will grow as your virtual machine needs it. I will say this is a big performance hit you take when the disk has to extend, but for most applications its OK. Also, I will warn that if the virtual disk grows and there is no physical disk left on the host operating system you will see a catastrophic failure and in most cases both the host and guest operating systems lock up and become unusable. (Don’t say I didn’t warn you) Lastly, you can split the files into 2GB sizes, while this isn’t necessary, it just makes all the disks much easier to manage and move around. For this step we want to set our disk size (12 GB in this case), I chose not to allocate the disk space right now (the machine has a 300 GB drive and has only 20 GB on it) and Split disk into 2 GB files.

Step 8: Name the disk file
This is actually pretty simple in that you decide what you want to physically call the disk and where to put it. .vmdk is the extension for VMWare virtual disks. After we name the disk we can select the “Finish” button which adds the disk to the virtual machine.

Step 9: Ensure new disk exists
So now we can see that the new disk has been added to the “Virtual Machine Settings” within the selected virtual machine. From here the disk acts just like it would if you added a new disk to a standalone server. So we select the “OK” button to continue.

Step 10: Boot the virtual machine
From here we just start the virtual machine like we would normally, either by selecting the button on the toolbar or selecting the “Start this virtual machine” link.

Step 11: Virtual machine start up
The machine boots normally as it would any other time.

Step 12: Create the Partition
After we’ve logged in and accessed a terminal window as root (or another user with root/sudo privs) we first want to run fdisk on the newly created drive. In Linux the first SCSI drive is sda, the second sdb, the third sdc, etc. since this was the second SCSI drive we added to the system, the device is known as /dev/sdb
The first command we want to run is fdisk /dev/sdb (NOTE: Thanks to everyone that caught my typo here) this utility works very much like the DOS utility of the old days and allows you to create and manage partitions. To create a new partition we enter the command n to create a new partition. This is going to be a primary partition p, and the first partition number 1. Because I want this disk to consume the full 12 GB I specified earlier we start at the first cylinder and end it at the last cylinder. We then want to write the partition table with the new partition we have just created so we enter the command w which writes the new table and exits fdisk.

Step 13: Format the partition
Now that we’ve create the partition, we now want to format the first with the new file system. I’ve decided to use ext3 filesystem for this disk, ext3 provides all the features of the classic ext2 file system plus journaling which helps to prevent disk corruption in the event of an improper shutdown and speeds up the recovery process. For a good overview of Linux standard file systems check out this article: http://linux.org.mt/article/filesystems So, to format the new partition we enter the command mkfs -t ext3 /dev/sdb1. This command makes a new files system with the type t ext3 on the /dev/sdb1 partition, this is the first partition on the sdb disk.

Step 14: Create the mount point
Determine where you want to add the new virtual disk you’ve created. I like to create a partition specifically for all the software I install after the basic Linux install called /software to do that we run mkdir /software, just a simple make directory command. Once that is complete we then want to mount the newly created partition. Because we haven’t added the partition to the /etc/fstab yet we have to mount it manually. To do that we run mount -t ext3 /dev/sdb1 /software. To break down this command we run mount with the ext3 filesystem type, the partition /dev/sdb1 to the directory /software. Pretty simple and straight forward. To check that the partition is properly mounted we run df -k which shows us the mounted partitions and the amount of available space.

Step 15: Open the fstab file
The fstab file holds all of the used disks and partitions, and determines how they are supposed to be used by the operating system. So we edit the file to add the newly created partition

Step 16: Modify the fstab for the new partition
After we open the fstab file in the previous step we add the following line:
/dev/sdb1 /software ext3 defaults 1 1
The first column is the partition name, the second is the default mount point, the third is the filesystem type. The fourth is the mount options, in this case I used default which mounts the drive rw, suid, dev, exec, auto, nouser and asynchronous. The 5th and 6th options are for the dump and fsck options. If dump is set to 1 the filesystem is marked to be backed up, if you are going to have sensitive material on the drive its a good idea to set it to 1. If fsck is set to greater than 1, then the operating system uses the number to determine in what order fsck should be run during start up. If it is set to 0 it will be ignored such as in the case of a cdrom drive since its a solid state disk. For more information on the fstab file check out this article: http://www.tuxfiles.org/linuxhelp/fstab.html
Lastly, we write and quit the file with the :wq command.

So now that the fstab has been written the drive will be mounted and unmounted when the machine is either started or shutdown. So there you have it, the quick and dirty process for adding a brand new disk to a virtual machine. Until next time…
【转】The Perfect Setup - Fedora Core 4
bluecolour 发表于 2008-02-26 15:04:48
Submitted by falko (Contact Author) (Forums) on Mon, 2005-07-18 14:44. :: Fedora
|
This is a "copy & paste" HowTo! The easiest way to follow this tutorial is to use a command line client/SSH client (like PuTTY for Windows) and simply copy and paste the commands (except where you have to provide own information like IP addresses, hostnames, passwords,...). This helps to avoid typos.
|
The Perfect Setup - Fedora Core 4 - Part I
Version 1.3
Author: Falko Timme <ft [at] falkotimme [dot] com>
Last edited: 01/03/2006
This is a detailed description about the steps to be taken to setup a Fedora Core 4 based server that offers all services needed by ISPs and hosters (web server (SSL-capable), mail server (with SMTP-AUTH and TLS!), DNS server, FTP server, MySQL server, POP3/IMAP, Quota, Firewall, etc.). In addition to that I will show how to use Debian's package manager apt on an rpm-based system because it takes care of package dependencies automagically which can save a lot of trouble.
I will use the following software:
- Web Server: Apache 2.0.x
- Mail Server: Postfix (easier to configure than sendmail; has a shorter history of security holes than sendmail)
- DNS Server: BIND9
- FTP Server: proftpd
- POP3/IMAP servers
- Webalizer for web site statistics
In the end you should have a system that works reliably and is ready for the free webhosting control panel ISPConfig (i.e., ISPConfig runs on it out of the box).
I want to say first that this is not the only way of setting up such a system. There are many ways of achieving this goal but this is the way I take. I do not issue any guarantee that this will work for you!
Requirements
To install such a system you will need the following:
- Download the 4 Fedora Core 4 CD iso images from a mirror near you (the list of mirrors can be found here: http://fedora.redhat.com/download/mirrors.html), e.g. ftp://ftp.tu-chemnitz.de/pub/linux/fedora-core/4/i386/iso/FC4-i386-disc1.iso, ftp://ftp.tu-chemnitz.de/pub/linux/fedora-core/4/i386/iso/FC4-i386-disc2.iso, ftp://ftp.tu-chemnitz.de/pub/linux/fedora-core/4/i386/iso/FC4-i386-disc3.iso and ftp://ftp.tu-chemnitz.de/pub/linux/fedora-core/4/i386/iso/FC4-i386-disc4.iso, or download the DVD iso image, e.g. ftp://ftp.tu-chemnitz.de/pub/linux/fedora-core/4/i386/iso/FC4-i386-DVD.iso
- an internet connection...
1 The Base System
Boot from your Fedora Core 4 CD (CD 1) or DVD.

It can take a long time to test the installation media so we skip this test here:
The welcome screen of the Fedora installer appears:

Choose your language next:

Select your keyboard layout:

We want to install a server so we choose Server here:

Now we have to partition our hard disk. You can choose to let the Fedora installer do the partitioning, or you can do it yourself. I want to create a small /boot partition (less than 100 MB) with the file system ext3, a swap partition and a huge / partition (again with ext3):





Now the boot loader GRUB will be installed. You can leave the default settings unchanged and click on Next:

On to the network settings. The default setting here seems to be to configure the network interfaces with DHCP, but we are installing a server, so static IP addresses are not a bad idea... Click on the Edit button at the top right. In the window that pops up uncheck Configure using DHCP and give your network card a static IP address (in this tutorial I'm using the IP address 192.168.0.100 for demonstration purposes):

Set the hostname manually, e.g. server1.example.com, and enter a gateway (e.g. 192.168.0.1) and up to three DNS servers (e.g. 145.253.2.75 and 193.174.32.18):

On the next screen we select No firewall (there's a firewall coming with ISPConfig that we want to use) and disable SELinux:

Click on Proceed (remember, we are going to use the ISPConfig firewall):

Choose your time zone:

Give root a password:

Now we are to select the package groups we want to install. Select Editors, Text Based Internet, Server Configuration Tools, Web Server, Mail Server, DNS Name Server, FTP Server, MySQL Database, Development Tools, Language Support, Administration Tools and System Tools and click on Next:

The installer tells you which CDs it will need to install the selected packages:


The installation begins. This will take a few minutes:

Finally, the installation is complete, and you can remove your CD/DVD from the computer and reboot it:

Now, on to the configuration...
The Perfect Setup - Fedora Core 4 - Part III
2 Installing And Configuring The Rest Of The System
Configure Additional IP Addresses
Let's assume our network interface is eth0. Then there is a file /etc/sysconfig/network-scripts/ifcfg-eth0 which looks like this:
DEVICE=eth0 |
Now we want to create the virtual interface eth0:0 with the IP address 192.168.0.101. All we have to do is to create the file /etc/sysconfig/network-scripts/ifcfg-eth0:0 which looks like this:
DEVICE=eth0:0 |
Afterwards we have to restart the network:
/etc/init.d/network restartSetting The Hostname
echo server1.example.com > /etc/hostname
/bin/hostname -F /etc/hostname
Install apt For Fedora
apt is the packaging system used on Debian. Since it cares much better for package dependencies than rpm it would be nice if we could use it on our new Fedora system. This would save us a lot of hassle. Fortunately, apt has been ported to a lot of rpm based distributions, and is also available for Fedora Core 4 (you will love it... :-)). In this tutorial I will use a mixture of Fedora's yum and apt, because not all yum packages are available for apt and vice versa.
yum install apt
Edit /etc/apt/sources.list. It should contain the following lines:
rpm http://ayo.freshrpms.net fedora/linux/4/i386 core updates freshrpms |
In the last line, rpm http://ayo.freshrpms.net fedora/linux/1/i386 core updates freshrpms, the 1 is not an error or typo! This is the repository that has the imap package which we are going to install soon! So do not change these lines!
Run
apt-get update
Import The GPG Keys For Software Packages
rpm --import /usr/share/rhn/RPM-GPG-KEY*
Install Some Software
yum install fetchmail wget bzip2 unzip zip nmap openssl lynx fileutils ncftp
Quota
yum install quota
Edit /etc/fstab to look like this (I added ,usrquota,grpquota to LABEL=/ (mount point /):
# This file is edited by fstab-sync - see 'man fstab-sync' for details |
Then run:
touch /aquota.user /aquota.group
chmod 600 /aquota.*
mount -o remount /
quotacheck -avugm
quotaon -avug
DNS-Server
yum install bind-chroot
chmod 755 /var/named/
chmod 775 /var/named/chroot/
chmod 775 /var/named/chroot/var/
chmod 775 /var/named/chroot/var/named/
chmod 775 /var/named/chroot/var/run/
chmod 777 /var/named/chroot/var/run/named/
cd /var/named/chroot/var/named/
ln -s ../../ chroot
chkconfig --levels 235 named on
/etc/init.d/named start
Bind will run in a chroot jail under /var/named/chroot/var/named/.
The Perfect Setup - Fedora Core 4 - Part IV
MySQL (4.1)
yum install mysql mysql-devel mysql-server
chkconfig --levels 235 mysqld on
/etc/init.d/mysqld start
Now check that networking is enabled. Run
netstat -tap
It should show a line like this:
tcp 0 0 *:mysql *:* LISTEN 6621/mysqld |
If it does not, edit /etc/my.cnf, comment out the option skip-networking:
# Don't listen on a TCP/IP port at all. This can be a security enhancement, |
and restart your MySQL server:
/etc/init.d/mysqld restart
Run
mysqladmin -u root password yourrootsqlpassword
mysqladmin -h server1.example.com -u root password yourrootsqlpassword
to set a password for the user root (otherwise anybody can access your MySQL database!).
Postfix With SMTP-AUTH And TLS
apt-get install cyrus-sasl cyrus-sasl-devel cyrus-sasl-gssapi cyrus-sasl-md5 cyrus-sasl-plain postfix imap
postconf -e 'smtpd_sasl_local_domain ='
postconf -e 'smtpd_sasl_auth_enable = yes'
postconf -e 'smtpd_sasl_security_options = noanonymous'
postconf -e 'broken_sasl_auth_clients = yes'
postconf -e 'smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination'
postconf -e 'inet_interfaces = all'
echo 'pwcheck_method: saslauthd' > /usr/lib/sasl2/smtpd.conf
echo 'mech_list: plain login' >> /usr/lib/sasl2/smtpd.conf
mkdir /etc/postfix/ssl
cd /etc/postfix/ssl/
openssl genrsa -des3 -rand /etc/hosts -out smtpd.key 1024
chmod 600 smtpd.key
openssl req -new -key smtpd.key -out smtpd.csr
openssl x509 -req -days 3650 -in smtpd.csr -signkey smtpd.key -out smtpd.crt
openssl rsa -in smtpd.key -out smtpd.key.unencrypted
mv -f smtpd.key.unencrypted smtpd.key
openssl req -new -x509 -extensions v3_ca -keyout cakey.pem -out cacert.pem -days 3650
postconf -e 'smtpd_tls_auth_only = no'
postconf -e 'smtp_use_tls = yes'
postconf -e 'smtpd_use_tls = yes'
postconf -e 'smtp_tls_note_starttls_offer = yes'
postconf -e 'smtpd_tls_key_file = /etc/postfix/ssl/smtpd.key'
postconf -e 'smtpd_tls_cert_file = /etc/postfix/ssl/smtpd.crt'
postconf -e 'smtpd_tls_CAfile = /etc/postfix/ssl/cacert.pem'
postconf -e 'smtpd_tls_loglevel = 1'
postconf -e 'smtpd_tls_received_header = yes'
postconf -e 'smtpd_tls_session_cache_timeout = 3600s'
postconf -e 'tls_random_source = dev:/dev/urandom'
Now start Postfix, saslauthd, imap and pop3:
chkconfig --levels 235 sendmail off
chkconfig --levels 235 postfix on
chkconfig --levels 235 saslauthd on
chkconfig imap on
chkconfig imaps on
chkconfig ipop3 on
chkconfig pop3s on
/etc/init.d/sendmail stop
/etc/init.d/postfix start
/etc/init.d/saslauthd start
/etc/init.d/xinetd restart
To see if SMTP-AUTH and TLS work properly now run the following command:
telnet localhost 25
After you have established the connection to your postfix mail server type
ehlo localhost
If you see the lines
250-STARTTLS
and
250-AUTH
everything is fine.

Type
quit
to return to the system's shell.
Apache With PHP5
apt-get install php php-devel php-gd php-imap php-ldap php-mysql php-odbc php-pear php-xml php-xmlrpc curl curl-devel perl-libwww-perl ImageMagick libxml2 libxml2-devel
Now edit /etc/httpd/conf.d/php.conf and comment out the AddHandler and AddType lines:
# |
Change the DirectoryIndex line in /etc/httpd/conf/httpd.conf to
DirectoryIndex index.html index.htm index.shtml index.cgi index.php index.php3 index.pl
Now configure your system to start Apache at boot time:
chkconfig --levels 235 httpd on
Start Apache:
/etc/init.d/httpd start
The Perfect Setup - Fedora Core 4 - Part V
Proftpd
ISPConfig works better with proftpd than with vsftpd, so let's remove vsftpd and install proftpd:
apt-get remove vsftpd
yum install proftpd
chkconfig --levels 235 proftpd on
/etc/init.d/proftpd start
Some users reported that they were not able to login with system users so you might have to do the following steps:
Create the file /etc/pam.d/ftp with the following content:
#%PAM-1.0 |
Restart proftpd afterwards:
/etc/init.d/proftpd restart
Webalizer
To install webalizer, just run
apt-get install webalizer
Synchronize the System Clock
If you want to have the system clock synchronized with an NTP server do the following:
apt-get install rdate
rdate -s time.nist.gov
Create /var/spool/cron/root:
# update time with ntp server |
Then run
chmod 600 /var/spool/cron/root
/etc/init.d/crond restart
Install some Perl Modules needed by SpamAssassin (comes with ISPConfig)
Installation using the Perl Shell
Login to your command line as root and run the following command to start the Perl shell:
perl -MCPAN -e shell
If you run the Perl shell for the first time you will be asked some questions. In most cases the default answers are ok.
Please note: If you run a firewall on your system you might have to turn it off while working on the Perl shell in order for the Perl shell to be able to fetch the needed modules without a big delay. You can switch it on afterwards.
The big advantage of the Perl shell compared to the two other methods described here is that it cares about dependencies when installing new modules. I.e., if it turns out that a prerequisite Perl module is missing when you install another module the Perl shell asks you if it should install the prerequisite module for you. You should answer that question with "Yes".
Run the following commands to install the modules needed by SpamAssassin:
install HTML::Parser
install DB_File
install Net::DNS (when prompted to enable tests, choose no)
install Digest::SHA1
q (to leave the Perl shell)
If a module is already installed on your system you will get a message similar to this one:
HTML::Parser is up to date.
Successful installation of a module looks like this:
/usr/bin/make install -- OK
The End
The configuration of the server is now finished, and if you wish you can now install ISPConfig on it.
A Note On SuExec
If you want to run CGI scripts under suExec, you should specify /var/www as the home directory for websites created by ISPConfig as Fedora's suExec is compiled with /var/www as Doc_Root. Run /usr/sbin/suexec -V, and the output should look like this:

To select /var/www as the home directory for websites during the installation of ISPConfig do the following: When you are asked for the installation mode, select the expert mode.

Later during the installation you are asked if the default directory /home/www should be the directory where ISPConfig will create websites in. Answer n and enter /var/www as the home directory for websites.

HTML <Select> + Onchange 的 Example
bluecolour 发表于 2008-01-25 11:49:09
<select onChange=javascript:window.open(this.options[this.selectedIndex].value) size=1 name=select1>
<option selected>选择网页</option>
<option value="http://www.baidu.com">百度</option>
<option value="http://www.163.com">网易</option>
</select>
悲歌之王 杨千桦
bluecolour 发表于 2008-01-24 15:27:45
作曲:林一峰
填词:林若宁
杨千桦
明明我起舞像羽毛
任我轻飘飘都跌倒
难令我羡慕 蝴蝶扑不到晨早
翅膀迟早都衰老
为何要抖擞问我前途
愉快这么少不要数
甜蜜有限度 期望那可过份高
俯瞰风光也恐怖
神只会歧视我 祷告假装听不到
逼迫悲观的少女穷途无路
唯有绝望 弹尽世间各样好
坚决拒绝祈祷
从来吃不到味美葡萄
问我怎懂得讲句好
凭藉你味道 明白我的价值高
好到使得我焦躁
神只会惩罚我 好处怎高攀得到
逼迫悲观的少女穷途无路
唯有绝望 弹尽世间各样好
坚决拒绝祈祷
从来我只配独处地牢
在暗灰天空找最好
留住你味道 甜蜜带不进泥土
饱满始终会呕吐
留住你味道 甜蜜带不进泥土
一切始终要清数
