;kernel.asm ;Author: Josh Holtrop ;Date: 10/30/03 ;Modified: 10/30/03 %define GDT_P 0x100000; ;1mb physical - Global Descriptor Table space %define GDT_V GDT_P+0xC0000000 %define IDT_P 0x102000 ;1mb+8kb - Interrupt Descriptor Table space %define IDT_V IDT_P+0xC0000000 %define PDBR_P 0x104000 ;1mb+16kb - Page Directory Base Register (first PD) %define PDBR_V PDBR_P+0xC0000000 %define LOPT_P 0x105000 ;1mb+20kb - LOw Page Table for mapping first 4mb %define LOPT_V LOPT_P+0xC0000000 %define KERNEL_P 0x106000 ;1mb+24kb - the kernel's physical address %define KERNEL_V KERNEL_P+0xC0000000 ;3gb+1mb+24kb, the virtual address of the kernel [global _start] [extern _isr] [extern _k_init] [extern _putc] bits 32 ;This is where the kernel begins execution ;At this point, the temporary gdt is set up to "map" 0xC000_0000 to 0x0. ;We must enable paging with the first 4mb mapped 1:1 virtual:physical ; and with the 4mb starting at 0xC000_0000 mapped to the first 4mb physical. ;Then we can start using our "real" gdt, then unmap the lower 4mb. _start: cli ;if they weren't already off xor eax, eax mov edi, PDBR_V mov ecx, 1024 ;clear the PDBR rep stosd mov [PDBR_V], dword LOPT_P|0x03 ;store the physical address of the LOw Page Table (read/write, present) mov [PDBR_V+0xC00], dword LOPT_P|0x03 ;store the physical address of the LOw Page Table (read/write, present) mov edi, LOPT_V mov ecx, 1024 mov eax, 0x03 ;starting physical address = 0x0 (read/write, present flags) fill_lopt_loop: ;fill the page table stosd add eax, 4096 ;increment next phsyical address by 4kb loop fill_lopt_loop mov eax, PDBR_P mov cr3, eax ;store the Page Directory Base Address mov eax, cr0 or eax, 0x80000000 ;set page enable bit mov cr0, eax ;now paging is active! mov edi, GDT_V mov esi, gdt mov ecx, gdt_end-gdt copy_gdt: lodsb stosb loop copy_gdt mov edi, IDT_V ;destination mov esi, isr_0 ;address of isr0 mov edx, isr_1-isr_0 ;distance between isr labels mov ecx, 50 ;number of isrlabels fill_idt: mov ebx, esi mov ax, si stosw ;0 offset 15:0 mov ax, KERNEL_CODE stosw ;2 selector 15:0 mov ax, 0x8E00 stosw ;4 [P][DPL][0][TYPE][0][0][0][0][0][0][0][0] shr esi, 16 mov ax, si stosw ;6 offset 31:16 mov esi, ebx add esi, edx loop fill_idt mov word [IDT_V+0x30*8+4], 0xEE00 ;interrupt 0x30 has user priviledges lgdt [gdtr] ;load gdt jmp KERNEL_CODE:newgdtcontinue newgdtcontinue: mov ax, KERNEL_DATA mov es, ax mov ds, ax mov gs, ax mov fs, ax mov ss, ax mov esp, 0xc0200000 ;stack just under 3gb+2mb, moves downward lidt [idtr] ;load idt call _k_init haltit: hlt ;halt processor when k_init is done jmp haltit ;shouldn't get here... %include "gdt.inc" %include "idt.inc"