Page 1 of 1

C Kernel?

Posted: Fri Feb 09, 2007 8:23 pm
by pcmattman
Ok, I'm off to a good start. I have a C kernel, kernel-space character output functions and am able to get keyboard input from the user. My questions are:
  • 1. How do I implement a filesystem?
    2. How do I implement multitasking?
I boot from GRUB, so I'm in PMode, and have written the memset, strlen, memcpy etc., functions.

Re: C Kernel?

Posted: Fri Feb 09, 2007 8:32 pm
by Alboin
pcmattman wrote:1. How do I implement a filesystem?
You have to write drivers for a floppy disk, hard driver, etc. before you can work on a file system.
pcmattman wrote:2. How do I implement multitasking?
here
and
here
and
here

There are lot more....If I recall I read a great tutorial on multitasking, but I can't find it now...

Good Luck!

Posted: Fri Feb 09, 2007 8:33 pm
by pcmattman
Thankyou for your help. Is there anywhere you can point me to that would help me write a floppy driver?

Posted: Fri Feb 09, 2007 8:48 pm
by Alboin
Here should be nearly everything you need.

Posted: Fri Feb 09, 2007 9:43 pm
by pcmattman
Thanks, one thing - is there anywhere I can find out how to do heap allocation (malloc and free)? I've tried to write my own malloc function but it doesn't work:

Code: Select all

void* malloc( unsigned int size )
{
	unsigned int* old_loc = *heap_loc;
	*heap_loc += size;
	return (void*) *(old_loc);
}
heap_loc is the base of the heap. So far, I'm just trying to allocate memory, once I can do that I can start putting in limiting and buffers.

Posted: Fri Feb 09, 2007 10:01 pm
by jvff
Just to note about memory allocation. You should also implement memory freeing (which means you must keep track of the blocks you alloc) and optimally reuse possible freed blocks (which means keeping tracks of free "bubbles"). In memory managers, you must also take care of virtual memory mapping, so you must also configure paging/segmentation, which I suspect you've already handled. Hope this helps,

JVFF

Posted: Fri Feb 09, 2007 10:07 pm
by pcmattman
I've figured out how to get it to work properly, now I'm implementing the management part. I'm using a linked list which has information about every memory block currently allocated (ie. the location, status ie. FREE or USED etc...).

Any pointers (pun intended) as to how I can go about doing this as efficiently as possible?

Posted: Fri Feb 09, 2007 10:24 pm
by jvff
IIRC, there are many ways to implement memory managers. While searching for a block to allocate, you have many ways to find the "best" block, and you trade efficiency with speed. You have first fit, which tends to be very fast, but can cause fragmentation; you have best fit, which often has very high efficiency but may be slow. You probably want a hybrid. Possibly in a future project use idle CPU time to sort the list.

Also, linked list with too much pointer referencing (ie. the traditional structure where a list node has pointers to it's neighbors) can thrash the memory. Ideally you should have blocks the size aligned with the size of a cache line (in general 16, 32 or 64 bytes). When I implemented a malloc, I used a whole page for a buffer to keep track of blocks (no problem for me because I still had more than 260 000 pages left). I don't know how bad that implementaion was, but it worked. Hope this helps,

JVFF

Posted: Sat Feb 10, 2007 2:30 am
by pcmattman
I've changed it, now using your idea. It's much simpler! But there is one problem: how to free data? A 'free( char* ptr )' function is what I'm using now, but it doesn't work. What do you use?

Posted: Sat Feb 10, 2007 7:31 am
by Otter
first, free should mark the allocated block as "free" and then, it should test if the neighbours of that block are free as well, so it can combines them. If you'll give some code about your malloc I could give you some for free ...

Posted: Sat Feb 10, 2007 5:22 pm
by pcmattman
I use a structure that holds the data for each memory block registered. This way, I only need to pass the structure to the free function and the free function can cleanup much faster than any other method.

malloc code - seriously needing some efficiency:

Code: Select all

void* malloc( mBlock* info )
{
	// find next free block
	int i = 0;
	for( i = 0; i < 4500; i++ )
	{
		// check
		if( heap[i].stat == FREE )
			break;
	}

	// return the memory
	heap[i].stat = USED;

	// return the info
	*info = heap[i];

	return (void*) (heap[i].bottom);
}
free code:

Code: Select all

void free( char* ptr, mBlock info )
{
	// free it
	heap[ info.id ].stat = FREE;

	// now clear the memory the block used to take
	*ptr = heap[ info.id ].bottom;
	int i;
	for( i = 0; i < 1024; i++ )
	{
		*ptr++ = 0;
	}

#ifdef DEBUG
	kputs( "\n\nFreed block of memory.\n\n" );
#endif
}
And the mBlock definition:

Code: Select all

// memory block structure
typedef struct mBlock {
	unsigned int stat;	// status - FREE or USED
	unsigned int bottom;	// bottom of the block
	unsigned int top;	// top of the block
	unsigned int id;	// id of the block
} mBlock;
Basically, it allocates 1KB per block. So far, that's all I really need for my OS - so I don't need to combine memory from neighbouring free blocks. In total, my heap is (4500*1024) = 4608000 bytes = 4.6 MB.

I'm happy with the way it works for now, but feel free to throw any ideas into the pot. One thing though, how do I allocate stack space? I'm going to implement a task system soon and I want to be able to get stack space for each task.

Posted: Sun Feb 11, 2007 3:20 am
by Otter
You only need 1 kb blocks for your kernel ? So you don't use any linked lists, trees or something like that, even not in the future ? ;) It's only a suggestion, but I really think a flexible malloc/free implementation which can alloc smaller and greater blocks is important. If you have something like that, it is much easier and more interesting to work with.