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

Re: Address space question



(* 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: