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.


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