From: Jack Lange Date: Tue, 4 Mar 2008 23:30:26 +0000 (+0000) Subject: added memory region generated page tables, and removed all the ugliness that was... X-Git-Tag: working-cdboot-physical-but-not-qemu~59 X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=190b2ef9470c23c275754b74745933d973f8c439 added memory region generated page tables, and removed all the ugliness that was the high memory loader --- diff --git a/palacios/build/Makefile b/palacios/build/Makefile index c3712a2..a82b6cc 100644 --- a/palacios/build/Makefile +++ b/palacios/build/Makefile @@ -1,6 +1,6 @@ # Makefile for GeekOS kernel, userspace, and tools # Copyright (c) 2004,2005 David H. Hovemeyer -# $Revision: 1.14 $ +# $Revision: 1.15 $ # This is free software. You are permitted to use, # redistribute, and modify it as specified in the file "COPYING". @@ -20,19 +20,6 @@ # to speed the build process on 2 processor systems. - -# THESE MUST MATCH WHAT IS DEFINED IN defs.h and defs.asm exactly -# MUST BE INTEGRAL NUMBER OF PAGES -TOP_OF_MEM := 0x30000000 -VM_SIZE := 0x20000000 -VM_START := 0x0 - -# -# THE KERNEL, SETUP, BOOTPACKAGE MUST BE SMALLER THAN THIS -# MUST BE INTEGRAL NUMBER OF PAGES -# define -MAX_VMM := 0x160000 - # Base address of kernel # # Note: at top of memory minus three pages (GDT/TSS/IDT) @@ -43,7 +30,7 @@ MAX_VMM := 0x160000 # # The setup code needs to copy it up to this address and jump there # -KERNEL_BASE_ADDR := $(shell perl -e 'print sprintf("0x%x",$(TOP_OF_MEM)-4096*3-$(MAX_VMM));') +KERNEL_BASE_ADDR := 0x00010000 # Kernel entry point function KERNEL_ENTRY = $(SYM_PFX)Main @@ -59,7 +46,7 @@ JRLDEBUG= -DSERIAL_PRINT_DEBUG=1 -DSERIAL_PRINT_DEBUG_LEVEL=10 -DSERIAL_PRINT=1 # # #Peter's compile flags -PADFLAGS = -DMAX_VMM=$(MAX_VMM) +PADFLAGS = # Figure out if we're compiling with cygwin, http://cygwin.com SYSTEM_NAME := $(shell uname -s) @@ -71,7 +58,7 @@ NON_ELF_SYSTEM := yes EXTRA_CC_USER_OPTS := -Dmain=geekos_main endif -VMM_SIZES = ../include/geekos/vmm_sizes.h + # ---------------------------------------------------------------------- @@ -99,7 +86,7 @@ KERNEL_C_SRCS := idt.c int.c trap.c irq.c io.c \ serial.c reboot.c \ paging.c vmx.c vmcs_gen.c vmcs.c \ svm.c vmm.c vmm_util.c vmm_stubs.c \ - vmcb.c vmm_mem.c vm_guest.c \ + vmcb.c vmm_mem.c vm_guest.c vmm_paging.c \ debug.c\ main.c @@ -281,12 +268,12 @@ geekos/fd_boot.bin : geekos/setup.bin geekos/kernel.bin $(PROJECT_ROOT)/src/geek -o $@ # Setup program (second stage boot loader). -geekos/setup.bin : geekos/kernel.exe $(PROJECT_ROOT)/src/geekos/setup.asm +geekos/setup.bin : geekos/kernel.bin $(PROJECT_ROOT)/src/geekos/setup.asm $(NASM) -f bin \ -I$(PROJECT_ROOT)/src/geekos/ \ -DENTRY_POINT=0x`egrep 'Main$$' geekos/kernel.syms |awk '{print $$1}'` \ - -DVMM_FINAL_ADDR=$(KERNEL_BASE_ADDR) \ - -DVMM_SIZE=$(MAX_VMM) \ + -DVMM_SIZE=`$(NUMSECS) geekos/kernel.bin` \ + -DGUEST_SIZE=`$(NUMSECS) vm_kernel` \ $(PROJECT_ROOT)/src/geekos/setup.asm \ -o $@ $(PAD) $@ 512 @@ -303,31 +290,6 @@ geekos/kernel.exe : $(KERNEL_OBJS) $(COMMON_C_OBJS) $(TARGET_NM) geekos/kernel.exe > geekos/kernel.syms -generate_sizes: force - echo "#ifndef __vmm_sizes" > $(VMM_SIZES) - echo "#define __vmm_sizes" >> $(VMM_SIZES) - echo "#define KERNEL_LOAD_ADDRESS " $(KERNEL_BASE_ADDR) >> $(VMM_SIZES) - - echo "#define KERNEL_START (KERNEL_LOAD_ADDRESS)" >> $(VMM_SIZES) - echo "#define KERNEL_CORE_LENGTH (" `$(NUMSECS) geekos/kernel.bin` "*512)" >> $(VMM_SIZES) - echo "#define KERNEL_END (KERNEL_LOAD_ADDRESS+KERNEL_CORE_LENGTH-1)" >> $(VMM_SIZES) - - echo "#define VM_KERNEL_LENGTH (" `$(NUMSECS) vm_kernel` "*512)" >> $(VMM_SIZES) - echo "#define VM_KERNEL_START (KERNEL_LOAD_ADDRESS + KERNEL_CORE_LENGTH)" >> $(VMM_SIZES) - echo "#define VM_BOOT_PACKAGE_START (VM_KERNEL_START) " >> $(VMM_SIZES) - echo "#define VM_BOOT_PACKAGE_END (VM_KERNEL_START+VM_KERNEL_LENGTH-1) " >> $(VMM_SIZES) - echo "#endif" >> $(VMM_SIZES) - -make_show_sizes: generate_sizes ../src/geekos/show_sizes.c - $(HOST_CC) -I../include/geekos ../src/geekos/show_sizes.c -o show_sizes - -show_sizes: make_show_sizes - ./show_sizes - - -get_kernel_size: make_show_sizes - ./show_sizes | grep - force: @@ -338,7 +300,7 @@ vm_kernel: force vmm_mem_test: geekos/vmm_mem.c - $(HOST_CC) -o mem_test -DVMM_MEM_TEST -I../include ../src/geekos/vmm_mem.c + $(HOST_CC) -m32 -o mem_test -DVMM_MEM_TEST -I../include ../src/geekos/vmm_mem.c ../src/geekos/vmm_paging.c # Clean build directories of generated files diff --git a/palacios/build/depend.mak b/palacios/build/depend.mak index cc91343..e69de29 100644 --- a/palacios/build/depend.mak +++ b/palacios/build/depend.mak @@ -1,257 +0,0 @@ -geekos/idt.o: ../src/geekos/idt.c ../include/geekos/kassert.h \ - ../include/geekos/screen.h ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/defs.h ../include/geekos/idt.h \ - ../include/geekos/int.h ../include/geekos/serial.h \ - ../include/geekos/irq.h ../include/geekos/string.h \ - ../include/geekos/../libc/string.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \ - ../include/geekos/io.h -geekos/int.o: ../src/geekos/int.c ../include/geekos/idt.h \ - ../include/geekos/int.h ../include/geekos/kassert.h \ - ../include/geekos/screen.h ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/defs.h ../include/geekos/serial.h \ - ../include/geekos/irq.h ../include/geekos/string.h \ - ../include/geekos/../libc/string.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \ - ../include/geekos/io.h ../include/geekos/vmcs.h \ - ../include/geekos/vmcs_gen.h ../include/geekos/cpu.h -geekos/trap.o: ../src/geekos/trap.c ../include/geekos/idt.h \ - ../include/geekos/int.h ../include/geekos/kassert.h \ - ../include/geekos/screen.h ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/defs.h ../include/geekos/kthread.h \ - ../include/geekos/list.h ../include/geekos/trap.h \ - ../include/geekos/serial.h ../include/geekos/irq.h \ - ../include/geekos/string.h ../include/geekos/../libc/string.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \ - ../include/geekos/io.h -geekos/irq.o: ../src/geekos/irq.c ../include/geekos/kassert.h \ - ../include/geekos/screen.h ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/idt.h ../include/geekos/int.h \ - ../include/geekos/defs.h ../include/geekos/io.h ../include/geekos/irq.h -geekos/io.o: ../src/geekos/io.c ../include/geekos/io.h \ - ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h -geekos/blockdev.o: ../src/geekos/blockdev.c ../include/geekos/errno.h \ - ../include/geekos/screen.h ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/string.h ../include/geekos/../libc/string.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \ - ../include/geekos/malloc.h ../include/geekos/int.h \ - ../include/geekos/kassert.h ../include/geekos/defs.h \ - ../include/geekos/kthread.h ../include/geekos/list.h \ - ../include/geekos/synch.h ../include/geekos/blockdev.h \ - ../include/geekos/fileio.h -geekos/ide.o: ../src/geekos/ide.c ../include/geekos/serial.h \ - ../include/geekos/irq.h ../include/geekos/int.h \ - ../include/geekos/kassert.h ../include/geekos/screen.h \ - ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/defs.h ../include/geekos/string.h \ - ../include/geekos/../libc/string.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \ - ../include/geekos/io.h ../include/geekos/errno.h \ - ../include/geekos/malloc.h ../include/geekos/timer.h \ - ../include/geekos/kthread.h ../include/geekos/list.h \ - ../include/geekos/blockdev.h ../include/geekos/fileio.h \ - ../include/geekos/ide.h -geekos/keyboard.o: ../src/geekos/keyboard.c ../include/geekos/kthread.h \ - ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/list.h ../include/geekos/kassert.h \ - ../include/geekos/screen.h ../include/geekos/irq.h \ - ../include/geekos/int.h ../include/geekos/defs.h ../include/geekos/io.h \ - ../include/geekos/keyboard.h -geekos/screen.o: ../src/geekos/screen.c \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \ - ../include/geekos/kassert.h ../include/geekos/screen.h \ - ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/io.h ../include/geekos/int.h ../include/geekos/defs.h \ - ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h -geekos/timer.o: ../src/geekos/timer.c \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/limits.h \ - ../include/geekos/io.h ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/int.h ../include/geekos/kassert.h \ - ../include/geekos/screen.h ../include/geekos/defs.h \ - ../include/geekos/irq.h ../include/geekos/kthread.h \ - ../include/geekos/list.h ../include/geekos/timer.h \ - ../include/geekos/serial.h ../include/geekos/string.h \ - ../include/geekos/../libc/string.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h -geekos/mem.o: ../src/geekos/mem.c ../include/geekos/defs.h \ - ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/kassert.h ../include/geekos/screen.h \ - ../include/geekos/bootinfo.h ../include/geekos/gdt.h \ - ../include/geekos/int.h ../include/geekos/malloc.h \ - ../include/geekos/string.h ../include/geekos/../libc/string.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \ - ../include/geekos/mem.h ../include/geekos/list.h \ - ../include/geekos/paging.h ../include/geekos/vmm_sizes.h \ - ../include/geekos/serial.h ../include/geekos/irq.h \ - ../include/geekos/io.h -geekos/crc32.o: ../src/geekos/crc32.c ../include/geekos/crc32.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \ - ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/kassert.h ../include/geekos/screen.h \ - ../include/geekos/serial.h ../include/geekos/irq.h \ - ../include/geekos/int.h ../include/geekos/defs.h \ - ../include/geekos/string.h ../include/geekos/../libc/string.h \ - ../include/geekos/io.h -geekos/gdt.o: ../src/geekos/gdt.c ../include/geekos/kassert.h \ - ../include/geekos/screen.h ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/segment.h ../include/geekos/int.h \ - ../include/geekos/defs.h ../include/geekos/tss.h \ - ../include/geekos/gdt.h ../include/libc/string.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h -geekos/tss.o: ../src/geekos/tss.c ../include/geekos/kassert.h \ - ../include/geekos/screen.h ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/defs.h ../include/geekos/gdt.h \ - ../include/geekos/segment.h ../include/geekos/string.h \ - ../include/geekos/../libc/string.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \ - ../include/geekos/tss.h ../include/geekos/serial.h \ - ../include/geekos/irq.h ../include/geekos/int.h ../include/geekos/io.h -geekos/segment.o: ../src/geekos/segment.c ../include/geekos/kassert.h \ - ../include/geekos/screen.h ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/string.h ../include/geekos/../libc/string.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \ - ../include/geekos/tss.h ../include/geekos/segment.h -geekos/bget.o: ../src/geekos/bget.c ../include/geekos/string.h \ - ../include/geekos/../libc/string.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \ - ../include/geekos/kassert.h ../include/geekos/screen.h \ - ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/bget.h -geekos/malloc.o: ../src/geekos/malloc.c ../include/geekos/screen.h \ - ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/int.h ../include/geekos/kassert.h \ - ../include/geekos/defs.h ../include/geekos/bget.h \ - ../include/geekos/malloc.h -geekos/synch.o: ../src/geekos/synch.c ../include/geekos/kthread.h \ - ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/list.h ../include/geekos/kassert.h \ - ../include/geekos/screen.h ../include/geekos/int.h \ - ../include/geekos/defs.h ../include/geekos/synch.h -geekos/kthread.o: ../src/geekos/kthread.c ../include/geekos/kassert.h \ - ../include/geekos/screen.h ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/defs.h ../include/geekos/int.h \ - ../include/geekos/mem.h ../include/geekos/list.h \ - ../include/geekos/paging.h ../include/geekos/bootinfo.h \ - ../include/geekos/symbol.h ../include/geekos/string.h \ - ../include/geekos/../libc/string.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \ - ../include/geekos/kthread.h ../include/geekos/malloc.h \ - ../include/geekos/serial.h ../include/geekos/irq.h \ - ../include/geekos/io.h -geekos/serial.o: ../src/geekos/serial.c ../include/geekos/serial.h \ - ../include/geekos/irq.h ../include/geekos/int.h \ - ../include/geekos/kassert.h ../include/geekos/screen.h \ - ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/defs.h ../include/geekos/string.h \ - ../include/geekos/../libc/string.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \ - ../include/geekos/io.h ../include/geekos/reboot.h \ - ../include/geekos/gdt.h ../include/geekos/idt.h -geekos/reboot.o: ../src/geekos/reboot.c ../include/geekos/reboot.h \ - ../include/libc/string.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h -geekos/paging.o: ../src/geekos/paging.c ../include/geekos/string.h \ - ../include/geekos/../libc/string.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \ - ../include/geekos/int.h ../include/geekos/kassert.h \ - ../include/geekos/screen.h ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/defs.h ../include/geekos/idt.h \ - ../include/geekos/kthread.h ../include/geekos/list.h \ - ../include/geekos/mem.h ../include/geekos/paging.h \ - ../include/geekos/bootinfo.h ../include/geekos/malloc.h \ - ../include/geekos/gdt.h ../include/geekos/segment.h \ - ../include/geekos/crc32.h ../include/geekos/serial.h \ - ../include/geekos/irq.h ../include/geekos/io.h ../include/geekos/vmcs.h \ - ../include/geekos/vmcs_gen.h -geekos/vmx.o: ../src/geekos/vmx.c ../include/geekos/vmx.h \ - ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/vmcs.h ../include/geekos/serial.h \ - ../include/geekos/irq.h ../include/geekos/int.h \ - ../include/geekos/kassert.h ../include/geekos/screen.h \ - ../include/geekos/defs.h ../include/geekos/string.h \ - ../include/geekos/../libc/string.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \ - ../include/geekos/io.h ../include/geekos/vmcs_gen.h \ - ../include/geekos/mem.h ../include/geekos/list.h \ - ../include/geekos/paging.h ../include/geekos/bootinfo.h \ - ../include/geekos/segment.h ../include/geekos/gdt.h \ - ../include/geekos/idt.h ../include/geekos/cpu.h \ - ../include/geekos/io_devs.h -geekos/vmcs_gen.o: ../src/geekos/vmcs_gen.c ../include/geekos/vmcs_gen.h \ - ../include/geekos/vmcs.h ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/serial.h ../include/geekos/irq.h \ - ../include/geekos/int.h ../include/geekos/kassert.h \ - ../include/geekos/screen.h ../include/geekos/defs.h \ - ../include/geekos/string.h ../include/geekos/../libc/string.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \ - ../include/geekos/io.h -geekos/vmcs.o: ../src/geekos/vmcs.c ../include/geekos/vmcs.h \ - ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/serial.h ../include/geekos/irq.h \ - ../include/geekos/int.h ../include/geekos/kassert.h \ - ../include/geekos/screen.h ../include/geekos/defs.h \ - ../include/geekos/string.h ../include/geekos/../libc/string.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \ - ../include/geekos/io.h ../include/geekos/vmcs_gen.h -geekos/svm.o: ../src/geekos/svm.c ../include/geekos/svm.h \ - ../include/geekos/screen.h ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/serial.h ../include/geekos/irq.h \ - ../include/geekos/int.h ../include/geekos/kassert.h \ - ../include/geekos/defs.h ../include/geekos/string.h \ - ../include/geekos/../libc/string.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \ - ../include/geekos/io.h -geekos/main.o: ../src/geekos/main.c ../include/geekos/bootinfo.h \ - ../include/geekos/string.h ../include/geekos/../libc/string.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \ - ../include/geekos/screen.h ../include/geekos/ktypes.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdbool.h \ - ../include/geekos/mem.h ../include/geekos/defs.h \ - ../include/geekos/list.h ../include/geekos/kassert.h \ - ../include/geekos/paging.h ../include/geekos/crc32.h \ - ../include/geekos/tss.h ../include/geekos/int.h \ - ../include/geekos/kthread.h ../include/geekos/trap.h \ - ../include/geekos/timer.h ../include/geekos/keyboard.h \ - ../include/geekos/io.h ../include/geekos/serial.h \ - ../include/geekos/irq.h ../include/geekos/reboot.h \ - ../include/geekos/ide.h ../include/geekos/vmx.h \ - ../include/geekos/vmcs.h ../include/geekos/vmcs_gen.h \ - ../include/geekos/svm.h ../include/geekos/vmcb.h \ - ../include/geekos/gdt.h ../include/geekos/vmm_sizes.h -common/fmtout.o: ../src/common/fmtout.c \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h \ - ../include/geekos/string.h ../include/geekos/../libc/string.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/limits.h \ - ../include/geekos/fmtout.h ../include/geekos/../libc/fmtout.h -common/string.o: ../src/common/string.c ../include/libc/fmtout.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stdarg.h \ - ../include/libc/string.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h -common/memmove.o: ../src/common/memmove.c ../include/libc/string.h \ - /home/jarusl/vmm-dev/devtools/i386/lib/gcc/i386-elf/3.4.6/include/stddef.h diff --git a/palacios/include/geekos/bootinfo.h b/palacios/include/geekos/bootinfo.h index bb50de1..5087f6f 100644 --- a/palacios/include/geekos/bootinfo.h +++ b/palacios/include/geekos/bootinfo.h @@ -1,7 +1,7 @@ /* * Boot information structure, passed to kernel Main() routine * Copyright (c) 2001, David H. Hovemeyer - * $Revision: 1.1 $ + * $Revision: 1.2 $ * * This is free software. You are permitted to use, * redistribute, and modify it as specified in the file "COPYING". @@ -11,8 +11,11 @@ #define GEEKOS_BOOTINFO_H struct Boot_Info { - int bootInfoSize; /* size of this struct; for versioning */ - int memSizeKB; /* number of KB, as reported by int 15h */ + int bootInfoSize; /* size of this struct; for versioning */ + int vmm_size; + int guest_load_addr; + int guest_size; + int memSizeKB; /* number of KB, as reported by int 15h */ }; #endif /* GEEKOS_BOOTINFO_H */ diff --git a/palacios/include/geekos/defs.h b/palacios/include/geekos/defs.h index 5d9bf89..f76f013 100644 --- a/palacios/include/geekos/defs.h +++ b/palacios/include/geekos/defs.h @@ -1,7 +1,7 @@ /* * Misc. kernel definitions * Copyright (c) 2001,2004 David H. Hovemeyer - * $Revision: 1.3 $ + * $Revision: 1.4 $ * * This is free software. You are permitted to use, * redistribute, and modify it as specified in the file "COPYING". @@ -22,8 +22,7 @@ /* - * Address where kernel is loaded INITIALLY - * we move it up in memory soon + * Address where kernel is loaded */ #define KERNEL_START_ADDR 0x10000 @@ -58,85 +57,16 @@ #define PAGE_SIZE (1<IDT_LOCATION) -#error VMM_MAX is too small! -#endif - - -#define KERNEL_THREAD_OBJECT (START_OF_VM+VM_SIZE) -#define KERNEL_STACK (KERNEL_THREAD_OBJECT+KERNEL_THREAD_OBJECT_SIZE) -#define KERNEL_HEAP (KERNEL_STACK+KERNEL_STACK_SIZE) -#define KERNEL_PAGELIST (KERNEL_HEAP+KERNEL_HEAP_SIZE) - - -/* - * PC memory map - */ -#define ISA_HOLE_START 0x0A0000 -#define ISA_HOLE_END 0x100000 #endif /* GEEKOS_DEFS_H */ diff --git a/palacios/include/geekos/mem.h b/palacios/include/geekos/mem.h index fdac1aa..eebbb3f 100644 --- a/palacios/include/geekos/mem.h +++ b/palacios/include/geekos/mem.h @@ -2,7 +2,7 @@ * Physical memory allocation * Copyright (c) 2001,2003,2004 David H. Hovemeyer * Copyright (c) 2003, Jeffrey K. Hollingsworth - * $Revision: 1.1 $ + * $Revision: 1.2 $ * * This is free software. You are permitted to use, * redistribute, and modify it as specified in the file "COPYING". @@ -32,6 +32,20 @@ struct Boot_Info; #define PAGE_VM 0x0080 /* page is used by the VM */ + +#define KERNEL_HEAP_SIZE (512*PAGE_SIZE) + +#define VMM_AVAIL_MEM_SIZE (4096 * PAGE_SIZE) + +/* + * PC memory map + */ +#define ISA_HOLE_START 0x0A0000 +#define ISA_HOLE_END 0x100000 + + + + struct Page; /* diff --git a/palacios/include/geekos/svm.h b/palacios/include/geekos/svm.h index 3854220..84c48dd 100644 --- a/palacios/include/geekos/svm.h +++ b/palacios/include/geekos/svm.h @@ -48,7 +48,7 @@ /******************************************/ -/* SVM Intercep Exit Codes */ +/* SVM Intercept Exit Codes */ /* AMD Arch Vol 3, Appendix C, pg 477-478 */ /******************************************/ #define VMEXIT_CR_READ_MASK 0xfffffff0 diff --git a/palacios/include/geekos/vmm.h b/palacios/include/geekos/vmm.h index 3b0b1e0..8751e02 100644 --- a/palacios/include/geekos/vmm.h +++ b/palacios/include/geekos/vmm.h @@ -89,8 +89,8 @@ struct vmm_os_hooks { void (*print_debug)(const char * format, ...); void (*print_trace)(const char * format, ...); - void *(*Allocate_Pages)(int numPages); - void (*Free_Page)(void * page); + void *(*allocate_pages)(int numPages); + void (*free_page)(void * page); void *(*malloc)(uint_t size); void (*free)(void * addr); diff --git a/palacios/include/geekos/vmm_mem.h b/palacios/include/geekos/vmm_mem.h index 32a254c..75e788c 100644 --- a/palacios/include/geekos/vmm_mem.h +++ b/palacios/include/geekos/vmm_mem.h @@ -5,10 +5,11 @@ #include +typedef unsigned long addr_t; typedef struct mem_region { - ullong_t addr; + addr_t addr; uint_t num_pages; struct mem_region * next; @@ -35,27 +36,25 @@ typedef enum region_type {GUEST, UNMAPPED, SHARED} region_type_t; typedef struct layout_region { - ullong_t addr; + addr_t addr; uint_t num_pages; region_type_t type; - ullong_t host_addr; + addr_t host_addr; struct layout_region * next; struct layout_region * prev; - - } layout_region_t; typedef struct vmm_mem_layout { uint_t num_pages; uint_t num_regions; + + uint_t num_guest_pages; layout_region_t * head; - //layout_region_t * tail; - } vmm_mem_layout_t; @@ -64,21 +63,33 @@ typedef struct vmm_mem_layout { void init_mem_list(vmm_mem_list_t * list); void free_mem_list(vmm_mem_list_t * list); -int add_mem_list_pages(vmm_mem_list_t * list, ullong_t addr, uint_t num_pages); -int remove_mem_list_pages(vmm_mem_list_t * list, ullong_t addr, uint_t num_pages); +int add_mem_list_pages(vmm_mem_list_t * list, addr_t addr, uint_t num_pages); +int remove_mem_list_pages(vmm_mem_list_t * list, addr_t addr, uint_t num_pages); + +mem_region_t * get_mem_list_cursor(vmm_mem_list_t * list, addr_t addr); -mem_region_t * get_mem_list_cursor(vmm_mem_list_t * list, ullong_t addr); +addr_t get_mem_list_addr(vmm_mem_list_t * list, uint_t index); +void print_mem_list(vmm_mem_list_t * list); -void init_mem_laout(vmm_mem_layout_t * layout); +void init_mem_layout(vmm_mem_layout_t * layout); void free_mem_layout(vmm_mem_layout_t * layout); -layout_region_t * get_layout_cursor(vmm_mem_layout_t * layout, ullong_t addr); +layout_region_t * get_layout_cursor(vmm_mem_layout_t * layout, addr_t addr); int add_mem_range(vmm_mem_layout_t * layout, layout_region_t * region); -int add_shared_mem_range(vmm_mem_layout_t * layout, ullong_t addr, uint_t num_pages, ullong_t host_addr); -int add_unmapped_mem_range(vmm_mem_layout_t * layout, ullong_t addr, uint_t num_pages); -int add_guest_mem_range(vmm_mem_layout_t * layout, ullong_t addr, uint_t num_pages); +int add_shared_mem_range(vmm_mem_layout_t * layout, addr_t addr, uint_t num_pages, addr_t host_addr); +int add_unmapped_mem_range(vmm_mem_layout_t * layout, addr_t addr, uint_t num_pages); +int add_guest_mem_range(vmm_mem_layout_t * layout, addr_t addr, uint_t num_pages); + + +addr_t get_mem_layout_addr(vmm_mem_layout_t * list, uint_t index); + +void print_mem_layout(vmm_mem_layout_t * layout); + + + + #endif diff --git a/palacios/include/geekos/vmm_paging.h b/palacios/include/geekos/vmm_paging.h new file mode 100644 index 0000000..5d41452 --- /dev/null +++ b/palacios/include/geekos/vmm_paging.h @@ -0,0 +1,62 @@ +#ifndef __VMM_PAGING_H +#define __VMM_PAGING_H + +#include +#include + + +#include +#include + +#define MAX_PAGE_TABLE_ENTRIES 1024 +#define MAX_PAGE_DIR_ENTRIES 1024 + + +#define PAGE_DIRECTORY_INDEX(x) ((((uint_t)x) >> 22) & 0x3ff) +#define PAGE_TABLE_INDEX(x) ((((uint_t)x) >> 12) & 0x3ff) +#define PAGE_OFFSET(x) ((((uint_t)x) & 0xfff)) + +#define PAGE_ALLIGNED_ADDR(x) (((uint_t) (x)) >> 12) +#define PAGE_ADDR(x) (PAGE_ALLIGNED_ADDR(x) << 12) + +#define PAGE_POWER 12 + +#define VM_WRITE 1 +#define VM_USER 2 +#define VM_NOCACHE 8 +#define VM_READ 0 +#define VM_EXEC 0 + + +typedef struct pde { + uint_t present : 1; + uint_t flags : 4; + uint_t accessed : 1; + uint_t reserved : 1; + uint_t large_pages : 1; + uint_t global_page : 1; + uint_t vmm_info : 3; + uint_t pt_base_addr : 20; +} pde_t; + +typedef struct pte { + uint_t present : 1; + uint_t flags : 4; + uint_t accessed : 1; + uint_t dirty : 1; + uint_t pte_attr : 1; + uint_t global_page : 1; + uint_t vmm_info : 3; + uint_t page_base_addr : 20; +} pte_t; + + +pde_t * generate_guest_page_tables(vmm_mem_layout_t * layout, vmm_mem_list_t * list); + + +void PrintDebugPageTables(pde_t * pde); + + + + +#endif diff --git a/palacios/include/geekos/vmm_sizes.h b/palacios/include/geekos/vmm_sizes.h deleted file mode 100644 index fbaa8d9..0000000 --- a/palacios/include/geekos/vmm_sizes.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __vmm_sizes -#define __vmm_sizes -#define KERNEL_LOAD_ADDRESS 0x2fe9d000 -#define KERNEL_START (KERNEL_LOAD_ADDRESS) -#define KERNEL_CORE_LENGTH ( 204 *512) -#define KERNEL_END (KERNEL_LOAD_ADDRESS+KERNEL_CORE_LENGTH-1) -#define VM_KERNEL_LENGTH ( 97 *512) -#define VM_KERNEL_START (KERNEL_LOAD_ADDRESS + KERNEL_CORE_LENGTH) -#define VM_BOOT_PACKAGE_START (VM_KERNEL_START) -#define VM_BOOT_PACKAGE_END (VM_KERNEL_START+VM_KERNEL_LENGTH-1) -#endif diff --git a/palacios/include/geekos/vmm_util.h b/palacios/include/geekos/vmm_util.h index 402d2c6..ae58b10 100644 --- a/palacios/include/geekos/vmm_util.h +++ b/palacios/include/geekos/vmm_util.h @@ -2,12 +2,12 @@ #define __VMM_UTIL_H #include +#include - - +#ifndef PAGE_SIZE #define PAGE_SIZE 4096 - +#endif typedef union reg_ex { ullong_t r_reg; struct { @@ -38,5 +38,4 @@ void PrintTraceHex(unsigned char x); void PrintTraceMemDump(unsigned char * start, int n); - #endif diff --git a/palacios/src/geekos/defs.asm b/palacios/src/geekos/defs.asm index ff863e2..a3de829 100644 --- a/palacios/src/geekos/defs.asm +++ b/palacios/src/geekos/defs.asm @@ -1,6 +1,6 @@ ; Definitions for use in GeekOS boot code ; Copyright (c) 2001, David H. Hovemeyer -; $Revision: 1.5 $ +; $Revision: 1.6 $ ; This is free software. You are permitted to use, ; redistribute, and modify it as specified in the file "COPYING". @@ -16,9 +16,6 @@ %ifndef DEFS_ASM %define DEFS_ASM -TOP_OF_MEM equ 0x30000000 -VM_SIZE equ 0x20000000 -START_OF_VM equ 0x0 VM_KERNEL_TARGET equ 0x100000 ; BIOS loads the boot sector at offset 0 in this segment @@ -89,7 +86,7 @@ KERNEL_DS equ 2<<3 ; kernel data segment is GDT entry 2 ; the one we construct for Main(). Keep these up to date with defs.h. ; We put them at 1MB, for no particular reason. ;; Moved to just after where the VM will go -KERN_THREAD_OBJ equ (START_OF_VM+VM_SIZE) +KERN_THREAD_OBJ equ 4096 KERN_STACK equ KERN_THREAD_OBJ + 4096 %endif diff --git a/palacios/src/geekos/gdt.c b/palacios/src/geekos/gdt.c index dd0ca5b..3667d46 100644 --- a/palacios/src/geekos/gdt.c +++ b/palacios/src/geekos/gdt.c @@ -1,7 +1,7 @@ /* * Initialize kernel GDT. * Copyright (c) 2001,2004 David H. Hovemeyer - * $Revision: 1.1 $ + * $Revision: 1.2 $ * * This is free software. You are permitted to use, * redistribute, and modify it as specified in the file "COPYING". @@ -32,8 +32,7 @@ extern void Load_GDTR(ushort_t* limitAndBase); /* * This is the kernel's global descriptor table. */ -struct Segment_Descriptor *s_GDT=(struct Segment_Descriptor *)GDT_LOCATION; - +struct Segment_Descriptor s_GDT[NUM_GDT_ENTRIES]; /* * Number of allocated GDT entries. */ @@ -139,7 +138,6 @@ void Init_GDT(void) struct Segment_Descriptor* desc; int i; - Print("GDT Placed at %x, %d entries\n",GDT_LOCATION,NUM_GDT_ENTRIES); KASSERT(sizeof(struct Segment_Descriptor) == 8); diff --git a/palacios/src/geekos/idt.c b/palacios/src/geekos/idt.c index c37a4d1..5b4c823 100644 --- a/palacios/src/geekos/idt.c +++ b/palacios/src/geekos/idt.c @@ -1,7 +1,7 @@ /* * GeekOS IDT initialization code * Copyright (c) 2001, David H. Hovemeyer - * $Revision: 1.2 $ + * $Revision: 1.3 $ * * This is free software. You are permitted to use, * redistribute, and modify it as specified in the file "COPYING". @@ -19,8 +19,8 @@ /* * Allocated */ -//static union IDT_Descriptor s_IDT[ NUM_IDT_ENTRIES ]; -static union IDT_Descriptor *s_IDT = (union IDT_Descriptor *)IDT_LOCATION; +static union IDT_Descriptor s_IDT[ NUM_IDT_ENTRIES ]; +//static union IDT_Descriptor *s_IDT = (union IDT_Descriptor *)IDT_LOCATION; /* diff --git a/palacios/src/geekos/main.c b/palacios/src/geekos/main.c index 734d9e1..3d3ebba 100644 --- a/palacios/src/geekos/main.c +++ b/palacios/src/geekos/main.c @@ -3,7 +3,7 @@ * Copyright (c) 2001,2003,2004 David H. Hovemeyer * Copyright (c) 2003, Jeffrey K. Hollingsworth * Copyright (c) 2004, Iulian Neamtiu - * $Revision: 1.15 $ + * $Revision: 1.16 $ * * This is free software. You are permitted to use, * redistribute, and modify it as specified in the file "COPYING". @@ -33,7 +33,7 @@ #include -#include + #include /* @@ -336,8 +336,8 @@ void Main(struct Boot_Info* bootInfo) os_hooks.print_debug = &PrintBoth; os_hooks.print_info = &Print; os_hooks.print_trace = &SerialPrint; - os_hooks.Allocate_Pages = &Allocate_VMM_Pages; - os_hooks.Free_Page = &Free_VMM_Page; + os_hooks.allocate_pages = &Allocate_VMM_Pages; + os_hooks.free_page = &Free_VMM_Page; os_hooks.malloc = &VMM_Malloc; os_hooks.free = &VMM_Free; @@ -345,6 +345,12 @@ void Main(struct Boot_Info* bootInfo) Init_VMM(&os_hooks, &vmm_ops); + init_mem_layout(&(vm_info.mem_layout)); + init_mem_list(&(vm_info.mem_list)); + + // add_mem_list_pages(&(vm_info.mem_list), START_OF_VM, 20); + //add_guest_mem_range(&(vm_info.mem_layout), 0, 20); + vm_info.rip = (ullong_t)(void*)&BuzzVM; vm_info.rsp = (ulong_t)Alloc_Page(); diff --git a/palacios/src/geekos/mem.c b/palacios/src/geekos/mem.c index b5ae966..5267ee1 100644 --- a/palacios/src/geekos/mem.c +++ b/palacios/src/geekos/mem.c @@ -2,7 +2,7 @@ * Physical memory allocation * Copyright (c) 2001,2003,2004 David H. Hovemeyer * Copyright (c) 2003, Jeffrey K. Hollingsworth - * $Revision: 1.3 $ + * $Revision: 1.4 $ * * This is free software. You are permitted to use, * redistribute, and modify it as specified in the file "COPYING". @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -64,7 +63,7 @@ static void Add_Page_Range(ulong_t start, ulong_t end, int flags) { ulong_t addr; - PrintBoth("Start: %u, End: %u\n", (unsigned int)start, (unsigned int)end); + PrintBoth("Start: %u, End: %u (Type=0x%.4x)\n", (unsigned int)start, (unsigned int)end, flags); KASSERT(Is_Page_Multiple(start)); KASSERT(Is_Page_Multiple(end)); @@ -111,32 +110,19 @@ extern char end; void Init_Mem(struct Boot_Info* bootInfo) { ulong_t numPages = bootInfo->memSizeKB >> 2; - // ulong_t endOfMem = numPages * PAGE_SIZE; + ulong_t endOfMem = numPages * PAGE_SIZE; unsigned numPageListBytes = sizeof(struct Page) * numPages; ulong_t pageListAddr; ulong_t pageListEnd; ulong_t kernEnd; + ulong_t guestEnd; + ulong_t heapAddr; + ulong_t heapEnd; + ulong_t vmmMemEnd; KASSERT(bootInfo->memSizeKB > 0); - if (bootInfo->memSizeKB != TOP_OF_MEM/1024) { - PrintBoth("Kernel compiled for %d KB machine, but machine claims %d KB\n",TOP_OF_MEM/1024,bootInfo->memSizeKB); - if (bootInfo->memSizeKB < TOP_OF_MEM/1024) { - PrintBoth("Kernel compiled for more memory than machine has. Panicking\n"); - KASSERT(0); - } - } - - if (0) { - // if there is not enough memory between START_OF_VM+VM_SIZE and TOP_OF_MEM - // to store the kernel and kernel structures, we need to panick - PrintBoth("Kernel is not compiled with sufficient memory above the VM to support the memory\n"); - KASSERT(0); - } - - - bootInfo->memSizeKB = TOP_OF_MEM / 1024; /* * Before we do anything, switch from setup.asm's temporary GDT @@ -144,141 +130,83 @@ void Init_Mem(struct Boot_Info* bootInfo) */ Init_GDT(); - /* - * We'll put the list of Page objects right after the end - * of the kernel, and mark it as "kernel". This will bootstrap - * us sufficiently that we can start allocating pages and - * keeping track of them. - */ - - // JRL: This is stupid... - // with large mem sizes the page list overruns into the ISA - // hole. By blind luck this causes an unrelated assertion failure, otherwise - // I might never have caught it... - // We fix it by moving the page list after the kernel heap... - // For now we'll make our own stupid assumption that the mem size - // is large enough to accomodate the list in high mem. PrintBoth("Total Memory Size: %u MBytes\n", bootInfo->memSizeKB/1024); - PrintBoth("VM Start: %x\n",START_OF_VM); - PrintBoth("VM End: %x\n",START_OF_VM+VM_SIZE-1); - - - PrintBoth("Page struct size: %lu bytes\n", sizeof(struct Page)); PrintBoth("Page List Size: %u bytes\n", numPageListBytes); - //pageListAddr = Round_Up_To_Page((ulong_t) &end); - //pageListAddr = Round_Up_To_Page(HIGHMEM_START + KERNEL_HEAP_SIZE); + /* Memory Layout: + * bios area (1 page reserved) + * kernel_thread_obj (1 page) + * kernel_stack (1 page) + * available space + * start - end: kernel + * available space + * ISA_HOLE_START - ISA_HOLE_END: hardware + * EXTENDED_MEMORY: + * VM Guest (variable pages) + * Heap (512 Pages) + * Page List (variable pages) + * Available Memory for VMM (4096 pages) + * VM Memory (everything else) + */ - // Note that this is now moved to be just above the kernel heap - // see defs.h for layout - pageListAddr=Round_Up_To_Page(KERNEL_PAGELIST); - - pageListEnd = Round_Up_To_Page(pageListAddr + numPageListBytes); + kernEnd = Round_Up_To_Page((ulong_t)&end); + PrintBoth("Kernel End=%lx\n", kernEnd); + + /* ************************************************************************************** */ + /* If we have dynamic loading of the guest kernel, we should put the relocation code here */ + /* ************************************************************************************** */ + + guestEnd = Round_Up_To_Page(ISA_HOLE_END + bootInfo->guest_size); + heapAddr = guestEnd; + heapEnd = Round_Up_To_Page(heapAddr + KERNEL_HEAP_SIZE); + pageListAddr = heapEnd; + pageListEnd = Round_Up_To_Page(pageListAddr + numPageListBytes); + /* Global variables */ + // These must be set before we can call Add_Page_Range.. g_pageList = (struct Page*) pageListAddr; - // kernEnd = Round_Up_To_Page(pageListAddr + numPageListBytes); - // - // PAD - Note: I am changing this so that everything through the end of - // the VM boot package (bioses/vmxassist) is off limits - //kernEnd = Round_Up_To_Page((ulong_t) &end); - kernEnd = Round_Up_To_Page(VM_BOOT_PACKAGE_END); s_numPages = numPages; + /* ** */ + vmmMemEnd = Round_Up_To_Page(pageListEnd + VMM_AVAIL_MEM_SIZE); - PrintBoth("Pagelist addr: %p\n", g_pageList); - PrintBoth("index: %p\n", &g_pageList[3]); - PrintBoth("direct offset: %p\n", g_pageList + (sizeof(struct Page) * 2)); - // PrintBoth("Kernel Size=%lx\n", (kernEnd - KERNEL_START_ADDR)); - // PrintBoth("Kernel Start=%x\n", KERNEL_START_ADDR); - PrintBoth("Kernel End=%lx\n", kernEnd); - //PrintBoth("end=%x\n", end); - PrintBoth("VM Boot Package Start=%x\n", VM_BOOT_PACKAGE_START); - PrintBoth("VM Boot Package End=%x\n", VM_BOOT_PACKAGE_END); - /* - * The initial kernel thread and its stack are placed - * just beyond the ISA hole. - */ - // This is no longer true - // KASSERT(ISA_HOLE_END == KERN_THREAD_OBJ); - // instead, - //KASSERT(KERN_THREAD_OBJ==(START_OF_VM+VM_SIZE)); - //KASSERT(KERN_STACK == KERN_THREAD_OBJ + PAGE_SIZE); - /* - * Memory looks like this: - * 0 - start: available (might want to preserve BIOS data area) - * start - end: kernel - * end - ISA_HOLE_START: available - * ISA_HOLE_START - ISA_HOLE_END: used by hardware (and ROM BIOS?) - * ISA_HOLE_END - HIGHMEM_START: used by initial kernel thread - * HIGHMEM_START - end of memory: available - * (the kernel heap is located at HIGHMEM_START; any unused memory - * beyond that is added to the freelist) - */ - // The VM region... 0 .. VM size is out of bounds - KASSERT(START_OF_VM==0); - - Add_Page_Range(START_OF_VM, START_OF_VM+VM_SIZE, PAGE_VM); - //PrintBoth("hello1\n"); - // The kernel is still in low memory at this point, in the VM region - // Thus we will mark it as kernel use - // Add_Page_Range(KERNEL_START_ADDR, kernEnd, PAGE_KERN); - - - //Add_Page_Range(kernEnd, ISA_HOLE_START, PAGE_AVAIL); - // ISA hole remains closed (no actual memory) - // Add_Page_Range(ISA_HOLE_START, ISA_HOLE_END, PAGE_HW); - - //Add_Page_Range(ISA_HOLE_END, HIGHMEM_START, PAGE_ALLOCATED); - // Add_Page_Range(HIGHMEM_START, HIGHMEM_START + KERNEL_HEAP_SIZE, PAGE_HEAP); - //Add_Page_Range(HIGHMEM_START + KERNEL_HEAP_SIZE, endOfMem, PAGE_AVAIL); - /* JRL: move page list after kernel heap */ - - //Now, above the VM region... - - // Kernel thread object - Add_Page_Range(KERNEL_THREAD_OBJECT,KERNEL_THREAD_OBJECT+KERNEL_THREAD_OBJECT_SIZE,PAGE_ALLOCATED); - // Kernel stack - Add_Page_Range(KERNEL_STACK,KERNEL_STACK+KERNEL_STACK_SIZE,PAGE_ALLOCATED); - // Kernel heap - Add_Page_Range(KERNEL_HEAP,KERNEL_HEAP+KERNEL_HEAP_SIZE,PAGE_HEAP); - // Kernel page list - Add_Page_Range(pageListAddr, pageListEnd, PAGE_KERN); - // Free space - Add_Page_Range(pageListEnd,Round_Down_To_Page(FINAL_KERNEL_START), PAGE_AVAIL); - // The kernel - Add_Page_Range(Round_Down_To_Page(FINAL_KERNEL_START),Round_Up_To_Page(FINAL_VMBOOTEND+1),PAGE_KERN); - // The vmbootpackage - // IDT (this should be one page) - Add_Page_Range(IDT_LOCATION,TSS_LOCATION,PAGE_KERN); - // TSS (this should be one page) - Add_Page_Range(TSS_LOCATION,GDT_LOCATION, PAGE_KERN); - // GDT (this should be one page) - Add_Page_Range(GDT_LOCATION,TOP_OF_MEM, PAGE_KERN); + Add_Page_Range(0, PAGE_SIZE, PAGE_UNUSED); // BIOS area + Add_Page_Range(PAGE_SIZE, PAGE_SIZE * 3, PAGE_ALLOCATED); // Intial kernel thread obj + stack + Add_Page_Range(PAGE_SIZE * 3, KERNEL_START_ADDR, PAGE_AVAIL); // Available space + Add_Page_Range(KERNEL_START_ADDR, kernEnd, PAGE_KERN); // VMM Kernel + Add_Page_Range(kernEnd, ISA_HOLE_START, PAGE_AVAIL); // Available Space + Add_Page_Range(ISA_HOLE_START, ISA_HOLE_END, PAGE_HW); // Hardware ROMs + Add_Page_Range(ISA_HOLE_END, guestEnd, PAGE_VM); // Guest kernel location + Add_Page_Range(heapAddr, heapEnd, PAGE_HEAP); // Heap + Add_Page_Range(pageListAddr, pageListEnd, PAGE_KERN); // Page List + Add_Page_Range(pageListEnd, vmmMemEnd, PAGE_AVAIL); // Available VMM memory + Add_Page_Range(vmmMemEnd, endOfMem, PAGE_VM); // Memory allocated to the VM + + /* Initialize the kernel heap */ - Init_Heap(KERNEL_HEAP, KERNEL_HEAP_SIZE); + Init_Heap(heapAddr, KERNEL_HEAP_SIZE); PrintBoth("%uKB memory detected, %u pages in freelist, %d bytes in kernel heap\n", bootInfo->memSizeKB, g_freePageCount, KERNEL_HEAP_SIZE); PrintBoth("Memory Layout:\n"); - PrintBoth("%x to %x - VM\n",START_OF_VM,START_OF_VM+VM_SIZE-1); - PrintBoth("%x to %x - INITIAL THREAD\n",KERNEL_THREAD_OBJECT,KERNEL_THREAD_OBJECT+KERNEL_THREAD_OBJECT_SIZE-1); - PrintBoth("%x to %x - KERNEL STACK\n",KERNEL_STACK,KERNEL_STACK+KERNEL_STACK_SIZE-1); - PrintBoth("%x to %x - KERNEL HEAP\n",KERNEL_HEAP,KERNEL_HEAP+KERNEL_HEAP_SIZE-1); - PrintBoth("%lx to %lx - PAGE LIST\n",pageListAddr,pageListEnd-1); - PrintBoth("%lx to %x - FREE\n",pageListEnd,FINAL_KERNEL_START-1); - PrintBoth("%x to %x - KERNEL CODE\n",FINAL_KERNEL_START,FINAL_KERNEL_END); - PrintBoth("%x to %x - VM_KERNEL\n", FINAL_VM_KERNEL_START, FINAL_VM_KERNEL_END); - PrintBoth("%x to %x - IDT\n",IDT_LOCATION,TSS_LOCATION-1); - PrintBoth("%x to %x - TSS\n",TSS_LOCATION,GDT_LOCATION-1); - PrintBoth("%x to %x - GDT\n",GDT_LOCATION,TOP_OF_MEM-1); - - + PrintBoth("%x to %x - BIOS AREA\n", 0, PAGE_SIZE - 1); + PrintBoth("%x to %x - KERNEL_THREAD_OBJ\n", PAGE_SIZE, PAGE_SIZE * 2 - 1); + PrintBoth("%x to %x - KERNEL_STACK\n", PAGE_SIZE * 2, PAGE_SIZE * 3 - 1); + PrintBoth("%lx to %x - FREE\n", PAGE_SIZE * 3, KERNEL_START_ADDR - 1); + PrintBoth("%x to %x - KERNEL CODE\n", KERNEL_START_ADDR, kernEnd - 1); + PrintBoth("%lx to %x - FREE\n", kernEnd, ISA_HOLE_START - 1); + PrintBoth("%x to %x - ISA_HOLE\n", ISA_HOLE_START, ISA_HOLE_END - 1); + PrintBoth("%x to %x - VM_KERNEL\n", ISA_HOLE_END, guestEnd - 1); + PrintBoth("%x to %x - KERNEL HEAP\n", heapAddr, heapEnd - 1); + PrintBoth("%lx to %lx - PAGE LIST\n", pageListAddr, pageListEnd - 1); + PrintBoth("%lx to %x - FREE\n", pageListEnd, vmmMemEnd - 1); + PrintBoth("%lx to %x - GUEST_MEMORY\n", vmmMemEnd, endOfMem - 1); } /* diff --git a/palacios/src/geekos/setup.asm b/palacios/src/geekos/setup.asm index 56c9938..d49a373 100644 --- a/palacios/src/geekos/setup.asm +++ b/palacios/src/geekos/setup.asm @@ -1,7 +1,7 @@ ; -*- fundamental -*- ; GeekOS setup code ; Copyright (c) 2001,2004 David H. Hovemeyer -; $Revision: 1.1 $ +; $Revision: 1.2 $ ; This is free software. You are permitted to use, ; redistribute, and modify it as specified in the file "COPYING". @@ -87,6 +87,16 @@ setup_32: shl ebx, 6 add eax, ebx push eax ; memSizeKB + + mov eax, GUEST_SIZE + push eax ; Size of the guest kernel + + mov eax, 0x100000 + push eax ; Load address of the guest + + mov eax, VMM_SIZE + push eax ; size of the VMM + push dword 8 ; bootInfoSize ; Pass pointer to Boot_Info struct as argument to kernel @@ -98,9 +108,6 @@ setup_32: push dword (SETUPSEG<<4)+.returnAddr - ; Copy VMM kernel and VMM Boot Package to final location - call copy_vmm - ; Far jump into kernel jmp KERNEL_CS:ENTRY_POINT @@ -109,24 +116,6 @@ setup_32: .here: jmp .here -copy_vmm: - pusha - - mov ebx, KERNSEG<<4 - mov ecx, VMM_FINAL_ADDR - mov edx, VMM_SIZE -repeat: - mov eax, [ebx] - mov [ecx], eax - add ebx, $4 - add ecx, $4 - sub edx, $4 - jnz repeat - - popa - - ret - [BITS 16] diff --git a/palacios/src/geekos/show_sizes.c b/palacios/src/geekos/show_sizes.c deleted file mode 100644 index c75d119..0000000 --- a/palacios/src/geekos/show_sizes.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include "vmm_sizes.h" - -int main() -{ - printf("KERNEL_LOAD_ADDRESS = 0x%x\n", KERNEL_LOAD_ADDRESS); - printf("KERNEL_SETUP_LENGTH = 0x%x\n", KERNEL_SETUP_LENGTH); - printf("KERNEL_CORE_LENGTH = 0x%x\n", KERNEL_CORE_LENGTH); - printf("BIOS_START = 0x%x\n", BIOS_START); - printf("BIOS_LENGTH = 0x%x\n", BIOS_LENGTH); - printf("BIOS2_START = 0x%x\n", BIOS2_START); - printf("VGA_BIOS_START = 0x%x\n", VGA_BIOS_START); - printf("VGA_BIOS_LENGTH = 0x%x\n", VGA_BIOS_LENGTH); - printf("VMXASSIST_START = 0x%x\n", VMXASSIST_START); - printf("VMXASSIST_LENGTH = 0x%x\n", VMXASSIST_LENGTH); - printf("\n"); - printf("KERNEL_START = 0x%x\n", KERNEL_START); - printf("KERNEL_END = 0x%x\n", KERNEL_END); - printf("VM_BOOT_PACKAGE_START = 0x%x\n", VM_BOOT_PACKAGE_START); - printf("VM_BOOT_PACKAGE_END = 0x%x\n", VM_BOOT_PACKAGE_END); - - - return 0; - -} diff --git a/palacios/src/geekos/svm.c b/palacios/src/geekos/svm.c index 9f30c49..4ba49b2 100644 --- a/palacios/src/geekos/svm.c +++ b/palacios/src/geekos/svm.c @@ -2,6 +2,9 @@ #include #include +#include +#include + extern struct vmm_os_hooks * os_hooks; @@ -57,7 +60,7 @@ void Init_SVM(struct vmm_ctrl_ops * vmm_ops) { // Setup the host state save area - host_state = os_hooks->Allocate_Pages(1); + host_state = os_hooks->allocate_pages(1); msr.e_reg.high = 0; msr.e_reg.low = (uint_t)host_state; @@ -78,12 +81,25 @@ void Init_SVM(struct vmm_ctrl_ops * vmm_ops) { int init_svm_guest(struct guest_info *info) { + pde_t * pde; + PrintDebug("Allocating VMCB\n"); info->vmm_data = (void*)Allocate_VMCB(); + + PrintDebug("Generating Guest nested page tables\n"); + print_mem_list(&(info->mem_list)); + print_mem_layout(&(info->mem_layout)); + pde = generate_guest_page_tables(&(info->mem_layout), &(info->mem_list)); + PrintDebugPageTables(pde); + + PrintDebug("Initializing VMCB (addr=%x)\n", info->vmm_data); Init_VMCB((vmcb_t*)(info->vmm_data), *info); + + + return 0; } @@ -124,7 +140,7 @@ int handle_svm_exit(struct VMM_GPRs guest_gprs) { vmcb_t * Allocate_VMCB() { - vmcb_t * vmcb_page = (vmcb_t*)os_hooks->Allocate_Pages(1); + vmcb_t * vmcb_page = (vmcb_t*)os_hooks->allocate_pages(1); memset(vmcb_page, 0, 4096); @@ -181,3 +197,5 @@ void Init_VMCB(vmcb_t *vmcb, guest_info_t vm_info) { /* ** */ } + + diff --git a/palacios/src/geekos/tss.c b/palacios/src/geekos/tss.c index 6936711..350cb98 100644 --- a/palacios/src/geekos/tss.c +++ b/palacios/src/geekos/tss.c @@ -1,7 +1,7 @@ /* * x86 TSS data structure and routines * Copyright (c) 2001,2004 David H. Hovemeyer - * $Revision: 1.2 $ + * $Revision: 1.3 $ * * This is free software. You are permitted to use, * redistribute, and modify it as specified in the file "COPYING". @@ -26,8 +26,7 @@ /* * We use one TSS in GeekOS. */ -//static struct TSS s_theTSS; -static struct TSS *s_theTSS = (struct TSS *) TSS_LOCATION; +static struct TSS s_theTSS; static struct Segment_Descriptor *s_tssDesc; static ushort_t s_tssSelector; @@ -56,8 +55,8 @@ void Init_TSS(void) s_tssDesc = Allocate_Segment_Descriptor(); KASSERT(s_tssDesc != 0); - memset(s_theTSS, '\0', sizeof(struct TSS)); - Init_TSS_Descriptor(s_tssDesc, s_theTSS); + memset(&s_theTSS, '\0', sizeof(struct TSS)); + Init_TSS_Descriptor(s_tssDesc, &s_theTSS); s_tssSelector = Selector(0, true, Get_Descriptor_Index(s_tssDesc)); @@ -72,8 +71,8 @@ void Init_TSS(void) */ void Set_Kernel_Stack_Pointer(ulong_t esp0) { - s_theTSS->ss0 = KERNEL_DS; - s_theTSS->esp0 = esp0; + s_theTSS.ss0 = KERNEL_DS; + s_theTSS.esp0 = esp0; /* * NOTE: I read on alt.os.development that it is necessary to diff --git a/palacios/src/geekos/vmm_mem.c b/palacios/src/geekos/vmm_mem.c index bba8333..b2721eb 100644 --- a/palacios/src/geekos/vmm_mem.c +++ b/palacios/src/geekos/vmm_mem.c @@ -38,17 +38,17 @@ void free_mem_list(vmm_mem_list_t * list) { // Then we clean up any region following the new region that overlaps // // JRL: This is pretty hairy... -int add_mem_list_pages(vmm_mem_list_t * list, ullong_t addr, uint_t num_pages) { +int add_mem_list_pages(vmm_mem_list_t * list, addr_t addr, uint_t num_pages) { uint_t num_new_pages = num_pages; - ullong_t new_end = addr + (num_pages * PAGE_SIZE); + addr_t new_end = addr + (num_pages * PAGE_SIZE) - 1; mem_region_t * cursor = get_mem_list_cursor(list, addr); - // PrintDebug("Adding: 0x%x - 0x%x\n", addr, num_pages * PAGE_SIZE); + // Make a new region at the head of the list if (cursor == NULL) { cursor = os_hooks->malloc(sizeof(mem_region_t)); @@ -66,9 +66,9 @@ int add_mem_list_pages(vmm_mem_list_t * list, ullong_t addr, uint_t num_pages) { list->num_regions++; } else { - ullong_t cursor_end = cursor->addr + (cursor->num_pages * PAGE_SIZE); + addr_t cursor_end = cursor->addr + (cursor->num_pages * PAGE_SIZE) - 1; - if (addr > cursor_end) { + if (addr > cursor_end + 1) { // address falls after cursor region mem_region_t * new_region = os_hooks->malloc(sizeof(mem_region_t)); @@ -88,7 +88,7 @@ int add_mem_list_pages(vmm_mem_list_t * list, ullong_t addr, uint_t num_pages) { cursor = new_region; } else if ((addr >= cursor->addr) && - (addr <= cursor_end)) { + (addr <= cursor_end + 1)) { // address falls inside the cursor region @@ -103,11 +103,12 @@ int add_mem_list_pages(vmm_mem_list_t * list, ullong_t addr, uint_t num_pages) { } } + // Clean up any overlaps that follow - while ((cursor->next) && (cursor->next->addr <= new_end)) { + while ((cursor->next) && (cursor->next->addr <= new_end + 1)) { mem_region_t * overlap = cursor->next; - ullong_t overlap_end = overlap->addr + (overlap->num_pages * PAGE_SIZE); + addr_t overlap_end = overlap->addr + (overlap->num_pages * PAGE_SIZE) - 1; cursor->next = overlap->next; if (overlap->next) { @@ -143,17 +144,17 @@ int add_mem_list_pages(vmm_mem_list_t * list, ullong_t addr, uint_t num_pages) { * IF addr is before all regions, returns NULL * IF list is empty, returns NULL */ -mem_region_t * get_mem_list_cursor(vmm_mem_list_t * list, ullong_t addr) { +mem_region_t * get_mem_list_cursor(vmm_mem_list_t * list, addr_t addr) { mem_region_t * prev_region = list->head; while (prev_region != NULL) { if ( (addr >= prev_region->addr) && - (addr <= (prev_region->addr + (prev_region->num_pages * PAGE_SIZE))) ) { + (addr < (prev_region->addr + (prev_region->num_pages * PAGE_SIZE) - 1)) ) { return prev_region; } else if (addr < prev_region->addr) { // If this region is the current head, then this should return NULL return prev_region->prev; - } else if (addr > (prev_region->addr + (prev_region->num_pages * PAGE_SIZE))) { + } else if (addr >= (prev_region->addr + (prev_region->num_pages * PAGE_SIZE))) { if (prev_region->next) { prev_region = prev_region->next; } else { @@ -167,6 +168,31 @@ mem_region_t * get_mem_list_cursor(vmm_mem_list_t * list, ullong_t addr) { +/* Returns the page address of page number 'index' in the memory list + * If index is out of bounds... returns -1 (an invalid page address) + */ +addr_t get_mem_list_addr(vmm_mem_list_t * list, uint_t index) { + mem_region_t * reg = list->head; + uint_t i = index; + + // Memory List overrun + if (index > list->num_pages - 1) { + return -1; + } + + while (i >= 0) { + if (reg->num_pages <= index) { + i -= reg->num_pages; + reg = reg->next; + } else { + return reg->addr + (i * PAGE_SIZE); + } + } + + return -1; +} + + void init_mem_layout(vmm_mem_layout_t * layout) { layout->num_pages = 0; layout->num_regions = 0; @@ -198,18 +224,18 @@ void free_mem_layout(vmm_mem_layout_t * layout) { * IF addr is before all regions, returns NULL * IF list is empty, returns NULL */ -layout_region_t * get_layout_cursor(vmm_mem_layout_t * layout, ullong_t addr) { +layout_region_t * get_layout_cursor(vmm_mem_layout_t * layout, addr_t addr) { layout_region_t * prev_region = layout->head; while (prev_region != NULL) { if ( (addr >= prev_region->addr) && - (addr <= (prev_region->addr + (prev_region->num_pages * PAGE_SIZE))) ) { + (addr < (prev_region->addr + (prev_region->num_pages * PAGE_SIZE))) ) { return prev_region; } else if (addr < prev_region->addr) { // If this region is the current head, then this should return NULL return prev_region->prev; - } else if (addr > (prev_region->addr + (prev_region->num_pages * PAGE_SIZE))) { + } else if (addr >= (prev_region->addr + (prev_region->num_pages * PAGE_SIZE))) { if (prev_region->next) { prev_region = prev_region->next; } else { @@ -231,7 +257,7 @@ int add_mem_range(vmm_mem_layout_t * layout, layout_region_t * region) { if (cursor == NULL) { if (layout->head) { - if (layout->head->addr < region->addr + (region->num_pages * PAGE_SIZE)) { + if (layout->head->addr < region->addr + (region->num_pages * PAGE_SIZE) - 1) { // overlaps not allowed return -1; } @@ -245,10 +271,10 @@ int add_mem_range(vmm_mem_layout_t * layout, layout_region_t * region) { layout->num_regions++; layout->num_pages += region->num_pages; } else if ((region->addr >= cursor->addr) && - (region->addr <= cursor->addr + (cursor->num_pages * PAGE_SIZE))) { + (region->addr <= cursor->addr + (cursor->num_pages * PAGE_SIZE) - 1)) { // overlaps not allowed return -1; - } else if (region->addr > cursor->addr + (cursor->num_pages * PAGE_SIZE)) { + } else if (region->addr > cursor->addr + (cursor->num_pages * PAGE_SIZE) - 1) { // add region to layout region->next = cursor->next; region->prev = cursor; @@ -272,8 +298,9 @@ int add_mem_range(vmm_mem_layout_t * layout, layout_region_t * region) { -int add_shared_mem_range(vmm_mem_layout_t * layout, ullong_t addr, uint_t num_pages, ullong_t host_addr) { +int add_shared_mem_range(vmm_mem_layout_t * layout, addr_t addr, uint_t num_pages, addr_t host_addr) { layout_region_t * shared_region = os_hooks->malloc(sizeof(layout_region_t)); + int ret; shared_region->next = NULL; shared_region->prev = NULL; @@ -282,12 +309,19 @@ int add_shared_mem_range(vmm_mem_layout_t * layout, ullong_t addr, uint_t num_pa shared_region->type = SHARED; shared_region->host_addr = host_addr; - return add_mem_range(layout, shared_region); + ret = add_mem_range(layout, shared_region); + + if (ret != 0) { + VMMFree(shared_region); + } + + return ret; } -int add_unmapped_mem_range(vmm_mem_layout_t * layout, ullong_t addr, uint_t num_pages) { +int add_unmapped_mem_range(vmm_mem_layout_t * layout, addr_t addr, uint_t num_pages) { layout_region_t * unmapped_region = os_hooks->malloc(sizeof(layout_region_t)); - + int ret; + unmapped_region->next = NULL; unmapped_region->prev = NULL; unmapped_region->addr = addr; @@ -295,11 +329,18 @@ int add_unmapped_mem_range(vmm_mem_layout_t * layout, ullong_t addr, uint_t num_ unmapped_region->type = UNMAPPED; unmapped_region->host_addr = 0; - return add_mem_range(layout, unmapped_region); + ret = add_mem_range(layout, unmapped_region); + + if (ret != 0) { + VMMFree(unmapped_region); + } + + return ret; } -int add_guest_mem_range(vmm_mem_layout_t * layout, ullong_t addr, uint_t num_pages) { +int add_guest_mem_range(vmm_mem_layout_t * layout, addr_t addr, uint_t num_pages) { layout_region_t * guest_region = os_hooks->malloc(sizeof(layout_region_t)); + int ret; guest_region->next = NULL; guest_region->prev = NULL; @@ -308,11 +349,48 @@ int add_guest_mem_range(vmm_mem_layout_t * layout, ullong_t addr, uint_t num_pag guest_region->type = GUEST; guest_region->host_addr = 0; - return add_mem_range(layout, guest_region); + ret = add_mem_range(layout, guest_region); + + if (ret == 0) { + layout->num_guest_pages += num_pages; + } else { + VMMFree(guest_region); + } + + return ret; } +/* Returns the page address of page number 'index' in the memory list + * If index is out of bounds... returns -1 (an invalid page address) + */ +addr_t get_mem_layout_addr(vmm_mem_layout_t * layout, uint_t index) { + layout_region_t * reg = layout->head; + uint_t i = index; + + // Memory List overrun + if (index > layout->num_pages - 1) { + return -1; + } + + while (i >= 0) { + if (!reg) { + return -1; + } + + if (reg->num_pages <= index) { + i -= reg->num_pages; + reg = reg->next; + } else { + return reg->addr + (i * PAGE_SIZE); + } + } + + return -1; +} + + void print_mem_list(vmm_mem_list_t * list) { @@ -322,7 +400,7 @@ void print_mem_list(vmm_mem_list_t * list) { PrintDebug("Memory Region List (regions: %d) (pages: %d)\n", list->num_regions, list->num_pages); while (cur) { - PrintDebug("%d: 0x%x - 0x%x\n", i, cur->addr, cur->addr + (cur->num_pages * PAGE_SIZE)); + PrintDebug("%d: 0x%x - 0x%x\n", i, cur->addr, cur->addr + (cur->num_pages * PAGE_SIZE) - 1); cur = cur->next; i++; } @@ -338,7 +416,7 @@ void print_mem_layout(vmm_mem_layout_t * layout) { PrintDebug("Memory Layout (regions: %d) (pages: %d)\n", layout->num_regions, layout->num_pages); while (cur) { - PrintDebug("%d: 0x%x - 0x%x\n", i, cur->addr, cur->addr + (cur->num_pages * PAGE_SIZE)); + PrintDebug("%d: 0x%x - 0x%x\n", i, cur->addr, cur->addr + (cur->num_pages * PAGE_SIZE) - 1); cur = cur->next; i++; } @@ -347,11 +425,23 @@ void print_mem_layout(vmm_mem_layout_t * layout) { + + + + + + + + + #ifdef VMM_MEM_TEST + + #include #include #include +#include @@ -361,6 +451,11 @@ void * TestMalloc(uint_t size) { return malloc(size); } +void * TestAllocatePages(int size) { + return malloc(4096 * size); +} + + void TestPrint(const char * fmt, ...) { va_list args; @@ -369,65 +464,92 @@ void TestPrint(const char * fmt, ...) { va_end(args); } -int mem_list_add_test_1() { - vmm_mem_list_t list; +int mem_list_add_test_1( vmm_mem_list_t * list) { + uint_t offset = 0; - init_mem_list(&list); + PrintDebug("\n\nTesting Memory List\n"); + + init_mem_list(list); offset = PAGE_SIZE * 6; PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 10)); - add_mem_list_pages(&list, PAGE_SIZE * 6, 10); - print_mem_list(&list); + add_mem_list_pages(list, offset, 10); + print_mem_list(list); offset = 0; PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + PAGE_SIZE * 4); - add_mem_list_pages(&list, 0, 4); - print_mem_list(&list); + add_mem_list_pages(list, offset, 4); + print_mem_list(list); offset = PAGE_SIZE * 20; PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 1)); - add_mem_list_pages(&list, PAGE_SIZE * 20, 1); - print_mem_list(&list); + add_mem_list_pages(list, offset, 1); + print_mem_list(list); + + offset = PAGE_SIZE * 21; + PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 3)); + add_mem_list_pages(list, offset, 3); + print_mem_list(list); offset = PAGE_SIZE * 10; PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 30)); - add_mem_list_pages(&list, PAGE_SIZE * 10, 30); - print_mem_list(&list); + add_mem_list_pages(list, offset, 30); + print_mem_list(list); + + + offset = PAGE_SIZE * 5; + PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 1)); + add_mem_list_pages(list, offset, 1); + print_mem_list(list); + + return 0; } -int mem_layout_add_test_1() { - vmm_mem_layout_t layout; +int mem_layout_add_test_1(vmm_mem_layout_t *layout) { + uint_t offset = 0; - init_mem_layout(&layout); + PrintDebug("\n\nTesting Memory Layout\n"); + + init_mem_layout(layout); offset = PAGE_SIZE * 6; PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 10)); - add_guest_mem_range(&layout, PAGE_SIZE * 6, 10); - print_mem_layout(&layout); + add_guest_mem_range(layout, offset, 10); + print_mem_layout(layout); - offset = 0; - PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + PAGE_SIZE * 4); - add_guest_mem_range(&layout, 0, 4); - print_mem_layout(&layout); - offset = PAGE_SIZE * 20; PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 1)); - add_guest_mem_range(&layout, PAGE_SIZE * 20, 1); - print_mem_layout(&layout); + add_guest_mem_range(layout, offset, 1); + print_mem_layout(layout); + + + offset = PAGE_SIZE * 16; + PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + PAGE_SIZE * 4); + add_guest_mem_range(layout, offset, 4); + print_mem_layout(layout); offset = PAGE_SIZE * 10; PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 30)); - add_guest_mem_range(&layout, PAGE_SIZE * 10, 30); - print_mem_layout(&layout); + add_guest_mem_range(layout, offset, 30); + print_mem_layout(layout); + + + offset = 0; + PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 1)); + add_guest_mem_range(layout, offset, 1); + print_mem_layout(layout); + + + return 0; } @@ -438,14 +560,29 @@ int main(int argc, char ** argv) { struct vmm_os_hooks dummy_hooks; os_hooks = &dummy_hooks; + vmm_mem_layout_t layout; + vmm_mem_list_t list; + os_hooks->malloc = &TestMalloc; os_hooks->free = &free; os_hooks->print_debug = &TestPrint; + os_hooks->allocate_pages = &TestAllocatePages; + - printf("mem_list_add_test_1: %d\n", mem_list_add_test_1()); - printf("layout_add_test_t: %d\n", mem_layout_add_test_1()); + printf("mem_list_add_test_1: %d\n", mem_list_add_test_1(&list)); + printf("layout_add_test_1: %d\n", mem_layout_add_test_1(&layout)); + + + pde_t * pde = generate_guest_page_tables(&layout, &list); + PrintDebugPageTables(pde); return 0; } #endif + + + + + + diff --git a/palacios/src/geekos/vmm_paging.c b/palacios/src/geekos/vmm_paging.c new file mode 100644 index 0000000..81719a4 --- /dev/null +++ b/palacios/src/geekos/vmm_paging.c @@ -0,0 +1,187 @@ +#include + + + + + +extern struct vmm_os_hooks * os_hooks; + + + + +/* We generate a page table to correspond to a given memory layout + * pulling pages from the mem_list when necessary + * If there are any gaps in the layout, we add them as unmapped pages + */ +pde_t * generate_guest_page_tables(vmm_mem_layout_t * layout, vmm_mem_list_t * list) { + ullong_t current_page_addr = 0; + uint_t layout_index = 0; + uint_t list_index = 0; + ullong_t layout_addr = 0; + int i, j; + uint_t num_entries = layout->num_pages; // The number of pages left in the layout + + + + + pde_t * pde = os_hooks->allocate_pages(1); + + for (i = 0; i < MAX_PAGE_DIR_ENTRIES; i++) { + if (num_entries == 0) { + pde[i].present = 0; + pde[i].flags = 0; + pde[i].accessed = 0; + pde[i].reserved = 0; + pde[i].large_pages = 0; + pde[i].global_page = 0; + pde[i].vmm_info = 0; + pde[i].pt_base_addr = 0; + } else { + pte_t * pte = os_hooks->allocate_pages(1); + + pde[i].present = 1; + pde[i].flags = VM_READ | VM_WRITE | VM_EXEC | VM_USER; + pde[i].accessed = 0; + pde[i].reserved = 0; + pde[i].large_pages = 0; + pde[i].global_page = 0; + pde[i].vmm_info = 0; + pde[i].pt_base_addr = PAGE_ALLIGNED_ADDR(pte); + + + + for (j = 0; j < MAX_PAGE_TABLE_ENTRIES; j++) { + layout_addr = get_mem_layout_addr(layout, layout_index); + + if ((current_page_addr < layout_addr) || (num_entries == 0)) { + // We have a gap in the layout, fill with unmapped page + pte[j].present = 0; + pte[j].flags = 0; + pte[j].accessed = 0; + pte[j].dirty = 0; + pte[j].pte_attr = 0; + pte[j].global_page = 0; + pte[j].vmm_info = 0; + pte[j].page_base_addr = 0; + + current_page_addr += PAGE_SIZE; + } else if (current_page_addr == layout_addr) { + // Set up the Table entry to map correctly to the layout region + layout_region_t * page_region = get_layout_cursor(layout, layout_addr); + + if (page_region->type == UNMAPPED) { + pte[j].present = 0; + pte[j].flags = 0; + } else { + pte[j].present = 1; + pte[j].flags = VM_READ | VM_WRITE | VM_EXEC | VM_USER; + } + + pte[j].accessed = 0; + pte[j].dirty = 0; + pte[j].pte_attr = 0; + pte[j].global_page = 0; + pte[j].vmm_info = 0; + + if (page_region->type == UNMAPPED) { + pte[j].page_base_addr = 0; + } else if (page_region->type == SHARED) { + pte[j].page_base_addr = page_region->host_addr >> 12; + } else if (page_region->type == GUEST) { + addr_t list_addr = get_mem_list_addr(list, list_index++); + + if (list_addr == -1) { + // error + // cleanup.... + return NULL; + } + PrintDebug("Adding guest page (%x)\n", list_addr); + pte[j].page_base_addr = list_addr >> 12; + } + + num_entries--; + current_page_addr += PAGE_SIZE; + layout_index++; + } else { + // error + PrintDebug("Error creating page table...\n"); + // cleanup + return NULL; + } + } + } + } + + return pde; +} + + + + +void PrintPDE(void * virtual_address, pde_t * pde) +{ + PrintDebug("PDE %p -> %p : present=%x, flags=%x, accessed=%x, reserved=%x, largePages=%x, globalPage=%x, kernelInfo=%x\n", + virtual_address, + (void *) (pde->pt_base_addr << PAGE_POWER), + pde->present, + pde->flags, + pde->accessed, + pde->reserved, + pde->large_pages, + pde->global_page, + pde->vmm_info); +} + +void PrintPTE(void * virtual_address, pte_t * pte) +{ + PrintDebug("PTE %p -> %p : present=%x, flags=%x, accessed=%x, dirty=%x, pteAttribute=%x, globalPage=%x, vmm_info=%x\n", + virtual_address, + (void*)(pte->page_base_addr << PAGE_POWER), + pte->present, + pte->flags, + pte->accessed, + pte->dirty, + pte->pte_attr, + pte->global_page, + pte->vmm_info); +} + + + +void PrintPD(pde_t * pde) +{ + int i; + + PrintDebug("Page Directory at %p:\n", pde); + for (i = 0; (i < MAX_PAGE_DIR_ENTRIES) && pde[i].present; i++) { + PrintPDE((void*)(PAGE_SIZE * MAX_PAGE_TABLE_ENTRIES * i), &(pde[i])); + } +} + +void PrintPT(void * starting_address, pte_t * pte) +{ + int i; + + // PrintDebug("Page Table at %p:\n", pte); + for (i = 0; (i < MAX_PAGE_TABLE_ENTRIES) && pte[i].present; i++) { + PrintPTE(starting_address + (PAGE_SIZE * i), &(pte[i])); + } +} + + + + + +void PrintDebugPageTables(pde_t * pde) +{ + int i; + + PrintDebug("Dumping the pages starting with the pde page at %p\n", pde); + + for (i = 0; (i < MAX_PAGE_DIR_ENTRIES) && pde[i].present; i++) { + PrintPDE((void *)(PAGE_SIZE * MAX_PAGE_TABLE_ENTRIES * i), &(pde[i])); + PrintPT((void *)(PAGE_SIZE * MAX_PAGE_TABLE_ENTRIES * i), (void *)(pde[i].pt_base_addr << PAGE_POWER)); + } +} + + diff --git a/palacios/src/geekos/vmm_util.c b/palacios/src/geekos/vmm_util.c index 2583c39..4aa4d34 100644 --- a/palacios/src/geekos/vmm_util.c +++ b/palacios/src/geekos/vmm_util.c @@ -1,10 +1,13 @@ #include +extern struct vmm_os_hooks * os_hooks; + + void PrintTraceHex(unsigned char x) { unsigned char z; - z = (x>>4) & 0xf ; + z = (x >> 4) & 0xf ; PrintTrace("%x", z); z = x & 0xf; PrintTrace("%x", z); @@ -15,19 +18,22 @@ void PrintTraceMemDump(unsigned char *start, int n) { int i, j; - for (i=0;i=32) && (start[j]<=126)) ? start[j] : '.'); + for (j = i; (j < (i + 16)) && (j < n); j++) { + PrintTrace("%c", ((start[j] >= 32) && (start[j] <= 126)) ? start[j] : '.'); } PrintTrace("\n"); } } + + +