Skip to content

Commit 6a51ce8

Browse files
committed
新增网络设备的独立注册机制, 扩展部分内核模块接口
1 parent cdc2c8d commit 6a51ce8

File tree

20 files changed

+372
-214
lines changed

20 files changed

+372
-214
lines changed

module/all_include/driver_subsystem.h

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,28 @@
22

33
#include "cp_kernel.h"
44

5+
typedef errno_t (*netdev_send_t)(void *dev, void *data, uint32_t len);
6+
typedef errno_t (*netdev_recv_t)(void *dev, void *data, uint32_t len);
7+
58
typedef enum {
69
VDISK_BLOCK,
710
VDISK_STREAM,
8-
} vdisk_flag_t;
11+
} device_flag_t;
912

10-
typedef struct vdisk_device {
13+
typedef struct _device {
1114
size_t (*read_vbuf)(int drive, struct vecbuf *buffer, size_t number, size_t lba);
1215
size_t (*write_vbuf)(int drive, struct vecbuf *buffer, size_t number, size_t lba);
1316
size_t (*read)(int drive, uint8_t *buffer, size_t number, size_t lba);
1417
size_t (*write)(int drive, uint8_t *buffer, size_t number, size_t lba);
15-
int (*ioctl)(struct vdisk_device *device, size_t req, void *handle);
18+
int (*ioctl)(struct _device *device, size_t req, void *handle);
1619
int (*poll)(size_t events);
1720
void *(*map)(int drive, void *addr, uint64_t len);
18-
int flag;
19-
size_t size; // 大小
20-
size_t sector_size; // 扇区大小
21-
vdisk_flag_t type;
22-
char drive_name[50];
23-
} vdisk; // 块设备
21+
int flag;
22+
size_t size; // 大小
23+
size_t sector_size; // 扇区大小
24+
device_flag_t type;
25+
char drive_name[50];
26+
} device_t; // 块设备
2427

