Temporary memory management
Temporary memory management
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
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
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: Temporary memory management
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
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.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); }
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
Hi,
Are you sure you need basic/temporary memory management , and don't just need a linker script or something (for now)?
Cheers,
Brendan
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).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?
Are you sure you need basic/temporary memory management , and don't just need a linker script or something (for now)?
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.
Re: Temporary memory management
My linker script is no more complex than:
Is there anything missing that should be there?
Thanks in advance,
Jules
Code: Select all
OUTPUT_FORMAT("binary")
ENTRY(main)
SECTIONS
{
.text 0x100000 : {
*(.text)
}
.data : {
*(.data)
*(.rodata)
}
.bss : {
*(.bss)
}
}
Thanks in advance,
Jules
Re: Temporary memory management
Hi,
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
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)...suthers wrote:My linker script is no more complex than:
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
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.
Re: Temporary memory management
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
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
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
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
Hi,
For example, imagine something like this:
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:
If that doesn't fix your problem then there's something else wrong...
Cheers,
Brendan
That depends on how the variables are used..suthers wrote:But anyway the variables aren't being written to the right address anyway...
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");
}
}
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
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.
Re: Temporary memory management
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:
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.
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))
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
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
Did you figure out how to get the addresses of the beginning of the .bss section and its size?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.
Thanks in advance,
Jules
Re: Temporary memory management
Hi,
Cheers,
Brendan
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.suthers wrote:Did you figure out how to get the addresses of the beginning of the .bss section and its size?
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.
Re: Temporary memory management
Yes, that is possible, here is an example:
(ld linker script)
(C code)
Code: Select all
.text 0xC0000000 : {
glob_image_start = .;
*(.text)
}
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);
}
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].
Re: Temporary memory management
Ok, I didn't know that, so I added this code to zero my .bss section:
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?
Code: Select all
mov edi, bss
mov ecx, end_of_bss
sub ecx, bss
mov al,0
cld
rep stosb
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?