加载中…
个人资料
从入门到放弃
从入门到放弃
  • 博客等级:
  • 博客积分:0
  • 博客访问:494,076
  • 关注人气:57
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

嵌入式linux通过DHCP自动获取IP地址

(2016-05-06 16:42:17)
标签:

linux

dhcp

分类: Linux

虽然还不太懂,但先记录摸索过程,后续懂了再来完善。

1.编译内核选项  

在内核中添加以下选项:

Networking  --->

   [*] Networking support  

      Networking options  ---> 

          <* > Packet socket                   //添加.配置CONFIG_PACKET

          [ * ]     IP: DHCP support         //添加

          [ * ] Network packet filtering (replaces ipchains)  --->    //添加,后面子选项可不选,配置CONFIG_NETFILTER

说明:若没选<* > Packet socket, [ * ] Network packet filtering (replaces ipchains)  --->选项,在执行udhcpc命令时出现如下错误:

# udhcpc

udhcpc (v0.9.9-pre) started

udhcpc[208]: udhcpc (v0.9.9-pre) started

FATAL: couldn't listen on socket, Address family not supported by protocol

udhcpc[208]: FATAL: couldn't listen on socket, Address family not supported by protocol

2.编译udhcpc  

Busybox中添加以下选项:

Networking Utilities

--->

   udhcp Server/Client  --->

        [] udhcp Server (udhcpd)       //在此不作服务端,故不选。生成udhcpd命令                             

        [*] udhcp Client (udhcpc)       //生成udhcpc命令                               

        [ ] Lease display utility (dumpleases)                        

        [ ]   Log udhcp messages to syslog (instead of stdout)        

        [ ]   Compile udhcp with noisy debugging messages

busybox没编译相应选项,也可从网上下载相应文件,用arm-linux交叉编译得到udhcpd,udhcpc命令copyusr/sbin下就可以了。

我从 网上  下的udhcp_0.9.8cvs20050303.orig.tar.gz文件,解压后修改Makefile文件。在19行添加CROSS_COMPILE=arm-linux- ,注释12行的COMBINED_BINARY=1,否则不生成udhcpc命令。

3.建相关配置文件

在文件/usr/share/udhcpc/default.script下编写脚本程序

#!/bin/sh

exec run-parts -a "$1" /etc/udhcpc.d   //运行此目录下的所有程序

/etc/udhcpc.d/50default文件中编写如下代码:

#!/bin/sh

 

# udhcpc script edited by Tim Riker

 

[ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1

 

RESOLV_CONF="/etc/resolv.conf"

[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"

[ -n "$subnet" ] && NETMASK="netmask $subnet"

 

# return 0 if root is mounted on a network filesystem

root_is_nfs() {

        sed -n 's/^[^ ]* \([^ ]*\) \([^ ]*\) .*$/\1 \2/p' /proc/mounts |

        grep -q "^/ \(nfs\|smbfs\|ncp\|coda\)$"

}

 

have_bin_ip=0

if [ -x /sbin/ip ]; then

  have_bin_ip=1

fi

 

case "$1" in

        deconfig)

                if [ -x /sbin/resolvconf ]; then

                        /sbin/resolvconf -d "${interface}.udhcpc"

                fi

                if ! root_is_nfs ; then

                        if [ $have_bin_ip -eq 1 ]; then

                                ip addr flush dev $interface

                                ip link set dev $interface up

                        else

                                /sbin/ifconfig $interface 0.0.0.0

                        fi

                fi

                ;;

 

        renew|bound)

                if [ $have_bin_ip -eq 1 ]; then

                        ip addr add dev $interface local $ip/$mask $BROADCAST

                else

                        /sbin/ifconfig $interface $ip $BROADCAST $NETMASK

                fi

 

                if [ -n "$router" ] ; then

                        if ! root_is_nfs ; then

                                if [ $have_bin_ip -eq 1 ]; then

                                        while ip route del default 2>/dev/null ; do

                                                :

                                        done

                                else

                                        while route del default gw 0.0.0.0 dev $interface 2>/dev/null ; do

                                                :

                                        done

                                fi

                        fi

 

                        metric=0

                        for i in $router ; do

                                if [ $have_bin_ip -eq 1 ]; then

                                        ip route add default via $i metric $metric

                                else

                                        route add default gw $i dev $interface metric $metric 2>/dev/null

                                fi

                                metric=$(($metric + 1))

                        done

                fi

 

                # Update resolver configuration file

                R=""

                [ -n "$domain" ] && R="domain $domain"

                for i in $dns; do

                        echo "$0: Adding DNS $i"

                        R="${R}nameserver $i"

                done

 

                if [ -x /sbin/resolvconf ]; then

                        echo -n "$R" | /sbin/resolvconf -a "${interface}.udhcpc"

                else

                        echo -n "$R" > "$RESOLV_CONF"

                fi

                ;;

