免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: 独孤九贱
打印 上一主题 下一主题

我也来学做嵌入式Linux系统V0.1(完整版) [复制链接]

论坛徽章:
0
11 [报告]
发表于 2005-10-15 21:45 |只看该作者

我也来学做嵌入式Linux系统V0.1(完整版)

thanks

论坛徽章:
0
12 [报告]
发表于 2005-10-19 10:57 |只看该作者

我也来学做嵌入式Linux系统V0.1(完整版)

好东东,收藏了!

论坛徽章:
0
13 [报告]
发表于 2005-10-19 11:08 |只看该作者

我也来学做嵌入式Linux系统V0.1(完整版)

谢谢了,copy到我的硬盘了

论坛徽章:
0
14 [报告]
发表于 2005-10-19 19:20 |只看该作者

我也来学做嵌入式Linux系统V0.1(完整版)

very good!

借鉴!学习中!!

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-03 17:23:07综合交流区版块每日发帖之星
日期:2015-08-19 06:20:00综合交流区版块每日发帖之星
日期:2015-09-15 06:20:00
15 [报告]
发表于 2005-10-23 10:51 |只看该作者

我也来学做嵌入式Linux系统V0.1(完整版)

Good job ~~!

LZ 太厉害啦

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
16 [报告]
发表于 2005-10-23 19:11 |只看该作者

我也来学做嵌入式Linux系统V0.1(完整版)

收藏了,谢楼主

论坛徽章:
0
17 [报告]
发表于 2005-10-27 12:46 |只看该作者

我也来学做嵌入式Linux系统V0.1(完整版)

谢谢第一手资料,感动中流泪中..................!!!!!!!!!!!!!!!!!

论坛徽章:
0
18 [报告]
发表于 2005-11-01 10:34 |只看该作者

继续补完

不好意思,最近工作太忙,好久没有来搞这个东东了,加之心爱的手机丢了,心情又不太好,不过一切都过去了,继续来将它补充完整。

修改启动脚本
在前面写rcS启动脚本中。当时只是为了系统能够正常地启动,在启动网卡/路由/服务等时,有如下语句:
——————————————————————————————————————————————
#set lo ip address
ifconfig lo 127.0.0.1

#set eth0 ip address
#当然,这样子做只是权宜之计,最后做的应该是在这一步引导网络启动脚本,像RedHat
#那样,自动读取所有指定的配置文件来启动
ifconfig eth0 192.168.0.68 netmask 255.255.255.0

#set route
#同样的,最终这里应该是运行启动路由的脚本,读取路由配置文件
route add default gw 192.168.0.1
……
———————————————————————————————————————————————
这样配置的最大坏处就是不能根据配置文件自定义,每次开机都定死了,现在来修改它,将这段语句删除之,换成如下语句:
for i in /etc/start/S??* ;do
    # Ignore dangling symlinks (if any).
    [ ! -f "$i" ] && continue

    echo "Running $i ."
    case "$i" in
        *.sh)
                # Source shell script for speed.
            (
            trap - INT QUIT TSTP
            set start
            . $i
            )
            ;;
        *)
            # No sh extension, so fork subprocess.
            $i start
            ;;
    esac
    echo "Done $i ."
    echo
done
解释一下,这段语句的作用,就是启动/etc/start/目录下,所有以S开头的脚本文件,可以启动两类,以sh结尾或没有 sh后缀的。
这样,我们在/etc/目录下再新建一目录start/,这里面就是我们启动时需要的脚本的。先来启动网卡。

修改网卡配置文件
我是根据Red hat的作法,把网卡配置放在/etc/sysconfig/network-scripts目录下,类似于ifcfg-ethXX这样子,它们的语法是:
DEVICE=eth0
BOOTPROTO=static
BROADCAST=88.88.88.255
IPADDR=88.88.88.44
NETMASK=255.255.255.0
NETWORK=88.88.88.0
ONBOOT=yes
好,建立这些目录和文件,我共有两个文件ifcfg-ethXX。回到/etc/start目录,建立网卡的启动脚本S01interface:
#!/bin/sh

. /etc/sysconfig/network
#enable ip_forword
echo >1 /proc/sys/net/ipv4/ip_forward

