feat: WiFi驱动(ath9k) + TTF字体 + shell命令行 + FirstInit WiFi跳过

新增: ath9k PCIe WiFi驱动(被动扫描/beacon解析), shell命令行(help/clear/echo/version/date/reboot/halt), Consolas 18px TTF字体, render_ascii.py

修改: dkm_net_api扩展scan接口, FirstInit无WiFi设备时跳过, DSK加载shell.elf, 非首次启动直接进shell
This commit is contained in:
xyou
2026-07-03 12:59:59 +08:00
parent 129175a5d8
commit 3662345434
31 changed files with 4437 additions and 240 deletions
+101 -10
View File
@@ -12,6 +12,7 @@ typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
typedef signed char i8;
typedef long long i64;
#define NULL ((void *)0)
@@ -22,6 +23,14 @@ struct dkm_log_api {
void (*panic)(const char *msg);
};
struct dkm_net_scan_result {
char ssid[33];
u8 bssid[6];
u8 channel;
i8 rssi;
u8 security;
};
struct dkm_net_device_desc {
const char *name;
u8 mac[6];
@@ -29,12 +38,23 @@ struct dkm_net_device_desc {
void *ctx;
int (*tx)(void *ctx, const void *packet, u32 length);
int (*rx_poll)(void *ctx, void *buffer, u32 capacity, u32 *out_length);
/* 无线扩展回调(有线驱动置 NULL,向后兼容)。 */
int (*scan_start)(void *ctx);
int (*scan_count)(void *ctx);
int (*scan_result)(void *ctx, u32 n, struct dkm_net_scan_result *out);
int (*is_wireless)(void *ctx);
};
struct dkm_net_api {
int (*register_device)(const struct dkm_net_device_desc *desc);
u32 (*device_count)(void);
int (*device_info)(u32 index, void *out);
int (*tx)(u32 index, const void *packet, u32 length);
int (*rx_poll)(u32 index, void *buffer, u32 capacity, u32 *out_length);
int (*scan_start)(u32 index);
int (*scan_count)(u32 index);
int (*scan_result)(u32 index, u32 n, struct dkm_net_scan_result *out);
int (*is_wireless)(u32 index);
};
struct dkm_dma_buffer {
@@ -95,6 +115,7 @@ const struct dkm_driver_desc driver_desc = {
#define PCI_DEVICE_ID 0x02
#define PCI_COMMAND 0x04
#define PCI_BAR0 0x10
#define PCI_BAR1 0x14
#define PCI_IRQ_LINE 0x3C
/* e1000 MMIO registers */
@@ -184,10 +205,10 @@ static u32 g_rx_tail;
static u32 g_tx_tail;
static int g_rings_ready;
static __inline__ void outl(u16 p, u32 v) { __asm__("outl %0,%1"::"a"(v),"Nd"(p)); }
static __inline__ u32 inl(u16 p) { u32 v; __asm__("inl %1,%0":"=a"(v):"Nd"(p)); return v; }
static u8 inb(u16 p) { u8 v; __asm__("inb %1,%0":"=a"(v):"Nd"(p)); return v; }
static void outb(u16 p, u8 v) { __asm__("outb %0,%1"::"a"(v),"Nd"(p)); }
static __inline__ void outl(u16 p, u32 v) { __asm__ volatile("outl %0,%1"::"a"(v),"Nd"(p):"memory"); }
static __inline__ u32 inl(u16 p) { u32 v; __asm__ volatile("inl %1,%0":"=a"(v):"Nd"(p):"memory"); return v; }
static u8 inb(u16 p) { u8 v; __asm__ volatile("inb %1,%0":"=a"(v):"Nd"(p):"memory"); return v; }
static void outb(u16 p, u8 v) { __asm__ volatile("outb %0,%1"::"a"(v),"Nd"(p):"memory"); }
static void raw_log(const char *s) {
while (*s) {
@@ -201,6 +222,17 @@ static void raw_log(const char *s) {
}
}
static void raw_hex(const char *prefix, u64 v) {
static const char h[] = "0123456789abcdef";
raw_log(prefix);
raw_log("0x");
for (int i=15; i>=0; i--) {
for (u32 wait=0; wait<100000; wait++) if (inb(0x3F8+5)&0x20) break;
outb(0x3F8, (u8)h[(v >> (i * 4)) & 0xf]);
}
raw_log("\n");
}
static u32 pci_read(u8 bus, u8 dev, u8 func, u8 reg) {
u32 a = (1u<<31)|((u32)bus<<16)|((u32)dev<<11)|((u32)func<<8)|((u32)reg&0xFC);
outl(PCI_ADDR,a); return inl(PCI_DATA);
@@ -253,6 +285,19 @@ static void copy_bytes(void *dst, const void *src, u32 len) {
for (u32 i=0;i<len;i++) d[i]=s[i];
}
static void zero_bytes(void *dst, u32 len) {
u8 *d = (u8 *)dst;
for (u32 i=0;i<len;i++) d[i]=0;
}
static void mmio_flush(void) {
if (g_mmio) (void)g_mmio[E1000_STATUS/4];
}
static void dma_fence(void) {
__asm__ volatile("" ::: "memory");
}
static int e1000_init_rings(const struct dkm_dma_api *dma) {
if (!dma || !dma->alloc_pages || !g_mmio) return -1;
@@ -269,8 +314,8 @@ static int e1000_init_rings(const struct dkm_dma_api *dma) {
if (dma->alloc_pages(1, 16, 0x100000000ULL, &b) != 0) return -4;
g_rx_buf[i] = (u8 *)b.virt;
g_rx_buf_phys[i] = b.phys;
zero_bytes(&g_rx_desc[i], sizeof(g_rx_desc[i]));
g_rx_desc[i].addr = b.phys;
g_rx_desc[i].status = 0;
}
for (u32 i=0;i<E1000_TX_DESC_COUNT;i++) {
@@ -278,13 +323,16 @@ static int e1000_init_rings(const struct dkm_dma_api *dma) {
if (dma->alloc_pages(1, 16, 0x100000000ULL, &b) != 0) return -5;
g_tx_buf[i] = (u8 *)b.virt;
g_tx_buf_phys[i] = b.phys;
zero_bytes(&g_tx_desc[i], sizeof(g_tx_desc[i]));
g_tx_desc[i].addr = b.phys;
g_tx_desc[i].status = E1000_TX_STA_DD;
}
dma_fence();
raw_log("[e1000.raw] ring/buffers allocated\n");
g_mmio[E1000_RCTL/4] = 0;
g_mmio[E1000_TCTL/4] = 0;
mmio_flush();
g_mmio[E1000_RDBAL/4] = (u32)(g_rx_desc_phys & 0xffffffffu);
g_mmio[E1000_RDBAH/4] = (u32)(g_rx_desc_phys >> 32);
@@ -305,8 +353,10 @@ static int e1000_init_rings(const struct dkm_dma_api *dma) {
g_mmio[E1000_TXDCTL/4] = (1u << 25);
g_mmio[E1000_TIPG/4] = 0x0060200Au;
dma_fence();
g_mmio[E1000_RCTL/4] = E1000_RCTL_EN | E1000_RCTL_UPE | E1000_RCTL_MPE | E1000_RCTL_BAM | E1000_RCTL_SECRC | E1000_RCTL_BSIZE_2048;
g_mmio[E1000_TCTL/4] = E1000_TCTL_EN | E1000_TCTL_PSP | (0x0Fu << E1000_TCTL_CT_SHIFT) | (0x40u << E1000_TCTL_COLD_SHIFT);
mmio_flush();
g_rings_ready = 1;
raw_log("[e1000.raw] RX/TX rings initialized\n");
@@ -316,32 +366,62 @@ static int e1000_init_rings(const struct dkm_dma_api *dma) {
static int e1000_tx(void *ctx, const void *packet, u32 length) {
(void)ctx;
raw_log("[e1000.raw] tx enter\n");
if (!g_rings_ready || !packet || length == 0 || length > E1000_RX_BUF_SIZE) return -1;
if (!g_rings_ready || !packet || length == 0 || length > E1000_TX_BUF_SIZE) return -1;
u32 index = g_tx_tail;
if (!(g_tx_desc[index].status & E1000_TX_STA_DD)) return -2;
copy_bytes(g_tx_buf[index], packet, length);
dma_fence();
raw_log("[e1000.raw] tx copied\n");
g_tx_desc[index].length = (u16)length;
g_tx_desc[index].cso = 0;
g_tx_desc[index].cmd = E1000_TX_CMD_EOP | E1000_TX_CMD_IFCS | E1000_TX_CMD_RS;
g_tx_desc[index].css = 0;
g_tx_desc[index].special = 0;
g_tx_desc[index].status = 0;
dma_fence();
g_tx_tail = (index + 1) % E1000_TX_DESC_COUNT;
g_mmio[E1000_TDT/4] = g_tx_tail;
raw_log("[e1000.raw] tx tdt written\n");
return 0;
mmio_flush();
for (u32 wait=0; wait<1000000; wait++) {
dma_fence();
if (g_tx_desc[index].status & E1000_TX_STA_DD) {
raw_log("[e1000.raw] tx complete\n");
return 0;
}
__asm__ volatile("pause");
}
raw_log("[e1000.raw] tx timeout\n");
raw_hex("[e1000.raw] STATUS=", g_mmio[E1000_STATUS/4]);
raw_hex("[e1000.raw] TCTL=", g_mmio[E1000_TCTL/4]);
raw_hex("[e1000.raw] TDH=", g_mmio[E1000_TDH/4]);
raw_hex("[e1000.raw] TDT=", g_mmio[E1000_TDT/4]);
raw_hex("[e1000.raw] desc.status=", g_tx_desc[index].status);
return -3;
}
static int e1000_rx_poll(void *ctx, void *buffer, u32 capacity, u32 *out_length) {
(void)ctx;
if (out_length) *out_length = 0;
if (!g_rings_ready || !buffer || !out_length) return -1;
u32 next = (g_rx_tail + 1) % E1000_RX_DESC_COUNT;
dma_fence();
if (!(g_rx_desc[next].status & E1000_RX_STA_DD)) return 1;
u32 len = g_rx_desc[next].length;
if (len > capacity) return -2;
if (len > capacity) {
g_rx_desc[next].status = 0;
dma_fence();
g_rx_tail = next;
g_mmio[E1000_RDT/4] = g_rx_tail;
mmio_flush();
return -2;
}
copy_bytes(buffer, g_rx_buf[next], len);
*out_length = len;
g_rx_desc[next].status = 0;
dma_fence();
g_rx_tail = next;
g_mmio[E1000_RDT/4] = g_rx_tail;
mmio_flush();
return 0;
}
@@ -367,7 +447,18 @@ int driver_init(const struct dkm_kernel_api *api,
pci_write(bus, dev, 0, PCI_COMMAND, cmd);
raw_log("[e1000.raw] PCI command enabled\n");
g_bar0_phys = (u64)pci_read(bus,dev,0,PCI_BAR0) & 0xFFFFFFF0ULL;
u32 bar0 = pci_read(bus,dev,0,PCI_BAR0);
if (bar0 & 1u) {
raw_log("[e1000.raw] IO BAR unsupported\n");
return 0;
}
g_bar0_phys = (u64)(bar0 & 0xFFFFFFF0ULL);
if ((bar0 & 0x6u) == 0x4u) {
u32 bar1 = pci_read(bus,dev,0,PCI_BAR1);
g_bar0_phys |= ((u64)bar1 << 32);
}
raw_hex("[e1000.raw] BAR0 raw=", bar0);
raw_hex("[e1000.raw] BAR0 phys=", g_bar0_phys);
if (!g_bar0_phys) {
raw_log("[e1000.raw] BAR0 unavailable\n");
return 0;