Skip to content

Commit debd8b8

Browse files
committed
kernel: fix heap addresses in docs, clean up APIC and IDT code
- Fix heap address references to use HHDM offset (0xFFFF_8000_4444_0000) in copilot-instructions.md and MEMORY_LAYOUT.md - Document I/O APIC redirection entry format in ioapic::map_irq - Remove unused ioapic::set_base call from apic::set_bases - Remove hardcoded keyboard handler from IDT (now registered by kernel)
1 parent c43a263 commit debd8b8

File tree

5 files changed

+28
-42
lines changed

5 files changed

+28
-42
lines changed

.github/copilot-instructions.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Serix is a **microkernel-style x86_64 OS** written in Rust with these key archit
4444
- **Workspace-based cargo project**: Kernel and subsystems are separate crates (`kernel/`, `memory/`, `hal/`, `apic/`, `idt/`, `graphics/`, `task/`, `capability/`, `drivers/`, `vfs/`, `ipc/`, `loader/`, `ulib/`)
4545
- **Limine bootloader**: Uses Limine v10.x boot protocol (not GRUB). Limine sets up initial paging, framebuffer, and memory map before jumping to kernel
4646
- **Physical memory mapping**: All physical RAM is mapped at virtual offset `0xFFFF_8000_0000_0000` (HHDM - Higher Half Direct Map)
47-
- **Heap location**: Kernel heap lives at `0x4444_4444_0000` (1 MB by default, configured in `memory/src/heap.rs`)
47+
- **Heap location**: Kernel heap lives at `0xFFFF_8000_4444_0000` (1 MB by default, configured in `memory/src/heap.rs`)
4848

4949
### Boot Flow
5050

@@ -68,7 +68,7 @@ The kernel entry point (`_start`) executes this initialization sequence:
6868
### Memory Layout
6969

7070
- **Physical memory offset (HHDM)**: `0xFFFF_8000_0000_0000`
71-
- **Kernel heap**: `0x4444_4444_0000` - `0x4444_4454_0000` (1 MB)
71+
- **Kernel heap**: `0xFFFF_8000_4444_0000` - `0xFFFF_8000_4454_0000` (1 MB)
7272
- **Kernel code**: High virtual addresses (loaded by Limine at `-2GB` from top typically)
7373

7474
To convert physical to virtual: `virt = phys + HHDM_offset`

