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

📄 ethernet.inc

📁 MenuetOS是一个用汇编开发的32/64位PC操作系统
💻 INC
📖 第 1 页 / 共 4 页
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                 ;;
;;  ETHERNET.INC                                                   ;;
;;                                                                 ;;
;;  Ethernet network layer for Menuet OS                           ;;
;;                                                                 ;;
;;  Version 0.4  22 September 2003                                 ;;
;;                                                                 ;;
;;  This file contains the following:                              ;;
;;      PCI bus scanning for valid devices                         ;;
;;      Table of supported ethernet drivers                        ;;
;;      Code to identify and activate a supported driver           ;;
;;      ARP handler                                                ;;
;;      Driver interface to the IP layer                           ;;
;;      Gateway support                                            ;;
;;                                                                 ;;
;;  Individual driver files are included here                      ;;
;;                                                                 ;;
;;  The PCI bus scanning code was ported from the etherboot        ;;
;;  5.0.6 project. The copyright statement for that code is        ;;
;;                                                                 ;;
;;          GNU GENERAL PUBLIC LICENSE                             ;;
;;             Version 2, June 1991                                ;;
;;                                                                 ;;
;;  remaining parts Copyright 2002 Mike Hibbett                    ;;
;;   mikeh@oceanfree.net                                           ;;
;;                                                                 ;;
;;  See file COPYING for details                                   ;;
;;                                                                 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;********************************************************************
;   Interface
;      ethernet_driver   called by stack_handler in stack.inc
;      eth_probe         called by app_stack_handler in stack.inc
;
;********************************************************************

; Some useful information on data structures

;     Ethernet Packet - ARP Request example
;
;   0                   1                   2                   3
;   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
;
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;   |       Dest   H/W Address                                      |
;   |                    ( 14 byte header )                         |
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;   |                               |     Source     H/W Address    |
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;   |                                                               |
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;   |    Protocol - ARP 08  06      |
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;   |  H/W Type  00           01    |  Protocol Type   08 00        |
;   |                   ( ARP Request packet )                      |
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;   | HLen    0x06  | PLen    0x04  |    OpCode        00   01      |
;   |               ( 0001 for request, 0002 for reply )            |
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;   | Source Hardware Address ( MAC Address )                       |
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;   |                               |  Source IP Address            |
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;   |                               | Destination Hardware Address  |
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;   |                                                               |
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;   | Destination IP Address                                        |
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

; Include individual drivers source files at this point.
; If you create a new driver, include it below.

include "RTL8029.INC"
include "I8255X.INC"
include "RTL8139.INC"
include "3C59X.INC"
include "SIS900.INC"
include "PCNET32.INC"

; DEBUGGING_STATE enables or disables output of received and transmitted
; data over the serial port
DEBUGGING_ENABLED           equ     1
DEBUGGING_DISABLED          equ     0
DEBUGGING_STATE             equ     DEBUGGING_DISABLED

; PCICards
; ========
; PCI vendor and hardware types for hardware supported by the above drivers
; If you add a driver, ensure you update this datastructure, otherwise the
; card will not be probed.
; Each driver is defined by 4 double words. These are
;   PCIVendorDevice  probeFunction ResetFunction PollFunction transmitFunction
; The last entry must be kept at all zeros, to indicate the end of the list
; As a PCI driver may support more than one hardware implementation, there may
; be several lines which refer to the same functions.
; The first driver found on the PCI bus will be the one used.

PCICARDS_ENTRY_SIZE         equ     20    ; Size of each PCICARDS entry

PCICards:
dd  0x12098086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit
dd  0x10298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit
dd  0x12298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit
dd  0x10308086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit
dd  0x24498086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit
dd  0x802910ec, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit
dd  0x12111113, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit
dd  0x813910ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
dd  0x590010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x592010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x597010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x595010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x595110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x595210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x900010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x900110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x900410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x900510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x900610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x900A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x905010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x905110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x905510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x905810b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x905A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x920010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x980010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x980510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x764610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x505510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x605510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x605610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x5b5710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x505710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x515710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x525710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x656010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x656210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x656410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x450010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd  0x09001039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit
dd  0x20001022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit
dd  0x26251022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit
dd  0x20011022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit
; following card is untested
dd  0x70161039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit 
dd  0,0,0,0,0  ; end of list marker, do not remove

