Merge branch 'master' into readwrite

This commit is contained in:
Marian Ohligs 2012-02-08 10:05:24 +01:00
commit 181610783e
8 changed files with 206 additions and 59 deletions

View file

@ -5,19 +5,28 @@ LWIPDIRS = lwip/src/arch lwip/src/api lwip/src/core lwip/src/core/ipv4 lwip/src/
DRIVERDIRS = drivers/net drivers/char
KERNDIRS = libkern kernel mm fs apps arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/scc $(LWIPDIRS) $(DRIVERDIRS)
SUBDIRS = $(KERNDIRS)
STACKPROT=-fno-stack-protector
# Set your own cross compiler tool chain prefix here
CROSSCOMPREFIX=
# Uncomment both lines if compiling for the SCC!
#CROSSCOMPREFIX=i386-unknown-linux-gnu-
#STACKPROT=
CC_FOR_TARGET=$(CROSSCOMPREFIX)gcc
CXX_FOR_TARGET=$(CROSSCOMPREFIX)g++
GCC_FOR_TARGET=$(CROSSCOMPREFIX)gcc
AR_FOR_TARGET=$(CROSSCOMPREFIX)ar
AS_FOR_TARGET=$(CROSSCOMPREFIX)as
LD_FOR_TARGET=$(CROSSCOMPREFIX)ld
NM_FOR_TARGET=$(CROSSCOMPREFIX)nm
OBJDUMP_FOR_TARGET=$(CROSSCOMPREFIX)objdump
OBJCOPY_FOR_TARGET=$(CROSSCOMPREFIX)objcopy
RANLIB_FOR_TARGET=$(CROSSCOMPREFIX)ranlib
STRIP_FOR_TARGET=$(CROSSCOMPREFIX)strip
READELF_FOR_TARGET=$(CROSSCOMPREFIX)readelf
CC_FOR_TARGET=gcc
CXX_FOR_TARGET=g++
GCC_FOR_TARGET=gcc
AR_FOR_TARGET=ar
AS_FOR_TARGET=as
LD_FOR_TARGET=ld
NM_FOR_TARGET=nm
OBJDUMP_FOR_TARGET=objdump
OBJCOPY_FOR_TARGET=objcopy
RANLIB_FOR_TARGET=ranlib
STRIP_FOR_TARGET=strip
READELF_FOR_TARGET=readelf
NASM = nasm
EMU=qemu
GDB=gdb
@ -26,9 +35,9 @@ MAKE = make
NASMFLAGS = -felf32 -g
INCLUDE = -I$(TOPDIR)/include -I$(TOPDIR)/arch/$(ARCH)/include -I$(TOPDIR)/lwip/src/include -I$(TOPDIR)/lwip/src/include/ipv4 -I$(TOPDIR)/drivers
# Compiler options for final code
CFLAGS = -g -m32 -march=i586 -Wall -O2 -fno-builtin -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc $(INCLUDE) -fno-stack-protector
CFLAGS = -g -m32 -march=i586 -Wall -O2 -fno-builtin -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc $(INCLUDE) $(STACKPROT)
# Compiler options for debuuging
#CFLAGS = -g -O -m32 -march=i586 -Wall -fno-builtin -DWITH_FRAME_POINTER -nostdinc $(INCLUDE) -fno-stack-protector
#CFLAGS = -g -O -m32 -march=i586 -Wall -fno-builtin -DWITH_FRAME_POINTER -nostdinc $(INCLUDE) $(STACKPROT)
ARFLAGS = rsv
RM = rm -rf
LDFLAGS = -T link.ld -z max-page-size=4096 --defsym __BUILD_DATE=$(shell date +'%Y%m%d') --defsym __BUILD_TIME=$(shell date +'%H%M%S')
@ -47,7 +56,7 @@ default: all
all: newlib tools $(NAME).elf
newlib:
$(MAKE) ARCH=$(ARCH) LDFLAGS="-m32" CFLAGS="-m32 -O2 -march=i586 -fno-stack-protector" NASMFLAGS="$(NASMFLAGS)" CC_FOR_TARGET=$(CC_FOR_TARGET) \
$(MAKE) ARCH=$(ARCH) LDFLAGS="-m32" CFLAGS="-m32 -O2 -march=i586 $(STACKPROT)" NASMFLAGS="$(NASMFLAGS)" CC_FOR_TARGET=$(CC_FOR_TARGET) \
CXX_FOR_TARGET=$(CXX_FOR_TARGET) \
GCC_FOR_TARGET=$(GCC_FOR_TARGET) \
AR_FOR_TARGET=$(AR_FOR_TARGET) \

