⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ethernet-howto-3.html

📁 Linux初学者最好的老师就是howto了。相当于函数man。
💻 HTML
📖 第 1 页 / 共 4 页
字号:
<P><P>全双工能达到20MBps吗?Linux支持吗?<P>Cameron Spitzer对全双工10Base-T网卡有如下论断:“如果你连在全双工交换HUB上,你的系统足够快而且不做太多其它的工作,它会使你的网络在两个方向上都保持忙碌。不存在什么全双工的10BASE-2或10BASE-5(细缆和粗缆)。全双工是通过取消适配器的碰撞检测来达到的。这就是为什么用同轴电缆实现不了全双工;LAN无法以全双工方式运转。10BASE-T(RJ45接口)使用不同的线进行发送和接收,所以二者可能同时进行。交换HUB处理碰撞问题。信号速率是10Mbps。”<P>所以,你只能以10Mbps速率接收或发送数据,无法期望得到两倍的性能提高。对于是否支持,取决于网卡和可能的驱动程序。有些网卡可以自动协商,有些需要驱动程序支持,还有的需要用户在网卡的EEPROM配置中设置选项。只有那些认真的用户会注意到全双工与半双工模式间的差别。<P><H3>SMP机器上的Linux以太网卡</H3><P><P>如果你有钱买多处理器(MP)的计算机,那么最好买一个好点儿的以太网卡。对v2.0内核这还不是个问题,但对v2.2就成问题了。大多数老式的非智能(如ISA总线的PIO和共享内存设计)网卡在设计时根本没考虑多处理器应用。简单地说就是买一个现代设计的智能网卡,并确定有能够处理多处理器操作的驱动程序。(注意这里的“现代设计” - PCI-NE2000就是在现代总线上有10多年历史的老式设计。)在驱动程序的源码里查找<CODE>spin_lock</CODE>可以很好地说明该驱动程序是否能够处理多处理器操作。下面详细解释了为何要为多处理器应用购买好的网卡(以及不买会出现什么问题)。<P>在v2.0内核,在任意时刻只有一个处理器允许进入“内核态”(即改变内核数据或运行设备驱动程序)。所以从网卡(及相关驱动程序)的角度来看,这与单处理器操作没有什么不同,所以不会出问题。(这也是得到一个可以工作的Linux多处理器版本的最简单的办法 -- 使用一个大锁使得一次只有一个处理器处于内核状态。这样你就知道不可能有两个处理器同时要修改同一数据!)<P>在任意时刻只有一个处理器允许进入内核态的不利之处在于只有运行自我控制和密集计算的程序时才会获得多处理器的优越性。如果程序进行了大量诸如向磁盘或网络读/写数据的I/O操作,在处于内核的那个处理器努力运行所有的设备驱动程序以满足I/O请求的同时,其它的处理器都必须等待自己的I/O请求被处理完成。这样内核就成为了瓶颈,由于只有一个处理器运行在内核态,多处理器机器的性能在I/O任务重、单锁的情况下迅速降级到接近单处理器的水平。<P>很明显这与理想情况相差太远(尤其是对于文件/WWW服务器、路由器等),v2.2的内核就使用了粒度更小的锁——也就是说同时可以有多个处理器进入内核。不再是对整个内核使用一个大锁,而是使用许多较小的锁保护关键数据,防止同时被多个处理器控制——例如,一个处理器可以运行网卡驱动程序,同时另一个处理器可以运行磁盘驱动器的驱动程序。<P>好的,这样就有问题了:更小的锁定就意味著可以有一个处理器试图通过以太网驱动程序发送数据,同时另一个处理器试图访问同一个驱动程序/网卡来做别的事情(比如通过<CODE>cat /proc/net/dev</CODE>得到网卡统计数据)。哎呦——你的网卡正在通过网线发数据,你又要用它来收数据。网卡被同时要求做两件事(或更多),会弄糊涂的,所以有可能在处理过程中网卡使你的机器死机。<P>因此,为单处理器写的驱动程序不再适用——它需要更新控制对网卡访问的锁,使得网卡的接收、发送和操作配置数据这三种任务以网卡稳定操作所要求的程度串行化起来。没有更新为使用稳定多处理器操作的锁的驱动程序在轻的网络负载下可能看起来会正常工作,但在两个(或更多)处理器试图同时进行多个任务时就会造成死机,或至少表现出奇怪的行为,这就是问题。<P>更新后的意识到多处理器的以太网驱动程序将要求一个驱动程序范围的锁,使得内核进入驱动程序的访问入口被限制为一次一个。这样,任务就被串行化,而对硬件的处理就如同在单处理器下一样,也就一定应当稳定。使用驱动程序范围的锁的不利之处在于它类似于对整个内核加锁(但规模较小)对性能的影响——也就是说,一次只可以有一个处理器处理网卡。[技术提示:如果增加的锁是<CODE>irqsave</CODE>类型的而且被持有较长时间,对性能的影响还包括增加了中断延迟。]<P>这里可以进行的改进有两处。可以尝试减少获得与释放锁之间所用的时间,或者在驱动程序内部实现更为细化的锁(比如满足网卡需求的前提下,把整个驱动程序的锁替换为若干保护同时访问若干敏感寄存器或设置的锁)。<P>但是,对于老式的非智能网卡而言,在设计时根本就没有考虑过多处理器的应用,这样的改进可能无法实现。更糟的是非智能网卡一般要求处理器在网卡和内存之间传送数据,所以在最坏的情况下,每当在ISA总线传送1.5kB数据包时,锁都被一直保持著。<P>现代的智能网卡一般无需处理器的帮助就可以直接在网卡和内存之间传递网络数据。这是个很大的改进,因为只需要在处理器通知网卡使用哪一块内存保存下一个网络数据包的那一小段时间持有锁。现代的网卡在设计时同样也不要求对整个驱动程序使用一个大锁。<P><P><P><H3>Alpha/AXP的PCI板上的Linux以太网卡</H3><P><P>对于v2.0,只有3c509、depca、de4x5、pcnet32和所有8390驱动程序(wd、smc-ultra、ne、3c503等等)是编写成“结构无关”的,所以它们可以运行在基于DEC的Alpha CPU系统上。其它一些从Donald的WWW主页上下载的更新过的PCI驱动程序也可以工作,因为它们也是按照结构无关的思想编写的。<P>注意,使驱动程序与结构无关所需要进行的改动并不很复杂。只需要如下进行:<P>--把所有与<CODE>jiffies</CODE>有关的值都乘以HZ/100,得到Alpha使用的不同的HZ值。(即<CODE>timeout=2;</CODE>变成<CODE>timeout=2*HZ/100;</CODE>)<P>--把所有I/O内存(从640k到1MB)的指针引用替换为相应的readb() writeb() readl() writel()调用,如下例所示。<P><HR><PRE>-       int *mem_base = (int *)dev->mem_start;-       mem_base[0] = 0xba5eba5e;+       unsigned long mem_base = dev->mem_start;+       writel(0xba5eba5e, mem_base);</PRE><HR><P>--把所有使用I/O内存作为源或目的地址的memcpy()调用替换为相应的<CODE>memcpy_fromio()</CODE>或者<CODE>memcpy_toio()</CODE>调用。<P>以结构无关的方式处理内存访问的细节在近期的内核所附的文件<CODE>linux/Documentation/IO-mapping.txt</CODE>中进行了说明。<P><H3>SUN/Sparc硬件上的Linux以太网卡。</H3><P>要得到最新的Sparc信息,可以访问以下URL:<P><A HREF="javascript:if(confirm('http://www.geog.ubc.ca/sparc  \n\nThis file was not retrieved by Teleport Pro, because it is addressed on a domain or path outside the boundaries set for its Starting Address.  \n\nDo you want to open it from the server?'))window.location='http://www.geog.ubc.ca/sparc'" tppabs="http://www.geog.ubc.ca/sparc">Linux Sparc</A><P>注意,有些Sparc的以太网硬件从主机获得其MAC地址,因此可能会有多个接口具有相同的MAC地址。如果想在同一个网络上使用多个接口,可以使用<CODE>ifconfig</CODE>的<CODE>hw</CODE>选项以分配唯一的MAC地址。<P>把PCI驱动程序移植到Sparc平台上与上面提到的AXP平台相似。可能的差异出在endian上,因为Sparc是big endian,而AXP和ix86是little endian。<P><H3>其它硬件上的Linux以太网卡。</H3><P>还有一些其它硬件平台可以运行Linux,比如Atari/Amiga(m68k)。就象Sparc一样,最好是访问每个Linux支持的平台主页,以了解当前都支持哪些硬件。(欢迎提供这样的站点连接——把它们发给我!)<P><H3>不使用Hub连接10/100BaseT</H3><P>可以不使用Hub连接基于10/100BaseT(RJ45)的系统吗?<P>如果不使用额外的设备或机械装置,可以很容易地连接两台这样的机器,但不可能再多。参阅<A HREF="Ethernet-HOWTO-6.html#utp" tppabs="http://www.linux.org.tw/CLDP/gb/Ethernet-HOWTO-6.html#utp">双绞线</A>——解释了如何做到这一点。而且你不可能简单地交叉几根线或其它什么就弄出一个Hub,不复制Hub也无法正确完成冲突信号。<P><H3>SIOCSIFxxx: No such device</H3><P>在启动时出现了一大堆“SIOCSIFxxx: No such device”信息,后面还有一条“SIOCADDRT: Network is unreachable”,怎么回事?<P>你的以太网设备在启动/插入模块时没有被检测到,当<CODE>ifconfig</CODE>和<CODE>route</CODE>运行时,它们没有可用的设备。使用<CODE>dmesg | more</CODE>来浏览启动信息,看看有没有检测以太网卡的信息。<P><H3>SIOCSFFLAGS: Try again</H3><P>在运行“ifconfig”时出现“SIOCSFFLAGS: Try again”——怎么回事?<P>某些其它的设备使用了以太网卡想用的IRQ,所以以太网卡无法使用该IRQ。你不必重新启动来解决这个问题,因为某些设备只是在需要时才获取IRQ,在完成后就释放了。例如某些声卡、串口、软盘驱动器等。你可以键入<CODE>cat /proc/interrupts</CODE>来看看哪些中断正在 <EM>被使用</EM>。绝大多数Linux以太网卡驱动程序只有在用“ifconfig”打开时才获取IRQ。如果你能让其它设备“放开”所需的IRQ中断线,那么你就可以用ifconfig来“再试一下”了。<P><H3>使用“ifconfig”得到的连接为UNSPEC,而硬件地址是00:00:00:00:00:00</H3><P>在不带参数运行ifconfig时,报告说连接为UNSPEC(而不是10Mbs以太网),而且硬件地址都是零。<P>这是因为运行的“ifconfig”程序版本比内核的版本高。在与老版本的内核一起运行时,新版本的ifconfig无法报告这些特性。你可以升级内核,或者“降级”ifconfig,或者干脆不理会这个错误。内核知道硬件地址,所以即使ifconfig无法读出它也没有关系。<P>如果使用的<CODE>ifconfig</CODE>程序比使用的内核旧很多的话,也会出现一些奇怪的信息。<P><H3>大量的RX和TX错误</H3><P>在不带参数运行ifconfig时,报告大量的接收和发送数据包错误。但看起来工作正常——怎么回事?<P>再看一遍。报告是说<CODE>RX packets</CODE> <EM>big number</EM> <B>停顿</B><CODE>errors 0</CODE> <B>停顿</B> <CODE>dropped 0</CODE> <B>停顿</B> <CODE>overrun 0</CODE>。所以你看到的那个大数字是机器接收和发送的数据包总数。如果还觉得不可思议,键入<CODE>cat /proc/net/dev</CODE>看看。<P><H3><CODE>/dev/</CODE>下的以太网卡入口</H3><P>/dev/eth0象是个到/dev/xxx的连接。这样对吗?<P>与你听过的正好相反,/dev/*下的文件没被使用。你可以删除掉任何<CODE>/dev/wd0、/dev/ne0</CODE>以及类似的入口。<P><H3>Linux与“trailers”</H3><P>在“ifconfig”网卡时,需要禁止trailers吗?<P>不能禁止trailers,而且也没必要。“trailers”是避免在网络层复制数据的工具。其想法是使用一个大小为“H”的固定大小的头,把可变大小的头信息放在包的尾部,并把所有包定位在页开始之前的“H”字节。这只是个好想法,在实际中工作得并不好。如果有人建议使用“-trailers”,那不过是找个替罪羊罢了。这对解决问题没有任何意义,但如果问题真的自行解决了,那么他就可以吹嘘自己的神奇本领了。<P><P><H3>访问原始以太网设备</H3><P>在Linux下怎样不通过TCP/IP之类的东西访问原始的以太网设备?<P><HR><PRE>        int s=socket(AF_INET,SOCK_PACKET,htons(ETH_P_ALL));</PRE><HR><P>这样就可以得到一个接收所有协议类型的socket。对它执行<CODE>recvfrom()</CODE>调用,它就会用sa_family里的设备类型和sa_data数组里的设备名来填充sockaddr。我不知道是谁最早在Linux里使用SOCK_PACKET,但它确实是个非常好的东西。你也可以通过<CODE>sendto()</CODE>调用发送原始数据包。当然,在这样做时你必须拥有root的权限。<P><HR><A HREF="Ethernet-HOWTO-4.html" tppabs="http://www.linux.org.tw/CLDP/gb/Ethernet-HOWTO-4.html"><IMG SRC="next.gif" tppabs="http://www.linux.org.tw/CLDP/gb/img/next.gif" ALT="Next"></A><A HREF="Ethernet-HOWTO-2.html" tppabs="http://www.linux.org.tw/CLDP/gb/Ethernet-HOWTO-2.html"><IMG SRC="prev.gif" tppabs="http://www.linux.org.tw/CLDP/gb/img/prev.gif" ALT="Previous"></A><A HREF="Ethernet-HOWTO.html#toc3" tppabs="http://www.linux.org.tw/CLDP/gb/Ethernet-HOWTO.html#toc3"><IMG SRC="toc.gif" tppabs="http://www.linux.org.tw/CLDP/gb/img/toc.gif" ALT="Contents"></A>  </BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -