feat(renaser): Fase 18 — red: virtio-net y el primer hola al exterior

renaser hablaba consigo mismo. Esta fase abre una boca y una oreja al
exterior con una tarjeta de red, reutilizando el `KernelHal` del
disco y el mapeador MMIO (la pieza estructural que hizo esto posible).

- `drivers/red`: monta `VirtIONet<KernelHal, PciTransport, 16>`,
  expone `enviar(frame)` y `drenar_rx(callback)`. Sin pila TCP/IP —
  solo Ethernet crudo; la composición de paquetes la hace el llamante.
- `componer_arp_request(mac, ip, objetivo)` construye el saludo
  inicial: «¿quien tiene 10.0.2.2?» dirigido al gateway de QEMU.
- `interrupts::registrar_irq_red` + handler `irq_red`, gemelo del de
  disco. La IRQ del dispositivo activa `red::atender_irq`, que hace
  `ack_interrupt` y suelta la línea.
- `tarea_red` en el reactor: al arrancar envía el ARP, después cada
  fotograma drena la cola RX y vuelca cada paquete a COM1.
- QEMU args ganan `-netdev user,id=net0 -device virtio-net-pci`.

Verificado con `-object filter-dump,...,file=/tmp/red.pcap`:
  red :: virtio-net :: MAC 52:54:00:12:34:56 :: IRQ Some(11)
  red :: ARP REQUEST enviado :: ¿quien tiene 10.0.2.2?
  red :: RX 64 bytes :: src=52:55:0a:00:02:02 type=0x0806

El src del paquete entrante (`52:55:0a:00:02:02`) codifica `10.0.2.2`
dentro del MAC — es el gateway de QEMU respondiendo. Renaser ya habla
con el exterior.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
sergio
2026-05-23 04:06:23 +00:00
parent 60553bec44
commit bdd088b89e
9 changed files with 420 additions and 6 deletions
+37
View File
@@ -1119,3 +1119,40 @@ sigue ahí. La huella vive en el grafo de objetos, como todo lo demás.
texto justo donde quedó. El `almacen` reporta 24 objetos en el grafo
(frente a 9 antes de escribir) y `raiz presente`: cada `guardar` anexó
una versión al log direccionado por contenido.
## Fase 18 — Red: virtio-net y el primer hola al exterior — 2026-05-23
renaser hablaba consigo mismo. Con la misma plantilla del disco —enumerar
PCI, montar el transporte virtio, ceder a `virtio-drivers` el diálogo de
bajo nivel— y reutilizando el `KernelHal` y el mapeador `memory::mmio`,
el kernel abre ahora una boca y una oreja al exterior: una tarjeta de red.
### Añadido
- **Driver `drivers/red`** — monta `VirtIONet<KernelHal, PciTransport, 16>`,
enruta su IRQ vía el PIC, expone `enviar(frame)` y `drenar_rx(callback)`.
La cabeza del archivo guarda el MAC del dispositivo y las constantes de
IP de QEMU user-mode (`10.0.2.15` invitado, `10.0.2.2` gateway).
- **`componer_arp_request(mac, ip, objetivo)`** — construye un frame
Ethernet + ARP listo para enviar.
- **`interrupts::registrar_irq_red`** + `extern "x86-interrupt" irq_red`
— mismo patrón que la IRQ del disco. Acknowledge en el dispositivo,
EOI al PIC.
- **`KernelHal` se hace `pub`** para que `red` lo reutilice como su Hal
de DMA — la misma arena de marcos físicos que el disco. El mapeador
MMIO (Fase 13.5) cubre los BAR del nuevo dispositivo sin tocar nada.
- **`tarea_red`**: tras 10 fotogramas para que la cola RX se estabilice,
envía un ARP request al gateway de QEMU. Después, cada fotograma drena
la cola RX y vuelca cada paquete a COM1.
- **QEMU args**: `-netdev user,id=net0 -device virtio-net-pci,netdev=net0`
(user-mode networking, NAT virtual al host).
### Verificado
- QEMU con `-object filter-dump,...,file=/tmp/red.pcap`. Trazas COM1:
```
red :: virtio-net :: MAC 52:54:00:12:34:56 :: IRQ Some(11)
red :: ARP REQUEST enviado :: ¿quien tiene 10.0.2.2?
red :: RX 64 bytes :: dst=52:54:00:12:34:56 src=52:55:0a:00:02:02 type=0x0806
```
El src del paquete entrante codifica la IP del gateway dentro del MAC
(`52:55:0a:00:02:02` = QEMU prefix + `10.0.2.2`): la respuesta ARP es
legítima. Renaser ya habla con la red.