#enable syn_cookie
echo >1 /proc/sys/net/ipv4/tcp_syncookies

#enable loopback interface
/sbin/ifconfig lo 127.0.0.1

#eanble ethernet interface
/usr/sbin/bootife

#set hostname
if [ -z "$HOSTNAME" -o "$HOSTNAME" = "(none)" ]
then
        HOSTNAME=localhost
fi

/bin/hostname ${HOSTNAME}

请注意这个脚本文件,有两个地方:
1、包含了另一个配置文件/etc/sysconfig/network,在这里,我也是照抄了redhat,我的/etc/sysconfig/network这个文件的内容如下:
NETWORKING=yes
HOSTNAME=skynet
GATEWAY=88.88.88.2
2、在启动网卡时,我使用了
#eanble ethernet interface
/usr/sbin/bootife
bootife是我自己写的一个C程序,作用是读取/etc/sysconfig/network-scripts/下面的ifcfg-ethXX文件,并配置之,本来这里就该用shell来完成更合适一点,无奈,偶shell功底实在差了一点(刚学几天),就是想从Redhat中照抄过来,反复试了几次也没有成功。所以被逼无奈用C来完成之,后面我会附上我的C的源码,也希望哪位大哥能够写一段Shell的程序代替它,放上来大家共享之。

修改路由启动文件
同样的,我在/etc/start下,建立新脚本S02route.sh,它的作用是启动所有配置的静态路由:
#!/bin/bash

. /etc/sysconfig/network
# Add non interface-specific static-routes.

if [ -f /etc/sysconfig/static-routes ]
then
        grep "eth*" /etc/sysconfig/static-routes | while read ignore args ; do
#               echo "/sbin/route add -"$args
                /sbin/route add -$args
        done
fi

#Add defalut gw
/sbin/route add default gw ${GATEWAY}

OK,启动时读取的配置文件是/etc/sysconfig/static-routes ,它的语法和Redhat是一样的,请参照建立此文件。

启动服务程序
新建启动脚本S03server:
#!/bin/sh
#------------------------------------------------------------------
#-- Source
#--     Author(s)        : kendo
#--                        Email: kendo999@sohu.com
#--                        http://www.skynet.org.cn
#--     2005/10/31
#------------------------------------------------------------------

. /etc/sysconfig/bootserver

if [ "$enable_httpd" = 1 ] ; then
        . /etc/scripts/httpd.sh $1
fi

if [ "$enable_adsl" = 1 ] ; then
        ……
fi

if [ "$enable_udhcpd" = 1 ] ; then
        ……
fi

很简单,根据相应变量的值,调用相应的脚本。
1、这些启动标志变量,我定义在了/etc/sysconfig/bootserver当中,其内容如下:
#start server on system boot
#1:yes  0:no
enable_httpd=1
enable_adsl=1
enable_udhcpd=1

2、每种服务对应的脚本,我都放在了/etc/scripts下面。这些脚本,取决于你打算使用哪些服务程序了。脚本的来源,可以自己编写,有可能其源码中自带有,也可以到网上查找……我就不再一一赘述了,

OK,基本上,脚本的修改就完成了,下一步,将是建立RamDisk。

