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] / misc / test_vm / src / geekos / setup.asm
diff --git a/misc/test_vm/src/geekos/setup.asm b/misc/test_vm/src/geekos/setup.asm
new file mode 100644 (file)
index 0000000..c88ed81
--- /dev/null
@@ -0,0 +1,240 @@
+; -*- fundamental -*-
+; GeekOS setup code
+; Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
+; $Revision: 1.1 $
+
+; This is free software.  You are permitted to use,
+; redistribute, and modify it as specified in the file "COPYING".
+
+; A lot of this code is adapted from Kernel Toolkit 0.2
+; and Linux version 2.2.x, so the following copyrights apply:
+
+; Copyright (C) 1991, 1992 Linus Torvalds
+; modified by Drew Eckhardt
+; modified by Bruce Evans (bde)
+; adapted for Kernel Toolkit by Luigi Sgro
+
+%include "defs.asm"
+
+; This is SUICIDE...
+; DON'T EVER INCLUDE CODE AT THE TOP LEVEL AGAIN
+;%include "util.asm"
+
+[BITS 16]
+[ORG 0x0]
+
+start_setup:
+
+       ; Redefine the data segment so we can access variables
+       ; declared in this file.
+       mov     ax, SETUPSEG
+       mov     ds, ax
+
+
+       ; Use int 15h to find out size of extended memory in KB.
+       ; Extended memory is the memory above 1MB.  So by
+       ; adding 1MB to this amount, we get the total amount
+       ; of system memory.  We can only detect 64MB this way,
+       ; but that's OK for now.
+       ;mov    ah, 0x88
+       ;int    0x15
+       ;add    ax, 1024        ; 1024 KB == 1 MB
+       mov     ax, 0xe801
+       int     0x15
+       add     ax, 1024        ; 1024 KB == 1 MB
+       mov     [mem_size_kbytes], ax
+       mov     [mem_size_eblocks], bx
+
+       ; Kill the floppy motor.
+       call    Kill_Motor
+
+
+
+       ; Block interrupts, since we can't meaningfully handle them yet
+       ; and we no longer need BIOS services.
+       cli
+
+       ; Set up IDT and GDT registers
+       lidt    [IDT_Pointer]
+       lgdt    [GDT_Pointer]
+
+       ; Initialize the interrupt controllers, and enable the
+       ; A20 address line
+       call    Init_PIC
+       call    Enable_A20
+
+       ; Switch to protected mode!
+       mov     ax, 0x01
+       lmsw    ax
+
+       ; Jump to 32 bit code.
+       jmp     dword KERNEL_CS:(SETUPSEG << 4) + setup_32
+
+
+[BITS 32]
+setup_32:
+
+       ; set up data segment registers
+       mov     ax, KERNEL_DS
+       mov     ds, ax
+       mov     es, ax
+       mov     fs, ax
+       mov     gs, ax
+       mov     ss, ax
+
+       ; Create the stack for the initial kernel thread.
+       mov     esp, KERN_STACK + 4096
+
+       ; Build Boot_Info struct on stack.
+       ; Note that we push the fields on in reverse order,
+       ; since the stack grows downwards.
+       xor     eax, eax
+       mov     ax, [(SETUPSEG<<4)+mem_size_kbytes]
+       xor     ebx, ebx
+       mov     bx, [(SETUPSEG<<4)+mem_size_eblocks]
+       shl     ebx, 6
+       add     eax, ebx
+       push    eax             ; memSizeKB
+       push    dword 8         ; bootInfoSize
+
+       ; Pass pointer to Boot_Info struct as argument to kernel
+       ; entry point.
+       push    esp
+
+       ; Push return address to make this look like a call
+       ; XXX - untested
+       push    dword (SETUPSEG<<4)+.returnAddr
+
+
+
+       ; Far jump into kernel
+       jmp     KERNEL_CS:ENTRY_POINT
+
+.returnAddr:
+       ; We shouldn't return here.
+.here: jmp .here
+
+
+
+
+
+[BITS 16]
+
+
+
+%include "util.asm"
+
+; Kill the floppy motor.
+; This code was shamelessly stolen from Linux.
+Kill_Motor:
+       mov     dx, 0x3f2
+       xor     al, al
+       out     dx, al
+       ret
+
+Init_PIC:
+       ; Initialize master and slave PIC!
+       mov     al, ICW1
+       out     0x20, al                ; ICW1 to master
+       call    Delay
+       out     0xA0, al                ; ICW1 to slave
+       call    Delay
+       mov     al, ICW2_MASTER
+       out     0x21, al                ; ICW2 to master
+       call    Delay
+       mov     al, ICW2_SLAVE
+       out     0xA1, al                ; ICW2 to slave
+       call    Delay
+       mov     al, ICW3_MASTER
+       out     0x21, al                ; ICW3 to master
+       call    Delay
+       mov     al, ICW3_SLAVE
+       out     0xA1, al                ; ICW3 to slave
+       call    Delay
+       mov     al, ICW4
+       out     0x21, al                ; ICW4 to master
+       call    Delay
+       out     0xA1, al                ; ICW4 to slave
+       call    Delay
+       mov     al, 0xff                ; mask all ints in slave
+       out     0xA1, al                ; OCW1 to slave
+       call    Delay
+       mov     al, 0xfb                ; mask all ints but 2 in master
+       out     0x21, al                ; OCW1 to master
+       call    Delay
+       ret
+
+; Linux uses this code.
+; The idea is that some systems issue port I/O instructions
+; faster than the device hardware can deal with them.
+Delay:
+       jmp     .done
+.done: ret
+
+; Enable the A20 address line, so we can correctly address
+; memory above 1MB.
+Enable_A20:
+       mov     al, 0xD1
+       out     0x64, al
+       call    Delay
+       mov     al, 0xDF
+       out     0x60, al
+       call    Delay
+       ret
+
+
+; ----------------------------------------------------------------------
+; Setup data
+; ----------------------------------------------------------------------
+
+mem_size_kbytes: dw 0
+mem_size_eblocks: dw 0
+
+; ----------------------------------------------------------------------
+; The GDT.  Creates flat 32-bit address space for the kernel
+; code, data, and stack.  Note that this GDT is just used
+; to create an environment where we can start running 32 bit
+; code.  The kernel will create and manage its own GDT.
+; ----------------------------------------------------------------------
+
+; GDT initialization stuff
+NUM_GDT_ENTRIES equ 3          ; number of entries in GDT
+GDT_ENTRY_SZ equ 8             ; size of a single GDT entry
+
+align 8, db 0
+GDT:
+       ; Descriptor 0 is not used
+       dw 0
+       dw 0
+       dw 0
+       dw 0
+
+       ; Descriptor 1: kernel code segment
+       dw 0xFFFF       ; bytes 0 and 1 of segment size
+       dw 0x0000       ; bytes 0 and 1 of segment base address
+       db 0x00         ; byte 2 of segment base address
+       db 0x9A         ; present, DPL=0, non-system, code, non-conforming,
+                       ;   readable, not accessed
+       db 0xCF         ; granularity=page, 32 bit code, upper nibble of size
+       db 0x00         ; byte 3 of segment base address
+
+       ; Descriptor 2: kernel data and stack segment
+       ; NOTE: what Intel calls an "expand-up" segment
+       ; actually means that the stack will grow DOWN,
+       ; towards lower memory.  So, we can use this descriptor
+       ; for both data and stack references.
+       dw 0xFFFF       ; bytes 0 and 1 of segment size
+       dw 0x0000       ; bytes 0 and 1 of segment base address
+       db 0x00         ; byte 2 of segment base address
+       db 0x92         ; present, DPL=0, non-system, data, expand-up,
+                       ;   writable, not accessed
+       db 0xCF         ; granularity=page, big, upper nibble of size
+       db 0x00         ; byte 3 of segment base address
+
+GDT_Pointer:
+       dw NUM_GDT_ENTRIES*GDT_ENTRY_SZ ; limit
+       dd (SETUPSEG<<4) + GDT          ; base address
+
+IDT_Pointer:
+       dw 0
+       dd 00