2528
typedef struct {
2629
uint64_t address;
@@ -53,10 +56,22 @@ typedef struct {
5356
pci_device_op_t *op;
5457
} pci_device_t;
5558

56-
int regist_vdisk(vdisk vd);
59+
typedef struct netdev {
60+
uint8_t mac[6];
61+
uint32_t mtu;
62+
void *desc;
63+
netdev_send_t send;
64+
netdev_recv_t recv;
65+
} netdev_t;
66+
67+
void regist_netdev(void *desc, uint8_t *mac, uint32_t mtu, netdev_send_t send, netdev_recv_t recv);
68+
errno_t netdev_send(netdev_t *dev, void *data, uint32_t len);
69+
errno_t netdev_recv(netdev_t *dev, void *data, uint32_t len);
70+
71+
int regist_device(device_t vd);
5772
void *driver_phys_to_virt(uint64_t phys_addr);
58-
size_t vdisk_read(size_t lba, size_t number, void *buffer, int drive);
59-
size_t vdisk_write(size_t lba, size_t number, const void *buffer, int drive);
73+
size_t device_read(size_t lba, size_t number, void *buffer, int drive);
74+
size_t device_write(size_t lba, size_t number, const void *buffer, int drive);
6075

6176
pci_device_t *pci_find_vid_did(uint16_t vendor_id, uint16_t device_id);
6277
pci_device_t *pci_find_class(uint32_t class_code);

module/all_include/mem_subsystem.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ void *virt_to_phys(uint64_t virt_addr);
5151
uint64_t page_virt_to_phys(uint64_t va);
5252
void *driver_phys_to_virt(uint64_t phys_addr);
5353
void *driver_virt_to_phys(uint64_t virt_addr);
54+
void unmap_page_range(page_directory_t *directory, uint64_t vaddr, uint64_t size);
5455

5556
uint64_t get_reserved_memory();
5657
uint64_t get_all_memory();

module/e1000/e1000.c

Lines changed: 98 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,13 +201,109 @@ int e1000_init(void *mmio_base) {
201201
// Disable interrupts (polling mode)
202202
e1000_write32(dev, E1000_IMC, 0xFFFFFFFF);
203203

204-
// Store device and register with network framework
205204
e1000_devices[e1000_device_count++] = dev;
206-
// regist_netdev(dev, dev->mac, dev->mtu, e1000_send, e1000_receive);
205+
regist_netdev(dev, dev->mac, dev->mtu, e1000_send, e1000_receive);
207206

208207
return 0;
209208
}
210209

210+
bool e1000_has_packets(e1000_device_t *dev) {
211+
uint16_t next_rx = (dev->rx_tail + 1) % E1000_NUM_RX_DESC;
212+
return (dev->rx_descs[next_rx].status & E1000_RXD_STAT_DD) != 0;
213+
}
214+
215+
errno_t e1000_send(void *dev_desc, void *data, uint32_t len) {
216+
e1000_device_t *dev = (e1000_device_t *)dev_desc;
217+
218+
if (len > E1000_MTU || len == 0) { return -1; }
219+
220+
// Check if we have a free TX descriptor
221+
uint16_t next_tail = (dev->tx_tail + 1) % E1000_NUM_TX_DESC;
222+
if (next_tail == dev->tx_head) {
223+
// TX queue full
224+
return -1;
225+
}
226+
227+
// Allocate buffer for packet
228+
uint64_t phy_ = alloc_frames(len / PAGE_SIZE + 1);
229+
void *tx_buffer = driver_phys_to_virt(phy_);
230+
page_map_range(get_current_directory(), (uint64_t)tx_buffer, phy_, len, KERNEL_PTE_FLAGS);
231+
if (!tx_buffer) { return -1; }
232+
233+
// Copy data to buffer
234+
memcpy(tx_buffer, data, len);
235+
236+
// Setup TX descriptor
237+
dev->tx_descs[dev->tx_tail].buffer_addr = (uint64_t)virt_to_phys(phy_);
238+
dev->tx_descs[dev->tx_tail].length = len;
239+
dev->tx_descs[dev->tx_tail].cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS | E1000_TXD_CMD_RS;
240+
dev->tx_descs[dev->tx_tail].status = 0;
241+
242+
// Store buffer pointer for later cleanup
243+
dev->tx_buffers[dev->tx_tail] = tx_buffer;
244+
245+
// Update tail pointer
246+
dev->tx_tail = next_tail;
247+
e1000_write32(dev, E1000_TDT, dev->tx_tail);
248+
249+
// Poll for completion
250+
while (!(dev->tx_descs[dev->tx_head].status & E1000_TXD_STAT_DD)) {
251+
// Wait for transmission to complete
252+
}
253+
254+
// Clean up completed descriptors
255+
while (dev->tx_head != dev->tx_tail) {
256+
if (dev->tx_descs[dev->tx_head].status & E1000_TXD_STAT_DD) {
257+
if (dev->tx_buffers[dev->tx_head]) {
258+
unmap_page_range(get_current_directory(), (uint64_t)dev->tx_buffers[dev->tx_head],
259+
len);
260+
dev->tx_buffers[dev->tx_head] = NULL;
261+
}
262+
dev->tx_descs[dev->tx_head].status = 0;
263+
dev->tx_head = (dev->tx_head + 1) % E1000_NUM_TX_DESC;
264+
} else {
265+
break;
266+
}
267+
}
268+
269+
return len;
270+
}
271+
272+
// Receive packet (polling mode)
273+
errno_t e1000_receive(void *dev_desc, void *buffer, uint32_t buffer_size) {
274+
e1000_device_t *dev = (e1000_device_t *)dev_desc;
275+
276+
uint16_t next_rx = (dev->rx_tail + 1) % E1000_NUM_RX_DESC;
277+
struct e1000_rx_desc *desc = &dev->rx_descs[next_rx];
278+
279+
bool have_data = !!(desc->status & E1000_RXD_STAT_DD);
280+
281+
if (!have_data) {
282+
// No packet available
283+
return 0;
284+
}
285+
286+
if (desc->errors & (E1000_RXD_ERR_CE | E1000_RXD_ERR_SE | E1000_RXD_ERR_SEQ |
287+
E1000_RXD_ERR_CXE | E1000_RXD_ERR_RXE)) {
288+
// Packet has errors, discard it
289+
goto cleanup;
290+
}
291+
292+
uint32_t packet_len = desc->length;
293+
if (packet_len > buffer_size) { packet_len = buffer_size; }
294+
295+
// Copy packet data to user buffer
296+
memcpy(buffer, driver_phys_to_virt(desc->buffer_addr), packet_len);
297+
298+
cleanup:
299+
// Recycle the descriptor
300+
desc->status = 0;
301+
dev->rx_tail = next_rx;
302+
e1000_write32(dev, E1000_RDT, dev->rx_tail);
303+
304+
return have_data ? packet_len : 0;
305+
}
306+
211307
__attribute__((used)) __attribute__((visibility("default"))) int dlmain(void) {
212308
pci_device_t *device = pci_find_vid_did(0x8086, 0x100e);
213309
if (device == NULL) {

module/e1000/e1000.h

Lines changed: 74 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -2,88 +2,88 @@
22

33
// E1000 Device IDs
44
#define E1000_DEVICE_ID_82540EM 0x100E
5-
#define MAX_E1000_DEVICES 8
5+
#define MAX_E1000_DEVICES 8
66

77
// E1000 Register Definitions
8-
#define E1000_CTRL 0x0000 // Device Control
9-
#define E1000_STATUS 0x0008 // Device Status
10-
#define E1000_EERD 0x0014 // EEPROM Read
8+
#define E1000_CTRL 0x0000 // Device Control
9+
#define E1000_STATUS 0x0008 // Device Status
10+
#define E1000_EERD 0x0014 // EEPROM Read
1111
#define E1000_CTRL_EXT 0x0018 // Extended Device Control
12-
#define E1000_ICR 0x00C0 // Interrupt Cause Read
13-
#define E1000_IMS 0x00D0 // Interrupt Mask Set
14-
#define E1000_IMC 0x00D8 // Interrupt Mask Clear
15-
#define E1000_RCTL 0x0100 // RX Control
16-
#define E1000_TCTL 0x0400 // TX Control
17-
#define E1000_TIPG 0x0410 // TX Inter-packet Gap
18-
#define E1000_RDBAL 0x2800 // RX Descriptor Base Address Low
19-
#define E1000_RDBAH 0x2804 // RX Descriptor Base Address High
20-
#define E1000_RDLEN 0x2808 // RX Descriptor Length
21-
#define E1000_RDH 0x2810 // RX Descriptor Head
22-
#define E1000_RDT 0x2818 // RX Descriptor Tail
23-
#define E1000_RDTR 0x2820 // RX Delay Timer
24-
#define E1000_TDBAL 0x3800 // TX Descriptor Base Address Low
25-
#define E1000_TDBAH 0x3804 // TX Descriptor Base Address High
26-
#define E1000_TDLEN 0x3808 // TX Descriptor Length
27-
#define E1000_TDH 0x3810 // TX Descriptor Head
28-
#define E1000_TDT 0x3818 // TX Descriptor Tail
29-
#define E1000_TIDV 0x3820 // TX Interrupt Delay Value
30-
#define E1000_RA 0x5400 // Receive Address (MAC)
12+
#define E1000_ICR 0x00C0 // Interrupt Cause Read
13+
#define E1000_IMS 0x00D0 // Interrupt Mask Set
14+
#define E1000_IMC 0x00D8 // Interrupt Mask Clear
15+
#define E1000_RCTL 0x0100 // RX Control
16+
#define E1000_TCTL 0x0400 // TX Control
17+
#define E1000_TIPG 0x0410 // TX Inter-packet Gap
18+
#define E1000_RDBAL 0x2800 // RX Descriptor Base Address Low
19+
#define E1000_RDBAH 0x2804 // RX Descriptor Base Address High
20+
#define E1000_RDLEN 0x2808 // RX Descriptor Length
21+
#define E1000_RDH 0x2810 // RX Descriptor Head
22+
#define E1000_RDT 0x2818 // RX Descriptor Tail
23+
#define E1000_RDTR 0x2820 // RX Delay Timer
24+
#define E1000_TDBAL 0x3800 // TX Descriptor Base Address Low
25+
#define E1000_TDBAH 0x3804 // TX Descriptor Base Address High
26+
#define E1000_TDLEN 0x3808 // TX Descriptor Length
27+
#define E1000_TDH 0x3810 // TX Descriptor Head
28+
#define E1000_TDT 0x3818 // TX Descriptor Tail
29+
#define E1000_TIDV 0x3820 // TX Interrupt Delay Value
30+
#define E1000_RA 0x5400 // Receive Address (MAC)
3131

3232
// Control Register Bits
33-
#define E1000_CTRL_RST (1 << 26) // Reset
34-
#define E1000_CTRL_ASDE (1 << 5) // Auto-Speed Detection Enable
35-
#define E1000_CTRL_SLU (1 << 6) // Set Link Up
36-
#define E1000_CTRL_FRCSPD (1 << 11) // Force Speed
33+
#define E1000_CTRL_RST (1 << 26) // Reset
34+
#define E1000_CTRL_ASDE (1 << 5) // Auto-Speed Detection Enable
35+
#define E1000_CTRL_SLU (1 << 6) // Set Link Up
36+
#define E1000_CTRL_FRCSPD (1 << 11) // Force Speed
3737
#define E1000_CTRL_FRCDPLX (1 << 12) // Force Duplex
3838

3939
// RCTL Register Bits
40-
#define E1000_RCTL_EN (1 << 1) // Enable
41-
#define E1000_RCTL_SBP (1 << 2) // Store Bad Packets
42-
#define E1000_RCTL_UPE (1 << 3) // Unicast Promiscuous Enable
43-
#define E1000_RCTL_MPE (1 << 4) // Multicast Promiscuous Enable
44-
#define E1000_RCTL_LPE (1 << 5) // Long Packet Enable
45-
#define E1000_RCTL_LBM_NONE (0 << 6) // No Loopback
46-
#define E1000_RCTL_RDMTS_HALF (0 << 8) // RX Desc Min Threshold Size
47-
#define E1000_RCTL_MO_36 (36 << 12) // Multicast Offset
48-
#define E1000_RCTL_BAM (1 << 15) // Broadcast Accept Mode
49-
#define E1000_RCTL_SECRC (1 << 26) // Strip Ethernet CRC
40+
#define E1000_RCTL_EN (1 << 1) // Enable
41+
#define E1000_RCTL_SBP (1 << 2) // Store Bad Packets
42+
#define E1000_RCTL_UPE (1 << 3) // Unicast Promiscuous Enable
43+
#define E1000_RCTL_MPE (1 << 4) // Multicast Promiscuous Enable
44+
#define E1000_RCTL_LPE (1 << 5) // Long Packet Enable
45+
#define E1000_RCTL_LBM_NONE (0 << 6) // No Loopback
46+
#define E1000_RCTL_RDMTS_HALF (0 << 8) // RX Desc Min Threshold Size
47+
#define E1000_RCTL_MO_36 (36 << 12) // Multicast Offset
48+
#define E1000_RCTL_BAM (1 << 15) // Broadcast Accept Mode
49+
#define E1000_RCTL_SECRC (1 << 26) // Strip Ethernet CRC
5050

5151
// TCTL Register Bits
52-
#define E1000_TCTL_EN (1 << 1) // Enable
53-
#define E1000_TCTL_PSP (1 << 3) // Pad Short Packets
54-
#define E1000_TCTL_CT_SHIFT 4 // Collision Threshold
55-
#define E1000_TCTL_COLD_SHIFT 12 // Collision Distance
56-
#define E1000_TCTL_SWXOFF (1 << 22) // Software XOFF Transmission
52+
#define E1000_TCTL_EN (1 << 1) // Enable
53+
#define E1000_TCTL_PSP (1 << 3) // Pad Short Packets
54+
#define E1000_TCTL_CT_SHIFT 4 // Collision Threshold
55+
#define E1000_TCTL_COLD_SHIFT 12 // Collision Distance
56+
#define E1000_TCTL_SWXOFF (1 << 22) // Software XOFF Transmission
5757

5858
// EERD Register Bits
59-
#define E1000_EERD_START (1 << 0) // Start Read
60-
#define E1000_EERD_DONE (1 << 1) // Read Done
61-
#define E1000_EERD_ADDR_SHIFT 2 // Address Shift
62-
#define E1000_EERD_DATA_SHIFT 16 // Data Shift
59+
#define E1000_EERD_START (1 << 0) // Start Read
60+
#define E1000_EERD_DONE (1 << 1) // Read Done
61+
#define E1000_EERD_ADDR_SHIFT 2 // Address Shift
62+
#define E1000_EERD_DATA_SHIFT 16 // Data Shift
6363

6464
// RX Descriptor Status Bits
65-
#define E1000_RXD_STAT_DD (1 << 0) // Descriptor Done
65+
#define E1000_RXD_STAT_DD (1 << 0) // Descriptor Done
6666
#define E1000_RXD_STAT_EOP (1 << 1) // End of Packet
67-
#define E1000_RXD_ERR_CE (1 << 0) // CRC Error
68-
#define E1000_RXD_ERR_SE (1 << 1) // Symbol Error
69-
#define E1000_RXD_ERR_SEQ (1 << 2) // Sequence Error
70-
#define E1000_RXD_ERR_CXE (1 << 3) // Carrier Extension Error
71-
#define E1000_RXD_ERR_RXE (1 << 4) // RX Data Error
67+
#define E1000_RXD_ERR_CE (1 << 0) // CRC Error
68+
#define E1000_RXD_ERR_SE (1 << 1) // Symbol Error
69+
#define E1000_RXD_ERR_SEQ (1 << 2) // Sequence Error
70+
#define E1000_RXD_ERR_CXE (1 << 3) // Carrier Extension Error
71+
#define E1000_RXD_ERR_RXE (1 << 4) // RX Data Error
7272

7373
// TX Descriptor Command Bits
74-
#define E1000_TXD_CMD_EOP (1 << 0) // End of Packet
74+
#define E1000_TXD_CMD_EOP (1 << 0) // End of Packet
7575
#define E1000_TXD_CMD_IFCS (1 << 1) // Insert FCS
76-
#define E1000_TXD_CMD_RS (1 << 3) // Report Status
76+
#define E1000_TXD_CMD_RS (1 << 3) // Report Status
7777

7878
// TX Descriptor Status Bits
7979
#define E1000_TXD_STAT_DD (1 << 0) // Descriptor Done
8080

8181
// Constants
82-
#define E1000_NUM_RX_DESC 32
83-
#define E1000_NUM_TX_DESC 32
82+
#define E1000_NUM_RX_DESC 32
83+
#define E1000_NUM_TX_DESC 32
8484
#define E1000_RX_BUFFER_SIZE 2048
8585
#define E1000_TX_BUFFER_SIZE 2048
86-
#define E1000_MTU 1500
86+
#define E1000_MTU 1500
8787

8888
#include "cp_kernel.h"
8989

@@ -92,37 +92,40 @@ struct e1000_rx_desc {
9292
uint64_t buffer_addr;
9393
uint16_t length;
9494
uint16_t checksum;
95-
uint8_t status;
96-
uint8_t errors;
95+
uint8_t status;
96+
uint8_t errors;
9797
uint16_t special;
9898
} __attribute__((packed));
9999

100100
// TX Descriptor Structure
101101
struct e1000_tx_desc {
102102
uint64_t buffer_addr;
103103
uint16_t length;
104-
uint8_t cso;
105-
uint8_t cmd;
106-
uint8_t status;
107-
uint8_t css;
104+
uint8_t cso;
105+
uint8_t cmd;
106+
uint8_t status;
107+
uint8_t css;
108108
uint16_t special;
109109
} __attribute__((packed));
110110

111111
// E1000 Device Structure
112-
typedef struct e1000_device{
113-
void *mmio_base;
114-
uint8_t mac[6];
112+
typedef struct e1000_device {
113+
void *mmio_base;
114+
uint8_t mac[6];
115115
uint32_t mtu;
116116

117117
// RX descriptors and buffers
118118
struct e1000_rx_desc *rx_descs;
119-
void *rx_buffers[E1000_NUM_RX_DESC];
120-
uint16_t rx_tail;
119+
void *rx_buffers[E1000_NUM_RX_DESC];
120+
uint16_t rx_tail;
121121

122122
// TX descriptors and buffers
123123
struct e1000_tx_desc *tx_descs;
124-
void *tx_buffers[E1000_NUM_TX_DESC];
125-
uint16_t tx_head;
126-
uint16_t tx_tail;
124+
void *tx_buffers[E1000_NUM_TX_DESC];
125+
uint16_t tx_head;
126+
uint16_t tx_tail;
127127
} e1000_device_t;
128128

129+
bool e1000_has_packets(e1000_device_t *dev);
130+
errno_t e1000_send(void *dev_desc, void *data, uint32_t len);
131+
errno_t e1000_receive(void *dev_desc, void *buffer, uint32_t buffer_size);

0 commit comments

Comments
 (0)