Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Perhaps Im missing something but Im not sure what can cause this. It may be paging-related, which is why I decided to post this here.
In a routine I have a unsigned char array defined as BYTE Image [1024+1];. I also have a BYTE pointer that points to a region where the data is to be copied, ImageRel. An instruction, *ImageRel = 0;, sets ImageRel[0] to 0 as expected. However if I loop it (or call memset) :
for (; count != 0; count--, i++)
ImageRel[i] = Image[i];
When running in Bochs, My display routine reports that ImageRel == 0xff instead of the value in Image (I display both values.)
This seems to work fine in the lower identity mapped region without problems. It only started happening when I first attempted to use a higher dynamically-mapped virtual address (tried 0xc0000000, mapped to a dynamically allocated page table.)
Has anyone seen this before? I am happy to post more code if needed,
*edit: Just tested with different code. This works as expected. ImageRel[0] == Image[0] :
Post the assembly generated from that function by the compiler you are using. Use objdump or something similar. Or, just use boches debugger and step through the assembly checking the registers and memory locations with manual probing as you go. The stack can do weird stuff if it grows into something. Also the time between the loop and when you display the values is unknown -- anything could be happening between there.
You could have major problems with corruption somewhere. I used to find a way to disable threading right before the problem area so I could step through using boches (disable interrupts) and generally I could discover if the problem was corruption from something multi-tasking related.
I was thinking a form of corruption as well, but I dont understand how this could surface only when using a non-identity mapped virtual address (It works fine if both addresses passed into the routine is identity mapped or physical addresses.)
Hm, then again that might mean theirs an issue in the memory manager somehow, although the pages are accessible fine and the "loop bug" only happens in that one routine. Ill post if I find any more info.
The routine is fairly complex, bochs does not seem to let me view virtual addresses (hm, perhaps I should test with newer versions as well.) but following the registers and disassembly seem to show the correct values.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
This is a little update: I created a stub memcpy2 routine and am printing the values of the addresses after being set and they are showing that they copied successfully. In a similar loop right after the call to the routine, I just print the values at the location we are copying to that has shown it was copied successfully. Sure enough, its somehow 0xff right after returning from the memcpy() call.
The only thing that I can think of that can cause this is that the virtual address is being set to a different frame while copying (This makes me think there might be page table corruption somehow...)
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
If you're doing any modification of page table entries, are you flushing the TLB entry for the page afterwards? I've had problems like this before from not flushing the TLB properly.
Thanks for the response - I do not, however. Currently I allocate a page directory and a page table (when needed) followed by a series of pages (as needed.) It does give me another place to look, though.
I also thank whoever changed the topic title - I originally did not know what the problem was thus the lack of info in the title
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Im still not sure what the actual cause of the issue is. However I found the new version of bochs does provide a page command that can be used to obtain the virtual to physical address mapping. When looking at the mapping, I noticed that the high bit of the frame address was always getting set which my physical frame allocator was not configured to work with addresses in that region. After fixing that, everything now seems to be working fine.
Thanks for the suggestions everyone
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}