OSDev.org

The Place to Start for Operating System Developers
It is currently Mon Aug 03, 2020 10:09 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: How each process can have same kernel address space?
PostPosted: Thu Nov 03, 2016 4:31 pm 
Offline
Member
Member

Joined: Mon Sep 19, 2016 5:34 am
Posts: 27
When system initialized and run its first init program, some high memory address had mapped. For example 0x80000000 - 0x80100000.
Then init execute its child processes, say process A, B, C,..., X. All process have mapped system address space equally.
What if X tries to load more kernel module? And now kernel mapping for X will grow till 0x80900000.
How each process (A,B,C,...,Y) adapt with newly mapped address space : 0x80100000 - 0x80900000?
I think, setting up higher half PDE at startup is inefficient. Especially for system that implements PAE.

_________________
https://github.com/irvanherz/jaura/


Top
 Profile  
 
 Post subject: Re: How each process can have same kernel address space?
PostPosted: Thu Nov 03, 2016 7:53 pm 
Offline
Member
Member

Joined: Fri Aug 19, 2016 10:28 pm
Posts: 360
You only need to set the top-level directory. This will cost you 2MB of memory or less. For many systems, it won't be noticed.

Alternatively, I think Windows used to have a prototype page directory and on-demand address space assignment. It was merely mentioned somewhere and I couldn't find more information. Probably the page directory of the initial process had invalid entries that the child processes could fault by copying the global prototypes. In case of a blank prototype, the OS could allocate table on demand and point the respective prototype entry. Probably the performance wasn't too hurt overall, although I cannot find reasons to recommend such approach for a consumer configuration today.


Top
 Profile  
 
 Post subject: Re: How each process can have same kernel address space?
PostPosted: Fri Nov 04, 2016 5:40 am 
Offline
Member
Member

Joined: Mon Sep 19, 2016 5:34 am
Posts: 27
simeonz wrote:
You only need to set the top-level directory. This will cost you 2MB of memory or less. For many systems, it won't be noticed.


What about PAE? It will need more space for those directories.
Is it OK to left them partially empty?

_________________
https://github.com/irvanherz/jaura/


Top
 Profile  
 
 Post subject: Re: How each process can have same kernel address space?
PostPosted: Fri Nov 04, 2016 9:54 am 
Offline
Member
Member

Joined: Fri Aug 19, 2016 10:28 pm
Posts: 360
Quote:
What about PAE? It will need more space for those directories.
On x86 PAE I think you need only a page or two pre-allocated (for the page directories of the kernel address range). But I may be missing a detail here. I hope someone else confirms this.

For x64, you need to pre-allocate the page directory pointer tables (level 3) and initialize the level 4 table with the pointers, etc. So, for the kernel address range, these are 256 tables 4K each, which is 1MB pre-allocated and shared between all processes. Then you can allocate the lower levels when faulting on level 3. The level 3 entries should be left invalid initially for the trick to work.


Top
 Profile  
 
 Post subject: Re: How each process can have same kernel address space?
PostPosted: Fri Nov 04, 2016 6:22 pm 
Offline
Member
Member

Joined: Mon Sep 19, 2016 5:34 am
Posts: 27
OK, It's all clear now. I just forgot that PAE has 4MB page size.
But it stiil unclear when facing user program. Do I need to preallocate page directory for user space programs at loading process ?
By doing so, page allocation is simple, I don't need checking page directory when allocating pages. But I think it will be inefficient.

_________________
https://github.com/irvanherz/jaura/


Top
 Profile  
 
 Post subject: Re: How each process can have same kernel address space?
PostPosted: Fri Nov 04, 2016 10:24 pm 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

irvanherz wrote:
When system initialized and run its first init program, some high memory address had mapped. For example 0x80000000 - 0x80100000.
Then init execute its child processes, say process A, B, C,..., X. All process have mapped system address space equally.
What if X tries to load more kernel module? And now kernel mapping for X will grow till 0x80900000.
How each process (A,B,C,...,Y) adapt with newly mapped address space : 0x80100000 - 0x80900000?
I think, setting up higher half PDE at startup is inefficient. Especially for system that implements PAE.


For paging; the highest level paging structure (e.g. the Page Directory Pointer Table for PAE) must be different for different virtual address spaces/processes; but one (or more) of the second highest level paging structures (e.g. a Page Directory for PAE) can be used in all virtual address spaces, so that all lower level paging structures (e.g. Page Tables and Pages) used by it end up being global, and so any change made within the area effected by the second highest level paging structure is global.

