1、嵌入式系统的以太网接口设计及 linux驱动1 以太网概述以太网(Ethernet)是当今局域网采用的最通用的通信协议标准。在以太网中,所有计算机被连接在一条电缆上,采用带冲突检测的载波侦听多路访问(CSMA/CD)方法,采用竞争机制和总线拓扑结构。基本上,以太网由共享传输媒体,如双绞线电缆或同轴电缆、多端口集线器、网桥或交换机构成。按照 OSI(Open System Interconnection Reference Model,开放式系统互联参考模型)7 层参考模型,以太网定义的是物理层(PHY)和数据链路层(对应以太网的 MAC层)的标准。2 嵌入式处理器上扩展以太网接口以太网接口控制
2、器主要包括 MAC乘 PHY两部分,如图 1所示为嵌入式处理器集成 MAC层控制器。MAC 层控制器和 PHY的连接是通过 MII、RMII 等接口实现的。在 IEEE802的标准系列中,数据链路层包括 LLC和 MAC两个子层。其中 MAC负责完成数据帧的封装、解封、发送和接受功能。PHY 层的结构随着传输速率的不同而有一定的差异。对于 1OBaseT等网络,从以太网 PHY芯片输出的就是传输所需的差分信号。但是还需要一个 网络隔离变压器组成图 2的结构。网络隔离变压器可起到抑制共模干扰、隔离线路以及 阻抗匹配等作用。本文介绍一种新款网络接口芯片 DM9000A,它可以很方便的实现与嵌入式C
3、PU的接口,实现扩展以太网口的功能。DM9000A 是中国台湾 DAVICOM公司推出的一款高速以太网接口芯片,其基本特征是:集成 10/100M物理层接口;内部带有 16K字节 SRAM用作接收发送的 FIFO缓存;支持 8/16bit两种主机工作模式:通过 HP认证的 AUTO-Mdix(支持直接互连自动翻转)功能;支持 TCP/IP加速,减轻 CPU负担,提高整机效能;10ns I/O 读写时间。DM9000A 以太网控制器遵循 IEEE颁布的 802.3以太网传输协议。该电路还集成了 EEPROM接口,自举时通过 EEPROM接口输入到芯片中,从而实现自动初始化。芯片和处理器的连接原理
4、图就不列图表示了,处理器这里选择AT91RM9200,DM9000A 与处理器连接时要注意:总线宽度读/写等待周期、时序匹配问题CS8900A 芯片复位后,在总线上的默认地址如何配置与保存默认的中断号及中断触发模式问题(上升沿,还是下降沿;低电平,还是高电平触发)系统上电时,AT91RM9200 通过总线配置 DM9000A内部网络控制寄存器(NCR)、中断寄存器(ISR)等,完成 DM9000A的初始化。随后,DM9000A 进入数据收发等待状态。当 AT91RM9200向以太网发送数据时,先将数据打包成 UDP或 IP数据包,并通过 16 bit总线发送到 DM9000A的数据发送缓存中,
5、然后将数据长度等信息填充到 DM9000A的相应寄存器内,使能发送。当 DM9000A接收到外部网络送来的以太网数据时,首先检测数据帧的合法性,如果帧头标志有误或存在CRC校验错误,则将该帧数据丢弃。否则将数据帧缓存到内部 RAM,并通过中断标志位通知 AT91RM9200,由 AT91RM9200对 DM9000A接收到的数据进行处理。3 linux 网络驱动程序3.1 Linux 网络驱动程序体系结构Linux 的网络系统主要是基于 BSD UNIX的套接字(socket)机制。在系统和驱动程序之间定义有专门的数据结构(sk_buff)进行数据传输。系统支持对发送数据缓存,提供流量控制机制
6、,提供对多协议的支持。Linux 网络驱动程序的体系结构可划分为图 2所示的 4个层次.Linux 内核中提供了网络设备接口及以上层次的代码,所以移植(或编写)特定网络硬件的驱动程序最主要的工作就是完成设备驱动功能层,主要是包括数据的接收,发送等控制。Linux 中所有的网络设备都抽象为一个接口,有结构体 struct net_device来表示网络设备在内核中的运行情况,即网络设备接口,此结构体位于网络驱动层的核心地位。net_device 中有很多供系访问和协议层调用的设备方法。网络驱动就是要实现这些具体的设备方法。3.2 网络设备的初始化由结构体 net_device中的 init函数指
7、针所指向的初始化函数来完成。网络的初始化是设备工作的第一步。当系统加载网络驱动模块的时候,就会调用初始化过程。首先利用函数:request_mem_region 映射 DM9000A的数据、地址端口,通过 dmfe_probe函数检测网络物理设备是否存在,检测 DM9000A内部串行 NIC的值是否正确,然后再对设备进行资源配置,构造设备的 net_device数据结构。包括一些低层硬件信息:base_addr(网络接口的 I/O基地址),irq(安排的中断号)等。3.3 打开设备和关闭设备 open 方法在网络设备被激活的时被调用,具体 DM9000A的硬件初始化工作放到这里来做。对于 DM
8、OOOOA需要完成的初始化包括:对 DM9000A内部上电,软件复位,通过 NCR寄存器设置网络工作模式,可以选择设置内部或者外部PHY、全双工或者半双工模式、使能唤醒事件等网络操作,对 RX/TX中断使能,使能数据接收功能。调用 request_jrq()申请中断号登记中断处理函数,调用netif_carrier_on侦测连接状态。启动定时器,调用 netif_start_queue激活设备发送队列。 这里对 DM9000A的中断设计做了一个特殊处理:通常 AT91RM9200提供最多32个中断源,默认提供 7个外部中断源,但对于较复杂的嵌入式系统,可能会面临中断源不够用的情况。由于 AT9
9、lRM9200的 PIO可以实现功能复用,因此可以把多余的 IO引脚配置为可用的中断源。故本系统中,设计 DM9000A中断源与AT91RM9200外部 I/O口 PD8引脚相连。一个 PIO端口的 32个引脚共享一个中断 ID,只需要在中断状态寄存器中区分具体哪个引脚引起中断,然后转向特定的中断处理函数执行操作,就可以实现中断处理。close 所做的工作和 open相反,主要释放 open获得的资源,以减少系统负担。3.4 数据包发送数据包的发送和接收是实现 Linux网络驱动程序中两个最关键的过程,对这两个过程处理的好坏将直接影响到驱动程序的整体运行质量。数据传输通过 hard_start
10、_xmit函数实现,首先把存放在套接字缓冲区中的数据发送到网络芯片 DM9000A内部的 TX FIFO SRAM中,该缓冲区是由数据结构 sk buff表示,把要传送的数据长度写入 DM9000A中的传输包长度寄存器TXPLL和 TXPLH中。然后使能传输。如果数据发送成功,则会触发一次中断。实际中会出现多个数据帧传输,需要考虑做并发处理。在发送时检测传输队例暂时满载时就要通过 netif_stop_queue来暂停,当发送完成触发中断处理时,调用 netif_wake_queue函数来重新启动传输队例。网络传输由于系统忙或硬件的问题发生延迟,则会调用传送超时处理函数 tx_timeout,
11、对硬件复位操作。3.5 数据包接收 数据包的接收是通过中断处理,当有数据到达时,就产生中断信号,网络设备驱动功能层就调用数据包接收程序来处理数据包的接收,然后网络协议接口层调用 netif_rx函数把接收到的数据包传输到网络协议的上层进行处理。 DM9000A 接收缓存区中的每帧数据由 4字节长的首部、有效数据和 CRC校验序列构成。首部 4字节依次是 01H、以太网帧状态、以太网帧长度低字节和长度高字节,数据包接收程序首先检测如果第一个字节是 01H,则说明有数据;如果是 00H,则说明无数据,需要进行复位。然后调用函数 dev_alloc_skb申请一块 sK_buff结构缓冲区,从 DM
12、9000A读出数据放置到缓冲区里,根据获取的长度信息,判断是否读完一帧。如果读完,接着读下一帧,直到遇到首字节是 00H的帧,说明接收数据已读完。接下来填充 sK_buff中的一些信息,使之成为规范的 sk_buff结构,最后调用 netif_rx()函数将接收到的数据传输到网络协议的上层。 最后,可通过两种方法加载网络设备驱动程序:系统内核加载和模块加载。4 网络的应用及测试 通过读取procnet 中的信息得到当前系统中的网络设备,通过它来测试: #catprocnetdev Linux 网络配置可在应用程序中通过 ifconfig和 router两个命令实现,它们都可以在 busybox
13、软件包中找到。可用以下命令来配置 ip、网关、子网掩码和域名解析服务器: # ifconfig eth0 192.168.0.11O # route add -net default gw 192.168.0.254 netmask 255.255.255.0 # nameserver 202.106.196.115 最后,通过 Ping命令,来测试一下和主机的通信是否联通。在本系统中通过。在嵌入式应用程序开发及调试中,NFS 起着非常重要的应用。不但可以通过 NFS文件系统共享远程硬盘的文件,我们还可以 mount远程文件系统直接作为嵌入式的根文件系统。 5 结论 本文完成了 Linux下扩
14、展以太网接口及测试网络接口的研究,采用了以太网芯片 DM9000,围绕太分析了嵌入式 Linux 网络的基本原理。最后我的嵌入式设备顺利连上网络。同时本文为移植 2.6内核的网络部分提供了移植方法。 浅谈 Linux 内核开发之网络设备驱动赵 昊翔, 软件工程师, Cisco Systems简介: 本文介绍了网络设备的基本概念,并从 Linux 内核的角度出发,介绍了网络设备驱动的开发方法和开发中的注意事项。网络设备介绍网络设备是计算机体系结构中必不可少的一部分,处理器如果想与外界通信,通常都会选择网络设备作为通信接口。众所周知,在 OSI(Open Systems Interconnecti
15、on,开放网际互连)中,网络被划分为七个层次,从下到上分别是物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。我们所讲的网络设备也包括两个层次,一层叫做 MAC(Media Access Control)层,对应于 OSI 的数据链路层;另一层叫做 PHY( Physical Layer)层,对应于物理层。常用的网络设备有很多,比如 PPC85XX 的 TSEC、AMCC 440GX 的 EMAC、INTEL 的 82559 等,它们的工作原理基本相同。DMA 介绍网络设备的核心处理模块是一个被称作 DMA(Direct Memory Access)的控制器,DMA 模块能够协助处理
16、器处理数据收发。对于数据发送来说,它能够将组织好的数据自动发出,无需处理器干预;对于数据接收来说,它能够将收到的数据以一定的格式组织起来,通知处理器,并等待处理器来取。DMA 模块收发数据的单元被称为 BD(Buffer Description,缓存描述符),每个包都会被分成若干个帧,而每个帧则被保存在一个 BD 中。BD 结构通常包含有以下字段:typedef struct void *bufptr; /* 保存当前 BD 对应缓存的起始地址 */ int length; /* 保存缓存中存储的数据包长度 */ int sc; /* 保存当前 BD 的状态信息 */ BD_STRUCT; 所
17、有的 BD 就组成了一张 BD 表,如图 1 所示,一般来说发送方向和接收方向的 BD 表是各自独立的。图 1. BD 表结构数据发送流程网络设备通过 DMA 进行数据发送的流程如 图 2 所示。图 2. 数据发送流程图中各步骤的具体含义描述如下:(1)协议层通知处理器开始发送数据;(2)处理器从 BD 表中取出一个 BD,将需要发送的数据拷贝至当前 BD 对应的缓存内,并设置好 BD 的状态;(3)处理器通知网络设备开始发送数据;(4) MAC 模块通知 DMA 单元开始发送数据;(5) DMA 模块操作 BD 表,取出当前有效 BD;(6) DMA 模块将当前 BD 对应缓存内的数据发送至
18、 MAC 模块;(7) MAC 模块将这些数据发送到网络中;(8)网络设备通知处理器数据发送完毕;(9)处理器通知协议层发送下面一帧数据。其中步骤(4)(8)是硬件自动完成的,不需要软件的干预,如此可以节省处理器的工作量。数据接收流程网络设备通过 DMA 进行数据接收的流程如图 3 所示。图 3. 数据接收流程图中各步骤的具体含义描述如下:(1)处理器初始化 BD 表;(2)处理器初始化网络设备;(3) MAC 模块从网络中接收数据;(4) MAC 模块通知 DMA 模块来取数据;(5) DMA 模块从 BD 表中取出合适的 BD;(6) MAC 模块将数据发送至当前 BD 对应的缓存内;(7
19、)网络设备通知处理器开始接收数据(以中断方式或轮询方式);(8)协议层从当前的 BD 缓存内取走数据。其中步骤(3)(6)是硬件自动完成的,不需要软件的干预,如此可以节省处理器的工作量。回页首Linux 网络设备驱动模型数据结构数据结构Linux 内核中对网络设备进行描述的核心结构类型叫做 net_device,net_device 结构定义在 include/linux/netdevice.h 文件中。该结构的字段可以分为以下几类。全局信息该类中包含了设备名(name 字段)、设备状态(state 字段)、设备初始化函数(init 字段)等。硬件信息该类中包含了设备内存使用情况(mem_en
20、d 和 mem_start 字段)、中断号(irq 字段)、IO 基地址(base_addr 字段)等。接口信息该类中包含了 MAC 地址(dev_addr 字段)、设备属性(flag 字段)、最大传输单元( mtu 字段)等。设备接口函数该类中包含了当前设备所提供的所有接口函数,比如设备打开函数(open 字段),该函数负责打开设备接口,当用户使用 ifconfig 命令配置网络时,该函数默认被调用;设备停止函数(stop 字段),该函数负责关闭设备接口;数据发送函数(hard_start_xmit 字段),当用户调用 socket 开始写数据时,该函数被调用,并负责往网络设备中发送数据。函
21、数接口设备初始化函数网络设备驱动在 Linux 内核中是以内核模块的形式存在的,对应于模块的初始化,需要提供一个初始化函数来初始化网络设备的硬件寄存器、配置 DMA 以及初始化相关内核变量等。设备初始化函数在内核模块被加载时调用,它的函数形式如下:static int _init xx_init (void) module_init(xx_init); / 这句话表明模块加载时自动调用 xx_init 函数设备初始化函数主要完成以下功能:1. 硬件初始化因为网络设备主要分为 PHY、MAC 和 DMA 三个硬件模块,开发者需要分别对这三个模块进行初始化。1. 初始化 PHY 模块,包括设置双工
22、 / 半双工运行模式、设备运行速率和自协商模式等。2. 初始化 MAC 模块,包括设置设备接口模式等。3. 初始化 DMA 模块,包括建立 BD 表、设置 BD 属性以及给 BD 分配缓存等。2. 内核变量初始化初始化并注册内核设备。内核设备是属性为 net_device 的一个变量,开发者需要申请该变量对应的空间(通过 alloc_netdev 函数)、设置变量参数、挂接接口函数以及注册设备(通过 register_netdev 函数)。常用的挂接接口函数如下:net_device *dev_p; dev_p-open = xx_open; / 设备打开函数dev_p-stop = xx_s
23、top; / 设备停止函数dev_p-hard_start_xmit = xx_tx; / 数据发送函数dev_p-do_ioctl = xx_ioctl; / 其它的控制函数数据收发函数数据的接收和发送是网络设备驱动最重要的部分,对于用户来说,他们无需了解当前系统使用了什么网络设备、网络设备收发如何进行等,所有的这些细节对于用户都是屏蔽的。Linux 使用 socket 做为连接用户和网络设备的一个桥梁。用户可以通过 read / write 等函数操作 socket,然后通过 socket 与具体的网络设备进行交互,从而进行实际的数据收发工作。Linux 提供了一个被称为 sk_buff
24、的数据接口类型,用户传给 socket 的数据首先会保存在 sk_buff 对应的缓冲区中,sk_buff 的结构定义在 include/linux/skbuff.h 文件中。它保存数据包的结构示意图如下所示。图 4. sk_buff 数据结构图1. 数据发送流程当用户调用 socket 开始发送数据时,数据被储存到了 sk_buff 类型的缓存中,网络设备的发送函数(设备初始化函数中注册的 hard_start_xmit)也随之被调用,流程图如下所示。图 5. 数据发送流程图a. 用户首先创建一个 socket,然后调用 write 之类的写函数通过 socket 访问网络设备,同时将数据保
25、存在 sk_buff 类型的缓冲区中。b. socket 接口调用网络设备发送函数(hard_start_xmit),hard_start_xmit 已经在初始化过程中被挂接成类似于 xx_tx 的具体的发送函数,xx_tx 主要实现如下步骤。1. 从发送 BD 表中取出一个空闲的 BD。2. 根据 sk_buff 中保存的数据修改 BD 的属性,一个是数据长度,另一个是数据包缓存指针。值得注意的是,数据包缓存指针对应的必须是物理地址,这是因为 DMA 在获取 BD 中对应的数据时只能识别储存该数据缓存的物理地址。bd_p-length = skb_p-len; bd_p-bufptr = v
26、irt_to_phys(skb_p-data); 3. 修改该 BD 的状态为就绪态,DMA 模块将自动发送处于就绪态 BD 中所对应的数据。4. 移动发送 BD 表的指针指向下一个 BD。c. DMA 模块开始将处于就绪态 BD 缓存内的数据发送至网络中,当发送完成后自动恢复该 BD 为空闲态。2. 数据接收流程当网络设备接收到数据时,DMA 模块会自动将数据保存起来并通知处理器来取,处理器通过中断或者轮询方式发现有数据接收进来后,再将数据保存到 sk_buff 缓冲区中,并通过 socket 接口读出来。流程图如下所示。图 6. 数据接收流程图a. 网络设备接收到数据后,DMA 模块搜索接
27、收 BD 表,取出空闲的 BD,并将数据自动保存到该 BD 的缓存中,修改 BD 为就绪态,并同时触发中断(该步骤可选)。b. 处理器可以通过中断或者轮询的方式检查接收 BD 表的状态,无论采用哪种方式,它们都需要实现以下步骤。1. 从接收 BD 表中取出一个空闲的 BD。2. 如果当前 BD 为就绪态,检查当前 BD 的数据状态,更新数据接收统计。3. 从 BD 中取出数据保存在 sk_buff 的缓冲区中。4. 更新 BD 的状态为空闲态。5. 移动接收 BD 表的指针指向下一个 BD。c. 用户调用 read 之类的读函数,从 sk_buff 缓冲区中读出数据,同时释放该缓冲区。中断和轮
28、询Linux 内核在接收数据时有两种方式可供选择,一种是中断方式,另外一种是轮询方式。中断方式如果选择中断方式,首先在使用该驱动之前,需要将该中断对应的中断类型号和中断处理程序注册进去。网络设备驱动在初始化时会将具体的 xx_open 函数挂接在驱动的 open 接口上,xx_open 函数挂接中断的步骤如下。request_irq(rx_irq, xx_isr_rx, ); request_irq(tx_irq, xx_isr_tx, ); 网络设备的中断一般会分为两种,一种是发送中断,另一种是接收中断。内核需要分别对这两种中断类型号进行注册。1. 发送中断处理程序(xx_isr_tx)的工
29、作主要是监控数据发送状态、更新数据发送统计等。2. 接收中断处理程序(xx_isr_rx)的工作主要是接收数据并传递给协议层、监控数据接收状态、更新数据接收统计等。对于中断方式来说,由于每收到一个包都会产生一个中断,而处理器会迅速跳到中断服务程序中去处理收包,因此中断接收方式的实时性高,但如果遇到数据包流量很大的情况时,过多的中断会增加系统的负荷。轮询方式如果采用轮询方式,就不需要使能网络设备的中断状态,也不需要注册中断处理程序。操作系统会专门开启一个任务去定时检查 BD 表,如果发现当前指针指向的 BD 非空闲,则将该 BD 对应的数据取出来,并恢复 BD 的空闲状态。由于是采用任务定时检查
30、的原理,从而轮询接收方式的实时性较差,但它没有中断那种系统上下文切换的开销,因此轮询方式在处理大流量数据包时会显得更加高效。回页首Linux 网络设备驱动优化随着科技的不断发展,网络设备所能承载的速率在不断提升,当前流行的网络设备普遍都能支持 10Mbps / 100Mbps / 1Gbps 这三种速率。虽然网络设备的硬件性能在不断的提升,但是实际在 Linux 系统中其运行性能(收发包速率)真能达到多达 1Gbps 的水平吗?这和处理器的性能有关,一般来说我们运行的系统中报文的收发速率是达不到 1Gbps 的(因为我们不可能将所有处理器的资源都贡献给报文的收发),但是我们可以在有限的条件下尽
31、可能的采取一些优化手段提高网络设备的运行性能。Cache 的应用Cache 位于存储系统金字塔的顶层(下面一层是内存),Cache 的容量不大(一级 Cache 一般是几十 KB,二级 Cache 一般是几 MB),但是它的访问速率却是内存的几十倍。因此如果处理器通过 Cache 来访问内存,将会极大的提高访问速率。在网络设备的数据收发中,恰当的应用 Cache 可以优化驱动的性能。下面列举几点 Cache 的优化措施。合理设置内存属性内存的页表有多种属性,其中有一项就是是否通过 Cache 访问。在给 BD 表配置内存时,这些被分配的内存属性需要支持 Cache 访问。Cache 的访问还有
32、两种方式:一种是写回操作(Write Back),处理器更新内存数据时,该数据首先保存在 Cache 中,Cache 并不及时将数据更新进内存,而是等到 Cache 需要再次更新时才会将数据写回到内存中。另一种是写穿操作(Write Through),处理器更新内存数据时,该数据首先保存在 Cache 中,Cache 随即将数据立刻更新进内存。显而易见,写回操作的性能比写穿操作更高,通常我们设置内存页表属性为写回方式。数据收发时的 Cache 操作在内存支持 Cache 且采用写回方式的情况下,当发送数据时,处理器先将数据写进 Cache,如果 DMA 模块直接从内存中取出数据发送的话,该数据
33、将与 Cache 并不一致,因此在驱动程序中,需要将 Cache 中的数据更新到内存,然后再通知 DMA 进行发送。当接收数据时,DMA 模块会将数据收到内存中,如果这时候处理器从该内存接收数据的话,处理器会从 Cache 中取数据,但是 Cache 并不知道内存已经被更新,这就会导致接收到的数据与实际不符,因此在驱动程序中,需要在接收数据之前刷新一下该 Cache,以保证 Cache 与内存的一致性。需要说明的是,并不是所有处理器都需要以上操作,有的处理器所带的 DMA 控制器是能感知 Cache(IO-Cache Coherence)的,它们能够自动进行上述的 Cache 操作,因此对于这
34、类处理器,驱动程序中无需关注 Cache。中断还是轮询?前面曾经介绍过,网络设备驱动支持两种接收数据的方式,一种是中断,另一种是轮询,在数据流量比较大的情况下,可以考虑采用轮询的方式以达到更高的效率。当采用轮询方式时,还有一个不得不考虑的问题,那就是轮询任务优先级的选择,众所周知,当任务优先级高时,该任务不会被其他的低优先级任务所打断,从而可以保证处理器能够专心完成数据接收工作;但如果任务优先级低时,一旦发生了其他高优先级的任务,处理器会将当前的数据接收工作暂停,转而执行别的任务,如此会影响网络设备驱动的效率。因此驱动设计者需要结合实际情况,恰当的选择任务的优先级。设备接口模式有时候我们会发现
35、虽然网络设备号称有 100Mbps 的速率,但是实际数据收发却非常慢,遇到这种情况,我们首先需要检查网络设备接口模式是否设置正确。PHY 模块接口模式PHY 模块的接口模式有两种,强制模式(强制 10M / 100M / 1G 等)和自协商模式。究竟选择哪种模式需要看当前 PHY 模块所连接的对端 PHY 状态才行,如果对端设置的是自协商模式,本端的 PHY 模块也需要相应设置成自协商,如此就能够保证协商出来的结果是当前链路所能支持的最大速率。反之,如果对端设置成强制模式,本端也需要设置成强制,且强制速率要与对端设置的强制速率相同。MAC 模块接口模式MAC 模块对于不同的速率(10M / 1
36、00M / 1G 等)也会有不同的接口模式选择,如果设置的模式与 PHY 模块所运行的速率不匹配的话,会极大的影响网络设备数据收发的速度。因此在初始化 MAC 模块时,需要检查 PHY 模块的运行速率,从而选择恰当的接口模式。每个 PHY / MAC 模块设备的接口模式选择都不尽相同,因此在开发网络设备驱动时,需要明确所使用的设备,并在该设备初始化时正确配置其接口模式。回页首结束语Linux 网络设备驱动与具体的设备关联很大,因此在实际编程中需要结合具体设备来写驱动代码,我们在开发过程中要格外注意驱动的优化,因为网络设备驱动的好坏将直接影响到整个系统的性能。参考资料 Linux Device
37、Drivers,Jonathan Corbet、Alessandro Rubini、Greg Kroah-Hartman 著,东南大学出版社。 参考 MPC8548E PowerQUICC III Integrated Processor Family Reference Manual, FreeScale。 在 developerWorks Linux 专区 寻找为 Linux 开发人员(包括 Linux 新手入门)准备的更多参考资料,查阅我们 最受欢迎的文章和教程。 在 developerWorks 上查阅所有 Linux 技巧 和 Linux 教程。 关于作者赵昊翔,南京大学计算机系硕士毕业,目前从事嵌入式方面的开发工作,对 Linux 内核和计算机体系结构颇有兴趣。