View file

@ -127,6 +127,9 @@ int timer_wait(unsigned int ticks)
}
#define LATCH(f) ((CLOCK_TICK_RATE + f/2) / f)
#define WAIT_SOME_TIME() do { uint64_t start = rdtsc(); \
while(rdtsc() - start < 1000000) ; \
} while (0)
/*
* Sets up the system clock by installing the timer handler
@ -134,10 +137,6 @@ int timer_wait(unsigned int ticks)
*/
int timer_init(void)
{
#ifndef CONFIG_ROCKCREEK
uint64_t start;
#endif
/*
* Installs 'timer_handler' for the PIC and APIC timer,
* only one handler will be later used.
@ -150,16 +149,27 @@ int timer_init(void)
* Therefore, we have not to configure the PIC timer.
*/
#ifndef CONFIG_ROCKCREEK
/*
* Port 0x43 is for initializing the PIT:
*
* 0x34 means the following:
* 0b... (step-by-step binary representation)
* ... 00 - channel 0
* ... 11 - write two values to counter register:
* first low-, then high-byte
* ... 010 - mode number 2: "rate generator" / frequency divider
* ... 0 - binary counter (the alternative is BCD)
*/
outportb(0x43, 0x34);
/* before we write to 0x40, we wait some time */
start = rdtsc();
while(rdtsc() - start < 1000000)
;
WAIT_SOME_TIME();
/* Port 0x40 is for the counter register of channel 0 */
outportb(0x40, LATCH(TIMER_FREQ) & 0xFF); /* low byte */
/* before we write to 0x40, we wait some time */
start = rdtsc();
while(rdtsc() - start < 1000000)
;
WAIT_SOME_TIME();
outportb(0x40, LATCH(TIMER_FREQ) >> 8); /* high byte */
#endif

View file

@ -764,6 +764,11 @@ int arch_paging_init(void)
if (mb_info && (mb_info->flags & MULTIBOOT_INFO_MODS)) {
multiboot_module_t* mmodule = (multiboot_module_t*) mb_info->mods_addr;
npages = mb_info->mods_count * sizeof(multiboot_module_t) >> PAGE_SHIFT;
if (mb_info->mods_count * sizeof(multiboot_module_t) & (PAGE_SIZE-1))
npages++;
map_region((size_t) (mb_info->mods_addr), (size_t) (mb_info->mods_addr), npages, MAP_KERNEL_SPACE);
for(i=0; i<mb_info->mods_count; i++, mmodule++) {
// map physical address to the same virtual address
npages = (mmodule->mod_end - mmodule->mod_start) >> PAGE_SHIFT;

View file

@ -45,23 +45,18 @@ $ cp include/metalsvm/config.h.example include/metalsvm/config.h \endverbatim
*
* -# Intel recommends to use their cross-compiler for generating code which is guaranteed to be SCC-compatible. Just set the environment variables with the following command:
* \verbatim$ . /opt/compilerSetupFiles/crosscompile.sh \endverbatim
* -# The Makefile needs to be adapted to actually use the cross compiler:
* \verbatim
CC_FOR_TARGET=i386-unknown-linux-gnu-gcc
CXX_FOR_TARGET=i386-unknown-linux-gnu-g++
GCC_FOR_TARGET=i386-unknown-linux-gnu-gcc
AR_FOR_TARGET=i386-unknown-linux-gnu-ar
AS_FOR_TARGET=i386-unknown-linux-gnu-as
LD_FOR_TARGET=i386-unknown-linux-gnu-ld
NM_FOR_TARGET=i386-unknown-linux-gnu-nm
OBJDUMP_FOR_TARGET=i386-unknown-linux-gnu-objdump
OBJCOPY_FOR_TARGET=i386-unknown-linux-gnu-objcopy
RANLIB_FOR_TARGET=i386-unknown-linux-gnu-ranlib
STRIP_FOR_TARGET=i386-unknown-linux-gnu-strip
READELF_FOR_TARGET=i386-unknown-linux-gnu-readelf \endverbatim
* -# The Makefile needs to be adapted to actually use the cross compiler.
* Just uncomment two lines like seen here:
* \code
# Set your own cross compiler tool chain prefix here
CROSSCOMPREFIX=
# Uncomment both lines if compiling for the SCC!
CROSSCOMPREFIX=i386-unknown-linux-gnu-
STACKPROT=\endcode
* -# Another important change in the Makefile is disabling the "-fno-stack-protector" option. It occurs several times.
* -# The SCC requires a special configuration for the MetalSVM kernel:
* \verbatim
* \code
//#define CONFIG_PCI
//#define CONFIG_VGA
//#define CONFIG_UART
@ -75,11 +70,11 @@ READELF_FOR_TARGET=i386-unknown-linux-gnu-readelf \endverbatim
//#define GORY
//#define SHMADD
#define SHMDBG
//#define SHMADD_CACHEABLE \endverbatim
//#define SHMADD_CACHEABLE \endcode
* -# There is only one core per tile, so it is adequate to reduce overhead by disabling SMP in MetalSVM:
* \verbatim#define MAX_CORES 1 \endverbatim
* \code#define MAX_CORES 1 \endcode
* -# Cache-line size is 32 byte:
* \verbatim#define CACHE_LINE 32 \endverbatim
* \code#define CACHE_LINE 32 \endcode
* -# MetalSVM can now be built using \c make.
* -# Build the SCC tools:
* \verbatim

View file

@ -1,7 +0,0 @@
/**
* @file kernelspace.dox
* @page kernelspace Development in kernel space
*
* @section kernelthreads Starting kernel threads
*
*/

View file

@ -0,0 +1,136 @@
/**
* @file tasks.dox
* @page tasks Creating your own tasks in MetalSVM
*
*
* @section toc Table of Contents
* - @ref initd
* - @ref kerneltasks
* - @ref usertasks
*
* @section initd Where MetalSVM starts tasks after boot
*
* The last step after booting is starting the \c initd process:
*
* \c kernel/main.c:
* \code
...
create_kernel_task (&id, initd, NULL, NORMAL_PRIO);
...\endcode
*
* \c Initd starts all the other processes and then exits.
* The list of processes to start is defined in \c kernel/tests.c
* within \c test_init():
*
* \code
int test_init(void)
{
/* This is how the ARGV parameter list is defined */
char* argv[] = {"/bin/tests", NULL};
char* server_argv[] = {"/bin/server", "6789", NULL};
char* client_argv[] = {"/bin/client", "192.168.0.1", "6789", NULL};
...
/* Starting kernel- and user space tasks */
create_kernel_task(NULL, foo, "Hello from foo1", NORMAL_PRIO);
create_kernel_task(NULL, join_test, NULL, NORMAL_PRIO);
create_user_task(NULL, "/bin/tests", argv);
return 0;
}\endcode
*
* @section kerneltasks Creating kernel tasks
*
* To create your own kernel task, you will need to write a task first.
* This can look like the following example task in \c kernel/tests.c:
*
* \code
static int foo(void* arg)
{
int i;
if (!arg)
return 0;
for(i=0; i<5; i++) {
kprintf("%s\n", (char*) arg);
sleep(1);
}
return 42;
}\endcode
*
* A kernel task is just a procedure within the scope of init_test().
* Its signature should match the following pattern:
* \code int my_task(void* my_args)\endcode
*
* To make \c initd start your task after booting the system, you will need to
* write a \c create_kernel_task() call within \c test_init() which looks like
* the \c foo example from the section above:
* \code create_kernel_task(NULL, foo, "Hello from foo1", NORMAL_PRIO); \endcode
*
* The \c create_kernel_task procedure has the following signature:
* \code int create_kernel_task(tid_t* id, entry_point_t ep, void* args, uint8_t prio)\endcode
* Its parameters are the following:
* - \c id: Provide the address of a \c tid_t variable here, if you need the new
* task's ID.
* - \c ep: The entry point of your task is just its function/procedure symbol.
* - \c args: The address of the parameter structure your task expects.
* - \c prio: The priority your task shall be executed with. Priority levels are
* defined in \c include/metalsvm/tasks_types.h:
* \code
#define MAX_PRIO 31
#define REALTIME_PRIO 31
#define HIGH_PRIO 16
#define NORMAL_PRIO 8
#define LOW_PRIO 1
#define IDLE_PRIO 0\endcode
*
* @section usertasks Creating user space tasks
*
* User space tasks are usually not defined within the kernel code,
* therefore they are launched differently.
*
* To write your own user space application, place your *.c source code within
* \c newlib/examples/ and add a target in the Makefile (\c newlib/examples/Makefile)
* to ensure that your application is built when you type \c "make" in the
* MetalSVM directory.
*
* If your code does not consist of just some *.c and *.h files and you rather want
* keep your own project folder: The only important thing for later is that your
* executables and other runtime-needed files lay in the \c newlib/examples/ directory
* during build of the initial ramdisk.
*
* The scripts which build MetalSVM's initial ramdisk are launched when the kernel
* itself is built. \c metalsvm.elf and \c tools/initrd.img together
* compose a bootable system which is rebuilt (if necessary) everytimes you run
* \c make in the project directory.
*
* The initrd building scripts include every file within the \c newlib/examples/
* directory which is marked as \b execuable. Do not forget this if you use your
* own build scripts!
*
* After providing your own executable for the system within the initial ramdisk,
* it still needs to be executed after boot. This is done very similarly to
* launching kernel threads.
*
* Place your application launching \c create_user_task() call within \c test_init():
* \code create_user_task(NULL, "/bin/tests", argv);\endcode
*
* In this case the executable \c tests is launched with the parameter array \c argv.
* Note that at build-time the executable is located at \c newlib/examples/tests.
* The \c argv array is constructed like in the example at the top of this page.
*
* \c create_user_task()'s signature looks like this:
* \code int create_user_task(tid_t* id, const char* fname, char** argv)\endcode
* Its parameters are the following:
* - \c id: Provide the address of a \c tid_t variable if you need the ID of your
* started process.
* - \c fname: This string denotes the path of your executable within the file system.
* Every executable which comes from \c newlib/examples/ will be located within
* \c /bin in MetalSVM's file system after boot.
* - \c argv: This is the ARGV-structure the task will be equipped with after launch.
*
*
*/

View file

@ -1,7 +0,0 @@
/**
* @file userspace.dox
* @page userspace Development in user space
*
* @section ownapps Installing and launching your own applications
*
*/

View file

@ -143,6 +143,12 @@ int mmu_init(void)
atomic_int32_inc(&total_allocated_pages);
atomic_int32_dec(&total_available_pages);
for(addr = mb_info->mods_addr; addr < mb_info->mods_addr + mb_info->mods_count * sizeof(multiboot_module_t); addr += PAGE_SIZE) {
page_set_mark(addr >> PAGE_SHIFT);
atomic_int32_inc(&total_allocated_pages);
atomic_int32_dec(&total_available_pages);
}
for(i=0; i<mb_info->mods_count; i++, mmodule++) {
for(addr=mmodule->mod_start; addr<mmodule->mod_end; addr+=PAGE_SIZE) {
page_set_mark(addr >> PAGE_SHIFT);