Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1024470
  • 博文数量: 238
  • 博客积分: 2842
  • 博客等级: 少校
  • 技术积分: 2765
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-16 00:20
个人简介

stdlf

文章分类

全部博文(238)

文章存档

2013年(6)

2012年(13)

2011年(82)

2010年(89)

2009年(48)

我的朋友

分类:

2011-07-04 22:41:25

这次要提的是: PCI ! 


[About PCI device]

1. 每一个PCI device都有其 unique PFA(PCI Function Address). PFA由 bus number,device number & function number所组成.


Ex. USB device PFA is (0,6,0) <- USB is a PCI device and its bus/dev/function is 0/6/0



2. 有了PFA,就可以存取其 PCI configuration registers.


Ex. write USB PCI register 43h bit1 = 1

=>

mov eax, 80003040h

mov dx, 0cf8h

out dx, eax


mov dx, 0cffh

in al, dx

or al, 00000010b

out dx, al


* IO port 0cf8/0cfc 为 PCI config address port & data port,意即:将 address(80003040h)送到config port(0cf8h),然后从 data port(0cfch + 3)来存取 data(al)


* 注意: 32-bit address(80003040h) 中 bit[1:0] = 00b(固定的),所以虽然存取的是 43h,但还是写成40h ! 而要存取到 43h,则从 0cfch+3来达成 (因为: 0cfch<-> 40h,0cfdh<->41h,0cfeh<->42h, 0cffh<->43h) 


3. 基本的PCI device的 config registers可分成 2 parts:


A. header region(offset 00h~3Fh)

B. device specific region(40h~FFh)


在BIOS's PCI_SCAN stage中,会touch到 part A. Ex. command byte, BARs, Interrupt line, latency timer,...etc. 而Part B是制作 or design这个device的厂商所附加的 function/feature.


4. 每个PCI device都可以 request 之前所提的 4 resources:

A. memory resource:透过 Base Address Register(BAR)

B. IO resource:透过 Base Address Register(BAR)

C. Interrupt: 透过 interrupt pin

D. DMA: 这需要 device本身即具有 bus master function(status byte会indicate)



[Why need PCI SCAN]

现在的computer system泰半由许多PCI devices所组成,因此,BIOS POST中另一个重要的 task is : PCI_SCAN !!! 


它代表的是: BIOS会扫瞄 whole system,找出所有的PCI devices; initial them and build a linked list of PCI devices.在此list中的每一个node都代表一个PCI device,且含有其 characteristics ! 


Ex. Vendor ID,Device ID, PFA,Option ROM exist or NOT,...etc. 


一旦建好此表,以后的 tasks 随时都可以参考 !!! 


所以, after PCI_SCAN,有两件事完成了:

1. PCI device initialization;device config registers(Part A) are correctly set ...

2. One data structure is built to describe the PCI devices in whole system(建在memory中) 


这也是属于kernel code part ^_^ ( system 一般很少 hang at this stage...)



符合PCI spec的device即称为........PCI device ^_^


[补充] PCIe device


PCIe device => 符合PCIe spec的device(...废话...)


对软件而言,它仍是PCI device. 因此,基本的 header region and device specific region也有. 不过,PCIe新定义了 extended config space,即 offset 100h(含)以上,直到 FFFh( 所以, 最大可以至 4096 bytes )


存取 PCI config space的方式,用原来 0cf8/0cfc的方式依然可行,但只能 access offset 00h~FFh. 要 access 100h(含)以上的 extended config space,则必须用 memory transaction的方式 !


Ex. mov ax, [50400000h] <- read device (4,0,0)'s register 0;2 bytes


here 50000000h: PCIe extended base address. 可以从 chipset register得知

bit[27:20]: Bus information

[19:15]: Device information

[14:12]: Function information

[11: 8]: Extended Register 

[7:2]: DW number

[1:0]: Byte enable


因此,只要知道 PCIe extended base address,就可以像以前一样,可以任意存取 PCIe config registers, even > 0FFh !


除此之外, PCIe device可以由其 Capability pointer(points to a linked list of capabilities)辨认出来. 因为,在众多的 capabilities中,会有一个 PCIe capability;其 ID value = 10h.


