3 ; Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
6 ; This is free software. You are permitted to use,
7 ; redistribute, and modify it as specified in the file "COPYING".
9 ; A lot of this code is adapted from Kernel Toolkit 0.2
10 ; and Linux version 2.2.x, so the following copyrights apply:
12 ; Copyright (C) 1991, 1992 Linus Torvalds
13 ; modified by Drew Eckhardt
14 ; modified by Bruce Evans (bde)
15 ; adapted for Kernel Toolkit by Luigi Sgro
24 ; Redefine the data segment so we can access variables
25 ; declared in this file.
29 ; Use int 15h to find out size of extended memory in KB.
30 ; Extended memory is the memory above 1MB. So by
31 ; adding 1MB to this amount, we get the total amount
32 ; of system memory. We can only detect 64MB this way,
33 ; but that's OK for now.
36 ;add ax, 1024 ; 1024 KB == 1 MB
39 add ax, 1024 ; 1024 KB == 1 MB
40 mov [mem_size_kbytes], ax
41 mov [mem_size_eblocks], bx
43 ; Kill the floppy motor.
46 ; Block interrupts, since we can't meaningfully handle them yet
47 ; and we no longer need BIOS services.
50 ; Set up IDT and GDT registers
54 ; Initialize the interrupt controllers, and enable the
59 ; Switch to protected mode!
63 ; Jump to 32 bit code.
64 jmp dword KERNEL_CS:(SETUPSEG << 4) + setup_32
69 ; set up data segment registers
77 ; Create the stack for the initial kernel thread.
78 mov esp, KERN_STACK + 4096
80 ; Build Boot_Info struct on stack.
81 ; Note that we push the fields on in reverse order,
82 ; since the stack grows downwards.
84 mov ax, [(SETUPSEG<<4)+mem_size_kbytes]
86 mov bx, [(SETUPSEG<<4)+mem_size_eblocks]
92 shl eax, 9 ; Multiply the vmm size by 512 to get byte size
93 push ebx ; size of the VMM
95 push dword 8 ; bootInfoSize
97 ; Pass pointer to Boot_Info struct as argument to kernel
101 ; Push return address to make this look like a call
103 push dword (SETUPSEG<<4)+.returnAddr
106 ; Far jump into kernel
107 jmp KERNEL_CS:ENTRY_POINT
110 ; We shouldn't return here.
118 ; Kill the floppy motor.
119 ; This code was shamelessly stolen from Linux.
127 ; Initialize master and slave PIC!
129 out 0x20, al ; ICW1 to master
131 out 0xA0, al ; ICW1 to slave
134 out 0x21, al ; ICW2 to master
137 out 0xA1, al ; ICW2 to slave
140 out 0x21, al ; ICW3 to master
143 out 0xA1, al ; ICW3 to slave
146 out 0x21, al ; ICW4 to master
148 out 0xA1, al ; ICW4 to slave
150 mov al, 0xff ; mask all ints in slave
151 out 0xA1, al ; OCW1 to slave
153 mov al, 0xfb ; mask all ints but 2 in master
154 out 0x21, al ; OCW1 to master
158 ; Linux uses this code.
159 ; The idea is that some systems issue port I/O instructions
160 ; faster than the device hardware can deal with them.
165 ; Enable the A20 address line, so we can correctly address
177 ; ----------------------------------------------------------------------
179 ; ----------------------------------------------------------------------
181 mem_size_kbytes: dw 0
182 mem_size_eblocks: dw 0
184 ; ----------------------------------------------------------------------
185 ; The GDT. Creates flat 32-bit address space for the kernel
186 ; code, data, and stack. Note that this GDT is just used
187 ; to create an environment where we can start running 32 bit
188 ; code. The kernel will create and manage its own GDT.
189 ; ----------------------------------------------------------------------
191 ; GDT initialization stuff
192 NUM_GDT_ENTRIES equ 3 ; number of entries in GDT
193 GDT_ENTRY_SZ equ 8 ; size of a single GDT entry
197 ; Descriptor 0 is not used
203 ; Descriptor 1: kernel code segment
204 dw 0xFFFF ; bytes 0 and 1 of segment size
205 dw 0x0000 ; bytes 0 and 1 of segment base address
206 db 0x00 ; byte 2 of segment base address
207 db 0x9A ; present, DPL=0, non-system, code, non-conforming,
208 ; readable, not accessed
209 db 0xCF ; granularity=page, 32 bit code, upper nibble of size
210 db 0x00 ; byte 3 of segment base address
212 ; Descriptor 2: kernel data and stack segment
213 ; NOTE: what Intel calls an "expand-up" segment
214 ; actually means that the stack will grow DOWN,
215 ; towards lower memory. So, we can use this descriptor
216 ; for both data and stack references.
217 dw 0xFFFF ; bytes 0 and 1 of segment size
218 dw 0x0000 ; bytes 0 and 1 of segment base address
219 db 0x00 ; byte 2 of segment base address
220 db 0x92 ; present, DPL=0, non-system, data, expand-up,
221 ; writable, not accessed
222 db 0xCF ; granularity=page, big, upper nibble of size
223 db 0x00 ; byte 3 of segment base address
226 dw NUM_GDT_ENTRIES*GDT_ENTRY_SZ ; limit
227 dd (SETUPSEG<<4) + GDT ; base address