feat: génération semi-automatique des SYSCALL pour le RING3 à partir d'un script python, encore instable

This commit is contained in:
Nicolas Hordé 2018-12-14 01:06:37 +01:00
parent deea5829d3
commit ddfba60973
23 changed files with 597 additions and 88 deletions

69
API.md
View File

@ -2,29 +2,74 @@
APIs given by COS2000 libraries
### LIBC
All fonction in the "libc" library.
### LIBSYS
All fonctions in the "libsys" library.
------
`u32 libc_testapi(void);`
`u32 getticks(void);`
*Description: function to test if the syscall mecanism is running.*
*Description:Return the internal value of the timer*
* syscall id : **0**
* syscall id : **4**
* arguments : **0**
* results : **yes (always 0x66666666)**
* results : **u32**
* dump of register cpu: **no**
------
`u32 libc_exit(u32 errorcode);`
`void exit(u32 resultcode);`
*Description: tell system that the user process is now finish. Free all ressources affected.*
*Description:End a task for user or kernel domain*
* syscall id : **5**
* arguments : **1**
* * argument 1 : **u32 resultcode** *Code result of the execution*
* results : **void**
* dump of register cpu: **no**
------
`u8 waitkey(void);`
*Description:Wait for user to press a key and return the ascii code pressed*
* syscall id : **1**
* arguments : **1**
* * argument 1 : **u32 pid** *PID process to free*
* results : **no**
* arguments : **0**
* results : **u8**
* dump of register cpu: **no**
------
`u32 testapi(u32 arg1, u32 arg2, u32 arg3);`
*Description:Simple function to test if SYSCALL API is correctly running*
* syscall id : **0**
* arguments : **3**
* * argument 1 : **u32 arg1** *first argument of your choice*
* * argument 2 : **u32 arg2** *second argument of your choice*
* * argument 3 : **u32 arg3** *third argument of your choice*
* results : **u32**
* dump of register cpu: **yes**
### LIBVIDEO
All fonctions in the "libvideo" library.
------
`u32 print(u8* string);`
*Description:Show a string on the screen*
* syscall id : **2**
* arguments : **1**
* * argument 1 : **u8* string** *string to show in ascii format*
* results : **u32**
* dump of register cpu: **no**
------

View File

@ -6,10 +6,6 @@
* Les modes VGA ne fonctionnent pas tous.
* Ralentissement lors du défilemment de la console en VESA.
### MEMOIRE
La commande mem plante parfois ?!
### 3D
La 3D utiliser sauvagement la mémoire sans malloc !!

View File

@ -86,8 +86,8 @@
dump->esp = (u32) oldesp + sizeof(exception_stack_noerror);\
else\
{\
dump->esp = (u32) ((exception_stack_user*) caller)->esp;\
dump->ss = (u32) ((exception_stack_user*) caller)->ss;\
dump->esp = (u32) ((exception_stack_noerror_user*) caller)->esp;\
dump->ss = (u32) ((exception_stack_noerror_user*) caller)->ss;\
}\
})

0
lib/TEST/NE PAS DETRUIRE Normal file
View File

View File

@ -123,6 +123,17 @@ u8 *getstring(u8 * temp)
/******************************************************************************/
/* Fonction qui attend l'appuie d'une touche générant un code ASCII puis le retourne */
/* SYSCALL
{
"ID":1,
"LIBRARY":"libsys",
"NAME":"waitkey",
"INTERNALNAME":"waitascii",
"DESCRIPTION":"Wait for user to press a key and return the ascii code pressed",
"ARGS": [],
"RETURN":"u8"
}
END */
u8 waitascii(void)
{

View File

@ -58,6 +58,28 @@ u32 elf_test(u8 * src)
return 1;
}
/*******************************************************************************/
/* Met fin à une tâche */
/* SYSCALL
{
"ID":5,
"LIBRARY":"libsys",
"NAME":"exit",
"INTERNALNAME":"exit",
"DESCRIPTION":"End a task for user or kernel domain",
"ARGS": [
{"TYPE":"u32","NAME":"resultcode","DESCRIPTION":"Code result of the execution"}
],
"RETURN":"void"
}
END */
void exit()
{
task_delete(getcurrentpid());
task_switch(0, false);
}
/*******************************************************************************/
/* Charge le fichier ELF en mémoire et mets à jour les informations sur le processus */

View File

@ -94,7 +94,7 @@ int test(void)
int testtask()
{
print("*** Creation d'une tache");
print("*** Creation d'une tache\r\n");
u32 pid = task_create(&programs_test, false);
task_run(pid);
}

View File