Note: PCIe extended base address 要 reserve and report to OS. Size is 256MByte. 这是BIOS需要做的. (当然,BIOS也要将此 base address写入 chipset register,让 chipset 知道:有这样的 cycle时,是给PCIe device的 ! )


[补充] For P2P bridge


P2P bridge = PCI-to-PCI bridge. 其存在可以 introduce 另一 new PCI bus,可以容纳更多的 PCI device.


P2P bridge亦有其 PCI config space,但是 lauout 与 PCI device有点不同,大家可以参阅P2P spec并与PCI device's config space比较一下.


在 P2P config space中,我常遇到的 issue是和下列 register有关的:

- Primary bus register: offset 18h

- Secondary bus register: offset 19h

- Subordinate bus register: offset 1Ah


----------------------------------------

Notes:

这三个 registers是BIOS在 PCI_SCAN时会决定的;所代表的意义是:这个 P2P bridge的上面 PCI bus number is ? 下面的PCI bus number is ? 及包含此 P2P bridge的 "branch" 最深的 PCI bus number is ?


Ex. 18/19/1Ah of one P2P bridge is 0/2/3

=> 此 P2P bridge 是 "bridge" PCI bus 0 and 2的(桥接在 PCI bus 0 and 2之间);而包含此P2P bridge的 PCI branch(想象成 tree structure) 最大(深)的PCI bus number is 3

----------------------------------------



- memory base/limit

- IO base/limit


----------------------------------------

Notes:

这两个是 BIOS 在 PCI_SCAN时所 assign的. 所代表的是: resource "window" for devices behind this bridge.意即:若P2P bridge下面(就上例言:是 Bus 2上)有 PCI devices,则他们的 BARs 必须被包含在此 window 之内 !!!

---------------------------------------- 


[Practice] 

[Q]假设有一个 P2P bridge ,下面有一PCI device;现在必须要去 accessPCI device's Device ID/Vendor ID(that is, PCI config read). 但是,问题是:做这事的"点"要在 PCI_SCAN之"前"....那要如何做到呢 ^_^ ?


Ans:假如要在很早前(Ex. PCI SCAN之前)去 access P2P bridge后面的 device,照理是做不到的,因为: P2P bridge没有被正确的 configed...


在此例中,P2P bridge的 primary/secondary/subordinate bus要被 set,后面的device才能被 accessed到 !


所以,假如要在 PCI SCAN前就 access,则BIOS必须手动去 set 此 3 bytes;然后,PCI config access才能被 forward to 其后的 PCI devices...


[Q] 如何 disable memory or IO resource window ?

Ans: 只要将 base设成比 limit "大" 即可 !!!



---------------

- 相关讨论 Part1 -

---------------

前辈已经提到P2P Bridge我就直接问我的问题了


[Q1] Bridge 是用来扩充PCI Bus,在PCI Bus Spec与PCI-PCI Bridge Spec中定义,PCI Device是透过IDSEL来决定他的身分,其中PCI Bus Spec定义AD[31:11],而PCI Bridge Spec定义AD[31:16] 当做IDSEL,这中间差异为何? 为什么一个要从Bit 11开始当作是Dev 0 ,而另一个由Bit 16 才当作是 Dev 0 ?


Ans: 1. IDSEL对PCI device而言是 input,是用来当作 device's "chip-select"讯号. 而且,IDSEL "如何连接" 是 H/W决定的,BIOS无法决定. 


假如将板子上某个device's IDSEL "割断",则此 device将无法接受 PCI configuration read/write(以 ru.exe来说,就是按F6后,是看不到它的...)


那要如何决定 device's IDSEL ? 一般而言, board designer会将 "unused AD lines"拿来做 IDSEL,以连接至 PCI device.


在 configuration access时,所下的 Ex. "o cf8 80001020"(看起来是 I/O transaction)会被 host bridge转成 configuration transaction;此时, host bridge即可判断此 transaction 要 access的 device是否在该 PCI bus上;if YES 转成 Type 0 transaction;If NO 转成 Type 1 transaction,并往下发送...(host bridge只要 check latched "bus information"即可完成此判断 !)


以 Type 0言,AD bus上的 format as follows:

bit[1:0] = 00 ( indicates "Type 0" )

bit[7:2] indicates register number

