diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 6122d8e..c8fa51f 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -5,4 +5,5 @@ authors = ["Runji Wang "] edition = "2018" [dependencies] -linked_list_allocator = "0.6" \ No newline at end of file +buddy_system_allocator = "0.1" +isomorphic_drivers = { git = "https://github.com/rcore-os/isomorphic_drivers", default-features = false, features = ["log"]} \ No newline at end of file diff --git a/rust/src/bin/arping.rs b/rust/src/bin/arping.rs new file mode 100644 index 0000000..6c9f943 --- /dev/null +++ b/rust/src/bin/arping.rs @@ -0,0 +1,77 @@ +#![feature(alloc)] +#![no_std] +#![no_main] + +#[macro_use] +extern crate rcore_user; + +extern crate alloc; + +use rcore_user::syscall::*; +use isomorphic_drivers::net::ethernet::intel::ixgbe; +use isomorphic_drivers::provider; +use alloc::prelude::*; +use alloc::vec; + +#[derive(Copy, Clone)] +pub struct Provider; + +impl Provider { + pub fn new() -> Box { + Box::new(Provider {}) + } +} + +impl provider::Provider for Provider { + /// Get page size + fn get_page_size(&self) -> usize { + 4096 + } + + // Translate virtual address to physical address + fn translate_va(&self, va: usize) -> usize { + let mut pa = [0u64; 1]; + sys_get_paddr(&[va as u64], &mut pa[..]); + pa[0] as usize + } + + // Bulk translate virtual addresses to physical addresses for performance + fn translate_vas(&self, vas: &[usize]) -> Vec { + let mut pas = vec![0u64; vas.len()]; + let mut vec_vas = vec![0u64; vas.len()]; + for va in vas.iter() { + vec_vas.push(*va as u64); + } + sys_get_paddr(&vec_vas[..], &mut pas[..]); + let mut res = vec![0usize; vas.len()]; + for pa in pas { + res.push(pa as usize); + } + res + } +} + + +// IMPORTANT: Must define main() like this +#[no_mangle] +pub fn main() { + println!("I am going to map IXGBE driver to user space"); + println!("Kernel network stack should not use it anymore"); + let addr = sys_map_pci_device(0x8086, 0x10fb); + println!("IXGBE addr at {:#X}", addr); + let ixgbe = ixgbe::IXGBEDriver::init(Provider::new(), addr as usize, 0x20000); + println!("IXGBE driver up"); + loop { + println!("IXGBE driver sending data"); + let data = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // mac + 0x00, 0x16, 0x31, 0xff, 0xa4, 0x9f, // mac + 0x08, 0x06, // arp + 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // mac + 0x0a, 0x00, 0x00, 0x02, // ip + 0x00, 0x16, 0x31, 0xff, 0xa4, 0x9f, // mac + 0x0a, 0x00, 0x00, 0x01]; // ip + ixgbe.send(&data); + sys_sleep(1); + } +} diff --git a/rust/src/bin/genpkts.rs b/rust/src/bin/genpkts.rs new file mode 100644 index 0000000..758091f --- /dev/null +++ b/rust/src/bin/genpkts.rs @@ -0,0 +1,85 @@ +#![feature(alloc)] +#![no_std] +#![no_main] + +#[macro_use] +extern crate rcore_user; + +extern crate alloc; + +use rcore_user::syscall::*; +use isomorphic_drivers::net::ethernet::intel::ixgbe; +use isomorphic_drivers::provider; +use alloc::prelude::*; +use alloc::vec; + +#[derive(Copy, Clone)] +pub struct Provider; + +impl Provider { + pub fn new() -> Box { + Box::new(Provider {}) + } +} + +impl provider::Provider for Provider { + /// Get page size + fn get_page_size(&self) -> usize { + 4096 + } + + // Translate virtual address to physical address + fn translate_va(&self, va: usize) -> usize { + let mut pa = [0u64; 1]; + sys_get_paddr(&[va as u64], &mut pa[..]); + pa[0] as usize + } + + // Bulk translate virtual addresses to physical addresses for performance + fn translate_vas(&self, vas: &[usize]) -> Vec { + let mut pas = vec![0u64; vas.len()]; + let mut vec_vas = vec![0u64; vas.len()]; + for va in vas.iter() { + vec_vas.push(*va as u64); + } + sys_get_paddr(&vec_vas[..], &mut pas[..]); + let mut res = vec![0usize; vas.len()]; + for pa in pas { + res.push(pa as usize); + } + res + } +} + + +// IMPORTANT: Must define main() like this +#[no_mangle] +pub fn main() { + println!("I am going to map IXGBE driver to user space"); + println!("Kernel network stack should not use it anymore"); + let addr = sys_map_pci_device(0x8086, 0x10fb); + println!("IXGBE addr at {:#X}", addr); + let ixgbe = ixgbe::IXGBEDriver::init(Provider::new(), addr as usize, 0x20000); + println!("IXGBE driver up"); + let data = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // mac + 0x00, 0x16, 0x31, 0xff, 0xa4, 0x9f, // mac + 0x08, 0x06, // arp + 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // mac + 0x0a, 0x00, 0x00, 0x02, // ip + 0x00, 0x16, 0x31, 0xff, 0xa4, 0x9f, // mac + 0x0a, 0x00, 0x00, 0x01]; // ip + let tx_batch = vec![&data[..]; 1024]; + println!("IXGBE driver waiting for link up"); + while !ixgbe.is_link_up() {} + println!("IXGBE driver link is up"); + println!("IXGBE driver will be sending lots of small packets"); + loop { + /* + let data = [0x00, 0x16, 0x31, 0xff, 0xa4, 0x0e, // mac + 0x00, 0x16, 0x31, 0xff, 0xa4, 0x9f, // mac + 0xff, 0xff]; // unknown + */ + ixgbe.msend(tx_batch.as_slice()); + } +} diff --git a/rust/src/lang_items.rs b/rust/src/lang_items.rs index a5421cb..573bd0f 100644 --- a/rust/src/lang_items.rs +++ b/rust/src/lang_items.rs @@ -3,6 +3,7 @@ use crate::ALLOCATOR; use core::alloc::Layout; use core::panic::PanicInfo; +use super::syscall::*; #[linkage = "weak"] #[no_mangle] @@ -11,9 +12,9 @@ fn main() { } fn init_heap() { - const HEAP_SIZE: usize = 0x1000; - static mut HEAP: [u8; HEAP_SIZE] = [0; HEAP_SIZE]; - unsafe { ALLOCATOR.lock().init(HEAP.as_ptr() as usize, HEAP_SIZE); } + const HEAP_SIZE: usize = 16 * 1024 * 1024; + let addr = sys_mmap(0, HEAP_SIZE, 0x3, 0x22, 0, 0) as usize; + unsafe { ALLOCATOR.lock().init(addr, HEAP_SIZE); } } #[no_mangle] diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 3863e78..1b22e9a 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -13,7 +13,7 @@ pub mod io; pub mod syscall; pub mod lang_items; -use linked_list_allocator::LockedHeap; +use buddy_system_allocator::LockedHeap; #[global_allocator] static ALLOCATOR: LockedHeap = LockedHeap::empty(); \ No newline at end of file diff --git a/rust/src/syscall.rs b/rust/src/syscall.rs index 904f5cf..acb2973 100644 --- a/rust/src/syscall.rs +++ b/rust/src/syscall.rs @@ -130,6 +130,19 @@ pub fn sys_arch_prctl(code: i32, addr: usize) -> i32 { sys_call(SyscallId::ArchPrctl, code as usize, addr, 0, 0, 0, 0) } +pub fn sys_map_pci_device(vendor: usize, product: usize) -> i32 { + sys_call(SyscallId::MapPciDevice, vendor, product, 0, 0, 0, 0) +} + +pub fn sys_get_paddr(vaddr: &[u64], paddr: &mut [u64]) -> i32 { + assert_eq!(vaddr.len(), paddr.len()); + sys_call(SyscallId::GetPaddr, vaddr.as_ptr() as usize, paddr.as_ptr() as usize, vaddr.len(), 0, 0, 0) +} + +pub fn sys_mmap(addr: usize, len: usize, prot: usize, flags: usize, fd: usize, offset: usize) -> i32 { + sys_call(SyscallId::Mmap, addr, len, prot, flags, fd, offset) +} + #[cfg(target_arch = "x86_64")] #[allow(dead_code)] enum SyscallId { @@ -156,6 +169,9 @@ enum SyscallId { GetDirEntry64 = 217, Openat = 257, Dup3 = 292, + // custom + MapPciDevice = 999, + GetPaddr = 998, } #[cfg(not(target_arch = "x86_64"))] @@ -184,4 +200,7 @@ enum SyscallId { GetTime = 169, SetPriority = 140, ArchPrctl = -4, + // custom + MapPciDevice = 999, + GetPaddr = 998, }