Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 1600 → Rev 1601

/demos/trunk/dynademo/data.bin
0,0 → 1,11
//////////////////////////////////////////////////////////////////////
/////////////// User Application running /////////////////////////////
 
Dynalink demo.
 
An ELF object (which is running now) and a data file
(which you read now) are parsed as 'boot modules'
to the S.H.A.R.K kernel by GRUB.
 
Press a key to continue with this lame application.....:)
//////////////////////////////////////////////////////////////////////
/demos/trunk/dynademo/app.c
0,0 → 1,188
///////////////////////////////////////////////////
// app.c -Lex Nahumury 2006
//
// This would be the Closed Source User Application part.
// The ELF object itself contains no GPL code.
// The references to GPL code are resolved
// by the Dynamic Linker after the kernel has loaded.
//
//////////////////////////////////////////////////
 
/*
Usage example:
 
# For booting SHARK image from HD
title S.H.A.R.K + Boot Modules from HD 0,0
kernel (hd0,0)/boot/os mount root=/dev/hda1
module (hd0,0)/boot/sh_app.bin
module (hd0,0)/boot/data.bin
 
*/
 
#include "kernel/kern.h"
#include <kernel/func.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "ll/i386/cons.h"
 
#include <drivers/shark_keyb26.h>
#include "../../ports/dynalink/dynalink.h"
 
extern void call_shutdown_task(void *arg);
extern DWORD get_tick();
 
struct params
{
int task_nr;
int row;
int count;
int cycles;
};
 
 
TASK periodic_task(void *arg)
{
int ani=0;
char c[2];
struct params* p = (struct params*)(arg);
int row = p->row;
char txt[4];
p->count=0;
 
while(p->count < p->cycles)
{
switch(ani)
{
case 0:
ani=1; sprintf(c,"%s", "\\");
break;
case 1:
ani=2; sprintf(c,"/");
break;
case 2:
ani=0; sprintf(c,"-");
break;
}
puts_xy(12,row,YELLOW, c );
 
++p->count;
sprintf(txt,"%02d", p->count);
puts_xy(8,row,YELLOW, txt);
task_endcycle();
}
 
cprintf("Task #%d end.\n", p->task_nr);
if(p->task_nr==4) call_shutdown_task(0);
return 0;
};
 
 
// This is the main user application entry point.
int main_module_entry(void* arg)
{
struct dynalink_module_list* dml = (struct dynalink_module_list*)arg;
// make char pointer to text data module,..
char* txt = (char*)(dml->dat[0].start);
// ... and print out it's data content
cprintf("%s", txt);
 
keyb_getch(BLOCK);
clear();
 
SOFT_TASK_MODEL msoft;
PID p1,p2,p3,p4;
 
int yrow = 1;
puts_xy(0,yrow, 7,"Task#1:[ ]");
puts_xy(0,yrow+1,7,"Task#2:[ ]");
puts_xy(0,yrow+2,7,"Task#3:[ ]");
puts_xy(0,yrow+3,7,"Task#4:[ ]");
 
place(0,7);
 
// Init shared soft task model
soft_task_default_model(msoft);
soft_task_def_met(msoft,10000);
soft_task_def_group(msoft, 1);
soft_task_def_periodic(msoft);
soft_task_def_level(msoft, 2);
int cycles = 4;
// init Task 1
float task_periode = 1.0; // 1sec
int tick = get_tick(); // 1000 usec = 1 ms
int per = (int)( task_periode *1000.0 * tick);
struct params pp1;
pp1.task_nr = 1;
pp1.row = yrow;
pp1.cycles = cycles;
soft_task_def_period(msoft, per); // set period
soft_task_def_arg(msoft, (void*)(&pp1) ); // set arguments
p1 = task_create("save", periodic_task, &msoft, NULL);
if (p1 == NIL)
{
sys_shutdown_message("Can't create task1 ...\n");
exit(1);
}
 
// init Task 2
task_periode = task_periode*0.5; // twice as fast as task1
tick = get_tick(); // 1000 usec = 1 ms
per = (int)( task_periode *1000.0 * tick);
struct params pp2;
pp2.task_nr = 2;
pp2.row = yrow+1;
pp2.cycles = cycles*2;
soft_task_def_period(msoft, per);
soft_task_def_arg(msoft, (void*)(&pp2) );
p2 = task_create("skip", periodic_task, &msoft, NULL);
if (p2 == NIL)
{
sys_shutdown_message("Can't create task2...\n");
exit(1);
}
 
// init Task 3
task_periode = task_periode*0.5; // twice as fast as previous task
tick = get_tick(); // 1000 usec = 1 ms
per = (int)( task_periode *1000.0 * tick);
struct params pp3;
pp3.task_nr = 3;
pp3.row = yrow+2;
pp3.cycles = cycles*4;
soft_task_def_period(msoft, per);
soft_task_def_arg(msoft, (void*)(&pp3) );
p3 = task_create("skip", periodic_task, &msoft, NULL);
if(p3 == NIL)
{
sys_shutdown_message("Can't create task3...\n");
exit(1);
}
 
// init Task 4
task_periode = task_periode*0.5; // twice as fast as previous task
tick = get_tick(); // 1000 usec = 1 ms
per = (int)( task_periode *1000.0 * tick);
struct params pp4;
pp4.task_nr = 4;
pp4.row = yrow+3;
pp4.cycles = cycles*8;
soft_task_def_period(msoft, per);
soft_task_def_arg(msoft, (void*)(&pp4) );
p4 = task_create("skip", periodic_task, &msoft, NULL);
if(p4 == NIL)
{
sys_shutdown_message("Can't create task4...\n");
exit(1);
}
group_activate(1);
 
return 0;
};
/demos/trunk/dynademo/os.c
0,0 → 1,201
//////////////////////////////////////////////////////////////
// os.c -Lex Nahumury 2006
//
// This is the OpenSource SHARK OS/kernel part.
// It will dynamicly link the main application ELF object
// through 'Dynalink'.
//
//////////////////////////////////////////////////////////////
#include "kernel/kern.h"
#include <kernel/func.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "ll/i386/cons.h"
 