bit[10:8] indicates function number 


那 Bus number ? Device number ?

=> Bus number不必知道 ! 因为:Type 0产生即代表 bus number = 现在的 bus #

=> Device number呢 ? 因为,此时(Config transaction && address phase) AD bus bit[31:11]没人用 !!! 因此, board designer会把此 21 bits拿来做 IDSEL用 !


因此, AD bus bit11 <-> device 0

12 <-> device 1

.......


当然,不可能 21 bits都拿来接 PCI devices;因为电路上的现实考虑...


.................以上为:我所知为何从 bit11开始来当作 IDSEL................


以 Type 1言,PCI-PCI bridge收到后,会将其 bus information与自己的 secondary bus number比较;若是 addressed device是在 secondary bus上,则将 Type 1 -> Type 0;若否,继续包成Type 1往下一层送... 


在P2P spec v1.1 page 22 有一张表,说明 IDSEL generation(from primary address -> secondary address),其中有提到: if primary address bit[15:11] =0,则 secondary address AD [31:16] = 0000 0000 0000 0001;以此类推. 


所以,我觉得为什么 for P2P bridge 其 IDSEL可由 bit[31:16] 来决定的原因在此 !!!(表的关系...)


.................以上为:我推论为何从 bit16开始来当作 IDSEL................

[补充]

PCI config index register里面的数据其实和硬件解出configuration cycle是相关的. 

一.转换出来是type 0 cycle的话. 硬件只要做以下两件事.

1. mask 掉bus number(bit 16 ~ 31)以上的部份.

2.译码 device number的部份即可到对应的 AD bit. 所以其最低可以使用的就是AD11.也就是说一个bus上最多只能有 21个 devices(只是由于推动力问题, 往往是做不到的). 

Note:其实也可以设计成其它大于AD 11开始, 这要看chip设计者决定了.

二. 转换出来是type 1 cycle的话. 只要做

1. mask 掉reserved以上的部份(bit 24 ~31)

2. bit 0 = 1

由于P2P跟其它device不同的地方就是, 除了type 0 clcye以外, 还必须处理 type 1 cycle. 这也是分成两部份

一. type 1 -> type 0. 当 bus number 等于 secondary bus number 时候出现.

1. 解碼 device number 到对应的 AD. spec中有提到转换的表. dev 0 = AD16....etc

2. 把 bit 0 由1 变成 0

二. type 1-> type 1. 当 bus number 介于 secondary bus number和 subordinate bus number

1. 直接往下一层送即可.交给其它的P2P 处理.


[Q2] 在IA32下,CONFIG_ADDRESS 会被转成Configuration Cycles,当Bus Number <>0 时,NB会转成Type 1 然后往 DMI送到SB,当P2P Bridge收到后,然后寻址到Slot上面的PCI Device,这样说法对吗?


Ans: 总而言之, 是自己local bus上的,就会转成 Type 0,然后打在AD bus上,等待认领;若否就转成 Type 1,往下一个bridge送,继续寻找...对的人...for each bridge,都是一样...

[补充]

对 PCI spec是, 如果以Intel PCI express架构来说. 那个已经被封装成 pci express的 package了.没有所谓的 type 0, type 1 cycle了.



[Q3]PCI Device透过IDSEL来决定身分,那PCIE Device呢? 我查过数据,好像PCIE不需要IDSEL那他是如何决定Device Number ?


Ans: 我所遇的 PCIe device也是由 AD bit[31:11]中找线拉至 device's IDSEL决定的.不知其它家 chipset是如何 implement.

[补充]

PCI express 是internal routing. PCI express是个跟PCI 完全不同的架构. 只是为了软件兼容性的关系, 把software架构做的跟PCI bus一样. PCI express是point-to-point架构, 一个link 只会连接一个device. 跟PCI 这种可以多个device在同一bus上是不一样的. 所以 device number对PCI express是完全不重要的.

Note. AMD的Hyper transport 也是基于一样的心态来设计软件架构的. 


※ PCIe 的device是 internal routing. 以规格来看,下一层的 device number都是为0. 


------------------

- 相关讨论 Part 2 -

------------------

