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] / geekos / src / geekos / setup.asm
1 ; -*- fundamental -*-
2 ; GeekOS setup code
3 ; Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
4 ; (c) 2008, Peter Dinda <pdinda@northwestern.edu> 
5 ; (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
6 ; (c) 2008, The V3VEE Project <http://www.v3vee.org> 
7 ; $Revision: 1.8 $
8
9 ; This is free software.  You are permitted to use,
10 ; redistribute, and modify it as specified in the file "COPYING".
11
12 ; A lot of this code is adapted from Kernel Toolkit 0.2
13 ; and Linux version 2.2.x, so the following copyrights apply:
14
15 ; Copyright (C) 1991, 1992 Linus Torvalds
16 ; modified by Drew Eckhardt
17 ; modified by Bruce Evans (bde)
18 ; adapted for Kernel Toolkit by Luigi Sgro
19
20 %define __BIG_KERNEL__
21
22 %include "defs.asm"
23
24 [BITS 16]
25 [ORG 0x0]
26
27 start:
28                 db      0xEB
29                 db      46 ;trampoline
30
31 ; This is the setup header, and it must start at %cs:2 (old 0x9020:2)
32
33                 db      'H'             ; header signature
34                 db      'd'
35                 db      'r'
36                 db      'S'
37                 dw      0x0203          ; header version number (>= 0x0105)
38                                         ; or else old loadlin-1.5 will fail)
39 realmode_swtch: dw      0, 0            ; default_switch, SETUPSEG
40 start_sys_seg:  dw      SYSSEG
41                 dw      kernel_version  ; pointing to kernel version string
42                                         ; above section of header is compatible
43                                         ; with loadlin-1.5 (header v1.5). Don't
44                                         ; change it.
45
46 type_of_loader: db      0               ; = 0, old one (LILO, Loadlin,
47                                         ;      Bootlin, SYSLX, bootsect...)
48                                         ; See Documentation/i386/boot.txt for
49                                         ; assigned ids
50         
51 ; flags, unused bits must be zero (RFU) bit within loadflags
52 loadflags:  db 1
53 ;LOADED_HIGH    equ 1                   ; If set, the kernel is loaded high
54 ;CAN_USE_HEAP   equ 0x80                        ; If set, the loader also has set
55                                         ; heap_end_ptr to tell how much
56                                         ; space behind setup.S can be used for
57                                         ; heap purposes.
58                                         ; Only the loader knows what is free
59 ;%ifndef __BIG_KERNEL__
60 ;               db      1
61 ;%else
62 ;               db      1
63 ;%endif
64
65 setup_move_size: dw  0x8000             ; size to move, when setup is not
66                                         ; loaded at 0x90000. We will move setup 
67                                         ; to 0x90000 then just before jumping
68                                         ; into the kernel. However, only the
69                                         ; loader knows how much data behind
70                                         ; us also needs to be loaded.
71
72 code32_start: dd 0x100000                               ; here loaders can put a different
73                                         ; start address for 32-bit code.
74 ;%ifndef __BIG_KERNEL__
75 ;               dd      0x100000        ;   0x1000 = default for zImage
76 ;%else
77 ;               dd      0x100000        ; 0x100000 = default for big kernel
78 ;%endif
79
80 ramdisk_image:  dd      0               ; address of loaded ramdisk image
81                                         ; Here the loader puts the 32-bit
82                                         ; address where it loaded the image.
83                                         ; This only will be read by the kernel.
84
85 ramdisk_size:   dd      0               ; its size in bytes
86
87 bootsect_kludge:
88                 dd      0               ; obsolete
89
90 heap_end_ptr:   dw      modelist+1024   ; (Header version 0x0201 or later)
91                                         ; space from here (exclusive) down to
92                                         ; end of setup code can be used by setup
93                                         ; for local heap purposes.
94
95 pad1:           dw      0
96 cmd_line_ptr:   dd      0               ; (Header version 0x0202 or later)
97                                         ; If nonzero, a 32-bit pointer
98                                         ; to the kernel command line.
99                                         ; The command line should be
100                                         ; located between the start of
101                                         ; setup and the end of low
102                                         ; memory (0xa0000), or it may
103                                         ; get overwritten before it
104                                         ; gets read.  If this field is
105                                         ; used, there is no longer
106                                         ; anything magical about the
107                                         ; 0x90000 segment; the setup
108                                         ; can be located anywhere in
109                                         ; low memory 0x10000 or higher.
110
111 ramdisk_max:      dd 0xffffffff
112 ;kernel_alignment:  dd 0x200000          ; physical addr alignment required for
113                                         ; protected mode relocatable kernel
114 ;%ifdef CONFIG_RELOCATABLE
115 ;relocatable_kernel:    db 1
116 ;%else
117 ;relocatable_kernel:    db 0
118 ;%endif
119 ;pad2:                  db 0
120 ;pad3:                  dw 0
121
122 ;cmdline_size:   dd   COMMAND_LINE_SIZE-1     ;length of the command line,
123                                               ;added with boot protocol
124                                               ;version 2.06
125
126 trampoline:     call    start_setup
127 ;               ALIGN 16
128 space: 
129        %rep  1024
130              db 0
131        %endrep                          ; The offset at this point is 0x240     
132                                         
133 ; End of setup header ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
134
135
136 start_setup:
137
138         ; Redefine the data segment so we can access variables
139         ; declared in this file.
140         mov     ax, SETUPSEG
141         mov     ds, ax
142
143         ; Use int 15h to find out size of extended memory in KB.
144         ; Extended memory is the memory above 1MB.  So by
145         ; adding 1MB to this amount, we get the total amount
146         ; of system memory.  We can only detect 64MB this way,
147         ; but that's OK for now.
148         ;mov    ah, 0x88
149         ;int    0x15
150         ;add    ax, 1024        ; 1024 KB == 1 MB
151         mov     ax, 0xe801
152         int     0x15
153         add     ax, 1024        ; 1024 KB == 1 MB
154         mov     [mem_size_kbytes], ax
155         mov     [mem_size_eblocks], bx
156
157         ; Kill the floppy motor.
158         call    Kill_Motor
159
160         ; Block interrupts, since we can't meaningfully handle them yet
161         ; and we no longer need BIOS services.
162         cli
163
164         ; Set up IDT and GDT registers
165         lidt    [IDT_Pointer]
166         lgdt    [GDT_Pointer]
167
168         ; Initialize the interrupt controllers, and enable the
169         ; A20 address line
170         call    Init_PIC
171         call    Enable_A20
172
173         ; Switch to protected mode!
174         mov     ax, 0x01
175         lmsw    ax
176
177
178         ; Jump to 32 bit code.
179         jmp     dword KERNEL_CS:(SETUPSEG << 4) + setup_32
180
181 [BITS 32]
182 setup_32:
183
184         ; set up data segment registers
185         mov     ax, KERNEL_DS
186         mov     ds, ax
187         mov     es, ax
188         mov     fs, ax
189         mov     gs, ax
190         mov     ss, ax
191
192         ; Create the stack for the initial kernel thread.
193         mov     esp, KERN_STACK + 4096
194
195         ; Build Boot_Info struct on stack.
196         ; Note that we push the fields on in reverse order,
197         ; since the stack grows downwards.
198
199         ;Zheng 08/02/2008
200         xor eax, eax
201         mov eax, [(SETUPSEG<<4)+ramdisk_size]
202         push eax
203
204         xor eax, eax
205         mov eax, [(SETUPSEG<<4)+ramdisk_image]
206         push eax        
207
208         xor     eax, eax
209         mov     ax, [(SETUPSEG<<4)+mem_size_kbytes]
210         xor     ebx, ebx
211         mov     bx, [(SETUPSEG<<4)+mem_size_eblocks]
212         shl     ebx, 6
213         add     eax, ebx
214         push    eax             ; memSizeKB
215         
216         mov     eax, VMM_SIZE
217         shl     eax, 9          ; Multiply the vmm size by 512 to get byte size
218         push    ebx             ; size of the VMM
219
220         push    dword 8         ; bootInfoSize
221
222         ; Pass pointer to Boot_Info struct as argument to kernel
223         ; entry point.
224         push    esp
225
226         ; Push return address to make this look like a call
227         ; XXX - untested
228         push    dword (SETUPSEG<<4)+.returnAddr
229
230
231         ; Far jump into kernel
232         jmp     KERNEL_CS:ENTRY_POINT
233
234 .returnAddr:
235         ; We shouldn't return here.
236 .here:  jmp .here
237
238
239
240
241 [BITS 16]
242
243 ; Kill the floppy motor.
244 ; This code was shamelessly stolen from Linux.
245 Kill_Motor:
246         mov     dx, 0x3f2
247         xor     al, al
248         out     dx, al
249         ret
250
251 Init_PIC:
252         ; Initialize master and slave PIC!
253         mov     al, ICW1
254         out     0x20, al                ; ICW1 to master
255         call    Delay
256         out     0xA0, al                ; ICW1 to slave
257         call    Delay
258         mov     al, ICW2_MASTER
259         out     0x21, al                ; ICW2 to master
260         call    Delay
261         mov     al, ICW2_SLAVE
262         out     0xA1, al                ; ICW2 to slave
263         call    Delay
264         mov     al, ICW3_MASTER
265         out     0x21, al                ; ICW3 to master
266         call    Delay
267         mov     al, ICW3_SLAVE
268         out     0xA1, al                ; ICW3 to slave
269         call    Delay
270         mov     al, ICW4
271         out     0x21, al                ; ICW4 to master
272         call    Delay
273         out     0xA1, al                ; ICW4 to slave
274         call    Delay
275         mov     al, 0xff                ; mask all ints in slave
276         out     0xA1, al                ; OCW1 to slave
277         call    Delay
278         mov     al, 0xfb                ; mask all ints but 2 in master
279         out     0x21, al                ; OCW1 to master
280         call    Delay
281         ret
282
283 ; Linux uses this code.
284 ; The idea is that some systems issue port I/O instructions
285 ; faster than the device hardware can deal with them.
286 Delay:
287         jmp     .done
288 .done:  ret
289
290 ; Enable the A20 address line, so we can correctly address
291 ; memory above 1MB.
292 Enable_A20:
293         mov     al, 0xD1
294         out     0x64, al
295         call    Delay
296         mov     al, 0xDF
297         out     0x60, al
298         call    Delay
299         ret
300
301
302 ; ----------------------------------------------------------------------
303 ; Setup data
304 ; ----------------------------------------------------------------------
305
306 mem_size_kbytes: dw 0
307 mem_size_eblocks: dw 0
308
309
310 ; ----------------------------------------------------------------------
311 ; The GDT.  Creates flat 32-bit address space for the kernel
312 ; code, data, and stack.  Note that this GDT is just used
313 ; to create an environment where we can start running 32 bit
314 ; code.  The kernel will create and manage its own GDT.
315 ; ----------------------------------------------------------------------
316
317 ; GDT initialization stuff
318 NUM_GDT_ENTRIES equ 3           ; number of entries in GDT
319 GDT_ENTRY_SZ equ 8              ; size of a single GDT entry
320
321 align 8, db 0
322 GDT:
323         ; Descriptor 0 is not used
324         dw 0
325         dw 0
326         dw 0
327         dw 0
328
329         ; Descriptor 1: kernel code segment
330         dw 0xFFFF       ; bytes 0 and 1 of segment size
331         dw 0x0000       ; bytes 0 and 1 of segment base address
332         db 0x00         ; byte 2 of segment base address
333         db 0x9A         ; present, DPL=0, non-system, code, non-conforming,
334                         ;   readable, not accessed
335         db 0xCF         ; granularity=page, 32 bit code, upper nibble of size
336         db 0x00         ; byte 3 of segment base address
337
338         ; Descriptor 2: kernel data and stack segment
339         ; NOTE: what Intel calls an "expand-up" segment
340         ; actually means that the stack will grow DOWN,
341         ; towards lower memory.  So, we can use this descriptor
342         ; for both data and stack references.
343         dw 0xFFFF       ; bytes 0 and 1 of segment size
344         dw 0x0000       ; bytes 0 and 1 of segment base address
345         db 0x00         ; byte 2 of segment base address
346         db 0x92         ; present, DPL=0, non-system, data, expand-up,
347                         ;   writable, not accessed
348         db 0xCF         ; granularity=page, big, upper nibble of size
349         db 0x00         ; byte 3 of segment base address
350
351 GDT_Pointer:
352         dw NUM_GDT_ENTRIES*GDT_ENTRY_SZ ; limit
353         dd (SETUPSEG<<4) + GDT          ; base address
354
355 IDT_Pointer:
356         dw 0
357         dd 00
358
359 ; Here's a bunch of information about your current kernel..
360 kernel_version: db      "1.0.0VMMHack"
361                 db      " ("
362                 db      "copyright"
363                 db      "@"
364                 db      "2008"
365                 db      ") "
366                 db      ""
367                 db      0
368
369 modelist: