Which is the memory map of each task that you used in your OS?
That is, what are address spaces of your operating system?
For example I thinked to use these address spaces for each task:
First 4MB are identically mapped to physical memory SUPERVISOR LEVEL
0x10000000 - For user code USER LEVEL
0x20000000 - For user stack USER LEVEL
0x30000000 - For user heap USER LEVEL
0xC0000000 - For kernel code (is this necessary?) SUPERVISOR LEVEL
0xD0000000 - For kernel heap (is this necessary?) SUPERVISOR LEVEL
0xE0000000 - For some physical memory (such as 0xb8000) SUPERVISOR LEVEL
Memory map of tasks
Re: Memory map of tasks
Hi,
Mine's a little complicated:MarkOS wrote:Which is the memory map of each task that you used in your OS?
Code: Select all
0 to X Process space
X to Y-8MB Normal thread space
Y-8 MB Thread stack top
Y-8 MB to Y-4MB Message buffer 1
Y-4 MB to Y Message buffer 2
Y to J Dynamically allocated kernel space (global, alloc/free, expands up)
J to K Kernel data (global, alloc during boot only, expands down)
K to L Kernel code (NUMA domain specific, never modified after boot)
L to M Kernel data (NUMA domain specific, rarely modified after boot)
M to N Linear memory manager space (page table mappings)
The actual address for X depends on the process using the address space (determined when the process starts from the file header), but is always aligned to a 1 GB boundary. The addresses for J, K, L, M and N depend on what sort of paging is being used (plain 32-bit, "36-bit" PAE or long mode). The address for J depends on which kernel modules are used.
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.
- Happy Egghead
- Member
- Posts: 32
- Joined: Thu Oct 19, 2006 5:25 am
- Location: Adelaide, Australia
- Contact:
HappyEggOS is a bit simpler as it doesn't support extended addressing (apart from the Pentium 4MB extensions) or NUMA.
Physical memory
Either the first 4 or 8 Mbytes is allocated to the kernel depending on the amount of actual RAM in the system. All other physical memory is set aside for paging.
Logical memory
The kernel is mapped at 0xC0010000 for 4 meg with 640k of pre allocated pages (reused real mode memory) from 0xC0000000 to 0xC00A0000. These pages are used for directories/pagetables or ISA compatible DMA if necessary.
Up to the 8 Mbytes of memory above the kernel is used for the page 'stack' (push and pop page addresses) and for extra page directories/tables if needed. That leaves everything above 0xC0800000 for paged kernel data device drivers etc.
All drivers run in kernel space above 0xC0000000 and there are only 5 drivers built into the kernel - the rest will be loaded dynamically (once the dynamic linker thing has been degubbed).
Some things above 0xC0800000 can be swapped out (when swapping is implemented) other things are locked (needed device drivers for example).
Most device drivers are only about 4k in size so that's ok. All the complicated stuff is moved into big user task services.
All tasks are User Mode tasks running below 0xC0000000. This includes all system services. Everything communicates via shared memory/messaging. (See example below)
So in texatgraphical form
Logical Memory Map :-
0x00000000 - 0x000001000 Page for page faults - unallocated to catch null pointers
0x00001000 - 0xC00000000 User mode task memory
0xC0000000 - 0xC08000000 Kernel critical memory
0xC0800000 - 0xE00000000 Kernel paged data
0xE0000000 - 0xF00000000 Memory mapped I/O
0xF0000000 - 0xFFFFFFFFFF 4 meg page directory self mapping / anything else that can be recovered from it (not a priority at the moment)
Example User Task Memory Map :- (A simple task like this would have this much shared memory)
0x00000000 - 0x000001000 Page for page faults - unallocated to catch null pointers
0x00001000 - 0x00002000 4k of code for tiny example task - "Hello World!" etc.
0x00002000 - 0x00008000 6k of data for tiny example task
0x00010000 - 0x00020000 64k frame buffer - shared memory with video manager
0x00030000 - 0x00040000 64k file buffer - shared memory with storage manager
0x00040000 - 0x00050000 64k network buffer - shared memory with network manager
0x00050000 - 0xB0000000 User mode heap
0xB0000000 - 0xBFFFF000 User mode Task stack
0xBFFFF000 - 0xC0000000 Page for page faults - unallocated to catch stack underruns
On the subject of stacks and 'heaps'.
Each User mode task has it's own stack (below 0xC0000000) and a kernel stack (4k) above 0xC0000000. Only 4k is needed as the kernel uses only this space for swapping. It's actually shared with the tasks' process table. Device drivers have their stacks above 0xC0000000 and can be of any size required. The addresses of all the device driver stacks are unfixed.
The same goes for 'heaps', they start at the end of the uninitialised data section (BSS sgment of a file) and finish at the end of the address space (the start address of the stack is good).
Even if tasks are only using 4Mbytes of address space, I'll bet that 'heaps' more data will be needed (on the 'heap') for tasks than memory is needed for a tasks' stack.
Physical memory
Either the first 4 or 8 Mbytes is allocated to the kernel depending on the amount of actual RAM in the system. All other physical memory is set aside for paging.
Logical memory
The kernel is mapped at 0xC0010000 for 4 meg with 640k of pre allocated pages (reused real mode memory) from 0xC0000000 to 0xC00A0000. These pages are used for directories/pagetables or ISA compatible DMA if necessary.
Up to the 8 Mbytes of memory above the kernel is used for the page 'stack' (push and pop page addresses) and for extra page directories/tables if needed. That leaves everything above 0xC0800000 for paged kernel data device drivers etc.
All drivers run in kernel space above 0xC0000000 and there are only 5 drivers built into the kernel - the rest will be loaded dynamically (once the dynamic linker thing has been degubbed).
Some things above 0xC0800000 can be swapped out (when swapping is implemented) other things are locked (needed device drivers for example).
Most device drivers are only about 4k in size so that's ok. All the complicated stuff is moved into big user task services.
All tasks are User Mode tasks running below 0xC0000000. This includes all system services. Everything communicates via shared memory/messaging. (See example below)
So in texatgraphical form
Logical Memory Map :-
0x00000000 - 0x000001000 Page for page faults - unallocated to catch null pointers
0x00001000 - 0xC00000000 User mode task memory
0xC0000000 - 0xC08000000 Kernel critical memory
0xC0800000 - 0xE00000000 Kernel paged data
0xE0000000 - 0xF00000000 Memory mapped I/O
0xF0000000 - 0xFFFFFFFFFF 4 meg page directory self mapping / anything else that can be recovered from it (not a priority at the moment)
Example User Task Memory Map :- (A simple task like this would have this much shared memory)
0x00000000 - 0x000001000 Page for page faults - unallocated to catch null pointers
0x00001000 - 0x00002000 4k of code for tiny example task - "Hello World!" etc.
0x00002000 - 0x00008000 6k of data for tiny example task
0x00010000 - 0x00020000 64k frame buffer - shared memory with video manager
0x00030000 - 0x00040000 64k file buffer - shared memory with storage manager
0x00040000 - 0x00050000 64k network buffer - shared memory with network manager
0x00050000 - 0xB0000000 User mode heap
0xB0000000 - 0xBFFFF000 User mode Task stack
0xBFFFF000 - 0xC0000000 Page for page faults - unallocated to catch stack underruns
On the subject of stacks and 'heaps'.
Each User mode task has it's own stack (below 0xC0000000) and a kernel stack (4k) above 0xC0000000. Only 4k is needed as the kernel uses only this space for swapping. It's actually shared with the tasks' process table. Device drivers have their stacks above 0xC0000000 and can be of any size required. The addresses of all the device driver stacks are unfixed.
The same goes for 'heaps', they start at the end of the uninitialised data section (BSS sgment of a file) and finish at the end of the address space (the start address of the stack is good).
One thing I can see from the memory map above is that the the tasks' stack is below the 'heap'. I recommend putting the stack above the 'heap' and set as high in user space as possible (ie at 0xBFFFFFC - 1 DWORD below 0xC0000000) going down. This gives the stack as much room to extend down as possible, and will give applications a huge 'heap' until allocations of 'heap' data collide with the stack data (classic crash scenario), but that's OK. Massive amounts of data and a function that uses megabytes of stack space would be needed to effect this though!0x10000000 - For user code USER LEVEL
0x20000000 - For user stack USER LEVEL
0x30000000 - For user heap USER LEVEL
Even if tasks are only using 4Mbytes of address space, I'll bet that 'heaps' more data will be needed (on the 'heap') for tasks than memory is needed for a tasks' stack.