Chinaunix首页 | 论坛 | 博客
  • 博客访问: 318009
  • 博文数量: 68
  • 博客积分: 1501
  • 博客等级: 上尉
  • 技术积分: 1010
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-30 09:52
文章分类

全部博文(68)

文章存档

2010年(1)

2009年(67)

我的朋友

分类:

2009-05-18 08:35:43

 
S3C2410拨号上网

最近做嵌入式实时视频服务器,S3C2410系列,需要让视频服务器支持ADSL宽带接入。

有以下软硬件支持:

ARM920T(S3C2410系列)

Arm-linux-2.4.18

Arm-linux-gcc-2.95.3

Arm-linux-gcc-3.4.1

PPPoE-3.7

PPP-2.4.1

 

很显然工作主要有两个:

1、  配置内核

2、  移植PPPoE和PPP

 

一、配置内核

需要说明的是,PC桌面linux中已经默认的支持了PPP协议,并且系统中已经存在了pppd这个进程。但在所用的armlinux中默认并没有支持ppp和pppoe协议,所以需要自己配置内核,使其支持,当然工作也是很简单的。

①       进入内核目录

②       在终端执行:Make menuconfig,之后就会出现内核配置界面,选择network device support,出现network device support配置界面,为了保险起见选择ppp的所有选项,选择仅有的一个pppoe选项,当然你可以以选入内核或者以模块加载两种方式使用,我选用的是编入内核,应为pppoe和ppp的程序makefile默认生成的可执行程序,而不是“.o”模块文件。

③       在终端执行:make dep,就是执行make文件关联,如果内核是第一次编译如果不执行此命令就会出错。

④       在终端执行:make zImage,经过漫长的过程,生成内核的压缩文件,在arch/arm/boot目录下面

⑤       把内核烧入开发板,这个办法很多啊,你可以在windows下面用超级终端,在linux下面有minicom,或者直接用网线下载(ztelnet).

二、移植PPP

我选用的PPP版本是2.4.1,linux-2.4.18内核配置帮助说明ppp的驱动是2.4.1的,所以我就选择了ppp-2.4.1。

①       当然先是解压缩:tar zxvf  ppp-2.4.1.tar.gz

②       进入目录执行:./configure  配置需要文件夹下面的Makefile文件,实际上需要编译的文件夹只有四个:chat、pppdump、pppstats、pppd,需要的可执行文件分别是:chat、pppdump、pppstats、pppd,也就是各个目录下的生成文件

③       你可以直接运行make CC=arm-liunx-gcc,当然起初选用的版本是2.95.3,你会发现出现很多的警告和错误,警告不要紧,可是那些错误就烦人了。然后进入各个文件夹执行:make CC=arm-linux-gcc,发现只有pppd文件夹的程序编译不通过,出现上面的问题,察看错误提示发现并核对编译器程序发现的确很多地方重复定义,试图修正一些,但太多了,还有一些莫名奇怪的错误,包括的头文件确实有这个东西,它却提示这个东西无定义,没办法,只好放弃2.95.3.试着采用arm-linux-gcc-3.4.1编译,哈哈,不错!顺利通过。赶紧把生成的四个可执行程序拷贝开发板上(/bin下就可以了,usr/sbin目录只是/bin的一个链接),还有etc.ppp目录下面的配置文件拷贝到/etc/ppp/下面,如果没有这个文件夹,就自己建了。运行./pppd。--------------------------错误提示:glibc库版本不对。查资料发现的确,gcc的两个交叉编译器所用的版本好像一个是glibc-2.1,一个是glibc-2.3。无奈~~~~~~~~~~~~~~~~~了一天多啊。

不过没有过不无的桥,仔细观察发现大部分错误出现在程序包括的一个文件中中,为什么3.4.1行,而2.95.3不行呢?把3.4.1的route.h更名route_lyn.h,拷贝到2.95.5 所在目录,修改pppd下包括头文件的文件为包括,重新编译,通过!!!!!

其实执行的时候有遇到一个地址族不支持协议的错误,重新编译内核选择IPv6支持就可以了。运行:发现与pc机现象相同,就是打印出一些乱码,姑且认为是移植成功了。

三、    移植PPPoE

①       解压缩

