操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    天把網(wǎng)卡的配置信息讀進(jìn)來了,利用配置信息中的class_code,我們找到了pc上的網(wǎng)卡設(shè)備。

    昨天的教程:在自制操作系統(tǒng)上寫網(wǎng)卡驅(qū)動(2): 網(wǎng)卡的I/O配置

    既然找到了網(wǎng)卡設(shè)備,今天就可以來使用網(wǎng)卡了。

    那么如何使用呢?

    給網(wǎng)卡內(nèi)部的寄存器寫內(nèi)容就可以控制網(wǎng)卡了。

    控制網(wǎng)卡,就是使用網(wǎng)卡收發(fā)數(shù)據(jù),觸發(fā)中斷等。

    網(wǎng)卡內(nèi)部的寄存器就是網(wǎng)卡的"遙控器",網(wǎng)卡的"控制面板",不同的寄存器就相當(dāng)于遙控器上的按鈕。

    具體怎么做呢?

    1. 通過讀取PCI配置中的基址寄存器base address register,BAR的值,來得到網(wǎng)卡內(nèi)部的寄存器的地址net_card_base_addr,這就是網(wǎng)卡的內(nèi)部寄存器的地址,往net_card_base_addr上寫內(nèi)容,就是往網(wǎng)卡內(nèi)部的寄存器里寫內(nèi)容。
    2. 網(wǎng)卡內(nèi)部都有啥寄存器?這個要看具體網(wǎng)卡的使用手冊,就是根據(jù)網(wǎng)卡的型號找到對應(yīng)的datasheet
    3. 在datasheet上,會詳細(xì)描述各個寄存器的功能,通過設(shè)置這些寄存器的值,就可以完成數(shù)據(jù)的收發(fā),是否觸發(fā)CPU的中斷等功能。

    讀取網(wǎng)卡的BAR

    網(wǎng)卡的BAR就存在于PCI配置信息中,它是PCI配置信息的第4--9行,如下圖所示:

    PCI配置信息

    第4--9行分別是BA0,BA1,BA2,BA3,BA4,BA5,一個6個BAR.

    既然在配置信息內(nèi)部了,仍然使用我們昨天的方法去讀取配置信息即可使用代碼:

              int offset=4; // 讀取第offset行
    					unsigned int addr3=addr | (offset<<2);
    					io_out32(0xCF8,addr3);
    					unsigned int abr=io_in32(0xCFC);

    通過以上代碼,我們讀取到了配置信息中的BA0,它的值顯示出來為:

    class_code=02時為網(wǎng)卡,其BAR為0xc101

    我們查詢到,網(wǎng)卡設(shè)備對應(yīng)的bar為0x0000 c101.那么這個數(shù)值代表著什么呢?是怎樣對應(yīng)于網(wǎng)卡內(nèi)部的“控制面板”呢?

    BAR各bits的意思

    先說結(jié)論:如上圖bar=0x0000c101時,我們訪問I/O端口 0xc100,就是訪問網(wǎng)卡內(nèi)部的寄存器。這個結(jié)論是如何得到的?

    查看IO BAR Written With Base Address字樣下面的說明:

    bit0為1,表示訪問網(wǎng)卡內(nèi)部的寄存器需要用CPU的I/O口;如果bit0為0,表示訪問網(wǎng)卡內(nèi)部的寄存器可以像訪問內(nèi)存那樣,不用通過I/O口。

    當(dāng)bits0為1時,網(wǎng)卡內(nèi)部寄存器對應(yīng)于CPU的I/O的地址net_card_base_addr為:bar & 0xffff ff00

    取bar的第8到31位作為net_card_base_addr的第8到31位,然后把net_card_base_addr的第0到7位設(shè)置為零即可。

    所以,我們這里得到結(jié)論,只要訪問I/O端口0xc100,就是訪問網(wǎng)卡內(nèi)部的寄存器。

    具體的訪問代碼為:

    //讀取網(wǎng)卡內(nèi)部寄存器的值
    unsigned int CR=io_in8(0xc100);
    //往網(wǎng)卡內(nèi)部寄存器里寫值
    unsigned int CR=io_out8(0xc100);

    這里為什么要用io_in8和io_out8,為什么要用8位的端口讀寫函數(shù)?不用16位的?不用32位的?

    因?yàn)檫@款網(wǎng)卡的內(nèi)部寄存器是8位的。

    這是一款什么樣的網(wǎng)卡呢?它的內(nèi)部寄存器到底是怎樣的呢?


    網(wǎng)卡內(nèi)部的寄存器

    我們要查詢網(wǎng)卡的內(nèi)部寄存器,首先要得到網(wǎng)卡的型號,怎么看呢?

    通過PCI配置信息的第一行vonder_id和device_id。

    比如我們這款網(wǎng)卡的vonder_id和device_id分別為:0x10ec和0x8029

    經(jīng)過搜索,在這里找到了具體解釋:

    10EC是Realtek公司

    那么8029是什么?8029是芯片的型號,所以,連起來,就是Realtek 8029。

    把"Realtek 8029"作為關(guān)鍵字搜索后,發(fā)現(xiàn)這款網(wǎng)卡的核心芯片就是 RTL8029芯片,

    那么就可以去搜索RTL8029芯片的datasheet了。這個還是比較容易搜索到。

    最終我找到了這個:


    RTL8029AS的芯片手冊。

    雖然是8029AS,不是8029,但是估計也是8029芯片的升級版,應(yīng)該跟8029操作起來差不多。這是總體介紹:



    在這個芯片手冊中,關(guān)于寄存器是這樣說的:


    8029AS的內(nèi)部寄存器總覽

    表5.1.1. Register Table就是8029內(nèi)部所有的寄存器了。我們要控制網(wǎng)卡收發(fā)信息,觸發(fā)中斷信號,就得給這些寄存器設(shè)置合適的值。

    表中,每個寄存器的意義在datasheet中都有詳細(xì)說明。

    我們先來看一下如何訪問表中的寄存器,比如訪問某個單獨(dú)的寄存器:CR寄存器。

    先看表中的第1列No(Hex),它表示序號,CR寄存器的No為00,這說明通過0xc100+0x00就可以訪問到CR寄存器了。

    比如表中有個寄存器FIFO,它的No為06,這意味著通過0xc100+0x06就可以訪問CR寄存器了。

    但是注意到,這個表每一行的幾個寄存器都同時對應(yīng)著一個No,那么問題就來了,當(dāng)我們in_io8(0xc100+0x06)時,具體讀的是哪一個寄存器呢?

    這個還要看CR寄存器內(nèi)的值。如果CR寄存器的第8,7bits為00,我們此時執(zhí)行的是讀操作,也就是in_io8(0xc100+0x06),那么此時操作的就是FIFO,

    如果此時執(zhí)行的是寫操作,那么此時操作寄存器就是TBCR1.

    如果CR寄存器的第8,7bits為01,我們此時執(zhí)行的是讀操作,也就是in_io8(0xc100+0x06),那么此時操作的就是PAR5,如果此時執(zhí)行的是寫操作,那么此時操作寄存器就還是PAR5.

    如果CR寄存器的第8,7bits為10,我們此時執(zhí)行的是讀操作,也就是in_io8(0xc100+0x06),那么此時操作的就是PAR5,如果此時執(zhí)行的是寫操作,那么此時操作寄存器就還是PAR5.

    所以說:某個寄存器的方位方式,由這個寄存器所在的行頭和列頭的值共同決定。

    比如PSTART,我們可以看其所在行01,其所在的列為:Page2-[R],那么要操作這個寄存器,要把CR寄存器的第8,7bit設(shè)置為2,即0x10,然后用io_in8(0xc100+0x01)來操作這個寄存器。

    所以,我們在訪問寄存器前,總是需要先設(shè)置一下CR寄存器,那么如何設(shè)置這個寄存器呢?

    CR的行為00,CR存在于所以列,這意味著訪問CR就只用io_in8(0xc100)和io_out8(0xc100,0x01)就可以了。

    所以,想把CR寄存器的bit8,bit7的值設(shè)置為10時,可以這樣操作:

    unsigned int temp=in_in8(0xc100); // 取CR原來的值
    temp=temp&0x3F;
    temp=temp|0x80; // 把bit8,bit7設(shè)置為10
    in_out8(0xc100+0x00,temp) //temp的值給到CR

    由于CR寄存器的bit8,bit7對應(yīng)著Page0,Page1,Page2,Page3,為了方便的操作各寄存器,我們寫了一個改變page的函數(shù)page_select:

    //輸入?yún)?shù)pagenumber,取之可以是0,1,2,3 
    void page_select(unsigned char pagenumber )
    {
        	unsigned int temp;
        	temp=io_in8(0xc100);
          temp=temp&0x3B;
          pagenumber=pagenumber<<6;// 將pagenumber向左移動6為,從bit2,bit1,移動到bit8,bit7
          temp=temp|pagenumber;
          io_out8(0xc100,temp);
          return;
    }

    這樣,當(dāng)我們需要操作寄存器PSTART的時候,就可以

    page_select(2);
    io_in8(0xc100+0x01);
    

    這就大大簡化了代碼的編寫,當(dāng)然還可以繼續(xù)簡化,比如

    void operation(unsigned char pagenumber,unsigned char No)
    {
      page_select(pagenumber);
      io_in8(0xc100+No);
    }
    operation(2,0x01);//只用一句就可以完成對PSTART的操作了

    不過我們這里似乎沒有必要做太復(fù)雜。太復(fù)雜了程序的可讀性就變差了。如果以后有必要就再說吧。

    到這里,我不僅感概,拿到這個datasheet真是太好了,終于可以實(shí)現(xiàn)對網(wǎng)卡的自由操作了。

    先試試page_select韓式是否能夠工作:先調(diào)用page_select(2),然后再查看0xc100處的值,看其bit8,bit7是否被設(shè)置為10.


    設(shè)置CR

    我們先調(diào)用page_select(2),然后再io_in8(base_addr)得到CR,然后把CR的值放到顯示變量bar里進(jìn)行顯示。結(jié)果如下:


    可以看到在表格的BAR列,最后一行的值為0x00000080,就是說CR的值為0x80,也就意味著CR的bit8,bit7位10.

    那么page_select(3)之后是怎樣的呢?

    代碼改為:


    對應(yīng)的結(jié)果為:0x000000c0.

    這個結(jié)果說明我們對RTL8029網(wǎng)卡芯片內(nèi)的寄存器CR設(shè)置成功了。

    這就意味著,我們可以對RTL8029網(wǎng)卡芯片內(nèi)的任何寄存器進(jìn)行操作了。

    這還意味著我們可以對不限于網(wǎng)卡,可以是顯卡,也可以是其他卡比如顯卡,比如聲卡進(jìn)行芯片內(nèi)的寄存器設(shè)置了。

    回到我們的RTL8029芯片。

    是時候按照datasheet上的說明,來初始化網(wǎng)卡,獲取網(wǎng)卡的mac地址,等操作了。

    這些操作是數(shù)據(jù)接收和發(fā)送的基礎(chǔ)步驟。


    發(fā)送數(shù)據(jù)前的準(zhǔn)備工作:讀取網(wǎng)卡的MAC地址

    網(wǎng)卡的初始化init比較繁瑣,需要設(shè)置一大堆的寄存器。

    我先把代碼放出來,然后再解釋這些代碼:

    // 先關(guān)閉網(wǎng)卡,然后設(shè)置接收數(shù)據(jù)的內(nèi)存區(qū)域信息,中斷信息,以及如果對接收的數(shù)據(jù)過濾
    void netcard_init()
    {
    	unsigned int  base_addr=0xC100;// 訪問網(wǎng)卡的內(nèi)部寄存器,只用訪問的I/O地址0xC100即可
    	io_out8(base_addr,0x21);// 設(shè)置page0,并且停止顯卡的一切操作。這里涉及到CR寄存器的所有8位的意義,在datasheet中有詳細(xì)解釋;
    	io_out8(base_addr+1,0x4c);// 寫PSTART寄存器,即接收數(shù)據(jù)的內(nèi)存的開始地址為0x4c頁
    	io_out8(base_addr+2,0x80);// 寫PSTOP寄存器,即接收數(shù)據(jù)的內(nèi)存的結(jié)束地址為0x80頁
    	io_out8(base_addr+3,0x4c);// 當(dāng)前接收到的最后一個數(shù)據(jù)所在的頁
    	io_out8(base_addr+4,0x45);// 當(dāng)前發(fā)送的第一數(shù)據(jù)所在的頁
    	io_out8(base_addr+0xc,0xcc);//RCR:決定哪些數(shù)據(jù)接收,哪些數(shù)據(jù)不接收
    	io_out8(base_addr+0xd,0xe0);//TCR:決定哪些數(shù)據(jù)發(fā)送,哪些數(shù)據(jù)不發(fā)送
    	io_out8(base_addr+0xe,0xc8);//DCR:決定處理數(shù)據(jù)時按照怎樣的順序,怎樣的長度,是否loopback
    	io_out8(base_addr+0xf,0x00);//IMR:決定開啟哪些中斷,這些設(shè)置為00,關(guān)閉所有中斷
    
      // 開始去設(shè)置page1的寄存器
    	page_select(1);
    	io_out8(base_addr+7,0x4c+1); // CURR, FIFO中,要存儲的下一頁數(shù)據(jù)的地址
    	io_out8(base_addr+8,0x00); // MAR0 // 多播地址的過濾
    	io_out8(base_addr+9,0x41); // MAR1
    	io_out8(base_addr+10,0x00);// MAR2
    	io_out8(base_addr+11,0x80);// MAR3
    	io_out8(base_addr+12,0x00);// MAR4
    	io_out8(base_addr+13,0x00);// MAR5
    	io_out8(base_addr+14,0x00);// MAR6
    	io_out8(base_addr+15,0x00);// MAR7
    	// 初始化完成,開啟網(wǎng)卡
    	io_out8(base_addr,0x22); //與開始的0x21對應(yīng),0x21是關(guān)閉網(wǎng)卡,0x22是開啟網(wǎng)卡
    	return;
    }




    CR寄存器每一bit的作用

    可以對照CR寄存器的詳細(xì)解釋,看0x21。 其中PS1,PS0=00,即page0.

    RD2,RD1,RD0位100,即Abort/Complete remote DMA

    然后TXP=0,即has no effect.

    STA=0,這一位不控制任何事情,controls nothing.

    STP=1,關(guān)閉網(wǎng)卡。即不再接收和發(fā)送任何的數(shù)據(jù)包。


    PSTART設(shè)置了網(wǎng)卡內(nèi)部用于接收數(shù)據(jù)的內(nèi)存區(qū)域的開始地址。

    PSTOP設(shè)置了網(wǎng)卡內(nèi)部用于存儲數(shù)據(jù)的內(nèi)存區(qū)域的結(jié)束地址。

    BNRY,接收的最后一個數(shù)據(jù)的地址。BNRY是boundary的縮寫,表示接收數(shù)據(jù)的邊界。

    TPSR,發(fā)送數(shù)據(jù)的地址,它是Transmet Page Start Register的縮寫。

    這4個寄存器設(shè)置了收到數(shù)據(jù)的存放位置。

    需要注意的是,這里的數(shù)據(jù)都是按page頁為單位處理的。

    每256個字節(jié)bytes為一頁page.

    所以PSTART=0x4C頁,PSTOP=0x80頁,那么這里一共包含0x80-0x4C=52頁。



    代碼中設(shè)置了RCR=0xcc

    這意味著MON=0,PRO=0,AM=1,AB=1,AR=0,SEP=0
    MON=0, 數(shù)據(jù)校驗(yàn)關(guān)
    PRO=0, MAC地址匹配的數(shù)據(jù)才接收
    AM=1,接受有多個目的地的數(shù)據(jù)
    AB=1,接受廣播的數(shù)據(jù)
    AR=0, 不接受少于64 bytes的數(shù)據(jù)
    SEP=0,不接受有錯誤的數(shù)據(jù)。

    這個寄存器果然如其名RCR,Receive Configuration Register,接收配置寄存器。用來配置哪些數(shù)據(jù)不接收,哪些數(shù)據(jù)接收。


    那么再看一個寄存器TCR,發(fā)送數(shù)據(jù)的配置寄存器

    	io_out8(base_addr+0xd,0xe0);//TCR:決定哪些數(shù)據(jù)發(fā)送,哪些數(shù)據(jù)不發(fā)送

    0xe0意味著OFST=0,ATD=0,LB1=0,LB0=0,CRC=0,
    OFST=0, 沖突偏移功能關(guān)閉
    ATD=0,關(guān)閉自動transmitter
    LB1=0,LB0=0,正常操作,沒有Loopback
    CRC=0,開啟CRC校驗(yàn)


    下一行代碼對應(yīng)的是DCR:


    io_out8(base_addr+0xe,0xc8);//DCR

    0xc8意味著:FT1=1,FT0=0,ARM=0,LS=1,LAS=0,BOS=0,WTS=0
    FT1=1,FT0=0,FIFO的閾值設(shè)置寄存器的bit1和 bit0位
    ARM=0, 發(fā)送沒有被執(zhí)行的包命令
    LS=1,正常操作,不進(jìn)行Loopback
    LAS=0,16-位的DMA
    BOS=0,MS byte placed on MD15-8,LS byte on MD7-0, 高位和低位的順序
    WTS=0: byte-wide DMA transfer ,DMA傳輸時的單位是byte還是word

    DCR中的位,都是選擇位。

    下一行代碼是是關(guān)于中斷的寄存器:


    IMR,與 ISR連用。每個bits對應(yīng)一個中斷interrupt.

    既然與ISR有關(guān)了,我們就把ISR看了:

    ISR配置在什么情況下觸發(fā)中斷的。
    RST:reset或者接收數(shù)據(jù)滿時觸發(fā)中斷
    RDC: 遠(yuǎn)程DMA操作完成時,觸發(fā)中斷。
    CNT:技術(shù)吻合時觸發(fā)中斷。
    OVW: 接收數(shù)據(jù)太多,太快,數(shù)據(jù)緩沖區(qū)滿時,觸發(fā)中斷
    TXE:因?yàn)闆_突造成發(fā)送數(shù)據(jù)取消,觸發(fā)中斷。
    RXE:接收數(shù)據(jù)時,CRC錯誤,幀對齊錯誤,包丟失時觸發(fā)中斷
    PTX:發(fā)送成功,產(chǎn)生中斷
    PRX:接收成功,產(chǎn)生中斷

    再往后的代碼:

    	page_select(1);
    	io_out8(base_addr+7,0x4d); // CURR 當(dāng)前正在寫的頁的下一頁
    	io_out8(base_addr+8,0x00); // MAR0
    	io_out8(base_addr+9,0x41); // MAR1
    	io_out8(base_addr+10,0x00);// MAR2
    	io_out8(base_addr+11,0x80);// MAR3
    	io_out8(base_addr+12,0x00);// MAR4
    	io_out8(base_addr+13,0x00);// MAR5
    	io_out8(base_addr+14,0x00);// MAR6
    	io_out8(base_addr+15,0x00);// MAR7


    CUPR就相當(dāng)于FIFO中P, 接收到下一個數(shù)據(jù)的時候,所存放的頁地址。

    關(guān)于FIFO可以看這里:30天自制操作系統(tǒng)day07:使鼠標(biāo)指針可移動

    MAR0-7:多播地址寄存器,過濾那些具有多地址的數(shù)據(jù)。


    網(wǎng)卡的初始化工作終于完成了,可以讀取網(wǎng)卡的MAC地址了,使用如下代碼:

    void read_nodeid(unsigned int  base_addr,union u *mynodeid)
    {
    	unsigned char i,temp;
      union u protocal;// temp var
    
    	page_select(0);
      // 從dma的0x0000開始讀取數(shù)據(jù),因?yàn)閙ac地址在其前12個字節(jié),所以從0x0000開始讀取
    	io_out8(base_addr+9,0x00);//RSAR1:the high address of  dma read
    	io_out8(base_addr+8,0x00);//RSAR0:the low address of  dma read
      // 一共讀取0x000c個字節(jié)
    	io_out8(base_addr+0xb,0x00);// RBCR1: the high bits of  read count.
    	io_out8(base_addr+0xa,0x0c);//RBCR0: the low bits of read count
    	io_out8(base_addr,0x0a);//CR寄存器中,開啟remote read 然后開啟網(wǎng)卡
    	//for循環(huán)把mac地址讀取進(jìn)來
      for(i=0;i<6;i++)
    	{
    		temp=io_in8(base_addr+0x10);//從dma讀取一個byte
    		if(i%2==0){
                protocal.bytes.high=temp;
    		}
    		else{
                protocal.bytes.low=temp;
                mynodeid[i/2].word=protocal.word;
    		}
    		temp=io_in8(base_addr+0x10);//從dma讀取一個byte,由于這個byte跟上個byte一樣,所以不用存儲
    	}
        return;
    }


    RSAR0,1,這兩位設(shè)置了讀取remote DMA的開始地址.

    RBCR0,1, 這兩位設(shè)置了從remote DMA讀取多少個byte.

    注意到,這個代碼中,使用一個聯(lián)合體數(shù)據(jù)結(jié)構(gòu):

    //存儲mac地址中的一個字
    // 利用這樣的一個聯(lián)合體,方便的把字的高8位,低8位拆出來。
    union u {
     	unsigned int word;
     	struct{
       	    unsigned char high;
            unsigned char low;
        }bytes;
        char addr[2];
    };

    還有,為什么丟掉一個byte,因?yàn)椋?/p>

    remote read時,存儲在0x0000-0x000b里的網(wǎng)卡物理地址0x52544CC118CF是這樣的:

    525254544C4CC1C11818CFCF

    這12字節(jié)把網(wǎng)卡地址重復(fù)存儲了一次。

    不過這樣存儲,單和雙的地址存儲的是一樣的。

    其實(shí)存儲在0x000b后面的是生產(chǎn)廠商的代碼和產(chǎn)品標(biāo)識代碼,也是單雙地址重復(fù)存儲。

    我們就先不去讀生成廠商的代碼和產(chǎn)品表示了。


    以上代碼最后讀取到的MAC地址結(jié)果為::

    可以看到,讀取到的Mac地址為54-52-12-00-56-34。

    讀取到了網(wǎng)卡的MAC地址,就可以在發(fā)送數(shù)據(jù)包的時候,加上這個地址了。

    我們理使用網(wǎng)卡發(fā)送數(shù)據(jù)越來越近了。

    總結(jié)

    今天利用配置信息中的Vendor_id=0x10ec和device_id=0x8029,我們對應(yīng)了網(wǎng)卡的生產(chǎn)商為Realtek,網(wǎng)卡里芯片的具體型號為8029.

    根據(jù)這寫信息,我么找到了這款網(wǎng)卡芯片的操作手冊datasheet.

    芯片的操作手冊就是芯片的使用說明了,里面詳細(xì)地介紹了如何使用芯片里的寄存器來控制芯片接收數(shù)據(jù),發(fā)送數(shù)據(jù)。一旦拿到芯片的操作手冊,我們其實(shí)已經(jīng)里操作網(wǎng)卡芯片發(fā)送數(shù)據(jù)很近了。

    這里面涉及到兩方面的知識:如果去操作網(wǎng)卡里的寄存器,以及網(wǎng)卡里都有哪些寄存器。

    通過CPI配置信息中的BAR就可以獲取到一個地址,通過這個地址,我們就可以用io_in8(地址)命令讀取到網(wǎng)卡內(nèi)的寄存器值。用io_out8(地址)往網(wǎng)卡的寄存器的值內(nèi)寫入內(nèi)容,達(dá)到控制網(wǎng)卡的目的。

    網(wǎng)卡的操作手冊datasheet里有對網(wǎng)卡里的寄存器的詳細(xì)說明。

    我們參考著這份datasheet完成了對網(wǎng)卡打開,關(guān)閉,設(shè)置接收數(shù)據(jù)緩沖區(qū),設(shè)置中斷等初始化工作,并讀取了屬于這個網(wǎng)卡的mac地址。

    今天的工作先到這里,后續(xù)就可以開始真正的使用網(wǎng)絡(luò)傳輸協(xié)議來收發(fā)數(shù)據(jù)了。



    附錄

    記錄一些寫代碼過程中的bug,以及debug的過程。

    在讀取網(wǎng)卡內(nèi)部的寄存器時,一開始讀取總是失敗的,后來更改了地址變量的類型后

    讀取物理地址就成功了。

    由unsigned char base_addr,

    	unsigned int bar=io_in32(0xCFC);
           unsigned char base_addr=bar&0x0000ff00;
           if(class_code==2){
    						 page_select(3);
                 unsigned int CR=io_in8(base_addr);
                 bar=CR;
    
    	}

    改為了unsigned int base_addr

    	unsigned int bar=io_in32(0xCFC);
           unsigned int base_addr=bar&0x0000ff00;
           if(class_code==2){
    						 page_select(3);
                 unsigned int CR=io_in8(base_addr);
                 bar=CR;
    
    	}

    就成功了。

    寫代碼時,主要參考了RTL8019AS的--以太網(wǎng)協(xié)議:http://www.doczj.com/doc/cb952888.html

    這個代碼讓我把看到的一些介紹信息和具體的芯片聯(lián)系起來,總算把datasheet看懂了個大概。

    另外,對BAR的理解其實(shí)又用的知識挺多,但是我們這里只是用到了部分信息,我是通過一下地址以及圖片學(xué)習(xí)了BAR的相關(guān)設(shè)置的:






    一個介紹比較完整的資料是:https://www.pianshen.com/article/40881826037/

    卡的MAC地址原來這么不簡單

    概念

    每個網(wǎng)卡只有一個 MAC 地址, MAC 地址是燒錄到硬件上,也稱為硬件地址。

    MAC地址相當(dāng)于互聯(lián)中的身份證號,全球唯一。

    MAC 地址由 6 個字節(jié)組成,前 3 個字節(jié)表示每個網(wǎng)卡廠商識別碼,后 3 個字節(jié)是廠商內(nèi)識別碼是廠商內(nèi)部為自己所產(chǎn)網(wǎng)卡進(jìn)行分配的編號。

    MAC 地址的6 個字節(jié)是使用十六進(jìn)制編制,每個字節(jié)的 8 位二進(jìn)制數(shù)分別用 2 個十六進(jìn)制數(shù)來表示,例如:

    有人說,那世界上有多數(shù)個MAC可供大家使用,答案是2的48次方,也即是281474976710656個,怎么讀呢?二百八十一萬四千七百四十九億七千六百七十一萬零六百五十六。夠用嗎,請把你的看法發(fā)到評論區(qū),大家一塊探討?

    網(wǎng)絡(luò)設(shè)備廠商也并不能隨意的使用Mac地址,需要向IEEE(電氣與電子工程師協(xié)會)申請,當(dāng)然廠商申請需要付費(fèi)

    網(wǎng)卡的工作原理

    在基于TCP/IP協(xié)議的網(wǎng)絡(luò)中,兩臺主機(jī)之間傳輸數(shù)據(jù)時,數(shù)據(jù)由發(fā)送主機(jī)的應(yīng)用層自上而下傳遞,依次經(jīng)過傳輸層、網(wǎng)絡(luò)層及數(shù)據(jù)鏈路層的封裝,成為數(shù)據(jù)幀后發(fā)送到物理媒體。

    在接收主機(jī)上,數(shù)據(jù)的傳遞是自下而上的,依次經(jīng)過數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層及傳輸層的解封,最終提交給應(yīng)用層。在數(shù)據(jù)發(fā)送和接收的過程中,主機(jī)網(wǎng)卡發(fā)揮著重要作用。



    MAC地址是負(fù)責(zé)表示計算機(jī)的數(shù)據(jù)鏈路層地址。

    數(shù)據(jù)幀是怎么知道是誰發(fā)送方或接收方?

    答案:數(shù)據(jù)幀的幀頭中有源MAC地址和目的MAC地址。

    數(shù)據(jù)幀到達(dá)主機(jī)網(wǎng)卡時,網(wǎng)卡負(fù)責(zé)解讀數(shù)據(jù)幀,并檢查數(shù)據(jù)幀幀頭中的MAC地址字段。如果數(shù)據(jù)幀的目的MAC地址是自己的MAC地址或者是廣播地址,則產(chǎn)生中斷信號通知操作系統(tǒng)進(jìn)行相應(yīng)的處理,否則,數(shù)據(jù)幀將被丟棄。

    查看MAC地址方法

    Windows 命令窗口#:ipconfig -all

    Linux 命令窗口#:ifconfig -a

    MAC廠商對應(yīng)列表(部分)

    網(wǎng)卡類產(chǎn)品

    版權(quán)說明:請尊重原創(chuàng)版權(quán),版權(quán)歸本人所有。

    in7系統(tǒng)電腦可以修改MAC地址嗎?如何修改Win7系統(tǒng)MAC地址?下面就給大家分享Win7系統(tǒng)電腦設(shè)置MAC地址的操作方法。

    操作步驟:

    1、點(diǎn)擊右下角小電腦的圖標(biāo),然后點(diǎn)擊“打開網(wǎng)絡(luò)和共享中心”

    2、點(diǎn)擊左側(cè)“更改適配器設(shè)置”

    3、右擊所需更改網(wǎng)卡圖標(biāo),點(diǎn)擊“屬性”

    4、點(diǎn)擊“配置”

    5、選擇“高級”——“網(wǎng)絡(luò)地址”

    6、勾選并填入期望的mac地址值,點(diǎn)擊確定即可

    7、更改完成后,可通過ipconfig /all命令查看mac地址是否更改

網(wǎng)站首頁   |    關(guān)于我們   |    公司新聞   |    產(chǎn)品方案   |    用戶案例   |    售后服務(wù)   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區(qū)    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權(quán)所有