#include "edf/edf/edf.h"
#include "cbs/cbs/cbs.h"
#include "hardcbs/hardcbs/hardcbs.h"
#include "rr/rr/rr.h"
#include "dummy/dummy/dummy.h"
#include "intdrive/intdrive/intdrive.h"
 
#include "sem/sem/sem.h"
#include "hartport/hartport/hartport.h"
#include "cabs/cabs/cabs.h"
 
#include <drivers/shark_linuxc26.h>
#include <drivers/shark_pci26.h>
#include <drivers/shark_input26.h>
#include <drivers/shark_keyb26.h>
 
// DYNALINK
#include <dynalink.h>
 
// some shark pci forward declaration stuff
extern int pci20to26_find_class(unsigned int class_code, int index, BYTE *bus, BYTE *dev);
extern int pci20to26_read_config_byte(unsigned int bus, unsigned int dev, int where, BYTE *val);
extern int pci20to26_read_config_word(unsigned int bus, unsigned int dev, int where, WORD *val);
extern int pci20to26_read_config_dword(unsigned int bus, unsigned int dev, int where, DWORD *val);
extern int pci20to26_write_config_byte(unsigned int bus, unsigned int dev, int where, BYTE val);
extern int pci20to26_write_config_word(unsigned int bus, unsigned int dev, int where, WORD val);
extern int pci20to26_write_config_dword(unsigned int bus, unsigned int dev, int where, DWORD val);
 
 
#define TICK 1000 // 1ms
#define RRTICK 100000 // 100ms
 
/*+ IntDrive Server +*/
#define INTDRIVE_Q 1000
#define INTDRIVE_U 0.1*MAX_BANDWIDTH
#define INTDRIVE_FLAG 0
 
