# Makefile for GeekOS kernel, userspace, and tools
# Copyright (c) 2004,2005 David H. Hovemeyer <daveho@cs.umd.edu>
-# $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".
# 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)
#
# 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
#
#
#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)
EXTRA_CC_USER_OPTS := -Dmain=geekos_main
endif
-VMM_SIZES = ../include/geekos/vmm_sizes.h
+
# ----------------------------------------------------------------------
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
-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
$(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:
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
-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
/*
* Boot information structure, passed to kernel Main() routine
* Copyright (c) 2001, David H. Hovemeyer <daveho@cs.umd.edu>
- * $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".
#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 */
/*
* Misc. kernel definitions
* Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
- * $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".
/*
- * Address where kernel is loaded INITIALLY
- * we move it up in memory soon
+ * Address where kernel is loaded
*/
#define KERNEL_START_ADDR 0x10000
#define PAGE_SIZE (1<<PAGE_POWER)
#define PAGE_MASK (~(0xffffffff << PAGE_POWER))
+#define KERNEL_THREAD_OBJECT (PAGE_SIZE)
+#define KERNEL_STACK (PAGE_SIZE * 2)
+
-/* Ultimate Memory Layout
-
-TOP_OF_MEM:
- GDT (one page)
- TSS (one page)
- IDT (one page)
- KernelImage
- VMBootPackage
- rombios (2nd copy)
- vmxassist
- vgabios
- rombios (1st copy)
- PageList (varies - must be an integral number of pages)
- KernelHeap (varies - KERNEL_HEAP_SIZE; must be integral number of pages)
- KernelStack (one page)
- KernelThreadObject (one page)
-0+VM_SIZE:
- VM (including ISA hole)
- (KernelImage, GDT, and IDT start down here and are moved up)
- (VMBoot Package is copied down to the first MB to start the VM boot)
- (VMXAssist is used to provide real mode emulation for initial VM boot steps)
-0:
-*/
-
-// This is for a 1 GB Machine
-// The last address (+1) at which physical memory ends
-#define TOP_OF_MEM (0x30000000)
-// How much space to reserve for the VM
-#define VM_SIZE (0x20000000)
-// Where the VM starts in physical memory
-#define START_OF_VM (0x0)
// Where we load the vm's kernel image (1MB)
#define VM_KERNEL_TARGET (0x100000)
-#define GDT_SIZE PAGE_SIZE
-#define TSS_SIZE PAGE_SIZE
-#define IDT_SIZE PAGE_SIZE
-#define KERNEL_HEAP_SIZE (256*PAGE_SIZE)
-#define KERNEL_STACK_SIZE PAGE_SIZE
-#define KERNEL_THREAD_OBJECT_SIZE PAGE_SIZE
-
-
-
-
-/*
- * * Keep these up to date with defs.asm.
- */
-#define GDT_LOCATION (TOP_OF_MEM-GDT_SIZE)
-#define TSS_LOCATION (GDT_LOCATION-TSS_SIZE)
-#define IDT_LOCATION (TSS_LOCATION-IDT_SIZE)
-
-
-#define FINAL_KERNEL_START (IDT_LOCATION-MAX_VMM)
-#define FINAL_KERNEL_END (FINAL_KERNEL_START+KERNEL_CORE_LENGTH-1)
-#define FINAL_VM_KERNEL_START (FINAL_KERNEL_START+KERNEL_CORE_LENGTH)
-#define FINAL_VM_KERNEL_END (FINAL_VM_KERNEL_START+VM_KERNEL_LENGTH-1)
-#define FINAL_VMBOOTSTART (FINAL_VM_KERNEL_START)
-#define FINAL_VMBOOTEND (VM_BOOT_PACKAGE_END)
-
-#if (FINAL_VMBOOTEND>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 */
* Physical memory allocation
* Copyright (c) 2001,2003,2004 David H. Hovemeyer <daveho@cs.umd.edu>
* Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
- * $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".
#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;
/*
/******************************************/
-/* SVM Intercep Exit Codes */
+/* SVM Intercept Exit Codes */
/* AMD Arch Vol 3, Appendix C, pg 477-478 */
/******************************************/
#define VMEXIT_CR_READ_MASK 0xfffffff0
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);
#include <geekos/ktypes.h>
+typedef unsigned long addr_t;
typedef struct mem_region {
- ullong_t addr;
+ addr_t addr;
uint_t num_pages;
struct mem_region * next;
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;
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
--- /dev/null
+#ifndef __VMM_PAGING_H
+#define __VMM_PAGING_H
+
+#include <geekos/ktypes.h>
+#include <geekos/vmm.h>
+
+
+#include <geekos/vmm_mem.h>
+#include <geekos/vmm_util.h>
+
+#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
+++ /dev/null
-#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
#define __VMM_UTIL_H
#include <geekos/vmm.h>
+#include <geekos/vmm_mem.h>
-
-
+#ifndef PAGE_SIZE
#define PAGE_SIZE 4096
-
+#endif
typedef union reg_ex {
ullong_t r_reg;
struct {
void PrintTraceMemDump(unsigned char * start, int n);
-
#endif
; Definitions for use in GeekOS boot code
; Copyright (c) 2001, David H. Hovemeyer <daveho@cs.umd.edu>
-; $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".
%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
; 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
/*
* Initialize kernel GDT.
* Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
- * $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".
/*
* 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.
*/
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);
/*
* GeekOS IDT initialization code
* Copyright (c) 2001, David H. Hovemeyer <daveho@cs.umd.edu>
- * $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".
/*
* 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;
/*
* Copyright (c) 2001,2003,2004 David H. Hovemeyer <daveho@cs.umd.edu>
* Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
* Copyright (c) 2004, Iulian Neamtiu <neamtiu@cs.umd.edu>
- * $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".
#include <geekos/gdt.h>
-#include <geekos/vmm_sizes.h>
+
#include <geekos/vmm_stubs.h>
/*
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;
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();
* Physical memory allocation
* Copyright (c) 2001,2003,2004 David H. Hovemeyer <daveho@cs.umd.edu>
* Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
- * $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".
#include <geekos/string.h>
#include <geekos/mem.h>
-#include <geekos/vmm_sizes.h>
#include <geekos/serial.h>
#include <geekos/debug.h>
{
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));
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
*/
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);
}
/*
; -*- fundamental -*-
; GeekOS setup code
; Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
-; $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".
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
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
.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]
+++ /dev/null
-#include <stdio.h>
-#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;
-
-}
#include <geekos/vmm.h>
#include <geekos/vmcb.h>
+#include <geekos/vmm_mem.h>
+#include <geekos/vmm_paging.h>
+
extern struct vmm_os_hooks * os_hooks;
// 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;
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;
}
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);
/* ** */
}
+
+
/*
* x86 TSS data structure and routines
* Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
- * $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".
/*
* 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;
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));
*/
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
// 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));
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));
cursor = new_region;
} else if ((addr >= cursor->addr) &&
- (addr <= cursor_end)) {
+ (addr <= cursor_end + 1)) {
// address falls inside the cursor region
}
}
+
// 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) {
* 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 {
+/* 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;
* 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 {
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;
}
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;
-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;
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;
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;
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) {
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++;
}
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++;
}
+
+
+
+
+
+
+
+
+
#ifdef VMM_MEM_TEST
+
+
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
+#include <geekos/vmm_paging.h>
return malloc(size);
}
+void * TestAllocatePages(int size) {
+ return malloc(4096 * size);
+}
+
+
void TestPrint(const char * fmt, ...) {
va_list args;
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;
}
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
+
+
+
+
+
+
--- /dev/null
+#include <geekos/vmm_paging.h>
+
+
+
+
+
+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));
+ }
+}
+
+
#include <geekos/vmm_util.h>
+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);
{
int i, j;
- for (i=0;i<n;i+=16) {
- PrintTrace("%8x", (unsigned)(start+i));
- for (j=i; j<i+16 && j<n; j+=2) {
+ for (i = 0; i < n; i += 16) {
+ PrintTrace("%8x", (unsigned)(start + i));
+ for (j = i; (j < (i + 16)) && (j < n); j += 2) {
PrintTrace(" ");
- PrintTraceHex(*((unsigned char *)(start+j)));
- if ((j+1)<n) {
- PrintTraceHex(*((unsigned char *)(start+j+1)));
+ PrintTraceHex(*((unsigned char *)(start + j)));
+ if ((j + 1) < n) {
+ PrintTraceHex(*((unsigned char *)(start + j + 1)));
}
}
PrintTrace(" ");
- for (j=i; j<i+16 && j<n;j++) {
- PrintTrace("%c", ((start[j]>=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");
}
}
+
+
+