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:
+22
-18
@@ -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
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user