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.


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