DMI指的是 Intel 南北桥中间的通道 ! 之前也是不知P2P bridge部份关于IDSEL的配置,查了表才知道原来有这样的 mapping(primary address<->secondary address). 其实,可以说 "unused AD bus 会被拿来当 IDSEL用"就是了吧 ^_^

[补充]

是的, 只要软件能够知道routing 关系.怎么接都可以. 只要bus controller控好实际的IDSEL即可. P2P之所以会有严格规定(两项, 1. IDSEL&device number表, 2. secondary bus IRQ routing)是因为P2P 不一定是在板子上. 包含卡都可以有P2P bridge. 在板子上的P2P 可以靠BIOS来建立正确的 routing, 但是插卡不行. 所以必须把这些定义好. 这样 PnP software(BIOS or OS)才能正确的完成IRQ 分配.让卡正常工作. 所以如果观察某些板厂. 就算是真的p2p 没有存在在板子上, 很多PCI slot的IRQ routing都是依据p2p spec里面的规定做(因为SB的PCI bus还是落在P2P之后).


在 PCI scan时,BIOS会扫描整个系统的PCI architecture(包含 device & bridge);其扫描方式由BIOS's PCI kernel来决定 !

[补充]

其实了解PCI spec. 要写PCI scan其实可以效率好又正确. 常见的新进工程师写法大概就是 3个 loop来处理. bus:0~255, device:0~31, function:0~7. 扫个 256*32*8次, 反正都是程序做, 结果往往也看来正确.这种写法其实是不对的. (其实,若是多了解硬件的架构,就可以写出有效率的code了 ! 这也是F/W工程师的价值...)


Ex. Assume 系统架构是这样的: NB,P2Px3, PCIe bridge x2;其中:

A. 3 P2Ps的配置 is: P2P0下面接P2P1;P2P下面接P2P2

B. PCIe x 2 & P2P0都在 bus 0;其PFA为

NB(0,0,0)

P2P0(0,1,0)

PCIE0(0,4,0)

PCIE1(0,5,0)


=> 最后的 PCI achitecture is:


Bus 0----------------------

NB(0,0,0),P2P0(0,1,0),PCIE0(0,5,0),PCIE1(0,6,0)


*下面 Bus 1/2/3由 P2P0/1/2所 introduce:

Bus 1----------------------

P2P1(1,0,0)

Bus 2----------------------

P2P2(2,0,0)

Bus 3----------------------


*下面 Bus 4由 PCIE0所 introduce:

Bus 4----------------------


*下面 Bus 5由 PCIE1所 introduce:

Bus 5----------------------


所以,Bus number 是由BIOS's scanning "algorithm"所决定的;假如采用 depth-first,则会产生上述的结果 ! 决定后的值会填到 bridge的 Primary/secondary/subordinate bus number registers ! 


[Q]顺便问个问题好了. 其实function number不应该是永远需要scan的, 为什么?什么时候才需要scan function number?

Ans: 我想,对于 function number的问题,应该是: PCI header region offset 0Eh bit7代表: milti-function or NOT ! 因此,可以先 check此bit,再决定要不要往下扫了...这样又少做了许多虚工...^_^


Ex. PFA (0,3,0) 有回应(that is, Vendor ID/Device ID != 0xFFFFFFFF),则先check (0,3,0)'s PCI Reg0Eh bit7; if "1" then 此device为 multi-function device,还要再往下找 Ex. (0,3,1~7) 有无回应;if "0" then try next device number...!


[补充,加快速的的方式]

检查multi function bit是正确的, 但是不只是因为效率问题. 而是PCI 规格中, single function装置可以不译码 config cycle type 0 bit[8~10], 也就是说 一个 single function装置, 会对 所有的function number响应, 也就是会出现 8 个相同的device.


顺便说一下我的scan加速法. 其实我不是使用 vandor ID & device ID来判断装置存在与否. 我是用 class/subclass/interfae ID来作判断. default 只scan bus 0, 遇到 P2P bridge才会把taget bus number+1, 如果遇到multi host(host bridge 数量> 1)的板子才会完整扫描 255个 bus. ^_^



---------------------------------------------------------------------------------

---------------------------------------------------------------------------------

---------------------------------------------------------------------------------


~转贴自艾克索夫实验室~

Rootkit in PCI Option ROM