@ -1,5 +1,5 @@
/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* COS2000 - Compatible Operating System - LGPL v3 - Horde Nicolas */
/* */
#include <types.h>
#include <gdt.h>
@ -14,41 +14,32 @@
* Arguments:
* %eax System call number.
* %ebx Arg1
* %ecx Arg2
* %edx Arg3
* %esi Arg4
* %edi Arg5
* %ebp user stack
* 0(%ebp) Arg6*/
* %esi Arg2
* %edi Arg3
/*******************************************************************************/
/* Entrée pour les appels système SYSENTER */
void sysenter_handler(void)
/* Fonction permettant de tester le fonctionnement de SYSENTER */
/* SYSCALL
{
cli();
regs *dump;
dumpcpu();
getESP(dump);
sti();
switch (dump->eax)
{
case 0:
printf("Test de fonctionnement syscall\r\n -arguments 1:%Y 2:%Y 3:%Y\r\n", dump->ebx, dump->esi, dump->edi);
dump->eax = 0x6666666;
break;
case 1:
task_delete(getcurrentpid());
task_switch(0, false);
break;
default:
printf("Appel syscall vers fonction inexistante en %Y:%Y", dump->cs, dump->eip);
break;
"ID":0,
"LIBRARY":"libsys",
"NAME":"testapi",
"INTERNALNAME":"testapi",
"DESCRIPTION":"Simple function to test if SYSCALL API is correctly running",
"ARGS": [
{"TYPE":"u32","NAME":"arg1","DESCRIPTION":"first argument of your choice"},
{"TYPE":"u32","NAME":"arg2","DESCRIPTION":"second argument of your choice"},
{"TYPE":"u32","NAME":"arg3","DESCRIPTION":"third argument of your choice"}
],
"RETURN":"u32",
"DUMP":"yes"
}
END */
}
restdebugcpu();
sysexit();
u32 testapi(u32 arg1, u32 arg2, u32 arg3, regs* dump)
{
printf("Appel syscall %u depuis %Y:%Y avec arguments => ARG1:%Y ARG2:%Y ARG3:%Y\r\n", dump->eax, (u32) dump->cs, dump->eip, arg1, arg2, arg3);
return;
}
/*******************************************************************************/
@ -63,3 +54,42 @@ void initsyscall(void)
}
/*******************************************************************************/
/* Entrée pour les appels système SYSENTER */
void sysenter_handler(void)
{
cli();
regs *dump;
dumpcpu();
getESP(dump);
sti();
switch (dump->eax)
{
case 4:
dump->eax=(u32) gettimer();
break;
case 5:
exit(dump->ebx);
break;
case 2:
dump->eax=(u32) print(dump->ebx);
break;
case 1:
dump->eax=(u32) waitascii();
break;
case 0:
dump->eax=(u32) testapi(dump->ebx, dump->esi, dump->edi, dump);
break;
default:
printf("Appel syscall vers fonction inexistante en %Y:%Y\r\n", dump->cs, dump->eip);
break;
}
restdebugcpu();
sysexit();
}
/*******************************************************************************/

View File

