--- /dev/null
+# Makefile for GeekOS kernel, userspace, and tools
+#
+# Northwestern University
+# (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+# (c) 2008, Peter Dinda <pdinda@northwestern.edu>
+# (c) 2008, Lei Xia <xiaxlei@gmail.com>
+# (c) 2008, The V3VEE Project <http://www.v3vee.org>
+#
+# Based on GeekOS Makefile:
+# Copyright (c) 2004,2005 David H. Hovemeyer <daveho@cs.umd.edu>
+# $Revision: 1.71 $
+
+
+# This is free software. You are permitted to use,
+# redistribute, and modify it as specified in the file "COPYING".
+
+# Required software to build GeekOS:
+# - GNU Make (http://www.gnu.org/software/make)
+# - gcc 2.95.2 generating code for target (i386/ELF) and host platforms
+# - nasm (http://nasm.sourceforge.net)
+# - Perl5, AWK (any version), egrep
+#
+# Cygwin (http://cygwin.com) may be used to build GeekOS.
+# Make sure that gcc, binutils, nasm, and perl are installed.
+
+# NOTES:
+# - This makefile has been written carefully to work correctly
+# with the -j (parallel make) option. I regularly use "make -j 2"
+# to speed the build process on 2 processor systems.
+
+
+# Base address of kernel
+#
+# Note: at top of memory minus three pages (GDT/TSS/IDT)
+# minus maximum size
+#
+#
+# Note that the code will initially load at 0x10000
+#
+# The setup code needs to copy it up to this address and jump there
+#
+KERNEL_BASE_ADDR := 0x00100000
+
+# Kernel entry point function
+KERNEL_ENTRY = $(SYM_PFX)Main
+
+
+PROJECT_ROOT := ..
+V3_ROOT := $(PROJECT_ROOT)/../palacios
+VPATH := $(PROJECT_ROOT)/src
+
+
+
+#
+#TCPSTACK, uIP is used currently
+#
+TCPSTACK=UIP
+
++#
++#TCPSTACK, uIP is used currently
++#
++UIP=OFF
+
++#
++#LWIP, ON -- used, OFF -- not used
++#
++LWIP=ON
+
+
+#
+# This is wrong for current cygwin - no changes needed
+#
+# Figure out if we're compiling with cygwin, http://cygwin.com
+#
+#
+#SYSTEM_NAME := $(shell uname -s)
+#ifeq ($(findstring CYGWIN,$(SYSTEM_NAME)),CYGWIN)
+#SYM_PFX := _
+#EXTRA_C_OPTS := -DNEED_UNDERSCORE -DGNU_WIN32
+#EXTRA_NASM_OPTS := -DNEED_UNDERSCORE
+#NON_ELF_SYSTEM := yes
+#EXTRA_CC_USER_OPTS := -Dmain=geekos_main
+#endif
+
+
+
+
+# ----------------------------------------------------------------------
+# Configuration -
+# Various options specifying how GeekOS should be built,
+# what source files to build, which user programs to build,
+# etc. This is generally the only section of the makefile
+# that will need to be modified.
+# ----------------------------------------------------------------------
+
+# List of targets to build by default.
+# These targets encompass everything needed to boot
+# and run GeekOS.
+ALL_TARGETS := vmm.img
+
+
+# Kernel source files
+KERNEL_C_SRCS := idt.c int.c trap.c irq.c io.c \
+ blockdev.c ide.c ne2k.c \
+ keyboard.c screen.c timer.c \
+ mem.c crc32.c \
+ gdt.c tss.c segment.c \
+ bget.c malloc.c \
+ synch.c kthread.c \
+ serial.c reboot.c \
+ paging.c \
+ debug.c vmm_stubs.c vm.c pci.c\
+ queue.c socket.c net.c ring_buffer.c \
+ main.c
+
+
+# Kernel object files built from C source files
+KERNEL_C_OBJS := $(KERNEL_C_SRCS:%.c=geekos/%.o)
+
+# Kernel assembly files
+KERNEL_ASM_SRCS := lowlevel.asm
+
+KERNEL_GAS_SRCS :=
+
+# Kernel object files build from assembler source files
+KERNEL_ASM_OBJS := $(KERNEL_ASM_SRCS:%.asm=geekos/%.o)
+
+KERNEL_GAS_OBJS := $(KERNEL_GAS_SRCS:%.s=geekos/%.o)
+
+
+# All kernel object files
+KERNEL_OBJS := $(KERNEL_C_OBJS) \
+ $(KERNEL_ASM_OBJS) $(KERNEL_GAS_OBJS)
+
+# Common library source files.
+# This library is linked into both the kernel and user programs.
+# It provides string functions and generic printf()-style
+# formatted output.
+COMMON_C_SRCS := fmtout.c string.c memmove.c
+
+# Common library object files.
+COMMON_C_OBJS := $(COMMON_C_SRCS:%.c=common/%.o)
+
+
+
+
+V3_LD_FLAGS := -L./palacios/
+#V3_LIBS := -lxed -lv3vee
+V3_LIBS := ./palacios/libxed.a ./palacios/libv3vee.a ./palacios/libxed.a ./palacios/libv3vee.a
+
+
+
- TCPSTACK_C_SRCS := psock.c timer.c uip_arp.c uip.c uip-fw.c uiplib.c uip-neighbor.c uip-split.c resolv.c
+
- TCPSTACK_C_OBJS := $(TCPSTACK_C_SRCS:%.c=net/%.o)
+
- TCPSTACK_OBJS := $(TCPSTACK_C_OBJS)
+
++ifeq ($(UIP),ON)
++ UIP_C_SRCS := psock.c timer.c uip_arp.c uip.c uip-fw.c uiplib.c uip-neighbor.c uip-split.c resolv.c
++ UIP_C_OBJS := $(UIP_C_SRCS:%.c=net/%.o)
++else
++ UIP_C_SRCS :=
++ UIP_C_OBJS :=
++endif
++
++ifeq ($(LWIP),ON)
++ LWIP_OBJS := lwip/*.o
++ CC_LWIP_OPTS := -I$(PROJECT_ROOT)/include/lwip -I$(PROJECT_ROOT)/include/lwip/ipv4 -I$(PROJECT_ROOT)/include/libc -DLWIP_DEBUG
++else
++ LWIP_OBJS :=
++ CC_LWIP_OPTS :=
++endif
+
++TCPSTACK_OBJS := $(UIP_C_OBJS) $(LWIP_OBJS)
+
+
+# ----------------------------------------------------------------------
+# Tools -
+# This section defines programs that are used to build GeekOS.
+# ----------------------------------------------------------------------
+
+# Uncomment if cross compiling
+TARGET_CC_PREFIX := $(PROJECT_ROOT)/../devtools/i386/bin/i386-elf-
+#TARGET_CC_PREFIX := i386-elf-
+
+# Target C compiler. gcc 2.95.2 or later should work.
+TARGET_CC := $(TARGET_CC_PREFIX)gcc
+#TARGET_CC := $(TARGET_CC_PREFIX)gcc34 -m32
+
+# Host C compiler. This is used to compile programs to execute on
+# the host platform, not the target (x86) platform. On x86/ELF
+# systems, such as Linux and FreeBSD, it can generally be the same
+# as the target C compiler.
+HOST_CC := gcc
+
+# Target linker. GNU ld is probably to only one that will work.
+TARGET_LD := $(TARGET_CC_PREFIX)ld -melf_i386
+
+# Target archiver
+TARGET_AR := $(TARGET_CC_PREFIX)ar
+
+# Target ranlib
+TARGET_RANLIB := $(TARGET_CC_PREFIX)ranlib
+
+# Target nm
+TARGET_NM := $(TARGET_CC_PREFIX)nm
+
+# Target objcopy
+TARGET_OBJCOPY := $(TARGET_CC_PREFIX)objcopy
+
+# Nasm (http://nasm.sourceforge.net)
+NASM := $(PROJECT_ROOT)/../devtools/bin/nasm
+#NASM := /opt/vmm-tools/bin/nasm
+
+AS = as --32
+
+# Tool to build PFAT filesystem images.
+BUILDFAT := tools/builtFat.exe
+
+# Perl5 or later
+PERL := perl
+
+# Pad a file so its size is a multiple of some unit (i.e., sector size)
+PAD := $(PERL) $(PROJECT_ROOT)/scripts/pad
+
+# Create a file filled with zeroes.
+ZEROFILE := $(PERL) $(PROJECT_ROOT)/scripts/zerofile
+
+# Calculate size of file in sectors
+NUMSECS := $(PERL) $(PROJECT_ROOT)/scripts/numsecs
+
+
+FD_SECTORS_PER_TRACK := $(PERL) $(PROJECT_ROOT)/scripts/numsecs_per_track
+
+
+# ----------------------------------------------------------------------
+# Definitions -
+# Options passed to the tools.
+# ----------------------------------------------------------------------
+
+# Flags used for all C source files
+GENERAL_OPTS := -O -Wall $(EXTRA_C_OPTS) $(BOOT_FLAGS) -fPIC
+CC_GENERAL_OPTS := $(GENERAL_OPTS) -Werror
+
+# Flags used for kernel C source files
+CC_KERNEL_OPTS := -g -DGEEKOS -I$(PROJECT_ROOT)/include -I$(V3_ROOT)/include
+
+
+# Flags user for kernel assembly files
+NASM_KERNEL_OPTS := -I$(PROJECT_ROOT)/src/geekos/ -f elf $(EXTRA_NASM_OPTS)
+
+# Flags used for common library and libc source files
+CC_USER_OPTS := -I$(PROJECT_ROOT)/include -I$(PROJECT_ROOT)/include/libc \
+ $(EXTRA_CC_USER_OPTS) -I$(V3_ROOT)/include
+
+# Flags passed to objcopy program (strip unnecessary sections from kernel.exe)
+OBJCOPY_FLAGS := -R .dynamic -R .note -R .comment
+
+# ----------------------------------------------------------------------
+# Rules -
+# Describes how to compile the source files.
+# ----------------------------------------------------------------------
+
+# Compilation of kernel C source files
+
+geekos/%.o : geekos/%.c
- $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_KERNEL_OPTS) $< -o geekos/$*.o
++ $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_KERNEL_OPTS) $(CC_LWIP_OPTS) $< -o geekos/$*.o
+
+
+# Compilation of kernel assembly source files
+geekos/%.o : geekos/%.asm
+ $(NASM) $(NASM_KERNEL_OPTS) $< -o geekos/$*.o
+
+
+# Compilation of common library C source files
+common/%.o : common/%.c
+ $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_USER_OPTS) $< -o common/$*.o
+
+
+net/%.o : net/%.c
+ $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_USER_OPTS) $< -o net/$*.o
+
+# ----------------------------------------------------------------------
+# Targets -
+# Specifies files to be built
+# ----------------------------------------------------------------------
+
+# Default target - see definition of ALL_TARGETS in Configuration section
+all : $(ALL_TARGETS)
+
+
+#geekos/vmx_lowlevel.o: $(PROJECT_ROOT)/src/geekos/vmx_lowlevel.asm
+# $(NASM) -O99 \
+# -f elf \
+# -I$(PROJECT_ROOT)/src/geekos/ \
+# $(PROJECT_ROOT)/src/geekos/vmx_lowlevel.asm \
+# -o $@
+
+
+#geekos/test: geekos/test.o geekos/vmcs.o geekos/vmx_lowlevel.o
+# $(CC) geekos/test.o geekos/vmcs.o geekos/vmx_lowlevel.o -o geekos/test
+
+# Standard floppy image - just boots the kernel
+fd.img : geekos/fd_boot.bin geekos/setup.bin geekos/kernel.bin
+ cat geekos/fd_boot.bin geekos/setup.bin geekos/kernel.bin > _temp
+ $(PAD) _temp 512
+ cp _temp fd.img
+
+
+vmm.img: fd.img
+ cp fd.img vmm.img
+ $(PAD) vmm.img 1474560
+
+
+
+
+
+
+# Floppy boot sector (first stage boot loader).
+geekos/fd_boot.bin : geekos/setup.bin geekos/kernel.bin $(PROJECT_ROOT)/src/geekos/fd_boot.asm
+ $(NASM) -f bin \
+ -I$(PROJECT_ROOT)/src/geekos/ \
+ -DNUM_SETUP_SECTORS=`$(NUMSECS) geekos/setup.bin` \
+ -DNUM_KERN_SECTORS=`$(NUMSECS) geekos/kernel.bin` \
+ -DSECTORS_PER_TRACK=`$(FD_SECTORS_PER_TRACK) geekos/kernel.bin geekos/setup.bin` \
+ $(PROJECT_ROOT)/src/geekos/fd_boot.asm \
+ -o $@
+
+# Setup program (second stage boot loader).
+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_SIZE=`$(NUMSECS) geekos/kernel.bin` \
+ $(PROJECT_ROOT)/src/geekos/setup.asm \
+ -o $@
+ $(PAD) $@ 2048
+
+# Loadable (flat) kernel image.
+geekos/kernel.bin : geekos/kernel.exe
+ $(TARGET_OBJCOPY) $(OBJCOPY_FLAGS) -S -O binary geekos/kernel.exe geekos/kernel.bin
+ $(PAD) $@ 512
+
+# The kernel executable and symbol map.
+geekos/kernel.exe : $(KERNEL_OBJS) $(COMMON_C_OBJS) $(TCPSTACK_OBJS)
+ $(TARGET_LD) -o geekos/kernel.exe -Ttext $(KERNEL_BASE_ADDR) -e $(KERNEL_ENTRY) \
+ $(V3_LD_FLAGS) \
+ $(KERNEL_OBJS) $(COMMON_C_OBJS) $(TCPSTACK_OBJS) $(V3_LIBS) -b binary ./palacios/vm_kernel
+ $(TARGET_NM) geekos/kernel.exe > geekos/kernel.syms
+
+
+force:
+
+
+#vm_kernel: force
+# $(PAD) vm_kernel 512
+# @echo "VM kernel lives at 0x100000 and is" `$(NUMSECS) vm_kernel` "sectors long"
+
+
+
+
+# Clean build directories of generated files
+clean :
+ for d in geekos common libc user tools net; do \
+ (cd $$d && rm -f *); \
+ done
+
+
+# Build header file dependencies, so source files are recompiled when
+# header files they depend on are modified.
+depend : $(GENERATED_LIBC_SRCS)
+ $(TARGET_CC) -M $(CC_GENERAL_OPTS) $(CC_KERNEL_OPTS) \
+ $(KERNEL_C_SRCS:%.c=$(PROJECT_ROOT)/src/geekos/%.c) \
+ | $(PERL) -n -e 's,^(\S),geekos/$$1,;print' \
+ > depend.mak
+ $(TARGET_CC) -M $(CC_GENERAL_OPTS) $(CC_USER_OPTS) \
+ $(COMMON_C_SRCS:%.c=$(PROJECT_ROOT)/src/common/%.c) \
+ | $(PERL) -n -e 's,^(\S),common/$$1,;print' \
+ >> depend.mak
+
+
+# By default, there are no header file dependencies.
+depend.mak :
+ touch $@
+
+include depend.mak
#include <geekos/ktypes.h>
#include <geekos/defs.h>
+
+ // to stop the compilation warnings
+ extern void Print(const char* fmt, ...);
+ extern void Set_Current_Attr(uchar_t attrib);
+
/*
* This struct reflects the contents of the stack when
* a C interrupt handler function is called.
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Matt Wojcik
+ * Copyright (c) 2008, Peter Kamm
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Matt Wojcik
+ * Author: Peter Kamm
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
#ifndef GEEKOS_NE2K_H
#define GEEKOS_NE2K_H
#define NE2K_IRQ 11 /* Interrupt channel */
+
+ /* Physical Address of Network Card */
+ #define PHY_ADDR1 0x52
+ #define PHY_ADDR2 0x54
+ #define PHY_ADDR3 0x00
+ #define PHY_ADDR4 0x12
+ #define PHY_ADDR5 0x34
+ #define PHY_ADDR6 0x58
+
+
struct NE2K_REGS {
uchar_t cr;
uchar_t isr;
#define TIMER_IRQ 0
- extern volatile ulong_t g_numTicks;
+ extern volatile unsigned long g_numTicks;
typedef void (*timerCallback)(int, void*);
int Start_Timer_MSecs(int msecs, timerCallback cb, void * arg);
int Start_Timer(int ticks, timerCallback, void * arg);
+
double Get_Remaining_Timer_Secs(int id);
int Get_Remaining_Timer_MSecs(int id);
int Get_Remaining_Timer_Ticks(int id);
void Micro_Delay(int us);
+ unsigned long clock_time(void); //return elipsed millisecs
+
#endif /* GEEKOS_TIMER_H */
char *strpbrk(const char *s, const char *accept);
char *strncat(char *s1, const char *s2, size_t limit);
int fprintf(FILE *file, char *fmt, ...);
- //int fflush(FILE *file);
+ int fflush(FILE *file);
+ int printf(char *fmt, ...);
--- /dev/null
--- /dev/null
++#ifndef __PING_H__
++#define __PING_H__
++
++void ping_init(void);
++
++#endif /* __PING_H__ */
/* Include some files for defining library routines */
#include <string.h>
-
- extern int fflush(FILE *file);
- extern int printf(char *fmt, ...);
- extern void abort (void);
-
+ #include <geekos/debug.h>
/* Define platform endianness */
#ifndef BYTE_ORDER
//#include <stdio.h>
//#include <stdlib.h>
/* Plaform specific diagnostic output */
- #define LWIP_PLATFORM_DIAG(x) //do {printf x;} while(0)
+ #define LWIP_PLATFORM_DIAG(x) do {PrintBoth x;} while(0)//do {printf x;} while(0)
#define LWIP_PLATFORM_ASSERT(x) do {printf("Assertion \"%s\" failed at line %d in %s\n", \
x, __LINE__, __FILE__); fflush(NULL); abort();} while(0)
#define PERF_STOP(x) /* null definition */
#endif /* PERF */
+ #if 0
+
void perf_print(unsigned long c1l, unsigned long c1h,
unsigned long c2l, unsigned long c2h,
char *key);
void perf_init(char *fname);
+ #endif
+
#endif /* __ARCH_PERF_H__ */
#ifndef __LWIP_IP_ADDR_H__
#define __LWIP_IP_ADDR_H__
- #include "lwip/opt.h"
+ #include <lwip/lwip/opt.h>
#ifdef __cplusplus
extern "C" {
* Include user defined options first. Anything not defined in these files
* will be set to standard values. Override anything you dont like!
*/
- #include "lwipopts.h"
+ #include <lwip/lwipopts.h>
#include "lwip/debug.h"
/*
* TCP_WND: The size of a TCP window.
*/
#ifndef TCP_WND
- #define TCP_WND 2048
+ #define TCP_WND 1024 //2048
#endif
/**
* LWIP_NETIF_API==1: Support netif api (in netifapi.c)
*/
#ifndef LWIP_NETIF_API
- #define LWIP_NETIF_API 0
+ #define LWIP_NETIF_API 1
#endif
/**
--- /dev/null
--- /dev/null
++/* ne2k network interface for lwip\r
++ *\r
++ * Lei Xia (lxia@northwestern.edu)\r
++ */
++
++#ifndef __NETIF_NE2KIF_H__
++#define __NETIF_NE2KIF_H__
++
++#include <lwip/lwip/netif.h>
++#include <lwip/lwip/err.h>
++#include <geekos/ktypes.h>
++#include <geekos/ne2k.h>
++
++extern struct netif ne2kif;
++
++err_t ne2kif_init(struct netif *netif);
++
++void ne2kif_input(struct NE2K_Packet_Info * info, uchar_t * pkt);
++
++err_t ne2kif_output(struct netif * netif, struct pbuf * p);
++
++#endif /*__NETIF_NE2KIF_H__*/
*
* \hideinitializer
*/
- typedef unsigned char u8_t;
+ //conflict with lwip
+ //typedef unsigned char u8_t;
/**
* 16 bit datatype
*
* \hideinitializer
*/
- typedef unsigned short int u16_t;
+ //confict with lwip
+ //typedef unsigned short int u16_t;
/**
* Statistics datatype
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Matt Wojcik
+ * Copyright (c) 2008, Peter Kamm
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Matt Wojcik
+ * Author: Peter Kamm
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
#include <geekos/ne2k.h>
#include <geekos/debug.h>
#include <geekos/io.h>
#include <geekos/irq.h>
#include <geekos/malloc.h>
#include <geekos/string.h>
+
+ #ifdef UIP
#include <uip/uip.h>
#include <uip/uip_arp.h>
+ #endif
#define DEBUG 1
#define TX_START_BUFF 0x40
cr->ps = 0x01; /* Switch to reg page 1 */
Out_Byte(NE2K_CR, regs->cr);
- /* Set the physical address of the card to 52:54:00:12:34:58 */
- Out_Byte(NE2K_CR+0x01, 0x52);
- Out_Byte(NE2K_CR+0x02, 0x54);
- Out_Byte(NE2K_CR+0x03, 0x00);
- Out_Byte(NE2K_CR+0x04, 0x12);
- Out_Byte(NE2K_CR+0x05, 0x34);
- Out_Byte(NE2K_CR+0x06, 0x58);
+ /* Set the physical address of the card */
+ Out_Byte(NE2K_CR+0x01, PHY_ADDR1);
+ Out_Byte(NE2K_CR+0x02, PHY_ADDR2);
+ Out_Byte(NE2K_CR+0x03, PHY_ADDR3);
+ Out_Byte(NE2K_CR+0x04, PHY_ADDR4);
+ Out_Byte(NE2K_CR+0x05, PHY_ADDR5);
+ Out_Byte(NE2K_CR+0x06, PHY_ADDR6);
/* Set the multicast address register to all 1s; accepts all multicast packets */
uint_t i;
* an ARP packet, which is sent out instead. The original packet will need to be
* retransmitted at some point in the future.
*/
+ #ifdef UIP
+
int NE2K_Transmit(uint_t size)
{
uip_arp_out();
return 0;
}
+ #endif
+
int NE2K_Send_Packet(uchar_t *packet, uint_t size)
{
struct _CR * cr = (struct _CR*)&(regs->cr);
- /*
- * This file is part of the Palacios Virtual Machine Monitor developed
- * by the V3VEE Project with funding from the United States National
- * Science Foundation and the Department of Energy.
- *
- * The V3VEE Project is a joint project between Northwestern University
- * and the University of New Mexico. You can find out more at
- * http://www.v3vee.org
- *
- * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software. You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
+ /* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
+ /* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+
#include <geekos/net.h>
#include <geekos/socket.h>
#include <geekos/ne2k.h>
+ #include <lwip/apps/ping.h>
+ #include <lwip/lwip/sockets.h>
+ #include <lwip/ipv4/lwip/ip_addr.h>
+ #include <lwip/netif/ne2kif.h>
+ #include <lwip/sys.h>
+ #include <lwip/netifapi.h>
+ #include <lwip/tcpip.h>
+ #include <netif/etharp.h>
+ #include <geekos/debug.h>
- void Init_Network() {
- init_socket_layer();
+
+ static void
+ tcpip_init_done(void *arg)
+ {
+ sys_sem_t *sem;
+ sem = arg;
+ sys_sem_signal(*sem);
}
+ void Init_Network() {
+
+ //temporay now we are using lwip sockets
+ // init_socket_layer();
+
+ struct ip_addr ipaddr, netmask, gateway;
+ sys_sem_t sem;
+ err_t err;
+
+ sem = sys_sem_new(0);
+
+ #ifdef LWIP_DEBUG
+ PrintBoth("lwIP: before tcpip_init\n");
+ #endif
+ tcpip_init(tcpip_init_done, &sem); //initial the whole lwip module
+ #ifdef LWIP_DEBUG
+ PrintBoth("lwIP: After tcpip_init\n");
+ #endif
+ sys_sem_wait(sem);
+ sys_sem_free(sem);
+
+ IP4_ADDR(&gateway, 192,168,1,1);
+ IP4_ADDR(&ipaddr, 192,168,1,2);
+ IP4_ADDR(&netmask, 255,255,255,0);
+
+
+ err = netifapi_netif_add(&ne2kif, &ipaddr, &netmask, &gateway,
+ NULL, ne2kif_init, ethernet_input);
+
+ if (err != ERR_OK){
+ PrintBoth("lwip: initial network failed! add netif error %d/n", err);
+ return;
+ }
+
+ netifapi_netif_set_default(&ne2kif);
+
+ //initial a network application
+ ping_init();
+ }
+
+
+ #if 0
void test_network() {
uchar_t local_addr[4];
local_addr[2] = 2;
local_addr[3] = 21;
- set_ip_addr(local_addr);
+ // set_ip_addr(local_addr);
remote_addr[0] = 10;
remote_addr[1] = 0;
remote_addr[3] = 20;
- connect(remote_addr, 4301);
+ // connect(remote_addr, 4301);
}
+
+ #endif
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, Lei Xia <xiaxlei@gmail.com> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, Lei Xia <xiaxlei@gmail.com>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ * Author: Lei Xia <xiaxlei@gmail.com>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
#include <geekos/socket.h>
#include <geekos/malloc.h>
#include <geekos/ne2k.h>
+
+ #ifdef UIP
+
#include <uip/uip.h>
#include <uip/uip_arp.h>
+
#include <geekos/vmm_stubs.h>
#include <geekos/debug.h>
#include <geekos/timer.h>
-
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
#define MAX_SOCKS 1024
#endif /* UIP_APPCALL */
-
-
static int Packet_Received(struct NE2K_Packet_Info* info, uchar_t *pkt);
static void periodic_caller(int timer_id, void * arg);
void init_socket_layer() {
+
int i = 0;
bool iflag;
sockets[i].state = CLOSED;
}
-
-
//initiate uIP
uip_init();
uip_arp_init();
- //setup device driver
- Init_Ne2k(&Packet_Received);
+ //setup device driver
+ Init_Ne2k(&Packet_Received);
iflag = Begin_Int_Atomic();
Start_Timer(2, periodic_caller, NULL);
End_Int_Atomic(iflag);
-
}
-
-
-
void set_ip_addr(uchar_t addr[4]) {
uip_ipaddr_t ipaddr;
uip_ipaddr(ipaddr, addr[0], addr[1], addr[2], addr[3]); /* Local IP address */
uip_sethostaddr(ipaddr);
}
-
static int allocate_socket_fd() {
int i = 0;
}
-
static void periodic_caller(int timer_id, void * arg) {
int i;
//handle the periodic calls of uIP
return 0;
}
+
+
+ #endif /* UIP */
#include <geekos/synch.h>
#include <geekos/timer.h>
+ #include <geekos/debug.h>
+
/*
* NOTES:
* - The GeekOS mutex and condition variable APIs are based on those
}
/*
+ * Destroy Mutex
+ */
+ void Mutex_Destroy(struct Mutex* mutex)
+ {
+
+
+ }
+
+ /*
+ * Condition Destroy
+ */
+ void Cond_Destroy(struct Condition* cond)
+ {
+
+
+ }
+
+ /*
* Initialize given condition.
*/
void Cond_Init(struct Condition* cond)
#include <geekos/io_defs.h>
/* PAD this currently is in nvram.c */
+/* JRL: This is completely broken
extern void deliver_timer_interrupt_to_vmm(uint_t period_us);
+*/
/* JRL Add a cpu frequency measurement */
uint_t cpu_khz_freq;
*/
volatile ulong_t g_numTicks;
- ulong_t clock_time(void){
- return g_numTicks;
- }
-
-
/*
* Number of times the spin loop can execute during one timer tick
*/
# define Debug(args...)
#endif
+ ulong_t clock_time(void){//in millisec
+ return g_numTicks * (1000/HZ);
+ }
+
/* ----------------------------------------------------------------------
* Private functions
* ---------------------------------------------------------------------- */
}
-
+ /* JRL: Broken,
deliver_timer_interrupt_to_vmm(1000000/HZ);
-
+ */
End_IRQ(state);
}
KASSERT(!Interrupts_Enabled());
+ PrintBoth ("there\n");
+
if (timeEventCount == MAX_TIMER_EVENTS) {
return -1;
} else {
LOCK_TCPIP_CORE();
while (1) { /* MAIN Loop */
+
+ PrintBoth("In tcp_thread: main loop\n");
+
sys_mbox_fetch(mbox, (void *)&msg);
+
switch (msg->type) {
#if LWIP_NETCONN
case TCPIP_MSG_API:
--- /dev/null
--- /dev/null
++/**
++ * @file
++ * Ping sender module
++ *
++ */
++
++/*
++ * Redistribution and use in source and binary forms, with or without modification,
++ * are permitted provided that the following conditions are met:
++ *
++ * 1. Redistributions of source code must retain the above copyright notice,
++ * this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright notice,
++ * this list of conditions and the following disclaimer in the documentation
++ * and/or other materials provided with the distribution.
++ * 3. The name of the author may not be used to endorse or promote products
++ * derived from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
++ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
++ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
++ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
++ * OF SUCH DAMAGE.
++ *
++ * This file is part of the lwIP TCP/IP stack.
++ *
++ */
++
++/**
++ * This is an example of a "ping" sender (with raw API and socket API).
++ * It can be used as a start point to maintain opened a network connection, or
++ * like a network "watchdog" for your device.
++ *
++ */
++
++#include "lwip/opt.h"
++
++#if LWIP_RAW && LWIP_ICMP /* don't build if not configured for use in lwipopts.h */
++
++#include "lwip/mem.h"
++#include "lwip/raw.h"
++#include "lwip/icmp.h"
++#include "lwip/netif.h"
++#include "lwip/sys.h"
++#include "lwip/sockets.h"
++#include "lwip/inet.h"
++#include "lwip/inet_chksum.h"
++
++#include "apps/ping.h"
++
++#include <geekos/timer.h>
++#include <geekos/ktypes.h>
++
++/**
++ * PING_DEBUG: Enable debugging for PING.
++ */
++#ifndef PING_DEBUG
++#define PING_DEBUG LWIP_DBG_ON
++#endif
++
++/** ping target - should be a "struct ip_addr" */
++#ifndef PING_TARGET
++#define PING_TARGET (netif_default?netif_default->gw:ip_addr_any)
++#endif
++
++/** ping receive timeout - in milliseconds */
++#ifndef PING_RCV_TIMEO
++#define PING_RCV_TIMEO 1000
++#endif
++
++/** ping delay - in milliseconds */
++#ifndef PING_DELAY
++#define PING_DELAY 1000
++#endif
++
++/** ping identifier - must fit on a u16_t */
++#ifndef PING_ID
++#define PING_ID 0xAFAF
++#endif
++
++/** ping additional data size to include in the packet */
++#ifndef PING_DATA_SIZE
++#define PING_DATA_SIZE 32
++#endif
++
++/** ping result action - no default action */
++#ifndef PING_RESULT
++#define PING_RESULT(ping_ok)
++#endif
++
++/* ping variables */
++static u16_t ping_seq_num;
++static u32_t ping_time;
++
++#if NO_SYS
++/* port-defined functions used for timer execution */
++void sys_msleep(u32_t ms);
++u32_t sys_now();
++#endif /* NO_SYS */
++
++/** Prepare a echo ICMP request */
++static void
++ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len)
++{
++ int i;
++
++ ICMPH_TYPE_SET(iecho,ICMP_ECHO);
++ ICMPH_CODE_SET(iecho, 0);
++ iecho->chksum = 0;
++ iecho->id = PING_ID;
++ iecho->seqno = htons(++ping_seq_num);
++ iecho->chksum = inet_chksum(iecho, len);
++
++ /* fill the additional data buffer with some data */
++ for(i = 0; i < PING_DATA_SIZE; i++) {
++ ((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = i;
++ }
++}
++
++#if LWIP_SOCKET
++
++/* Ping using the socket ip */
++static err_t
++ping_send(int s, struct ip_addr *addr)
++{
++ int err;
++ struct icmp_echo_hdr *iecho;
++ struct sockaddr_in to;
++ size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE;
++
++ if (!(iecho = mem_malloc(ping_size))) {
++ return ERR_MEM;
++ }
++
++ ping_prepare_echo(iecho, ping_size);
++
++ to.sin_len = sizeof(to);
++ to.sin_family = AF_INET;
++ to.sin_addr.s_addr = addr->addr;
++
++ err = lwip_sendto(s, iecho, ping_size, 0, (struct sockaddr*)&to, sizeof(to));
++
++ mem_free(iecho);
++
++ return (err ? ERR_OK : ERR_VAL);
++}
++
++static void
++ping_recv(int s)
++{
++ char buf[64];
++ int fromlen, len;
++ struct sockaddr_in from;
++ struct ip_hdr *iphdr;
++ struct icmp_echo_hdr *iecho;
++
++ while((len = lwip_recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr*)&from, (socklen_t*)&fromlen)) > 0) {
++ if (len >= (sizeof(struct ip_hdr)+sizeof(struct icmp_echo_hdr))) {
++ LWIP_DEBUGF( PING_DEBUG, ("ping: recv "));
++ ip_addr_debug_print(PING_DEBUG, (struct ip_addr *)&(from.sin_addr));
++ LWIP_DEBUGF( PING_DEBUG, (" %lu ms\n", (sys_now()-ping_time)));
++
++ iphdr = (struct ip_hdr *)buf;
++ iecho = (struct icmp_echo_hdr *)(buf+(IPH_HL(iphdr) * 4));
++ if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num))) {
++ /* do some ping result processing */
++ PING_RESULT((ICMPH_TYPE(iecho) == ICMP_ER));
++ return;
++ } else {
++ LWIP_DEBUGF( PING_DEBUG, ("ping: drop\n"));
++ }
++ }
++ }
++
++ if (len == 0) {
++ LWIP_DEBUGF( PING_DEBUG, ("ping: recv - %lu ms - timeout\n", (sys_now()-ping_time)));
++ }
++
++ /* do some ping result processing */
++ PING_RESULT(0);
++}
++
++static void
++ping_thread(void *arg)
++{
++ int s;
++ int timeout = PING_RCV_TIMEO;
++ struct ip_addr ping_target;
++
++ LWIP_UNUSED_ARG(arg);
++
++ if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0) {
++ return;
++ }
++
++ lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
++
++ while (1) {
++ ping_target = PING_TARGET;
++
++ if (ping_send(s, &ping_target) == ERR_OK) {
++ LWIP_DEBUGF( PING_DEBUG, ("ping: send "));
++ ip_addr_debug_print(PING_DEBUG, &ping_target);
++ LWIP_DEBUGF( PING_DEBUG, ("\n"));
++
++ ping_time = sys_now();
++ ping_recv(s);
++ } else {
++ LWIP_DEBUGF( PING_DEBUG, ("ping: send "));
++ ip_addr_debug_print(PING_DEBUG, &ping_target);
++ LWIP_DEBUGF( PING_DEBUG, (" - error\n"));
++ }
++ sys_msleep(PING_DELAY);
++ }
++}
++
++#else /* LWIP_SOCKET */
++
++/* Ping using the raw ip */
++static u8_t
++ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *addr)
++{
++ struct icmp_echo_hdr *iecho;
++
++ if (pbuf_header( p, -PBUF_IP_HLEN)==0) {
++ iecho = p->payload;
++
++ if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num))) {
++ LWIP_DEBUGF( PING_DEBUG, ("ping: recv "));
++ ip_addr_debug_print(PING_DEBUG, addr);
++ LWIP_DEBUGF( PING_DEBUG, (" %lu ms\n", (sys_now()-ping_time)));
++
++ /* do some ping result processing */
++ PING_RESULT(1);
++ }
++ }
++
++ return 1; /* eat the event */
++}
++
++static void
++ping_send(struct raw_pcb *raw, struct ip_addr *addr)
++{
++ struct pbuf *p;
++ struct icmp_echo_hdr *iecho;
++ size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE;
++
++ if (!(p = pbuf_alloc(PBUF_IP, ping_size, PBUF_RAM))) {
++ return;
++ }
++ if ((p->len == p->tot_len) && (p->next == NULL)) {
++ iecho = p->payload;
++
++ ping_prepare_echo(iecho, ping_size);
++
++ raw_sendto(raw, p, addr);
++ ping_time = sys_now();
++ }
++ pbuf_free(p);
++}
++
++static void
++ping_timeout(void *arg)
++{
++ struct raw_pcb *pcb = (struct raw_pcb*)arg;
++ struct ip_addr ping_target = PING_TARGET;
++
++ LWIP_ASSERT("ping_timeout: no pcb given!", pcb != NULL);
++
++ LWIP_DEBUGF( PING_DEBUG, ("ping: send "));
++ ip_addr_debug_print(PING_DEBUG, &ping_target);
++ LWIP_DEBUGF( PING_DEBUG, ("\n"));
++
++ ping_send(pcb, &ping_target);
++
++ sys_timeout(PING_DELAY, ping_timeout, pcb);
++}
++
++static void
++ping_raw_init(void)
++{
++ struct raw_pcb *pcb;
++
++ if (!(pcb = raw_new(IP_PROTO_ICMP))) {
++ return;
++ }
++
++ raw_recv(pcb, ping_recv, NULL);
++ raw_bind(pcb, IP_ADDR_ANY);
++ sys_timeout(PING_DELAY, ping_timeout, pcb);
++}
++
++#endif /* LWIP_SOCKET */
++
++void
++ping_init(void)
++{
++#if LWIP_SOCKET
++ sys_thread_new("ping_thread", ping_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
++#else /* LWIP_SOCKET */
++ ping_raw_init();
++#endif /* LWIP_SOCKET */
++}
++
++
++u32_t
++sys_now()
++{
++ ulong_t msec;
++
++ msec = clock_time();
++
++ return msec;
++}
++
++#endif /* LWIP_RAW && LWIP_ICMP */
* will block until there is more room instead of just
* leaking messages.
*/
+ /*
+ * Modified by Lei Xia (lxia@northwestern.edu) to fit to Palacios, 9/29/2008
+ */
#include "lwip/debug.h"
#include <string.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <pthread.h>
+ #include <palacios/vmm.h>
#include <geekos/synch.h>
#include <geekos/kthread.h>
#include <geekos/debug.h>
+ #include <geekos/timer.h>
#include <geekos/malloc.h>
#include "lwip/sys.h"
};
- static struct timeval starttime;
+ //static struct timeval starttime;
//static pthread_mutex_t lwprot_mutex = PTHREAD_MUTEX_INITIALIZER;
static struct Mutex lwprot_mutex; // !!!! need to be initiated, void Mutex_Init(struct Mutex* mutex);
//static pthread_t lwprot_thread = (pthread_t) 0xDEAD;
- static struct Kernel_Thread lwprot_thread = (struct Kernel_Thread) 0xDEAD; //!!!!! how to set it to a NULL thread?
+ //static struct Kernel_Thread lwprot_thread = (struct Kernel_Thread) 0xDEAD; //!!!!! how to set it to a NULL thread?
- static int lwprot_count = 0;
+ //static int lwprot_count = 0;
static struct sys_sem *sys_sem_new_(u8_t count);
static void sys_sem_free_(struct sys_sem *sem);
}
- //!!!!!!!!!!!!backto this function later
/*-----------------------------------------------------------------------------------*/
sys_thread_t
sys_thread_new(char *name, void (* function)(void *arg), void *arg, int stacksize, int prio)
{
- int code;
+ //int code;
//pthread_t tmp;
struct Kernel_Thread *tmp;
struct sys_thread *st = NULL;
thread = current_thread();
return &thread->timeouts;
}
+
+
/*-----------------------------------------------------------------------------------*/
/** sys_prot_t sys_arch_protect(void)
sys_arch_protect() is only required if your port is supporting an operating
system.
*/
+
+ #if 0
sys_prot_t
sys_arch_protect(void)
{
{
if (--lwprot_count == 0)
{
- lwprot_thread = (Kernel_Thread) 0xDEAD;
+ lwprot_thread = (struc Kernel_Thread) 0xDEAD;
Mutex_Unlock(&lwprot_mutex);
}
}
}
+ #endif
/*-----------------------------------------------------------------------------------*/
#define HZ 100
#endif
+ #if 0
unsigned long
sys_jiffies(void)
{
usec /= 1000000L / HZ;
return HZ * sec + usec;
}
+ #endif
#if PPP_DEBUG
va_start(args, format);
//vprintf(format, args);
- SerialPrintList(format, args);
+ PrintDebug(format, args);
va_end(args);
}
# COREFILES, CORE4FILES: The minimum set of files needed for lwIP.
COREFILES=$(LWIPDIR)/core/mem.c $(LWIPDIR)/core/memp.c $(LWIPDIR)/core/netif.c \
$(LWIPDIR)/core/pbuf.c $(LWIPDIR)/core/stats.c $(LWIPDIR)/core/sys.c \
- $(LWIPDIR)/core/tcp.c $(LWIPDIR)/core/tcp_in.c \
+ $(LWIPDIR)/core/tcp.c $(LWIPDIR)/core/tcp_in.c $(LWIPDIR)/core/raw.c\
$(LWIPDIR)/core/tcp_out.c $(LWIPDIR)/core/udp.c $(LWIPDIR)/core/init.c
CORE4FILES=$(LWIPDIR)/core/ipv4/icmp.c $(LWIPDIR)/core/ipv4/ip.c \
$(LWIPDIR)/core/ipv4/inet.c $(LWIPDIR)/core/ipv4/ip_addr.c \
- $(LWIPDIR)/core/ipv4/inet_chksum.c
+ $(LWIPDIR)/core/ipv4/inet_chksum.c $(LWIPDIR)/core/ipv4/ip_frag.c
# APIFILES: The files which implement the sequential and socket APIs.
APIFILES=$(LWIPDIR)/api/api_lib.c $(LWIPDIR)/api/api_msg.c $(LWIPDIR)/api/tcpip.c \
- $(LWIPDIR)/api/err.c $(LWIPDIR)/api/sockets.c $(LWIPDIR)/api/netbuf.c $(LWIPDIR)/api/netdb.c
+ $(LWIPDIR)/api/err.c $(LWIPDIR)/api/sockets.c $(LWIPDIR)/api/netbuf.c $(LWIPDIR)/api/netdb.c $(LWIPDIR)/api/netifapi.c
# NETIFFILES: Files implementing various generic network interface functions.'
- NETIFFILES=$(LWIPDIR)/netif/loopif.c \
- $(LWIPDIR)/netif/etharp.c
+ NETIFFILES=$(LWIPDIR)/netif/loopif.c $(LWIPDIR)/netif/ne2kif.c $(LWIPDIR)/netif/etharp.c
# ARCHFILES: Architecture specific files.
ARCHFILES=$(LWIPDIR)/arch/sys_arch.c
+ # APPFILES: Application files
+ APPFILES=$(LWIPDIR)/apps/ping.c
+
# LWIPFILES: All the above.
- LWIPFILES=$(COREFILES) $(CORE4FILES) $(APIFILES) $(NETIFFILES) $(ARCHFILES)
+ LWIPFILES=$(COREFILES) $(CORE4FILES) $(APIFILES) $(NETIFFILES) $(ARCHFILES) $(APPFILES)
LWIPFILESW=$(wildcard $(LWIPFILES))
LWIPOBJS=$(notdir $(LWIPFILESW:.c=.o))
- #LWIPLIB=lwip.o
+ # LWIPLIB=lwip.o
%.o:
$(CC) $(CFLAGS) -c $(LWIPFILES)
- all: $(LWIPOBJS)
+ all: $(LWIPOBJS)
cp *.o $(PROJECT_ROOT)build/lwip/
.PHONY: all
clean:
- rm -f *.o $(LWIPLIB) *.s .depend* *.core
+ rm -f *.o .depend*
depend dep: .depend
include .depend
- ##$(LWIPLIB): $(LWIPOBJS)
- ## $(CC) -g -nostartfiles -shared -static $^ -o $@
+ # $(LWIPLIB): $(LWIPOBJS)
+ # $(CC) -g -nostartfiles -shared -static $^ -o $@
.depend: $(LWIPFILES)
$(CC) $(CFLAGS) -MM $^ > .depend || rm -f .depend
if (TCP_SNDLOWAT > TCP_SND_BUF)
LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than or equal to TCP_SND_BUF.\n"));
if (TCP_WND > (PBUF_POOL_SIZE*PBUF_POOL_BUFSIZE))
- LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE*PBUF_POOL_BUFSIZE\n"));
+ LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE*PBUF_POOL_BUFSIZE: %d\n", (PBUF_POOL_SIZE*PBUF_POOL_BUFSIZE)));
if (TCP_WND < TCP_MSS)
LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_WND is smaller than MSS\n"));
#endif /* LWIP_TCP */
--- /dev/null
--- /dev/null
++/**\r
++ * @file\r
++ * Ethernet Interface for ne2k device\r
++ *\r
++ * Lei Xia (lxia@northwestern.edu\r
++ */\r
++\r
++#include "lwip/opt.h"\r
++ \r
++\r
++#include "lwip/def.h"\r
++#include "lwip/mem.h"\r
++#include "lwip/pbuf.h"\r
++#include "lwip/sys.h"\r
++#include <lwip/stats.h>\r
++#include <lwip/snmp.h>\r
++#include "netif/etharp.h"\r
++#include "netif/ppp_oe.h"\r
++#include "lwip/netifapi.h"\r
++#include "netif/ne2kif.h"\r
++\r
++\r
++#include <geekos/ne2k.h>\r
++#include <geekos/ktypes.h>\r
++#include <geekos/debug.h>\r
++\r
++\r
++struct netif ne2kif; \r
++\r
++/**\r
++ * This function should do the actual transmission of the packet. The packet is\r
++ * contained in the pbuf that is passed to the function. This pbuf\r
++ * might be chained.\r
++ *\r
++ * @param netif the lwip network interface structure for this ethernetif\r
++ * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)\r
++ * @return ERR_OK if the packet could be sent\r
++ * an err_t value if the packet couldn't be sent\r
++ *\r
++ * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to\r
++ * strange results. You might consider waiting for space in the DMA queue\r
++ * to become availale since the stack doesn't retry to send a packet\r
++ * dropped because of memory failure (except for the TCP timers).\r
++ */\r
++\r
++err_t\r
++ne2kif_output(struct netif *netif, struct pbuf *p)\r
++{\r
++ struct pbuf *q;\r
++ int size, offset, remlen;\r
++ uchar_t *packet;\r
++ \r
++#if ETH_PAD_SIZE\r
++ pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */\r
++#endif\r
++\r
++ size = p->tot_len;\r
++ offset = 0;\r
++ remlen = size;\r
++\r
++ packet = (uchar_t *)Malloc (remlen);\r
++\r
++ for(q = p; q != NULL && remlen >0; q = q->next) {\r
++ /* Send the data from the pbuf to the interface, one pbuf at a\r
++ time. The size of the data in each pbuf is kept in the ->len\r
++ variable. */\r
++\r
++ memcpy(packet+offset, q->payload, q->len < remlen? q->len:remlen);\r
++ remlen -= q->len;\r
++ offset += q->len;\r
++ \r
++ }\r
++ NE2K_Send_Packet(packet, size);\r
++\r
++ //signal that packet should be sent();\r
++\r
++#if ETH_PAD_SIZE\r
++ pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */\r
++#endif\r
++ \r
++ LINK_STATS_INC(link.xmit);\r
++\r
++ return ERR_OK;\r
++}\r
++\r
++\r
++/**\r
++ * This function should be called when a packet is ready to be read\r
++ * from the interface. It uses the function low_level_input() that\r
++ * should handle the actual reception of bytes from the network\r
++ * interface. Then the type of the received packet is determined and\r
++ * the appropriate input function is called.\r
++ *\r
++ * @param netif the lwip network interface structure for this ethernetif\r
++ */\r
++void\r
++ne2kif_input(struct NE2K_Packet_Info * info, uchar_t * pkt)\r
++{\r
++ struct pbuf *p, *q;\r
++ uint_t offset;\r
++ uint_t len, rlen;\r
++ \r
++ len = info->size; \r
++\r
++ PrintBoth("Ne2k: Packet REceived\n");\r
++\r
++#if ETH_PAD_SIZE\r
++ len += ETH_PAD_SIZE; // allow room for Ethernet padding \r
++#endif\r
++\r
++ p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);\r
++ \r
++ if (p != NULL) {\r
++\r
++#if ETH_PAD_SIZE\r
++ pbuf_header(p, -ETH_PAD_SIZE); // drop the padding word \r
++#endif\r
++\r
++ // iterate over the pbuf chain until it has read the entire packet into the pbuf.\r
++ for(offset = 0, q = p; q != NULL && rlen > 0; q = q->next) {\r
++ memcpy(q->payload, pkt+offset, rlen > q->len? q->len: rlen);\r
++ rlen -= q->len;\r
++ offset += q->len;\r
++ }\r
++\r
++#if ETH_PAD_SIZE\r
++ pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */\r
++#endif\r
++\r
++ LINK_STATS_INC(link.recv);\r
++ } else {\r
++ LINK_STATS_INC(link.memerr);\r
++ LINK_STATS_INC(link.drop);\r
++ }\r
++\r
++ Free(pkt);\r
++ \r
++ if (p == NULL) return;\r
++ /* points to packet payload, which starts with an Ethernet header */\r
++ //ethhdr = p->payload;\r
++\r
++ /* full packet send to tcpip_thread to process */\r
++ if (ne2kif.input(p, &ne2kif)!=ERR_OK)\r
++ { LWIP_DEBUGF(NETIF_DEBUG, ("ne2kif_input: IP input error\n"));\r
++ pbuf_free(p);\r
++ p = NULL;\r
++ }\r
++\r
++#if 0\r
++ switch (htons(ethhdr->type)) {\r
++ /* IP or ARP packet? */\r
++ case ETHTYPE_IP:\r
++ case ETHTYPE_ARP:\r
++#if PPPOE_SUPPORT\r
++ /* PPPoE packet? */\r
++ case ETHTYPE_PPPOEDISC:\r
++ case ETHTYPE_PPPOE:\r
++#endif /* PPPOE_SUPPORT */\r
++ \r
++ break;\r
++\r
++ default:\r
++ pbuf_free(p);\r
++ p = NULL;\r
++ break;\r
++ }\r
++#endif\r
++\r
++}\r
++\r
++/**\r
++ * Should be called at the beginning of the program to set up the\r
++ * network interface. It calls the function low_level_init() to do the\r
++ * actual setup of the hardware.\r
++ *\r
++ * This function should be passed as a parameter to netif_add().\r
++ *\r
++ * @param netif the lwip network interface structure for this ethernetif\r
++ * @return ERR_OK if the loopif is initialized\r
++ * ERR_MEM if private data couldn't be allocated\r
++ * any other err_t on error\r
++ */\r
++err_t\r
++ne2kif_init(struct netif *netif)\r
++{\r
++\r
++#if LWIP_NETIF_HOSTNAME\r
++ /* Initialize interface hostname */\r
++ netif->hostname = "lwip";\r
++#endif /* LWIP_NETIF_HOSTNAME */\r
++\r
++ /*\r
++ * Initialize the snmp variables and counters inside the struct netif.\r
++ * The last argument should be replaced with your link speed, in units\r
++ * of bits per second.\r
++ */\r
++ NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 10000000);\r
++\r
++ netif->state = NULL;\r
++ netif->name[0] = 'n';\r
++ netif->name[1] = 'e';\r
++ /* We directly use etharp_output() here to save a function call.\r
++ * You can instead declare your own function an call etharp_output()\r
++ * from it if you have to do some checks before sending (e.g. if link\r
++ * is available...) */\r
++ netif->output = etharp_output;\r
++ netif->linkoutput = ne2kif_output;\r
++ \r
++\r
++ /* set MAC hardware address length */\r
++ netif->hwaddr_len = ETHARP_HWADDR_LEN;\r
++\r
++ /* set MAC hardware address */\r
++ netif->hwaddr[0] = PHY_ADDR1;\r
++ netif->hwaddr[1] = PHY_ADDR2;\r
++ netif->hwaddr[2] = PHY_ADDR3;\r
++ netif->hwaddr[3] = PHY_ADDR4;\r
++ netif->hwaddr[4] = PHY_ADDR5;\r
++ netif->hwaddr[5] = PHY_ADDR6;\r
++\r
++ /* maximum transfer unit */\r
++ netif->mtu = 1500;\r
++ \r
++ /* device capabilities */\r
++ /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */\r
++ netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;\r
++\r
++ //initate ne2k hardware\r
++ Init_Ne2k(&ne2kif_input);\r
++\r
++ return ERR_OK;\r
++}\r
uip_flags = 0;
return;
}
+
/*---------------------------------------------------------------------------*/
+ /* replicate defined in lwip.c,
u16_t
htons(u16_t val)
{
return HTONS(val);
}
+ */
+
/*---------------------------------------------------------------------------*/
void
uip_send(const void *data, int len)
#
# The setup code needs to copy it up to this address and jump there
#
-KERNEL_BASE_ADDR := 0x00100000
-# Kernel entry point function
-KERNEL_ENTRY = $(SYM_PFX)Main
+
PROJECT_ROOT := ..
ifeq ($(DECODER),XED)
DECODER_SRCS := vmm_xed.c
DECODER_FLAGS := -L../lib/xed
-DECODER_LIBS := -lxed
+DECODER_LIBS := $(PROJECT_ROOT)/lib/xed/libxed.a
else
# This is an error
endif
-#
-#TCPSTACK, uIP is used currently
-#
-UIP=OFF
-
-#
-#LWIP, ON -- used, OFF -- not used
-#
-LWIP=ON
-#
-#RAMDISK
-#
-RAMDISK_SRCS=
-BOOT_FLAGS=
-ifeq ($(RAMDISK_BOOT),1)
-BOOT_FLAGS := $(BOOT_FLAGS) -DRAMDISK_BOOT
-RAMDISK_SRCS := ramdisk.c cdrom.c
-endif
# List of targets to build by default.
# These targets encompass everything needed to boot
# and run GeekOS.
-ALL_TARGETS := vmm.img vm_kernel
-
-
-# Kernel source files
-KERNEL_C_SRCS := idt.c int.c trap.c irq.c io.c \
- blockdev.c ide.c ne2k.c \
- keyboard.c screen.c timer.c \
- mem.c crc32.c \
- gdt.c tss.c segment.c \
- bget.c malloc.c \
- synch.c kthread.c \
- serial.c reboot.c \
- paging.c \
- debug.c vmm_stubs.c vm.c pci.c\
- queue.c socket.c net.c ring_buffer.c \
- main.c
-
+ALL_TARGETS := vmm vm_kernel
-# Kernel object files built from C source files
-KERNEL_C_OBJS := $(KERNEL_C_SRCS:%.c=geekos/%.o)
-# Kernel assembly files
-KERNEL_ASM_SRCS := lowlevel.asm
-KERNEL_GAS_SRCS := testvm.s udivdi3.s
-# Kernel object files build from assembler source files
-KERNEL_ASM_OBJS := $(KERNEL_ASM_SRCS:%.asm=geekos/%.o)
-KERNEL_GAS_OBJS := $(KERNEL_GAS_SRCS:%.s=geekos/%.o)
-
-# All kernel object files
-KERNEL_OBJS := $(KERNEL_C_OBJS) \
- $(KERNEL_ASM_OBJS) $(KERNEL_GAS_OBJS)
-
-# Common library source files.
-# This library is linked into both the kernel and user programs.
-# It provides string functions and generic printf()-style
-# formatted output.
-COMMON_C_SRCS := fmtout.c string.c memmove.c
-
-# Common library object files.
-COMMON_C_OBJS := $(COMMON_C_SRCS:%.c=common/%.o)
-
-VMM_ASM_SRCS := svm_lowlevel.asm \
+VMM_ASM_SRCS := svm_lowlevel.asm vmm_lowlevel.asm\
# vmx_lowlevel.asm
VMM_ASM_OBJS := $(VMM_ASM_SRCS:%.asm=palacios/%.o)
+XED_C_SRCS := v3-xed-compat.c
-DEVICE_C_SRCS := generic.c keyboard.c nvram.c timer.c simple_pic.c 8259a.c 8254.c serial.c $(RAMDISK_SRCS)
+XED_C_OBJS := $(XED_C_SRCS:%.c=xed/%.o)
-DEVICE_C_OBJS := $(DEVICE_C_SRCS:%.c=devices/%.o)
+XED_GAS_SRCS := v3-udiv-compat.s
-DEVICE_OBJS := $(DEVICE_C_OBJS)
+XED_GAS_OBJS := $(XED_GAS_SRCS:%.s=xed/%.o)
-V3LIBS := $(DECODER_LIBS)
+XED_OBJS := $(XED_C_OBJS) $(XED_GAS_OBJS)
+
+DEVICE_C_SRCS := generic.c keyboard.c nvram.c timer.c simple_pic.c 8259a.c 8254.c serial.c ramdisk.c cdrom.c
-ifeq ($(UIP),ON)
- UIP_C_SRCS := psock.c timer.c uip_arp.c uip.c uip-fw.c uiplib.c uip-neighbor.c uip-split.c resolv.c
- UIP_C_OBJS := $(UIP_C_SRCS:%.c=net/%.o)
-else
- UIP_C_SRCS :=
- UIP_C_OBJS :=
-endif
+DEVICE_C_OBJS := $(DEVICE_C_SRCS:%.c=devices/%.o)
-ifeq ($(LWIP),ON)
- LWIP_OBJS := lwip/*.o
- CC_LWIP_OPTS := -I$(PROJECT_ROOT)/include/lwip -I$(PROJECT_ROOT)/include/lwip/ipv4 -I$(PROJECT_ROOT)/include/libc -DLWIP_DEBUG
-else
- LWIP_OBJS :=
- CC_LWIP_OPTS :=
-endif
+DEVICE_OBJS := $(DEVICE_C_OBJS)
+
+V3LIBS := $(DECODER_LIBS)
+
# ----------------------------------------------------------------------
# Tools -
# This section defines programs that are used to build GeekOS.
TARGET_CC := $(TARGET_CC_PREFIX)gcc
#TARGET_CC := $(TARGET_CC_PREFIX)gcc34 -m32
-# Host C compiler. This is used to compile programs to execute on
-# the host platform, not the target (x86) platform. On x86/ELF
-# systems, such as Linux and FreeBSD, it can generally be the same
-# as the target C compiler.
-HOST_CC := gcc
# Target linker. GNU ld is probably to only one that will work.
TARGET_LD := $(TARGET_CC_PREFIX)ld -melf_i386
# ----------------------------------------------------------------------
# Flags used for all C source files
-GENERAL_OPTS := -O -Wall $(EXTRA_C_OPTS) $(VMM_FLAGS) $(BOOT_FLAGS) -fPIC
+GENERAL_OPTS := -O -Wall $(EXTRA_C_OPTS) $(VMM_FLAGS) -fPIC #-fvisibility=hidden
CC_GENERAL_OPTS := $(GENERAL_OPTS) -Werror
-# Flags used for kernel C source files
-CC_KERNEL_OPTS := -g -DGEEKOS -I$(PROJECT_ROOT)/include
-
# Flags used for VMM C source files
CC_VMM_OPTS := -g -I$(PROJECT_ROOT)/include -D__V3VEE__ -D__V3_32BIT__ $(DECODER_FLAGS) $(JRLDEBUG)
# Flags used for VMM C ASM files
NASM_VMM_OPTS := -I$(PROJECT_ROOT)/src/palacios/ -f elf $(EXTRA_NASM_OPTS)
-# Flags user for kernel assembly files
-NASM_KERNEL_OPTS := -I$(PROJECT_ROOT)/src/geekos/ -f elf $(EXTRA_NASM_OPTS)
-# Flags used for common library and libc source files
-CC_USER_OPTS := -I$(PROJECT_ROOT)/include -I$(PROJECT_ROOT)/include/libc \
- $(EXTRA_CC_USER_OPTS)
+
+
# Flags passed to objcopy program (strip unnecessary sections from kernel.exe)
OBJCOPY_FLAGS := -R .dynamic -R .note -R .comment
# Describes how to compile the source files.
# ----------------------------------------------------------------------
-# Compilation of kernel C source files
-geekos/%.o : geekos/%.c
- $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_KERNEL_OPTS) $(CC_LWIP_OPTS) $< -o geekos/$*.o
-
-
-# Compilation of kernel assembly source files
-geekos/%.o : geekos/%.asm
- $(NASM) $(NASM_KERNEL_OPTS) $< -o geekos/$*.o
-
-# Compilation of test VM
-geekos/%.o : geekos/%.s
- $(AS) $< -o geekos/$*.o
-
-geekos/%.o : geekos/%.S
- $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_KERNEL_OPTS) $< -o geekos/$*.o
-
-# Compilation of common library C source files
-common/%.o : common/%.c
- $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_USER_OPTS) $< -o common/$*.o
-
palacios/%.o : palacios/%.c
$(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_VMM_OPTS) $< -o palacios/$*.o
devices/%.o : devices/%.asm
$(NASM) $(NASM_VMM_OPTS) $< -o devices/$*.o
-net/%.o : net/%.c
- $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_USER_OPTS) $< -o net/$*.o
+
+xed/%.o : xed/%.c
+ $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_VMM_OPTS) $< -o xed/$*.o
+
+xed/%.o : xed/%.s
+ $(AS) $< -o xed/$*.o
+
# ----------------------------------------------------------------------
# Targets -
#geekos/test: geekos/test.o geekos/vmcs.o geekos/vmx_lowlevel.o
# $(CC) geekos/test.o geekos/vmcs.o geekos/vmx_lowlevel.o -o geekos/test
-# Standard floppy image - just boots the kernel
-fd.img : geekos/fd_boot.bin geekos/setup.bin geekos/kernel.bin
- cat geekos/fd_boot.bin geekos/setup.bin geekos/kernel.bin > _temp
- $(PAD) _temp 512
- cp _temp fd.img
-vmm.img : fd.img
- cp fd.img vmm.img
- $(PAD) vmm.img 1474560
rombios_link:
ln -s -f ../src/vmboot/rombios/BIOS-bochs-latest rombios
vgabios_link:
ln -s -f ../src/vmboot/vgabios/VGABIOS-lgpl-latest.bin vgabios
+ force_lwip:
+ (cd ../src/lwip/build; make clean; make)
+
force_rombios: rombios_link
(cd ../src/vmboot/rombios; make clean; make)
force_payload: force_rombios force_vgabios
../scripts/make_payload.pl payload_layout.txt vm_kernel
- inter1: force_payload
+ inter1: force_payload force_lwip
-make clean
-world: inter1 vmm.img
-
-# make ready to boot over PXE
-pxe: vmm.img
- cp vmm.img /tftpboot/vmm.img
+world: inter1 vmm
-run: vmm.img
- /usr/local/qemu/bin/qemu-system-x86_64 -m 1024 -serial file:serial.out -cdrom puppy.iso -fda vmm.img
+vmm: palacios/vmm.lib
-# Floppy boot sector (first stage boot loader).
-geekos/fd_boot.bin : geekos/setup.bin geekos/kernel.bin $(PROJECT_ROOT)/src/geekos/fd_boot.asm
- $(NASM) -f bin \
- -I$(PROJECT_ROOT)/src/geekos/ \
- -DNUM_SETUP_SECTORS=`$(NUMSECS) geekos/setup.bin` \
- -DNUM_KERN_SECTORS=`$(NUMSECS) geekos/kernel.bin` \
- -DSECTORS_PER_TRACK=`$(FD_SECTORS_PER_TRACK) geekos/kernel.bin geekos/setup.bin` \
- $(PROJECT_ROOT)/src/geekos/fd_boot.asm \
- -o $@
-
-# Setup program (second stage boot loader).
-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_SIZE=`$(NUMSECS) geekos/kernel.bin` \
- $(PROJECT_ROOT)/src/geekos/setup.asm \
- -o $@
- $(PAD) $@ 2048
-
# Loadable (flat) kernel image.
-geekos/kernel.bin : geekos/kernel.exe
- $(TARGET_OBJCOPY) $(OBJCOPY_FLAGS) -S -O binary geekos/kernel.exe geekos/kernel.bin
- $(PAD) $@ 512
+palacios/vmm.bin : palacios/vmm.lib
+ $(TARGET_OBJCOPY) $(OBJCOPY_FLAGS) -S -O binary palacios/vmm.lib palacios/vmm.bin
+
# The kernel executable and symbol map.
-geekos/kernel.exe : $(KERNEL_OBJS) $(COMMON_C_OBJS) $(VMM_OBJS) $(DEVICE_OBJS) $(TCPSTACK_OBJS) vm_kernel
- $(TARGET_LD) -o geekos/kernel.exe -Ttext $(KERNEL_BASE_ADDR) -e $(KERNEL_ENTRY) \
- $(DECODER_FLAGS) \
- $(KERNEL_OBJS) $(COMMON_C_OBJS) $(VMM_OBJS) $(DEVICE_OBJS) $(V3LIBS) $(TCPSTACK_OBJS) -b binary vm_kernel
- $(TARGET_NM) geekos/kernel.exe > geekos/kernel.syms
+palacios/vmm.lib: $(VMM_OBJS) $(DEVICE_OBJS) $(XED_OBJS) vm_kernel
+# $(TARGET_LD) -o palacios/vmm.lib \
+# $(DECODER_FLAGS) \
+# $(VMM_OBJS) $(DEVICE_OBJS) $(XED_OBJS) $(V3LIBS) -b binary vm_kernel
+# $(TARGET_NM) palacios/vmm.lib > palacios/vmm.syms
+ $(TARGET_AR) rcs libv3vee.a \
+ $(VMM_OBJS) $(DEVICE_OBJS) $(XED_OBJS)
-force:
+force:
-#vm_kernel: force
-# $(PAD) vm_kernel 512
-# @echo "VM kernel lives at 0x100000 and is" `$(NUMSECS) vm_kernel` "sectors long"
# Clean build directories of generated files
clean :
- for d in geekos common libc user tools palacios devices net; do \
+ for d in palacios devices; do \
(cd $$d && rm -f *); \
done
# Build header file dependencies, so source files are recompiled when
# header files they depend on are modified.
depend : $(GENERATED_LIBC_SRCS)
- $(TARGET_CC) -M $(CC_GENERAL_OPTS) $(CC_KERNEL_OPTS) \
- $(KERNEL_C_SRCS:%.c=$(PROJECT_ROOT)/src/geekos/%.c) \
- | $(PERL) -n -e 's,^(\S),geekos/$$1,;print' \
- > depend.mak
- $(TARGET_CC) -M $(CC_GENERAL_OPTS) $(CC_USER_OPTS) \
- $(COMMON_C_SRCS:%.c=$(PROJECT_ROOT)/src/common/%.c) \
- | $(PERL) -n -e 's,^(\S),common/$$1,;print' \
- >> depend.mak
+
$(TARGET_CC) -M $(CC_GENERAL_OPTS) $(CC_KERNEL_OPTS) \
$(VMM_C_SRCS:%.c=$(PROJECT_ROOT)/src/palacios/%.c) \
| $(PERL) -n -e 's,^(\S),palacios/$$1,;print' \