Essentially; for PAE the second highest level paging structure (a Page Directory) effects 1 GiB of virtual space; which means that (for 2 GiB of "kernel space") you can pre-allocate 2 Page Directories during boot and use them in all virtual address spaces (in all Page Directory Pointer Tables) and any change made to kernel space from any virtual address space will automatically effect all virtual address spaces.

For long mode, the second highest level paging structure (a Page Directory Pointer Table) effects 512 GiB of virtual space; which is why a lot of operating systems use 512 GiB of kernel space in long mode.

For "plain 32-bit paging", the second highest level paging structure (a Page Table) only effects 4 MiB of virtual space; which means that (for 2 GiB of kernel space) you'd have to pre-allocate 512 Page Tables during boot. This isn't as nice (and will cost 2 MiB regardless of whether it's actually used or not).

Also note that (even for PAE where it could work very nicely) there may be other things that need to be taken into account. For example, if you decide to use paging to create a 32 MiB "CPU specific" area in kernel space (where that area is different for each different CPU) then the larger 1 GiB of space that contains that 32 MiB area can't be global.

For cases where you can't or don't use "global second highest level paging structure", you need an alternative. The simplest alternative is to map the highest (and/or second highest) level paging structure/s into kernel space as if they're normal pages. For example; for "plain 32-bit paging" you could have something like an array of Page Directories with one entry per virtual address space/process; then when you need to make a global change (e.g. add or remove a page table in kernel space) you'd do a "for each virtual address space { make change using the mapping }" loop.

More complex alternatives are possible. For example; you could have an authoritative copy in kernel space somewhere (e.g. in kernel's ".bss") and use version numbering; where you change the authoritative copy and do "authoritativeVersion++;" and then update each process that's currently running on each CPU (and don't bother updating processes that aren't currently running); and then during task switches you can do "if(process.kernelSpaceVersion != authoritativeVersion) { copy authoritative copy into this virtual address space; process.kernelSpaceVersion = authoritativeVersion;}".

The most complex (and possibly the fastest) alternative I've heard of is to combine "authoritative copy and versioning" with journaling. Essentially; you'd have a relatively small circular buffer of entries that describe what changed from one version to the next (the journal); and when you update a virtual address space from a "recent enough" version to the current version you only copy whatever is necessary from the authoritative copy (and don't have to copy everything from the authoritative copy). Of course if the virtual address space is too old (e.g. if the journal has 32 entries but the virtual address space needs more than 32 changes) you'd fall back to copying everything from the authoritative copy.


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject: Re: How each process can have same kernel address space?
PostPosted: Sat Nov 05, 2016 4:11 pm 
Offline
Member
Member

Joined: Wed Oct 01, 2008 1:55 pm
Posts: 2249
Brendan wrote:
Essentially; for PAE the second highest level paging structure (a Page Directory) effects 1 GiB of virtual space; which means that (for 2 GiB of "kernel space") you can pre-allocate 2 Page Directories during boot and use them in all virtual address spaces (in all Page Directory Pointer Tables) and any change made to kernel space from any virtual address space will automatically effect all virtual address spaces.

For long mode, the second highest level paging structure (a Page Directory Pointer Table) effects 512 GiB of virtual space; which is why a lot of operating systems use 512 GiB of kernel space in long mode.

For "plain 32-bit paging", the second highest level paging structure (a Page Table) only effects 4 MiB of virtual space; which means that (for 2 GiB of kernel space) you'd have to pre-allocate 512 Page Tables during boot. This isn't as nice (and will cost 2 MiB regardless of whether it's actually used or not).


If you plan for being compatible with all three modes, you need to settle for something that works for more than one of them. The only solution to that is to have the kernel as a number of 4k pages of protected mode paging, as this can work both with PAE and long mode paging too.


Top
 Profile  
 
 Post subject: Re: How each process can have same kernel address space?
PostPosted: Sat Nov 05, 2016 7:47 pm 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

rdos wrote:
If you plan for being compatible with all three modes, you need to settle for something that works for more than one of them. The only solution to that is to have the kernel as a number of 4k pages of protected mode paging, as this can work both with PAE and long mode paging too.


That's extremely retarded.

If you plan to support all 3 modes; you use conditional compiling (e.g. "#ifdef ARCH_x86_64") to get a kernel for long mode, a kernel for protected mode without PAE and a kernel for protected mode with PAE (and some kernels for ARM, and PowerPC, and ....). Then you have a "virtual memory manager abstraction" and put all the architecture specific code behind the abstraction, so that the code for each architecture can use the best possible method/s for that specific architecture without stupid inefficient compromises.

Then you have an OS installer that determines which kernel to install, and/or a boot loader that determines which kernel to boot; which uses auto-detection (e.g. CPUID on 80x86) to ensure there's no end-user hassle (e.g. so the same "OS installer CD" works on all supported computers without asking the user which kernel to use).


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject: Re: How each process can have same kernel address space?
PostPosted: Mon Nov 07, 2016 1:45 pm 
Offline
Member
Member

Joined: Wed Oct 01, 2008 1:55 pm
Posts: 2249
Brendan wrote:
Hi,

rdos wrote:
If you plan for being compatible with all three modes, you need to settle for something that works for more than one of them. The only solution to that is to have the kernel as a number of 4k pages of protected mode paging, as this can work both with PAE and long mode paging too.


That's extremely retarded.

If you plan to support all 3 modes; you use conditional compiling (e.g. "#ifdef ARCH_x86_64") to get a kernel for long mode, a kernel for protected mode without PAE and a kernel for protected mode with PAE (and some kernels for ARM, and PowerPC, and ....). Then you have a "virtual memory manager abstraction" and put all the architecture specific code behind the abstraction, so that the code for each architecture can use the best possible method/s for that specific architecture without stupid inefficient compromises.


Now that is really retarded. Not only do I hate #ifdefs generally, but you are setting up something that is not flexible at all. I prefer my kernel to be multi-mode, and I don't want it to be "protected mode", "long mode" or "PAE". I also don't want to restrict myself to only 32-bit, or only 64-bit applications. I support all of them, and also 16-bit protected mode and old DOS programs with the proper emulator loaded. And I have no "wow" modules in the design.

Brendan wrote:
Then you have an OS installer that determines which kernel to install, and/or a boot loader that determines which kernel to boot; which uses auto-detection (e.g. CPUID on 80x86) to ensure there's no end-user hassle (e.g. so the same "OS installer CD" works on all supported computers without asking the user which kernel to use).


That's even more retarded. I don't "install" my OS. It boots from a single file that is created with a tool that runs on Windows or on my OS.


Top
 Profile  
 
 Post subject: Re: How each process can have same kernel address space?
PostPosted: Mon Nov 07, 2016 2:10 pm 
Offline
Member
Member
User avatar

Joined: Wed Jul 13, 2011 7:38 pm
Posts: 550
Supporting that much legacy cruft -- especially legacy cruft from old 80s operating systems -- is, to use your and Brendan's parlances, the supremely retarded thing here.

I'm with Brendan on this one. It's a lot more sensible to have one kernel per platform than to try to shove a half dozen kernels into one and get them to cooperate.


Top
 Profile  
 
 Post subject: Re: How each process can have same kernel address space?
PostPosted: Mon Nov 07, 2016 2:32 pm 
Offline
Member
Member

Joined: Wed Oct 01, 2008 1:55 pm
Posts: 2249
Kazinsal wrote:
Supporting that much legacy cruft -- especially legacy cruft from old 80s operating systems -- is, to use your and Brendan's parlances, the supremely retarded thing here.

I'm with Brendan on this one. It's a lot more sensible to have one kernel per platform than to try to shove a half dozen kernels into one and get them to cooperate.


Well, in your model, they don't cooperate at all. You need a reinstall to switch model, so there is no cooperation. Which also means that in order to run the next program, you might need to install a different kernel because the current one cannot handle the program. Now, that IS retarded.


Top
 Profile  
 
 Post subject: Re: How each process can have same kernel address space?
PostPosted: Mon Nov 07, 2016 2:46 pm 
Offline
Member
Member
User avatar

Joined: Wed Jul 13, 2011 7:38 pm
Posts: 550
Why would I need to run a 32-bit program on a 64-bit kernel when I could just recompile the 32-bit program for the 64-bit architecture? And more pressingly, why would I need to run a 16-bit DOS program (or gods forbid, a 32-bit DPMI program) on my 32-bit kernel?


Top
 Profile  
 
 Post subject: Re: How each process can have same kernel address space?
PostPosted: Mon Nov 07, 2016 4:06 pm 
Offline
Member
Member
User avatar

Joined: Fri Oct 27, 2006 9:42 am
Posts: 1637
Location: Athens, GA, USA
I think there are a lot of people talking cross-purposes in this thread. We need to pin down just what we are really talking about, or it's going to degenerate further into the realm of flames.

@rdos: what, in either the OP's description or the responses, led you to the conclusion that "plan[ning] for being compatible with all three modes" was an issue in the discussion?

Also, I know of no OS in use (including RDOS, to the best of my knowledge) that actually is written to support multiple modes in a single installation - the closest thing I can think of is Windows 3.0 (which was not a stand-alone OS, as I am sure you remember) which was primarily a 16-bit 80286 protected mode system and needed the WIN32S ad-on to run 32-bit programs (a 'feature' rapidly discarded with Windows 3.1, along with support for 286 processors in general - you could run older 16-bit programs, but you needed a processor with 32-bit 80386 protected mode support to run it).

This is an especially puzzling assertion from you, as RDOS is a real-time control OS that (if I understand your website correctly) needs to be compiled and tuned for the specific platform it is to run on. It would never run applications in different memory models because, well, first off, it generally isn't used to run applications in the conventional sense at all, and second, all code for it needs to be compiled locally (or at least be written for the specific hardware it is controlling, and tuned to the specific hosts), and presumably the tuning has effects similar to those brought about by an equivalent conditional compilation.

I can appreciate the dislike of C style conditional compilation (I do to, though I have no problem with conditional compilation in general - it is, after all, a common idiom in Lisp macrology), but since conditional compilation switches are not the only solution to that problem even in C, I am not sure where the objection lies. I can see the purpose of adaptive optimization in general, but I cannot see a case where it would apply to the memory model on a given system (though it could, I suppose, apply to the memory models of separate client domains under a single hypervisor), nor would it be required in order to run code compiled under an older memory model in a newer system - and, in any case, adaptive systems generally work by selective recompilation anyway (which is how I plan to do it in Kether myself).

However, I get the feeling that something is missing in this conversation, a piece of context that makes your statements sensible in some way that the rest of us are missing. If you could clarify your statements, please do so.

_________________
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
μή εἶναι βασιλικήν ἀτραπόν ἐπί γεωμετρίαν
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.


Top
 Profile  
 
 Post subject: Re: How each process can have same kernel address space?
PostPosted: Tue Nov 08, 2016 1:51 am 
Offline
Member
Member

Joined: Wed Oct 01, 2008 1:55 pm
Posts: 2249
Schol-R-LEA wrote:
Also, I know of no OS in use (including RDOS, to the best of my knowledge) that actually is written to support multiple modes in a single installation - the closest thing I can think of is Windows 3.0 (which was not a stand-alone OS, as I am sure you remember) which was primarily a 16-bit 80286 protected mode system and needed the WIN32S ad-on to run 32-bit programs (a 'feature' rapidly discarded with Windows 3.1, along with support for 286 processors in general - you could run older 16-bit programs, but you needed a processor with 32-bit 80386 protected mode support to run it).

This is an especially puzzling assertion from you, as RDOS is a real-time control OS that (if I understand your website correctly) needs to be compiled and tuned for the specific platform it is to run on. It would never run applications in different memory models because, well, first off, it generally isn't used to run applications in the conventional sense at all, and second, all code for it needs to be compiled locally (or at least be written for the specific hardware it is controlling, and tuned to the specific hosts), and presumably the tuning has effects similar to those brought about by an equivalent conditional compilation.

I can appreciate the dislike of C style conditional compilation (I do to, though I have no problem with conditional compilation in general - it is, after all, a common idiom in Lisp macrology), but since conditional compilation switches are not the only solution to that problem even in C, I am not sure where the objection lies. I can see the purpose of adaptive optimization in general, but I cannot see a case where it would apply to the memory model on a given system (though it could, I suppose, apply to the memory models of separate client domains under a single hypervisor), nor would it be required in order to run code compiled under an older memory model in a newer system - and, in any case, adaptive systems generally work by selective recompilation anyway (which is how I plan to do it in Kether myself).

However, I get the feeling that something is missing in this conversation, a piece of context that makes your statements sensible in some way that the rest of us are missing. If you could clarify your statements, please do so.


RDOS was written with a mixed-memory model to begin with. Drivers can be 16-bit or 32-bit segmented, and syscalls serve both 16-bit and 32-bit targets, primarily by extending registers for 16-bit targets to 32-bits. C based drivers must be 32-bit. Applications are flat (but don't need to be). Flat memory model drivers are not supported.

To handle all three paging models doesn't need conditional compiling. First, PAE and long mode is basically the same for a protected mode application. The only difference is that behind-the-scenes, there needs to be a 64-bit page fault handler for long-mode, while page faults for PAE (and protected mode) are handled with protected mode handlers. Second, to distinguish between 64-bit page entries (long mode and PAE) and 32-bit page entries, the most convenient is to use a method table for all the APIs that are needed for handling pages. That hides the differences for the rest of the kernel too.


Top
 Profile  
 
 Post subject: Re: How each process can have same kernel address space?
PostPosted: Tue Nov 08, 2016 4:36 am 
Offline
Member
Member

Joined: Tue May 13, 2014 3:02 am
Posts: 279
Location: Private, UK
Schol-R-LEA wrote:
Also, I know of no OS in use (including RDOS, to the best of my knowledge) that actually is written to support multiple modes in a single installation - the closest thing I can think of is Windows 3.0 (which was not a stand-alone OS, as I am sure you remember) which was primarily a 16-bit 80286 protected mode system and needed the WIN32S ad-on to run 32-bit programs (a 'feature' rapidly discarded with Windows 3.1, along with support for 286 processors in general - you could run older 16-bit programs, but you needed a processor with 32-bit 80386 protected mode support to run it).


I feel a little bit of factual correction is needed here... Windows 3.0 was the last version of Windows to support real (8086-compatible) mode and the only version to support 3 modes (Real, Standard (286) and 386-Enhanced). The previous 2.x/386 versions supported Real mode and a proto-386-Enhanced mode (the non-/386 versions only supported Real mode) that ran Real-mode Windows code in V86 mode along with concurrent V86 DOS sessions. All Windows user applications were Real-mode applications prior to Windows 3.0.

Windows 3.1 dropped support for Real mode. Windows 3.11 dropped Standard mode.

Win32s was a 32-bit "Windows Extender" that provided a (restricted) Windows NT-compatible 32-bit API (Windows NT was always 32-bit native) for user applications. It required Windows 3.1 or later, but was not shipped with any version of Windows. Third party 32-bit extenders also existed. No version of Windows 3.x supported 32-bit applications "natively".

Windows 3.x did have separate kernels for running in different modes (KERNEL.EXE for Real mode, KRNL286.EXE for Standard mode and KRNL386.EXE for 386-Enhanced mode), but, of course most Windows applications designed for Real mode could be run in Protected mode (Standard or 386-Enhanced) without modification. The reverse was obviously not true. DOS applications were run in different ways depending on the mode ("shelling out" in Real, suspending/swapping in Standard, V86/DPMI in 386-Enhanced). Apart from the introduction of a "native" 32-bit API, the basic architecture of Windows 9x was exactly the same as 386-Enhanced Windows 3.x.

Bringing the discussion back into the 21st century... I believe emulation is the best way to support older applications on modern OSs. Modern CPUs are more than fast enough to run any application designed for DOS at full speed in software emulation. Emulation is more portable and vastly simplifies the job of the kernel. A somewhat "integrated" emulator (e.g. DOSBox, Windows VDMs on non-x86 NT) can be pretty much seamless.

Supporting 32-bit "native" binaries on a 64-bit kernel can make a lot of sense if your OS supports both 32-bit and 64-bit architectures. If not, a "fat" binary format or similar is essential; relying on the user to choose the right binary is a bad user experience.

I personally also believe that supporting 32-bit x86 is still worthwhile; 32-bit only x86 CPUs aimed at "consumer" markets are still being manufactured by the likes of VIA and are still very common in second-hand equipment in less "developed" areas of the world. Not to mention that getting someone to try out your OS on their "old" system is going to be much easier than getting them to abandon mainstream software on a brand new system. Linux gained a lot of early popularity by giving new life to "obsolete" 386/486 systems in the late 1990s (as low/zero-cost servers, etc.); doing something similar in the 21st century might help your OS gain a few users...

_________________
Image


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 12 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group