——————————————————————————————————————————————
附,读取网卡配置文件,启动网卡的C源码:
/************************************************************************
** author:kendo
** date:2005/10/26

***********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>

#define NETCFGDIR        "/etc/sysconfig/network-scripts/"

struct _ifcfg{
        char device[8];
        char bootproto[8];
        char br[16];
        char netmask[16];
        char ip[16];
        char network[16];
        int onboot;
};

void ParseKey(struct _ifcfg *ifcfg,char *key,char *value)
{
        if(!strcmp(key,"DEVICE"))
        {
                strcpy(ifcfg->device,value);
        }
        else if(!strcmp(key,"BOOTPROTO"))
        {
                strcpy(ifcfg->bootproto,value);
        }
        else if(!strcmp(key,"BROADCAST"))
        {
                strcpy(ifcfg->br,value);
        }
        else if(!strcmp(key,"IPADDR"))
        {
                strcpy(ifcfg->ip,value);
        }
        else if(!strcmp(key,"NETMASK"))
        {
                strcpy(ifcfg->netmask,value);
        }
        else if(!strcmp(key,"NETWORK"))
        {
                strcpy(ifcfg->network,value);
        }
        else if(!strcmp(key,"ONBOOT"))
        {
                ifcfg->onboot=(strcmp(value,"yes") ? 0 : 1);               
        }
}

int main(int argc,char **argv)
{
        FILE *fp;
        DIR *dir;
        int i;
        char filename[50],buf[80];
        char *index,*key,*value,*p;
        struct _ifcfg *ifcfg;
        struct dirent *ptr;

        ifcfg=(struct _ifcfg *)malloc(sizeof(struct _ifcfg));
        memset(ifcfg,0,sizeof(struct _ifcfg));

        dir=opendir(NETCFGDIR);                        /*打开脚本目录*/
        while((ptr=readdir(dir))!=NULL)                /*读取所有文件*/
        {
                if(strncmp(ptr->d_name,"ifcfg-eth",9))                /*这里,只启动了以太网卡^o^*/
                {
                        continue;
                }
                memset(filename,0,sizeof(filename));
                sprintf(filename,"%s%s",NETCFGDIR,ptr->d_name);
                if((fp=fopen(filename,"r"))==NULL)                /*打开配置文件*/
                {
                        continue;
                }

                while(!feof(fp))
                {
                        memset(buf,0,sizeof(buf));
                        if(fgets(buf,80,fp)!=NULL)                /*逐行读取分析*/
                        {
                                p=strchr(buf,'n');
                                if(p)
                                {
                                        *p='';
                                }
                                index=buf;
                                key=strtok(index,"=");                /*读取配置变量*/
                                value=strtok(NULL,"=");                /*读取变量的值*/
                                ParseKey(ifcfg,key,value);        /*分析之,存入结构ifcfg中*/
                        }
                }
                /*构建相应的命令*/
                memset(buf,0,80);
                strcpy(buf,"/sbin/ifconfig");

                if(ifcfg->onboot)
                {
                        sprintf(buf,"%s %s %s netmask %s broadcast %s",
                                buf,
                                ifcfg->device,
                                ifcfg->ip,
                                ifcfg->netmask,
                                ifcfg->br);
                        /*直接调用system来实现,当然也可以自己通过ioctl来设置,相应源码,我以前在c/c++版发过*/
                        system(buf);
                }
        }
        free(ife);
        return 0;
}

论坛徽章:
0
19 [报告]
发表于 2005-11-01 10:52 |只看该作者

  1.                 memset(buf,0,80);
  2.                 strcpy(buf,"/sbin/ifconfig");

  3.                 if(ifcfg->onboot)
  4.                 {
  5.                         sprintf(buf,"%s %s %s netmask %s broadcast %s",
  6.                                 buf,
  7.                                 ifcfg->device,
  8.                                 ifcfg->ip,
  9.                                 ifcfg->netmask,
  10.                                 ifcfg->br);
  11.                         /*直接调用system来实现,当然也可以自己通过ioctl来设置,相应源码,我以前在c/c++版发过*/
  12.                         system(buf);
复制代码

两个问题
1、从这段代码看,实际调用了 /sbin/ifconfig 来完成网卡的设置,那么,这个程序是否必须用 root 来执行?
2、为何不用 system("command") 呢?

论坛徽章:
0
20 [报告]
发表于 2005-11-01 11:03 |只看该作者

回复 19楼 platinum 的帖子

1、ifconfig本身运行,应该不需要root吧?而至于在shell中的运行权限,要看看相应的权限位了,事实上它已经能够在我的系统中很好的运行了,测试过很多次的。不过现在我的系统,其实没有用这种方法的,我是自己封装了一个网卡管理的库,也就是重写了ifconfig,不过要把这些代码发上来,太麻烦了,所以,就用了解system简单了一点。

2、我不是很理解“为何不用 system("command") 呢?”这句话的含义,我用的是system(buf);你说的是不是为什么要去构建一个buf,而不是直接用system("/sbin/ifconfig ethXX……")?清楚一点……^o^
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP