Skip to content

Networking

Distendo edited this page May 15, 2026 · 1 revision

Networking

minios includes a custom TCP/IP stack and an RTL8139 NIC driver for networking in QEMU's user-mode slirp network.

RTL8139 NIC Driver

Features

  • PCI bus discovery (vendor 0x10EC, device 0x8139)
  • I/O-mapped register access
  • Ring-buffer DMA for transmit and receive
  • MAC address read from ROM

Key Registers

Register Offset Purpose
MAC 0x00 6-byte MAC address
TxStatus0 0x10 Transmit status
TxAddr0 0x20 Transmit buffer address
RxBuf 0x30 Receive buffer address
ChipCmd 0x37 Command register
RxBufPtr 0x38 Receive buffer read pointer (+0x10 compensation)
RxBufAddr 0x3A Receive buffer write pointer
TxConfig 0x40 Transmit config
RxConfig 0x44 Receive config
Cfg9346 0x50 EEPROM config
TxPoll 0xD9 Transmit poll
RxRingAddrLO 0xE4 Receive ring low address

Note: The RTL8139 in QEMU returns RxBufPtr - 0x10 when reading register 0x38. The driver compensates by adding 0x10.

TCP/IP Stack

The stack is entirely custom — no external networking library.

Layers

  1. ARP — Resolves IP addresses (10.0.2.15) to MAC addresses. Sends ARP requests and processes replies.
  2. IP — Packet send/receive with header checksum. Handles fragmentation? (minimal).
  3. TCP — Full handshake (SYN → SYN-ACK → ACK), sequence/acknowledgement number tracking, data transmission, connection close.
  4. DNS — Resolves hostnames over UDP (port 53) to QEMU's built-in DNS proxy at 10.0.2.3.
  5. HTTP — GET requests over TCP.

Network Configuration

  • Static IP: 10.0.2.15
  • Gateway: 10.0.2.2
  • DNS: 10.0.2.3
  • Network: 10.0.2.0/24

These are QEMU's default user-mode network addresses.

Polling Model

The stack is polling-basednet_poll() is called in the main loop to process incoming packets. Each iteration uses io_wait() (a single outb to port 0x80) to yield to QEMU's event loop. This is critical for slirp's async socket event processing.

HTTP Test

When networking initializes, the kernel runs an HTTP GET test:

HTTP OK: <response body>

This fetches /test.txt from 10.0.2.2:8080 (the host running QEMU). To test:

# On your host machine, serve a test file:
echo "Hello from minios!" > /tmp/test.txt
cd /tmp && python3 -m http.server 8080

# Then run minios:
qemu-system-i386 -kernel minios.bin -m 64 -vga std -nic user,model=rtl8139

Usage from Shell

The browser command opens the GUI web browser app, which uses the TCP/IP stack to fetch HTTP pages.

Debugging

Serial output includes network debug info:

NIC: RTL8139 found at IO 0x...
NET: NIC init failed

(or NET: NIC init OK on success).

The driver checks for the RTL8139 at PCI bus 0, device 3, function 0 (QEMU's default).

Clone this wiki locally