everything is working fine, then you add a new line of code on whatever you have done so far, and *sbam* you start to see lot of cpu exceptions going on...
And then you try to do some debug and nope you can't figure out where is the bug, becauise everything looks fine.
So here is the problem:
my code was working (at least that is what i thought) so far, and recently i was doing some refactoring of basic screen i/o, just to make the codoe more readable, i basically added a _printStringAndNumber function that it just print the string, convert the number given in input to a string (max 30 chars), and then print that number string and finally a new line.
This is the code:
Code: Select all
void _printStringAndNumber(char *string, unsigned long number){
char buffer[30];
_printStr(string);
_getHexString(buffer, number);
_printStr(buffer);
_printNewLine();
}
Code: Select all
int _getHexString(char *buffer, unsigned long hexnumber){
unsigned long tmpnumber = hexnumber;
int shift = 0;
int size = 0;
char *hexstring = buffer;
while (tmpnumber >= 16){
tmpnumber >>= 4;
shift++;
}
size = shift;
for(; shift >=0; shift--){
tmpnumber = hexnumber;
tmpnumber>>=(4*shift);
tmpnumber&=0xF;
if(tmpnumber < 10){
*hexstring++ = '0' + tmpnumber; //Same as decimal number
} else {
*hexstring++ = 'A' + tmpnumber-10; //11-15 Are letters
}
*hexstring = '\0';
}
return size;
}
Before adding them to print a number i should have done something like:
Code: Select all
char buffer[30]
uint32_t number = 125
_getHexString(buffer, number)
_printStr("Number is: ");
_printStr(number);
_printNewLine();
Btw i started to replace the snippet above with the new function that was doing the same thing and everything was still working, until yesterday.
When i started to get exception raised, most of the time i got an Invalid Opcode exception, and few other times (depending on what i was changing in the code) i got a #PF.
So far this is what i found/current information:
- For some reason it is appening only after i add a cpuid instruction (no matter if is a function i wrote in assembly, that is pretty shitty) or call just cpuid with (asm("cpuid)
- If i don't call cpuid exceptions are not raised and i tried many printStringAndNumber functions and no exception was raised
- Not sure if the two problems are related but when i tried to implement a basic printf like function, with the va_list, va_arg stuff, i got a similar problem on the second time i was trying to call it, if i'm not wrong was with a #pf but in this case i assumed that issue could have been that the va_* macros were messing around with pointers to access parameters so i was going to hit an unmapped region
- I'm running the kernel in the higher half, but in theory the video ram should have been correctly mapped, this is the boot mapping code for the kernel:
where p3_table_hh is the p3 table of the kernel in the higher half, and i'm using actually 2mb pages, so i have mapped something like 1gb of memory!
Code: Select all
mov eax, p2_table - KERNEL_VIRTUAL_ADDR or eax, 0b11 mov dword[(p3_table_hh - KERNEL_VIRTUAL_ADDR) + 510 * 8], eax ; Now let's prepare a loop... mov ecx, 0 ; Loop counter .map_p2_table: mov eax, 0x200000 ; Size of the page mul ecx ; Multiply by counter or eax, 0b10000011 ; We set: huge page bit, writable and present ; Moving the computed value into p2_table entry defined by ecx * 8 ; ecx is the counter, 8 is the size of a single entry mov [(p2_table - KERNEL_VIRTUAL_ADDR) + ecx * 8], eax inc ecx ; Let's increase ecx cmp ecx, 512 ; have we reached 512 ? ; each table is 4k size. Each entry is 8bytes ; that is 512 entries in a table jne .map_p2_table ; if ecx < 512 then loop
* Actually i'm coding stuff that has basic support for framebuffer and vga, so i thought that probably printiung on the VGA while not using it could have been a problem, so commented that part when using the framebuffer, but stiill same error, and switched back to vga mode and sill same problem (but with a nice crazy screen after a while... that i will probably post in the when your os is going crazy topic)
* Another interesting thing is that if i replace that last printSringAndNumber, with the old way of printing numbers, this exception is not happening.
* I though the problem was that i was using the mapped VGA memory in the higher half, so tried to revert back to the old one, but again without luck.,
Whatever i tried so far is not working (i thought that maybe since i was in framebuffer mode, and still calling the _printCh function:
Code: Select all
void _printCh(char c, character_color color){
*VIDEO_PTR++ = c;
*VIDEO_PTR++ = color;
}
Can be the fact that whenever i'm calling the _printStringAndNumber function i'm allocating a 30 char buffer? (even if i don't see why it should be a problem).
So my question is if someone can help me investigating further to try to understand how to find the root of the problem.
If needed the full code of the os is here: https://github.com/dreamos82/Dreamos64
P.s. the _printStringAndNumber function is kind of temporary until i implement the basic printing C functions.
P.P.s. The branch with the exception: https://github.com/dreamos82/Dreamos64/ ... n_on_print