; PCI Bus defines
PCI_HEADER_TYPE             equ     0x0e  ;8 bit
PCI_BASE_ADDRESS_0          equ     0x10  ;32 bit
PCI_BASE_ADDRESS_5          equ     0x24  ;32 bits
PCI_BASE_ADDRESS_SPACE_IO   equ     0x01
PCI_VENDOR_ID               equ     0x00  ;16 bit
PCI_BASE_ADDRESS_IO_MASK    equ     0xFFFFFFFC

ETHER_IP                    equ     0x0008      ; Reversed from 0800 for intel
ETHER_ARP                   equ     0x0608      ; Reversed from 0806 for intel
ETHER_RARP                  equ     0x3580
ARP_REQ_OPCODE              equ     0x0100
ARP_REP_OPCODE              equ     0x0200

arp_rx_count:       dd  0
ip_rx_count:        dd  0
dumped_rx_count:    dd  0
ip_tx_count:        dd  0
node_addr:          db  0,0,0,0,0,0
eth_rx_data_len:    dw  0
eth_status:         dd  0
io_addr:            dd  0
hdrtype:            db  0
vendor_device:      dd  0
pci_data:           dd  0
pci_dev:            dd  0
pci_bus:            dd  0

; These will hold pointers to the selected driver functions
drvr_probe:         dd  0
drvr_reset:         dd  0
drvr_poll:          dd  0
drvr_transmit:      dd  0

; These hold the destination Host identity for ARP responses
remote_ip_add:      dd  0
remote_hw_add:      db  0, 0, 0, 0, 0, 0
broadcast_add:      db  0xff,0xff,0xff,0xff,0xff,0xff

; This is used by getMACfromIP
MACAddress:         db  0,0,0,0,0,0
gateway_ip:         db  0, 0, 0, 0
subnet_mask:        dd  0x00ffffff
dns_ip:             dd  0

; The follow is the ARP Table.
; This table must be manually updated and the kernel recompilied if
; changes are made to it.
; ARP_TABLE_SIZE defines the size of the table
; ARP_TABLE_ENTRIES defines the number of entries in the table
; Each entry is 10 bytes: 4 Byte IP address, 6 byte MAC Address,
;                         2 bytes status, 2 bytes TTL ( in seconds )
; Empty entries are filled with zeros
; The TTL field is decremented every second, and is deleted when it
; reaches 0. It is refreshed every time a packet is received
; If the TTL field is 0xFFFF it is a permanent entry and is never deleted
; The status field can be the following values
; 0x0000  entry not used
; 0x0001  entry holds a valid mapping
; 0x0002  entry contains an IP address, awaiting ARP response
; 0x0003  No response received to ARP request.
; The last status value is provided to allow the network layer to delete
; a packet that is queued awaiting an ARP response

ARP_NO_ENTRY                equ 0
ARP_VALID_MAPPING           equ 1
ARP_AWAITING_RESPONSE       equ 2
ARP_RESPONSE_TIMEOUT        equ 3

ARP_ENTRY_SIZE              equ     14          ; Number of bytes per entry
ARP_TABLE_SIZE              equ     20          ; Size of table
ARP_TABLE_ENTRIES           equ     0           ; Inital, hardcoded entries

ARPTable:
times ( ARP_TABLE_SIZE - ARP_TABLE_ENTRIES ) * ARP_ENTRY_SIZE  db 0

NumARP:        db    ARP_TABLE_ENTRIES

;***************************************************************************
;   Function
;      eth_probe
;   Description
;      Searches for an ethernet card. If found, the card is enabled and
;      the ethernet -> IP link established
;
;      This function scans the PCI bus looking for a supported device.
;      ISA bus is currently not supported.
;
;        eax is 0 if no hardware found
;***************************************************************************
eth_probe:
    ; Find a card on the PCI bus, and get it's address
    call    scan_bus                    ; Find the ethernet cards PIC address
    xor     eax, eax
    cmp     [io_addr], eax
    je      ep_00x                      ; Return 0 in eax if no cards found

    call    dword [drvr_probe]          ; Call the drivers probe function

    mov     eax, [io_addr]              ; return a non zero value

ep_00x:
    ret

