Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Release 1.0
[palacios.git] / misc / test_vm / src / geekos / setup.asm
1 ; -*- fundamental -*-
2 ; GeekOS setup code
3 ; Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
4 ; $Revision: 1.1 $
5
6 ; This is free software.  You are permitted to use,
7 ; redistribute, and modify it as specified in the file "COPYING".
8
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:
11
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
16
17 %include "defs.asm"
18
19 ; This is SUICIDE...
20 ; DON'T EVER INCLUDE CODE AT THE TOP LEVEL AGAIN
21 ;%include "util.asm"
22
23 [BITS 16]
24 [ORG 0x0]
25
26 start_setup:
27
28         ; Redefine the data segment so we can access variables
29         ; declared in this file.
30         mov     ax, SETUPSEG
31         mov     ds, ax
32
33
34         ; Use int 15h to find out size of extended memory in KB.
35         ; Extended memory is the memory above 1MB.  So by
36         ; adding 1MB to this amount, we get the total amount
37         ; of system memory.  We can only detect 64MB this way,
38         ; but that's OK for now.
39         ;mov    ah, 0x88
40         ;int    0x15
41         ;add    ax, 1024        ; 1024 KB == 1 MB
42         mov     ax, 0xe801
43         int     0x15
44         add     ax, 1024        ; 1024 KB == 1 MB
45         mov     [mem_size_kbytes], ax
46         mov     [mem_size_eblocks], bx
47
48         ; Kill the floppy motor.
49         call    Kill_Motor
50
51
52
53         ; Block interrupts, since we can't meaningfully handle them yet
54         ; and we no longer need BIOS services.
55         cli
56
57         ; Set up IDT and GDT registers
58         lidt    [IDT_Pointer]
59         lgdt    [GDT_Pointer]
60
61         ; Initialize the interrupt controllers, and enable the
62         ; A20 address line
63         call    Init_PIC
64         call    Enable_A20
65
66         ; Switch to protected mode!
67         mov     ax, 0x01
68         lmsw    ax
69
70         ; Jump to 32 bit code.
71         jmp     dword KERNEL_CS:(SETUPSEG << 4) + setup_32
72
73
74 [BITS 32]
75 setup_32:
76
77         ; set up data segment registers
78         mov     ax, KERNEL_DS
79         mov     ds, ax
80         mov     es, ax
81         mov     fs, ax
82         mov     gs, ax
83         mov     ss, ax
84
85         ; Create the stack for the initial kernel thread.
86         mov     esp, KERN_STACK + 4096
87
88         ; Build Boot_Info struct on stack.
89         ; Note that we push the fields on in reverse order,
90         ; since the stack grows downwards.
91         xor     eax, eax
92         mov     ax, [(SETUPSEG<<4)+mem_size_kbytes]
93         xor     ebx, ebx
94         mov     bx, [(SETUPSEG<<4)+mem_size_eblocks]
95         shl     ebx, 6
96         add     eax, ebx
97         push    eax             ; memSizeKB
98         push    dword 8         ; bootInfoSize
99
100         ; Pass pointer to Boot_Info struct as argument to kernel
101         ; entry point.
102         push    esp
103
104         ; Push return address to make this look like a call
105         ; XXX - untested
106         push    dword (SETUPSEG<<4)+.returnAddr
107
108
109
110         ; Far jump into kernel
111         jmp     KERNEL_CS:ENTRY_POINT
112
113 .returnAddr:
114         ; We shouldn't return here.
115 .here:  jmp .here
116
117
118
119
120
121 [BITS 16]
122
123
124
125 %include "util.asm"
126
127 ; Kill the floppy motor.
128 ; This code was shamelessly stolen from Linux.
129 Kill_Motor:
130         mov     dx, 0x3f2
131         xor     al, al
132         out     dx, al
133         ret
134
135 Init_PIC:
136         ; Initialize master and slave PIC!
137         mov     al, ICW1
138         out     0x20, al                ; ICW1 to master
139         call    Delay
140         out     0xA0, al                ; ICW1 to slave
141         call    Delay
142         mov     al, ICW2_MASTER
143         out     0x21, al                ; ICW2 to master
144         call    Delay
145         mov     al, ICW2_SLAVE
146         out     0xA1, al                ; ICW2 to slave
147         call    Delay
148         mov     al, ICW3_MASTER
149         out     0x21, al                ; ICW3 to master
150         call    Delay
151         mov     al, ICW3_SLAVE
152         out     0xA1, al                ; ICW3 to slave
153         call    Delay
154         mov     al, ICW4
155         out     0x21, al                ; ICW4 to master
156         call    Delay
157         out     0xA1, al                ; ICW4 to slave
158         call    Delay
159         mov     al, 0xff                ; mask all ints in slave
160         out     0xA1, al                ; OCW1 to slave
161         call    Delay
162         mov     al, 0xfb                ; mask all ints but 2 in master
163         out     0x21, al                ; OCW1 to master
164         call    Delay
165         ret
166
167 ; Linux uses this code.
168 ; The idea is that some systems issue port I/O instructions
169 ; faster than the device hardware can deal with them.
170 Delay:
171         jmp     .done
172 .done:  ret
173
174 ; Enable the A20 address line, so we can correctly address
175 ; memory above 1MB.
176 Enable_A20:
177         mov     al, 0xD1
178         out     0x64, al
179         call    Delay
180         mov     al, 0xDF
181         out     0x60, al
182         call    Delay
183         ret
184
185
186 ; ----------------------------------------------------------------------
187 ; Setup data
188 ; ----------------------------------------------------------------------
189
190 mem_size_kbytes: dw 0
191 mem_size_eblocks: dw 0
192
193 ; ----------------------------------------------------------------------
194 ; The GDT.  Creates flat 32-bit address space for the kernel
195 ; code, data, and stack.  Note that this GDT is just used
196 ; to create an environment where we can start running 32 bit
197 ; code.  The kernel will create and manage its own GDT.
198 ; ----------------------------------------------------------------------
199
200 ; GDT initialization stuff
201 NUM_GDT_ENTRIES equ 3           ; number of entries in GDT
202 GDT_ENTRY_SZ equ 8              ; size of a single GDT entry
203
204 align 8, db 0
205 GDT:
206         ; Descriptor 0 is not used
207         dw 0
208         dw 0
209         dw 0
210         dw 0
211
212         ; Descriptor 1: kernel code segment
213         dw 0xFFFF       ; bytes 0 and 1 of segment size
214         dw 0x0000       ; bytes 0 and 1 of segment base address
215         db 0x00         ; byte 2 of segment base address
216         db 0x9A         ; present, DPL=0, non-system, code, non-conforming,
217                         ;   readable, not accessed
218         db 0xCF         ; granularity=page, 32 bit code, upper nibble of size
219         db 0x00         ; byte 3 of segment base address
220
221         ; Descriptor 2: kernel data and stack segment
222         ; NOTE: what Intel calls an "expand-up" segment
223         ; actually means that the stack will grow DOWN,
224         ; towards lower memory.  So, we can use this descriptor
225         ; for both data and stack references.
226         dw 0xFFFF       ; bytes 0 and 1 of segment size
227         dw 0x0000       ; bytes 0 and 1 of segment base address
228         db 0x00         ; byte 2 of segment base address
229         db 0x92         ; present, DPL=0, non-system, data, expand-up,
230                         ;   writable, not accessed
231         db 0xCF         ; granularity=page, big, upper nibble of size
232         db 0x00         ; byte 3 of segment base address
233
234 GDT_Pointer:
235         dw NUM_GDT_ENTRIES*GDT_ENTRY_SZ ; limit
236         dd (SETUPSEG<<4) + GDT          ; base address
237
238 IDT_Pointer:
239         dw 0
240         dd 00