/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 |