[Prev][Next][Index][Thread]

Re: Address space question



Hello,
	Funny, I'm wrestling with a similar problem right now. I'm trying
to create a paging, task switching OS from scratch, using OSKit for its
device drivers, malloc and bootloader. So this means doing all the
interrupts myself, as well as the context switching. I fiddled with using
the TSS for context switching, but decided that was cumbersome and that I
could get a more of what I wanted by doing it myself in software.
	Anyhow, the problem I get sometimes is that when my scheduler goes
and lets a process continue running that was once interrupted, somehow the
DS and ES segment selectors are set to 0, even though I set them to
segments that span the entire address space at DPL 3 right before I switch
to the user process. Since my user processes do use data, they promptly
segfault (general protection fault).
	I also had a problem for a little while with my interrupt handlers
segfaulting because the data segment selectors DS and ES had been cleared;
although I fixed this by always setting them to those address-space
spanning segments at the top of the handlers. I know the x86 arch
sometimes clears segment selectors if you're jumping to a code segment
that is less priveged than the segment a selector points to, but in this
case these segments are DPL 3. I'm mystified, but after all the other
problems I've battled (and overcome), this one seems fairly minor. If
anyone has any ideas, please lemme know.

cheers,
steve

*------------*
| Steve Muckle
| Electrical & Computer Engineering
| Carnegie Mellon University
|
| Visit http://smuckle.com today!
*------------*

On Wed, 3 Jul 2002, UNIX savvy Brian Witt wrote:

> (* long descriptiopn of X86 address translation follows *)
>
> On Wed, 3 Jul 2002, Gopalakrishnan Suresh wrote:
> > Hello,
> >
> > In sproc_machdep_init.c, it seems that the default user CS and DS segments
> > are set to span the entire linear address space 0-0xffffffff. Since user
> > code and data all start from 0x40000000, i thought i could set the start
> > of user CS and DS at 0x40000000. This causes seg faults, i am not sure
> > why.
> >
> > Could it be because the return from user space is via the interrupt call
> > gate, and the idt descriptors are not mapped in the current user space?
> >
> > Thanks
> > --suresh
> >
> Hello Suresh,
>
> Yes. If you provide a traceback or better description of "seg faults"
> that would help.  For X86 GPF and page fault are very different.
>
>
> On the intel X86 there are two protection mechanisms: segments and
> paging.  If you skew the address, like you describe above, you use
> segment base address to "hide" portions of the virtual address
> space.  (Segments are logical, paging is virtual, RAM is physical.)
> (I think.)
>
> What you have done is change user address 0 into virtual address
> 0x40000000 .  (You should probably set the limit to 3G instead of
> the normal 4G.)  Note that all addresses the user program hands to
> the kernel, such as disk buffers, will be offset like this.  If
> you offset the address by 2G, then the kernel can live in the bottom
> 2G of virtual memory, and the user space is 2G.  In this arrangement
> there is no way for the user program to see kernel memory.  (I
> believe VSTa uses this ... http://vsta.zendo.com )
>
> Segment descriptors are unique to the X86.  A more traditional
> approach is to use the paging system.  In the page table entries
> (PTE), there are bits describing user mode access.  Typically a
> kernel can use memory anyway it wants (but code and data depending
> on segment descriptor type).  User's might have read-only or no
> access to a page (4K chunk of memory).  By altering the user
> access bits, you control access to the kernel.
>
> To implement all this, you should have a bunch of PTE pages that
> give kernel-only access to the kernel portion of the address space.
> Your initial page directory points to these page tables.  When you
> create user spaces, start with a copy of the original (kernel)
> page directory (cr3 points to it).  Then add page tables for
> the user address space (1G and up).  This will give you the
> protected kernel memory in every user's address space.
>
> ---> PROBABLY THE REASON YOUR SYSTEM IS CRASHING --->
> Why put the kernel everywhere?  Think about software interrupts.
> When a hardware interrupt occurs, the CPU reads the IDTR to
> locate the Interrupt descriptor table.  Hopefully the IDT is
> addressible while in user mode.  The segment values there
> must also address actual memory.
>
> To debug, turn off interrupts and go into user-mode.  If you can
> spin without interrupts and kernel service traps, the IDTR might
> have a (now) bad value.  Of course, the page directory must also
> be accessible.  If either of those can't be found, the Intel CPU
> takes a double-fault, which usually leads to a Triple-fault.  This
> is A Bad Thing(TM).  The CPU indicates it is stopping by asserting
> some pins on itself.  The motherboard can either turn off or
> reboot the system.
>
> I have made this happen a few times.............  :-/
>
> Well, it was long, but I hope a few points are helpful.
>
> <shameless_plug>
> I teach at CSU Sacramento (california) and we end the OS class by
> doing address translation on Pentium PC's.  Class starts in Aug.
> </shameless_plug>
>
> ---------------------------------------------------------------------
> brian witt    Railroads, computers, sailboats, etc.   bwitt@value.net
>
>
>


Follow-Ups: References: