00001 ; ndk - [ start.asm ]
00002 ;
00003 ; The assembly language stub which defines its
00004 ; sections to the multiboot loader, and sets up
00005 ; the environment so that a transfer to the C
00006 ; source code can be made.
00007 ;
00008 ; Please see:
00009 ; /src/ndk.c
00010 ;
00011 ; (c)2002 dcipher / neuraldk
00012 ; www.neuraldk.org
00013
00014 section .text
00015 bits 32
00016
00017 ; multi boot header defines
00018 MBOOT_PAGE_ALIGN equ 1 << 0
00019 MBOOT_MEM_INFO equ 1 << 1
00020 MBOOT_AOUT_KLUDGE equ 1 << 16
00021
00022 MBOOT_MAGIC equ 0x1BADB002
00023 MBOOT_FLAGS equ MBOOT_PAGE_ALIGN | MBOOT_MEM_INFO | MBOOT_AOUT_KLUDGE
00024 CHECKSUM equ -(MBOOT_MAGIC + MBOOT_FLAGS)
00025
00026 STACK_SIZE equ 0x1000
00027
00028 ; defined in the linker script
00029 extern textEnd
00030 extern dataEnd
00031 extern bssEnd
00032 extern ndkStart
00033 extern mb_main
00034
00035 global start
00036 global _start
00037
00038 entry:
00039 jmp start
00040
00041 ; The Multiboot header
00042 align 4, db 0
00043 mBootHeader:
00044 dd MBOOT_MAGIC
00045 dd MBOOT_FLAGS
00046 dd CHECKSUM
00047 ; fields used if MBOOT_AOUT_KLUDGE is set in
00048 ; MBOOT_HEADER_FLAGS
00049 dd mBootHeader ; these are PHYSICAL addresses
00050 dd entry ; start of kernel .text (code) section
00051 dd dataEnd ; end of kernel .data section
00052 dd bssEnd ; end of kernel BSS
00053 dd entry ; kernel entry point (initial EIP)
00054
00055 start:
00056 _start:
00057 ; can't include this here... corrupts eax, ebx from multiboot
00058 ; mov edi, 0xB8000
00059 ; mov esi, string
00060 ; mov ah, 0x0F
00061 ; .displaying:
00062 ; lodsb
00063 ; stosw
00064 ; or al, al
00065 ; jnz .displaying
00066
00067 ; make sure we're going in the right direction!
00068 cld
00069
00070 ; copy the current real mode idt + bios info
00071 ; to a safe page (it's about to be overwritten)
00072 xor esi, esi
00073 mov edi, 0x00001000
00074 mov ecx, 0x1000
00075 rep movsb
00076
00077 ; clear the idt + gdt @ 0x0
00078 push eax
00079 xor eax, eax
00080 xor esi, esi
00081 mov ecx, 0x800 + 0x800
00082 rep stosb
00083 pop eax
00084
00085 ; setup a bare bones GDT
00086 mov esi, my_gdt
00087 mov edi, 0x0800
00088 mov ecx, 8 * 7
00089 rep movsb
00090
00091 lgdt [pGDT] ; load the GDT
00092 lidt [pIDT] ; load the IDT
00093 lldt [pLDT] ; load the LDT (0)
00094
00095 mov dx, 0x08 ; 0x08 - kernel data segment
00096 mov ds, dx
00097 mov es, dx
00098 mov fs, dx
00099 mov gs, dx
00100 mov dx, 0x18 ; 0x18 - kernel stack segment
00101 mov ss, dx
00102
00103 mov esp, (stack + STACK_SIZE)
00104
00105 ; push the multiboot info structure, and magic
00106 push ebx
00107 push eax
00108
00109 ; load cs with new selector
00110 jmp 0x10:new_gdt
00111
00112 new_gdt:
00113 ; time for some C!
00114
00115 ; enable the alignment check bit, for fun :)
00116 ; Personally, I think every single program should be
00117 ; properly aligned, but too many people don't know about
00118 ; the performance penalties! With this bit enabled, the
00119 ; processor will interrupt on any unaligned memory
00120 ; access (assuming eflags also contains the same bit)
00121 ; In time, I'll probably just contain a running count
00122 ; of unaligned access per task... just for show (it'll
00123 ; slow unaligned programs even more... but... tough!)
00124 mov eax, cr0
00125 or eax, 262144
00126 mov cr0, eax
00127
00128 call ndkStart
00129 ;call mb_main
00130 jmp short $
00131
00132 section .data
00133 string db "ndk is alive!", 0
00134
00135 pIDT dw 800h ; limit of 256 IDT slots
00136 dd 00000000h ; starting at 0
00137
00138 pGDT dw 800h ; 256 GDT slots
00139 dd 00000800h ; starting at 800h (after IDT)
00140
00141 pLDT dw 0 ; no LDT at this time, but must still load
00142 dd 0 ; with someone (else multitasking might fail)
00143
00144 my_gdt:
00145 ; Null descriptor
00146 ; base : 0x00000000
00147 ; limit: 0x00000000 ( 0.0 MB)
00148 dd 0
00149 dd 0
00150
00151 ; 0x08 descriptor - Kernel data segment
00152 ; base : 0x00000000
00153 ; limit: 0xfffff pages (4 GB)
00154 ; DPL : 0
00155 ; 32 bit, present, system, expand-up, writeable
00156 dd 0x0000ffff
00157 dd 0x00cf9200
00158
00159 ; 0x10 descriptor - Kernel code segment
00160 ; base : 0x00000000
00161 ; limit: 0xfffff (4 GB)
00162 ; DPL : 0
00163 ; 32 bit, present, system, non-conforming, readable
00164 dd 0x0000ffff
00165 dd 0x00cf9A00
00166
00167 ; 0x18 descriptor - Kernel stack segment
00168 ; base : 0x00000000
00169 ; limit: 0xfffff (4 GB)
00170 ; DPL : 0
00171 ; 32 bit, present, system, expand-up, writeable
00172 dd 0x0000ffff
00173 dd 0x00cf9200
00174 ;dd 0x00cb9200
00175
00176 ; ----
00177
00178 ; 0x20 descriptor - Task data segment
00179 ; base : 0x00000000
00180 ; limit: 0xfffff pages (4 GB)
00181 ; DPL : 3
00182 ; 32 bit, present, system, expand-up, writeable
00183 dd 0x0000ffff
00184 dd 0x00cff200
00185
00186 ; 0x28 descriptor - Task code segment
00187 ; base : 0x00000000
00188 ; limit: 0xfffff (4 GB)
00189 ; DPL : 3
00190 ; 32 bit, present, system, non-conforming, readable
00191 dd 0x0000ffff
00192 dd 0x00cffA00
00193
00194 ; 0x30 descriptor - Task stack segment
00195 ; base : 0x00000000
00196 ; limit: 0xfffff (4 GB)
00197 ; DPL : 3
00198 ; 32 bit, present, system, expand-up, writeable
00199 dd 0x0000ffff
00200 dd 0x00cff200
00201
00202 section .bss
00203 align 4, db 0
00204 common stack 0x4000
00205 resb 0x4000
00206