I am about to begin re-writing my kernel. It will be more towards the microkernel approach, I think.
Basically when grub loads, it will load a module package into memory along with a service package and app package.
Just enough things to get the kernel up and running.
Modules will be loaded into the kernel's own address space and page directory.
Services and Apps however, will have there own PD's.
The memory model I am choosing to use is as follows:
Physical:
0-1mb - Reserved for vm86 Support.
1mb - 2mb kernel
2mb - 3mb kernel data structures
3mb - 16mb reserved for dma (if mem total > 32)
16mb > Memory used for everything else, heaps, apps, etc etc...
Virtual (Kernels PD):
0-4mb - 1 to 1 map, includes the kernel and its data structures.
508mb-512mb - Kernels Recursive PD.
512mb - 1gb - Kernels Heap
1gb - 2gb - Modules (Modules will be compiled with fixed starting addresses, ie, perhaps one every 16mb)
2gb - 4gb - Reserved (Apps and Services)
Applications (and services PD)
0-2gb - Kernel Block
2gb - 4gb - Application Starting Address Home.
I know this may not be the best memory layout, I am not a fan of the higher half, and tbh, my OS will never exceed the setup above, even if it gets off the ground.
Now my question is:
If I have two applications and the kernel running, and I switch from Kernel PD to App1 PD, will that creates misses for all of the 0-2gb code? Those address do not change in the new PD, but I know the switching PDs causes paging misses right?
Thanks,
Rich
Question about Paging Misses.
Re: Question about Paging Misses.
Hi,
Cheers,
Brendan
Does that include the VFS and hard disk drivers (both with potentially several GB of cached data)?astrocrep wrote:Modules will be loaded into the kernel's own address space and page directory.
If the CPU supports "global pages" (Pentium and later CPUs IIRC) and if the OS uses this feature for the kernel's pages, then changing CR3 does not flush kernel pages from the TLB. If you don't or can't use global pages then changing CR3 will flush kernel pages from the TLB....astrocrep wrote:Now my question is:
If I have two applications and the kernel running, and I switch from Kernel PD to App1 PD, will that creates misses for all of the 0-2gb code? Those address do not change in the new PD, but I know the switching PDs causes paging misses right?
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.
Thanks for the info.
What I imagined in terms of file systems is as such:
Modules:
- vfs - My vfs reader / writer
- fat1x - My fat12/16 driver
- ...
Services:
- DiskMan - He will talk to all of the drivers to interface with the various medians... He will also be responsible for maintaining the cache and the like.
Back to the Multipage directory thing. I would preffer NOT to bind myself to pentium and greater, though I doubt my OS would ever see that.
Is there a better way to implement what I wanted to do from above?
Thanks for the quick response.
-Rich
What I imagined in terms of file systems is as such:
Modules:
- vfs - My vfs reader / writer
- fat1x - My fat12/16 driver
- ...
Services:
- DiskMan - He will talk to all of the drivers to interface with the various medians... He will also be responsible for maintaining the cache and the like.
Back to the Multipage directory thing. I would preffer NOT to bind myself to pentium and greater, though I doubt my OS would ever see that.
Is there a better way to implement what I wanted to do from above?
Thanks for the quick response.
-Rich
Hi,
During boot you detect what the CPU/s support, and if they all support global pages you set a "use global pages" flag/variable somewhere and enable the global pages feature for each CPU (set bit 7 in CR4). Then, whenever you add a page to one of the kernel's page tables you test if your "use global pages" flag is set and if it is you set the 'G' flag in the page table entry. Lastly, whenever you remove a page from one of the kernel's page directories you use INVLPG (if supported by the CPU/s) because reloading CR3 won't flush global pages (but your OS should use INVLPG for this anyway).
It may even be easier than that - I don't think any older CPUs care if the 'G' flag in the page table entries is set (even though the flag is reserved on older CPUs that don't support global pages). In this case you don't need a "use global pages" flag/variable and can skip an "if/then" in the linear memory manager.
I should also mention that the cost of a TLB miss depends how much faster the CPU is than RAM (and other factors, like pipeline length). For 80386 where the RAM typically runs at the same speed as the CPU the TLB miss penalty is relatively small. For something like a 3 GHz Pentium 4 using 133 MHz RAM a TLB miss sucks badly.
Cheers,
Brendan
I'm not sure I know what you mean...astrocrep wrote:Back to the Multipage directory thing. I would preffer NOT to bind myself to pentium and greater, though I doubt my OS would ever see that.
During boot you detect what the CPU/s support, and if they all support global pages you set a "use global pages" flag/variable somewhere and enable the global pages feature for each CPU (set bit 7 in CR4). Then, whenever you add a page to one of the kernel's page tables you test if your "use global pages" flag is set and if it is you set the 'G' flag in the page table entry. Lastly, whenever you remove a page from one of the kernel's page directories you use INVLPG (if supported by the CPU/s) because reloading CR3 won't flush global pages (but your OS should use INVLPG for this anyway).
It may even be easier than that - I don't think any older CPUs care if the 'G' flag in the page table entries is set (even though the flag is reserved on older CPUs that don't support global pages). In this case you don't need a "use global pages" flag/variable and can skip an "if/then" in the linear memory manager.
If you don't want to use the global pages feature then you'll have unnecessary TLB flushes *unless* you find a way to avoid changing CR3. There's only 3 ways to do this that I know of:astrocrep wrote:Is there a better way to implement what I wanted to do from above?
- 1) You could do L4 style "small address spaces", where segments are used to reduce the need for changing CR3. This works, but the small address spaces need to be small (although in L4, if they grow too large they're shifted to large/normal address spaces and the TLB flushing problem comes back).
2) Leave CR3 alone and (during task switches) change all of the user space page directory entries instead. In this case you'd need to use INVLPG to flush the TLB entries for all pages that belonged to the previous task (and INVLPG isn't supported on 80386). Of course manually messing with the page directory like that would probably be much slower than the unnecessary TLB flushing you're trying to avoid. As an added advantage each process could have a 2 KB pretend page directory (which is copied to the real page directory during task switches), which saves 2 KB per process (assuming you want 2 GB of user space and 2 GB of kernel space).
3) Write a single-tasking OS
I should also mention that the cost of a TLB miss depends how much faster the CPU is than RAM (and other factors, like pipeline length). For 80386 where the RAM typically runs at the same speed as the CPU the TLB miss penalty is relatively small. For something like a 3 GHz Pentium 4 using 133 MHz RAM a TLB miss sucks badly.
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.