Page 1 of 1
Building new processes
Posted: Wed Jan 15, 2003 8:25 am
by drizzt
I'm writing a memory manager for my little kernel...
I know that many kernels use a malloc() approach with a heap like so:
void *kmalloc(unsigned int size)
{
if (!size) return NULL;
k_heap_end+=size;
if (k_heap_end > HEAP_MAX) return NULL;
return ((void *)(k_heap_end-size))
}
...and don't care about kfree() to free the memory that has been used.
But when the kernel creates new processes it must allocate some memory areas used by the kernel itself, for example the process tss, a system stack, a local descriptor table ecc... So when the process dies all of its memory areas could be freed...
So, where to allocate these areas?! I've read the Tim Robinson's memory manager tutorials and I know I must write a malloc() & free() also for the user space... but what about the structures like TSSs, for example?!
I must reserve a part of the user memory to store these structures?!
And what about the task address space (code, data & bss)? I think I must define a header for every task to know how to (virtual) allocate it?
I think I need some clarifications.
Thanks, drizzt.
Re:Building new processes
Posted: Wed Jan 15, 2003 9:16 am
by Pype.Clicker
You can identify two kind of requirements for your allocations :
1. should the object be visible by the user process or by the kernel only ?
2. should the object be visible from every process or only from the owner process ?
This will place your objects on the following 2D map:
[table]
[tr][td][/td][td]user viewable[/td][td]kernel only[/td][/tr]
[tr][td]process-specific[/td][td]code, stacks, data segments, etc.[/td][td] file descriptors, process page tables, etc. [/td][/tr]
[tr][td]system-wide[/td][td]--[/td][td]TSS, semaphores, any IPC item[/td][/tr]
[/table]
Everything that is process-specific can be assumed free once the address space is destroyed. However, system-wide objects are allocated in a shared area that every processes use and should therefore be freed with care.
Re:Building new processes
Posted: Wed Jan 15, 2003 9:20 am
by Pype.Clicker
If you set up a memory map for your process, you can easily find out how to solve the problem:
have a given memory range for kernel [kbase .. ktop] which includes fix-allocated data&code and a kernel heap [khbase .. khtop] on which you run a malloc-like or a buddy heap system to get chunks of memory (which could be used for TSS, semaphores, whatever)
have a given memory range for user process [ubase .. utop] which will run a separate allocator for user stacks, code, heap, etc.
According to the kind of system you plan to do (micro or monolithic), the system-wide kernel area and process-specific kernel area can or cannot be merged.
Re:Building new processes
Posted: Thu Jan 16, 2003 4:02 am
by drizzt
Tnx pype!
I've another question: if I allocate the TSS of every task in the kernel heap (with kmalloc) I must also write a kfree() operator for the heap, to free the space of the TSS when a task is killed... or not? otherwise a heap overflow will came surely when processes will be created and destroyed...
...and what's the best way to keep track about virtual allocated memory if malloc and free are not still created?
Re:Building new processes
Posted: Thu Jan 16, 2003 5:10 am
by Pype.Clicker
yep. you'll need a kfree operator ...
But you can also short-circuit it with this funny code:
Code: Select all
TSS* freeTSS=NULL;
TSS *create_TSS()
{
if(!freeTSS) return kalloc(KMEM_KERNEL,sizeof(TSS));
else {
TSS* ret=freeTSS;
freeTSS=freeTSS->next;
return ret;
}
}
void free_TSS(TSS* tss)
{
tss->next=freeTSS;
freeTSS=tss;
}
Re:Building new processes
Posted: Thu Jan 16, 2003 9:58 am
by drizzt
WOW! ...very funny code ;D
Re:Building new processes
Posted: Thu Jan 16, 2003 10:10 am
by Pype.Clicker
the only drawback it has against the usual kfree() feature is that if you kalloc()ate a lot of TSS and destroy them, the memory remains locked for TSSes and cannot be used for something else. An alternative is to have size-based lists instead of use-based queues:
Code: Select all
cell *mem_lists[32];
cell **freeTSS=NULL;
initializ0r setup_TSS_mem() {
int i,sz;
for (i=0, sz=sizeof(TSS); sz; sz=sz/2 ; i++);
freeTSS=mem_lists+i;
}
or declare "freeTSS" as a lazy_free'er (once kfree will be there, you can call it on every item of every lazy_free'er when the system lacks memory for a given alloc...)
This way, it looks more and more like a "garbage collection"...
Re:Building new processes
Posted: Fri Jan 17, 2003 2:52 am
by drizzt
or declare "freeTSS" as a lazy_free'er (once kfree will be there, you can call it on every item of every lazy_free'er when the system lacks memory for a given alloc...)
...i've not understood very well this last thing, but if i'm not wrong you intend a buddy allocator...
...and another disadvantage of the first allocator is that i can allocate only structures which have a fixed size. Right?
Re:Building new processes
Posted: Fri Jan 17, 2003 3:23 am
by Pype.Clicker
very true ...
Let's say its just a convenient way to go around the problem of 'free' while waiting the kfree() function is written but it cannot be kept as is in a complete and finalized kernel :-/
Re:Building new processes
Posted: Fri Jan 17, 2003 6:47 am
by drizzt
ok! thanks a lot for the clarifications...
