Wierd system reset when I try to enable paging

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.
Post Reply
jhunterd
Posts: 12
Joined: Tue May 14, 2013 3:03 pm

Wierd system reset when I try to enable paging

Post by jhunterd »

I have an odd bug in my OS where when I try to enable paging, the entire system reboots. As of now, QEMU shows no errors, but earlier, QEMU would output:

Code: Select all

pflash_write: Unimplemented flash cmd sequence (offset 000000000000xxxxx. wcycle 0x0 cmd 0x0 value 0x18
pflash_write: Unimplemented flash cmd sequence (offset 000000000000xxxxx. wcycle 0x0 cmd 0x0 value 0x104004)
pflash_write: Unimplemented flash cmd sequence (offset 000000000000xxxxx. wcycle 0x0 cmd 0x0 value 0x103fc8)
pflash_write: Unimplemented flash cmd sequence (offset 000000000000xxxxx. wcycle 0x0 cmd 0x0 value 0x11)
pflash_write: Unimplemented flash cmd sequence (offset 000000000000xxxxx. wcycle 0x0 cmd 0x0 value 0xa0003)
pflash_write: Unimplemented flash cmd sequence (offset 000000000000xxxxx. wcycle 0x0 cmd 0x0 value 0xa0)
pflash_write: Unimplemented flash cmd sequence (offset 000000000000xxxxx. wcycle 0x0 cmd 0x0 value 0x80000011)
Here is the code that causes the error:

Code: Select all

	unsigned int *p_dir = (unsigned int *) 0x9C000;
	unsigned int *p_tab = p_dir + 0x1000;

	for(i = 0; i < 1024; i++)
		p_dir[i] = 0 | 2; 
	for(i = 0; i < 1024; i++)
	{
		p_tab[i] = addr | 3;
		addr += 406;
	}

	p_dir[0] = (int) p_tab;
	p_dir[0] |= 3;

	asm("mov %0, %%cr3" :: "b" ((int) p_dir));
	asm("mov %cr0, %eax");
	asm("or $0x80000001, %eax");
	asm("mov %eax, %cr0");	//Here's the faulty line.  When I remove it, the system doesn't reboot.
Note that I use GRUB 2 to boot the operating system and I have cleared interrupts. Are there any ways that I can stop this reboot from happening?
jhunterd
Posts: 12
Joined: Tue May 14, 2013 3:03 pm

Re: Wierd system reset when I try to enable paging

Post by jhunterd »

Bump
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Re: Wierd system reset when I try to enable paging

Post by jnc100 »

Several issues:

1) You don't need to bump so quickly (or at all???)
2) You don't initialize addr anywhere
3) Setting p_tab to 0xa0000 isn't sensible as this is usually some part of video memory
4) I presume 'addr += 406;' is supposed to be 4096?

Regards,
John.
User avatar
sortie
Member
Member
Posts: 931
Joined: Wed Mar 21, 2012 3:01 pm
Libera.chat IRC: sortie

Re: Wierd system reset when I try to enable paging

Post by sortie »

Beware of your inline assembly. It looks like you know enough for it to be dangerous. Inline assembly statements can have input and output registers and clobbered registers. The compiler is unable to understand your inline assembly (it just inserts it verbatim, after expanding the virtual registers such as %0). It uses the input and output registers to see what the inline assembly is calculating, and the clobber list to know what additional registers it is using. Additionally, the compiler assumes your inline assembly have no side effects, unless you specify the memory as clobbered. If your inline assembly statements do nothing from a compiler point of view (only input registers, no output registers, no side effects) it will optimize them away like it would a normal statement. You can add the volatile keyword to your inline assembly statements such that the compiler will not attempt to optimize the statements, which is useful when your inline assembly have hidden side effects (such as enabling paging). In addition, you have no guarantee that if you left a value in a register at the end of an inline assembly register that it will still be there during the next (even if it is the very next statement). I recommend that you really look into inline assembly (which is a bit hard, it's badly documented) or avoid its use by using actual assembly files.

Does your compiled code look correct when you examine the output of objdump -d mykernel.bin?
Last edited by sortie on Fri May 17, 2013 11:40 am, edited 1 time in total.
jhunterd
Posts: 12
Joined: Tue May 14, 2013 3:03 pm

Re: Wierd system reset when I try to enable paging

Post by jhunterd »

Yeah, there are __a lot__ of errors in this code that were brought to my attention by jnc100. Thanks for helping!
Kevin
Member
Member
Posts: 1071
Joined: Sun Feb 01, 2009 6:11 am
Location: Germany
Contact:

Re: Wierd system reset when I try to enable paging

Post by Kevin »

sortie wrote:Beware of your inline assembly. [...]
You're explaining some of the subtleties here, but you're missing the one big problem with the code:

Code: Select all

asm("mov %0, %%cr3" :: "b" ((int) p_dir));
	asm("mov %cr0, %eax");
	asm("or $0x80000001, %eax");
	asm("mov %eax, %cr0");	//Here's the faulty line.  When I remove it, the system doesn't reboot.
There is no reason why in the third or fourth asm block eax should still have the same value as it had at the end of the previous asm block. As soon as an asm block end, the compiler has full control over all registers again. You want to write this as a single asm block like this:

Code: Select all

asm volatile(
    "mov %cr0, %eax\n"
    "or $0x80000001, %eax\n"
    "mov %eax, %cr0"
    ::: "eax");
Or use an output variable for eax in the first instruction, do the or in C and have an input variable for eax in the last instruction.

Also, I'm pretty sure you're in protected mode already, so setting cr0.PE with 0x80000001 is unnecessary.
Developer of tyndur - community OS of Lowlevel (German)
jhunterd
Posts: 12
Joined: Tue May 14, 2013 3:03 pm

Re: Wierd system reset when I try to enable paging

Post by jhunterd »

I did not know that register values were not preserved when the inline asm block ends. Thanks for telling me this.
Last edited by jhunterd on Fri May 17, 2013 2:36 pm, edited 1 time in total.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Wierd system reset when I try to enable paging

Post by bluemoon »

In fact the compiler/optimizer is free to reorder or even eliminate your assembly blocks since you didn't tell it what it clobber and there is no output, there is just no side-effect.
Check the inline assembly guide.
User avatar
sortie
Member
Member
Posts: 931
Joined: Wed Mar 21, 2012 3:01 pm
Libera.chat IRC: sortie

Re: Wierd system reset when I try to enable paging

Post by sortie »

Kevin wrote:
sortie wrote:Beware of your inline assembly. [...]
You're explaining some of the subtleties here, but you're missing the one big problem with the code:
Read my post a bit more carefully, I did say there was no such guarantee. Admittedly, I wasn't trying to give all the answers, but rather point out that inline assembly is very subtle and that you should study it carefully before using it, rather than giving an incomplete list of things to watch out for.
Post Reply