From 150183508b01254d8fe14e8fc698593c57c42f07 Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Thu, 24 Sep 2020 20:44:48 +0200 Subject: Restructured network stack --- kernel/Makefile | 3 +- kernel/drivers/net.c | 189 ----------------------------------------------- kernel/drivers/rtl8139.c | 131 ++++++++++++++++++++++++++++++++ kernel/features/net.c | 97 ++++++++++++++++++++++++ kernel/inc/net.h | 38 ++++------ kernel/inc/rtl8139.h | 33 +++++++++ 6 files changed, 278 insertions(+), 213 deletions(-) delete mode 100644 kernel/drivers/net.c create mode 100644 kernel/drivers/rtl8139.c create mode 100644 kernel/features/net.c create mode 100644 kernel/inc/rtl8139.h diff --git a/kernel/Makefile b/kernel/Makefile index 4334987..02f5156 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -9,13 +9,14 @@ COBJS = main.o \ drivers/mouse.o \ drivers/pci.o \ drivers/ide.o \ - drivers/net.o \ drivers/timer.o \ + drivers/rtl8139.o \ features/fs.o \ features/load.o \ features/proc.o \ features/proc_asm.o \ features/syscall.o \ + features/net.o \ features/event.o CC = ../cross/opt/bin/i686-elf-gcc LD = ../cross/opt/bin/i686-elf-ld diff --git a/kernel/drivers/net.c b/kernel/drivers/net.c deleted file mode 100644 index 86c2fea..0000000 --- a/kernel/drivers/net.c +++ /dev/null @@ -1,189 +0,0 @@ -// MIT License, Copyright (c) 2020 Marvin Borner -// Uses parts of the ToAruOS Project, released under the terms of the NCSA -// Copyright (C) 2011-2018 K. Lange - -#include -#include -#include -#include -#include -#include -#include - -static u8 mac[6]; -static u8 *rx_buffer; -u32 current_packet_ptr; - -u16 flip_short(u16 short_int) -{ - u32 first_byte = *((u8 *)(&short_int)); - u32 second_byte = *((u8 *)(&short_int) + 1); - return (first_byte << 8) | (second_byte); -} - -u32 flip_long(u32 long_int) -{ - u32 first_byte = *((u8 *)(&long_int)); - u32 second_byte = *((u8 *)(&long_int) + 1); - u32 third_byte = *((u8 *)(&long_int) + 2); - u32 fourth_byte = *((u8 *)(&long_int) + 3); - return (first_byte << 24) | (second_byte << 16) | (third_byte << 8) | (fourth_byte); -} - -u8 flip_byte(u8 byte, int num_bits) -{ - u8 t = byte << (8 - num_bits); - return t | (byte >> num_bits); -} - -u8 htonb(u8 byte, int num_bits) -{ - return flip_byte(byte, num_bits); -} - -u8 ntohb(u8 byte, int num_bits) -{ - return flip_byte(byte, 8 - num_bits); -} - -u16 htons(u16 hostshort) -{ - return flip_short(hostshort); -} - -u32 htonl(u32 hostlong) -{ - return flip_long(hostlong); -} - -u16 ntohs(u16 netshort) -{ - return flip_short(netshort); -} - -u32 ntohl(u32 netlong) -{ - return flip_long(netlong); -} - -void ethernet_handle_packet(struct ethernet_packet *packet, int len) -{ - /* void *data = packet + sizeof(*packet); */ - printf("", len); - if (ntohs(packet->type) == ETHERNET_TYPE_ARP) - print("ARP PACKET\n"); - else if (ntohs(packet->type) == ETHERNET_TYPE_IP4) - print("IP4 PACKET\n"); - else if (ntohs(packet->type) == ETHERNET_TYPE_IP6) - print("IP6 PACKET\n"); - else - printf("UNKNOWN PACKET %x\n", ntohs(packet->type)); -} - -/** - * RTL8139 specific things - */ - -static int rtl_irq = 0; -static u32 rtl_device_pci = 0; -static u32 rtl_iobase = 0; - -void rtl_receive_packet() -{ - u16 *t = (u16 *)(rx_buffer + current_packet_ptr); - u16 length = *(t + 1); - t += 2; - - void *packet = malloc(length); - memcpy(packet, t, length); - ethernet_handle_packet(packet, length); - - current_packet_ptr = (current_packet_ptr + length + 4 + 3) & (~3); - - if (current_packet_ptr > RX_BUF_SIZE) - current_packet_ptr -= RX_BUF_SIZE; - - outw(rtl_iobase + RTL_PORT_RXPTR, current_packet_ptr - 0x10); -} - -void rtl8139_find(u32 device, u16 vendor_id, u16 device_id, void *extra) -{ - if ((vendor_id == 0x10ec) && (device_id == 0x8139)) { - *((u32 *)extra) = device; - } -} - -void rtl8139_irq_handler() -{ - print("RTL INT!\n"); - u16 status = inw(rtl_iobase + RTL_PORT_ISR); - if (!status) - return; - - if (status & RTL_TOK) { - printf("Sent packet\n"); - } else if (status & RTL_ROK) { - rtl_receive_packet(); - } - - outw(rtl_iobase + RTL_PORT_ISR, 0x5); -} - -void rtl8139_init() -{ - if (!rtl_device_pci) - return; - - u16 command_reg = (u16)pci_read_field(rtl_device_pci, PCI_COMMAND, 4); - if ((command_reg & (1 << 2)) == 0) { - command_reg |= (1 << 2); - pci_write_field(rtl_device_pci, PCI_COMMAND, command_reg); - } - - rtl_irq = pci_get_interrupt(rtl_device_pci); - irq_install_handler(rtl_irq, rtl8139_irq_handler); - - u32 rtl_bar0 = pci_read_field(rtl_device_pci, PCI_BAR0, 4); - /* u32 rtl_bar1 = pci_read_field(rtl_device_pci, PCI_BAR1, 4); */ - rtl_iobase = 0; - - if (rtl_bar0 & 0x00000001) - rtl_iobase = rtl_bar0 & (~0x3); - - // Get mac address - for (int i = 0; i < 6; ++i) - mac[i] = inb(rtl_iobase + RTL_PORT_MAC + i); - printf("Mac address: %x:%x:%x:%x:%x:%x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - - // Activate - outb(rtl_iobase + RTL_PORT_CONFIG, 0x0); - - // Reset - outb((u16)(rtl_iobase + RTL_PORT_CMD), 0x10); - while ((inb(rtl_iobase + RTL_PORT_CMD) & 0x10) != 0) - ; - - // Set receive buffer - rx_buffer = (u8 *)malloc(RX_BUF_SIZE); - memset(rx_buffer, 0, RX_BUF_SIZE); - outl(rtl_iobase + RTL_PORT_RBSTART, (u32)rx_buffer); - - // Set TOK and ROK - outw(rtl_iobase + RTL_PORT_IMR, 0x0005); - - // AB+AM+APM+AAP except WRAP - outl(rtl_iobase + RTL_PORT_RCR, 0xf | (1 << 7)); - - // Enable receive and transmit - outb(rtl_iobase + RTL_PORT_CMD, 0x08 | 0x04); -} - -void net_install() -{ - pci_scan(&rtl8139_find, -1, &rtl_device_pci); - - if (rtl_device_pci) { - print("Found rtl8139 card\n"); - rtl8139_init(); - } -} diff --git a/kernel/drivers/rtl8139.c b/kernel/drivers/rtl8139.c new file mode 100644 index 0000000..e45864b --- /dev/null +++ b/kernel/drivers/rtl8139.c @@ -0,0 +1,131 @@ +// MIT License, Copyright (c) 2020 Marvin Borner +// Uses parts of the ToAruOS Project, released under the terms of the NCSA +// Copyright (C) 2011-2018 K. Lange + +#include +#include +#include +#include +#include +#include +#include +#include + +static u8 mac[6]; +static u8 *rx_buffer; +static u32 current_packet_ptr; + +static int rtl_irq = 0; +static u32 rtl_device_pci = 0; +static u32 rtl_iobase = 0; + +void rtl_receive_packet() +{ + u16 *t = (u16 *)(rx_buffer + current_packet_ptr); + u16 length = *(t + 1); + t += 2; + + void *packet = malloc(length); + memcpy(packet, t, length); + ethernet_handle_packet(packet, length); + + current_packet_ptr = (current_packet_ptr + length + 4 + 3) & (~3); + + if (current_packet_ptr > RX_BUF_SIZE) + current_packet_ptr -= RX_BUF_SIZE; + + outw(rtl_iobase + RTL_PORT_RXPTR, current_packet_ptr - 0x10); +} + +/* static u8 tsad_array[4] = { 0x20, 0x24, 0x28, 0x2C }; */ +/* static u8 tsd_array[4] = { 0x10, 0x14, 0x18, 0x1C }; */ +/* static u8 tx_current = 0; */ +/* void rtl_send_packet(void *data, u32 len) */ +/* { */ +/* outl(rtl_iobase + tsad_array[tx_current], (u32)data); */ +/* outl(rtl_iobase + tsd_array[tx_current++], len); */ +/* if (tx_current > 3) */ +/* tx_current = 0; */ +/* } */ + +void rtl8139_find(u32 device, u16 vendor_id, u16 device_id, void *extra) +{ + if ((vendor_id == 0x10ec) && (device_id == 0x8139)) { + *((u32 *)extra) = device; + } +} + +void rtl8139_irq_handler() +{ + print("RTL INT!\n"); + u16 status = inw(rtl_iobase + RTL_PORT_ISR); + if (!status) + return; + + if (status & RTL_TOK) { + printf("Sent packet\n"); + } else if (status & RTL_ROK) { + rtl_receive_packet(); + } + + outw(rtl_iobase + RTL_PORT_ISR, 0x5); +} + +void rtl8139_init() +{ + if (!rtl_device_pci) + return; + + u16 command_reg = (u16)pci_read_field(rtl_device_pci, PCI_COMMAND, 4); + if ((command_reg & (1 << 2)) == 0) { + command_reg |= (1 << 2); + pci_write_field(rtl_device_pci, PCI_COMMAND, command_reg); + } + + rtl_irq = pci_get_interrupt(rtl_device_pci); + irq_install_handler(rtl_irq, rtl8139_irq_handler); + + u32 rtl_bar0 = pci_read_field(rtl_device_pci, PCI_BAR0, 4); + /* u32 rtl_bar1 = pci_read_field(rtl_device_pci, PCI_BAR1, 4); */ + rtl_iobase = 0; + + if (rtl_bar0 & 0x00000001) + rtl_iobase = rtl_bar0 & (~0x3); + + // Get mac address + for (int i = 0; i < 6; ++i) + mac[i] = inb(rtl_iobase + RTL_PORT_MAC + i); + printf("Mac address: %x:%x:%x:%x:%x:%x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + // Activate + outb(rtl_iobase + RTL_PORT_CONFIG, 0x0); + + // Reset + outb((u16)(rtl_iobase + RTL_PORT_CMD), 0x10); + while ((inb(rtl_iobase + RTL_PORT_CMD) & 0x10) != 0) + ; + + // Set receive buffer + rx_buffer = (u8 *)malloc(RX_BUF_SIZE); + memset(rx_buffer, 0, RX_BUF_SIZE); + outl(rtl_iobase + RTL_PORT_RBSTART, (u32)rx_buffer); + + // Set TOK and ROK + outw(rtl_iobase + RTL_PORT_IMR, 0x0005); + + // AB+AM+APM+AAP except WRAP + outl(rtl_iobase + RTL_PORT_RCR, 0xf | (1 << 7)); + + // Enable receive and transmit + outb(rtl_iobase + RTL_PORT_CMD, 0x08 | 0x04); +} + +void rtl8139_install() +{ + pci_scan(&rtl8139_find, -1, &rtl_device_pci); + + if (rtl_device_pci) { + print("Found rtl8139 card\n"); + rtl8139_init(); + } +} diff --git a/kernel/features/net.c b/kernel/features/net.c new file mode 100644 index 0000000..fbc0289 --- /dev/null +++ b/kernel/features/net.c @@ -0,0 +1,97 @@ +// MIT License, Copyright (c) 2020 Marvin Borner + +#include +#include +#include +#include +#include + +u8 ntohb(u8 byte, int num_bits); +u16 ntohs(u16 netshort); +u32 ntohl(u32 netlong); + +void ip_handle_packet(struct ip_packet *packet, int len) +{ + /* printf("V%d\n", packet->version_ihl); */ + u32 test = (u32)packet->src_ip[0]; + u8 *ip = (u8 *)ntohl(test); + printf("IP %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); +} + +void ethernet_handle_packet(struct ethernet_packet *packet, int len) +{ + void *data = packet + sizeof(*packet); + int data_len = len - sizeof(*packet); + if (ntohs(packet->type) == ETHERNET_TYPE_ARP) { + print("ARP PACKET\n"); + } else if (ntohs(packet->type) == ETHERNET_TYPE_IP4) { + print("IP4 PACKET\n"); + ip_handle_packet(data, data_len); + } else if (ntohs(packet->type) == ETHERNET_TYPE_IP6) { + print("IP6 PACKET\n"); + ip_handle_packet(data, data_len); + } else { + printf("UNKNOWN PACKET %x\n", ntohs(packet->type)); + } +} + +void net_install() +{ + rtl8139_install(); +} + +/** + * Utilities + */ + +u16 flip_short(u16 short_int) +{ + u32 first_byte = *((u8 *)(&short_int)); + u32 second_byte = *((u8 *)(&short_int) + 1); + return (first_byte << 8) | (second_byte); +} + +u32 flip_long(u32 long_int) +{ + u32 first_byte = *((u8 *)(&long_int)); + u32 second_byte = *((u8 *)(&long_int) + 1); + u32 third_byte = *((u8 *)(&long_int) + 2); + u32 fourth_byte = *((u8 *)(&long_int) + 3); + return (first_byte << 24) | (second_byte << 16) | (third_byte << 8) | (fourth_byte); +} + +u8 flip_byte(u8 byte, int num_bits) +{ + u8 t = byte << (8 - num_bits); + return t | (byte >> num_bits); +} + +u8 htonb(u8 byte, int num_bits) +{ + return flip_byte(byte, num_bits); +} + +u8 ntohb(u8 byte, int num_bits) +{ + return flip_byte(byte, 8 - num_bits); +} + +u16 htons(u16 hostshort) +{ + return flip_short(hostshort); +} + +u32 htonl(u32 hostlong) +{ + return flip_long(hostlong); +} + +u16 ntohs(u16 netshort) +{ + return flip_short(netshort); +} + +u32 ntohl(u32 netlong) +{ + return flip_long(netlong); +} diff --git a/kernel/inc/net.h b/kernel/inc/net.h index b5193ed..211cf90 100644 --- a/kernel/inc/net.h +++ b/kernel/inc/net.h @@ -5,29 +5,6 @@ #include -#define RX_BUF_SIZE 0x3000 - -#define RTL8139_VENDOR_ID 0x10ec -#define RTL8139_DEVICE_ID 0x8139 - -#define RTL_ROK (1 << 0) -#define RTL_TOK (1 << 2) - -#define RTL_PORT_MAC 0x00 -#define RTL_PORT_MAR 0x08 -#define RTL_PORT_TXSTAT 0x10 -#define RTL_PORT_TXBUF 0x20 -#define RTL_PORT_RBSTART 0x30 -#define RTL_PORT_CMD 0x37 -#define RTL_PORT_RXPTR 0x38 -#define RTL_PORT_RXADDR 0x3A -#define RTL_PORT_IMR 0x3C -#define RTL_PORT_ISR 0x3E -#define RTL_PORT_TCR 0x40 -#define RTL_PORT_RCR 0x44 -#define RTL_PORT_RXMISS 0x4C -#define RTL_PORT_CONFIG 0x52 - #define ETHERNET_TYPE_IP4 0x0800 #define ETHERNET_TYPE_IP6 0x86dd #define ETHERNET_TYPE_ARP 0x0806 @@ -39,6 +16,21 @@ struct ethernet_packet { u8 data[]; } __attribute__((packed)); +struct ip_packet { + u8 version_ihl; + u8 dscp_ecn; + u16 length; + u16 id; + u8 flags_fragment; + u8 ttl; + u8 protocol; + u16 checksum; + u8 src_ip[4]; + u8 dst_ip[4]; + u8 data[]; +} __attribute__((packed)); + +void ethernet_handle_packet(struct ethernet_packet *packet, int len); void net_install(); #endif diff --git a/kernel/inc/rtl8139.h b/kernel/inc/rtl8139.h new file mode 100644 index 0000000..9e84a28 --- /dev/null +++ b/kernel/inc/rtl8139.h @@ -0,0 +1,33 @@ +// MIT License, Copyright (c) 2020 Marvin Borner + +#ifndef RTL8139_H +#define RTL8139_H + +#include + +#define RX_BUF_SIZE 0x3000 + +#define RTL8139_VENDOR_ID 0x10ec +#define RTL8139_DEVICE_ID 0x8139 + +#define RTL_ROK (1 << 0) +#define RTL_TOK (1 << 2) + +#define RTL_PORT_MAC 0x00 +#define RTL_PORT_MAR 0x08 +#define RTL_PORT_TXSTAT 0x10 +#define RTL_PORT_TXBUF 0x20 +#define RTL_PORT_RBSTART 0x30 +#define RTL_PORT_CMD 0x37 +#define RTL_PORT_RXPTR 0x38 +#define RTL_PORT_RXADDR 0x3A +#define RTL_PORT_IMR 0x3C +#define RTL_PORT_ISR 0x3E +#define RTL_PORT_TCR 0x40 +#define RTL_PORT_RCR 0x44 +#define RTL_PORT_RXMISS 0x4C +#define RTL_PORT_CONFIG 0x52 + +void rtl8139_install(); + +#endif -- cgit v1.2.3