#define NSEC_PER_SEC (1000000000L)
#define SHUTDOWN_TIMEOUT_SEC 0.5 // seconds
 
// prototypes
void call_shutdown_task(void *arg);
int device_drivers_init();
int device_drivers_close();
void set_shutdown_task();
TASK shutdown_task_body(void *arg);
 
// user application function pointer prototype
int (*main_app_entry)(void* arg);
 
 
// vars
static struct multiboot_info *mb = 0;
static struct dynalink_module_list dml;
PID shutdown_task_PID = -1;
 
 
// user app calls this to retrieve tick
DWORD get_tick()
{
return TICK;
};
 
TASK shutdown_task_body(void *arg)
{
device_drivers_close();
sys_shutdown_message("-- OS Closed --\n");
return NULL;
};
 
void set_shutdown_task()
{
NRT_TASK_MODEL nrt;
nrt_task_default_model(nrt);
nrt_task_def_system(nrt);
 
shutdown_task_PID = task_create("Shutdown Task", shutdown_task_body, &nrt, NULL);
if (shutdown_task_PID == NIL)
{
sys_shutdown_message("Error: Cannot create shutdown task\n");
exit(1);
}
};
 
 
void call_shutdown_task(void *arg)
{
struct timespec t;
sys_gettime(&t);
t.tv_nsec += NSEC_PER_SEC * SHUTDOWN_TIMEOUT_SEC;
kern_event_post(&t,(void *)((void *)sys_abort_shutdown),(void *)0);
task_activate(shutdown_task_PID);
};
 
 
TIME __kernel_register_levels__(void *arg)
{
mb = (struct multiboot_info *)arg;
LEVEL EDF_level;
 
INTDRIVE_register_level(INTDRIVE_Q, INTDRIVE_Q, INTDRIVE_U, INTDRIVE_FLAG);
EDF_level = EDF_register_level(EDF_ENABLE_ALL);
CBS_register_level(CBS_ENABLE_ALL, EDF_level);
RR_register_level(RRTICK, RR_MAIN_YES, mb);
dummy_register_level();
SEM_register_module();
CABS_register_module();
return TICK;
};
 
TASK __init__(void *arg)
{
mb = (struct multiboot_info *)arg;
//HARTPORT_init();
set_shutdown_task();
device_drivers_init();
 
sys_atrunlevel( call_shutdown_task,
NULL,
RUNLEVEL_SHUTDOWN);
__call_main__(mb);
 
return (void *)0;
};
 
 
int main(int argc, char **argv)
{
// Any modules passed to kernel by GRUB?
if(!mb->mods_count)
{
printk("No modules passed at all! Bye..\n");
exit(1);
}
// Process the modules through 'dynalink'
dynalink_modules(mb, &dml, "_module_entry");
if(dml.num_apps == 0)
{
printk("No Application modules found! Bye..\n");
exit(1);
}
 
// Run first found user application function
// and pass the dynalink_module_list..
DWORD dynadr = dml.app[0].dyn_entry;
if(dynadr)
{
main_app_entry = (void*)dynadr;
main_app_entry(&dml);
}
else
{
printk("No Application modules found! Bye..\n");
exit(1);
}
return 0;
};
 
 
int device_drivers_init()
{
LINUXC26_register_module(TRUE);
//PCI26_init();
INPUT26_init();
KEYB_PARMS kparms = BASE_KEYB;
keyb_def_ctrlC(kparms, NULL);
KEYB26_init(&kparms);
return 0;
};
 
int device_drivers_close()
{
KEYB26_close();
INPUT26_close();
return 0;
};
 
 
/demos/trunk/dynademo/make_app.mk
0,0 → 1,35
# This will make one single object file from multiple sources [Lex.N]
 
DYNALINK=1
ifndef BASE
BASE=../..
endif
 