@ -16,6 +16,17 @@ static u32 time = 0;
/******************************************************************************/
/* Récupère la valeur du timer */
/* SYSCALL
{
"ID":4,
"NAME":"getticks",
"LIBRARY":"libsys",
"INTERNALNAME":"gettimer",
"DESCRIPTION":"Return the internal value of the timer",
"ARGS": [],
"RETURN":"u32"
}
END */
u32 gettimer(void)
{

View File

@ -1033,6 +1033,19 @@ void triangle(vertex2d * AA, vertex2d * BB, vertex2d * CC, u32 color)
/*******************************************************************************/
/* affiche une chaine de caractčre a l'écran */
/* SYSCALL
{
"ID":2,
"LIBRARY":"libvideo",
"NAME":"print",
"INTERNALNAME":"print",
"DESCRIPTION":"Show a string on the screen",
"ARGS": [
{"TYPE":"u8*","NAME":"string","DESCRIPTION":"string to show in ascii format"}
],
"RETURN":"u32"
}
END */
u32 print(u8 * string)
{

181
makesyscall.py Normal file
View File

@ -0,0 +1,181 @@
#!/usr/bin/env python2.7
# -*-coding:utf-8 -*
import os, os.path, re, string, json
def getfunction(syscall):
args=""
num=1
for argument in syscall['ARGS']:
if num>1:
args=args+", "
args=args+argument['TYPE']+" "+argument['NAME']
num=num+1
if args=="":
args="void"
return str(syscall['RETURN'])+" "+str(syscall['NAME'])+"("+args+")"
def getfunctioninternal(syscall):
args=""
argsname=["ebx","esi","edi","ebp"]
num=1
for argument in syscall['ARGS']:
if num>1:
args=args+", "
args=args+"dump->"+argsname[num-1]
num=num+1
if syscall.has_key('DUMP'):
if num>1:
args=args+", "
args=args+"dump"
return str(syscall['INTERNALNAME'])+"("+args+")"
def get_duplicates(sorted_list):
duplicates = []
last = sorted_list[0]
for x in sorted_list[1:]:
if x == last:
duplicates.append(x)
last = x
return set(duplicates)
path = "./"
files = os.listdir(path)
pattern = r'\/\* SYSCALL.*END \*\/'
output_file = "syscalls.txt"
if os.path.exists(output_file):
os.remove(output_file)
fo = open(output_file, "a+")
fo.write("[")
print "*** Collecte des SYSCALL"
for root, dirs, files in os.walk(path):
for name in files:
if name.endswith((".c")):
if root=="./templates":
continue
input_file = os.path.join(root, name)
with open(input_file, "r") as fi :
content = fi.read()
results = re.findall(pattern, content, re.MULTILINE| re.DOTALL)
for result in results:
print("Fichier :"+os.path.join(root, name))
new=string.replace(string.replace(result,"/* SYSCALL ",""),"END */","")
if fo.tell()>2:
new=","+new;
fo.write(new+"\r\n")
fo.write("]")
fo.seek(0)
alljson=json.load(fo);
print alljson
fo.close()
dup = get_duplicates([syscall['ID'] for syscall in alljson]);
if len(dup)>0:
print "ERREUR : deux fonctions possedent le meme numero de SYSCALL"
for error in dup:
for syscall in alljson:
if syscall['ID']==error:
print "librairie :"+syscall['LIBRARY']+" fonction: "+syscall['INTERNALNAME']+" id:"+str(syscall['ID'])
exit()
print "*** Mise en place de la documentation"
os.popen('cp ./templates/API.md ./API.md')
alllibs=set([syscall['LIBRARY'] for syscall in alljson])
text=""
for lib in alllibs:
text=text+"""
### """+lib.upper()+"""
All fonctions in the \""""+lib+"""\" library.
"""
for syscall in alljson:
if syscall['LIBRARY']==lib:
textargs=""
num=1
for argument in syscall['ARGS']:
textargs=textargs+"\n* * argument "+str(num)+" : **"+argument['TYPE']+" "+argument['NAME']+"** *"+argument['DESCRIPTION']+"*"
num=num+1
dump="no"
if syscall.has_key('DUMP'):
dump="yes"
text=text+"""------
`"""+getfunction(syscall)+""";`
*Description:"""+str(syscall['DESCRIPTION'])+"""*
* syscall id : **"""+str(syscall['ID'])+"""**
* arguments : **"""+str(len(syscall['ARGS']))+"""**"""+textargs+"""
* results : **"""+str(syscall['RETURN'])+"""**
* dump of register cpu: **"""+dump+"""**
"""
fo = open("./API.md", "r+")
content = fo.read()
content=content.replace("/* FOR INSERTING */",text)
##print content
fo.seek(0)
fo.write(content)
fo.close()
print "*** Mise en place des libraires (HEADERS)"
for lib in alllibs:
text=""
print "Librairie :"+lib
libname="./programs/include/"+lib+".h"
os.popen('cp ./templates/lib.h '+libname)
for syscall in alljson:
if syscall['LIBRARY']==lib:
text=text+getfunction(syscall)+";\n"
fo = open(libname, "r+")
content = fo.read()
content=content.replace("/* FOR INSERTING */",text)
##print content
fo.seek(0)
fo.write(content)
fo.close()
print "*** Mise en place des libraires (SOURCES)"
for lib in alllibs:
text=""
print "Librairie :"+lib
libname="./programs/lib/"+lib+".c"
os.popen('cp ./templates/lib.c '+libname)
for syscall in alljson:
if syscall['LIBRARY']==lib:
numargs=len(syscall['ARGS'])
textargs="syscall"+str(numargs)+"("+str(syscall['ID'])
for i in range(0,numargs):
if numargs>0:
textargs=textargs+","
textargs=textargs+"(u32) "+syscall['ARGS'][i]['NAME']
text=text+getfunction(syscall)+"""
{
"""+textargs+""");
}
"""
fo = open(libname, "r+")
content = fo.read()
content=content.replace("/* FOR INSERTING */",text)
##print content
fo.seek(0)
fo.write(content)
fo.close()
print "*** Mise en place du fichier noyau SYSCALL"
text=""
libname="./lib/syscall.c"
os.popen('cp ./templates/syscall.c '+libname)
for syscall in alljson:
print "ID :"+str(syscall['ID'])
call=""
if syscall['RETURN']!='void':
call="dump->eax=(u32) "
call=call+getfunctioninternal(syscall)
text=text+""" case """+str(syscall['ID'])+""":
"""+call+""";
break;
"""
fo = open(libname, "r+")
content = fo.read()
content=content.replace("/* FOR INSERTING */",text)
##print content
fo.seek(0)
fo.write(content)

11
programs/include/libsys.h Normal file
View File

@ -0,0 +1,11 @@
/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Horde Nicolas */
/* */
#include "types.h";
u32 getticks(void);
void exit(u32 resultcode);
u8 waitkey(void);
u32 testapi(u32 arg1, u32 arg2, u32 arg3);

View File

@ -1,8 +1,8 @@
/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* COS2000 - Compatible Operating System - LGPL v3 - Horde Nicolas */
/* */
#include "types.h";
u32 libc_testapi(void);
u32 libc_exit(u32 errorcode);
u32 print(u8* string);

View File

@ -1,17 +0,0 @@
/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* */
#include "libc.h";
#include "syscall.h";
#include "types.h";
u32 libc_testapi(void)
{
syscall3(0x0, 0x1980, 0x2505, 0x4444);
}
u32 libc_exit(u32 errorcode)
{
syscall1(0x1, errorcode);
}

29
programs/lib/libsys.c Normal file
View File

@ -0,0 +1,29 @@
/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Horde Nicolas */
/* */
#include "libsys.h";
#include "syscall.h";
#include "types.h";
u32 getticks(void)
{
syscall0(4);
}
void exit(u32 resultcode)
{
syscall1(5,(u32) resultcode);
}
u8 waitkey(void)
{
syscall0(1);
}
u32 testapi(u32 arg1, u32 arg2, u32 arg3)
{
syscall3(0,(u32) arg1,(u32) arg2,(u32) arg3);
}

14
programs/lib/libvideo.c Normal file
View File

@ -0,0 +1,14 @@
/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Horde Nicolas */
/* */
#include "libsys.h";
#include "syscall.h";
#include "types.h";
u32 print(u8* string)
{
syscall1(2,(u32) string);
}

View File

@ -2,11 +2,14 @@
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* */
#include "libc.h";
#include "libsys.h";
#include "libvideo.h";
#include "types.h";
void main(void)
{
u32 result = libc_testapi();
libc_exit(result);
//u32 result = testapi(0x1234,0x88888888,0x2505);
print("ceci est un test d'appel");
waitkey();
//exit(result);
}

65
syscalls.txt Normal file
View File

@ -0,0 +1,65 @@
[
{
"ID":4,
"NAME":"getticks",
"LIBRARY":"libsys",
"INTERNALNAME":"gettimer",
"DESCRIPTION":"Return the internal value of the timer",
"ARGS": [],
"RETURN":"u32"
}
,
{
"ID":5,
"LIBRARY":"libsys",
"NAME":"exit",
"INTERNALNAME":"exit",
"DESCRIPTION":"End a task for user or kernel domain",
"ARGS": [
{"TYPE":"u32","NAME":"resultcode","DESCRIPTION":"Code result of the execution"}
],
"RETURN":"void"
}
,
{
"ID":2,
"LIBRARY":"libvideo",
"NAME":"print",
"INTERNALNAME":"print",
"DESCRIPTION":"Show a string on the screen",
"ARGS": [
{"TYPE":"u8*","NAME":"string","DESCRIPTION":"string to show in ascii format"}
],
"RETURN":"u32"
}
,
{
"ID":1,
"LIBRARY":"libsys",
"NAME":"waitkey",
"INTERNALNAME":"waitascii",
"DESCRIPTION":"Wait for user to press a key and return the ascii code pressed",
"ARGS": [],
"RETURN":"u8"
}
,
{
"ID":0,
"LIBRARY":"libsys",
"NAME":"testapi",
"INTERNALNAME":"testapi",
"DESCRIPTION":"Simple function to test if SYSCALL API is correctly running",
"ARGS": [
{"TYPE":"u32","NAME":"arg1","DESCRIPTION":"first argument of your choice"},
{"TYPE":"u32","NAME":"arg2","DESCRIPTION":"second argument of your choice"},
{"TYPE":"u32","NAME":"arg3","DESCRIPTION":"third argument of your choice"}
],
"RETURN":"u32",
"DUMP":"yes"
}
]

View File

@ -58,44 +58,39 @@ int main(u32 magic, u32 addr)
print("\033[2J\r\n\000");
logo();
print("\033[37m\033[0m -Chargement noyaux");
ok();
print("\033[37m\033[0m -Initilisation de la memoire (GDT)");
print("\033[37m\033[0m -Initilisation de la memoire virtuelle");
initgdt(&&next);
next:
ok();
print("\033[37m\033[0m -Initilisation de la pagination (PAGING)");
initpaging();
remap_memory(VESA_FBMEM);
ok();
print("\033[37m\033[0m -Initilisation des taches (TSR)");
print("\033[37m\033[0m -Initilisation des processus");
inittr();
initretry(&&retry);
task_init();
initsyscall();
ok();
print("\033[37m\033[0m -Initilisation des interruptions (IDT/PIC)");
print("\033[37m\033[0m -Initilisation des interruptions");
initidt();
initpic();
sti();
ok();
print(" -Installation du handler timer (IRQ 0)");
print(" -Installation de l'horloge systeme (IRQ 0)");
setidt((u32) timer, SEL_KERNEL_CODE,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 32);
enableirq(0);
ok();
print(" -Installation du handler clavier (IRQ 1)");
print(" -Installation du pilote clavier (IRQ 1)");
setidt((u32) keyboard, SEL_KERNEL_CODE,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 33);
enableirq(1);
ok();
print(" -Installation du handler souris (IRQ12+Cascade IRQ2)");
print(" -Installation du pilote souris (IRQ12+IRQ2)");
setidt((u32) mouse, SEL_KERNEL_CODE,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 100);
enableirq(2);
@ -104,8 +99,7 @@ int main(u32 magic, u32 addr)
warning();
else
ok();
printf(" -Installation des appels systemes utilisateur et du FPU");
initsyscall();
printf(" -Installation du coprocesseur arithmetique");
finit();
ok();

5
templates/API.md Normal file
View File

@ -0,0 +1,5 @@
## API List
APIs given by COS2000 libraries
/* FOR INSERTING */

9
templates/lib.c Normal file
View File

@ -0,0 +1,9 @@
/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Horde Nicolas */
/* */
#include "libsys.h";
#include "syscall.h";
#include "types.h";
/* FOR INSERTING */

7
templates/lib.h Normal file
View File

@ -0,0 +1,7 @@
/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Horde Nicolas */
/* */
#include "types.h";
/* FOR INSERTING */

80
templates/syscall.c Normal file
View File

@ -0,0 +1,80 @@
/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Horde Nicolas */
/* */
#include <types.h>
#include <gdt.h>
#include <asm.h>
#include <memory.h>
#include <interrupts.h>
#include <syscall.h>
#include <process.h>
/* 32bit SYSENTER instruction entry.
*
* Arguments:
* %eax System call number.
* %ebx Arg1
* %esi Arg2
* %edi Arg3
/*******************************************************************************/
/* Fonction permettant de tester le fonctionnement de SYSENTER */
/* SYSCALL
{
"ID":0,
"LIBRARY":"libsys",
"NAME":"testapi",
"INTERNALNAME":"testapi",
"DESCRIPTION":"Simple function to test if SYSCALL API is correctly running",
"ARGS": [
{"TYPE":"u32","NAME":"arg1","DESCRIPTION":"first argument of your choice"},
{"TYPE":"u32","NAME":"arg2","DESCRIPTION":"second argument of your choice"},
{"TYPE":"u32","NAME":"arg3","DESCRIPTION":"third argument of your choice"}
],
"RETURN":"u32",
"DUMP":"yes"
}
END */
u32 testapi(u32 arg1, u32 arg2, u32 arg3, regs* dump)
{
printf("Appel syscall %u depuis %Y:%Y avec arguments => ARG1:%Y ARG2:%Y ARG3:%Y\r\n", dump->eax, (u32) dump->cs, dump->eip, arg1, arg2, arg3);
return;
}
/*******************************************************************************/
/* Initialise les appels système par SYSENTER/SYSEXIT */
void initsyscall(void)
{
wrmsr(0x174, SEL_KERNEL_CODE, 0x0);
wrmsr(0x175, 0x60000, 0x0);
wrmsr(0x176, &sysenter_handler + 6, 0x0);
}
/*******************************************************************************/
/* Entrée pour les appels système SYSENTER */
void sysenter_handler(void)
{
cli();
regs *dump;
dumpcpu();
getESP(dump);
sti();
switch (dump->eax)
{
/* FOR INSERTING */
default:
printf("Appel syscall vers fonction inexistante en %Y:%Y", dump->cs, dump->eip);
break;
}
restdebugcpu();
sysexit();
}
/*******************************************************************************/