Skip to content

Commit 162abd5

Browse files
net: init
Signed-off-by: Andy-Python-Programmer <[email protected]>
1 parent 7c1a1b9 commit 162abd5

File tree

7 files changed

+334
-6
lines changed

7 files changed

+334
-6
lines changed

src/aero_kernel/src/drivers/e1000.rs

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ use crate::acpi::aml;
2323
use crate::arch::interrupts::{self, InterruptStack};
2424
use crate::drivers::pci::*;
2525
use crate::mem::paging::*;
26+
use crate::net::{self, ethernet, MacAddr, NetworkDevice};
27+
use crate::utils::sync::BMutex;
2628

2729
const TX_DESC_NUM: u32 = 32;
2830
const TX_DESC_SIZE: u32 = TX_DESC_NUM * core::mem::size_of::<TxDescriptor>() as u32;
@@ -212,10 +214,14 @@ impl<'a> Eeprom<'a> {
212214

213215
struct E1000 {
214216
base: VirtAddr,
217+
mac: MacAddr,
218+
219+
tx_cur: usize,
220+
tx_ring: VirtAddr,
215221
}
216222

217223
impl E1000 {
218-
fn new(header: &PciHeader) -> Result<(), Error> {
224+
fn new(header: &PciHeader) -> Result<Self, Error> {
219225
header.enable_bus_mastering();
220226
header.enable_mmio();
221227

@@ -232,8 +238,12 @@ impl E1000 {
232238
header.capabilities().collect::<alloc::vec::Vec<_>>()
233239
);
234240

235-
let this = Self {
241+
let mut this = Self {
236242
base: registers_addr.as_hhdm_virt(),
243+
mac: MacAddr([0; 6]),
244+
245+
tx_cur: 0,
246+
tx_ring: VirtAddr::zero(),
237247
};
238248

239249
this.reset();
@@ -263,6 +273,8 @@ impl E1000 {
263273
mac[5]
264274
);
265275

276+
this.mac = MacAddr(mac);
277+
266278
this.init_tx()?;
267279
this.init_rx()?;
268280

@@ -289,7 +301,27 @@ impl E1000 {
289301
this.receive();
290302

291303
log::trace!("e1000: successfully initialized");
292-
Ok(())
304+
Ok(this)
305+
}
306+
307+
fn send(&mut self, packet: ethernet::Packet) {
308+
let cur = self.tx_cur;
309+
let ring = self.tx_ring();
310+
let e: PhysFrame<Size4KiB> = FRAME_ALLOCATOR.allocate_frame().unwrap();
311+
312+
unsafe {
313+
*(e.start_address().as_hhdm_virt().as_ptr::<u8>() as *mut ethernet::Packet) = packet;
314+
}
315+
316+
ring[cur].addr = e.start_address().as_u64();
317+
ring[cur].length = core::mem::size_of::<ethernet::Packet>() as u16;
318+
ring[cur].cmd = 0b1011;
319+
ring[cur].status = TStatus::empty();
320+
321+
drop(ring);
322+
self.tx_cur = (self.tx_cur + 1) % TX_DESC_NUM as usize;
323+
324+
self.write(Register::TxDescTail, self.tx_cur as u32);
293325
}
294326

295327
fn receive(&self) {}
@@ -302,7 +334,13 @@ impl E1000 {
302334
}
303335
}
304336

305-
fn init_tx(&self) -> Result<(), Error> {
337+
fn tx_ring(&mut self) -> &mut [TxDescriptor] {
338+
self.tx_ring
339+
.read_mut::<[TxDescriptor; TX_DESC_NUM as usize]>()
340+
.unwrap()
341+
}
342+
343+
fn init_tx(&mut self) -> Result<(), Error> {
306344
assert!(TX_DESC_SIZE < Size4KiB::SIZE as u32);
307345

308346
let frame: PhysFrame<Size4KiB> =
@@ -319,6 +357,8 @@ impl E1000 {
319357
desc.status = TStatus::DD;
320358
}
321359

360+
self.tx_ring = addr;
361+
322362
self.write(Register::TxDesLo, phys.as_u64() as _);
323363
self.write(Register::TxDesHi, (phys.as_u64() >> 32) as _);
324364
self.write(Register::TxDescLen, TX_DESC_SIZE);
@@ -433,6 +473,24 @@ impl E1000 {
433473
}
434474
}
435475

476+
struct Device(BMutex<E1000>);
477+
478+
impl Device {
479+
fn new(e1000: E1000) -> Self {
480+
Self(BMutex::new(e1000))
481+
}
482+
}
483+
484+
impl NetworkDevice for Device {
485+
fn send(&self, packet: ethernet::Packet) {
486+
self.0.lock().send(packet)
487+
}
488+
489+
fn mac(&self) -> net::MacAddr {
490+
self.0.lock().mac
491+
}
492+
}
493+
436494
struct Handler;
437495

438496
impl Handler {
@@ -447,12 +505,15 @@ impl PciDeviceHandle for Handler {
447505
}
448506

449507
fn start(&self, header: &PciHeader, _offset_table: &mut OffsetPageTable) {
450-
E1000::new(header).unwrap()
508+
let e1000 = E1000::new(header).unwrap();
509+
let device = Arc::new(Device::new(e1000));
510+
511+
net::add_device(device);
451512
}
452513
}
453514

454515
fn irq_handler(_stack: &mut InterruptStack) {
455-
unreachable!()
516+
log::debug!("a!")
456517
}
457518

458519
fn init() {

src/aero_kernel/src/main.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ mod fs;
8282
mod logger;
8383
mod mem;
8484
mod modules;
85+
mod net;
8586
mod rendy;
8687
mod socket;
8788
mod syscall;
@@ -144,6 +145,9 @@ fn kernel_main_thread() {
144145
modules::init();
145146
log::info!("loaded kernel modules");
146147

148+
net::init();
149+
log::info!("initialized networking stack");
150+
147151
#[cfg(target_arch = "x86_64")]
148152
arch::enable_acpi();
149153

src/aero_kernel/src/net/arp.rs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
* Copyright (C) 2021-2023 The Aero Project Developers.
3+
*
4+
* This file is part of The Aero Project.
5+
*
6+
* Aero is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* Aero is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with Aero. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
20+
// Address Resolution Protocol
21+
22+
use alloc::collections::BTreeMap;
23+
use spin::{Once, RwLock};
24+
25+
use super::ethernet::MacAddr;
26+
use super::ip::Ipv4Addr;
27+
28+
struct Entry {
29+
mac: MacAddr,
30+
}
31+
32+
impl Entry {
33+
fn new(mac: MacAddr) -> Self {
34+
Self { mac }
35+
}
36+
}
37+
38+
struct Cache(BTreeMap<Ipv4Addr, Entry>);
39+
40+
impl Cache {
41+
fn new() -> Self {
42+
Self(BTreeMap::new())
43+
}
44+
45+
fn insert(&mut self, ip: Ipv4Addr, mac: MacAddr) {
46+
if let Some(_entry) = self.0.get_mut(&ip) {
47+
todo!()
48+
} else {
49+
self.0.insert(ip, Entry::new(mac));
50+
}
51+
}
52+
53+
fn get(&self, ip: Ipv4Addr) -> Option<MacAddr> {
54+
if let Some(entry) = self.0.get(&ip) {
55+
return Some(entry.mac);
56+
}
57+
58+
None
59+
}
60+
}
61+
62+
static CACHE: Once<RwLock<Cache>> = Once::new();
63+
64+
pub fn get(ip: Ipv4Addr) -> Option<MacAddr> {
65+
CACHE
66+
.get()
67+
.as_ref()
68+
.expect("arp: cache not initialized")
69+
.read()
70+
.get(ip)
71+
}
72+
73+
pub fn init() {
74+
CACHE.call_once(|| {
75+
let mut cache = Cache::new();
76+
cache.insert(Ipv4Addr::BROADCAST, MacAddr::BROADCAST);
77+
78+
RwLock::new(cache)
79+
});
80+
}

src/aero_kernel/src/net/dhcp.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (C) 2021-2023 The Aero Project Developers.
3+
*
4+
* This file is part of The Aero Project.
5+
*
6+
* Aero is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* Aero is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with Aero. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
20+
// Dynamic Host Configuration Protocol
21+
22+
use super::{ethernet, ip::Ipv4Addr};
23+
24+
pub fn init() {
25+
// Send DHCP discover message (UDP: source port=67; destination port=68).
26+
let balls = ethernet::Packet::new(ethernet::Type::Ip);
27+
28+
super::ethernet::send_packet(balls, Ipv4Addr::BROADCAST);
29+
}

src/aero_kernel/src/net/ethernet.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright (C) 2021-2023 The Aero Project Developers.
3+
*
4+
* This file is part of The Aero Project.
5+
*
6+
* Aero is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* Aero is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with Aero. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
20+
use super::arp;
21+
use super::ip::Ipv4Addr;
22+
23+
#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default)]
24+
#[repr(C)]
25+
pub struct MacAddr(pub [u8; 6]);
26+
27+
impl MacAddr {
28+
pub const BROADCAST: Self = Self([0xff; 6]);
29+
}
30+
31+
#[repr(u16)]
32+
pub enum Type {
33+
Ip = 0x800,
34+
}
35+
36+
#[repr(C, packed)]
37+
pub struct Packet {
38+
pub dest_mac: MacAddr,
39+
pub src_mac: MacAddr,
40+
pub typ: Type,
41+
}
42+
43+
impl Packet {
44+
/// Creates a new ethernet packet.
45+
pub fn new(typ: Type) -> Self {
46+
let src_mac = super::default_device().mac();
47+
Self {
48+
src_mac,
49+
dest_mac: MacAddr([0; 6]),
50+
typ,
51+
}
52+
}
53+
}
54+
55+
pub fn send_packet(mut packet: Packet, ip: Ipv4Addr) {
56+
if let Some(addr) = arp::get(ip) {
57+
packet.dest_mac = addr;
58+
super::default_device().send(packet);
59+
}
60+
}

src/aero_kernel/src/net/ip.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright (C) 2021-2023 The Aero Project Developers.
3+
*
4+
* This file is part of The Aero Project.
5+
*
6+
* Aero is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* Aero is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with Aero. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
20+
/// Size of IPv4 adderess in octets.
21+
///
22+
/// [RFC 8200 § 2]: https://www.rfc-editor.org/rfc/rfc791#section-3.2
23+
pub const ADDR_SIZE: usize = 4;
24+
25+
#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default)]
26+
pub struct Ipv4Addr(pub [u8; ADDR_SIZE]);
27+
28+
impl Ipv4Addr {
29+
pub const BROADCAST: Self = Self([0xff; ADDR_SIZE]);
30+
}

0 commit comments

Comments
 (0)