esac

 

exit 0

 

4/etc/rc5.d中有一个关于网络的启动文件,当嵌入式Linux启动时会进入rc5.d文件执行(因为inittab文件中The default runlevel=5)。其中网络启动脚本S01networking如下:

 

root@am335x-evm:/etc/rc5.d# cat S01networking

#!/bin/sh

#

### BEGIN INIT INFO

# Provides:          networking

# Required-Start:    $local_fs mountvirtfs

# Required-Stop:     $local_fs

# Default-Start:     S

# Default-Stop:      0 6

# Short-Description: Raise network interfaces and configure them

### END INIT INFO

 

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

 

if ! [ -x /sbin/ifup ]; then

    exit 0

fi

 

case "$1" in

    start)

        if sed -n 's/^[^ ]* \([^ ]*\) \([^ ]*\) .*$/\1 \2/p' /proc/mounts |

          grep -q "^/ nfs$"; then

            echo "NOT configuring network interfaces: / is an NFS mount"

        elif sed -n 's/^[^ ]* \([^ ]*\) \([^ ]*\) .*$/\1 \2/p' /proc/mounts |

          grep -q "^/ smbfs$"; then

            echo "NOT configuring network interfaces: / is an SMB mount"

        elif sed -n 's/^[^ ]* \([^ ]*\) \([^ ]*\) .*$/\2/p' /proc/mounts |

          grep -qE '^(nfs|smbfs|ncp|coda)$'; then

            echo "NOT configuring network interfaces: network shares still mounted."

        else

            echo -n "Configuring network interfaces... "

            ifup -a

            echo "done."

      fi

        ;;

    stop)

        if sed -n 's/^[^ ]* \([^ ]*\) \([^ ]*\) .*$/\1 \2/p' /proc/mounts |

          grep -q "^/ nfs$"; then

            echo "NOT deconfiguring network interfaces: / is an NFS mount"

        elif sed -n 's/^[^ ]* \([^ ]*\) \([^ ]*\) .*$/\1 \2/p' /proc/mounts |

          grep -q "^/ smbfs$"; then

            echo "NOT deconfiguring network interfaces: / is an SMB mount"

        elif sed -n 's/^[^ ]* \([^ ]*\) \([^ ]*\) .*$/\2/p' /proc/mounts |

          grep -qE '^(nfs|smbfs|ncp|coda)$'; then

            echo "NOT deconfiguring network interfaces: network shares still mounted."

        else

            echo -n "Deconfiguring network interfaces... "

            ifdown -a

            echo "done."

        fi

        ;;

    force-reload|restart)

        echo -n "Reconfiguring network interfaces... "

        ifdown -a

        ifup -a

        echo "done."

        ;;

    *)

        echo "Usage: /etc/init.d/networking {start|stop|restart|force-reload}"

        exit 1

        ;;

esac

 

exit 0

执行此脚本和执行 /etc/init.d/networking是一样的,包括start|stop|restart|force-reload