;***************************************************************************
;   Function
;      ethernet_driver
;
;   Description
;       The ethernet RX and TX handler
;       This is a kernel function, called by stack_handler
;
;***************************************************************************
ethernet_driver:
    ; Do nothing if the driver is inactive
    cmp     [ethernet_active], byte 0
    je      eth_exit

    call    eth_rx
    call    eth_tx

eth_exit:
    ret

;***************************************************************************
;   Function
;      eth_rx
;
;   Description
;      Polls the ethernet card for received data. Extracts if present
;       Depending on the Protocol within the packet:
;         ARP : Pass to ARP_handler. This may result in an ARP reply
;               being tx'ed
;         IP  : Store in an IP buffer
;
;***************************************************************************
eth_rx:
    xor     ax, ax
    mov     [eth_rx_data_len], ax
    call    dword [drvr_poll]       ; Call the drivers poll function

    mov     ax, [eth_rx_data_len]
    cmp     ax, 0
    je      erx_exit

if DEBUGGING_STATE = DEBUGGING_ENABLED
    pusha
    mov     eax, 0                    ;Indicate that this is a received packet
    mov     cx, [eth_rx_data_len]
    mov     esi, Ether_buffer
    cmp     word [esi + 12], ETHER_IP
    jnz     erxd_done
;    cmp     byte [esi + 14 + 9], 0x06  ; TCP
;    jnz     erxd_done
    call    eth_dump
erxd_done:
    popa
end if

    ; Check the protocol. Call appropriate handler
    mov     eax, Ether_buffer
    add     eax, 12                  ; The address of the protocol word

    mov     ax, [eax]

    cmp     ax, ETHER_ARP
    je      erx_001                  ; It is ARP

    cmp     ax, ETHER_IP
    je      erx_002                  ; It's IP

;    inc     dword [dumped_rx_count]

    jmp     erx_exit               ; If not IP or ARP, ignore

erx_001:
    mov     eax, [arp_rx_count]
    inc     eax
    mov     [arp_rx_count], eax

    ; At this point, the packet is still in the Ether_buffer
    call    arp_handler

    jmp     erx_exit

erx_002:
    mov     eax, [ip_rx_count]
    inc     eax
    mov     [ip_rx_count], eax

    ; Check to see if the MAC address is in our arp table
    ; refresh the arp ttl if so

    mov     esi, Ether_buffer
    add     esi, 6

    call    refreshARP

    call    ether_IP_handler

    jmp     erx_exit

erx_exit:
    ret

;***************************************************************************
;   Function
;      eth_tx
;
;   Description
;      Looks at the NET1OUT_QUEUE for data to send.
;      Stores that destination IP in a location used by the tx routine
;      Looks up the MAC address in the ARP table; stores that where
;      the tx routine can get it
;      Get the length of the data. Store that where the tx routine wants it
;      Call tx
;      Places buffer on empty queue when the tx routine finished
;
;***************************************************************************
eth_tx:
    ; Look for a buffer to tx
    mov     eax, NET1OUT_QUEUE
    call    dequeue
    cmp     ax, NO_BUFFER
    je      eth_exit            ; Exit if no buffer available

    push    eax

    ; convert buffer pointer eax to the absolute address
    mov     ecx, IPBUFFSIZE
    mul     ecx
    add     eax, IPbuffs

    ; Extract the destination IP
    ; find the destination IP in the ARP table, get MAC
    ; store this MAC in 'MACAddress'
    mov     ebx, eax               ; Save buffer address
    mov     edx, [ebx + 16]        ; get destination address

    ; If the destination address is 255.255.255.255,
    ; set the MACAddress to all ones ( broadcast )
    mov     [MACAddress], dword 0xffffffff
    mov     [MACAddress + 4], word 0xffff
    cmp     edx, 0xffffffff
    je      etx_send                ; If it is broadcast, just send

    call    getMACfromIP           ; Get the MAC address.

    cmp     eax, ARP_VALID_MAPPING
    jz      etx_send

    ; No valid entry. Are we waiting for a response?
    cmp     eax, ARP_AWAITING_RESPONSE
    jne     etx_001

    ; Re-queue the packet, and exit
    pop     ebx
    mov     eax, NET1OUT_QUEUE
    call    queue
    jmp     etx_exit

etx_001:
    ; HAs the request been sent, but timed out?
    cmp     eax, ARP_RESPONSE_TIMEOUT

⌨️ 快捷键说明

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