diff --git a/README.md b/README.md index a912802..fe72259 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,8 @@ Autres commandes de compilation de COS2000 * `make test` lance l'émulation QEMU en 32 bits sur disque dur * `make test64` lance l'émulation QEMU en 64 bits sur disque dur en UEFI * `make clean` supprime les fichers compilés +* `make syscall` réactualise les librairies du domaine utilisateur +* `make programs` compile les programmes du domaine utilisateur * `VESA=no make test` préfixe à utiliser (VESA=no) pour faire appel au pilote VGA et non pas VESA #### Utilisation @@ -193,6 +195,7 @@ Pour l'instant quelques commandes seulement sont disponibles: * `include` - fichier d'entête C * `lib` - librairies pour le noyau * `makefile` - Makefile du projet +* `templates` - Modèles utilisés pour générer des libraires du domaine utilisateur * `programs` - programmes pour le domaine utilisateur * * `include` - fichier d'entête C * * `lib` - librairies pour le domaine utilisateur diff --git a/include/memory.h b/include/memory.h index 95169a9..96c7717 100644 --- a/include/memory.h +++ b/include/memory.h @@ -63,7 +63,7 @@ # define MALLOC_MINIMUM 16 -# define setcr3(addr) \ +# define setCR3(addr) \ asm volatile ("mov %[memaddr], %%eax; mov %%eax, %%cr3"::[memaddr] "m" (addr) ); /* Malloc, pour l'attribution de mémoire en heap */ diff --git a/include/process.h b/include/process.h index 256e90f..35df93b 100644 --- a/include/process.h +++ b/include/process.h @@ -9,11 +9,14 @@ #define MAXPIDVALUE 0xFFFF #define MAXNUMPROCESS 256 -#define STATUS_FREE 0x0 -#define STATUS_ZOMBIE 0xFF -#define STATUS_READY 0xF0 -#define STATUS_RUN 0x1 -#define STATUS_SLEEP 0x2 +#define PROCESS_STATUS_FREE 0x0 +#define PROCESS_STATUS_READY 0xF0 +#define PROCESS_STATUS_RUN 0x1 +#define PROCESS_STATUS_SLEEP 0x2 + +#define TASK_STATUS_READY 0x0 +#define TASK_STATUS_RUN 0x1 +#define TASK_STATUS_STOP 0xFF /* ELF type */ #define ET_NONE 0 //No file type @@ -104,7 +107,7 @@ typedef struct elf32 u16 e_shentsize; u16 e_shnum; u16 e_shstrndx; -} elf32; +} elf32 __attribute__ ((packed)); typedef struct elf32p { @@ -116,41 +119,94 @@ typedef struct elf32p u32 p_memsz; u32 p_flags; u32 p_align; -} elf32p; +} elf32p __attribute__ ((packed)); +typedef unsigned int pid_t; -typedef struct stackdef +typedef struct tid_t +{ + pid_t pid; + u32 number; +} tid_t __attribute__ ((packed)); + +typedef struct stack { u32 esp0; u16 ss0; -} stackdef __attribute__ ((packed)); +} stack __attribute__ ((packed)); +typedef struct task +{ + tid_t tid; + stack kernel_stack; + u32 status; + regs dump; +} task __attribute__ ((packed)); + +typedef struct childs +{ + pid_t pid; + TAILQ_ENTRY(childs) tailq; +} childs __attribute__ ((packed)); + +typedef TAILQ_HEAD(childs_s, childs) childs_t; + +typedef struct others +{ + pid_t pid; + TAILQ_ENTRY(others) tailq; +} others __attribute__ ((packed)); + +typedef TAILQ_HEAD(others_s, others) others_t; typedef struct process { - u32 pid; - bool kernel; - regs dump; - stackdef kstack; + pid_t pid; + pid_t parent; + bool iskernel; pd *pdd; + s8 priority; + childs *allchilds; + others *allothers; u32 result; u8 status; u8 *exec_low; u8 *exec_high; u8 *bss_low; u8 *bss_high; - struct process *parent; page_t page_head; u32 entry; } process __attribute__ ((packed)); -u32 getcurrentpid(); -void task_init(); -u32 task_getfreePID(); -u32 task_usePID(u32 pid); -u32 task_create(u8 * code, bool kerneltask); -u32 elf_test(u8 * src); -u32 elf_load(u8 * src, u32 pid); -void task_switch(u32 pid, bool fromkernelmode); -process *getcurrentprocess(); -void task_run(u32 pid); + +pid_t getcurrentpid(); +pid_t getparentpid(); +pid_t getfreepid(); +void usepid(pid_t pid); + +void stop(); +void wait(); +pid_t fork(); +pid_t clone(); +pid_t exec(u8* entry, u8* args, bool kerneltask); + +void switchtask(tid_t tid, bool fromkernelmode); +tid_t getnexttask(); + +tid_t createtask(pid_t pid,u8 *entry); +void deletetask(pid_t pid); +void runtask(tid_t tid); +void stoptask(pid_t pid); + +pid_t createprocess(u8 src, bool kerneltask); +void deleteprocess(pid_t pid); +void runprocess(pid_t pid); +void stopprocess(pid_t pid); + + +void setpriority(pid_t pid,s8 priority); + +void initprocesses(); + +u32 iself(u8 * src); +u32 loadelf(u8 * src, pid_t pid); diff --git a/lib/process.c b/lib/process.c index 686288f..24da76e 100644 --- a/lib/process.c +++ b/lib/process.c @@ -8,8 +8,8 @@ #include "gdt.h" process *processes; -process *current; -u32 lastpid; +pid_t current; +pid_t lastpid; static u8 elf_errors1[] = "Aucune signature ELF"; @@ -33,7 +33,7 @@ static u8 *elf_errors[] = 5 - pas bon OS 6 - pas bon type machine */ -u32 elf_test(u8 * src) +u32 iself(u8 * src) { elf32 *header = (elf32 *) src; if (header->e_ident[EI_MAG0] == ELFMAG0 @@ -65,7 +65,7 @@ u32 elf_test(u8 * src) "ID":5, "LIBRARY":"libsys", "NAME":"exit", -"INTERNALNAME":"exit", +"INTERNALNAME":"processexit", "DESCRIPTION":"End a task for user or kernel domain", "ARGS": [ {"TYPE":"u32","NAME":"resultcode","DESCRIPTION":"Code result of the execution"} @@ -74,16 +74,16 @@ u32 elf_test(u8 * src) } END */ -void exit() +void processexit() { - task_delete(getcurrentpid()); - task_switch(0, false); + deletetask(getcurrentpid()); + switchtask(0, false); } /*******************************************************************************/ /* Charge le fichier ELF en mémoire et mets à jour les informations sur le processus */ -u32 elf_load(u8 * src, u32 pid) +u32 loadelf(u8 * src, pid_t pid) { u8 *ptr; u8 code; @@ -119,13 +119,13 @@ u32 elf_load(u8 * src, u32 pid) } if (program->p_flags == PF_X + PF_R) { - processes[pid].exec_low = (u8 *) v_begin; - processes[pid].exec_high = (u8 *) v_end; + processes[(u32)pid].exec_low = (u8 *) v_begin; + processes[(u32)pid].exec_high = (u8 *) v_end; } if (program->p_flags == PF_W + PF_R) { - processes[pid].bss_low = (u8 *) v_begin; - processes[pid].bss_high = (u8 *) v_end; + processes[(u32)pid].bss_low = (u8 *) v_begin; + processes[(u32)pid].bss_high = (u8 *) v_end; } memcpy((u8 *) (src + program->p_offset), (u8 *) v_begin, program->p_filesz, 0); @@ -136,14 +136,13 @@ u32 elf_load(u8 * src, u32 pid) ptr[i] = 0; } } - processes[pid].entry = header->e_entry; return header->e_entry; } /*******************************************************************************/ /* Initialise la liste des processus */ -void task_init() +void initprocesses() { u32 i = 1; processes = (process *) vmalloc(sizeof(process) * MAXNUMPROCESS); @@ -152,34 +151,18 @@ void task_init() processes[i].pid = NULL; processes[i++].status = STATUS_FREE; } - processes[0].dump.ss = SEL_KERNEL_STACK; - processes[0].dump.esp = KERNEL_STACK_ADDR; - processes[0].dump.eflags = 0x0; - processes[0].dump.cs = SEL_KERNEL_CODE; - processes[0].dump.eip = getinitretry(); - processes[0].dump.ds = SEL_KERNEL_DATA; - processes[0].dump.es = SEL_KERNEL_DATA; - processes[0].dump.fs = SEL_KERNEL_DATA; - processes[0].dump.gs = SEL_KERNEL_DATA; - processes[0].dump.cr3 = KERNEL_PD_ADDR; - processes[0].dump.eax = 0; - processes[0].dump.ecx = 0; - processes[0].dump.edx = 0; - processes[0].dump.ebx = 0; - processes[0].dump.ebp = 0; - processes[0].dump.esi = 0; - processes[0].dump.edi = 0; + createtask(0,getinitretry()); processes[0].result = 0; processes[0].status = STATUS_READY; - processes[0].kernel = true; - current = &processes[0]; + processes[0].iskernel = true; + current = 0; lastpid = NULL; } /*******************************************************************************/ /* Récupère un emplacement dans la liste des processus */ -u32 task_getfreePID() +pid_t getfreepid() { u32 i = lastpid; u32 parsed = 0; @@ -194,21 +177,13 @@ u32 task_getfreePID() printf("PANIC: plus d'emplacement disponible pour un novueau processus\n"); return NULL; } - return i; -} - -/*******************************************************************************/ -/* Récupère les informations sur le processus courant */ - -process *getcurrentprocess() -{ - return current; + return (pid_t)i; } /*******************************************************************************/ /* Récupère le PID du processus courant */ -u32 getcurrentpid() +pid_t getcurrentpid() { return current->pid; } @@ -217,7 +192,7 @@ u32 getcurrentpid() /*******************************************************************************/ /* Determine le dernier PID occupé */ -u32 task_usePID(u32 pid) +void usepid(pid_t pid) { lastpid = pid; } @@ -225,10 +200,10 @@ u32 task_usePID(u32 pid) /*******************************************************************************/ /* Bascule vers une tâche */ -void task_switch(u32 pid, bool fromkernelmode) +void switchtask(tid_t pid, bool fromkernelmode) { - process *previous = current; - current = &processes[pid]; + pid_t previous = current; + current = &processes[(u32)pid]; if (!current->kernel) setTSS(current->kstack.ss0, current->kstack.esp0); else @@ -243,101 +218,202 @@ void task_switch(u32 pid, bool fromkernelmode) } /*******************************************************************************/ -/* Execute une tâche */ +/* Détruit une tâche */ -void task_run(u32 pid) +void deletetask(tid_t tid) { - if (processes[pid].status == STATUS_READY) - { - processes[pid].status = STATUS_RUN; - task_switch(pid, false); - } + stoptask + } /*******************************************************************************/ /* Execute une tâche */ -void task_delete(u32 pid) +void runtask(tid_t tid) { - if (processes[pid].status == STATUS_READY - || processes[pid].status == STATUS_RUN) + if (processes[(u32)pid].status == STATUS_READY) { - processes[pid].status = STATUS_FREE; + processes[(u32)pid].status = STATUS_RUN; + switchtask(u32)pid, false); } } /*******************************************************************************/ /* Initialise une tâche */ -u32 task_create(u8 * code, bool kerneltask) +tid_t createtask(pid_t pid,u8 *entry) { - process *previous = current; - u32 pid = task_getfreePID(); - task_usePID(pid); + pid_t previous = current; + pid_t pid = getfreepid(); + usepid(pid); page *kstack; - processes[pid].pid = pid; - processes[pid].pdd = virtual_pd_create(); - TAILQ_INIT(&processes[pid].page_head); - if (kerneltask) + processes[(u32)pid].pid = (u32)pid; + processes[(u32)pid].pdd = virtual_pd_create(); + TAILQ_INIT(&processes[(u32)pid].page_head); + if (&processes[(u32)pid].iskernel) { - processes[pid].dump.ss = SEL_KERNEL_STACK; - processes[pid].dump.esp = + processes[(u32)pid].dump.ss = SEL_KERNEL_STACK; + processes[(u32)pid].dump.esp = (u32) kstack->vaddr + PAGESIZE - 16; - processes[pid].dump.eflags = 0x0; - processes[pid].dump.cs = SEL_KERNEL_CODE; - processes[pid].dump.eip = elf_load(code, pid); - if (processes[pid].dump.eip == NULL) + processes[(u32)pid].dump.eflags = 0x0; + processes[(u32)pid].dump.cs = SEL_KERNEL_CODE; + processes[(u32)pid].dump.eip = elf_load(code, pid); + if (processes[(u32)pid].dump.eip == NULL) return NULL; - processes[pid].dump.ds = SEL_KERNEL_DATA; - processes[pid].dump.es = SEL_KERNEL_DATA; - processes[pid].dump.fs = SEL_KERNEL_DATA; - processes[pid].dump.gs = SEL_KERNEL_DATA; - processes[pid].dump.cr3 = KERNEL_PD_ADDR; - processes[pid].dump.eax = 0; - processes[pid].dump.ecx = 0; - processes[pid].dump.edx = 0; - processes[pid].dump.ebx = 0; - processes[pid].dump.ebp = 0; - processes[pid].dump.esi = 0; - processes[pid].dump.edi = 0; - processes[pid].result = 0; - processes[pid].status = STATUS_READY; - processes[pid].kernel = true; + processes[(u32)pid].dump.ds = SEL_KERNEL_DATA; + processes[(u32)pid].dump.es = SEL_KERNEL_DATA; + processes[(u32)pid].dump.fs = SEL_KERNEL_DATA; + processes[(u32)pid].dump.gs = SEL_KERNEL_DATA; + processes[(u32)pid].dump.cr3 = KERNEL_PD_ADDR; + processes[(u32)pid].dump.eax = 0; + processes[(u32)pid].dump.ecx = 0; + processes[(u32)pid].dump.edx = 0; + processes[(u32)pid].dump.ebx = 0; + processes[(u32)pid].dump.ebp = 0; + processes[(u32)pid].dump.esi = 0; + processes[(u32)pid].dump.edi = 0; + processes[(u32)pid].result = 0; + processes[(u32)pid].status = STATUS_READY; + processes[(u32)pid].kernel = true; current = previous; } else { - current = &processes[pid]; - setcr3(processes[pid].pdd->addr->paddr); + current = &processes[(u32)pid]; + setCR3(processes[(u32)pid].pdd->addr->paddr); kstack = virtual_page_getfree(); - processes[pid].dump.ss = SEL_USER_STACK | RPL_RING3; - processes[pid].dump.esp = USER_STACK - 16; - processes[pid].dump.eflags = 0x0; - processes[pid].dump.cs = SEL_USER_CODE | RPL_RING3; - processes[pid].dump.eip = elf_load(code, pid); - if (processes[pid].dump.eip == NULL) + processes[(u32)pid].dump.ss = SEL_USER_STACK | RPL_RING3; + processes[(u32)pid].dump.esp = USER_STACK - 16; + processes[(u32)pid].dump.eflags = 0x0; + processes[(u32)pid].dump.cs = SEL_USER_CODE | RPL_RING3; + processes[(u32)pid].dump.eip = elf_load(code, pid); + if (processes[(u32)pid].dump.eip == NULL) return NULL; - processes[pid].dump.ds = SEL_USER_DATA | RPL_RING3; - processes[pid].dump.es = SEL_USER_DATA | RPL_RING3; - processes[pid].dump.fs = SEL_USER_DATA | RPL_RING3; - processes[pid].dump.gs = SEL_USER_DATA | RPL_RING3; - processes[pid].dump.cr3 = - (u32) processes[pid].pdd->addr->paddr; - processes[pid].kstack.ss0 = SEL_KERNEL_STACK; - processes[pid].kstack.esp0 = + processes[(u32)pid].dump.ds = SEL_USER_DATA | RPL_RING3; + processes[(u32)pid].dump.es = SEL_USER_DATA | RPL_RING3; + processes[(u32)pid].dump.fs = SEL_USER_DATA | RPL_RING3; + processes[(u32)pid].dump.gs = SEL_USER_DATA | RPL_RING3; + processes[(u32)pid].dump.cr3 = + (u32) processes[(u32)pid].pdd->addr->paddr; + processes[(u32)pid].kstack.ss0 = SEL_KERNEL_STACK; + processes[(u32)pid].kstack.esp0 = (u32) kstack->vaddr + PAGESIZE - 16; - processes[pid].dump.eax = 0; - processes[pid].dump.ecx = 0; - processes[pid].dump.edx = 0; - processes[pid].dump.ebx = 0; - processes[pid].dump.ebp = 0; - processes[pid].dump.esi = 0; - processes[pid].dump.edi = 0; - processes[pid].result = 0; - processes[pid].status = STATUS_READY; - processes[pid].kernel = false; + processes[(u32)pid].dump.eax = 0; + processes[(u32)pid].dump.ecx = 0; + processes[(u32)pid].dump.edx = 0; + processes[(u32)pid].dump.ebx = 0; + processes[(u32)pid].dump.ebp = 0; + processes[(u32)pid].dump.esi = 0; + processes[(u32)pid].dump.edi = 0; + processes[(u32)pid].result = 0; + processes[(u32)pid].status = STATUS_READY; + processes[(u32)pid].kernel = false; current = previous; - setcr3(current->dump.cr3); + setCR3(current->dump.cr3); } return pid; } + +/*******************************************************************************/ +/* Arrête une tâche */ + +void stoptask(tid_t tid) +{ + +} + +/*******************************************************************************/ +/* Initialise un processus */ + +pid_t createprocess(u8 *src, bool kerneltask) +{ + pid_t previous = current; + pid_t pid = getfreepid(); + usepid(pid); + page *kstack; + processes[(u32)pid].pid = (u32)pid; + processes[(u32)pid].pdd = virtual_pd_create(); + TAILQ_INIT(&processes[(u32)pid].page_head); + processes[(u32)pid].entry = elf_load(code, pid); + +if (processes[(u32)pid].dump.eip == NULL) + return NULL; + processes[(u32)pid].dump.ds = SEL_KERNEL_DATA; + processes[(u32)pid].dump.es = SEL_KERNEL_DATA; + processes[(u32)pid].dump.fs = SEL_KERNEL_DATA; + processes[(u32)pid].dump.gs = SEL_KERNEL_DATA; + processes[(u32)pid].dump.cr3 = KERNEL_PD_ADDR; + processes[(u32)pid].dump.eax = 0; + processes[(u32)pid].dump.ecx = 0; + processes[(u32)pid].dump.edx = 0; + processes[(u32)pid].dump.ebx = 0; + processes[(u32)pid].dump.ebp = 0; + processes[(u32)pid].dump.esi = 0; + processes[(u32)pid].dump.edi = 0; + processes[(u32)pid].result = 0; + processes[(u32)pid].status = STATUS_READY; + processes[(u32)pid].kernel = true; + current = previous; + } + else + { + current = &processes[(u32)pid]; + setCR3(processes[(u32)pid].pdd->addr->paddr); + kstack = virtual_page_getfree(); + processes[(u32)pid].dump.ss = SEL_USER_STACK | RPL_RING3; + processes[(u32)pid].dump.esp = USER_STACK - 16; + processes[(u32)pid].dump.eflags = 0x0; + processes[(u32)pid].dump.cs = SEL_USER_CODE | RPL_RING3; + processes[(u32)pid].dump.eip = elf_load(code, pid); + if (processes[(u32)pid].dump.eip == NULL) + return NULL; + processes[(u32)pid].dump.ds = SEL_USER_DATA | RPL_RING3; + processes[(u32)pid].dump.es = SEL_USER_DATA | RPL_RING3; + processes[(u32)pid].dump.fs = SEL_USER_DATA | RPL_RING3; + processes[(u32)pid].dump.gs = SEL_USER_DATA | RPL_RING3; + processes[(u32)pid].dump.cr3 = + (u32) processes[(u32)pid].pdd->addr->paddr; + processes[(u32)pid].kstack.ss0 = SEL_KERNEL_STACK; + processes[(u32)pid].kstack.esp0 = + (u32) kstack->vaddr + PAGESIZE - 16; + processes[(u32)pid].dump.eax = 0; + processes[(u32)pid].dump.ecx = 0; + processes[(u32)pid].dump.edx = 0; + processes[(u32)pid].dump.ebx = 0; + processes[(u32)pid].dump.ebp = 0; + processes[(u32)pid].dump.esi = 0; + processes[(u32)pid].dump.edi = 0; + processes[(u32)pid].result = 0; + processes[(u32)pid].status = STATUS_READY; + processes[(u32)pid].kernel = false; + current = previous; + setCR3(current->dump.cr3); + } + return pid; +} + +/*******************************************************************************/ +/* Détruit un processus */ + +void deleteprocess(pid_t pid) +{ + +} + +/*******************************************************************************/ +/* Execute un processus */ + +void runprocess(pid_t pid) +{ + +} + +/*******************************************************************************/ +/* Arrête un processus */ + +void stopprocess(pid_t pid) +{ + +} + +/*******************************************************************************/