X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=blobdiff_plain;f=misc%2Ftest_vm%2Fsrc%2Fgeekos%2Fsetup.asm;fp=misc%2Ftest_vm%2Fsrc%2Fgeekos%2Fsetup.asm;h=c88ed81be3692fbe2950c15f3f39cfa25249086b;hp=0000000000000000000000000000000000000000;hb=ddc16b0737cf58f7aa90a69c6652cdf4090aec51;hpb=626595465a2c6987606a6bc697df65130ad8c2d3 diff --git a/misc/test_vm/src/geekos/setup.asm b/misc/test_vm/src/geekos/setup.asm new file mode 100644 index 0000000..c88ed81 --- /dev/null +++ b/misc/test_vm/src/geekos/setup.asm @@ -0,0 +1,240 @@ +; -*- fundamental -*- +; GeekOS setup code +; Copyright (c) 2001,2004 David H. Hovemeyer +; $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