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.


moved guest files to kernel image
[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.4 $
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, VMM_SIZE
92         shl     eax, 9          ; Multiply the vmm size by 512 to get byte size
93         push    ebx             ; size of the VMM
94
95         push    dword 8         ; bootInfoSize
96
97         ; Pass pointer to Boot_Info struct as argument to kernel
98         ; entry point.
99         push    esp
100
101         ; Push return address to make this look like a call
102         ; XXX - untested
103         push    dword (SETUPSEG<<4)+.returnAddr
104
105
106         ; Far jump into kernel
107         jmp     KERNEL_CS:ENTRY_POINT
108
109 .returnAddr:
110         ; We shouldn't return here.
111 .here:  jmp .here
112
113
114
115
116 [BITS 16]
117
118 ; Kill the floppy motor.
119 ; This code was shamelessly stolen from Linux.
120 Kill_Motor:
121         mov     dx, 0x3f2
122         xor     al, al
123         out     dx, al
124         ret
125
126 Init_PIC:
127         ; Initialize master and slave PIC!
128         mov     al, ICW1
129         out     0x20, al                ; ICW1 to master
130         call    Delay
131         out     0xA0, al                ; ICW1 to slave
132         call    Delay
133         mov     al, ICW2_MASTER
134         out     0x21, al                ; ICW2 to master
135         call    Delay
136         mov     al, ICW2_SLAVE
137         out     0xA1, al                ; ICW2 to slave
138         call    Delay
139         mov     al, ICW3_MASTER
140         out     0x21, al                ; ICW3 to master
141         call    Delay
142         mov     al, ICW3_SLAVE
143         out     0xA1, al                ; ICW3 to slave
144         call    Delay
145         mov     al, ICW4
146         out     0x21, al                ; ICW4 to master
147         call    Delay
148         out     0xA1, al                ; ICW4 to slave
149         call    Delay
150         mov     al, 0xff                ; mask all ints in slave
151         out     0xA1, al                ; OCW1 to slave
152         call    Delay
153         mov     al, 0xfb                ; mask all ints but 2 in master
154         out     0x21, al                ; OCW1 to master
155         call    Delay
156         ret
157
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.
161 Delay:
162         jmp     .done
163 .done:  ret
164
165 ; Enable the A20 address line, so we can correctly address
166 ; memory above 1MB.
167 Enable_A20:
168         mov     al, 0xD1
169         out     0x64, al
170         call    Delay
171         mov     al, 0xDF
172         out     0x60, al
173         call    Delay
174         ret
175
176
177 ; ----------------------------------------------------------------------
178 ; Setup data
179 ; ----------------------------------------------------------------------
180
181 mem_size_kbytes: dw 0
182 mem_size_eblocks: dw 0
183
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 ; ----------------------------------------------------------------------
190
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
194
195 align 8, db 0
196 GDT:
197         ; Descriptor 0 is not used
198         dw 0
199         dw 0
200         dw 0
201         dw 0
202
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
211
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
224
225 GDT_Pointer:
226         dw NUM_GDT_ENTRIES*GDT_ENTRY_SZ ; limit
227         dd (SETUPSEG<<4) + GDT          ; base address
228
229 IDT_Pointer:
230         dw 0
231         dd 00