Here is the first file I link with every other kernel object files (start.s):
Code: Select all
[BITS 32]
%define ADDRADJUST 0xBFF00000
; // Kernel virtual start address //
%define K_VIR_START 0xC0000000
; // Kernel physiscal start address //
%define K_PHYS_START 0x100000
; // Addressing macros //
%define SEGMENT(linear) ((linear & 0xFFFF0000) >> 4)
%define OFFSET(linear) (linear & 0xFFFF)
; // Paging constants //
%define P_PRESENT 0x01
%define P_WRITE 0x02
%define P_USER 0x04
%define PAGE_SIZE 0x1000
%define K_PDE 0x1000 ; // Page directory //
%define K_PTE 0x2000 ; // Kernel page table #0 (4MB) //
%define I_PTE 0x3000 ; // First 4MB Identity-map page table //
%macro memset 3
; // void memset(void *dest_ptr, int val, dword count); //
mov edi, %1
mov eax, %2
mov ecx, %3
cld
o32 a32 rep stosb
%endmacro
%macro memcpy 3
; // void memcpy(void *dest_ptr, void *org_ptr, dword count); //
mov edi, %1
mov esi, %2
mov ecx, %3
cld
o32 a32 rep movsb
%endmacro
; // Global variables //
GLOBAL _start
[EXTERN k_main]
[EXTERN K_STACK_END]
_start:
jmp entry
; // Here is the Multiboot Header (...required by GRUB!) //
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
CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
ALIGN 4
dd MULTIBOOT_HEADER_MAGIC
dd MULTIBOOT_HEADER_FLAGS
dd CHECKSUM
entry:
; // Turn off floppy motor //
mov dx, 0x03F2
mov al, 0x0C
out dx, al
; // Setup paging //
memset K_PDE, 0, PAGE_SIZE
; // Setup first 4MB as identity-map (I_PTE) //
mov eax, (P_PRESENT | P_WRITE)
mov ecx, 1024
mov edi, I_PTE
cld
Map_I_PTE:
stosd
add eax, PAGE_SIZE
loop Map_I_PTE
; // Setup the kernel page table (K_PTE) //
mov eax, (K_PHYS_START | P_PRESENT | P_WRITE)
mov ecx, 1024
mov edi, K_PTE
Map_K_PTE:
stosd
add eax, PAGE_SIZE
loop Map_K_PTE
; // Store the identity-map table (first 4MB) //
mov dword [K_PDE], I_PTE | P_PRESENT | P_WRITE | P_USER
; // Store the kernel table (4MB of kernel virtual space) //
mov dword [K_PDE+(K_VIR_START/(PAGE_SIZE*1024))*4], K_PTE | P_PRESENT | P_WRITE | P_USER
; // Map page directory into itself //
mov dword [K_PDE+1023*4], K_PDE | P_PRESENT | P_WRITE | P_USER
; // Setup PDBR //
mov eax, K_PDE
mov cr3, eax
; // Enable paging //
mov eax, cr0
or eax, 0x80010000 ; CR0.PG = CR0.WP = 1
mov cr0, eax
o32 a32 lgdt [gdtr]
jmp FLAT_CODE_SEL:paging_enabled
paging_enabled:
; // Update segment registers //
mov eax, FLAT_DATA_SEL
mov ds, eax
mov es, eax
mov ss, eax
nop
mov fs, eax
mov gs, eax
; // Print a yellow smile on the screen //
mov word [0xB8000], 0x0E02
; // Initialize kernel stack pointer //
mov esp, K_STACK_END
; // Jump to the kernel main //
jmp k_main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Global Descriptor Table ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
gdtr:
dw (gdt_end - gdt - 1) ; GDT limit
dd gdt-ADDRADJUST ; GDT linear address
gdt:
; Dummy descriptor ; 0x00
dw 0 ; Limit 15:0
dw 0 ; Base 15:0
db 0 ; Base 23:16
db 0 ; Access byte (descriptor type)
db 0 ; Limits 19:16, Flags
db 0 ; Base 31:24
; Data descriptor
FLAT_DATA_SEL equ $-gdt ; 0x08
dw 0xFFFF ; Limit 15:0
dw 0 ; Base 15:0
db 0 ; Base 23:16
db 0x92 ; Data, Present, Writeable (1,0,0,1,0010)
db 0xCF ; G=1, D=1, 0, AVL=0, 1111=F: Limit/Length (1,1,0,0,1111)
db 0 ; Base 31:24
; Code descriptor
FLAT_CODE_SEL equ $-gdt ; 0x10
dw 0xFFFF ; Limit 15:0
dw 0 ; Base 15:0
db 0 ; Base 23:16
db 0x9A ; Code, Present, Non-conforming, Exec/read (1,0,0,1,1110)
db 0xCF ; G=1, D=1, 0, AVL=0, 1111=F: Limit/Length (1,1,0,0,1111)
db 0 ; Base 31:24
gdt_end: