From: Adam L. <ag...@li...> - 2000-02-20 18:06:46
|
Last post was too big ;( Fixed ;) Single letter typo (Doh!) I'm not going to commit this, but post the patches here because it's had too many problems for me to be sure of a commit, and I want you to check it first. Attached files: p.diff - patch in kernel/src p2.diff - patch in kernel/include Download these: http://www.agl.uklinux.net/ t1.tgz - Test 1, based on init, it test PCT with... t2.tgz - Test 2 e.g. $ cd kernel/src $ patch --dry-run -p0 < p.diff <check for errors, if none> $ patch -p0 < p.diff <etc for include ..> Walkthru: It starts in t1/src/main.c:107 sys_pct_register (&_pct_entry); This calls t1/src/syscall.S which moves the argument into EAX and calls in = 0x46 The kernel ends up in process.c:sys_pct_register. It stores the address of = the entry in pr_pct. t1 then goes into a loop printing "t1, heartbeat\n". t2 is in a loop printing ("t2!\n") and calling sys_pct (0, 99), which goes = to t2/src/syscall.S: sys_pct: movl 4(%esp),%ebx <move the data argument to EBX> movl 8(%esp),%eax <move the pid to jump to to EAX> pushl $sys_pct_after <push the return address, so that when prolog calls ret, it jumps to sys_pct_after>=20 pushal pushf <push other stuff for prolog> movl %esp, _crt0_saved_sp <save ESP> int $0x47 <jump to kernel> Kernel: void sys_pct (pid_t pid, uint32_t data) { cpucontext_t *cpu =3D stack_get_cpu_context (); process_t *p; if (cpu->cpu_in_revocation) { /* FIXME: What to do here ? --AGL */ #ifdef DEBUG printf ("Eek!, sys_pct() while revoking CPU time!\n"); #endif return; } if (process_lookup (&p, pid) =3D=3D -1) { /* FIXME: What to do here ? --AGL */ #ifdef DEBUG printf ("Eek!, bad pid in sys_pct()\n"); #endif return; } /* We don't update the quantums as a PCT donates them.. --AGL */ cpu->cpu_current_process =3D p; process_pct (cpu->cpu_current_process->pr_pid, data, p); } I don't know what to do about bad pids, or revokes. Currently it returns which upsets the processes and they page fault. I'd suggest a return code (in EAX maybe) that is *standard* for all syscalls. The processes can then check for errors and cleanup and pass the error code up the call chain. process_pct ends up in process.h: _process_pct (calling_pid, data, p->pr_cr3, p->pr_pct, USER_CS, 0x3202, 0, USER_DS); and that goes to process.S: _process_pct: popl %eax <clear the ret from the stack> popl %eax <move the *calling pid* to EAX> popl %ebx <move the data to EBX> popl %ecx movl %ecx,%cr3 <setup page directory> iret <jump> That goes to t1/src/syscall.S: _pct_entry: /* This is the wrapper for PCT. It restores state, pushes the pid (given by kernel in EAX) and calls pct_entry. It then saves state and returns to code. --AGL */ movl _crt0_saved_sp, %esp <restore ESP> popf <setup saved flags (saved either by sys_pct or epilog)> push %ebx <push the data into the stack> push %eax <and the pid> call pct_entry <this is in main.c> /* Better hope our stack is good --AGL */ addl $0x8,%esp <update the stack to remove the push'ed args> popal <pop all the registers that were saved> ret <jump back to wherever we were and eat up the quantums> pct_entry in t1/src/main.c prints "t1, pct (pid,data)\n" Problems: * Error codes (as discussed above) * If pct_entry calls sys_pct the stack fills up with the pushal's * If pct_entry trashes the flags the process can get upset. Maybe the flags should be popped off after calling pct_entry, but what flags should be set? * <vage> How will processes setup shared memory. Currently they can pass 32-bits per call, but really they want shared memory buffers. Could they pass capibilities that can be given to the kernel to setup the page tables? * <vage> How will the kernel demultiplex the console and keyboard? Currently all the processes outputting can get a little strange. They mustn't be allowed to write to the screen unless they have 'focus', and maybe a keyboard handling process that handles the keyboard IRQ and sends it on (via PCT) to the right process? AGL -- Smoking is one of the leading causes of statistics. |