Page 1 of 2
memory problem
Posted: Fri Nov 07, 2003 8:19 am
by Zottri
I have a weird problem.
I want to initialize my MemoryMap variable, but it stacks in loop and executes loop infinitelly. I think Im missing something with memory references. ıll be if someone helps..
Here is my code:
Code: Select all
/*********************************************************
/ VARIABLE DECLERATION
*********************************************************/
static unsigned long MemoryMap[MAXPAGENUMBER/32]; //1bit/page
static unsigned long SystemTotalMemory;
static unsigned long SystemTotalPageNumber;
static unsigned long CurrentFreePageNo;
/*********************************************************
/ FUNCTION IMPLEMENTATIONS
*********************************************************/
/*********************************************************
/ Initialising memory
/ in : None
/ out : None
*********************************************************/
void InitMemory(void)
{
unsigned long Cnt;
SystemTotalMemory = GetMemorySize();
if(SystemTotalMemory > MAXMEMORY) SystemTotalMemory = MAXMEMORY;
SystemTotalPageNumber = SystemTotalMemory / PAGESIZE;
for(Cnt = 0; Cnt < 4096; Cnt++) //this loop never ends
MemoryMap[Cnt] = (unsigned long)0;
CurrentFreePageNo = 0;
}
Re:memory problem
Posted: Fri Nov 07, 2003 11:39 pm
by BoomSukka
It seems impossible that a FOR loop doesn't end when it's initial and terminal conditions are properly defined, which yours are.
So, in my opinion, you're surpassing the bounds of your MemoryMap[] array (i.e. you don't have 4096 elements in the array) -- and therefore you're writing zeros god-knows-where...
Tim.
Re:memory problem
Posted: Sat Nov 08, 2003 12:37 am
by Schol-R-LEA
I agree; the solution I would recommend is to replace the hardcoded '4096' with 'MAXPAGENUMBER/32', or better still, define another constant of that value and use it in both cases:
Code: Select all
#define MAXPAGEBYTES (MAXPAGENUMBER/32)
static unsigned long MemoryMap[MAXPAGEBYTES]; //1bit/page
//....
for(Cnt = 0; Cnt < MAXPAGEBYTES; Cnt++) //this loop never ends
MemoryMap[Cnt] = (unsigned long)0;
HTH.
Re:memory problem
Posted: Sun Nov 09, 2003 4:14 pm
by Zottri
Indeed I have tried both you said. Either replacing both definitions with 4096 nor (MAXPAGENUMBER/32) worked. I mean both the codes results in an infinite loop. Also I have tried printing a char in that loop and it prints it infinitelly. BUTT, if I change the counting number from 4096 to 4089, it exits loop successfully. (What makes this problem weird.)
And here is last condition of my code:
Code: Select all
static unsigned long MemoryMap[4096]; //1bit/page
static unsigned long SystemTotalMemory;
static unsigned long SystemTotalPageNumber;
static unsigned long CurrentFreePageNo;
void InitMemory(void)
{
unsigned long Cnt;
SystemTotalMemory = GetMemorySize();
if(SystemTotalMemory > MAXMEMORY) SystemTotalMemory = MAXMEMORY;
SystemTotalPageNumber = SystemTotalMemory / PAGESIZE;
for(Cnt = 0; Cnt < 4096; Cnt++) { //Set all pages free
MemoryMap[Cnt] = (unsigned long)0;
if((Cnt % 1024)==0) Print("#");
}
CurrentFreePageNo = 0;
}
This piece of code prints '#' char infinitelly. If I chage both 4096 with 4089, it finishes loop successfully. ALSO, if I declare MemoryMap variable under CurrentFreePageNo, as:
Code: Select all
static unsigned long SystemTotalMemory;
static unsigned long SystemTotalPageNumber;
static unsigned long CurrentFreePageNo;
static unsigned long MemoryMap[4096]; //1bit/page
also loop doesnt end even if I change 4096 with 4089(what couse my to think that my problem is something with memory references). Off off.. Ha, Im sure that my computer doesnt crash in loop, it just executes loop infinitelly. Because all my interrupts (keyboard, timer..) works and it prints '#' infinitelly.
What may couse this problem? Ill be glad if someone helps...Thanks...
Re:memory problem
Posted: Sun Nov 09, 2003 6:58 pm
by Schol-R-LEA
Do you have a function for printing numbers, moving the cursor, and finding the cursor's position? If so, then you could try something like this to help see what the Cnt function is actually doing without take inordinate screen space:
Code: Select all
int xpos = 0;
int ypos = 0;
// ...
Print("Now clearing memory map section #");
xpos = get_x();
ypos = get_y();
for(Cnt = 0; Cnt < 4096; Cnt++) { // Set all pages free
MemoryMap[Cnt] = (unsigned long) 0;
// print out counter value periodically for debugging purposes
if (Cnt % 16) { // set granularity as needed for testing
move_cursor(xpos, ypos); // return cursor to start position of counter
Print_Decimal(Cnt);
}
}
You would have to replace these functions with your own equivalents, of course. The effect should be an in-place counter, like the memory test counter on older PCs (newer ones usually have it, but it's disabled by default).
BTW, you might want to wrap these test operations in a macro
like this one, so that you can select or deselect them at compile time:
Code: Select all
#define __DEBUG__ 1
#if __DEBUG__
#define DEBUG(x) {x}
#elif
#define DEBUG(x)
#endif
A more sophisticated version of this would be a 'verbose' or 'logging' mode which can be enabled or disabled by an initialization script, which could allow you to show this and other system startup information.
Re:memory problem
Posted: Mon Nov 10, 2003 2:35 am
by zottri
I printed out the value of Cnt. I counts normally until 4086. And then restarts counting:
..
4083
4084
4085
4086
0
1
2
3
..
Also, if I declare some variables before declaring Cnt, it counts less then 4086 and restarts counting. I mean if I declare some other variables before Cnt:
Code: Select all
void InitMemory(void)
{
unsigned int dummyVar1;
unsigned int dummyVar2;
unsigned int dummyVar3;
unsigned long Cnts;
then screen is like this:
..
4082
4083
0
1
2
..
I think, but dont know how, my memory map variable (MemoryMap[4096]) share same memory location with my Cnt variable. Because, If I fill my MemoryMap array with, for instance, 50, then Cnt value changes like this:
..
4083
4084
4085
4086
50
51
52
..
How this may happen? I compile and run my code under different computers and they gave same results. So my fool computer works fine. But my brain leave me alone. Please help before I got crazy.. What may couse such a problem?
Re:memory problem
Posted: Mon Nov 10, 2003 2:05 pm
by Schol-R-LEA
I don't like the sound of that; since Cnt is a local variable, it implies that the stack is getting so low that it is overlapping your data area (I am assuming that this is running in flat mode, since gcc doesn't like any other memory models
.) How are you setting up the segment selectors?
BTW, why do you need to cast 0 to (unsigned long)? I hadn't notced that earlier, but I can't see why it woul dbe necessary. It isn't as if you are assigning an integer to a pointer.
Re:memory problem
Posted: Mon Nov 10, 2003 2:24 pm
by zottri
Schol-R-LEA wrote:
How are you setting up the segment selectors?
What do u mean and how can I do that?
(My english is not so good, sorry.)
Re:memory problem
Posted: Tue Nov 11, 2003 5:15 pm
by Schol-R-LEA
EDIT: I should clarify what I wrote earlier.
I ran some tests with a mockup of you code, and it worked exactly as intended, more or less. Whatever the problem is, it probably isn't in the InitMemory() function itself. This supports my conjecture that it is some kind of problem with the system environment which is causing you data segment to overlap with you stack.
In testing, I found another possible problem, one which is probably unrelated but nonntheless probably should be addressed.
In you current setup, is the MAXMEMORY constant set to 4294967296 (2[sup]32[/sup]) or to 4294967295 (2[sup]32[/sup] - 1)? Either one will cause a problem, but the former is more serious - a 32-bit long will overflow with that value. The result will be that the assignment
[tt]SystemTotalMemory = MAXMEMORY;[/tt]
SystemTotalMemory set to zero, not 2[sup]32[/sup].
The easiest solution is probably to use unsigned long long, a 64-bit type which gcc supports now (on a side note, there's no reason that Cnt has to be a long, in fact even an unsigned short will do nicely here). It may seem a waste of memory, but it's probably less so than the other possibilities.
The test code I used is
Code: Select all
#include <stdio.h>
/*********************************************************
/ VARIABLE DECLERATION
*********************************************************/
#define MAXMEMORY 4294967296 // 4 gigabytes
#define PAGESIZE 32768 // 32 kilobytes
#define MAXPAGENUMBER (MAXMEMORY / PAGESIZE)
#define MAXPAGEBLOCKS (MAXPAGENUMBER / 32)
static unsigned long MemoryMap[MAXPAGEBLOCKS]; //1bit/page
static unsigned long long SystemTotalMemory;
static unsigned long SystemTotalPageNumber;
static unsigned long CurrentFreePageNo;
// this function added for testing purposes
unsigned long long GetMemorySize()
{
return (unsigned long long) MAXMEMORY;
}
/*********************************************************
/ FUNCTION IMPLEMENTATIONS
*********************************************************/
/*********************************************************
/ Initialising memory
/ in : None
/ out : None
*********************************************************/
void InitMemory(void)
{
unsigned short Cnt;
SystemTotalMemory = GetMemorySize();
printf("%I64d\n", SystemTotalMemory);
getch();
if(SystemTotalMemory > (unsigned long long) MAXMEMORY) {
SystemTotalMemory = (unsigned long long) MAXMEMORY;
}
SystemTotalPageNumber = (unsigned long) (SystemTotalMemory / PAGESIZE);
printf("%lu\n", SystemTotalPageNumber);
getch();
for(Cnt = 0; Cnt < MAXPAGEBLOCKS; Cnt++) { //this loop never ends
MemoryMap[Cnt] = 0;
printf("%hu\n", Cnt);
}
CurrentFreePageNo = 0;
}
main()
{
InitMemory();
getch();
}
Re:memory problem
Posted: Thu Nov 13, 2003 10:26 am
by Schol-R-LEA
Have you made any prograss on this, Zottri?
Re:memory problem
Posted: Thu Nov 13, 2003 10:52 am
by Zottri
As you said, I suspect overlapping stack segment over data segment. Afer jumping to protected mode, when I set all segment registers, I set my esp to 0xffff. I changed it to 0x9ffff and my problem is solved.
Now, there is another thing confusing me. I set my gdt in my second stage loader. But it doesnt have any stack segment. I wonder if it is necessarry to set up a stack segment in gdt to avoid this kind of problems.
Re:memory problem
Posted: Sat Nov 15, 2003 6:24 am
by Candy
Zottri wrote:
Now, there is another thing confusing me. I set my gdt in my second stage loader. But it doesnt have any stack segment. I wonder if it is necessarry to set up a stack segment in gdt to avoid this kind of problems.
a stack segment is only called a stack segment either because it contains a stack (and is in fact a normal data segment) or because it grows downwards (which might just contain data or even code). You can always use a data segment for your stack.
Re:memory problem
Posted: Mon Nov 17, 2003 5:40 am
by Pype.Clicker
one thing that looks suspect to me in your code is that i cannot see the definition of memorymap[]. are you sure it's long enough to hold what you put in it? is it an array or a pointer ? if it's a pointer, has it been correctly initialized ?
it looks like mmap[] overwites the (future) stack until it reaches 'counter' and resets it to 0.
Re:memory problem
Posted: Mon Nov 17, 2003 9:13 pm
by Zottri
I have found my problem. It was in my WriteCR0 functions. But now something weird occurs.
My WriteCR0 function was like this before I correct it:
Code: Select all
mov eax, [esp+8]
mov cr0, eax
ret
And it writes wrong value in cr0. The correct one is:
Code: Select all
push ebp
mov ebp, esp
mov eax, [ebp+8]
mov cr0, eax
pop ebp
ret
Indeed I know that using esp is wrong but in tasm it gaves a compile time error. But in nasm it didnt warn me for anything and so I have thought that using esp couses no problem. But my WriteCR0 function gaves error until I change it. (Ill be glad if someone explain the difference between these codes.)
And also my WriteCR3 function, even I changed according to WriteCR0 function, works in both ways. I mean both:
Code: Select all
mov eax, [esp+8]
mov cr3, eax
ret
and
Code: Select all
push ebp
mov ebp, esp
mov eax, [ebp+8]
mov cr3, eax
pop ebp
ret
works for writing cr3 register. Is there anything Im missing or the behave of cpu's writing cr0 or cr3 registers are different???
Re:memory problem
Posted: Tue Nov 18, 2003 3:30 am
by Pype.Clicker
there's no reason for nasm to complain about
mov eax,[esp+8], while it's a perfectly valid instruction.
The problem is that if you have
Code: Select all
setCR0:
mov eax,[esp+8]
mov cr0,eax
ret
[esp+8] do not point to the first argument of setCR0(value), but rather to the second inexistent parameter.
Before you use [ebp+8], you pushed old ebp on the stack, which means you decreased esp ...
In other words,
Code: Select all
setCR0:
mov eax,[esp+4]
mov cr0,eax
would have worked perfectly (though using ebp leads to less future troubles, indeed).
The reason while CR3 seems unaffected is that the paging base directory register is less sensitive to garbage loading: as long as you give it a correct memory address it will take it as the future page table. If after calling setCR3(directory) with [esp+8], you read back CR3, you may discovery getCR3()!=directory.
But this becomes a problem *only* if you filled directory[0]... rather than *getCR3().
Did i make myself clear ?