Page 1 of 2
Temporary memory management
Posted: Fri Jun 20, 2008 7:26 am
by suthers
I'm still in the primary stages of developing my OS, but the biggest problems have been cause by memory management.
I've found out that most of the bugs I couldn't figure out (most of my bufs that is...), are caused by my compiler/linker allocating memory to variables in the middle of my OS code causing some pretty severe problems.
For the moment for all my variables I've reserved space in the .data section in my asm code which i've then used as a var in C by defining it as an extern, but this is a very round about method that significantly increases coding time.
So my question basically is what do you think/sudgest is the best way of implimenting basic temporary memory management in an OS that is just starting?
Thanks in advance,
Jules
Re: Temporary memory management
Posted: Fri Jun 20, 2008 8:01 am
by Combuster
The most basic malloc I could think of:
Code: Select all
top_of_heap = 0x????????; // somewhere your kernel does not go
void * malloc(int size)
{ address = (void *) top_of_heap;
top_of_heap += size;
return(address);
}
Re: Temporary memory management
Posted: Fri Jun 20, 2008 8:39 am
by JamesM
Combuster wrote:The most basic malloc I could think of:
Code: Select all
top_of_heap = 0x????????; // somewhere your kernel does not go
void * malloc(int size)
{ address = (void *) top_of_heap;
top_of_heap += size;
return(address);
}
Which is the exact same solution I use on PPC. My physical memory manager has two modes - initial and normal. In initial mode, it allocates just like the snippet above. In normal mode it uses a proper physical page stack.
The idea is that it boots in initial mode, then uses itself to allocate resources to build its page stacks, then switches modes.
Re: Temporary memory management
Posted: Fri Jun 20, 2008 8:51 am
by Brendan
Hi,
suthers wrote:I've found out that most of the bugs I couldn't figure out (most of my bufs that is...), are caused by my compiler/linker allocating memory to variables in the middle of my OS code causing some pretty severe problems.
For the moment for all my variables I've reserved space in the .data section in my asm code which i've then used as a var in C by defining it as an extern, but this is a very round about method that significantly increases coding time.
So my question basically is what do you think/sudgest is the best way of implimenting basic temporary memory management in an OS that is just starting?
Your description of the problem makes me think that your linker/compiler is stuffing up memory references (for example, maybe your ".bss" section overlaps your ".text" and/or ".data" sections or something).
Are you sure you need basic/temporary memory management , and don't just need a linker script or something (for now)?
Cheers,
Brendan
Re: Temporary memory management
Posted: Fri Jun 20, 2008 9:19 am
by suthers
My linker script is no more complex than:
Code: Select all
OUTPUT_FORMAT("binary")
ENTRY(main)
SECTIONS
{
.text 0x100000 : {
*(.text)
}
.data : {
*(.data)
*(.rodata)
}
.bss : {
*(.bss)
}
}
Is there anything missing that should be there?
Thanks in advance,
Jules
Re: Temporary memory management
Posted: Sat Jun 21, 2008 11:25 pm
by Brendan
Hi,
suthers wrote:My linker script is no more complex than:
The linker script seems OK to me (but I don't use linkers, and I don't know where your code ends up in memory or anything else about your code)...
Also, the linker script may not be the cause of your problem - it could be dodgy segment registers, a bug in code that sets up paging, failing to fill the ".bss" section with zeros before your code starts, using memory reserved by the BIOS, or some other bug.
Basically what I'm saying is that you should be able to create variables, structures, arrays, etc directly in C (instead of reserving space in your assembly code and defining it as an extern); and if you can't do that then something is wrong. A temporary memory manager (e.g. kmalloc/kfree) might help to hide the symptoms but it won't fix the cause of the problem. You need to find and fix the cause of the problem (and then implement a temporary memory manager later if you still need one).
Cheers,
Brendan
Re: Temporary memory management
Posted: Sun Jun 22, 2008 4:38 pm
by suthers
All my segment registers are correctly setup and I don't yet have paging set up...
I don't zero my .bss section and I'm not quite sure how to do this...
I also don't think I use any memory reserved by the BIOS...
So what would I do to zero my .bss section (my kernel is stored in binary format, so I'm not quite sure how to locate it.)?
Thanks in advance,
Jules
Re: Temporary memory management
Posted: Sun Jun 22, 2008 6:29 pm
by suthers
But anyway the variables aren't being written to the right address anyway...
So it wouldn't make a difference whether or not the .bss section i zeroed...
Am I right?
Thanks in advance,
Jules
Re: Temporary memory management
Posted: Sun Jun 22, 2008 8:16 pm
by Brendan
Hi,
suthers wrote:But anyway the variables aren't being written to the right address anyway...
That depends on how the variables are used..
For example, imagine something like this:
Code: Select all
#define maxValue 1234
int myIndex;
int myArray[maxValue];
void addNextEntry(int nextValue) {
if(myIndex < maxValue) {
myArray[myIndex++] = nextValue;
} else {
printf("The array thing is full!\n");
}
}
Now imagine that "myIndex" starts with a negative value (like -54321) instead of zero, and it's easy to see how it could trash your code.
In any case you should fill the ".bss" with zeros anyway. You've probably already got some sort of assembly language startup code that sets up your stack, segment registers, etc - just add something like this to it:
Code: Select all
mov edi, address_for_the_start_of_the_bss
mov ecx,size_of_the_bss/4
mov eax,0
cld
rep stosd
If that doesn't fix your problem then there's something else wrong...
Cheers,
Brendan
Re: Temporary memory management
Posted: Mon Jun 23, 2008 5:26 am
by suthers
Thanks, but I didn't have a problem witting code to zero out a section of memory (I wouldn't be here if I couldn't do basic coding
)
My problem was how to locate the beginning of my .bss section...
But i've made some changes to my linker script that seem to have fixed the problem.
Firstly I added symbols at the beginning of each section so I could address then I put an AT at the beginning of each section and passed this to each AT:
Code: Select all
AT(0x100000 + (symbol_for_text_section - symbol_for_actual_section))
That fixed it, now I can remove the reserved memory and stop defining the variables as external...
But I'd still like to know how to zero the .bss section, so how would I locate it's address and size?
Thanks in advance,
Jules
edit: I also 4kb aligned each section so that when I get round to implementing paging, each section will be on a different page.
Re: Temporary memory management
Posted: Mon Jun 23, 2008 12:13 pm
by eax
Hey guys I'm about to start writing amemory manager and this post really helped, especially like the example of what can go wrong with arrays if BSS is not zeroed.
Re: Temporary memory management
Posted: Mon Jun 23, 2008 12:35 pm
by suthers
eax wrote:Hey guys I'm about to start writing amemory manager and this post really helped, especially like the example of what can go wrong with arrays if BSS is not zeroed.
Did you figure out how to get the addresses of the beginning of the .bss section and its size?
Thanks in advance,
Jules
Re: Temporary memory management
Posted: Mon Jun 23, 2008 6:31 pm
by Brendan
Hi,
suthers wrote:Did you figure out how to get the addresses of the beginning of the .bss section and its size?
If I remember correctly (for LD and GCC), it's possible to define labels in the linker script and then access them from C by defining them as "extern". I can't remember details though (I did it ages ago) - you'll probably need to use some "trial and error" and find the manual for your linker.
Cheers,
Brendan
Re: Temporary memory management
Posted: Tue Jun 24, 2008 1:27 am
by Korona
Yes, that is possible, here is an example:
Code: Select all
.text 0xC0000000 : {
glob_image_start = .;
*(.text)
}
(ld linker script)
Code: Select all
extern void *glob_image_start;
// glob_image_start should point to 0xC0000000
// note that we want the address of the pointer and not the value pointed to!
void main() {
printf("Image starts at: %u\n", (unsigned int)glob_image_start);
}
(C code)
Re: Temporary memory management
Posted: Tue Jun 24, 2008 7:01 am
by suthers
Ok, I didn't know that, so I added this code to zero my .bss section:
Code: Select all
mov edi, bss
mov ecx, end_of_bss
sub ecx, bss
mov al,0
cld
rep stosb
It assembles fine, but it causes an error in bochs 2.0.2, but not in 2.3.6....
Weird.
I looked at bochs 2.0.2 debug output to find the error... turns out bochs 2.0.2 generates a system timer interrupt before my IDT is setup, where as 2.3.6 doesn't...
Weird, but I can live with that (for some reason I prefer 2.0.2 because I started with it, but I'm trying to shift completely to 2.3.6... )
Well anyway doesn't matter.
Thanks for the help.
Jules
P.S. Brendan, If you don't use a linker script what do you use?