其中,ifup -a 会执行/etc/network/interfaces程序(If given to ifup, affect all interfaces marked auto. Interfaces are brought up in the order in which they are defined in /etc/network/interfaces.  http://www.computerhope.com/unix/ifup.htm)。

 

/etc/network/interfaces下的程序如下所示,应该是声明和启动各种类型的网卡。我这里使用eth0,初始声明为静态static,后面根据配置参数在选择是动态分配dhcp还是静态分配static

root@am335x-evm:/etc/rc5.d# cat /etc/network/interfaces

# /etc/network/interfaces -- configuration file for ifup(8), ifdown(8)

 

# The loopback interface

auto lo

iface lo inet loopback

 

# Wireless interfaces

iface wlan0 inet dhcp

        wireless_mode managed

        wireless_essid any

        wpa-driver wext

        wpa-conf /etc/wpa_supplicant.conf

 

iface tiwlan0 inet dhcp

        wireless_mode managed

        wireless_essid any

 

iface atml0 inet dhcp

 

# Wired or wireless interfaces

auto eth0

iface eth0 inet static

       pre-up /bin/grep -v -e "ip=[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+" /proc/cmdline > /dev/null

 

iface eth1 inet dhcp

 

# Ethernet/RNDIS gadget (g_ether)

# ... or on host side, usbnet and random hwaddr

iface usb0 inet dhcp

 

# Bluetooth networking

iface bnep0 inet dhcp

 

#dns-nameservers 114.114.114.114 8.8.8.8

可直接在此文件中配置动态分配dhcp和静态分配static,以及DNS等。配置方法如下:

http://os.51cto.com/art/201003/186914.htm

Ø  DHCP方式配置网卡

auto eth0
iface eth0 inet dhcp

Ø  为网卡配置静态IP地址

auto eth0  

iface eth0 inet static  

address 192.168.3.90  

gateway 192.168.3.1  

netmask 255.255.255.0  

#network 192.168.3.0  

#broadcast 192.168.3.255

 

我根据用户配置文件来选择动态还是静态,当选择动态dhcp分配时,使用如下命令:

root@am335x-evm:/etc/rc5.d# udhcpc -b -i eth0 -p /var/run/udhcpc.Rpid

udhcpc (v1.22.1) started

Sending discover...

Sending select for 188.188.181.175...

Lease of 188.188.181.175 obtained, lease time 86400

/etc/udhcpc.d/50default: Adding DNS 202.96.209.5

/etc/udhcpc.d/50default: Adding DNS 202.96.209.133

注:解释一下,-b就是切换到后台指令,-i是指定使用哪个网络接口,双网卡的时候一定要使用它来指定eth0  or  eth1

 

udhcpc -R -q 退出DHCP并且释放IP地址

root@am335x-evm:/etc/rc5.d# udhcpc -R -q

udhcpc (v1.22.1) started

Sending discover...

Sending select for 188.188.181.175...

Lease of 188.188.181.175 obtained, lease time 86400

/etc/udhcpc.d/50default: Adding DNS 202.96.209.5

/etc/udhcpc.d/50default: Adding DNS 202.96.209.133

Unicasting a release of 188.188.181.175 to 188.188.181.1

Sending release...

Entering released state

 

系统启动后,当用户选择静态分配IP时,使用ifconfigroute来设置IP地址、掩码地址和网关地址,并在/etc/resolv.conf文件中写入dns解析地址,这样就可以ping通百度了。

echo nameserver 114.114.114.114 > /etc/resolv.conf

echo nameserver 8.8.8.8 >> /etc/resolv.conf

ifconfig eth0 $gateway_ip netmask $gateway_mk

route add default gw $gateway_gw

 

参考文章:

http://os.51cto.com/art/201003/186914.htm

http://blog.csdn.net/zhangboyj/article/details/6154846

http://blog.csdn.net/hshl1214/article/details/8684740

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有