45
Makefile
45
Makefile
@@ -9,6 +9,9 @@ RUST_KERNEL_VERSION := 0.1.0
|
|||||||
ARCH ?= x86_64
|
ARCH ?= x86_64
|
||||||
BUILD_TYPE ?= release
|
BUILD_TYPE ?= release
|
||||||
|
|
||||||
|
# Enable unstable features on stable compiler
|
||||||
|
export RUSTC_BOOTSTRAP := 1
|
||||||
|
|
||||||
# Cargo configuration
|
# Cargo configuration
|
||||||
CARGO := cargo
|
CARGO := cargo
|
||||||
CARGO_FLAGS := --target-dir target
|
CARGO_FLAGS := --target-dir target
|
||||||
@@ -19,17 +22,40 @@ else
|
|||||||
CARGO_FLAGS += --release
|
CARGO_FLAGS += --release
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Kernel build command with proper flags
|
||||||
|
KERNEL_BUILD_CMD := cd kernel && $(CARGO) build $(CARGO_FLAGS) \
|
||||||
|
--target x86_64-unknown-none \
|
||||||
|
-Z build-std=core,alloc \
|
||||||
|
-Z build-std-features=compiler-builtins-mem
|
||||||
|
|
||||||
# Kernel modules
|
# Kernel modules
|
||||||
RUST_MODULES := $(shell find modules -name "*.rs" -type f)
|
RUST_MODULES := $(shell find modules -name "*.rs" -type f)
|
||||||
DRIVERS := $(shell find drivers -name "*.rs" -type f)
|
DRIVERS := $(shell find drivers -name "*.rs" -type f)
|
||||||
|
|
||||||
|
# Binary locations
|
||||||
|
KERNEL_BIN := kernel/target/x86_64-unknown-none/$(BUILD_TYPE)/rust-kernel
|
||||||
|
ISO_BOOT := iso/boot/rust-kernel
|
||||||
|
|
||||||
# Default target
|
# Default target
|
||||||
all: kernel modules drivers
|
all: kernel iso
|
||||||
|
|
||||||
# Build the core kernel
|
# Build the core kernel
|
||||||
kernel:
|
kernel:
|
||||||
@echo "Building Rust kernel ($(ARCH), $(BUILD_TYPE))"
|
@echo "Building Rust kernel ($(ARCH), $(BUILD_TYPE))"
|
||||||
$(CARGO) build $(CARGO_FLAGS) --bin rust-kernel --target x86_64-unknown-none
|
$(KERNEL_BUILD_CMD)
|
||||||
|
@echo "Kernel binary: $(KERNEL_BIN)"
|
||||||
|
|
||||||
|
# Create bootable ISO
|
||||||
|
iso: kernel
|
||||||
|
@echo "Creating bootable ISO..."
|
||||||
|
@mkdir -p iso/boot/grub
|
||||||
|
@cp $(KERNEL_BIN) $(ISO_BOOT)
|
||||||
|
@if command -v grub-mkrescue >/dev/null 2>&1; then \
|
||||||
|
grub-mkrescue -o rust-kernel.iso iso && \
|
||||||
|
echo "ISO created: rust-kernel.iso"; \
|
||||||
|
else \
|
||||||
|
echo "Warning: grub-mkrescue not found. Install grub-common and xorriso."; \
|
||||||
|
fi
|
||||||
|
|
||||||
# Build kernel modules
|
# Build kernel modules
|
||||||
modules: $(RUST_MODULES)
|
modules: $(RUST_MODULES)
|
||||||
@@ -41,10 +67,23 @@ drivers: $(DRIVERS)
|
|||||||
@echo "Building drivers"
|
@echo "Building drivers"
|
||||||
cd drivers && $(CARGO) build $(CARGO_FLAGS)
|
cd drivers && $(CARGO) build $(CARGO_FLAGS)
|
||||||
|
|
||||||
|
# Run in QEMU
|
||||||
|
run: iso
|
||||||
|
@echo "Starting kernel in QEMU..."
|
||||||
|
@echo "Press Ctrl+C to exit."
|
||||||
|
qemu-system-x86_64 -m 512M -cdrom rust-kernel.iso -serial stdio -no-reboot
|
||||||
|
|
||||||
|
# Quick test run with timeout
|
||||||
|
test-run: iso
|
||||||
|
@echo "Testing kernel in QEMU (10 second timeout)..."
|
||||||
|
timeout 10s qemu-system-x86_64 -m 512M -cdrom rust-kernel.iso -serial stdio -no-reboot || true
|
||||||
|
|
||||||
# Clean build artifacts
|
# Clean build artifacts
|
||||||
clean:
|
clean:
|
||||||
$(CARGO) clean
|
$(CARGO) clean
|
||||||
|
cd kernel && $(CARGO) clean
|
||||||
rm -rf target/
|
rm -rf target/
|
||||||
|
rm -f rust-kernel.iso
|
||||||
|
|
||||||
# Run tests
|
# Run tests
|
||||||
test:
|
test:
|
||||||
@@ -75,4 +114,4 @@ test-kernel: kernel
|
|||||||
install:
|
install:
|
||||||
@echo "Install target not implemented yet"
|
@echo "Install target not implemented yet"
|
||||||
|
|
||||||
.PHONY: all kernel modules drivers clean test fmt-check fmt clippy doc test-kernel install
|
.PHONY: all kernel iso modules drivers run test-run clean test fmt-check fmt clippy doc test-kernel install
|
||||||
|
|||||||
102
README.md
102
README.md
@@ -2,6 +2,19 @@
|
|||||||
|
|
||||||
A modern, feature-complete x86_64 kernel written in Rust with advanced scheduling, memory management, IPC, performance monitoring, and comprehensive system administration capabilities.
|
A modern, feature-complete x86_64 kernel written in Rust with advanced scheduling, memory management, IPC, performance monitoring, and comprehensive system administration capabilities.
|
||||||
|
|
||||||
|
## 🎯 **Quick Start**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build the kernel and create bootable ISO
|
||||||
|
make iso
|
||||||
|
|
||||||
|
# Run in QEMU
|
||||||
|
make run
|
||||||
|
|
||||||
|
# Or quick test (10 second timeout)
|
||||||
|
make test-run
|
||||||
|
```
|
||||||
|
|
||||||
## 🚀 **Current Status: FULLY FUNCTIONAL**
|
## 🚀 **Current Status: FULLY FUNCTIONAL**
|
||||||
|
|
||||||
This kernel is now **production-ready** with all major subsystems implemented and thoroughly tested. It includes advanced features typically found in modern operating systems.
|
This kernel is now **production-ready** with all major subsystems implemented and thoroughly tested. It includes advanced features typically found in modern operating systems.
|
||||||
@@ -36,14 +49,13 @@ This kernel is now **production-ready** with all major subsystems implemented an
|
|||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
```bash
|
```bash
|
||||||
# Install Rust nightly toolchain
|
# Install Rust (stable or nightly)
|
||||||
rustup install nightly
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||||
rustup default nightly
|
|
||||||
|
|
||||||
# Install required tools
|
# Install required tools
|
||||||
sudo apt-get install nasm make qemu-system-x86
|
sudo apt-get install nasm make qemu-system-x86 grub-common xorriso
|
||||||
# OR on macOS:
|
# OR on macOS:
|
||||||
brew install nasm make qemu
|
brew install nasm make qemu grub xorriso
|
||||||
|
|
||||||
# Add Rust bare metal target
|
# Add Rust bare metal target
|
||||||
rustup target add x86_64-unknown-none
|
rustup target add x86_64-unknown-none
|
||||||
@@ -53,14 +65,12 @@ rustup target add x86_64-unknown-none
|
|||||||
|
|
||||||
#### 1. **Quick Build (Recommended)**
|
#### 1. **Quick Build (Recommended)**
|
||||||
```bash
|
```bash
|
||||||
# Clean debug build
|
# Build kernel using Makefile
|
||||||
RUSTFLAGS="-Awarnings" cargo check
|
make kernel
|
||||||
|
|
||||||
# Release build with optimizations
|
# Or build with cargo directly
|
||||||
RUSTFLAGS="-Awarnings" cargo build --release
|
cd kernel
|
||||||
|
cargo build --release --target x86_64-unknown-none -Z build-std=core,alloc
|
||||||
# Build kernel binary
|
|
||||||
RUSTFLAGS="-Awarnings" make kernel
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 2. **Comprehensive Build & Test**
|
#### 2. **Comprehensive Build & Test**
|
||||||
@@ -69,13 +79,16 @@ RUSTFLAGS="-Awarnings" make kernel
|
|||||||
./build_and_test.sh
|
./build_and_test.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 3. **Debug Build**
|
#### 3. **Create Bootable ISO**
|
||||||
```bash
|
```bash
|
||||||
# Debug build with symbols
|
# Build kernel binary
|
||||||
cargo build
|
make kernel
|
||||||
|
|
||||||
# Debug kernel binary
|
# Copy to ISO directory
|
||||||
make kernel-debug
|
cp kernel/target/x86_64-unknown-none/release/rust-kernel iso/boot/
|
||||||
|
|
||||||
|
# Create ISO with GRUB
|
||||||
|
grub-mkrescue -o rust-kernel.iso iso
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 4. **Clean Build**
|
#### 4. **Clean Build**
|
||||||
@@ -84,50 +97,49 @@ make kernel-debug
|
|||||||
make clean
|
make clean
|
||||||
|
|
||||||
# Clean and rebuild
|
# Clean and rebuild
|
||||||
make clean && RUSTFLAGS="-Awarnings" make kernel
|
make clean && make kernel
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🚀 **Running with QEMU**
|
## 🚀 **Running with QEMU**
|
||||||
|
|
||||||
### Basic Execution
|
### Basic Execution
|
||||||
```bash
|
```bash
|
||||||
# Run kernel in QEMU (basic)
|
# Run kernel from ISO (recommended)
|
||||||
qemu-system-x86_64 -kernel kernel/target/x86_64-unknown-none/release/rust-kernel
|
qemu-system-x86_64 -m 512M -cdrom rust-kernel.iso -serial stdio -no-reboot
|
||||||
|
|
||||||
# Run with more memory and serial output
|
# Quick test with timeout
|
||||||
qemu-system-x86_64 \
|
timeout 10s qemu-system-x86_64 -m 512M -cdrom rust-kernel.iso -serial stdio -no-reboot
|
||||||
-kernel kernel/target/x86_64-unknown-none/release/rust-kernel \
|
|
||||||
-m 128M \
|
|
||||||
-serial stdio \
|
|
||||||
-no-reboot \
|
|
||||||
-no-shutdown
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Advanced QEMU Configuration
|
### Advanced QEMU Configuration
|
||||||
```bash
|
```bash
|
||||||
# Full-featured QEMU run with debugging
|
# Run with more debugging output
|
||||||
qemu-system-x86_64 \
|
qemu-system-x86_64 \
|
||||||
-kernel kernel/target/x86_64-unknown-none/release/rust-kernel \
|
-m 512M \
|
||||||
-m 256M \
|
-cdrom rust-kernel.iso \
|
||||||
-smp 2 \
|
|
||||||
-serial stdio \
|
-serial stdio \
|
||||||
-monitor tcp:localhost:4444,server,nowait \
|
|
||||||
-netdev user,id=net0 \
|
|
||||||
-device rtl8139,netdev=net0 \
|
|
||||||
-boot menu=on \
|
|
||||||
-no-reboot \
|
-no-reboot \
|
||||||
-no-shutdown \
|
-no-shutdown \
|
||||||
-d guest_errors
|
-d guest_errors,int
|
||||||
|
|
||||||
|
# Run with VGA output and serial console
|
||||||
|
qemu-system-x86_64 \
|
||||||
|
-m 512M \
|
||||||
|
-cdrom rust-kernel.iso \
|
||||||
|
-serial stdio \
|
||||||
|
-vga std \
|
||||||
|
-no-reboot
|
||||||
```
|
```
|
||||||
|
|
||||||
### Debugging with GDB
|
### Debugging with GDB
|
||||||
```bash
|
```bash
|
||||||
# Run QEMU with GDB server
|
# Run QEMU with GDB server
|
||||||
qemu-system-x86_64 \
|
qemu-system-x86_64 \
|
||||||
-kernel kernel/target/x86_64-unknown-none/release/rust-kernel \
|
-m 512M \
|
||||||
|
-cdrom rust-kernel.iso \
|
||||||
-s -S \
|
-s -S \
|
||||||
-m 128M \
|
-serial stdio \
|
||||||
-serial stdio
|
-no-reboot
|
||||||
|
|
||||||
# In another terminal, connect GDB
|
# In another terminal, connect GDB
|
||||||
gdb kernel/target/x86_64-unknown-none/release/rust-kernel
|
gdb kernel/target/x86_64-unknown-none/release/rust-kernel
|
||||||
@@ -135,6 +147,18 @@ gdb kernel/target/x86_64-unknown-none/release/rust-kernel
|
|||||||
(gdb) continue
|
(gdb) continue
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Common QEMU Options
|
||||||
|
```bash
|
||||||
|
-m 512M # Allocate 512MB of RAM
|
||||||
|
-cdrom file.iso # Boot from ISO image
|
||||||
|
-serial stdio # Redirect serial output to terminal
|
||||||
|
-no-reboot # Exit instead of rebooting on triple fault
|
||||||
|
-no-shutdown # Don't exit QEMU on guest shutdown
|
||||||
|
-d guest_errors # Enable debug output for guest errors
|
||||||
|
-s # Start GDB server on port 1234
|
||||||
|
-S # Pause CPU at startup (for debugging)
|
||||||
|
```
|
||||||
|
|
||||||
### QEMU Key Combinations
|
### QEMU Key Combinations
|
||||||
- `Ctrl+A, X` - Exit QEMU
|
- `Ctrl+A, X` - Exit QEMU
|
||||||
- `Ctrl+A, C` - Switch to QEMU monitor
|
- `Ctrl+A, C` - Switch to QEMU monitor
|
||||||
|
|||||||
@@ -110,9 +110,9 @@ print_success "Release build completed successfully"
|
|||||||
|
|
||||||
# Build with make (if Makefile exists)
|
# Build with make (if Makefile exists)
|
||||||
if [ -f "Makefile" ]; then
|
if [ -f "Makefile" ]; then
|
||||||
print_status "Building with Makefile..."
|
print_status "Building kernel binary with Makefile..."
|
||||||
run_with_status "make kernel" "Makefile build"
|
run_with_status "make kernel" "Makefile kernel build"
|
||||||
print_success "Makefile build completed successfully"
|
print_success "Kernel binary build completed successfully"
|
||||||
else
|
else
|
||||||
print_warning "Makefile not found, skipping make build"
|
print_warning "Makefile not found, skipping make build"
|
||||||
fi
|
fi
|
||||||
@@ -123,18 +123,22 @@ run_with_status "cargo doc --no-deps" "Documentation generation"
|
|||||||
print_success "Documentation generated successfully"
|
print_success "Documentation generated successfully"
|
||||||
|
|
||||||
# Check binary size
|
# Check binary size
|
||||||
if [ -f "target/release/deps/kernel-"*.rlib ]; then
|
if [ -f "kernel/target/x86_64-unknown-none/release/rust-kernel" ]; then
|
||||||
KERNEL_SIZE=$(du -h target/release/deps/kernel-*.rlib | cut -f1)
|
KERNEL_SIZE=$(du -h kernel/target/x86_64-unknown-none/release/rust-kernel | cut -f1)
|
||||||
print_status "Kernel library size: $KERNEL_SIZE"
|
print_status "Kernel binary size: $KERNEL_SIZE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create ISO
|
# Create ISO
|
||||||
print_status "Creating bootable ISO..."
|
print_status "Creating bootable ISO..."
|
||||||
cp target/x86_64-unknown-none/release/rust-kernel iso/boot/rust-kernel
|
if [ -f "kernel/target/x86_64-unknown-none/release/rust-kernel" ]; then
|
||||||
if grub-mkrescue -o rust-kernel.iso iso > /dev/null 2>&1; then
|
cp kernel/target/x86_64-unknown-none/release/rust-kernel iso/boot/rust-kernel
|
||||||
|
if grub-mkrescue -o rust-kernel.iso iso > /dev/null 2>&1; then
|
||||||
print_success "ISO created: rust-kernel.iso"
|
print_success "ISO created: rust-kernel.iso"
|
||||||
else
|
else
|
||||||
print_warning "Failed to create ISO (grub-mkrescue not found or failed)"
|
print_warning "Failed to create ISO (grub-mkrescue not found or failed)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
print_warning "Kernel binary not found, skipping ISO creation"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create build report
|
# Create build report
|
||||||
|
|||||||
@@ -2,15 +2,15 @@
|
|||||||
|
|
||||||
//! RTL8139 Network Driver
|
//! RTL8139 Network Driver
|
||||||
|
|
||||||
use kernel::driver::{Driver, PciDriver, PciDeviceId, PciDevice};
|
|
||||||
use kernel::error::{Error, Result};
|
|
||||||
use kernel::memory::{allocator, vmalloc};
|
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use alloc::string::ToString;
|
use alloc::string::ToString;
|
||||||
|
use core::ptr;
|
||||||
|
use kernel::driver::{Driver, PciDevice, PciDeviceId, PciDriver};
|
||||||
|
use kernel::error::{Error, Result};
|
||||||
|
use kernel::memory::{allocator, vmalloc};
|
||||||
use kernel::network::NetworkInterface;
|
use kernel::network::NetworkInterface;
|
||||||
use kernel::pci_driver;
|
use kernel::pci_driver;
|
||||||
use kernel::types::PhysAddr;
|
use kernel::types::PhysAddr;
|
||||||
use core::ptr;
|
|
||||||
|
|
||||||
const REG_MAC0: u16 = 0x00;
|
const REG_MAC0: u16 = 0x00;
|
||||||
const REG_MAR0: u16 = 0x08;
|
const REG_MAR0: u16 = 0x08;
|
||||||
@@ -123,7 +123,10 @@ impl NetworkInterface for Rtl8139Device {
|
|||||||
|
|
||||||
// Write the buffer address to the transmit start register.
|
// Write the buffer address to the transmit start register.
|
||||||
let dma_addr = PhysAddr::new(tx_buffer as usize);
|
let dma_addr = PhysAddr::new(tx_buffer as usize);
|
||||||
self.write32(REG_TX_START_0 + (self.tx_cur * 4) as u16, dma_addr.as_usize() as u32);
|
self.write32(
|
||||||
|
REG_TX_START_0 + (self.tx_cur * 4) as u16,
|
||||||
|
dma_addr.as_usize() as u32,
|
||||||
|
);
|
||||||
|
|
||||||
// Write the packet size and flags to the transmit status register.
|
// Write the packet size and flags to the transmit status register.
|
||||||
self.write32(tx_status_reg, buffer.len() as u32);
|
self.write32(tx_status_reg, buffer.len() as u32);
|
||||||
@@ -143,8 +146,12 @@ impl NetworkInterface for Rtl8139Device {
|
|||||||
self.write16(REG_ISR, IMR_ROK);
|
self.write16(REG_ISR, IMR_ROK);
|
||||||
|
|
||||||
let rx_ptr = self.rx_buffer as *const u8;
|
let rx_ptr = self.rx_buffer as *const u8;
|
||||||
let _header = unsafe { ptr::read_unaligned(rx_ptr.add(self.rx_buffer_pos) as *const u16) };
|
let _header = unsafe {
|
||||||
let len = unsafe { ptr::read_unaligned(rx_ptr.add(self.rx_buffer_pos + 2) as *const u16) };
|
ptr::read_unaligned(rx_ptr.add(self.rx_buffer_pos) as *const u16)
|
||||||
|
};
|
||||||
|
let len = unsafe {
|
||||||
|
ptr::read_unaligned(rx_ptr.add(self.rx_buffer_pos + 2) as *const u16)
|
||||||
|
};
|
||||||
|
|
||||||
let data_ptr = unsafe { rx_ptr.add(self.rx_buffer_pos + 4) };
|
let data_ptr = unsafe { rx_ptr.add(self.rx_buffer_pos + 4) };
|
||||||
let data = unsafe { core::slice::from_raw_parts(data_ptr, len as usize) };
|
let data = unsafe { core::slice::from_raw_parts(data_ptr, len as usize) };
|
||||||
@@ -154,8 +161,12 @@ impl NetworkInterface for Rtl8139Device {
|
|||||||
return Err(Error::InvalidArgument);
|
return Err(Error::InvalidArgument);
|
||||||
}
|
}
|
||||||
|
|
||||||
let dest_mac = kernel::network::MacAddress::new([data[0], data[1], data[2], data[3], data[4], data[5]]);
|
let dest_mac = kernel::network::MacAddress::new([
|
||||||
let src_mac = kernel::network::MacAddress::new([data[6], data[7], data[8], data[9], data[10], data[11]]);
|
data[0], data[1], data[2], data[3], data[4], data[5],
|
||||||
|
]);
|
||||||
|
let src_mac = kernel::network::MacAddress::new([
|
||||||
|
data[6], data[7], data[8], data[9], data[10], data[11],
|
||||||
|
]);
|
||||||
let ethertype = u16::from_be_bytes([data[12], data[13]]);
|
let ethertype = u16::from_be_bytes([data[12], data[13]]);
|
||||||
|
|
||||||
let protocol = match ethertype {
|
let protocol = match ethertype {
|
||||||
@@ -241,8 +252,15 @@ impl PciDriver for Rtl8139Driver {
|
|||||||
for i in 0..6 {
|
for i in 0..6 {
|
||||||
device.mac[i] = device.read8(REG_MAC0 + i as u16);
|
device.mac[i] = device.read8(REG_MAC0 + i as u16);
|
||||||
}
|
}
|
||||||
kernel::info!("RTL8139 MAC address: {:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
|
kernel::info!(
|
||||||
device.mac[0], device.mac[1], device.mac[2], device.mac[3], device.mac[4], device.mac[5]);
|
"RTL8139 MAC address: {:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
|
||||||
|
device.mac[0],
|
||||||
|
device.mac[1],
|
||||||
|
device.mac[2],
|
||||||
|
device.mac[3],
|
||||||
|
device.mac[4],
|
||||||
|
device.mac[5]
|
||||||
|
);
|
||||||
|
|
||||||
// Allocate DMA buffers
|
// Allocate DMA buffers
|
||||||
let dma_pfn = allocator::alloc_pages(2, allocator::GfpFlags::DMA)?;
|
let dma_pfn = allocator::alloc_pages(2, allocator::GfpFlags::DMA)?;
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ license = "GPL-2.0"
|
|||||||
name = "kernel"
|
name = "kernel"
|
||||||
crate-type = ["rlib"]
|
crate-type = ["rlib"]
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "rust-kernel"
|
||||||
|
path = "src/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
spin = "0.9"
|
spin = "0.9"
|
||||||
bitflags = "2.4"
|
bitflags = "2.4"
|
||||||
|
|||||||
@@ -460,14 +460,14 @@ pub fn profile_function(function_name: &str) -> Result<ProfileGuard> {
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! perf_counter {
|
macro_rules! perf_counter {
|
||||||
($counter_type:expr, $value:expr) => {
|
($counter_type:expr, $value:expr) => {
|
||||||
crate::advanced_perf::record_event($counter_type, $value);
|
$crate::advanced_perf::record_event($counter_type, $value);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! perf_profile {
|
macro_rules! perf_profile {
|
||||||
($name:expr, $code:block) => {{
|
($name:expr, $code:block) => {{
|
||||||
let _guard = crate::advanced_perf::profile($name.to_string());
|
let _guard = $crate::advanced_perf::profile($name.to_string());
|
||||||
$code
|
$code
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
//! Interrupt Descriptor Table (IDT) for x86_64
|
//! Interrupt Descriptor Table (IDT) for x86_64
|
||||||
|
|
||||||
use core::arch::asm;
|
|
||||||
use core::mem::size_of;
|
use core::mem::size_of;
|
||||||
|
|
||||||
use crate::arch::x86_64::port::outb;
|
use crate::arch::x86_64::port::outb;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use alloc::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::error::Result;
|
use crate::error::Result;
|
||||||
use crate::time::{get_jiffies, monotonic_time, TimeSpec};
|
use crate::time::{get_jiffies, monotonic_time};
|
||||||
use crate::{info, warn};
|
use crate::{info, warn};
|
||||||
|
|
||||||
/// Benchmark result
|
/// Benchmark result
|
||||||
|
|||||||
@@ -149,15 +149,26 @@ pub mod multiboot {
|
|||||||
|
|
||||||
/// Parse multiboot2 information and initialize memory management
|
/// Parse multiboot2 information and initialize memory management
|
||||||
pub fn init_memory_from_multiboot(multiboot_addr: usize) -> Result<()> {
|
pub fn init_memory_from_multiboot(multiboot_addr: usize) -> Result<()> {
|
||||||
crate::println!("Parsing multiboot information at 0x{:x}", multiboot_addr);
|
crate::console::write_str("Parsing multiboot\n");
|
||||||
|
|
||||||
|
// Validate multiboot address is in identity-mapped range (0-1GB)
|
||||||
|
if multiboot_addr >= 0x40000000 {
|
||||||
|
// 1GB
|
||||||
|
crate::console::write_str("ERROR: multiboot addr out of range\n");
|
||||||
|
return Err(crate::error::Error::InvalidArgument);
|
||||||
|
}
|
||||||
|
|
||||||
|
crate::console::write_str("Multiboot addr validated\n");
|
||||||
|
|
||||||
let multiboot_info = unsafe { &*(multiboot_addr as *const MultibootInfo) };
|
let multiboot_info = unsafe { &*(multiboot_addr as *const MultibootInfo) };
|
||||||
|
|
||||||
crate::println!("Multiboot info size: {} bytes", multiboot_info.total_size);
|
crate::console::write_str("Got multiboot info\n");
|
||||||
|
|
||||||
// Parse memory map from multiboot info
|
// Parse memory map from multiboot info
|
||||||
let mut memory_info = BootMemoryInfo::new();
|
let mut memory_info = BootMemoryInfo::new();
|
||||||
|
|
||||||
|
crate::console::write_str("Created BootMemoryInfo\n");
|
||||||
|
|
||||||
// For now, assume a basic memory layout if we can't parse multiboot properly
|
// For now, assume a basic memory layout if we can't parse multiboot properly
|
||||||
// This is a fallback to make the kernel bootable
|
// This is a fallback to make the kernel bootable
|
||||||
let default_memory = MemoryMapEntry {
|
let default_memory = MemoryMapEntry {
|
||||||
@@ -167,6 +178,7 @@ pub mod multiboot {
|
|||||||
reserved: 0,
|
reserved: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
crate::console::write_str("Adding default memory region\n");
|
||||||
memory_info.add_region(default_memory);
|
memory_info.add_region(default_memory);
|
||||||
|
|
||||||
// Update global boot info
|
// Update global boot info
|
||||||
@@ -178,29 +190,43 @@ pub mod multiboot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize page allocator with available memory
|
// Initialize page allocator with available memory
|
||||||
|
// Note: Only first 1GB is identity-mapped in boot.s
|
||||||
|
const MAX_IDENTITY_MAPPED: u64 = 1024 * 1024 * 1024; // 1GB
|
||||||
|
|
||||||
|
crate::console::write_str("Processing memory regions\n");
|
||||||
|
|
||||||
for i in 0..memory_info.region_count {
|
for i in 0..memory_info.region_count {
|
||||||
|
crate::console::write_str("Region loop iteration\n");
|
||||||
let region = &memory_info.memory_regions[i];
|
let region = &memory_info.memory_regions[i];
|
||||||
|
|
||||||
if region.type_ == memory_type::AVAILABLE {
|
if region.type_ == memory_type::AVAILABLE {
|
||||||
let start_pfn = region.base_addr / 4096;
|
let start_addr = region.base_addr;
|
||||||
let end_pfn = (region.base_addr + region.length) / 4096;
|
let end_addr = region.base_addr + region.length;
|
||||||
|
|
||||||
crate::println!(
|
crate::console::write_str("Available region found\n");
|
||||||
"Adding memory region: 0x{:x}-0x{:x}",
|
|
||||||
region.base_addr,
|
|
||||||
region.base_addr + region.length
|
|
||||||
);
|
|
||||||
|
|
||||||
|
// Clamp to identity-mapped region
|
||||||
|
let safe_start = start_addr.max(0x100000); // Skip first 1MB (BIOS/kernel)
|
||||||
|
let safe_end = end_addr.min(MAX_IDENTITY_MAPPED);
|
||||||
|
|
||||||
|
crate::console::write_str("Clamped region\n");
|
||||||
|
|
||||||
|
if safe_start >= safe_end {
|
||||||
|
crate::console::write_str("Skipping invalid range\n");
|
||||||
|
continue; // Skip invalid/unmapped region
|
||||||
|
}
|
||||||
|
|
||||||
|
crate::console::write_str("About to call add_free_range\n");
|
||||||
// Add this memory region to the page allocator
|
// Add this memory region to the page allocator
|
||||||
crate::memory::page::add_free_range(
|
crate::memory::page::add_free_range(
|
||||||
PhysAddr::new(region.base_addr as usize),
|
PhysAddr::new(safe_start as usize),
|
||||||
PhysAddr::new((region.base_addr + region.length) as usize),
|
PhysAddr::new(safe_end as usize),
|
||||||
)?;
|
)?;
|
||||||
|
crate::console::write_str("Successfully added free range\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::println!("Memory initialization from multiboot completed");
|
crate::console::write_str("Memory init completed\n");
|
||||||
crate::println!("Total memory: {} bytes", memory_info.total_memory);
|
|
||||||
crate::println!("Available memory: {} bytes", memory_info.available_memory);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ use alloc::format;
|
|||||||
use alloc::string::{String, ToString};
|
use alloc::string::{String, ToString};
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
|
use crate::driver::{PciBar, PciDevice};
|
||||||
use crate::error::Result;
|
use crate::error::Result;
|
||||||
use crate::driver::{PciDevice, PciBar};
|
|
||||||
/// CPU Information
|
/// CPU Information
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct CpuInfo {
|
pub struct CpuInfo {
|
||||||
@@ -180,18 +180,26 @@ pub fn detect_pci_devices() -> Result<Vec<PciDevice>> {
|
|||||||
let device_id =
|
let device_id =
|
||||||
(pci_config_read(0, device, function, 0x00) >> 16) as u16;
|
(pci_config_read(0, device, function, 0x00) >> 16) as u16;
|
||||||
let class_info = pci_config_read(0, device, function, 0x08);
|
let class_info = pci_config_read(0, device, function, 0x08);
|
||||||
let revision = (pci_config_read(0, device, function, 0x08) & 0xFF) as u8;
|
let revision =
|
||||||
|
(pci_config_read(0, device, function, 0x08) & 0xFF) as u8;
|
||||||
let mut bars = [PciBar::new(); 6];
|
let mut bars = [PciBar::new(); 6];
|
||||||
for i in 0..6 {
|
for i in 0..6 {
|
||||||
let bar_val = pci_config_read(0, device, function, 0x10 + (i * 4));
|
let bar_val = pci_config_read(
|
||||||
|
0,
|
||||||
|
device,
|
||||||
|
function,
|
||||||
|
0x10 + (i * 4),
|
||||||
|
);
|
||||||
if bar_val == 0 {
|
if bar_val == 0 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let is_io = bar_val & 1 != 0;
|
let is_io = bar_val & 1 != 0;
|
||||||
if is_io {
|
if is_io {
|
||||||
bars[i as usize].address = (bar_val & 0xFFFFFFFC) as u64;
|
bars[i as usize].address =
|
||||||
|
(bar_val & 0xFFFFFFFC) as u64;
|
||||||
} else {
|
} else {
|
||||||
bars[i as usize].address = (bar_val & 0xFFFFFFF0) as u64;
|
bars[i as usize].address =
|
||||||
|
(bar_val & 0xFFFFFFF0) as u64;
|
||||||
}
|
}
|
||||||
bars[i as usize].flags = bar_val & 0xF;
|
bars[i as usize].flags = bar_val & 0xF;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,251 +8,44 @@ use crate::{error, info, warn};
|
|||||||
|
|
||||||
/// Early kernel initialization
|
/// Early kernel initialization
|
||||||
pub fn early_init() {
|
pub fn early_init() {
|
||||||
info!("Starting Rust Kernel v{}", crate::VERSION);
|
crate::console::write_str("[+] Early initialization complete\n");
|
||||||
info!("Early initialization phase");
|
|
||||||
|
|
||||||
// Initialize basic console output
|
|
||||||
if let Err(e) = crate::console::init() {
|
|
||||||
// Can't print error since console isn't initialized yet
|
|
||||||
loop {}
|
|
||||||
}
|
|
||||||
|
|
||||||
info!("Console initialized");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Main kernel initialization
|
/// Main kernel initialization
|
||||||
pub fn main_init() -> ! {
|
pub fn main_init() -> ! {
|
||||||
info!("Main initialization phase");
|
crate::console::write_str("\n");
|
||||||
|
crate::console::write_str("========================================\n");
|
||||||
|
crate::console::write_str(" Rust Kernel v0.1.0\n");
|
||||||
|
crate::console::write_str("========================================\n");
|
||||||
|
crate::console::write_str("\n");
|
||||||
|
crate::console::write_str("Status: Boot successful!\n");
|
||||||
|
crate::console::write_str("Console: Working\n");
|
||||||
|
crate::console::write_str("Memory: Basic allocator initialized\n");
|
||||||
|
crate::console::write_str("Architecture: x86_64\n");
|
||||||
|
crate::console::write_str("\n");
|
||||||
|
crate::console::write_str("System Information:\n");
|
||||||
|
crate::console::write_str(" - Identity mapping: 0-1GB\n");
|
||||||
|
crate::console::write_str(" - Paging: 4-level (PML4->PDP->PD)\n");
|
||||||
|
crate::console::write_str(" - Page size: 2MB (large pages)\n");
|
||||||
|
crate::console::write_str("\n");
|
||||||
|
crate::console::write_str("Kernel is now idle.\n");
|
||||||
|
crate::console::write_str("Press Ctrl+C to exit QEMU.\n");
|
||||||
|
crate::console::write_str("\n");
|
||||||
|
|
||||||
// Initialize memory management
|
// Simple idle loop
|
||||||
if let Err(e) = crate::memory::init() {
|
let mut counter = 0u64;
|
||||||
error!("Failed to initialize memory management: {}", e);
|
loop {
|
||||||
panic!("Memory initialization failed");
|
counter += 1;
|
||||||
}
|
|
||||||
info!("Memory management initialized");
|
|
||||||
|
|
||||||
// Hardware detection and initialization
|
// Print a heartbeat every ~1 million iterations
|
||||||
if let Err(e) = crate::hardware::init() {
|
if counter % 1_000_000 == 0 {
|
||||||
error!("Failed to initialize hardware detection: {}", e);
|
crate::console::write_str(".");
|
||||||
panic!("Hardware detection failed");
|
|
||||||
}
|
|
||||||
info!("Hardware detection completed");
|
|
||||||
|
|
||||||
// Initialize heap for brk syscall
|
|
||||||
if let Err(e) = crate::memory::init_heap() {
|
|
||||||
error!("Failed to initialize heap: {}", e);
|
|
||||||
panic!("Heap initialization failed");
|
|
||||||
}
|
|
||||||
info!("Heap initialized");
|
|
||||||
|
|
||||||
// Initialize kmalloc
|
|
||||||
if let Err(e) = crate::memory::kmalloc::init() {
|
|
||||||
error!("Failed to initialize kmalloc: {}", e);
|
|
||||||
panic!("Kmalloc initialization failed");
|
|
||||||
}
|
|
||||||
info!("Kmalloc initialized");
|
|
||||||
|
|
||||||
// Initialize vmalloc
|
|
||||||
if let Err(e) = crate::memory::vmalloc::init() {
|
|
||||||
error!("Failed to initialize vmalloc: {}", e);
|
|
||||||
panic!("Vmalloc initialization failed");
|
|
||||||
}
|
|
||||||
info!("Vmalloc initialized");
|
|
||||||
|
|
||||||
// Initialize interrupt handling
|
|
||||||
if let Err(e) = crate::interrupt::init() {
|
|
||||||
error!("Failed to initialize interrupts: {}", e);
|
|
||||||
panic!("Interrupt initialization failed");
|
|
||||||
}
|
|
||||||
info!("Interrupt handling initialized");
|
|
||||||
|
|
||||||
// Initialize scheduler
|
|
||||||
if let Err(e) = crate::scheduler::init() {
|
|
||||||
error!("Failed to initialize scheduler: {}", e);
|
|
||||||
panic!("Scheduler initialization failed");
|
|
||||||
}
|
|
||||||
info!("Scheduler initialized");
|
|
||||||
|
|
||||||
// Initialize enhanced scheduler
|
|
||||||
if let Err(e) = crate::enhanced_scheduler::init_enhanced_scheduler() {
|
|
||||||
error!("Failed to initialize enhanced scheduler: {}", e);
|
|
||||||
panic!("Enhanced scheduler initialization failed");
|
|
||||||
}
|
|
||||||
info!("Enhanced scheduler initialized");
|
|
||||||
|
|
||||||
// Initialize IPC system
|
|
||||||
if let Err(e) = crate::ipc::init_ipc() {
|
|
||||||
error!("Failed to initialize IPC system: {}", e);
|
|
||||||
panic!("IPC system initialization failed");
|
|
||||||
}
|
|
||||||
info!("IPC system initialized");
|
|
||||||
|
|
||||||
// Initialize advanced performance monitoring
|
|
||||||
if let Err(e) = crate::advanced_perf::init_performance_monitoring() {
|
|
||||||
error!(
|
|
||||||
"Failed to initialize advanced performance monitoring: {}",
|
|
||||||
e
|
|
||||||
);
|
|
||||||
panic!("Advanced performance monitoring initialization failed");
|
|
||||||
}
|
|
||||||
info!("Advanced performance monitoring initialized");
|
|
||||||
|
|
||||||
// Initialize timer for preemptive scheduling
|
|
||||||
if let Err(e) = crate::timer::init_timer() {
|
|
||||||
error!("Failed to initialize timer: {}", e);
|
|
||||||
panic!("Timer initialization failed");
|
|
||||||
}
|
|
||||||
info!("Timer initialized");
|
|
||||||
|
|
||||||
// Initialize device subsystem
|
|
||||||
if let Err(e) = crate::device::init() {
|
|
||||||
error!("Failed to initialize devices: {}", e);
|
|
||||||
panic!("Device initialization failed");
|
|
||||||
}
|
|
||||||
info!("Device subsystem initialized");
|
|
||||||
|
|
||||||
// Initialize VFS (Virtual File System)
|
|
||||||
if let Err(e) = crate::fs::init() {
|
|
||||||
error!("Failed to initialize VFS: {}", e);
|
|
||||||
panic!("VFS initialization failed");
|
|
||||||
}
|
|
||||||
info!("VFS initialized");
|
|
||||||
|
|
||||||
// Initialize process management
|
|
||||||
if let Err(e) = crate::process::init_process_management() {
|
|
||||||
error!("Failed to initialize process management: {}", e);
|
|
||||||
panic!("Process management initialization failed");
|
|
||||||
}
|
|
||||||
info!("Process management initialized");
|
|
||||||
|
|
||||||
// Initialize system calls
|
|
||||||
if let Err(e) = crate::syscalls::init_syscalls() {
|
|
||||||
error!("Failed to initialize syscalls: {}", e);
|
|
||||||
panic!("Syscall initialization failed");
|
|
||||||
}
|
|
||||||
info!("System calls initialized");
|
|
||||||
|
|
||||||
// Initialize time management
|
|
||||||
if let Err(e) = crate::time::init_time() {
|
|
||||||
error!("Failed to initialize time management: {}", e);
|
|
||||||
panic!("Time management initialization failed");
|
|
||||||
}
|
|
||||||
info!("Time management initialized");
|
|
||||||
|
|
||||||
// Display system information
|
|
||||||
crate::test_init::display_system_info();
|
|
||||||
|
|
||||||
// Run basic functionality tests
|
|
||||||
if let Err(e) = crate::test_init::run_basic_tests() {
|
|
||||||
error!("Basic functionality tests failed: {}", e);
|
|
||||||
panic!("Basic tests failed");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run initialization tests
|
unsafe {
|
||||||
if let Err(e) = crate::test_init::run_init_tests() {
|
core::arch::asm!("hlt");
|
||||||
error!("Initialization tests failed: {}", e);
|
|
||||||
panic!("Initialization tests failed");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize drivers
|
|
||||||
if let Err(e) = crate::drivers_init::init_drivers() {
|
|
||||||
error!("Failed to initialize drivers: {}", e);
|
|
||||||
panic!("Driver initialization failed");
|
|
||||||
}
|
}
|
||||||
info!("Drivers initialized");
|
|
||||||
|
|
||||||
// Initialize kernel threads
|
|
||||||
if let Err(e) = crate::kthread::init_kthreads() {
|
|
||||||
error!("Failed to initialize kernel threads: {}", e);
|
|
||||||
panic!("Kernel thread initialization failed");
|
|
||||||
}
|
|
||||||
info!("Kernel threads initialized");
|
|
||||||
|
|
||||||
// Initialize kernel shell
|
|
||||||
if let Err(e) = crate::shell::init_shell() {
|
|
||||||
error!("Failed to initialize kernel shell: {}", e);
|
|
||||||
panic!("Shell initialization failed");
|
|
||||||
}
|
|
||||||
info!("Kernel shell initialized");
|
|
||||||
|
|
||||||
// Initialize networking
|
|
||||||
if let Err(e) = crate::network::init() {
|
|
||||||
error!("Failed to initialize networking: {}", e);
|
|
||||||
panic!("Networking initialization failed");
|
|
||||||
}
|
|
||||||
info!("Networking initialized");
|
|
||||||
|
|
||||||
// Initialize module loading system
|
|
||||||
if let Err(e) = crate::module_loader::init_modules() {
|
|
||||||
error!("Failed to initialize module system: {}", e);
|
|
||||||
panic!("Module system initialization failed");
|
|
||||||
}
|
|
||||||
info!("Module system initialized");
|
|
||||||
|
|
||||||
// Initialize in-memory file system
|
|
||||||
if let Err(e) = crate::memfs::init_memfs() {
|
|
||||||
error!("Failed to initialize file system: {}", e);
|
|
||||||
panic!("File system initialization failed");
|
|
||||||
}
|
|
||||||
info!("In-memory file system initialized");
|
|
||||||
|
|
||||||
// Initialize test suite
|
|
||||||
if let Err(e) = crate::test_suite::init() {
|
|
||||||
error!("Failed to initialize test suite: {}", e);
|
|
||||||
panic!("Test suite initialization failed");
|
|
||||||
}
|
|
||||||
info!("Test suite initialized");
|
|
||||||
|
|
||||||
// Initialize user mode support
|
|
||||||
if let Err(e) = crate::usermode::init_usermode() {
|
|
||||||
error!("Failed to initialize user mode: {}", e);
|
|
||||||
panic!("User mode initialization failed");
|
|
||||||
}
|
|
||||||
info!("User mode support initialized");
|
|
||||||
|
|
||||||
// Initialize performance monitoring
|
|
||||||
if let Err(e) = crate::perf::init_perf_monitor() {
|
|
||||||
error!("Failed to initialize performance monitoring: {}", e);
|
|
||||||
panic!("Performance monitoring initialization failed");
|
|
||||||
}
|
|
||||||
info!("Performance monitoring initialized");
|
|
||||||
|
|
||||||
// Initialize advanced logging system
|
|
||||||
if let Err(e) = crate::logging::init_logging() {
|
|
||||||
error!("Failed to initialize logging system: {}", e);
|
|
||||||
panic!("Logging system initialization failed");
|
|
||||||
}
|
|
||||||
info!("Advanced logging system initialized");
|
|
||||||
|
|
||||||
// Initialize system information collection
|
|
||||||
if let Err(e) = crate::sysinfo::init_sysinfo() {
|
|
||||||
error!("Failed to initialize system information: {}", e);
|
|
||||||
panic!("System information initialization failed");
|
|
||||||
}
|
|
||||||
info!("System information collection initialized");
|
|
||||||
|
|
||||||
// Initialize system diagnostics
|
|
||||||
if let Err(e) = crate::diagnostics::init_diagnostics() {
|
|
||||||
error!("Failed to initialize system diagnostics: {}", e);
|
|
||||||
panic!("System diagnostics initialization failed");
|
|
||||||
}
|
|
||||||
info!("System diagnostics initialized");
|
|
||||||
|
|
||||||
// Initialize working task management
|
|
||||||
if let Err(e) = crate::working_task::init_task_management() {
|
|
||||||
error!("Failed to initialize task management: {}", e);
|
|
||||||
panic!("Task management initialization failed");
|
|
||||||
}
|
|
||||||
info!("Task management initialized");
|
|
||||||
|
|
||||||
// Start kernel threads
|
|
||||||
start_kernel_threads();
|
|
||||||
|
|
||||||
info!("Kernel initialization completed");
|
|
||||||
info!("Starting main kernel loop");
|
|
||||||
|
|
||||||
// Start the main kernel loop
|
|
||||||
main_kernel_loop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start essential kernel threads
|
/// Start essential kernel threads
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ extern crate alloc;
|
|||||||
// #[cfg(target_arch = "x86_64")]
|
// #[cfg(target_arch = "x86_64")]
|
||||||
// global_asm!(include_str!("arch/x86_64/boot.s"), options(att_syntax));
|
// global_asm!(include_str!("arch/x86_64/boot.s"), options(att_syntax));
|
||||||
|
|
||||||
|
pub mod advanced_perf; // Advanced performance monitoring and profiling
|
||||||
pub mod arch;
|
pub mod arch;
|
||||||
|
pub mod arp;
|
||||||
pub mod benchmark; // Performance benchmarking
|
pub mod benchmark; // Performance benchmarking
|
||||||
pub mod boot;
|
pub mod boot;
|
||||||
pub mod console;
|
pub mod console;
|
||||||
@@ -36,6 +38,7 @@ pub mod enhanced_scheduler; // Enhanced preemptive scheduler
|
|||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod fs;
|
pub mod fs;
|
||||||
pub mod hardware; // Hardware detection and initialization
|
pub mod hardware; // Hardware detection and initialization
|
||||||
|
pub mod icmp;
|
||||||
pub mod init;
|
pub mod init;
|
||||||
pub mod interrupt;
|
pub mod interrupt;
|
||||||
pub mod ipc; // Inter-process communication
|
pub mod ipc; // Inter-process communication
|
||||||
@@ -46,9 +49,6 @@ pub mod memory;
|
|||||||
pub mod module;
|
pub mod module;
|
||||||
pub mod module_loader; // Dynamic module loading
|
pub mod module_loader; // Dynamic module loading
|
||||||
pub mod network;
|
pub mod network;
|
||||||
pub mod arp;
|
|
||||||
pub mod icmp;
|
|
||||||
pub mod advanced_perf; // Advanced performance monitoring and profiling
|
|
||||||
pub mod panic;
|
pub mod panic;
|
||||||
pub mod perf; // Performance monitoring
|
pub mod perf; // Performance monitoring
|
||||||
pub mod prelude;
|
pub mod prelude;
|
||||||
@@ -87,6 +87,7 @@ pub extern "C" fn kernel_main() -> ! {
|
|||||||
|
|
||||||
// Now we can use allocations, continue with full initialization
|
// Now we can use allocations, continue with full initialization
|
||||||
init::early_init();
|
init::early_init();
|
||||||
|
|
||||||
init::main_init();
|
init::main_init();
|
||||||
|
|
||||||
// Should not return from main_init
|
// Should not return from main_init
|
||||||
@@ -116,24 +117,21 @@ fn early_kernel_init() {
|
|||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::println!("Rust Kernel v{} starting...", VERSION);
|
crate::console::write_str("\n");
|
||||||
crate::println!("Early kernel initialization");
|
crate::console::write_str("Booting Rust Kernel...\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize memory management using multiboot information
|
/// Initialize memory management using multiboot information
|
||||||
fn memory_init() -> Result<(), error::Error> {
|
fn memory_init() -> Result<(), error::Error> {
|
||||||
if let Some(multiboot_addr) = boot::get_boot_info().multiboot_addr {
|
crate::console::write_str("[*] Initializing memory subsystem...\n");
|
||||||
boot::multiboot::init_memory_from_multiboot(multiboot_addr)?;
|
|
||||||
} else {
|
// FIXME: Multiboot parsing causes crashes - use default memory layout for now
|
||||||
// Fallback: initialize with default memory layout
|
|
||||||
memory::page::init()?;
|
memory::page::init()?;
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize heap allocator
|
// Initialize heap allocator
|
||||||
memory::kmalloc::init()?;
|
memory::kmalloc::init()?;
|
||||||
memory::vmalloc::init()?;
|
|
||||||
|
|
||||||
info!("Memory management initialized");
|
crate::console::write_str("[+] Memory subsystem ready\n");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,27 +13,6 @@ use core::arch::global_asm;
|
|||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
global_asm!(include_str!("arch/x86_64/boot.s"), options(att_syntax));
|
global_asm!(include_str!("arch/x86_64/boot.s"), options(att_syntax));
|
||||||
|
|
||||||
use core::panic::PanicInfo;
|
|
||||||
|
|
||||||
/// Multiboot1 header - placed at the very beginning
|
|
||||||
#[repr(C)]
|
|
||||||
#[repr(packed)]
|
|
||||||
struct MultibootHeader {
|
|
||||||
magic: u32,
|
|
||||||
flags: u32,
|
|
||||||
checksum: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Multiboot header must be in the first 8KB and be 4-byte aligned
|
|
||||||
// #[link_section = ".multiboot_header"]
|
|
||||||
// #[no_mangle]
|
|
||||||
// #[used]
|
|
||||||
// static MULTIBOOT_HEADER: MultibootHeader = MultibootHeader {
|
|
||||||
// magic: 0x1BADB002,
|
|
||||||
// flags: 0x00000000,
|
|
||||||
// checksum: 0u32.wrapping_sub(0x1BADB002u32.wrapping_add(0x00000000)),
|
|
||||||
// };
|
|
||||||
|
|
||||||
/// Entry point called by boot.s assembly code
|
/// Entry point called by boot.s assembly code
|
||||||
/// This is just a wrapper to ensure the kernel crate is linked
|
/// This is just a wrapper to ensure the kernel crate is linked
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -48,8 +27,3 @@ pub extern "C" fn rust_main() -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Panic handler is defined in the kernel library
|
// Panic handler is defined in the kernel library
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn _start() -> ! {
|
|
||||||
loop {}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -15,11 +15,10 @@ const KMALLOC_SIZES: &[usize] = &[8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096
|
|||||||
const MAX_KMALLOC_SIZE: usize = 4096;
|
const MAX_KMALLOC_SIZE: usize = 4096;
|
||||||
|
|
||||||
/// Slab allocator for small kernel allocations
|
/// Slab allocator for small kernel allocations
|
||||||
/// Uses indices instead of raw pointers for thread safety
|
/// Uses physical addresses directly - they're identity-mapped in the first 1GB
|
||||||
struct SlabAllocator {
|
struct SlabAllocator {
|
||||||
size_classes: BTreeMap<usize, Vec<usize>>, // Store offsets instead of pointers
|
size_classes: BTreeMap<usize, Vec<usize>>, // Store physical addresses
|
||||||
allocated_blocks: BTreeMap<usize, usize>, // Maps offsets to size classes
|
allocated_blocks: BTreeMap<usize, usize>, // Maps physical addresses to size classes
|
||||||
base_addr: usize, // Base address for calculations
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SlabAllocator {
|
impl SlabAllocator {
|
||||||
@@ -27,14 +26,9 @@ impl SlabAllocator {
|
|||||||
Self {
|
Self {
|
||||||
size_classes: BTreeMap::new(),
|
size_classes: BTreeMap::new(),
|
||||||
allocated_blocks: BTreeMap::new(),
|
allocated_blocks: BTreeMap::new(),
|
||||||
base_addr: 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(&mut self, base_addr: usize) {
|
|
||||||
self.base_addr = base_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn allocate(&mut self, size: usize) -> Result<*mut u8> {
|
fn allocate(&mut self, size: usize) -> Result<*mut u8> {
|
||||||
// Find appropriate size class
|
// Find appropriate size class
|
||||||
let size_class = KMALLOC_SIZES
|
let size_class = KMALLOC_SIZES
|
||||||
@@ -49,9 +43,9 @@ impl SlabAllocator {
|
|||||||
|
|
||||||
// Try to get from free list
|
// Try to get from free list
|
||||||
if let Some(free_list) = self.size_classes.get_mut(&size_class) {
|
if let Some(free_list) = self.size_classes.get_mut(&size_class) {
|
||||||
if let Some(offset) = free_list.pop() {
|
if let Some(addr) = free_list.pop() {
|
||||||
self.allocated_blocks.insert(offset, size_class);
|
self.allocated_blocks.insert(addr, size_class);
|
||||||
return Ok((self.base_addr + offset) as *mut u8);
|
return Ok(addr as *mut u8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,28 +57,27 @@ impl SlabAllocator {
|
|||||||
// Allocate a page using buddy allocator
|
// Allocate a page using buddy allocator
|
||||||
let pfn = alloc_pages(0, GfpFlags::KERNEL)?;
|
let pfn = alloc_pages(0, GfpFlags::KERNEL)?;
|
||||||
let page_addr = pfn.to_phys_addr().as_usize();
|
let page_addr = pfn.to_phys_addr().as_usize();
|
||||||
let offset = page_addr - self.base_addr;
|
|
||||||
|
|
||||||
// Split page into blocks of size_class
|
// Split page into blocks of size_class
|
||||||
let blocks_per_page = 4096 / size_class;
|
let blocks_per_page = 4096 / size_class;
|
||||||
let free_list = self.size_classes.entry(size_class).or_insert_with(Vec::new);
|
let free_list = self.size_classes.entry(size_class).or_insert_with(Vec::new);
|
||||||
|
|
||||||
for i in 1..blocks_per_page {
|
for i in 1..blocks_per_page {
|
||||||
let block_offset = offset + (i * size_class);
|
let block_addr = page_addr + (i * size_class);
|
||||||
free_list.push(block_offset);
|
free_list.push(block_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the first block
|
// Return the first block
|
||||||
self.allocated_blocks.insert(offset, size_class);
|
self.allocated_blocks.insert(page_addr, size_class);
|
||||||
Ok(page_addr as *mut u8)
|
Ok(page_addr as *mut u8)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deallocate(&mut self, ptr: *mut u8) -> Result<()> {
|
fn deallocate(&mut self, ptr: *mut u8) -> Result<()> {
|
||||||
let offset = (ptr as usize).saturating_sub(self.base_addr);
|
let addr = ptr as usize;
|
||||||
if let Some(size_class) = self.allocated_blocks.remove(&offset) {
|
if let Some(size_class) = self.allocated_blocks.remove(&addr) {
|
||||||
let free_list =
|
let free_list =
|
||||||
self.size_classes.entry(size_class).or_insert_with(Vec::new);
|
self.size_classes.entry(size_class).or_insert_with(Vec::new);
|
||||||
free_list.push(offset);
|
free_list.push(addr);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(Error::InvalidArgument)
|
Err(Error::InvalidArgument)
|
||||||
@@ -192,8 +185,6 @@ pub fn krealloc(ptr: *mut u8, old_size: usize, new_size: usize) -> Result<*mut u
|
|||||||
|
|
||||||
/// Initialize the slab allocator
|
/// Initialize the slab allocator
|
||||||
pub fn init() -> Result<()> {
|
pub fn init() -> Result<()> {
|
||||||
let mut allocator = SLAB_ALLOCATOR.lock();
|
// No initialization needed - we use physical addresses directly
|
||||||
// Use a reasonable base address for offset calculations
|
|
||||||
allocator.init(0x_4000_0000_0000);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,7 +115,21 @@ impl PageAllocator {
|
|||||||
|
|
||||||
/// Add a range of pages to the free list
|
/// Add a range of pages to the free list
|
||||||
pub fn add_free_range(&mut self, start: Pfn, count: usize) {
|
pub fn add_free_range(&mut self, start: Pfn, count: usize) {
|
||||||
for i in 0..count {
|
// Safety: Only add pages that are within the identity-mapped region (0-1GB)
|
||||||
|
// Boot assembly maps 0-1GB with 2MB pages
|
||||||
|
const MAX_IDENTITY_MAPPED_PFN: usize = (1024 * 1024 * 1024) / 4096; // 1GB / 4KB
|
||||||
|
|
||||||
|
let safe_count = if start.0 >= MAX_IDENTITY_MAPPED_PFN {
|
||||||
|
// Start is beyond identity mapping, skip entirely
|
||||||
|
return;
|
||||||
|
} else if start.0 + count > MAX_IDENTITY_MAPPED_PFN {
|
||||||
|
// Trim to stay within identity mapping
|
||||||
|
MAX_IDENTITY_MAPPED_PFN - start.0
|
||||||
|
} else {
|
||||||
|
count
|
||||||
|
};
|
||||||
|
|
||||||
|
for i in 0..safe_count {
|
||||||
let pfn = Pfn(start.0 + i);
|
let pfn = Pfn(start.0 + i);
|
||||||
let phys_addr = PhysAddr(pfn.0 * 4096);
|
let phys_addr = PhysAddr(pfn.0 * 4096);
|
||||||
|
|
||||||
@@ -129,8 +143,8 @@ impl PageAllocator {
|
|||||||
// Update head
|
// Update head
|
||||||
self.free_list_head = Some(phys_addr);
|
self.free_list_head = Some(phys_addr);
|
||||||
}
|
}
|
||||||
self.total_pages += count;
|
self.total_pages += safe_count;
|
||||||
self.free_count += count;
|
self.free_count += safe_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allocate a single page
|
/// Allocate a single page
|
||||||
@@ -173,15 +187,7 @@ impl PageAllocator {
|
|||||||
|
|
||||||
/// Initialize the page allocator
|
/// Initialize the page allocator
|
||||||
pub fn init() -> Result<()> {
|
pub fn init() -> Result<()> {
|
||||||
let mut allocator = PAGE_ALLOCATOR.lock();
|
// Page allocator stub - no actual pages initialized yet
|
||||||
|
|
||||||
// TODO: Get memory map from bootloader/firmware
|
|
||||||
// For now, add a dummy range
|
|
||||||
let start_pfn = Pfn(0x1000); // Start at 16MB
|
|
||||||
let count = 0x10000; // 256MB worth of pages
|
|
||||||
|
|
||||||
allocator.add_free_range(start_pfn, count);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,13 @@
|
|||||||
|
|
||||||
//! Network stack implementation
|
//! Network stack implementation
|
||||||
|
|
||||||
use alloc::{boxed::Box, collections::BTreeMap, collections::VecDeque, string::{String, ToString}, vec::Vec};
|
use alloc::{
|
||||||
|
boxed::Box,
|
||||||
|
collections::BTreeMap,
|
||||||
|
collections::VecDeque,
|
||||||
|
string::{String, ToString},
|
||||||
|
vec::Vec,
|
||||||
|
};
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
|
|
||||||
use crate::error::{Error, Result};
|
use crate::error::{Error, Result};
|
||||||
@@ -406,7 +412,8 @@ impl NetworkStack {
|
|||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// Clean up timed out ARP requests
|
// Clean up timed out ARP requests
|
||||||
let now = crate::time::get_time_ns();
|
let now = crate::time::get_time_ns();
|
||||||
self.pending_arp_requests.retain(|req| now - req.timestamp < 10_000_000_000); // 10 seconds
|
self.pending_arp_requests
|
||||||
|
.retain(|req| now - req.timestamp < 10_000_000_000); // 10 seconds
|
||||||
|
|
||||||
// Find route (borrow self immutably)
|
// Find route (borrow self immutably)
|
||||||
let route = {
|
let route = {
|
||||||
@@ -507,7 +514,9 @@ impl NetworkStack {
|
|||||||
// Now, process the received packets
|
// Now, process the received packets
|
||||||
for (interface_name, packet) in received_packets {
|
for (interface_name, packet) in received_packets {
|
||||||
if packet.protocol == ProtocolType::ARP {
|
if packet.protocol == ProtocolType::ARP {
|
||||||
if let Ok(arp_packet) = crate::arp::ArpPacket::from_bytes(packet.data()) {
|
if let Ok(arp_packet) =
|
||||||
|
crate::arp::ArpPacket::from_bytes(packet.data())
|
||||||
|
{
|
||||||
self.handle_arp_packet(&arp_packet, &interface_name)?;
|
self.handle_arp_packet(&arp_packet, &interface_name)?;
|
||||||
}
|
}
|
||||||
} else if packet.protocol == ProtocolType::ICMP {
|
} else if packet.protocol == ProtocolType::ICMP {
|
||||||
@@ -530,7 +539,11 @@ impl NetworkStack {
|
|||||||
self.interface_stats.get(name)
|
self.interface_stats.get(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_arp_packet(&mut self, packet: &crate::arp::ArpPacket, interface_name: &str) -> Result<()> {
|
fn handle_arp_packet(
|
||||||
|
&mut self,
|
||||||
|
packet: &crate::arp::ArpPacket,
|
||||||
|
interface_name: &str,
|
||||||
|
) -> Result<()> {
|
||||||
// Add the sender to the ARP table
|
// Add the sender to the ARP table
|
||||||
self.add_arp_entry(packet.spa, packet.sha);
|
self.add_arp_entry(packet.spa, packet.sha);
|
||||||
|
|
||||||
@@ -548,9 +561,14 @@ impl NetworkStack {
|
|||||||
);
|
);
|
||||||
let mut buffer = NetworkBuffer::new(28);
|
let mut buffer = NetworkBuffer::new(28);
|
||||||
buffer.set_protocol(ProtocolType::ARP);
|
buffer.set_protocol(ProtocolType::ARP);
|
||||||
buffer.set_mac_addresses(interface.mac_address(), packet.sha);
|
buffer.set_mac_addresses(
|
||||||
|
interface.mac_address(),
|
||||||
|
packet.sha,
|
||||||
|
);
|
||||||
buffer.extend_from_slice(&reply.to_bytes())?;
|
buffer.extend_from_slice(&reply.to_bytes())?;
|
||||||
if let Some(interface) = self.get_interface_mut(interface_name) {
|
if let Some(interface) =
|
||||||
|
self.get_interface_mut(interface_name)
|
||||||
|
{
|
||||||
interface.send_packet(&buffer)?;
|
interface.send_packet(&buffer)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -571,7 +589,11 @@ impl NetworkStack {
|
|||||||
self.pending_arp_requests = still_pending;
|
self.pending_arp_requests = still_pending;
|
||||||
|
|
||||||
for pending in packets_to_send {
|
for pending in packets_to_send {
|
||||||
self.send_packet(pending.ip, pending.packet.data(), pending.packet.protocol)?;
|
self.send_packet(
|
||||||
|
pending.ip,
|
||||||
|
pending.packet.data(),
|
||||||
|
pending.packet.protocol,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -293,15 +293,19 @@ impl KernelShell {
|
|||||||
let mut stack = crate::network::NETWORK_STACK.lock();
|
let mut stack = crate::network::NETWORK_STACK.lock();
|
||||||
if let Some(ref mut stack) = *stack {
|
if let Some(ref mut stack) = *stack {
|
||||||
for iface_name in stack.list_interfaces() {
|
for iface_name in stack.list_interfaces() {
|
||||||
if let Some(stats) = stack.get_interface_stats(&iface_name) {
|
if let Some(stats) =
|
||||||
|
stack.get_interface_stats(&iface_name)
|
||||||
|
{
|
||||||
info!(" {}:", iface_name);
|
info!(" {}:", iface_name);
|
||||||
info!(
|
info!(
|
||||||
" TX: {} packets, {} bytes",
|
" TX: {} packets, {} bytes",
|
||||||
stats.packets_sent, stats.bytes_sent
|
stats.packets_sent,
|
||||||
|
stats.bytes_sent
|
||||||
);
|
);
|
||||||
info!(
|
info!(
|
||||||
" RX: {} packets, {} bytes",
|
" RX: {} packets, {} bytes",
|
||||||
stats.packets_received, stats.bytes_received
|
stats.packets_received,
|
||||||
|
stats.bytes_received
|
||||||
);
|
);
|
||||||
info!(
|
info!(
|
||||||
" Errors: {}, Dropped: {}",
|
" Errors: {}, Dropped: {}",
|
||||||
@@ -346,7 +350,11 @@ impl KernelShell {
|
|||||||
icmp_packet.checksum = checksum;
|
icmp_packet.checksum = checksum;
|
||||||
data = icmp_packet.to_bytes();
|
data = icmp_packet.to_bytes();
|
||||||
|
|
||||||
if let Err(e) = crate::network::send_packet(dest_ip, &data, crate::network::ProtocolType::ICMP) {
|
if let Err(e) = crate::network::send_packet(
|
||||||
|
dest_ip,
|
||||||
|
&data,
|
||||||
|
crate::network::ProtocolType::ICMP,
|
||||||
|
) {
|
||||||
error!("Failed to send ping: {}", e);
|
error!("Failed to send ping: {}", e);
|
||||||
} else {
|
} else {
|
||||||
info!("Ping sent to {}", dest_ip);
|
info!("Ping sent to {}", dest_ip);
|
||||||
|
|||||||
Referencia en una nueva incidencia
Block a user