「Rootkit」一字来自 UNIX 界;但目前通常用于描述 Windows 木马程序作者所运用的隐形技术。 

起初,Rootkit指的是一组程序,可让黑客躲过侦测。 为达成此目的,可执行的系统档案 (如 login、ps、ls、netstat 等) 或系统链接库 (libproc.a) 会遭到更换,或安装核心模块。 这两种动作只有一个相同目的;防止使用者收到正确信息,知道计算机上发生了什么事。


首先介绍PCI的基本常识, PCI Bus是在约1990年由Intel发展出来, 用来连接主机板上的各项装置的总线标准, 后来成为业界的标准之一, Spec可以在PCI-SIG注册会员之后下载, 架构上简单的说, 就是一个Host bridge, 在一般的PC上通常指的就是North Brdige, 这个brdige后面就是bus#0(当然也有Multi Host-Bridge的状况, 这边举例的是最单纯的情况), 然后接到South Bridge, South Bridge之后可能接的是ISA Bus, IDE Controller, USB, IDE, DMA Controller等等, 如果bus#0上还有别的PCI Bridge, 这个Bridge后面就是bus#1, 如果有多个Bridge存在(PCI最多可以有256个bus), bus#就不一定是固定的了, 一个PCI Bus上可以有32个device, 每个device可以有8个function, 每个function都有属于自己的256个register. 在PCI的规范里, 256个register中的前0×40个是公定的功能, 从0×40到0xff则由各家厂商自行实作, 存取这些register的方法, 一般的PC上是透过IO port 0xCF8~0xCFF, 如果是新的PCI-Express则是直接透过Memory Mapped IO, 以存取内存的方式直接进行存取, 例如我们想要读取一个在bus#0 dev#1 func#0的register#40~43, 透过IO的方式如下:


mov eax, (0x01 << 31 ) // Type-1 PCI Configuration

+ (0x00 << 16 ) // Bus#0

+ (0x01 << 11 ) // Device#1

+ (0x00 << 8 ) // Function#0

+ 0x40 // Register#40

mov dx, 0xCF8 // Index Port 0xCF8 ~ 0xCFB

out dx, eax

mov dx, 0xCFC // Data Port 0xCFC ~ 0xCFF

in eax, dx // Get Data in EAX


如果是透过MMIO的方式则简单多了:


mov esi, (MMIO_BASE) + (0x00 << 20) + (0x01 << 15) + (0x00 << 12) + 0x40

mov eax, [esi]


今天我们比较有兴趣的是位在0×30~0×33的register, 在PCI Spec定义中, 这里的值存放的就是expansion rom在physical memory中被decode到IO的地址, 比如说这个地址是0xFE000000, 如果你在0×30把bit0设为0×1(io->mem decode), Command Register(0×04~0×05)的Memory Space Bit打开, 在0xFE000000的地方你就可以找到这个rom, 开头是0×55AA(这当然也是规范之一, 用来辨视是否为一个PCI rom), BIOS在POST过程中, 会逐一扫描位于主机板上所有的PCI Device, 假如device上有rom, 就会把它给拷贝到memory中, 然后用jmp指令跳到ROM开头offset 0×02(别忘了开头offset 0×00是0×55AA)的地方开始执行PCI ROM, 执行完后ROM会再把控制权交回到BIOS手上, 一般而言, 在传统记体空间中, 0xC0000~0xCFFFF是给VGA ROM用的, 0xD0000~0xEFFFF则是留给一般的PCI ROM使用, 当然各种情况下还是会有些许差异, 例如有些BIOS会保留0xE0000~0xFFFFF给自己使用, 像是BIOS的interrupt service, DMI data….等等杂七杂八的东西, 执行完的ROM仍然会保留在内存中, 因为有些ROM会修改IVT(Interrupt Vector Table), 将某些interrupt service导向自己的code, 像是VGA ROM可能就会hook int 0×10, 这是很合理的, 因为int 0×10是BIOS所提供用来控制屏幕的service, 聪明的你看到这里应该就知道前面所提的那篇文章想说什么了, 如果有个”恶意”的程序被埋在PCI ROM里面, 只要一开机就会自动被执行, 它的运作并不是一时的, 它可以hook某个OS一定会用到的BIOS Interrupt Service, 然后在这个interrupt service被呼叫的时候动作就可以了, 而且麻烦的是即使你format你的HDD也没用, 除非你把有问题的PCI Device从你的主机板上移除, 嗯….听起来蛮炫的, 但是, 有可能吗?


