Some questions about PM

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
JoeKayzA

Re:Some questions about PM

Post by JoeKayzA »

At least paging is well supported in today's compilers (because it needs no further support), and segmentation is not. I am used to flat address spaces so much that I could hardly imagine to implement memory protection, swapping and memory mapping through segmentation.

cheers Joe
Freanan

Re:Some questions about PM

Post by Freanan »

I think paging is slightly more difficult to implement, and it is a bit difficult to really understand how to make use of all it's elegance.
But it IS more elegant, and if i am not wrong, the slightly higher difficulty to get it work initially will simplify many memory management stuff that is going to come later on.
codemastersnake

Re:Some questions about PM

Post by codemastersnake »

This means that

* I can only access 6 segmennts at a given time ( es ds gs etc...) even if I have many segments defined....
* if I have a segment defined with base address at 0xb000 and limit till 0xbfff... then I can only access video ram through only one segment defined above not from any other in asm.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Some questions about PM

Post by Solar »

Codemaster Snake wrote: This means that

* I can only access 6 segmennts at a given time ( es ds gs etc...) even if I have many segments defined....
Correct. No matter how many segment descriptors you have in your GDT / LDT, only those currently stored in one of the segment registers can actually be addressed.
* if I have a segment defined with base address at 0xb000 and limit till 0xbfff... then I can only access video ram through only one segment defined above not from any other in asm.
Wrong. If some other segment also contains that memory area, you can access video RAM through that segment as well. There is no exclusiveness asserted by the segment feature.
Every good solution is obvious once you've found it.
codemastersnake

Re:Some questions about PM

Post by codemastersnake »

Thank you all for taking your time.....

Well I think now I will be able to program my OS in protected mode....

I'll be using Segmentation feature....

Thanks and cheers....
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Some questions about PM

Post by Solar »

I devlop in 'C'.
I'll be using Segmentation feature....
Ahem... might be the language barrier, but... remember that GCC (and most other C compilers) do only support "flat" memory, i.e. all segments starting at 0x0000 0000.
Every good solution is obvious once you've found it.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Some questions about PM

Post by Pype.Clicker »

[quote author=Solar link=board=1;threadid=8206;start=0#msg70470
Ahem... might be the language barrier, but... remember that GCC (and most other C compilers) do only support "flat" memory, i.e. all segments starting at 0x0000 0000.
[quote][/quote]

Not quite. If your kernel is written accordingly, it can perfectly cope with a non-zero based segment. That means, however, that any "linear address" must first be converted into an "offset in the data segment" before being used. In clicker, e.g. you will not write

Code: Select all

    char *video=(char*)0xb8000;
but instead

Code: Select all

   char *video=l2a(0xb8000); // l2a meaning "Logical to Absolute"
It is also perfectly possible to have a code segment that do not share the base of the data segment (provided that you do *not* store your strings in .text but in a read-only part of .data :). You may also have a distinct stack segment for each thread, using the CPU to enforce strong stack-overflow-checks (using paging for this may be fooled and it will cause havoc with kernel-stacks overflow), provided that they're expand-down and that they all share the same base as the data segment.

You could also have multiple code segments and use automatically generated (by a tool of your own) trampolines to transparently jump from one to another.

But indeed, GCC will offer no "far pointer" concept and it will not be able to access a data item that is stored on a segment that's not the current one without the help of carefully crafted inline assembly.
AR

Re:Some questions about PM

Post by AR »

Pype, how do you handle shared libraries with segmentation? Do you provide tunnelling with the kernel to change segments or something else?
JoeKayzA

Re:Some questions about PM

Post by JoeKayzA »

@Pype: I always think that segmentation could be a great thing, as long as the compiler offers a concept like far pointers. Of course you can use different code and data segments, but you couldn't even tell the compiler, for instance, that some piece of data resides in %es or %fs instead of %ds. And, btw, how do you handle stack variables? (From what I've seen in the code that gcc produces, it always uses offsets to %esp, but manipulates these with 'mov' statements through %ds instead of %ss. Or am I wrong?)

IMHO, the real benefits of segmentation are that you can independently address multiple, very small address spaces in parallel, instead of having to manipulate the page tables (or switch the page directory) whenever you need a small piece of data of another one. But this requires compiler's support for using multiple segment registers in parallel.

How do you handle these things in clicker, btw? (After what I have read, you seem to use segmentation there)

cheers Joe
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Some questions about PM

Post by Pype.Clicker »

AR wrote: Pype, how do you handle shared libraries with segmentation? Do you provide tunnelling with the kernel to change segments or something else?
Well, i don't do anything like a shared library so far. If the question is "how do you avoid duplication of shared stuff with segmentation alone", then the answer is that -even if i use some segmentation- i don't use it alone, of course.
If the question rather was "how do you make use of segmentation to ease position-independent code in shared libraries", then i'd say you can have your shlib in a different code segment (but since we have relative addressing of code, it's of little use) or make use of a trampoline to switch code segments on enter/leave of the library. That of course makes it hard to access data of the caller in the callee and vice-versa, so i don't recommend to think of such approach as "libraries", but rather as a kind of small and lightweight process that can co-exists for the sake of performing a more complex operation (think of cat, grep, sort and sed altogether in the same address space, each having its own segments and ignoring the segments the other use).
some piece of data resides in %es or %fs instead of %ds. And, btw, how do you handle stack variables?
That's a big issue. Actually, when you make a reference to [esp+xxx] or [ebp+xxx], you're implicitly referencing %ss rather than %ds. Now, look at what

Code: Select all

