Building new processes

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
drizzt

Building new processes

Post 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.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Building new processes

Post 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.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Building new processes

Post 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.
drizzt

Re:Building new processes

Post 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?
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Building new processes

Post 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;
}
drizzt

Re:Building new processes

Post by drizzt »

WOW! ...very funny code ;D
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Building new processes

Post 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"...
drizzt

Re:Building new processes

Post 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?
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Building new processes

Post 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 :-/
drizzt

Re:Building new processes

Post by drizzt »

ok! thanks a lot for the clarifications... :)
Post Reply