2018-12-09 00:40:25 +01:00
|
|
|
/*******************************************************************************/
|
|
|
|
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
|
|
|
|
/* */
|
|
|
|
|
|
|
|
#include "types.h"
|
|
|
|
#include "process.h"
|
|
|
|
#include "memory.h"
|
|
|
|
#include "gdt.h"
|
|
|
|
|
|
|
|
process *processes;
|
2018-12-19 12:06:05 +01:00
|
|
|
tid_t current;
|
2018-12-19 07:34:44 +01:00
|
|
|
pid_t lastpid;
|
2018-12-09 00:40:25 +01:00
|
|
|
|
2018-12-09 11:11:39 +01:00
|
|
|
|
2018-12-12 15:25:04 +01:00
|
|
|
static u8 elf_errors1[] = "Aucune signature ELF";
|
|
|
|
static u8 elf_errors2[] = "Fichier au format ELF mais non 32 bits";
|
|
|
|
static u8 elf_errors3[] = "ELF non LSB";
|
|
|
|
static u8 elf_errors4[] = "ELF mauvaise version";
|
|
|
|
static u8 elf_errors5[] = "ELF pour OS ne correspondant pas";
|
|
|
|
static u8 elf_errors6[] = "Mauvais type de machine";
|
|
|
|
static u8 *elf_errors[] =
|
|
|
|
{ &elf_errors1, &elf_errors2, &elf_errors3, &elf_errors4,
|
2018-12-12 17:57:23 +01:00
|
|
|
&elf_errors5, &elf_errors6
|
|
|
|
};
|
2018-12-09 00:40:25 +01:00
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Vérifie la signature ELF
|
|
|
|
0 - RAS
|
|
|
|
1 - Pas la signature ELF
|
|
|
|
2 - pas ELF32
|
|
|
|
3 - pas bon organisation LSB/MSB
|
|
|
|
4 - pas bonne version ELF
|
|
|
|
5 - pas bon OS
|
|
|
|
6 - pas bon type machine */
|
2018-12-12 15:25:04 +01:00
|
|
|
|
2018-12-19 07:34:44 +01:00
|
|
|
u32 iself(u8 * src)
|
2018-12-09 00:40:25 +01:00
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
elf32 *header = (elf32 *) src;
|
|
|
|
if (header->e_ident[EI_MAG0] == ELFMAG0
|
|
|
|
&& header->e_ident[EI_MAG1] == ELFMAG1
|
|
|
|
&& header->e_ident[EI_MAG2] == ELFMAG2
|
|
|
|
&& header->e_ident[EI_MAG3] == ELFMAG3)
|
|
|
|
{
|
|
|
|
if (header->e_ident[EI_CLASS] != ELFCLASS32)
|
|
|
|
return 2;
|
|
|
|
if (header->e_ident[EI_DATA] != ELFDATA2LSB)
|
|
|
|
return 3;
|
|
|
|
if (header->e_ident[EI_VERSION] != EV_CURRENT
|
|
|
|
|| header->e_version != EV_CURRENT)
|
|
|
|
return 4;
|
|
|
|
if (header->e_ident[EI_OSABI] != ELFOSABI_COS2000)
|
|
|
|
return 5;
|
|
|
|
if (header->e_machine != EM_386)
|
|
|
|
return 6;
|
|
|
|
return 0;
|
|
|
|
}
|
2018-12-09 00:40:25 +01:00
|
|
|
else
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-12-14 01:06:37 +01:00
|
|
|
/*******************************************************************************/
|
|
|
|
/* Met fin à une tâche */
|
|
|
|
/* SYSCALL
|
|
|
|
{
|
|
|
|
"ID":5,
|
|
|
|
"LIBRARY":"libsys",
|
|
|
|
"NAME":"exit",
|
2018-12-19 07:34:44 +01:00
|
|
|
"INTERNALNAME":"processexit",
|
2018-12-14 01:06:37 +01:00
|
|
|
"DESCRIPTION":"End a task for user or kernel domain",
|
|
|
|
"ARGS": [
|
|
|
|
{"TYPE":"u32","NAME":"resultcode","DESCRIPTION":"Code result of the execution"}
|
|
|
|
],
|
2018-12-20 16:29:04 +01:00
|
|
|
"RETURN":"u32"
|
2018-12-14 01:06:37 +01:00
|
|
|
}
|
2018-12-27 14:24:47 +01:00
|
|
|
END-SYSCALL */
|
2018-12-14 01:06:37 +01:00
|
|
|
|
2018-12-19 12:06:05 +01:00
|
|
|
void processexit(void)
|
2018-12-14 01:06:37 +01:00
|
|
|
{
|
2018-12-20 17:16:51 +01:00
|
|
|
cli();
|
2018-12-19 12:06:05 +01:00
|
|
|
deleteprocess(getcurrentpid());
|
2018-12-19 23:31:13 +01:00
|
|
|
switchtask(maketid(1,1));
|
2018-12-20 17:16:51 +01:00
|
|
|
sti();
|
2018-12-14 01:06:37 +01:00
|
|
|
}
|
|
|
|
|
2018-12-09 00:40:25 +01:00
|
|
|
/*******************************************************************************/
|
|
|
|
/* Charge le fichier ELF en mémoire et mets à jour les informations sur le processus */
|
|
|
|
|
2018-12-19 07:34:44 +01:00
|
|
|
u32 loadelf(u8 * src, pid_t pid)
|
2018-12-09 00:40:25 +01:00
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
u8 *ptr;
|
|
|
|
u8 code;
|
|
|
|
u32 v_begin, v_end;
|
|
|
|
elf32 *header;
|
2018-12-09 00:40:25 +01:00
|
|
|
elf32p *program;
|
2018-12-12 15:25:04 +01:00
|
|
|
u32 i;
|
2018-12-09 00:40:25 +01:00
|
|
|
|
|
|
|
header = (elf32 *) src;
|
2018-12-09 11:11:39 +01:00
|
|
|
program = (elf32p *) (src + header->e_phoff);
|
2018-12-19 12:06:05 +01:00
|
|
|
code = iself(src);
|
2018-12-19 16:13:47 +01:00
|
|
|
process *aprocess=findprocess(pid);
|
|
|
|
if (aprocess==NULL) return NULL;
|
2018-12-12 15:25:04 +01:00
|
|
|
if (code != 0)
|
|
|
|
{
|
|
|
|
printf("Erreur de chargement ELF, %s !\r\n",
|
|
|
|
elf_errors[code - 1]);
|
2018-12-09 00:40:25 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
2018-12-12 15:25:04 +01:00
|
|
|
for (i = 0; i < header->e_phnum; i++, program++)
|
|
|
|
{
|
|
|
|
if (program->p_type == PT_LOAD)
|
|
|
|
{
|
2018-12-09 00:40:25 +01:00
|
|
|
v_begin = program->p_vaddr;
|
|
|
|
v_end = program->p_vaddr + program->p_memsz;
|
2018-12-12 15:25:04 +01:00
|
|
|
if (v_begin < USER_CODE)
|
|
|
|
{
|
|
|
|
printf("Ne peut charger l'executable en desssous de l'adresse %X\r\n", USER_CODE);
|
2018-12-09 00:40:25 +01:00
|
|
|
return 0;
|
|
|
|
}
|
2018-12-12 15:25:04 +01:00
|
|
|
if (v_end > USER_STACK)
|
|
|
|
{
|
|
|
|
printf("Ne peut charger l'executable au desssus de l'adresse %X\r\n", USER_STACK);
|
2018-12-09 00:40:25 +01:00
|
|
|
return 0;
|
|
|
|
}
|
2018-12-12 15:25:04 +01:00
|
|
|
if (program->p_flags == PF_X + PF_R)
|
|
|
|
{
|
2018-12-19 16:13:47 +01:00
|
|
|
aprocess->exec_low = (u8 *) v_begin;
|
|
|
|
aprocess->exec_high = (u8 *) v_end;
|
2018-12-09 00:40:25 +01:00
|
|
|
}
|
2018-12-12 15:25:04 +01:00
|
|
|
if (program->p_flags == PF_W + PF_R)
|
|
|
|
{
|
2018-12-19 16:13:47 +01:00
|
|
|
aprocess->bss_low = (u8 *) v_begin;
|
|
|
|
aprocess->bss_high = (u8 *) v_end;
|
2018-12-09 00:40:25 +01:00
|
|
|
}
|
2018-12-12 15:25:04 +01:00
|
|
|
memcpy((u8 *) (src + program->p_offset),
|
|
|
|
(u8 *) v_begin, program->p_filesz, 0);
|
2018-12-09 00:40:25 +01:00
|
|
|
if (program->p_memsz > program->p_filesz)
|
2018-12-12 15:25:04 +01:00
|
|
|
for (i = program->p_filesz, ptr =
|
|
|
|
(u8 *) program->p_vaddr;
|
|
|
|
i < program->p_memsz; i++)
|
2018-12-09 11:11:39 +01:00
|
|
|
ptr[i] = 0;
|
2018-12-09 00:40:25 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return header->e_entry;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Initialise la liste des processus */
|
|
|
|
|
2018-12-19 12:06:05 +01:00
|
|
|
void initprocesses(void)
|
2018-12-12 15:25:04 +01:00
|
|
|
{
|
2018-12-19 16:13:47 +01:00
|
|
|
u32 i = 0;
|
2018-12-12 15:25:04 +01:00
|
|
|
processes = (process *) vmalloc(sizeof(process) * MAXNUMPROCESS);
|
2018-12-12 18:49:21 +01:00
|
|
|
while (i < MAXNUMPROCESS)
|
2018-12-12 15:25:04 +01:00
|
|
|
{
|
2018-12-22 00:19:34 +01:00
|
|
|
processes[i].pid = i+1;
|
2018-12-19 12:06:05 +01:00
|
|
|
processes[i++].status = PROCESS_STATUS_FREE;
|
2018-12-12 15:25:04 +01:00
|
|
|
}
|
2018-12-22 00:19:34 +01:00
|
|
|
pid_t pid=(pid_t)1;
|
2018-12-19 16:13:47 +01:00
|
|
|
process *aprocess=findprocess(pid);
|
|
|
|
if (aprocess==NULL) return NULL;
|
|
|
|
aprocess->pid = pid;
|
|
|
|
aprocess->result = 0;
|
2018-12-25 19:22:56 +01:00
|
|
|
aprocess->pdd = NULL;
|
2018-12-20 16:29:04 +01:00
|
|
|
aprocess->status = PROCESS_STATUS_RUN;
|
2018-12-19 16:13:47 +01:00
|
|
|
aprocess->iskernel = true;
|
2018-12-19 23:31:13 +01:00
|
|
|
TAILQ_INIT(&aprocess->task_head);
|
2018-12-19 16:13:47 +01:00
|
|
|
current=createtask(pid,getinitretry(),true);
|
2018-12-20 16:29:04 +01:00
|
|
|
task *atask = findtask(current);
|
|
|
|
atask->status = TASK_STATUS_RUN;
|
2018-12-09 00:40:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Récupère un emplacement dans la liste des processus */
|
|
|
|
|
2018-12-19 12:06:05 +01:00
|
|
|
pid_t getfreepid(void)
|
2018-12-09 00:40:25 +01:00
|
|
|
{
|
2018-12-22 00:19:34 +01:00
|
|
|
if ((u32)lastpid==0 || lastpid>MAXNUMPROCESS)
|
|
|
|
lastpid=(pid_t)1;
|
|
|
|
process* aprocess=findprocess(lastpid);
|
|
|
|
aprocess=getnextprocess(aprocess, PROCESS_STATUS_FREE);
|
|
|
|
if (aprocess == NULL)
|
2018-12-12 15:25:04 +01:00
|
|
|
{
|
2018-12-09 00:40:25 +01:00
|
|
|
printf("PANIC: plus d'emplacement disponible pour un novueau processus\n");
|
|
|
|
return NULL;
|
2018-12-12 15:25:04 +01:00
|
|
|
}
|
2018-12-22 00:19:34 +01:00
|
|
|
lastpid=aprocess->pid;
|
|
|
|
return lastpid;
|
2018-12-10 17:03:52 +01:00
|
|
|
}
|
|
|
|
|
2018-12-19 12:06:05 +01:00
|
|
|
/*******************************************************************************/
|
|
|
|
/* Récupère un emplacement dans la liste des tâche du processus donné */
|
|
|
|
|
|
|
|
tid_t getfreeptid(pid_t pid)
|
|
|
|
{
|
2018-12-19 16:13:47 +01:00
|
|
|
process *aprocess=findprocess(pid);
|
|
|
|
if (aprocess==NULL) return maketid(0,0);
|
|
|
|
u32 number=0;
|
2018-12-19 12:06:05 +01:00
|
|
|
task *next;
|
2018-12-19 16:13:47 +01:00
|
|
|
TAILQ_FOREACH(next, &aprocess->task_head, tailq)
|
|
|
|
if (next->tid.number>number)
|
|
|
|
number=next->tid.number;
|
|
|
|
number++;
|
|
|
|
return maketid(pid,number);
|
2018-12-19 12:06:05 +01:00
|
|
|
}
|
|
|
|
|
2018-12-12 17:57:23 +01:00
|
|
|
/*******************************************************************************/
|
|
|
|
/* Récupère le PID du processus courant */
|
|
|
|
|
2018-12-19 12:06:05 +01:00
|
|
|
pid_t getcurrentpid(void)
|
|
|
|
{
|
|
|
|
return current.pid;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Récupère le TID de la tâche courante */
|
|
|
|
|
|
|
|
tid_t getcurrenttid(void)
|
|
|
|
{
|
|
|
|
return current;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Change la tâche désigné dans le TID */
|
|
|
|
|
|
|
|
tid_t maketid(pid_t pid, u32 number)
|
|
|
|
{
|
|
|
|
tid_t newtid;
|
|
|
|
newtid.pid=pid;
|
|
|
|
newtid.number=number;
|
|
|
|
return newtid;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Récupère l'adresse d'un processus */
|
|
|
|
|
|
|
|
process* findprocess(pid_t pid)
|
2018-12-12 17:57:23 +01:00
|
|
|
{
|
2018-12-19 16:13:47 +01:00
|
|
|
if ((u32)pid>0)
|
|
|
|
return &processes[(u32)pid-1];
|
|
|
|
else
|
|
|
|
return NULL;
|
2018-12-12 17:57:23 +01:00
|
|
|
}
|
|
|
|
|
2018-12-19 12:06:05 +01:00
|
|
|
/*******************************************************************************/
|
|
|
|
/* Récupère l'adresse du processus courant */
|
|
|
|
|
|
|
|
process* findcurrentprocess(void)
|
|
|
|
{
|
2018-12-19 16:13:47 +01:00
|
|
|
return &processes[(u32)getcurrentpid()-1];
|
2018-12-09 00:40:25 +01:00
|
|
|
}
|
|
|
|
|
2018-12-10 19:12:20 +01:00
|
|
|
/*******************************************************************************/
|
|
|
|
/* Bascule vers une tâche */
|
|
|
|
|
2018-12-19 12:06:05 +01:00
|
|
|
void switchtask(tid_t tid)
|
2018-12-10 19:12:20 +01:00
|
|
|
{
|
2018-12-20 17:16:51 +01:00
|
|
|
cli();
|
2018-12-19 12:06:05 +01:00
|
|
|
tid_t previous = current;
|
|
|
|
task *atask = findtask(tid);
|
2018-12-19 16:13:47 +01:00
|
|
|
if (atask==NULL) return;
|
2018-12-19 12:06:05 +01:00
|
|
|
process *aprocess=findprocess(tid.pid);
|
2018-12-19 16:13:47 +01:00
|
|
|
if (aprocess==NULL) return;
|
2018-12-19 23:31:13 +01:00
|
|
|
current = tid;
|
2018-12-19 12:06:05 +01:00
|
|
|
if (!aprocess->iskernel)
|
2018-12-20 16:29:04 +01:00
|
|
|
{
|
2018-12-19 12:06:05 +01:00
|
|
|
setTSS(atask->kernel_stack.ss0, atask->kernel_stack.esp0);
|
2018-12-20 16:29:04 +01:00
|
|
|
wrmsr(0x175, atask->syscall_stack.esp0, 0x0);
|
|
|
|
}
|
2018-12-12 10:14:31 +01:00
|
|
|
else
|
2018-12-20 16:29:04 +01:00
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
setTSS(0x0, 0x0);
|
2018-12-20 16:29:04 +01:00
|
|
|
wrmsr(0x175, 0x0, 0x0);
|
2018-12-26 00:54:19 +01:00
|
|
|
}
|
|
|
|
if (((atask->dump.cs & 0xFFF8) !=SEL_KERNEL_CODE) && ((atask->dump.cs & 0xFFF8) !=SEL_USER_CODE))
|
|
|
|
cpuerror("SWITCH ERROR", &atask->dump, false);
|
2018-12-27 14:24:47 +01:00
|
|
|
//printf("%Y\r\n",atask->tid.pid);
|
2018-12-19 12:06:05 +01:00
|
|
|
atask->dump.eflags = (atask->dump.eflags | 0x200) & 0xFFFFBFFF;
|
|
|
|
createdump(atask->dump);
|
2018-12-26 00:54:19 +01:00
|
|
|
if ((atask->dump.cs & 0xFFF8)==SEL_KERNEL_CODE)
|
2018-12-16 01:50:03 +01:00
|
|
|
restcpu_kernel();
|
|
|
|
else
|
|
|
|
restcpu_user();
|
2018-12-12 15:25:04 +01:00
|
|
|
iret();
|
2018-12-10 19:12:20 +01:00
|
|
|
}
|
|
|
|
|
2018-12-20 16:29:04 +01:00
|
|
|
/*******************************************************************************/
|
|
|
|
/* Cherche le prochain processus */
|
2018-12-22 00:19:34 +01:00
|
|
|
|
|
|
|
process* getnextprocess(process* aprocess, u32 status)
|
2018-12-20 16:29:04 +01:00
|
|
|
{
|
2018-12-22 00:19:34 +01:00
|
|
|
u32 i = (u32) aprocess->pid;
|
|
|
|
u32 parsed = 0;
|
|
|
|
while (parsed++ < MAXNUMPROCESS && ((status != PROCESS_STATUS_ALL && processes[i++].status != status) ||
|
|
|
|
(status == PROCESS_STATUS_ALL && processes[i++].status == PROCESS_STATUS_FREE)))
|
2018-12-20 16:29:04 +01:00
|
|
|
{
|
|
|
|
if (i >= MAXNUMPROCESS)
|
|
|
|
i = 0;
|
|
|
|
}
|
2018-12-22 00:19:34 +01:00
|
|
|
if (parsed > MAXNUMPROCESS)
|
|
|
|
return NULL;
|
|
|
|
else
|
|
|
|
return &processes[i-1];
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Cherche la prochaine tâche du processus */
|
|
|
|
|
|
|
|
task* getnexttask(task *atask, u32 status)
|
|
|
|
{
|
|
|
|
task *next=atask;
|
|
|
|
while (next!=NULL)
|
|
|
|
{
|
|
|
|
next=TAILQ_NEXT(next, tailq);
|
|
|
|
if (next!=NULL && (status == TASK_STATUS_ALL || next->status == status))
|
|
|
|
return next;
|
|
|
|
}
|
|
|
|
return NULL;
|
2018-12-20 16:29:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Cherche la prochaine tâche */
|
2018-12-22 00:19:34 +01:00
|
|
|
|
|
|
|
task* getschedule(void)
|
2018-12-20 16:29:04 +01:00
|
|
|
{
|
|
|
|
process *aprocess=findcurrentprocess();
|
2018-12-22 00:19:34 +01:00
|
|
|
task *next=findcurrenttask();
|
2018-12-20 16:29:04 +01:00
|
|
|
u32 flag=0;
|
|
|
|
while(flag<2) {
|
|
|
|
if (aprocess==NULL) return NULL;
|
2018-12-22 00:19:34 +01:00
|
|
|
if (next==NULL)
|
|
|
|
next=findfirsttask(aprocess);
|
|
|
|
while(true)
|
2018-12-20 16:29:04 +01:00
|
|
|
{
|
2018-12-22 00:19:34 +01:00
|
|
|
if (next!=NULL)
|
2018-12-20 16:29:04 +01:00
|
|
|
if (current.pid==next->tid.pid && current.number==next->tid.number)
|
|
|
|
flag++;
|
2018-12-22 00:19:34 +01:00
|
|
|
else
|
|
|
|
return next;
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
next=getnexttask(next,TASK_STATUS_RUN);
|
|
|
|
}
|
|
|
|
aprocess=getnextprocess(aprocess,PROCESS_STATUS_RUN);
|
2018-12-20 16:29:04 +01:00
|
|
|
}
|
2018-12-22 00:19:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Cherche la première tâche du processeur */
|
|
|
|
|
|
|
|
task* findfirsttask(process* aprocess)
|
|
|
|
{
|
|
|
|
task *first;
|
|
|
|
return TAILQ_FIRST(&aprocess->task_head);
|
2018-12-20 16:29:04 +01:00
|
|
|
}
|
|
|
|
|
2018-12-19 12:06:05 +01:00
|
|
|
/*******************************************************************************/
|
|
|
|
/* Cherche l'adresse d'une tâche */
|
|
|
|
|
|
|
|
task* findtask(tid_t tid)
|
|
|
|
{
|
2018-12-19 16:13:47 +01:00
|
|
|
process *aprocess=findprocess(tid.pid);
|
|
|
|
if (aprocess==NULL) return NULL;
|
2018-12-19 12:06:05 +01:00
|
|
|
task *next;
|
2018-12-19 16:13:47 +01:00
|
|
|
TAILQ_FOREACH(next, &aprocess->task_head, tailq)
|
2018-12-19 12:06:05 +01:00
|
|
|
if (next->tid.number==tid.number)
|
|
|
|
return next;
|
|
|
|
}
|
|
|
|
|
2018-12-20 16:29:04 +01:00
|
|
|
|
2018-12-19 12:06:05 +01:00
|
|
|
/*******************************************************************************/
|
|
|
|
/* Cherche l'adresse de la tâche courante */
|
|
|
|
|
|
|
|
task* findcurrenttask(void)
|
|
|
|
{
|
|
|
|
return findtask(getcurrenttid());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-12-10 17:03:52 +01:00
|
|
|
/*******************************************************************************/
|
2018-12-19 07:34:44 +01:00
|
|
|
/* Détruit une tâche */
|
2018-12-10 17:03:52 +01:00
|
|
|
|
2018-12-19 07:34:44 +01:00
|
|
|
void deletetask(tid_t tid)
|
2018-12-12 15:25:04 +01:00
|
|
|
{
|
2018-12-20 17:16:51 +01:00
|
|
|
cli();
|
2018-12-19 12:06:05 +01:00
|
|
|
stoptask(tid);
|
|
|
|
process* aprocess=findprocess(tid.pid);
|
2018-12-19 16:13:47 +01:00
|
|
|
if (aprocess==NULL) return;
|
2018-12-26 00:54:19 +01:00
|
|
|
if (current.pid=tid.pid && current.number==tid.number)
|
|
|
|
current=maketid(1,1);
|
2018-12-19 12:06:05 +01:00
|
|
|
task *atask=findtask(tid);
|
2018-12-19 16:13:47 +01:00
|
|
|
if (atask==NULL) return;
|
2018-12-19 12:06:05 +01:00
|
|
|
TAILQ_REMOVE(&aprocess->task_head, atask, tailq);
|
|
|
|
vfree(atask);
|
2018-12-12 17:57:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Execute une tâche */
|
|
|
|
|
2018-12-19 07:34:44 +01:00
|
|
|
void runtask(tid_t tid)
|
2018-12-12 17:57:23 +01:00
|
|
|
{
|
2018-12-19 12:06:05 +01:00
|
|
|
task *atask=findtask(tid);
|
2018-12-19 16:13:47 +01:00
|
|
|
if (atask==NULL) return;
|
2018-12-19 12:06:05 +01:00
|
|
|
if (atask->status == TASK_STATUS_READY)
|
|
|
|
atask->status = TASK_STATUS_RUN;
|
2018-12-10 17:03:52 +01:00
|
|
|
}
|
|
|
|
|
2018-12-09 00:40:25 +01:00
|
|
|
/*******************************************************************************/
|
|
|
|
/* Initialise une tâche */
|
|
|
|
|
2018-12-19 12:06:05 +01:00
|
|
|
tid_t createtask(pid_t pid,u8 *entry, bool kerneltask)
|
2018-12-12 15:25:04 +01:00
|
|
|
{
|
2018-12-20 17:16:51 +01:00
|
|
|
cli();
|
2018-12-19 12:06:05 +01:00
|
|
|
tid_t tid;
|
|
|
|
tid.pid=pid;
|
|
|
|
process* aprocess=findprocess(pid);
|
2018-12-19 16:13:47 +01:00
|
|
|
if (aprocess==NULL) return maketid(0,0);
|
2018-12-19 12:06:05 +01:00
|
|
|
task *new = (task *) vmalloc(sizeof(task));
|
|
|
|
TAILQ_INSERT_TAIL(&aprocess->task_head, new, tailq);
|
2018-12-20 16:29:04 +01:00
|
|
|
page *apage = virtual_page_getfree();
|
2018-12-19 12:06:05 +01:00
|
|
|
if (kerneltask)
|
2018-12-19 07:34:44 +01:00
|
|
|
{
|
2018-12-19 12:06:05 +01:00
|
|
|
new->dump.ss = SEL_KERNEL_STACK;
|
2018-12-20 16:29:04 +01:00
|
|
|
if (pid!=1)
|
|
|
|
new->dump.esp =
|
|
|
|
(u32) apage->vaddr + PAGESIZE - 16;
|
|
|
|
new->dump.esp = KERNEL_STACK_ADDR;
|
2018-12-19 12:06:05 +01:00
|
|
|
new->dump.eflags = 0x0;
|
|
|
|
new->dump.cs = SEL_KERNEL_CODE;
|
|
|
|
new->dump.ds = SEL_KERNEL_DATA;
|
|
|
|
new->dump.es = SEL_KERNEL_DATA;
|
|
|
|
new->dump.fs = SEL_KERNEL_DATA;
|
|
|
|
new->dump.gs = SEL_KERNEL_DATA;
|
|
|
|
new->dump.cr3 = KERNEL_PD_ADDR;
|
2018-12-19 07:34:44 +01:00
|
|
|
}
|
|
|
|
else
|
2018-12-12 10:14:31 +01:00
|
|
|
{
|
2018-12-27 14:24:47 +01:00
|
|
|
TAILQ_INSERT_TAIL(&aprocess->pdd->page_head, apage, tailq);
|
2018-12-19 12:06:05 +01:00
|
|
|
new->kernel_stack.ss0 = SEL_KERNEL_STACK;
|
|
|
|
new->kernel_stack.esp0 =
|
2018-12-20 16:29:04 +01:00
|
|
|
(u32) apage->vaddr + PAGESIZE - 16;
|
|
|
|
page *apage = virtual_page_getfree();
|
2018-12-27 14:24:47 +01:00
|
|
|
TAILQ_INSERT_TAIL(&aprocess->pdd->page_head, apage, tailq);
|
2018-12-20 16:29:04 +01:00
|
|
|
new->syscall_stack.ss0 = SEL_KERNEL_STACK;
|
|
|
|
new->syscall_stack.esp0 =
|
|
|
|
(u32) apage->vaddr + PAGESIZE - 16;
|
2018-12-19 12:06:05 +01:00
|
|
|
new->dump.ss = SEL_USER_STACK | RPL_RING3;
|
|
|
|
new->dump.esp = USER_STACK - 16;
|
|
|
|
new->dump.eflags = 0x0;
|
|
|
|
new->dump.cs = SEL_USER_CODE | RPL_RING3;
|
|
|
|
new->dump.ds = SEL_USER_DATA | RPL_RING3;
|
|
|
|
new->dump.es = SEL_USER_DATA | RPL_RING3;
|
|
|
|
new->dump.fs = SEL_USER_DATA | RPL_RING3;
|
|
|
|
new->dump.gs = SEL_USER_DATA | RPL_RING3;
|
|
|
|
new->dump.cr3 = aprocess->pdd->addr->paddr;
|
2018-12-19 07:34:44 +01:00
|
|
|
}
|
2018-12-19 12:06:05 +01:00
|
|
|
new->tid=getfreeptid(pid);
|
2018-12-20 16:29:04 +01:00
|
|
|
if (entry==NULL)
|
|
|
|
new->dump.eip = aprocess->entry;
|
|
|
|
else
|
|
|
|
new->dump.eip = entry;
|
2018-12-19 12:06:05 +01:00
|
|
|
new->dump.eax = 0;
|
|
|
|
new->dump.ecx = 0;
|
|
|
|
new->dump.edx = 0;
|
|
|
|
new->dump.ebx = 0;
|
|
|
|
new->dump.ebp = 0;
|
|
|
|
new->dump.esi = 0;
|
|
|
|
new->dump.edi = 0;
|
|
|
|
new->status = TASK_STATUS_READY;
|
|
|
|
return new->tid;
|
2018-12-19 07:34:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Arrête une tâche */
|
|
|
|
|
|
|
|
void stoptask(tid_t tid)
|
|
|
|
{
|
2018-12-19 16:13:47 +01:00
|
|
|
task *atask=findtask(tid);
|
|
|
|
if (atask==NULL) return;
|
|
|
|
atask->status=TASK_STATUS_STOP;
|
2018-12-19 07:34:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Initialise un processus */
|
|
|
|
|
|
|
|
pid_t createprocess(u8 *src, bool kerneltask)
|
|
|
|
{
|
2018-12-20 17:16:51 +01:00
|
|
|
cli();
|
2018-12-19 12:06:05 +01:00
|
|
|
tid_t previous = current;
|
2018-12-25 19:22:56 +01:00
|
|
|
process* oldprocess=findcurrentprocess();
|
2018-12-19 12:06:05 +01:00
|
|
|
current.pid = getfreepid();
|
|
|
|
current.number = 0;
|
|
|
|
process* new=findcurrentprocess();
|
2018-12-19 16:13:47 +01:00
|
|
|
if (new==NULL) return NULL;
|
2018-12-25 19:22:56 +01:00
|
|
|
new->parent=oldprocess->pid;
|
2018-12-19 12:06:05 +01:00
|
|
|
new->pdd = virtual_pd_create();
|
2018-12-26 00:54:19 +01:00
|
|
|
new->iskernel=kerneltask;
|
2018-12-19 12:06:05 +01:00
|
|
|
TAILQ_INIT(&new->page_head);
|
2018-12-19 16:13:47 +01:00
|
|
|
TAILQ_INIT(&new->task_head);
|
2018-12-19 12:06:05 +01:00
|
|
|
setCR3(new->pdd->addr->paddr);
|
|
|
|
new->entry = loadelf(src, new->pid);
|
|
|
|
createtask(new->pid,new->entry, new->iskernel);
|
|
|
|
current = previous;
|
|
|
|
process* old=findcurrentprocess();
|
2018-12-19 16:13:47 +01:00
|
|
|
if (old==NULL) return NULL;
|
|
|
|
u32 cr3=KERNEL_PD_ADDR;
|
|
|
|
if (old->pdd!=NULL)
|
|
|
|
cr3=old->pdd->addr->paddr;
|
|
|
|
setCR3(cr3);
|
|
|
|
new->status=PROCESS_STATUS_READY;
|
2018-12-19 12:06:05 +01:00
|
|
|
return new->pid;
|
2018-12-26 00:54:19 +01:00
|
|
|
sti();
|
2018-12-09 00:40:25 +01:00
|
|
|
}
|
2018-12-19 07:34:44 +01:00
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Détruit un processus */
|
|
|
|
|
|
|
|
void deleteprocess(pid_t pid)
|
|
|
|
{
|
2018-12-20 17:16:51 +01:00
|
|
|
cli();
|
2018-12-19 12:06:05 +01:00
|
|
|
stopprocess(pid);
|
|
|
|
process* aprocess=findprocess(pid);
|
2018-12-19 16:13:47 +01:00
|
|
|
if (aprocess==NULL) return;
|
2018-12-19 12:06:05 +01:00
|
|
|
task *next;
|
|
|
|
TAILQ_FOREACH(next, &aprocess->task_head, tailq)
|
|
|
|
deletetask(next->tid);
|
2018-12-27 14:24:47 +01:00
|
|
|
virtual_pd_destroy(aprocess->pdd);
|
|
|
|
if (current.pid==pid)
|
|
|
|
current=maketid(1,1);
|
2018-12-19 12:06:05 +01:00
|
|
|
aprocess->status = PROCESS_STATUS_FREE;
|
2018-12-20 17:16:51 +01:00
|
|
|
sti();
|
2018-12-19 07:34:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Execute un processus */
|
|
|
|
|
|
|
|
void runprocess(pid_t pid)
|
|
|
|
{
|
2018-12-20 17:16:51 +01:00
|
|
|
cli();
|
2018-12-19 12:06:05 +01:00
|
|
|
process* aprocess=findprocess(pid);
|
2018-12-19 16:13:47 +01:00
|
|
|
if (aprocess==NULL) return;
|
2018-12-19 12:06:05 +01:00
|
|
|
if (aprocess->status == PROCESS_STATUS_READY)
|
|
|
|
{
|
|
|
|
aprocess->status = PROCESS_STATUS_RUN;
|
2018-12-19 16:13:47 +01:00
|
|
|
tid_t tid=maketid(pid,1);
|
2018-12-19 12:06:05 +01:00
|
|
|
task *atask=findtask(tid);
|
2018-12-19 16:13:47 +01:00
|
|
|
if (atask==NULL) return;
|
2018-12-19 12:06:05 +01:00
|
|
|
atask->status=TASK_STATUS_RUN;
|
|
|
|
}
|
2018-12-20 17:16:51 +01:00
|
|
|
sti();
|
2018-12-19 07:34:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Arrête un processus */
|
|
|
|
|
|
|
|
void stopprocess(pid_t pid)
|
|
|
|
{
|
2018-12-19 12:06:05 +01:00
|
|
|
process* aprocess=findprocess(pid);
|
2018-12-19 16:13:47 +01:00
|
|
|
if (aprocess==NULL) return;
|
2018-12-19 12:06:05 +01:00
|
|
|
if (aprocess->status == PROCESS_STATUS_RUN)
|
|
|
|
{
|
|
|
|
aprocess->status = PROCESS_STATUS_READY;
|
|
|
|
task *next;
|
|
|
|
TAILQ_FOREACH(next, &aprocess->task_head, tailq)
|
|
|
|
next->status=TASK_STATUS_READY;
|
|
|
|
}
|
2018-12-19 07:34:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|