From 43d0bb8e3997022e5270f7f75f615a47819c929e Mon Sep 17 00:00:00 2001 From: Alex AUVOLAT Date: Tue, 1 May 2012 23:48:56 +0200 Subject: Basic object system - THIS IS STILL A LONG WAY TO GO!! --- doc/objects.txt | 181 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ doc/roadmap.txt | 1 - doc/syscalls.txt | 64 ++++++++++++++------ 3 files changed, 226 insertions(+), 20 deletions(-) create mode 100644 doc/objects.txt (limited to 'doc') diff --git a/doc/objects.txt b/doc/objects.txt new file mode 100644 index 0000000..956ad74 --- /dev/null +++ b/doc/objects.txt @@ -0,0 +1,181 @@ +Let me say this in french. Sorry for english-only-speaking people, i'll translate someday. + +L'idée principale motivant le développement de T/CE est celle d'un nouveau protocole entre le +noyau et les applications utilisateur. + +Les objets du systèmes sont accessibles sous la forme d'un système de fichiers dans lequel on +navigue, sauf que les objets sont en fait bien plus que de simples fichiers. + +Ce protocole se base sur trois définitions fondamentales : +-- Interfaces : +Une interface est un ensemble de définitions (de prototypes, donc) de méthodes qui +peuvent être implémentées par un objet du système. +Parmi les méthodes, il y a des méthodes publiques, faites pour être appellées par les +applications utilisateurs, et des méthodes internes au noyau. +-- Classe : +Une classe, c'est un regroupement d'interfaces avec leur implémentation spécifique. +-- Objet : +Un objet du système est d'une classe précise, et correspond donc à un des objets gérés +par le code de cette classe. On peut appeller toutes les méthodes des interfaces implémentées +par la classe de l'objet sur cet objet. + +Ce n'est peut-être pas très clair, alors illustrons : + +Interface : Keyboard +- OutputToConsole(Console) +Interface : Console +- SetActiveVT (VirtualTerminal) +- NewBufferedVT (char*) // crée un nouveau terminal virtuel - char* = le nom +- (internal) receiveKeyboardInput(int) +- (internal) repaint(char*) +- (internal) write(int, char*) +Interface : VirtualTerminal +- Read(int, char*) +- Write(int, char*) +- (internal) receiveKeyboardInput(int) +- (internal) outputToConsole(Console, int, int) // int, int = dimensions de la console + +Classe : PS2Keyboard +- Garde en mémoire la console à qui il envoie les données +- Quand une touche est pressée/relâchée, appeller receiveKeyboardInput sur cette console +- Implémenter la méthode OutputToConsole pour changer la console à qui les données sont envoyées +Classe : TextConsole +- Implémente la gestion de l'écran texte VGA de base +- Garde en mémoire le VirtualTerminal actif +- Transmet l'entrée clavier au VirtualTerminal actif +- Lorsqu'on lui demande de changer le VT actif : + il signale à l'ancien VT de ne plus émettre, + il signale au nouveau VT d'émettre vers cette console + et spécifie au nouveau VT la bonne dimension d'écran +Classe : BufferedVirtualTerminal +- Il garde en mémoire LA Console vers laquelle il doit émettre, ainsi que ses dimensions +- Garde un buffer de tout ce qui passe sur la console, et un buffer de l'écran actif. +- Lorsqu'il reçoit une entrée clavier, la bufferise, puis la restitue lors du prochain appel à Read +- Lorsqu'on écrit quelque chose dessus avec Write, il le garde dans son buffer + et le donne aussi au terminal virtuel de sortie, s'il y en a un + + +Implémentation : + +// Structures + +struct Interface { + char* name; + int method_count; + int public_method_count; + + NumberedMethod numberedMethods[]; + int methodNumbers[]; +}; + +struct NumberedMethod { + Interface *iface; + int numberInIface; +}; + +type MethodPtr (function pointer type); + +struct InterfaceImpl { + Interface *interface; + MethodPtr methods[]; +}; + +struct Class { + char* name; + MethodPtr *findChild; + InterfaceImpl interfaces[]; //zero-terminated list +}; + +struct Object { + Class *class; + void *data; +}; + +// setup code + +void Class_setup(Class* class) { + for (int i = 0; class->interfaces[i] != 0; i++) { + Interface_setup(class->interfaces[i]->interface) + } +} + +ExpandableTable allMethods; + +void Interface_setup(Interface* iface) { + if (iface->numberedMethods != 0) return; + iface->numberedMethods = malloc(iface->method_count * sizeof(NumberedMethod)); + iface->methodNumbers = malloc(iface->method_count * sizeof(int)); + + for (int i = 0; i < iface->method_count; i++) { + iface->methodNumbers[i] = allMethods.register(&impl->numberedMethods[i]) + iface->numberedMethods[i]->numberInIface = i; + iface->numberedMethods[i]->ptr = impl->methods[i]; + } +} + +void Object_callByNumber(Object *obj, int number, params...) { + NumberedMethod *method = allMethods.get(number); + for (int i = 0; obj->class->interfaces[i] != 0; i++) { + InterfaceImpl impl = obj->class->interfaces[i]; + if (method->iface == impl->interface) { + MethodPtr fct = impl->methods[method->numberInIface]; + return fct (params...) + } + } + return E_NOT_IMPLEMENTED; +} + +// Exemple + +struct ConsoleMethods { + MethodPtr SetActiveVT; + MethodPtr NewBufferedVT; + MethodPtr receiveKeyboardInput; + MethodPtr repaint; + MethodPtr write; +}; + +Interface ConsoleIface = { + name: "Console", + method_count: 5, + public_method_count: 2, + + numberedMethods: 0, methodNumbers: 0, // internal +}; + +ConsoleMethods TextConsole_as_Console = { + SetActiveVT: TextConsole_SetActiveVT, + NewBufferedVT: TextConsole_NewBufferedVT, + receiveKeyboardInput: TextConsole_receiveKeyboardInput, + repaint: TextConsole_repaint, + write: TextConsole_write, +}; + +Class TextConsoleClass = { + name: "TextConsole", + findChild: Console_findChild, + interfaces: { + { ConsoleIface, (MethodPtr*)TextConsole_as_Console }, + 0 + }, +}; + +struct TextConsole { + Object object; + + //... data ... +}; + +// Other example + +struct FolderMethods { + MethodPtr GetChildList; +}; + +Interface FolderIface = { + name: "Folder", + method_count: 1, + public_method_count: 1, + + numberedMethods: 0, methodNumbers: 0, // internal +}; diff --git a/doc/roadmap.txt b/doc/roadmap.txt index dabae61..835b26d 100644 --- a/doc/roadmap.txt +++ b/doc/roadmap.txt @@ -4,7 +4,6 @@ Stuff to do : - remove useless code from grapes - clean up existing code -- reorganize directories - document the new syscall (Interface/Class/Object) system - basic implementation diff --git a/doc/syscalls.txt b/doc/syscalls.txt index c94db19..d37d822 100644 --- a/doc/syscalls.txt +++ b/doc/syscalls.txt @@ -1,25 +1,51 @@ -Syscalls pass by int64. The identifier of the called function is in eax, parameters -are in ebx, ecx, edx, esi, edi. +See objects.txt for info about the object model in the kernel. + +Syscalls are called with int64. + +== Calls to objects + +When eax != 0, the value of eax is the ID of an object in the process's handle list. +In that case, ebx is the number of the method to be called, +and ecx, edx, esi, edi are the parameters. + + +== Calls to other stuff + +When int64 is called with eax = 0, it's identified as a normal syscall from the following list: + +The identifier of the called function is in ebx, parameters are in ecx, edx, esi, edi. Syscall list : -id=eax Name Parameters Description - 0 thread_exit none Signal kernel that current thread has finished - 1 schedule none Switch to next thread (might be the current one) - 2 thread_sleep ebx: time (int) msecs Tell kernel to put current thread to sleep - 3 process_exit ebx: return value (int) Tell kernel to end current process, cleaning up everything - 4 printk ebx: addr of a string Print a message to screen - 5 thread_new ebx: entry point Creates a new thread - ecx: data pointer - edx: stack pointer - 6 irq_wait ebx: irq number Waits for an IRQ (requires privilege PL_DRIVER) - 7 proc_priv none Returns current process privilege level - - 8 sbrk ebx: size Allocates some memory - 9 brk ebx: new_end Allocates/frees some memory - - 10 mmap (see linux specs) - 11 munmap (see linux specs) +id=ebx Name Parameters Description + 1 thread_exit none Signal kernel that current thread has finished + 2 schedule none Switch to next thread (might be the current one) + 3 thread_sleep ecx: time (int) msecs Tell kernel to put current thread to sleep + 4 process_exit ecx: return value (int) Tell kernel to end current process, cleaning up everything + 5 printk ecx: addr of a string Print a message to screen + 6 thread_new ecx: entry point Creates a new thread + edx: data pointer + esi: stack pointer + 7 irq_wait ecx: irq number Waits for an IRQ (requires privilege PL_DRIVER) + 8 proc_priv none Returns current process privilege level + + 9 sbrk ecx: size Allocates some memory + 10 brk ecx: new_end Allocates/frees some memory + + 11 mmap (see linux specs) NOT IMPLEMENTED + 12 munmap (see linux specs) NOT IMPLEMENTED + + 13 + ... UNUSED (yet) + 19 + + 20 open ecx: ptr to path str Looks for an object in the hierarchy, returns a handle + 21 open_relative ecx: ptr to path str Looks for an object using a given root object + edx: base object handle + 22 close ecx: object handle Close handle to an object + 23 get_methods ecx: ptr to iface name Gets the numbers of the methods in an interface + str + edx: ptr to where to store If a processes wishes to exit with an error code, it HAS to use process_exit. thread_exit will do nothing. -- cgit v1.2.3