[bits 32]
KERNEL_BASE equ 0xC0000000
+%define MAX_CPUS 16
[extern __load_addr]
[extern __bss_start]
dd MULTIBOOT_HEADER_MAGIC
dd MULTIBOOT_HEADER_FLAGS
dd MULTIBOOT_CHECKSUM
- dd mboot - KERNEL_BASE ;Location of Multiboot Header
+ dd mboot; - KERNEL_BASE ;Location of Multiboot Header
; Multiboot 2 Header
;mboot2:
[extern kmain]
[global start]
start:
+ ; Just show we're here
+ mov WORD [0xB8000], 0x0741 ; 'A'
; Set up stack
mov esp, Kernel_Stack_Top
mov cr3, ecx
mov ecx, cr0
- or ecx, 0x80010000 ; PG and WP
+ or ecx, 0x80010000 ; PG and WP
mov cr0, ecx
+ mov WORD [0xB8002], 0x0763 ; 'c'
+ mov WORD [0xB8004], 0x0765 ; 'e'
+
lea ecx, [.higherHalf]
jmp ecx
.higherHalf:
+
+ mov WORD [0xB8006], 0x0773 ; 's'
+ mov WORD [0xB8008], 0x0773 ; 's'
; Call the kernel
push ebx ; Multiboot Info
push eax ; Multiboot Magic Value
+ mov WORD [0xB800A], 0x0732 ; '2'
call kmain
; Halt the Machine
jmp .hlt
;
-; Multiprocessing AP Startup Code (Must be within 0x10FFF0)
+; Multiprocessing AP Startup Code (Must be within 0 - 0x10FFF0)
;
%if USE_MP
[extern gGDT]
[extern gGDTPtr]
[extern gIDTPtr]
[extern gpMP_LocalAPIC]
+[extern giMP_TimerCount]
[extern gaAPIC_to_CPU]
[extern gaCPUs]
[extern giNumInitingCPUs]
+[extern MM_NewKStack]
+
lGDTPtr: ; Local GDT Pointer
- dw 2*8-1
+ dw 3*8-1
dd gGDT-KERNEL_BASE
[bits 16]
+[global APWait]
+APWait:
+ ;xchg bx, bx
+.hlt:
+ ;hlt
+ jmp .hlt
[global APStartup]
APStartup:
- xchg bx, bx ; MAGIC BREAK!
+ ;xchg bx, bx ; MAGIC BREAK!
+ ; Load initial GDT
mov ax, 0xFFFF
mov ds, ax
lgdt [DWORD ds:lGDTPtr-KERNEL_BASE-0xFFFF0]
+ ; Enable PMode in CR0
mov eax, cr0
- or al, 1
- mov cr0, eax
+ or al, 1
+ mov cr0, eax
+ ; Jump into PMode
jmp 08h:DWORD .ProtectedMode-KERNEL_BASE
[bits 32]
.ProtectedMode:
+ ; Load segment registers
+ mov ax, 0x10
+ mov ss, ax
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
; Start Paging
mov eax, gaInitPageDir - KERNEL_BASE
mov cr3, eax
mov eax, cr0
- or eax, 0x80010000 ; PG and WP
+ or eax, 0x80010000 ; PG and WP
mov cr0, eax
; Jump to higher half
lea eax, [.higherHalf]
lgdt [gGDTPtr]
lidt [gIDTPtr]
- mov eax, [gpMP_LocalAPIC]
- mov DWORD [eax], 0
- xor ecx, ecx
- mov cl, BYTE [eax+0x10]
+ mov ebp, [gpMP_LocalAPIC]
+ mov ebx, [ebp+0x20] ; Read ID
+ shr ebx, 24
+ ;xchg bx, bx ; MAGIC BREAK
; CL is now local APIC ID
- mov cl, BYTE [gaAPIC_to_CPU+ecx]
- ; CL is now the CPU ID
- mov BYTE [gaCPUs+ecx*8+1], 1
+ mov cl, BYTE [gaAPIC_to_CPU+ebx]
+ xor ebx, ebx
+ mov bl, cl
+ ; BL is now the CPU ID
+ mov BYTE [gaCPUs+ebx*8+1], 1
; Decrement the remaining CPU count
dec DWORD [giNumInitingCPUs]
+
+ ; Create a stack
+ lea edx, [ebx+1]
+ shl edx, 5+2 ; *32 *4
+ lea esp, [gInitAPStacks+edx]
+ call MM_NewKStack
+ mov esp, eax
+
+ ; Set TSS
+ lea ecx, [ebx*8+0x30]
+ ltr cx
+ ; Save the CPU number to a debug register
+ mov dr1, ebx
+
+ ;xchg bx, bx ; MAGIC_BREAK
+ ; Enable Local APIC
+ mov DWORD [ebp+0x0F0], 0x000001EF ; Spurious Interrupt Vector (0xEF)
+ mov ecx, DWORD [giMP_TimerCount]
+ mov DWORD [ebp+0x380], ecx ; Set Initial Count
+ mov DWORD [ebp+0x320], 0x000200EE ; Enable timer on IVT#0xEE
+ mov DWORD [ebp+0x330], 0x000100E0 ; ##Enable thermal sensor on IVT#0xE0
+ mov DWORD [ebp+0x340], 0x000100D0 ; ##Enable performance counters on IVT#0xD0
+ mov DWORD [ebp+0x350], 0x000100D1 ; ##Enable LINT0 on IVT#0xD1
+ mov DWORD [ebp+0x360], 0x000100D2 ; ##Enable LINT1 on IVT#0xD2
+ mov DWORD [ebp+0x370], 0x000100E1 ; ##Enable Error on IVT#0xE1
+ mov DWORD [ebp+0x0B0], 0 ; Send an EOI (just in case)
+
; CPU is now marked as initialised
sti
+ ;xchg bx, bx ; MAGIC BREAK
.hlt:
hlt
jmp .hlt
[section .initpd]
[global gaInitPageDir]
[global gaInitPageTable]
-align 0x1000
+align 4096
gaInitPageDir:
- dd gaInitPageTable-KERNEL_BASE+3 ; 0x00
- times 1024-256-1 dd 0
- dd gaInitPageTable-KERNEL_BASE+3 ; 0xC0
- times 256-1 dd 0
-align 0x1000
+ dd gaInitPageTable-KERNEL_BASE+3 ; 0x000 - Low kernel
+ times 0x300-0x000-1 dd 0
+ dd gaInitPageTable-KERNEL_BASE+3 ; 0xC00 - High kernel
+ times 0x3F0-0x300-1 dd 0
+ dd gaInitPageDir-KERNEL_BASE+3 ; 0xFC0 - Fractal
+ times 0x400-0x3F0-1 dd 0
+align 4096
gaInitPageTable:
%assign i 0
%rep 1024
%assign i i+1
%endrep
[global Kernel_Stack_Top]
-ALIGN 0x1000
+ALIGN 4096
times 1024 dd 0
Kernel_Stack_Top:
+gInitAPStacks:
+ times 32*MAX_CPUS dd 0