include $(BASE)/config/config.mk
 
OTHERINCL += -I$(BASE)/drivers/linuxc26/include -I./include -I.
OTHERINCL += -I$(BASE)/drivers/pci/include
OTHERINCL += -I$(BASE)/drivers/input/include
 
# add all sources here..
OBJS = app.o
 
all: sh_app.o
$(MV) sh_app.o sh_app.bin
 
 
clean :
$(RM) *.o
 
sh_app.o: $(OBJS)
$(LD) $(LINK_OPT) $(OBJS) -r -s -o sh_app.o
 
# Common rules
%.o : %.c
$(REDIR) $(CC) $(C_OPT) $(C_OUTPUT) -c $<
%.s : %.c
$(REDIR) $(CC) $(C_OPT) $(C_OUTPUT) -S $<
%.o : %.s
$(CC) $(ASM_OPT) -c $<
 
/demos/trunk/dynademo/make_os.mk
0,0 → 1,19
#
 
ifndef BASE
BASE=../..
endif
 
PROGS = os
 
include $(BASE)/config/config.mk
include $(BASE)/config/example.mk
$(PROGS):
make -f $(SUBMAKE) APP=$(PROGS) \
INIT= \
OTHEROBJS= \
OTHERINCL= \
SHARKOPT="__LINUXC26__ __PCI__ __INPUT__ __DYNALINK__"
 
/demos/trunk/dynademo/readme.txt
0,0 → 1,83
---------------------------------------------
Dynalink Demo.
---------------------------------------------
This is the Dynalink for S.H.A.R.K demo.
Source files are in /shark/projects/dynademo
The SHARK kernel and the user application
are compiled seperatly by;
 
make_os.mk
make_app.mk
 
The resulting OS kernel file is a default
SHARK mutliboot compliant ELF executable.
The resluting user Application is an ELF object file.
 
Also included is a small test data.bin file
to illustrate the use of extra data module parsing through GRUB.
 
The idea is to boot the SHARK kernel through GRUB,
and parsing the User Application plus any needed
data files as 'boot modules'.
GRUB usage example:
 
# For booting SHARK image from HD
title S.H.A.R.K + Boot Modules from HD 0,0
kernel (hd0,0)/boot/os mount root=/dev/hda1
module (hd0,0)/boot/sh_app.bin
module (hd0,0)/boot/data.bin
 
This could be a possible solution to get by
certain GPL restrictions since no GPL code
resides in the user application.
The user application is dynamicly linked
after the kernel is loaded.
 
Another advantage is that we have a simple
way of loading data files without the need for
an IDE-driver plus Filesystem.
Good enough for a few embedded solutions.
 
-------------------------------------------------------------
Dynalink code
-------------------------------------------------------------
The Dynalinker is based on Luca Abenia's code
as used in the FD32 project.
Source files are in /shark/dynalink
The Dynalink makefile produces libdynalink.a
which is compiled into the kernel by adding SHARKOPT =" __DYNALINK__"
 
Also not that I added a section to config.mk as
you can see in the included config.mk
 
# added for dynalink [lex]
ifndef DYNALINK
LINK_OPT = -Bstatic -Ttext $(MEM_START) -s -nostartfiles -nostdlib -L$(LIB_PATH) -L$(OSLIB_PATH)
else
LINK_OPT = -Bstatic
endif
 
Operation:
The Dynalinker supports only ELF objects.
Everything else is loaded and treated as Data objects.
 
After the SHARK kernel is booted it will execute main()
which sole purpose here is to process all parsed
boot modules, link any valid ELF objects
and put the results in a dynalink_module_list struct.
This struct is then used to run the actual User Application
and to hold info about possible data files in memory
that the User Application can use.
 
The dynalinker uses a syscall_table to export/import the symbols.
(review dynalink.c)
Not all SHARK/Library functions needs to be exported!
This is of course just an example.
 
 
/Lex Nahumury 5:41 19-7-06