apic/src/ioapic.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,24 @@ unsafe fn ioapic_write(reg: u32, value: u32) {
4848
* @irq: IRQ line number
4949
* @vector: Interrupt vector to map to
5050
*
51-
* Routes the specified IRQ to the given interrupt vector.
51+
* Routes the specified IRQ to the given interrupt vector and unmasks it.
52+
* I/O APIC Redirection Entry format (lower 32 bits):
53+
* - Bits 0-7: Vector
54+
* - Bits 8-10: Delivery Mode (000 = Fixed)
55+
* - Bit 11: Destination Mode (0 = Physical)
56+
* - Bit 12: Delivery Status (read-only)
57+
* - Bit 13: Polarity (0 = Active High)
58+
* - Bit 14: Remote IRR (read-only)
59+
* - Bit 15: Trigger Mode (0 = Edge)
60+
* - Bit 16: Mask (0 = Enabled, 1 = Disabled)
61+
* - Bits 17-31: Reserved
5262
*/
5363
pub unsafe fn map_irq(irq: u8, vector: u8) {
5464
let reg = 0x10 + (irq as u32 * 2);
55-
ioapic_write(reg, vector as u32);
65+
/* Set vector and enable (mask bit = 0) */
66+
let low = vector as u32; // Bits 0-7 = vector, bit 16 = 0 (enabled)
67+
ioapic_write(reg, low);
68+
/* Upper 32 bits: destination (0 = BSP/CPU 0) */
5669
ioapic_write(reg + 1, 0);
5770
}
5871

apic/src/lib.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,9 @@ static APIC_BASE: AtomicU64 = AtomicU64::new(0xFEE00000);
2323
/*
2424
* set_bases - Update the base addresses for APIC components
2525
* @lapic: Virtual address of Local APIC
26-
* @ioapic: Virtual address of I/O APIC
2726
*/
2827
pub fn set_bases(lapic: u64) {
2928
APIC_BASE.store(lapic, Ordering::Relaxed);
30-
// I/O APIC base is managed in ioapic.rs, we'll add a setter there
31-
ioapic::set_base(0xFEC00000); // Default or pass as arg if needed
3229
}
3330

3431
fn lapic_reg(offset: u32) -> *mut u32 {

docs/MEMORY_LAYOUT.md

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,16 @@ Canonical Form:
7979
│ │
8080
│ Unused Virtual Space │
8181
│ │
82-
├─────────────────────────────────────┤
83-
Memory-Mapped I/O (Future)
84-
(GPU framebuffers, PCIe BARs)
85-
├─────────────────────────────────────┤
82+
0xFFFF_8000_4454_0000 ├─────────────────────────────────────┤
83+
Kernel Heap
84+
Size: 1 MB (configurable)
85+
0xFFFF_8000_4444_0000 ├─────────────────────────────────────┤
8686
│ │
8787
│ Unused Virtual Space │
8888
│ │
89-
0x4444_4454_0000 ├─────────────────────────────────────┤
90-
│ Kernel Heap │
91-
│ Size: 1 MB (configurable) │
92-
0x4444_4444_0000 ├─────────────────────────────────────┤
89+
├─────────────────────────────────────┤
90+
│ Memory-Mapped I/O (Future) │
91+
│ (GPU framebuffers, PCIe BARs) │
9392
│ │
9493
│ Unused Virtual Space │
9594
│ │
@@ -144,7 +143,7 @@ Physical 0x0000_0001_0000_0000 (4 GB)
144143
- Consumes virtual address space equal to physical RAM
145144
- Not suitable for >64 TB systems (exceeds 47-bit canonical limit)
146145

147-
#### Kernel Heap (0x4444_4444_0000 - 0x4444_4454_0000)
146+
#### Kernel Heap (0xFFFF_8000_4444_0000 - 0xFFFF_8000_4454_0000)
148147

149148
**Purpose**: Dynamic memory allocation for kernel data structures.
150149

@@ -551,7 +550,7 @@ SECTIONS {
551550

552551
### Heap Region
553552

554-
**Virtual Range**: `0x4444_4444_0000` - `0x4444_4454_0000` (1 MB)
553+
**Virtual Range**: `0xFFFF_8000_4444_0000` - `0xFFFF_8000_4454_0000` (1 MB)
555554

556555
**Physical Backing**: Allocated on demand from frame allocator during `init_heap()`.
557556

@@ -753,7 +752,7 @@ let mut frame_alloc = StaticBootFrameAllocator::new(frame_count);
753752
#### Step 5: Initialize Heap
754753

755754
```rust
756-
const HEAP_START: usize = 0x4444_4444_0000;
755+
const HEAP_START: usize = 0xFFFF_8000_4444_0000;
757756
const HEAP_SIZE: usize = 1024 * 1024; // 1 MB
758757

759758
init_heap(&mut mapper, &mut frame_alloc);

idt/src/lib.rs

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -35,37 +35,14 @@ lazy_static! {
3535
idt.divide_error.set_handler_fn(divide_by_zero_handler);
3636
idt.page_fault.set_handler_fn(page_fault_handler);
3737
idt.double_fault.set_handler_fn(double_fault_handler);
38-
idt[33].set_handler_fn(keyboard_interrupt_handler);
38+
/* Keyboard handler (IRQ 1, vector 33) is registered by kernel module */
3939
IdtWrapper {
4040
idt: UnsafeCell::new(idt),
4141
loaded: UnsafeCell::new(false),
4242
}
4343
};
4444
}
4545

46-
/*
47-
* keyboard_interrupt_handler - Handle keyboard interrupts
48-
* @_stack_frame: Interrupt stack frame (unused)
49-
*
50-
* Reads scancode from keyboard controller and sends EOI to APIC.
51-
*/
52-
extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStackFrame) {
53-
use x86_64::instructions::port::Port;
54-
55-
/* Read scancode from keyboard data port */
56-
let mut port = Port::new(0x60);
57-
let scancode: u8 = unsafe { port.read() };
58-
59-
/* Process the scancode */
60-
keyboard::handle_scancode(scancode);
61-
62-
/* Send End of Interrupt to Local APIC */
63-
unsafe {
64-
const APIC_EOI: *mut u32 = 0xFEE000B0 as *mut u32;
65-
APIC_EOI.write_volatile(0);
66-
}
67-
}
68-
6946
/*
7047
* divide_by_zero_handler - Handle division by zero exception
7148
* @_stack: Interrupt stack frame (unused)

0 commit comments

Comments
 (0)