From e850a0e9de57660aa6cc662c8160ec6a9b2248a3 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Thu, 4 May 2023 19:30:19 +0200 Subject: [PATCH 01/13] Fix typo in rx buffer size --- src/sys/net/rtl8139.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sys/net/rtl8139.rs b/src/sys/net/rtl8139.rs index 1fcfb72e..5f78e6fb 100644 --- a/src/sys/net/rtl8139.rs +++ b/src/sys/net/rtl8139.rs @@ -17,7 +17,7 @@ const RX_BUFFER_IDX: usize = 0; const MTU: usize = 1500; const RX_BUFFER_PAD: usize = 16; -const RX_BUFFER_LEN: usize = (8129 << RX_BUFFER_IDX) + RX_BUFFER_PAD; +const RX_BUFFER_LEN: usize = (8192 << RX_BUFFER_IDX) + RX_BUFFER_PAD; const TX_BUFFER_LEN: usize = 4096; const TX_BUFFERS_COUNT: usize = 4; From 200f2d064c67e86c83835e6cd6fd940a38ca37cd Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Thu, 4 May 2023 19:31:55 +0200 Subject: [PATCH 02/13] Fix issue with small packets tx --- src/sys/net/rtl8139.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sys/net/rtl8139.rs b/src/sys/net/rtl8139.rs index 5f78e6fb..066ba617 100644 --- a/src/sys/net/rtl8139.rs +++ b/src/sys/net/rtl8139.rs @@ -257,6 +257,9 @@ impl EthernetDeviceIO for Device { let tx_id = self.tx_id.load(Ordering::SeqCst); let mut cmd_port = self.ports.tx_cmds[tx_id].clone(); unsafe { + // RTL8139 will not transmit packets smaller than 64 bits + let len = len.max(60); // 60 + 4 bits of CRC + // Fill in Transmit Status: the size of this packet, the early // transmit threshold, and clear OWN bit in TSD (this starts the // PCI operation). From d71a65254cb1a479673b0a97e64f42886459206c Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Thu, 4 May 2023 19:32:47 +0200 Subject: [PATCH 03/13] Change tx buffer len --- src/sys/net/rtl8139.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sys/net/rtl8139.rs b/src/sys/net/rtl8139.rs index 066ba617..c6ca65e8 100644 --- a/src/sys/net/rtl8139.rs +++ b/src/sys/net/rtl8139.rs @@ -19,7 +19,7 @@ const MTU: usize = 1500; const RX_BUFFER_PAD: usize = 16; const RX_BUFFER_LEN: usize = (8192 << RX_BUFFER_IDX) + RX_BUFFER_PAD; -const TX_BUFFER_LEN: usize = 4096; +const TX_BUFFER_LEN: usize = 2048; const TX_BUFFERS_COUNT: usize = 4; const ROK: u16 = 0x01; From fefda8cee73c54e8624d4f4154bc02d4b1dee653 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Thu, 4 May 2023 19:34:50 +0200 Subject: [PATCH 04/13] Fix tx ring overflow --- src/sys/net/rtl8139.rs | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/sys/net/rtl8139.rs b/src/sys/net/rtl8139.rs index c6ca65e8..5afe3a9c 100644 --- a/src/sys/net/rtl8139.rs +++ b/src/sys/net/rtl8139.rs @@ -17,15 +17,15 @@ const RX_BUFFER_IDX: usize = 0; const MTU: usize = 1500; const RX_BUFFER_PAD: usize = 16; -const RX_BUFFER_LEN: usize = (8192 << RX_BUFFER_IDX) + RX_BUFFER_PAD; +const RX_BUFFER_LEN: usize = 8192 << RX_BUFFER_IDX; const TX_BUFFER_LEN: usize = 2048; const TX_BUFFERS_COUNT: usize = 4; const ROK: u16 = 0x01; -const CR_RST: u8 = 1 << 4; // Reset -const CR_RE: u8 = 1 << 3; // Receiver Enable -const CR_TE: u8 = 1 << 2; // Transmitter Enable +const CR_RST: u8 = 1 << 4; // Reset +const CR_RE: u8 = 1 << 3; // Receiver Enable +const CR_TE: u8 = 1 << 2; // Transmitter Enable const CR_BUFE: u8 = 1 << 0; // Buffer Empty // Rx Buffer Length @@ -37,10 +37,10 @@ const RCR_RBLEN: u32 = (RX_BUFFER_IDX << 11) as u32; // of the buffer. So the buffer must have an additionnal 1500 bytes. const RCR_WRAP: u32 = 1 << 7; -const RCR_AB: u32 = 1 << 3; // Accept Broadcast packets -const RCR_AM: u32 = 1 << 2; // Accept Multicast packets -const RCR_APM: u32 = 1 << 1; // Accept Physical Match packets -const RCR_AAP: u32 = 1 << 0; // Accept All Packets +const RCR_AB: u32 = 1 << 3; // Accept Broadcast packets +const RCR_AM: u32 = 1 << 2; // Accept Multicast packets +const RCR_APM: u32 = 1 << 1; // Accept Physical Match packets +const RCR_AAP: u32 = 1 << 0; // Accept All Packets // Interframe Gap Time const TCR_IFG: u32 = 3 << 24; @@ -78,7 +78,7 @@ pub struct Ports { pub config1: Port, // Configuration Register 1 (CONFIG1) pub rx_addr: Port, // Receive (Rx) Buffer Start Address (RBSTART) pub capr: Port, // Current Address of Packet Read (CAPR) - pub cbr: Port, // Current Buffer Address (CBR) + pub cba: Port, // Current Buffer Address (CBA) pub cmd: Port, // Command Register (CR) pub imr: Port, // Interrupt Mask Register (IMR) pub isr: Port, // Interrupt Status Register (ISR) @@ -112,7 +112,7 @@ impl Ports { config1: Port::new(io_base + 0x52), rx_addr: Port::new(io_base + 0x30), capr: Port::new(io_base + 0x38), - cbr: Port::new(io_base + 0x3A), + cba: Port::new(io_base + 0x3A), cmd: Port::new(io_base + 0x37), imr: Port::new(io_base + 0x3C), isr: Port::new(io_base + 0x3E), @@ -155,7 +155,7 @@ impl Device { ports: Ports::new(io_base), // Add MTU to RX_BUFFER_LEN if RCR_WRAP is set - rx_buffer: PhysBuf::new(RX_BUFFER_LEN + MTU), + rx_buffer: PhysBuf::new(RX_BUFFER_LEN + RX_BUFFER_PAD + MTU), rx_offset: 0, tx_buffers: [(); TX_BUFFERS_COUNT].map(|_| PhysBuf::new(TX_BUFFER_LEN)), @@ -230,14 +230,13 @@ impl EthernetDeviceIO for Device { } //let isr = unsafe { self.ports.isr.read() }; - let capr = unsafe { self.ports.capr.read() }; - let cbr = unsafe { self.ports.cbr.read() }; + let cba = unsafe { self.ports.cba.read() }; // CAPR starts at 65520 and with the pad it overflows to 0 + let capr = unsafe { self.ports.capr.read() }; let offset = ((capr as usize) + RX_BUFFER_PAD) % (1 << 16); - let header = u16::from_le_bytes(self.rx_buffer[(offset + 0)..(offset + 2)].try_into().unwrap()); if header & ROK != ROK { - unsafe { self.ports.capr.write(cbr) }; + unsafe { self.ports.capr.write((((cba as usize) % RX_BUFFER_LEN) - RX_BUFFER_PAD) as u16) }; return None; } @@ -247,7 +246,7 @@ impl EthernetDeviceIO for Device { // Update buffer read pointer self.rx_offset = (offset + n + 4 + 3) & !3; unsafe { - self.ports.capr.write((self.rx_offset - RX_BUFFER_PAD) as u16); + self.ports.capr.write(((self.rx_offset % RX_BUFFER_LEN) - RX_BUFFER_PAD) as u16); } Some(self.rx_buffer[(offset + 4)..(offset + n)].to_vec()) From 7e02481d3635407b6e705e2aba2c4106eaf0adfe Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Thu, 4 May 2023 19:36:47 +0200 Subject: [PATCH 05/13] Use 1024 bytes for max DMA burst size --- src/sys/net/rtl8139.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sys/net/rtl8139.rs b/src/sys/net/rtl8139.rs index 5afe3a9c..9e13d11e 100644 --- a/src/sys/net/rtl8139.rs +++ b/src/sys/net/rtl8139.rs @@ -178,6 +178,9 @@ impl Device { while self.ports.cmd.read() & CR_RST != 0 {} } + // Set interrupts + unsafe { self.ports.imr.write(IMR_TOK | IMR_ROK) } + // Enable Receive and Transmitter unsafe { self.ports.cmd.write(CR_RE | CR_TE) } @@ -198,14 +201,11 @@ impl Device { unsafe { self.ports.tx_addrs[i].write(tx_addr as u32) } } - // Set interrupts - unsafe { self.ports.imr.write(IMR_TOK | IMR_ROK) } - // Configure receive buffer (RCR) unsafe { self.ports.rx_config.write(RCR_RBLEN | RCR_WRAP | RCR_AB | RCR_AM | RCR_APM | RCR_AAP) } // Configure transmit buffer (TCR) - unsafe { self.ports.tx_config.write(TCR_IFG | TCR_MXDMA0 | TCR_MXDMA1 | TCR_MXDMA2); } + unsafe { self.ports.tx_config.write(TCR_IFG | TCR_MXDMA1 | TCR_MXDMA2); } } } From 7eea0893c89b8c2d311842f576317303a5d75577 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Thu, 4 May 2023 19:39:00 +0200 Subject: [PATCH 06/13] Use spin_loop --- src/sys/net/rtl8139.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/sys/net/rtl8139.rs b/src/sys/net/rtl8139.rs index 9e13d11e..fc7e403a 100644 --- a/src/sys/net/rtl8139.rs +++ b/src/sys/net/rtl8139.rs @@ -5,6 +5,7 @@ use alloc::sync::Arc; use alloc::vec::Vec; use core::convert::TryInto; use core::sync::atomic::{AtomicUsize, Ordering}; +use core::hint::spin_loop; use smoltcp::wire::EthernetAddress; use x86_64::instructions::port::Port; @@ -175,7 +176,9 @@ impl Device { // Software reset unsafe { self.ports.cmd.write(CR_RST); - while self.ports.cmd.read() & CR_RST != 0 {} + while self.ports.cmd.read() & CR_RST != 0 { + spin_loop(); + } } // Set interrupts @@ -267,11 +270,12 @@ impl EthernetDeviceIO for Device { // transmit threshold means 8 bytes. So we just write the size of // the packet. cmd_port.write(0x1FFF & len as u32); - - // When the whole packet is moved to FIFO, the OWN bit is set to 1 - while cmd_port.read() & OWN != OWN {} - // When the whole packet is moved to line, the TOK bit is set to 1 - while cmd_port.read() & TOK != TOK {} + while cmd_port.read() & OWN != OWN { + spin_loop(); + } + while cmd_port.read() & TOK != TOK { + spin_loop(); + } } } From 68ad46bf987a7ccb7838c162c4e9e7e1fee4aedc Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Thu, 4 May 2023 19:46:58 +0200 Subject: [PATCH 07/13] Add atomic fence before polling for status change --- src/sys/net/rtl8139.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sys/net/rtl8139.rs b/src/sys/net/rtl8139.rs index fc7e403a..d25ed774 100644 --- a/src/sys/net/rtl8139.rs +++ b/src/sys/net/rtl8139.rs @@ -4,8 +4,8 @@ use crate::sys::net::{EthernetDeviceIO, Config, Stats}; use alloc::sync::Arc; use alloc::vec::Vec; use core::convert::TryInto; -use core::sync::atomic::{AtomicUsize, Ordering}; use core::hint::spin_loop; +use core::sync::atomic::{fence, AtomicUsize, Ordering}; use smoltcp::wire::EthernetAddress; use x86_64::instructions::port::Port; @@ -176,6 +176,7 @@ impl Device { // Software reset unsafe { self.ports.cmd.write(CR_RST); + fence(Ordering::SeqCst); while self.ports.cmd.read() & CR_RST != 0 { spin_loop(); } @@ -270,6 +271,8 @@ impl EthernetDeviceIO for Device { // transmit threshold means 8 bytes. So we just write the size of // the packet. cmd_port.write(0x1FFF & len as u32); + fence(Ordering::SeqCst); + while cmd_port.read() & OWN != OWN { spin_loop(); } From 0b2f371efc55eb81e3883993a04368edd4fffc79 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Fri, 5 May 2023 08:45:09 +0200 Subject: [PATCH 08/13] Disable interrupts --- src/sys/net/rtl8139.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sys/net/rtl8139.rs b/src/sys/net/rtl8139.rs index d25ed774..362d6ed3 100644 --- a/src/sys/net/rtl8139.rs +++ b/src/sys/net/rtl8139.rs @@ -183,7 +183,7 @@ impl Device { } // Set interrupts - unsafe { self.ports.imr.write(IMR_TOK | IMR_ROK) } + //unsafe { self.ports.imr.write(IMR_TOK | IMR_ROK) } // Enable Receive and Transmitter unsafe { self.ports.cmd.write(CR_RE | CR_TE) } @@ -253,6 +253,7 @@ impl EthernetDeviceIO for Device { self.ports.capr.write(((self.rx_offset % RX_BUFFER_LEN) - RX_BUFFER_PAD) as u16); } + //unsafe { self.ports.isr.write(0x1); } Some(self.rx_buffer[(offset + 4)..(offset + n)].to_vec()) } @@ -280,6 +281,7 @@ impl EthernetDeviceIO for Device { spin_loop(); } } + //unsafe { self.ports.isr.write(0x4); } } fn next_tx_buffer(&mut self, len: usize) -> &mut [u8] { From b80a596314dae39b14ee5b7b4d98e0dc714b6eda Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Fri, 5 May 2023 19:01:12 +0200 Subject: [PATCH 09/13] Update device capabilities --- src/sys/net/mod.rs | 2 +- src/sys/net/rtl8139.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sys/net/mod.rs b/src/sys/net/mod.rs index 4fff322d..78d0369c 100644 --- a/src/sys/net/mod.rs +++ b/src/sys/net/mod.rs @@ -79,7 +79,7 @@ impl<'a> smoltcp::phy::Device<'a> for EthernetDevice { fn capabilities(&self) -> DeviceCapabilities { let mut caps = DeviceCapabilities::default(); caps.max_transmission_unit = 1500; - caps.max_burst_size = Some(1); + caps.max_burst_size = Some(64); caps } diff --git a/src/sys/net/rtl8139.rs b/src/sys/net/rtl8139.rs index 362d6ed3..a71a0772 100644 --- a/src/sys/net/rtl8139.rs +++ b/src/sys/net/rtl8139.rs @@ -15,7 +15,7 @@ use x86_64::instructions::port::Port; // 11 = 64K + 16 bytes const RX_BUFFER_IDX: usize = 0; -const MTU: usize = 1500; +const MTU: usize = 1536; const RX_BUFFER_PAD: usize = 16; const RX_BUFFER_LEN: usize = 8192 << RX_BUFFER_IDX; From b33b6d37fc3e3d9556e85423a1a1cca9cb96182d Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Fri, 5 May 2023 19:02:45 +0200 Subject: [PATCH 10/13] Fix http service --- src/usr/httpd.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/usr/httpd.rs b/src/usr/httpd.rs index 4e03c721..8fc4b911 100644 --- a/src/usr/httpd.rs +++ b/src/usr/httpd.rs @@ -209,11 +209,11 @@ pub fn main(args: &[&str]) -> Result<(), ExitCode> { if let Some(ref mut iface) = *sys::net::IFACE.lock() { println!("{}HTTP Server listening on 0.0.0.0:{}{}", csi_color, port, csi_reset); - let mtu = iface.device().capabilities().max_transmission_unit; + let buf_len = iface.device().capabilities().max_transmission_unit - 54; let mut connections = Vec::new(); for _ in 0..MAX_CONNECTIONS { - let tcp_rx_buffer = TcpSocketBuffer::new(vec![0; mtu]); - let tcp_tx_buffer = TcpSocketBuffer::new(vec![0; mtu]); + let tcp_rx_buffer = TcpSocketBuffer::new(vec![0; buf_len]); + let tcp_tx_buffer = TcpSocketBuffer::new(vec![0; buf_len]); let tcp_socket = TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer); let tcp_handle = iface.add_socket(tcp_socket); let send_queue: VecDeque> = VecDeque::new(); @@ -339,12 +339,13 @@ pub fn main(args: &[&str]) -> Result<(), ExitCode> { } (buffer.len(), res) }).unwrap(); - for chunk in res.buf.chunks(mtu) { + for chunk in res.buf.chunks(buf_len) { send_queue.push_back(chunk.to_vec()); } if socket.can_send() { if let Some(chunk) = send_queue.pop_front() { - socket.send_slice(&chunk).unwrap(); + let sent = socket.send_slice(&chunk).expect("Could not send chunk"); + debug_assert!(sent == chunk.len()); } } if send_queue.is_empty() && !res.is_persistent() { From 50c578f7da34b6ecd49b94967a084823435f2fca Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Fri, 5 May 2023 19:55:04 +0200 Subject: [PATCH 11/13] Update /var/www --- dsk/var/www/index.html | 18 ++++++++++++++++++ dsk/var/www/moros.css | 1 + dsk/var/www/moros.png | 1 + src/usr/install.rs | 5 +++-- www/build.sh | 2 +- 5 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 dsk/var/www/index.html create mode 120000 dsk/var/www/moros.css create mode 120000 dsk/var/www/moros.png diff --git a/dsk/var/www/index.html b/dsk/var/www/index.html new file mode 100644 index 00000000..b0862bc4 --- /dev/null +++ b/dsk/var/www/index.html @@ -0,0 +1,18 @@ + + + + + MOROS: Obscure Rust Operating System + + + +

MOROS: Obscure Rust Operating System

+ +

screenshot

+ +

MOROS is a hobby operating system written in Rust by Vincent Ollivier.

+ +

It targets computers with a x86-64 architecture and a BIOS, so mostly from 2005 +to 2020, but it also runs well on most emulators (Bochs, QEMU, and VirtualBox).

+ + diff --git a/dsk/var/www/moros.css b/dsk/var/www/moros.css new file mode 120000 index 00000000..50c6c28c --- /dev/null +++ b/dsk/var/www/moros.css @@ -0,0 +1 @@ +../../../www/moros.css \ No newline at end of file diff --git a/dsk/var/www/moros.png b/dsk/var/www/moros.png new file mode 120000 index 00000000..2dc35f00 --- /dev/null +++ b/dsk/var/www/moros.png @@ -0,0 +1 @@ +../../../www/moros.png \ No newline at end of file diff --git a/src/usr/install.rs b/src/usr/install.rs index fa1adeb7..6d445453 100644 --- a/src/usr/install.rs +++ b/src/usr/install.rs @@ -82,8 +82,9 @@ pub fn copy_files(verbose: bool) { copy_file("/tmp/beep/mario.sh", include_bytes!("../../dsk/tmp/beep/mario.sh"), verbose); create_dir("/var/www", verbose); - copy_file("/var/www/index.html", include_bytes!("../../www/index.html"), verbose); - copy_file("/var/www/moros.png", include_bytes!("../../www/moros.png"), verbose); + copy_file("/var/www/index.html", include_bytes!("../../dsk/var/www/index.html"), verbose); + copy_file("/var/www/moros.png", include_bytes!("../../dsk/var/www/moros.png"), verbose); + copy_file("/var/www/moros.css", include_bytes!("../../dsk/var/www/moros.css"), verbose); } pub fn main(args: &[&str]) -> Result<(), ExitCode> { diff --git a/www/build.sh b/www/build.sh index e67d2127..e8f3ca81 100644 --- a/www/build.sh +++ b/www/build.sh @@ -14,7 +14,7 @@ for md in ../doc/*.md; do $title - + EOF From 981073f7b12525d68b9a9fcddc337ab4e33bf27d Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Fri, 5 May 2023 22:13:07 +0200 Subject: [PATCH 12/13] Refactor buf len --- src/usr/httpd.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/usr/httpd.rs b/src/usr/httpd.rs index 8fc4b911..75c00a16 100644 --- a/src/usr/httpd.rs +++ b/src/usr/httpd.rs @@ -209,7 +209,8 @@ pub fn main(args: &[&str]) -> Result<(), ExitCode> { if let Some(ref mut iface) = *sys::net::IFACE.lock() { println!("{}HTTP Server listening on 0.0.0.0:{}{}", csi_color, port, csi_reset); - let buf_len = iface.device().capabilities().max_transmission_unit - 54; + let mtu = iface.device().capabilities().max_transmission_unit; + let buf_len = mtu - 14 - 20 - 20; // ETH+TCP+IP headers let mut connections = Vec::new(); for _ in 0..MAX_CONNECTIONS { let tcp_rx_buffer = TcpSocketBuffer::new(vec![0; buf_len]); From f0014aa3b2278c488d8778dcaee2d73539850816 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Fri, 5 May 2023 22:59:53 +0200 Subject: [PATCH 13/13] Update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf067d6b..4cd21b36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ # Changelog ## Unreleased +- Fix RTL8139 driver issues (#483) +- Improve help system (#481) +- Refactor lisp functions (#478) +- Improve asm binaries (#482) +- Add light palette (#480) +- Fix invalid bytes from serial (#479) - Refactor lisp functions (#478) - Improve asm binaries (#482) - Add light palette (#480)