difference between a segment and a page

This is a discussion on difference between a segment and a page within the Tech Board forums, part of the Community Boards category; Originally Posted by matsp As Elysia says, pages are definitely still in use. That is how your Linux or Windows ...

  1. #16
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,239
    Quote Originally Posted by matsp View Post
    As Elysia says, pages are definitely still in use. That is how your Linux or Windows can run several applications that are all loaded at the same address, but in their own virtual space.

    Yes, flat memory model, using the segments as I described above (base=0, limit=4GB) is the convention used by most OS's.
    On that note, the NX problem could always be solved all the way as early as the 80386, but you have to use the segmentation architecture to do it. Under segmentation, only code within a "code segment" can execute. Since segments are stupid when compared with paging, nobody ever took advantage of this. I've written code in both spheres, and I don't blame them, either.

  2. #17
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by brewbuck View Post
    With OS support, the processor could set up alternate page tables pointing to the same region of memory, but with different execute/write bits.

    Failing that, on a POSIX-like operating system you can call mprotect() to cause the pages to become writable, write the generated code into them, then call mprotect() again to flip them back to read-only. That's a lot of thunking in and out of the kernel, though.
    Actually, there is no need to alias the same bit of memory - you just have to make sure that data-space that also need to be executable DOES NOT have the NX/XD bit set, whilst normal data-space not intended for execution has said bit set. Aliasing the same location in at different virtual locations just causes all sorts of confusion.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #18
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by brewbuck View Post
    On that note, the NX problem could always be solved all the way as early as the 80386, but you have to use the segmentation architecture to do it. Under segmentation, only code within a "code segment" can execute. Since segments are stupid when compared with paging, nobody ever took advantage of this. I've written code in both spheres, and I don't blame them, either.
    Yes, indeed, as long as CS and DS or SS don't overlap, there is no risk of execution anywhere outside the code-segment. But as you say, it gets a bit clunky, and doesn't work well with traditional pointer architectures.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #19
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,239
    Quote Originally Posted by matsp View Post
    Aliasing the same location in at different virtual locations just causes all sorts of confusion.
    It happens quite often, whenever processes share a memory map or a SHM segment...

    You could probably do it even without special OS support, simply by opening /proc/self/mem and mmapping it straight back into your own address space. Yeah, it kinda makes my head hurt.

  5. #20
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by brewbuck View Post
    It happens quite often, whenever processes share a memory map or a SHM segment...

    You could probably do it even without special OS support, simply by opening /proc/self/mem and mmapping it straight back into your own address space. Yeah, it kinda makes my head hurt.
    Yes, but shared memory isn't mapping the same memory twice IN THE SAME PROCESS.

    And yes, you can trick around with mmaping your own memory, but that's rarely meaningful.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #21
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,239
    Quote Originally Posted by matsp View Post
    Yes, but shared memory isn't mapping the same memory twice IN THE SAME PROCESS.

    And yes, you can trick around with mmaping your own memory, but that's rarely meaningful.
    I have to do it as part of the startup process of my own toy kernel. When you flip paging on, you have to make sure that CS:EIP is still pointing to a valid instruction. I map the kernel way up at 0xC0100000, but I also have to make sure the first megabyte of memory is mapped to itself, so that when you flip the switch you're still okay. Of course I immediately jump up to 0xC0100000 and then remove the identity map. The first meg actually ends up mapped at 0xC0000000, right beneath the kernel in VM space.

    I guess it's a kernel, not a "process," but it's still something I have to do.

    Also, there's a little catch you have to deal with when calling or gating between TSS segments -- the processor fills in the TSS link field of the switched-to-TSS using the page tables of the switching-from TSS. But when the TSS call returns, it restores the link field using the page tables of the switched-to process. This implies that the TSS segments themselves have to be placed somewhere in memory and mapped to the same virtual address in both of the involved tasks.

    It's all so "fun..."

  7. #22
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, startup code is kind of special case too. And kernels sometimes map user-space memory into kernel mode too, which is another special case. But it's a good idea not to do that unless there is a GOOD reason for it. [E.g. kernel needs to keep a reference to the user processes memory after the system call has been finished. Since the user can free that memory back to the kernel and then do other things with it if we juse keep the user-space mapping around, there is a reason to map it "again"].

    TSS belongs in the kernel - and by the way, most of the time, you don't want to use the x86 task-switching mechanisms. [We're getting away from the subject, but ...]. I have ported/written/worked on several different kernels, and none of them use Task-Gates or Task Switches using the x86 mechanisms except for two special cases:
    1. Stack fault.
    2. Double fault.

    Since both of these tend to happen when "things have gone really wrong", you may need a fresh stack, CR3, etc to be able to continue anything useful at all. Stack-fault can of course happen in user-mode, so you detect that case and continue to a kernel function to grow the stack or kill the user-mode app, whichever makes most sense. But in kernel mode, if you ran out of stack, it's bad news - and normal fault handling don't work well when you have "no workable stack", so Task-gate is the only viable option. Double-fault is either a consequence of completely blowing the stack, or something else horribly wrong, so same thing there.

    You may need a TSS for switching user/kernel stack, but that's all it does in the normal case. But in modern processors there are "syscall" or "sysenter" (which is which I can never remember) that avoids that for system calls, which leaves interrupts and traps/exceptions. It may be that you have to support multiple TSS so that multiple threads can be in the kernel at the same time.

    For general task-switching, you are much better off just writing the code to switch from one process to another (save all registers on stack, save stack in process control block, and fetch page-table map from the new proces into CR3, then reverse the save-process).

    FPU state is lazy-saved "on demand".

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Page 2 of 2 FirstFirst 12
Popular pages Recent additions subscribe to a feed

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21