要回答这个问题之前, 需要知道一些基本的常识, 在保护模式下, 因为IO动作受到限制的关系, 要存取IO并不像在DOS那样容易, 但如果想尝试Re-flash一颗PCI ROM, 势必得进行IO动作, 所幸在Windows下这并不是不可能的事, 有些人可能知道利用SeTcbPrivilege和使用ProcessUserModeIOPL structure呼叫undocumented Native API NtSetInformationProcess()就可以达成目的. 一旦攻击者有办法修改PCI ROM, 他就可以利用文章中所提到的例子: int 0×10(Windows在开机过程中会透过Ke386CallBios()呼叫int x010), 作他想作的任何事了.


可惜不论哪种攻击方式, 最终都是要对OS kernel动手脚, 利用各种侦测工具(如: Archon Scanner), 一定可以找到有问题的地方, 如果最后的箭头指向PCI ROM, 我们可以透过上文所述, 将存在PCI Device和memory中的ROM给dump出来, 需要dump两边的rom, 是因为PCI Spec规范中允许实际上所需要配置的内存不一定要等于原本rom的大小, 藉以节省保贵的内存(别忘了PCI ROM只能被配置到几个64KB的segment里而已), 然后向PCI Device的制造商索取正常版本的rom进行比对, 藉以得知是否为被修改的版本. 假如发现有不一样的地方, 接下来可以朝几个方向继续分析是否为有问题的ROM, 我们可以检查一下它是否修改了不必要的IVT, 像PXE ROM就不太可能hook int 0×10, 或是有保护模式相关的程序代码, 因为一般的ROM应该都是在real mode下执行, 所以应该不会切到protected mode, 如果有相关的程序代码那就非常可疑, 还有rom里面是否有可疑的字符串, 或是位在Windows Kernel地址空间里的32-bit address, 另外ROM里面也不太可能出现编码过的code, 如果rom里的code很难被disassemble, 或是充满了一堆obfuscated code, 那也是很有问题.


除了软件的方式, 最近兴起的新技术TPM也能克制这种攻击手法


张贴者: Harrison Hsieh 于 6:12 下午 


标签: BIOS相关


8 意见:




poyuan 提到...


此文章已被作者删除。


八月 21, 2008 1:13 上午 




poyuan 提到...


BIOS界的前辈您好, 无意间看到您的部落格, 对于您巨细弥遗的文章, 深为感动. 谢谢您在工作闲聊之余, 写了这些BIOS相关的文章. 

有一个问题想请教您: 敝公司做了一块PCI卡,发生了难以理解的现象, 就是在P915的主机板上可以WORK, 但是在P35 or P965的主机板上却不行?! 

用LA侧录PCI BUS的讯号后发现, BAR0被WRITE 0x80008000, 再被READ出

0x80008001, 最后BAR0被WRITE 

0xFFFF_FFFF, 等于BAR0是被关闭? 故无法map 到IO SPACE? 查了很久不知道原因, 可不可以请前辈给一点HINT?

八月 21, 2008 1:15 上午 




Harrison Hsieh 提到...


我进入BIOS才两年,很多东西不懂! 大家互相讨论啦!


关于你的问题,我不太懂你测录的讯号,


不过我从PCI Spec 看到的步骤是:


1.对BAR写入"全部1"的值

2.读回BAR状态值并判断,假设bit 0=1 则代表这个PCI应该是实做IO Space


3.从bit 0开始往高位检查第一个"1"的出现的权值..假设出现在bit 8 , 代表这是一个256 bytes的IO范围


4.填入IO BaseAddress (因为是256,所以填入的bit7:0无效)


所以解碼范围是IOBASE~IOBASE+256


5.到CMD Register去Enable BAR


所以你看到写入FFFF_FFFF应该是我说的步骤1...所以你可能还是要继续测录一下后面的讯号,希望这些信息能帮的上你的忙!

八月 25, 2008 8:58 上午 




Colorben 提到...