void myFunc(int *x) {
   *x++;
}

void caller() {
   int x;
   int *y=malloc(sizeof(int));
   myFunc(&x);
   myFunc(y);
}
and you'll understand why you _need_ to keep the data segment and the stack segment on the same base.
IMHO, the real benefits of segmentation are that you can independently address multiple, very small address spaces in parallel, instead of having to manipulate the page tables (or switch the page directory) whenever you need a small piece of data of another one. But this requires compiler's support for using multiple segment registers in parallel.
That will be only required if you want to make it explicit. Imagine you have a library able to build a "pipe" using shared memory (pages) between two components and that you communicate with that component by reading/writing to that shared area.

Each component will have its own data/stack segment and the code of each component blissfully ignores the presence of other segments. The only code that need to be aware of it is the code for "synchronizing" those data (e.g. jump to the other component when sufficient amount of data have been written). That can be hidden by the library and it will mainly consist of

Code: Select all

    push ds
    mov [controlblock],esp
    mov [controlblock+4],ss
    lss esp,[newcontrolblock]
    pop ds
    jmp __function
just a regular "stack switch", in some sense.
How do you handle these things in clicker, btw? (After what I have read, you seem to use segmentation there)
so far, the use of segmentation in clicker is limited to 2 things:
- allow the kernel to be loaded anywhere in conventional memory -- which was mainly useful when the "bootloader" was a regular MS-DOS program
- allow kernel stack to have their own limit that triggers a "stack fault" when encountered (hooked by a task gate).

I don't have a real implementation of all the rest, but if ia-32 lasts as long as i hope, there will eventually be :)
AR

Re:Some questions about PM

Post by AR »

JoeKayzA wrote:Of course you can use different code and data segments, but you couldn't even tell the compiler, for instance, that some piece of data resides in %es or %fs instead of %ds. And, btw, how do you handle stack variables? (From what I've seen in the code that gcc produces, it always uses offsets to %esp, but manipulates these with 'mov' statements through %ds instead of %ss. Or am I wrong?)

IMHO, the real benefits of segmentation are that you can independently address multiple, very small address spaces in parallel, instead of having to manipulate the page tables (or switch the page directory) whenever you need a small piece of data of another one. But this requires compiler's support for using multiple segment registers in parallel.
More specifically, it is also a limitation of the available languages [that I am aware of] except Assembly of course, how would you even write "Use %ES" in C for example?

Code: Select all

char *videomem = (char*{%ES})0xB8000;
So not only do you need a specific compiler, but a specific language as well (or at least modify an existing one to create a new dialect like the example above - which is more complex then it appears since you need to modify the pointer type to include the segment information).
AR

Re:Some questions about PM

Post by AR »

Pype.Clicker wrote: If the question is "how do you avoid duplication of shared stuff with segmentation alone"...
If the question rather was "how do you make use of segmentation to ease position-independent code in shared libraries"...
Actually neither :), I meant how do you actually call functions in the libraries? To have a seperate code segment that doesn't cover the whole address space would imply that you need to switch segments to execute library functions, the only way I thought of dealing with this was to require the kernel to tunnel between segments to call library functions on the process' behalf, that would incur a context switching cost and also plays hell with dynamic linking so I was wondering if you had a way around it?

Libraries fulfill a different purpose than your description though, they don't so much provide a service as they simplify providing the service that the program is trying to perform, take libc, libstdc++ and Boost for example, they are just librarys of functions to simplify programming tasks, it wouldn't really be appropriate to tunnel to them for each call and I would like to avoid requiring static linkage for everything. (I am trying to create a "legacy avoidance" feature, everything, including system calls is concealed in libraries so if I change the kernel ABI or the ABI of any of the services then it won't require a code update and recompile since the libraries will automagically translate the older functions into the newer ones with the program being none the wiser - this avoids having to do the checks in the services or the kernel which helps prevent unnecessary bloat and conditions checks which would penalise up-to-date software *cough*MSWindows*cough*)
User avatar
Colonel Kernel
Member
Member
Posts: 1437
Joined: Tue Oct 17, 2006 6:06 pm
Location: Vancouver, BC, Canada
Contact:

Re:Some questions about PM

Post by Colonel Kernel »

AR wrote:I meant how do you actually call functions in the libraries? To have a seperate code segment that doesn't cover the whole address space would imply that you need to switch segments to execute library functions, the only way I thought of dealing with this was to require the kernel to tunnel between segments to call library functions on the process' behalf, that would incur a context switching cost and also plays hell with dynamic linking so I was wondering if you had a way around it?
Can't the code calling the library function just change CS itself? I thought that was perfectly fine, as long as the selector being loaded is valid. The kernel would need to be involved when adding a new code segment to the LDT for that process, but otherwise it should be fine. Windows 3.x was able to do it in 16-bit protected mode, anyway...
Top three reasons why my OS project died:
  1. Too much overtime at work
  2. Got married
  3. My brain got stuck in an infinite loop while trying to design the memory manager
Don't let this happen to you!
AR

Re:Some questions about PM

Post by AR »

I was under the impression that changing CS/DS/ES/FS/GS/SS was a privileged operation since it would violate containment if the program can change it's own segments (which is presumably why "gates" exist).

Windows 3.x ran everything in Ring0 IIRC, so that isn't a big suprise.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Some questions about PM

Post by Pype.Clicker »

you can perfectly change the current selector for any register segment as long as you don't enfringe the priority rules, which means:
1) you don't try to call code segment at another priviledge level than yours
2) you don't try to access a code segment that requires higher priviledge than yours.
Post Reply