X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Fx86%2Fstart.asm;h=b6026de6b936ccbe97ba75dd6d8c53066b83ba91;hb=a20cfd571f504f5c7f2d29516442a12c200441d5;hp=d9a1e500ea6d8316cf28c38e6208023dc2bc122c;hpb=775bf8013abe9fe4ef3d4883ea2e43bba2a84da1;p=tpg%2Facess2.git diff --git a/Kernel/arch/x86/start.asm b/Kernel/arch/x86/start.asm index d9a1e500..b6026de6 100644 --- a/Kernel/arch/x86/start.asm +++ b/Kernel/arch/x86/start.asm @@ -1,216 +1,285 @@ -; AcessOS Microkernel Version -; Start.asm - -[bits 32] - -KERNEL_BASE equ 0xC0000000 - -[extern __load_addr] -[extern __bss_start] -[extern gKernelEnd] -[section .multiboot] -mboot: - ; Multiboot macros to make a few lines later more readable - MULTIBOOT_PAGE_ALIGN equ 1<<0 - MULTIBOOT_MEMORY_INFO equ 1<<1 - MULTIBOOT_HEADER_MAGIC equ 0x1BADB002 - MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO - MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) - - ; This is the GRUB Multiboot header. A boot signature - dd MULTIBOOT_HEADER_MAGIC - dd MULTIBOOT_HEADER_FLAGS - dd MULTIBOOT_CHECKSUM - dd mboot - KERNEL_BASE ;Location of Multiboot Header - -; Multiboot 2 Header -mboot2: - MULTIBOOT2_HEADER_MAGIC equ 0xE85250D6 - MULTIBOOT2_HEADER_ARCH equ 0 - MULTIBOOT2_HEADER_LENGTH equ (mboot2_end-mboot2) - MULTIBOOT2_CHECKSUM equ -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_HEADER_ARCH + MULTIBOOT2_HEADER_LENGTH) - - dd MULTIBOOT2_HEADER_MAGIC - dd MULTIBOOT2_HEADER_ARCH - dd MULTIBOOT2_HEADER_LENGTH - dd MULTIBOOT2_CHECKSUM - ; MBoot2 Address Header - dw 2, 0 - dd 8 + 16 - dd mboot2 ; Location of Multiboot Header - dd __load_addr - KERNEL_BASE ; Kernel Load base - dd __bss_start - KERNEL_BASE ; Kernel Data End - dd gKernelEnd - KERNEL_BASE ; Kernel BSS End - ; MBoot2 Entry Point Tag - dw 3, 0 - dd 8 + 4 - dd start - KERNEL_BASE - ; MBoot2 Module Alignment Tag - dw 6, 0 - dd 12 ; ??? - dd 0 ; Search me, seems it wants padding - ; Terminator - dw 0, 0 - dd 8 -mboot2_end: - -[section .text] -[extern kmain] -[global start] -start: - ; Set up stack - mov esp, Kernel_Stack_Top - - ; Start Paging - mov ecx, gaInitPageDir - KERNEL_BASE - mov cr3, ecx - - mov ecx, cr0 - or ecx, 0x80010000 ; PG and WP - mov cr0, ecx - - lea ecx, [.higherHalf] - jmp ecx -.higherHalf: - - ; Call the kernel - push ebx ; Multiboot Info - push eax ; Multiboot Magic Value +; AcessOS Microkernel Version +; Start.asm + +[bits 32] + +KERNEL_BASE equ 0xC0000000 +%define MAX_CPUS 16 + +[extern __load_addr] +[extern __bss_start] +[extern gKernelEnd] +[section .multiboot] +mboot: + ; Multiboot macros to make a few lines later more readable + MULTIBOOT_PAGE_ALIGN equ 1<<0 + MULTIBOOT_MEMORY_INFO equ 1<<1 + MULTIBOOT_HEADER_MAGIC equ 0x1BADB002 + MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO + MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) + + ; This is the GRUB Multiboot header. A boot signature + dd MULTIBOOT_HEADER_MAGIC + dd MULTIBOOT_HEADER_FLAGS + dd MULTIBOOT_CHECKSUM + dd mboot; - KERNEL_BASE ;Location of Multiboot Header + +; Multiboot 2 Header +;mboot2: +; MULTIBOOT2_HEADER_MAGIC equ 0xE85250D6 +; MULTIBOOT2_HEADER_ARCH equ 0 +; MULTIBOOT2_HEADER_LENGTH equ (mboot2_end-mboot2) +; MULTIBOOT2_CHECKSUM equ -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_HEADER_ARCH + MULTIBOOT2_HEADER_LENGTH) +; +; dd MULTIBOOT2_HEADER_MAGIC +; dd MULTIBOOT2_HEADER_ARCH +; dd MULTIBOOT2_HEADER_LENGTH +; dd MULTIBOOT2_CHECKSUM +; ; MBoot2 Address Header +; dw 2, 0 +; dd 8 + 16 +; dd mboot2 ; Location of Multiboot Header +; dd __load_addr - KERNEL_BASE ; Kernel Load base +; dd __bss_start - KERNEL_BASE ; Kernel Data End +; dd gKernelEnd - KERNEL_BASE ; Kernel BSS End +; ; MBoot2 Entry Point Tag +; dw 3, 0 +; dd 8 + 4 +; dd start - KERNEL_BASE +; ; MBoot2 Module Alignment Tag +; dw 6, 0 +; dd 12 ; ??? +; dd 0 ; Search me, seems it wants padding +; ; Terminator +; dw 0, 0 +; dd 8 +;mboot2_end: + +[section .text] +[extern kmain] +[global start] +start: + ; Just show we're here + mov WORD [0xB8000], 0x0741 ; 'A' + + ; Set up stack + mov esp, Kernel_Stack_Top + + ; Start Paging + mov ecx, gaInitPageDir - KERNEL_BASE + mov cr3, ecx + mov ecx, cr0 + or ecx, 0x80010000 ; PG and WP + mov cr0, ecx + + mov WORD [0xB8002], 0x0763 ; 'c' + + ; Set GDT + lgdt [gGDTPtr] + mov cx, 0x10 ; PL0 Data + mov ss, cx + mov ds, cx + mov es, cx + mov gs, cx + mov fs, cx + mov WORD [0xB8004], 0x0765 ; 'e' + jmp 0x08:.higher_half +.higher_half: + + 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 - cli -.hlt: - hlt - jmp .hlt - -; -; Multiprocessing AP Startup Code (Must be within 0x10FFF0) -; -%if USE_MP -[extern gGDT] -[extern gGDTPtr] -[extern gIDTPtr] -[extern gpMP_LocalAPIC] -[extern gaAPIC_to_CPU] -[extern gaCPUs] -[extern giNumInitingCPUs] -lGDTPtr: ; Local GDT Pointer - dw 2*8-1 - dd gGDT-KERNEL_BASE - -[bits 16] -[global APStartup] -APStartup: - xchg bx, bx ; MAGIC BREAK! - mov ax, 0xFFFF - mov ds, ax - lgdt [DWORD ds:lGDTPtr-KERNEL_BASE-0xFFFF0] - mov eax, cr0 - or al, 1 - mov cr0, eax - jmp 08h:DWORD .ProtectedMode-KERNEL_BASE -[bits 32] -.ProtectedMode: - ; Start Paging - mov eax, gaInitPageDir - KERNEL_BASE - mov cr3, eax - mov eax, cr0 - or eax, 0x80010000 ; PG and WP - mov cr0, eax - ; Jump to higher half - lea eax, [.higherHalf] - jmp eax -.higherHalf: - ; Load True GDT & IDT - lgdt [gGDTPtr] - lidt [gIDTPtr] - - mov eax, [gpMP_LocalAPIC] - mov DWORD [eax], 0 - xor ecx, ecx - mov cl, BYTE [eax+0x10] - ; 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 - ; Decrement the remaining CPU count - dec DWORD [giNumInitingCPUs] - ; CPU is now marked as initialised - sti -.hlt: - hlt - jmp .hlt -%endif - -[global GetEIP] -GetEIP: - mov eax, [esp] - ret - -; int CallWithArgArray(void *Ptr, int NArgs, Uint *Args) -; Call a function passing the array as arguments -[global CallWithArgArray] -CallWithArgArray: - push ebp - mov ebp, esp - mov ecx, [ebp+12] ; Get NArgs - mov edx, [ebp+16] - -.top: - mov eax, [edx+ecx*4-4] - push eax - loop .top - - mov eax, [ebp+8] - call eax - lea esp, [ebp] - pop ebp - ret - -[extern Proc_Clone] -[extern Threads_Exit] -[global SpawnTask] -SpawnTask: - ; Call Proc_Clone with Flags=0 - xor eax, eax + ; Halt the Machine + cli +.hlt: + hlt + jmp .hlt + +; +; Multiprocessing AP Startup Code (Must be within 0 - 0x10FFF0) +; +%if USE_MP +[extern gIDTPtr] +[extern gpMP_LocalAPIC] +[extern giMP_TimerCount] +[extern gaAPIC_to_CPU] +[extern gaCPUs] +[extern giNumInitingCPUs] +[extern MM_NewKStack] +[extern Proc_InitialiseSSE] + +lGDTPtr: ; Local GDT Pointer + dw 3*8-1 + dd gGDT-KERNEL_BASE + +[bits 16] +[global APWait] +APWait: + ;xchg bx, bx +.hlt: + ;hlt + jmp .hlt +[extern Proc_Reschedule] +[global APStartup] +APStartup: + ;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 + ; 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 + mov cr0, eax + ; Jump to higher half + lea eax, [.higherHalf] + jmp eax +.higherHalf: + ; Load True GDT & IDT + lgdt [gGDTPtr] + lidt [gIDTPtr] + + mov ebp, [gpMP_LocalAPIC] + mov ebx, [ebp+0x20] ; Read ID + shr ebx, 24 + ;xchg bx, bx ; MAGIC BREAK + ; BL is now local APIC ID + mov cl, BYTE [gaAPIC_to_CPU+ebx] + xor ebx, ebx + mov bl, cl + ; BL is now the CPU ID + mov dr1, ebx ; Save the CPU number to a debug register + ; Mark the CPU as up + 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 + + ;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) + + ; Initialise SSE support + call Proc_InitialiseSSE + + ; CPU is now marked as initialised + +.hlt: + sti + call Proc_Reschedule + hlt + jmp .hlt +%endif + +[global GetEIP] +GetEIP: + mov eax, [esp] + ret + +; int CallWithArgArray(void *Ptr, int NArgs, Uint *Args) +; Call a function passing the array as arguments +[global CallWithArgArray] +CallWithArgArray: + push ebp + mov ebp, esp + mov ecx, [ebp+12] ; Get NArgs + mov edx, [ebp+16] + +.top: + mov eax, [edx+ecx*4-4] push eax - push eax - call Proc_Clone - add esp, 8 ; Remove arguments from stack - - test eax, eax - jnz .parent - - ; In child, so now set up stack frame - mov ebx, [esp+4] ; Child Function - mov edx, [esp+8] ; Argument - ; Child - push edx ; Argument - call ebx ; Function - call Threads_Exit ; Kill Thread - -.parent: - ret - -[section .initpd] -[global gaInitPageDir] -[global gaInitPageTable] -align 0x1000 -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 -gaInitPageTable: - %assign i 0 - %rep 1024 - dd i*0x1000+3 - %assign i i+1 - %endrep -[global Kernel_Stack_Top] -ALIGN 0x1000 - times 1024 dd 0 -Kernel_Stack_Top: + loop .top + mov eax, [ebp+8] + call eax + lea esp, [ebp] + pop ebp + ret + +[section .data] +; GDT +GDT_SIZE equ (1+2*2+1+MAX_CPUS)*8 +[global gGDT] +gGDT: + ; PL0 - Kernel + ; PL3 - User + dd 0x00000000, 0x00000000 ; 00 NULL Entry + dd 0x0000FFFF, 0x00CF9A00 ; 08 PL0 Code + dd 0x0000FFFF, 0x00CF9200 ; 10 PL0 Data + dd 0x0000FFFF, 0x00CFFA00 ; 18 PL3 Code + dd 0x0000FFFF, 0x00CFF200 ; 20 PL3 Data + dd 26*4-1, 0x00408900 ; 28 Double Fault TSS + times MAX_CPUS dd 26*4-1, 0x00408900 ; 30+ TSSes +[global gGDTPtr] +gGDTPtr: + dw GDT_SIZE-1 + dd gGDT + +[section .initpd] +[global gaInitPageDir] +[global gaInitPageTable] +align 4096 +gaInitPageDir: + 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 + dd i*0x1000+3 + %assign i i+1 + %endrep +[global Kernel_Stack_Top] +ALIGN 4096 + times 1024 dd 0 +Kernel_Stack_Top: +gInitAPStacks: + times 32*MAX_CPUS dd 0 + +; vim: ft=nasm ts=8