NIC

John·2025년 6월 14일

system programming

목록 보기
9/11

NIC(Network Interface Card)은 여러 interface(=ports, endpoints)를 가지고 있는 디바이스이다.

NIC as a Hardware

  • NIC은 하드웨어다.

  • 내장형, 외장형 존재

  • PCIe bus로 연결
    *PCIe(Peripheral Componenet Interconnect Express) : CPU와 디바이스 연결하기 위한 버스(인터페이스)

  • PC에 NIC가 인식되면, 얼마나 많은 인터페이스가 NIC에 있는지 확인.

  • 인터페이스 수 만큼 struct net_device 생성(e.g. eth0) --> HW와 SW가 서로 구현되는 포인트.

struct net_device : an Interface Between HW and SW

  • NIC의 인터페이스는 struct net_device로 관리된다.
  • 구조체는 각 인터페이스 마다 하나씩 생성된다.
  • 구조체의 function pointer들은 L2, device driver과 연결되어 있다.

ex) L2에서 dev_queue_xmit() 함수 실행 -> struct net_device 안의 ndo_start_xmit() 함수 호출 -> 디바이스 드라이버의 ..._xmit()(드라이버 종류마다 다름) 호출
-- 중간 단계가 있어 디바이스 드라이버를 바꿔도 mapping을 통해 연결되어 있으므로 다양한 드라이버에 대응 가능.
<포함하는 것>

  • HW 정보 (e.g. interrupt/ports/정의된 driver function 등등)
  • HW의 메타데이터 (IP 주소 등)
  • function pointer

structure of struct net_device

*참고 자료 : https://flylib.com/books/en/3.475.1.34/1/

*open, stop, hard_start_xmit에 연결된 function은 NIC1_ndo_open(), NIC1_ndo_stop() , NIC1_ndo_start_xmit() 이다. (그림의 adapter...() 부분)

*ndo = net device operations

  • L2에서 dev_open()을 날리면 struct net_device안의 ndo_init()이 실행되어 여러 변수들(메타데이터들)이 채워진다.

Device Driver

  • 디바이스 드라이버에는 요구되는 함수로 실행되는 다양한 역할을 수행해야 한다. (ex. 송수신)

  • 송수신 시, DMA에 의해 데이터 copy가 일어난다. copy를 위한 TX, RX ring 존재
    * ex) 송신 시, 메인메모리의 어디부터 어디까지(address + length)를 DMA에 주면 DMA가 copy.

  • TX ring : 전송해야 할 패킷(skb)의 address & length 저장

  • RX ring : 저장할 skb의 address & length 저장

  • 디바이스 드라이버가 init될 때 ring또한 준비.

*address는 물리주소
* 패킷 자체가 ring에 들어가는 것이 아님

TX in NIC

메인 메모리 -> NIC으로 데이터가 전달되는 과정.

과정은 다음과 같다.

  1. CPU가 인터페이스 상태 체크 후 TX ring에 패킷의 addr & length(=패킷 디스크립터) 추가.
  2. NIC에게 write할 새 데이터가 있다고 알림.
  3. DMA가 TX ring으로부터 패킷 디스크립터 fetch
  4. 디스크립터 보고 실제 패킷 데이터(skb) fetch
  5. 패킷 전송

RX in NIC

NIC에 도착한 패킷 -> 메인메모리로 전달되는 과정은 다음과 같다.

우선, RX ring이 초기화 될 떄, 패킷 디스크립터 공간이 다음과 같이 주어진다.
rx_desc[i].buffer_addr = dma_map_single(dev, rx_buf[i], BUF_SIZE, DMA_FROM_DEVICE); //DMA가 복사할 주소. 실제 주소는 rx_buf[i]

  1. 패킷 도착
  2. DMA가 RX ring으로부터 패킷 디스크립터 fetch
  3. DMA가 패킷을 디스크립터 데이터 부분에 write
  4. NIC가 패킷이 도착해 copy까지 했다고 interrupt 발생시켜 CPU에게 알려줌.
  5. 디바이스 드라이버가 등록해놓은 interrupt handler 실행. 네트워킹 스택 스타트 (L2 - L3 - L4 - (recv queue)- 유저프로세스 순차적 실행).
profile
¡Salid y Disfrutad!

0개의 댓글