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.


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