个人问题请教:我要读取的rtl8139网卡都很顺利读到mac addr,在p35主板上内建好像是rtl8168也都从BAR就可以顺利读取,因为它们都是I/O mapping,但从ga-P965-ds3主版上内建网卡读取mac addr确读不到正确ㄉ值,因为它是memory mapping,从bar读到ㄉ值是f4000004,像这样我要如何正确读取网卡mac addr?

三月 17, 2009 8:19 上午 




Colorben 提到...


我目前是在DOS下写ㄉ一个应用,由于必须得知网卡MAC ADDRESS,所以我写ㄌ这样ㄉROUTINE:

subGetMacAddr proc uses eax ecx dx si di

xor ebx,ebx

xor si, si ;index 0

mov ecx,020000h ;因为网卡ㄉclass=02h Subclass=00h

mov ax, 0B103h ;find PCI B/D/F

int 1ah

jc loc_err

mov di, 10h ;register 10h

mov ax, 0B10Ah ;read pcicfg dword

int 1ah

test ecx,1

jz Memoryio

mov dx, cx ;port

xor dl, dl

in eax, dx

out 0EDh, al

mov DWORD PTR MacAddr, eax

add dx, 4

in ax, dx

out 0EDh, al

mov WORD PTR MacAddr[4], ax 

loc_err: 

ret

Memoryio: 

我想在这里加入若网卡的BAR是memory mapping,就使用MMIOㄉ方式读取此时ㄉECX:0x0f4000004(marvell yukon 88E8056 配置BUS4 DEVICE0 FUNCTION0)

ret

subGetMacAddr endp


由于我只会碰到两块主机板:GA-965P-DS3及GA-P35-DS3L,GA-965P-DS3ㄉ主机板所配置ㄉ网卡是marvell yukon 88E8056 ㄉController(它是memory mapping),另外GA-P35-DS3L配置ㄉ网卡是RTL8168 Controller(它是IO映射),上面那ㄍROUTINE对RTL8168可以读取到MAC ADDRESS,而且外接RTL8139也可以读到MAC,会用上面ㄉ方法也是因为在网络上找到如附图ㄉ数据。但是marvell yukon 88E8056没办法读到MAC,红色区域就是想为它而写,不知是否能帮帮我。

我使用过以下方法但都读不到MAC ADDR

mov esi, (MMIO_BASE) + (0x04 << 20) + (0x00 << 15) + (0x00 << 12) + 0x10

mov eax, [esi]

当然我知道这和实作硬件有关,况且又没有SPEC,所以只能求救ㄌ。

TKS,Benson

四月 22, 2009 11:19 下午 




Birdy 提到...


请问前辈, 最近公司要开发一个板子, 是有6个PCI slot. 3个slot后会接一个PCI-to-PCI bridge, 然后再扩3个slot出来.

但另外有一片PCI外围卡片, 上面是由一个PCI-to-PCI bridge去接4个PCI LAN.

请问当把这片外围接到第4-6的slot时, 上面的PCI LAN能动吗? 若第3个slot接了这片有PCI-to-PCI bridge的卡后, 第4-6的slot又接一片这个LAN卡, 这样子两片都能动吗?拜托帮我解答一下吧? 如果要能动, PCI SCAN与BUS的关系是怎样呢? 谢谢!

四月 28, 2009 10:54 上午 




匿名提到...


我现在在做的Project为AMD CPU+NB RS780+SB SB710.


挂在NB下有三个PCIE devices

两个Lan chip 和一个Mini PCIE slot


当我Clear CMOS 后的第一次开机

系统可是Scan 到两个LAN chip

但Scan不到Mini PCIE slot(Wireless lan)


第二次(CMOS 储存)开机时

则三个devices都抓不到(RU看不到)


有人可以帮忙嘛?

我目前用AMI core8


Grant

PS. email : Grantwu00@yahoo.com.tw

二月 19, 2010 4:02 下午 




Grant 提到...


Hi Harrison,


因为我现在在一个17人的小公司

公司只有我一个BIOS engineer

我一人孤军奋战实在很辛苦


如果你方便给我你的Email

我好和您讨论问题


谢谢

Grant

二月 19, 2010 11:46 下午


 

阅读(7199) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~