②       运行./go,在PC上自动编译、安装所需要的文件。在这里我们需要的可

不是这些,当出现配置“配置参数”时,退出,然后进入src文件夹,PPPoE

源程序都在这里,修改makefile,将其中的gcc换成arm-linux-gcc,

Ar换成arm-linux-ar。编译生成我们所需要的文件,然后将pppoe、

pppoe-server、pppoe-sniff、pppoe-relay和configs文件夹下的东西

拷贝到开发板上,运行pppoe-setup进行配置,然后运行pppoe-start

开始拨号,很遗憾,不是我们想要的结果:Timeout for wait PADO packets

LCP:Timeout for configs request等错误提示.无奈试了好几天:检查

所建立的设备文件、测试PADI保温是否发出等等,试了好多办法都无法

拨号。

③       后来发现pppoe—PADI阶段采用SOCK_PACKET广播,最后写了个简单的

sniffer程序抓包(只针对pppoe包)。和PC机正确拨号的PADI包相比

多了两个字节:在以太网协议的类型的后面多了FF BF两个字节。马上想

到PC和arm两个操作系统中对PPPoE数据包结构体的大小解释不一样。

通过简单的程序验证,发现的确。PC机采用16-32位混合操作系统,可

以按照16位对齐,而arm采用纯32位操作系统,只能以32位对齐。

文件中定义的结构体:

struct ethhdr

{

    unsigned char   h_dest[ETH_ALEN]; 

    unsigned char   h_source[ETH_ALEN];

    unsigned short  h_proto;

};

Pc中是占14个字节(16位对齐),arm中占16位字节(32位对齐)

 

于是将:pppoe.h中定义的结构体:

 

 

 

/* A PPPoE Packet, including Ethernet headers */

typedef struct PPPoEPacketStruct {

    struct ethhdr ethHdr;   /* Ethernet header */

#ifdef PACK_BITFIELDS_REVERSED

    unsigned int type:4;    /* PPPoE Type (must be 1) */

    unsigned int ver:4;     /* PPPoE Version (must be 1) */

#else

    unsigned int ver:4;     /* PPPoE Version (must be 1) */

    unsigned int type:4;    /* PPPoE Type (must be 1) */

#endif

    unsigned int code:8;    /* PPPoE code */

    unsigned int session:16;    /* PPPoE session */

    unsigned int length:16; /* Payload length */

    unsigned char payload[ETH_DATA_LEN]; //1500

} PPPoEPacket;

 

改为:

/* A PPPoE Packet, including Ethernet headers */

typedef struct PPPoEPacketStruct {

      unsigned char h_dest[ETH_ALEN]; 

      unsigned char h_source[ETH_ALEN];

      unsigned short    h_proto;

#ifdef PACK_BITFIELDS_REVERSED

      unsigned int type:4;      /* PPPoE Type (must be 1) */

      unsigned int ver:4;       /* PPPoE Version (must be 1) */

    unsigned int ver:4;       /* PPPoE Version (must be 1) */

      unsigned int type:4;      /* PPPoE Type (must be 1) */

#endif

      unsigned int code:8;  /* PPPoE code */

      unsigned int session:16;  /* PPPoE session */

      unsigned int length:16;   /* Payload length */

      unsigned char payload[ETH_DATA_LEN];

} PPPoEPacket;

 

编译运行还是不行,跟踪程序(没法直接打印数出运行结果,只好写在文

件中):

发现:discovery.c:

void  waitForPADO(PPPoEConnection *conn, int timeout)函数错误返

回:

if (ntohs(packet.length) + HDR_SIZE > len) {

        syslog(LOG_ERR, "Bogus PPPoE length field (%u)",

           (unsigned int) ntohs(packet.length));

        continue;

    }

导致无法解析PADO包,检查pppoe.h中HDR_SIZE定义:

#define PPPOE_OVERHEAD 6  /* type, code, session, length */

#define HDR_SIZE (sizeof(struct ethhdr) + PPPOE_OVERHEAD)

 

哈哈,找到原因,在arm中应该-2才对:

#define HDR_SIZE (sizeof(struct ethhdr)-2 + PPPOE_OVERHEAD)

编译运行:

--------------------------提示.Connected!成功!!!!!!
阅读(1995) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~