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 guest size by 512 to get byte size
93 push eax ; Size of the guest kernel
96 push eax ; Load address of the guest
99 shl eax, 9 ; Multiply the vmm size by 512 to get byte size
100 push eax ; size of the VMM
102 push dword 8 ; bootInfoSize
104 ; Pass pointer to Boot_Info struct as argument to kernel
108 ; Push return address to make this look like a call
110 push dword (SETUPSEG<<4)+.returnAddr
113 ; Far jump into kernel
114 jmp KERNEL_CS:ENTRY_POINT
117 ; We shouldn't return here.
125 ; Kill the floppy motor.
126 ; This code was shamelessly stolen from Linux.
134 ; Initialize master and slave PIC!
136 out 0x20, al ; ICW1 to master
138 out 0xA0, al ; ICW1 to slave
141 out 0x21, al ; ICW2 to master
144 out 0xA1, al ; ICW2 to slave
147 out 0x21, al ; ICW3 to master
150 out 0xA1, al ; ICW3 to slave
153 out 0x21, al ; ICW4 to master
155 out 0xA1, al ; ICW4 to slave
157 mov al, 0xff ; mask all ints in slave
158 out 0xA1, al ; OCW1 to slave
160 mov al, 0xfb ; mask all ints but 2 in master
161 out 0x21, al ; OCW1 to master
165 ; Linux uses this code.
166 ; The idea is that some systems issue port I/O instructions
167 ; faster than the device hardware can deal with them.
172 ; Enable the A20 address line, so we can correctly address
184 ; ----------------------------------------------------------------------
186 ; ----------------------------------------------------------------------
188 mem_size_kbytes: dw 0
189 mem_size_eblocks: dw 0
191 ; ----------------------------------------------------------------------
192 ; The GDT. Creates flat 32-bit address space for the kernel
193 ; code, data, and stack. Note that this GDT is just used
194 ; to create an environment where we can start running 32 bit
195 ; code. The kernel will create and manage its own GDT.
196 ; ----------------------------------------------------------------------
198 ; GDT initialization stuff
199 NUM_GDT_ENTRIES equ 3 ; number of entries in GDT
200 GDT_ENTRY_SZ equ 8 ; size of a single GDT entry
204 ; Descriptor 0 is not used
210 ; Descriptor 1: kernel code segment
211 dw 0xFFFF ; bytes 0 and 1 of segment size
212 dw 0x0000 ; bytes 0 and 1 of segment base address
213 db 0x00 ; byte 2 of segment base address
214 db 0x9A ; present, DPL=0, non-system, code, non-conforming,
215 ; readable, not accessed
216 db 0xCF ; granularity=page, 32 bit code, upper nibble of size
217 db 0x00 ; byte 3 of segment base address
219 ; Descriptor 2: kernel data and stack segment
220 ; NOTE: what Intel calls an "expand-up" segment
221 ; actually means that the stack will grow DOWN,
222 ; towards lower memory. So, we can use this descriptor
223 ; for both data and stack references.
224 dw 0xFFFF ; bytes 0 and 1 of segment size
225 dw 0x0000 ; bytes 0 and 1 of segment base address
226 db 0x00 ; byte 2 of segment base address
227 db 0x92 ; present, DPL=0, non-system, data, expand-up,
228 ; writable, not accessed
229 db 0xCF ; granularity=page, big, upper nibble of size
230 db 0x00 ; byte 3 of segment base address
233 dw NUM_GDT_ENTRIES*GDT_ENTRY_SZ ; limit
234 dd (SETUPSEG<<4) + GDT ; base address