From: Kasper V. L. <ve...@da...> - 2000-02-16 18:39:23
|
Hi guys, I've added user-level IRQ handling stuff to the Elysium kernel. The 'init' module shows how to hook the interrupt generated from an IRQ - in this particular case IRQ 1 (keyboard) - and I'll be implementing a keyboard driver in a few days. Before this week is over we'll have a primitive shell up and running :-) We still need to work on PCT (protected control transfer) - anyone? /Kasper |
From: Adam L. <ag...@li...> - 2000-02-17 08:58:18
|
On Wed, Feb 16, 2000 at 07:37:10PM +0100, Kasper Verdich Lund wrote: > Hi guys, > > I've added user-level IRQ handling stuff to the Elysium kernel. The > 'init' module shows how to hook the interrupt generated from an IRQ - in > this particular case IRQ 1 (keyboard) - and I'll be implementing a > keyboard driver in a few days. Before this week is over we'll have a > primitive shell up and running :-) > > We still need to work on PCT (protected control transfer) - anyone? Well, I've got some free time coming up. I've got some other stuff to do but I'll take a look. I've lost my Insight CD (damm!) but can you explain how the upcalling works? I've only used TSS before. popl %eax popl %eax movl %cr3,%eax iret I think that's the code (from memory), it sets up the page tables but does the iret pop stuff off the argument stack? And does that drop the privelage level? AGL |
From: Kasper V. L. <ve...@da...> - 2000-02-17 14:00:50
|
> > We still need to work on PCT (protected control transfer) - anyone? > > [snip] I've lost my Insight CD (damm!) but can you explain how the upcalling works? I've only used TSS before. > > popl %eax > popl %eax > movl %cr3,%eax > iret > > I think that's the code (from memory), it sets up the page tables but does the iret pop stuff off the argument stack? And does that drop the privelage level? The code is correct. It doesn't set up any page tables, but it does change the page directory. The assembly code you've included in your posting is the implementation of a function with the following prototype: extern void _process_run(uint32_t cr3, uint32_t eip, uint32_t cs, uint32_t eflags, uint32_t esp, uint32_t ss) __attribute__ ((noreturn)); The compiler will push the arguments from right to left leaving the stack something like this: [...:ss:esp:eflags:cs:eip:cr3:ret] ^ stack top The first instruction (popl %eax) just removes the return address, because we don't need it. The stack is now: [...:ss:esp:eflags:cs:eip:cr3] ^ stack top Next we pop the physical address of the page directory we want to switch to from the stack (popl %eax) and do the context switch. The stack now looks something like: [...:ss:esp:eflags:cs:eip] ^ stack top When we issue the 'iret' instruction the CPU will remove the eip, cs, and eflags from the stack. The CPU can tell by code segment selector that we're returning to user-level. This will make the CPU pop the ss and esp from the stack as well. We're now running in user-space at address eip with a stack specified by ss:esp. Hope this helps! /Kasper -- ------------------------------------------------------------------- Kasper Verdich Lund, Computer Science Department, Aarhus University Office: 34P.218 | Phone: (+45) 8942 5680 Email: ve...@da... | WWW: http://www.daimi.au.dk/~verdich |
From: Adam L. <ag...@li...> - 2000-02-18 18:39:01
|
On Thu, Feb 17, 2000 at 02:58:03PM +0100, Kasper Verdich Lund wrote: > > > We still need to work on PCT (protected control transfer) - anyone? > >=20 > > [snip] I've lost my Insight CD (damm!) but can you explain how the upca= lling works? I've only used TSS before. > >=20 > > popl %eax > > popl %eax > > movl %cr3,%eax > > iret > >=20 > > I think that's the code (from memory), it sets up the page tables but d= oes the iret pop stuff off the argument stack? And does that drop the prive= lage level? >=20 > The code is correct. It doesn't set up any page tables, but it does > change the page directory. The assembly code you've included in your > posting is the implementation of a function with the following > prototype: >=20 > extern void _process_run(uint32_t cr3, uint32_t eip, uint32_t cs,=20 > uint32_t eflags, uint32_t esp,=20 > uint32_t ss) __attribute__ ((noreturn)); >=20 AH! Missed that ;) Sorry, everything is clear now AGL --=20 Smoking is one of the leading causes of statistics. |
From: Adam L. <ag...@li...> - 2000-02-19 09:26:03
|
Well I've got a quick PCT system working. It ends up w/ _process_run (p->pr_cr3, p->pr_pct, USER_CS, 0x3202, 0, USER_DS); But as soon as the called process tries to push to the stack it page faults= . I didn't spend very long hunting, but anyway: SS =3D 0x00100023 ESP=3D 0x0 ESI=3D 0x0 EBP=3D 0x00837000 DS =3D 0x23 CS =3D 0x1b Should SS have the extra 1 in it? I've got to order a new Insight from Inte= l, so I don't know the selector structure. But I don't think a bad selector wo= uld cause a page fault. Thanks AGL --=20 Smoking is one of the leading causes of statistics. |
From: Kasper V. L. <ve...@da...> - 2000-02-19 11:59:56
|
> Well I've got a quick PCT system working. It ends up w/ > > _process_run (p->pr_cr3, p->pr_pct, USER_CS, 0x3202, 0, USER_DS); That looks okay. > But as soon as the called process tries to push to the stack it > page faults. I > didn't spend very long hunting, but anyway: > > SS = 0x00100023 > ESP= 0x0 > ESI= 0x0 > EBP= 0x00837000 > DS = 0x23 > CS = 0x1b Apart from the extra 1 in the SS it seems correct. And as soon as the called process tries to push something on the stack it SHOULD page fault. The exception error code should probably indicate that it is an access rights violation that caused the page fault (as opposed to a non-present page). The value you try to push on the stack will be written into memory at 0xfffffffc (which is a part of the read-only mapping of page tables and directories). If you look at init/src/crt/crt0.S you'll see the following lines of code: .align 4 _crt0_prolog: movl _crt0_saved_sp, %esp popf popal ret .align 4 _crt0_epilog: pushal pushf movl %esp, _crt0_saved_sp int $0x40 The prolog code is called with the _process_run() function and as you can see the first thing it does is to set %esp to something sensible. > Should SS have the extra 1 in it? I've got to order a new Insight > from Intel, > so I don't know the selector structure. But I don't think a bad > selector would > cause a page fault. It cannot. AFAIK it should cause a GPF, but who knows what happens. /Kasper BTW: I'm working on a specification of the PCT and IRQ stuff - I'm looking forward to seeing your work under CVS :-) |
From: Adam L. <ag...@li...> - 2000-02-20 10:37:37
|
On Sat, Feb 19, 2000 at 12:57:04PM +0100, Kasper Verdich Lund wrote: > > Well I've got a quick PCT system working. It ends up w/ > > > > _process_run (p->pr_cr3, p->pr_pct, USER_CS, 0x3202, 0, USER_DS); >=20 > That looks okay. >=20 Well I'm stuck again ;( In t2 (the test program that currently does a PCT to t1) the asm code for sys_pct is thus: sys_pct: movl $0x55,%ecx movl 4(%esp),%eax movl $0x58,%ecx pushl sys_pct_after movl $0x59,%ecx pushal movl $0x62,%ecx pushf movl $0x60,%ecx movl %esp, _crt0_saved_sp movl $0x61,%ecx movl $0x57,%ecx int $0x47 The prototype is: void sys_pct (int pid); All the movl $xx,%ecx are debugging t2 crashes with ECX=3D59 everytime (and I've put delay loops in to check it= isn't a timing thing). CS =3D 0x1b DS =3D 0x23 SS =3D 0x00100023 (that 1 is there again, but pushl sys_pct_after works...) EIP=3D 0xc35832eb ESP=3D 0x10001d0c (there's room on the stack yet) It must be that pushal crashing I think (because if it ever finished ECX wo= uld change). But how does EIP go so wonkey? AGL |
From: Kasper V. L. <ve...@da...> - 2000-02-20 11:57:20
|
> Well I'm stuck again ;( Okay - let's see... > In t2 (the test program that currently does a PCT to t1) the asm code for > sys_pct is thus: > > sys_pct: > movl $0x55,%ecx > movl 4(%esp),%eax > movl $0x58,%ecx > pushl sys_pct_after > movl $0x59,%ecx > pushal > movl $0x62,%ecx > pushf > movl $0x60,%ecx > movl %esp, _crt0_saved_sp > movl $0x61,%ecx > movl $0x57,%ecx > int $0x47 What's your strategy? Do you intend to let the called process return? When I did the IRQ handling stuff I made a mistake that produced strange results. I ran the IRQ handling process with _process_run() which changes the address space (by changing CR3), but on return I didn't change back. > The prototype is: > void sys_pct (int pid); Fine. > All the movl $xx,%ecx are debugging > t2 crashes with ECX=59 everytime (and I've put delay loops in to check it isn't > a timing thing). > > CS = 0x1b > DS = 0x23 > SS = 0x00100023 > (that 1 is there again, but pushl sys_pct_after works...) > EIP= 0xc35832eb > ESP= 0x10001d0c > (there's room on the stack yet) I'm really worried about the SS = 0x00100023 - could you send me the code? I want to investigate :-) > It must be that pushal crashing I think (because if it ever finished ECX would > change). But how does EIP go so wonkey? It's easy to mess up EIP - if you fail to maintain the stack properly a single 'ret' instruction will certainly do something like that. /Kasper BTW: Let's make a debug system call (interrupt 3 would do fine) and let that dump some basic CPU information. That would be useful instead of the movl $xx,%ecx stuff :-) |
From: Adam L. <ag...@li...> - 2000-02-20 12:10:29
|
On Sun, Feb 20, 2000 at 12:54:53PM +0100, Kasper Verdich Lund wrote: > > Well I'm stuck again ;( >=20 > Okay - let's see... BTW: Im Nebulae on us.chatjunkies.org, #linux > What's your strategy? Do you intend to let the called process return? > When I did the IRQ handling stuff I made a mistake that produced strange > results. I ran the IRQ handling process with _process_run() which > changes the address space (by changing CR3), but on return I didn't > change back.=20 Process 1 wants to jump to process 2: It saves state so prolog can restore state=20 It sets up the pid in %eax It sets a value in %ebx int $0x47 kernel jumps to the PCT entry in process 2 process 2 does what it wants at somepoint process 1 prolog is called and everything continues > > All the movl $xx,%ecx are debugging > > t2 crashes with ECX=3D59 everytime (and I've put delay loops in to chec= k it isn't > > a timing thing). Doh! The ECX came from prolog when it popal's. In sys_pct I push (in order): pushl 0x10000950 pusha pushf Now prolog pops the flags and registers ok, but the ret seems to jump to 0xc35831eb > I'm really worried about the SS =3D 0x00100023 - could you send me the > code? I want to investigate :-) SS is 16bit. Thus that 1 can't be there. It must be from the debug code that prints the value > =20 > > It must be that pushal crashing I think (because if it ever finished EC= X would > > change). But how does EIP go so wonkey? >=20 > It's easy to mess up EIP - if you fail to maintain the stack properly a > single 'ret' instruction will certainly do something like that. But popal seems to restore all the registers to the correct values in prolo= g, which makes me think the stack is OK > BTW: Let's make a debug system call (interrupt 3 would do fine) and let > that dump some basic CPU information. That would be useful instead of > the movl $xx,%ecx stuff :-) It wouldn't have helped, but it sounds a good idea. Maybe we it could set t= he single-step flag (that would have been usful), if the kernel dumps state on every instruction. Also maybe the kernel could write it to a serial port... AGL --=20 Smoking is one of the leading causes of statistics. |
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. |
From: Kasper V. L. <ve...@da...> - 2000-02-21 13:07:56
|
> Fixed ;) Single letter typo (Doh!) Let me guess... pushl sys_pct_after should have been pushl $sys_pct_after :-) |
From: Adam L. <ag...@li...> - 2000-02-21 17:19:56
|
On Mon, Feb 21, 2000 at 02:04:41PM +0100, Kasper Verdich Lund wrote: > > Fixed ;) Single letter typo (Doh!) >=20 > Let me guess... >=20 > pushl sys_pct_after=20 >=20 > should have been >=20 > pushl $sys_pct_after > =20 > :-) You guessed it! Whats next on the TODO? AGL --=20 Smoking is one of the leading causes of statistics. |
From: Kasper V. L. <ve...@da...> - 2000-02-21 17:32:25
|
> > [snipped something about the bug] > You guessed it! Whats next on the TODO? Well, Bastiaan, Claus, Jakob, and I are working on improving the web site considerably, but unfortunately the site isn't quite done yet. I think we should start writing some floppy driver code. Right now all applications have full access to all ports so it should be fairly easy to do a simple floppy disk driver. Once the floppy driver code is working we could implement a basic filesystem (such as FAT12) on top of it. Other hot topics would drivers for network adapters.... We need to get some people to work on SMP support. IMHO it has quite high priority, and I would be delighted to see - at least - the APIC CPU detection routines in a few weeks. I know Jakob is willing to do some work on this part of kernel, but he'll probably need help. Anyone? I'll be working on a kernel specification in the near future, and the plan is to have a full specification in 2 or 3 weeks. The specification will describe and explain the implementation of all the features the kernel currently lacks. I probably need help writing this specification. The kernel currently lacks support for: * protection of resources, such as physical pages * capabilities (related to the previous entry) * protection of individual I/O ports * SMP * .... ? /Kasper |
From: Adam L. <ag...@li...> - 2000-02-22 10:51:00
|
> I think we should start writing some floppy driver code. I'll see what I can dig up regarding h/w datasheets > Other hot topics would drivers for network adapters.... Despite the fact that they are the standard netcard, I can't find *any* doc= s on NE2000 programming ;(=20 =20 > We need to get some people to work on SMP support. I *hope* to be getting an SMP box quite soon. If I do (fingers crossed - I = run a P100 at the moment!), I should be able to help. > * capabilities (related to the previous entry) Well, from what little I know about O/S design there are 3 ways of doing capabilities: * In kernel, per-process tables. (Like file descriptors in *NIX), each process gets it capabilites stored in the table and can't touch them * Capabilites are stored in protected pages (e.g. EROS) so it can't cha= nge them. * Capabilites are crypto protected, usally using MAC's Personally, I like the openness of the 3rd option, but there are good reaso= ns for the others (e.g. you can't brute force them open) AGL --=20 Smoking is one of the leading causes of statistics. |
From: Adam L. <ag...@li...> - 2000-02-23 13:51:34
|
> > I think we should start writing some floppy driver code. >=20 > I'll see what I can dig up regarding h/w datasheets =20 <after a morning of coding> Yuk! Whoever designed floppy controlers should be *shot*. What a pile of cr= ap. (If you can't guess, I'm fed up with writing floppy code, which isn't worki= ng ;) AGL --=20 Smoking is one of the leading causes of statistics. |
From: Kasper V. L. <ve...@da...> - 2000-02-23 14:09:03
|
[snipped something about crappy floppy controllers] Yeah, it's probably really difficult to get working. How about looking at the Linux sources? /Kasper ------------------------------------------------------------------- Kasper Verdich Lund, Computer Science Department, Aarhus University Office: 34P.218 | Phone: (+45) 8942 5680 Email: ve...@da... | WWW: http://www.daimi.au.dk/~verdich/ |
From: Adam L. <ag...@li...> - 2000-02-23 18:28:43
|
On Wed, Feb 23, 2000 at 03:05:48PM +0100, Kasper Verdich Lund wrote: > [snipped something about crappy floppy controllers] >=20 > Yeah, it's probably really difficult to get working. How about looking at > the Linux sources? >=20 floppy.c is 4500 lines long and deals w/ every device under the sun. I tend to look at old sources (I've got linux 0.0.1), but the early kernels didn't have floppy support. I'll go hunting. AGL --=20 Smoking is one of the leading causes of statistics. |