feat: Eliminate all stubs; implement real RTL8139 physical DMA ping, dmesg ring buffer, live scheduler thread list, and physical RAM stats

This commit is contained in:
RarDog
2026-09-02 20:24:02 +03:00
parent aa32cffd15
commit c98c8de9d4
13 changed files with 510 additions and 141 deletions
+22 -18
View File
@@ -4,9 +4,8 @@
#include "stdio.h"
// Default QEMU User Networking (SLIRP) Configuration
// Guest IP: 10.0.2.15 (0x0F02000A)
// Gateway: 10.0.2.2 (0x0202000A)
// Netmask: 255.255.255.0
// Guest IP: 10.0.2.15
// Gateway: 10.0.2.2 (Default QEMU MAC: 52:55:0a:00:02:02)
net_config_t g_net_cfg = {
.ip = (10) | (0 << 8) | (2 << 16) | (15 << 24),
.gateway = (10) | (0 << 8) | (2 << 16) | (2 << 24),
@@ -14,17 +13,12 @@ net_config_t g_net_cfg = {
.mac = {0x52, 0x54, 0x00, 0x12, 0x34, 0x56}
};
static uint8_t g_gateway_mac[6] = {0x52, 0x55, 0x0a, 0x00, 0x02, 0x02};
static uint16_t htons(uint16_t v) {
return (uint16_t)(((v & 0xFF) << 8) | ((v >> 8) & 0xFF));
}
static __attribute__((unused)) uint32_t htonl(uint32_t v) {
return (((v & 0xFF) << 24) |
(((v >> 8) & 0xFF) << 16) |
(((v >> 16) & 0xFF) << 8) |
((v >> 24) & 0xFF));
}
uint16_t net_checksum(const void *buf, size_t len) {
const uint16_t *data = (const uint16_t *)buf;
uint32_t sum = 0;
@@ -47,6 +41,8 @@ void net_init(void) {
for (int i = 0; i < 6; i++) {
g_net_cfg.mac[i] = g_rtl8139.mac[i];
}
// Send initial ARP request to resolve gateway MAC
net_send_arp_request(g_net_cfg.gateway);
}
int net_send_arp_request(uint32_t target_ip) {
@@ -59,7 +55,7 @@ int net_send_arp_request(uint32_t target_ip) {
memcpy(eth->src_mac, g_net_cfg.mac, 6);
eth->ethertype = htons(ETHERTYPE_ARP);
// ARP Payload
// ARP Payload (Who has target_ip? Tell sender_ip)
arp->hw_type = htons(1); // Ethernet
arp->proto_type = htons(0x0800); // IPv4
arp->hw_len = 6;
@@ -80,8 +76,8 @@ int net_send_icmp_ping(uint32_t target_ip, uint16_t seq) {
icmp_hdr_t *icmp = (icmp_hdr_t *)(packet + sizeof(eth_hdr_t) + sizeof(ipv4_hdr_t));
uint8_t *payload = packet + sizeof(eth_hdr_t) + sizeof(ipv4_hdr_t) + sizeof(icmp_hdr_t);
// 1. Ethernet Header (Direct to Gateway or Broadcast MAC in QEMU SLIRP)
memset(eth->dest_mac, 0xFF, 6);
// 1. Ethernet Header (Direct unicast to resolved gateway MAC)
memcpy(eth->dest_mac, g_gateway_mac, 6);
memcpy(eth->src_mac, g_net_cfg.mac, 6);
eth->ethertype = htons(ETHERTYPE_IPv4);
@@ -104,7 +100,6 @@ int net_send_icmp_ping(uint32_t target_ip, uint16_t seq) {
icmp->id = htons(0x1234);
icmp->sequence = htons(seq);
// 32-byte payload pattern: 'a', 'b', 'c'...
for (int i = 0; i < 32; i++) {
payload[i] = (uint8_t)('a' + (i % 26));
}
@@ -120,12 +115,22 @@ int net_poll_icmp_reply(uint32_t *from_ip, uint16_t *seq) {
uint8_t buffer[1600];
int len = rtl8139_poll_packet(buffer, sizeof(buffer));
if (len < (int)(sizeof(eth_hdr_t) + sizeof(ipv4_hdr_t) + sizeof(icmp_hdr_t))) {
if (len < (int)sizeof(eth_hdr_t)) {
return 0;
}
eth_hdr_t *eth = (eth_hdr_t *)buffer;
if (htons(eth->ethertype) != ETHERTYPE_IPv4) {
// Handle ARP Reply to dynamically update gateway MAC
if (htons(eth->ethertype) == ETHERTYPE_ARP && len >= (int)(sizeof(eth_hdr_t) + sizeof(arp_hdr_t))) {
arp_hdr_t *arp = (arp_hdr_t *)(buffer + sizeof(eth_hdr_t));
if (htons(arp->opcode) == 2) { // ARP Reply
memcpy(g_gateway_mac, arp->sender_mac, 6);
}
return 0;
}
if (htons(eth->ethertype) != ETHERTYPE_IPv4 || len < (int)(sizeof(eth_hdr_t) + sizeof(ipv4_hdr_t) + sizeof(icmp_hdr_t))) {
return 0;
}
@@ -140,7 +145,7 @@ int net_poll_icmp_reply(uint32_t *from_ip, uint16_t *seq) {
if (icmp->type == ICMP_ECHO_REPLY) {
if (from_ip) *from_ip = ip->src_ip;
if (seq) *seq = htons(icmp->sequence);
return 1; // Got Echo Reply!
return 1; // Genuine Echo Reply received!
}
return 0;
@@ -162,7 +167,6 @@ uint32_t parse_ip(const char *str) {
void format_ip(uint32_t ip, char *buf) {
uint8_t *b = (uint8_t *)&ip;
// Simple itoa formatting
int len = 0;
for (int i = 0; i < 4; i++) {
uint8_t val = b[i];
+30 -7
View File
@@ -53,35 +53,58 @@ int vsnprintf(char *buf, size_t size, const char *fmt, __builtin_va_list args) {
}
fmt++; // skip '%'
int left_align = 0;
char pad = ' ';
int width = 0;
if (*fmt == '0') {
pad = '0';
while (*fmt == '-' || *fmt == '0') {
if (*fmt == '-') left_align = 1;
if (*fmt == '0') pad = '0';
fmt++;
}
int width = 0;
while (*fmt >= '0' && *fmt <= '9') {
width = width * 10 + (*fmt - '0');
fmt++;
}
int is_long = 0;
while (*fmt == 'l' || *fmt == 'z' || *fmt == 'h') {
if (*fmt == 'l' || *fmt == 'z') is_long++;
fmt++;
}
if (*fmt == 's') {
const char *str = __builtin_va_arg(args, const char *);
if (!str) str = "(null)";
int slen = 0;
while (str[slen]) slen++;
if (!left_align) {
while (width > slen && out < size - 1) {
buf[out++] = pad;
width--;
}
}
while (*str && out < size - 1) {
buf[out++] = *str++;
}
if (left_align) {
while (width > slen && out < size - 1) {
buf[out++] = ' ';
width--;
}
}
} else if (*fmt == 'd' || *fmt == 'i') {
long long val = __builtin_va_arg(args, int);
long long val = (is_long) ? __builtin_va_arg(args, long long) : (long long)__builtin_va_arg(args, int);
if (val < 0) {
if (out < size - 1) buf[out++] = '-';
val = -val;
}
out += format_uint(buf + out, (unsigned long long)val, 10, width, pad);
} else if (*fmt == 'u') {
unsigned long long val = __builtin_va_arg(args, unsigned int);
unsigned long long val = (is_long) ? __builtin_va_arg(args, unsigned long long) : (unsigned long long)__builtin_va_arg(args, unsigned int);
out += format_uint(buf + out, val, 10, width, pad);
} else if (*fmt == 'x' || *fmt == 'X') {
unsigned long long val = __builtin_va_arg(args, unsigned int);
unsigned long long val = (is_long) ? __builtin_va_arg(args, unsigned long long) : (unsigned long long)__builtin_va_arg(args, unsigned int);
out += format_uint(buf + out, val, 16, width, pad);
} else if (*fmt == 'p') {
unsigned long long val = (unsigned long long)__builtin_va_arg(args, void *);
@@ -111,7 +134,7 @@ int sprintf(char *buf, const char *fmt, ...) {
}
int printf(const char *fmt, ...) {
char buf[1024];
char buf[2048];
__builtin_va_list args;
__builtin_va_start(args, fmt);
int len = vsnprintf(buf, sizeof(buf), fmt, args);