Page 2 of 3

Re: Real Mode Confusion

Posted: Thu Oct 27, 2011 2:02 pm
by theseankelly
Well he removed ret, and now I know more about the int command :)

Thanks

Re: Real Mode Confusion

Posted: Thu Oct 27, 2011 4:49 pm
by Combuster

Code: Select all

   int 0x10
[section .bss]
stack:
   resb 0x600
You know what happens after the int 0x10 now?

Re: Real Mode Confusion

Posted: Thu Oct 27, 2011 5:01 pm
by RobertF
Combuster wrote:You know what happens after the int 0x10 now?
I'm assuming the next thing to execute would be a bunch of uninitialized data? Although I feel like I'm wrong because I get the same result regardless of whether I do nothing after the int 0x10 or just loop.

Re: Real Mode Confusion

Posted: Fri Oct 28, 2011 4:09 am
by Chandra
RobertF wrote:I'm assuming the next thing to execute would be a bunch of uninitialized data? Although I feel like I'm wrong because I get the same result regardless of whether I do nothing after the int 0x10 or just loop.
Check the Bochs debug window to make sure you've actually entered Real Mode. Examine the size of segment registers. Once that is done, fix the stack, again.(Hint: Your approach is right but not the implementation)

Re: Real Mode Confusion

Posted: Sat Oct 29, 2011 6:14 am
by RobertF
Chandra wrote:Check the Bochs debug window to make sure you've actually entered Real Mode. Examine the size of segment registers. Once that is done, fix the stack, again.(Hint: Your approach is right but not the implementation)
I'm completely baffled. Using the same code from before, which didn't cause any errors (although still didn't call the BIOS), I'm now getting one "SLDT: not recognized in real or v8086 mode" and a bunch of "LOCK prefix unallowed."

Code: Select all

00436860000i[CPU0 ] CPU is in real mode (active)
00436860000i[CPU0 ] CS.d_b = 16 bit
00436860000i[CPU0 ] SS.d_b = 16 bit
00436860000i[CPU0 ] | EAX=001bfb01  EBX=00000541  ECX=001b0a85  EDX=001ba9ea
00436860000i[CPU0 ] | ESP=00115c9b  EBP=00117fe9  ESI=0002c63a  EDI=0002c6db
00436860000i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt OF df if tf sf ZF AF PF CF
00436860000i[CPU0 ] | SEG selector     base    limit G D
00436860000i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00436860000i[CPU0 ] |  CS:0000( 0003| 0|  0) 00000000 000fffff 0 0
00436860000i[CPU0 ] |  DS:c63a( 0004| 0|  0) 000c63a0 000fffff 0 0
00436860000i[CPU0 ] |  SS:ffff( 0004| 0|  0) 000ffff0 000fffff 0 0
00436860000i[CPU0 ] |  ES:0000( 0004| 0|  0) 00000000 000fffff 0 0
00436860000i[CPU0 ] |  FS:0000( 0004| 0|  0) 00000000 000fffff 0 0
00436860000i[CPU0 ] |  GS:0000( 0004| 0|  0) 00000000 000fffff 0 0
00436860000i[CPU0 ] | EIP=00000407 (00000407)
00436860000i[CPU0 ] | CR0=0x60000010 CR2=0x00000000
00436860000i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00436860000i[CPU0 ] 0x00000407>> add byte ptr ds:[bx+si], al : 0000


So I am in real mode, at least. I thought the fact that CS and SS being 16-bit was a hint, but I don't see how. Before, when I didn't get the errors I am now, the ss selector stayed at 0. I notice now it's at its limit. Is this why I'm getting the "LOCK prefix unallowed" errors?

Is there anything I could read that would give a little insight on how I should properly set up the stack? I've read the segmentation page on the wiki as turdus suggested, but from what I gathered, I thought I would be able to make the stack pointer anywhere inside the 16KB window and it would work fine.

Re: Real Mode Confusion

Posted: Sat Oct 29, 2011 6:22 am
by Chandra
Is there anything I could read that would give a little insight on how I should properly set up the stack? I've read the segmentation page on the wiki as turdus suggested, but from what I gathered, I thought I would be able to make the stack pointer anywhere inside the 16KB window and it would work fine.
Take this:

Code: Select all

resb 0x400 ; Reserve 1 kb space   
stack:

Code: Select all

00436860000i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00436860000i[CPU0 ] |  CS:0000( 0003| 0|  0) 00000000 000fffff 0 0
00436860000i[CPU0 ] |  DS:c63a( 0004| 0|  0) 000c63a0 000fffff 0 0
00436860000i[CPU0 ] |  SS:ffff( 0004| 0|  0) 000ffff0 000fffff 0 0
00436860000i[CPU0 ] |  ES:0000( 0004| 0|  0) 00000000 000fffff 0 0
00436860000i[CPU0 ] |  FS:0000( 0004| 0|  0) 00000000 000fffff 0 0
00436860000i[CPU0 ] |  GS:0000( 0004| 0|  0) 00000000 000fffff 0 0
That gives me the feeling that you've loaded invalid selectors. Are you sure 0x18 and 0x20 corresponds to the proper real mode code and data selectors? You should double check the GDT structure for these selectors and if no progress, post that code too.

Re: Real Mode Confusion

Posted: Sat Oct 29, 2011 6:31 am
by RobertF
Chandra wrote:That gives me the feeling that you've loaded invalid selectors. Are you sure 0x18 and 0x20 corresponds to the proper real mode code and data selectors? You should double check the GDT structure for these selectors and if no progress, post that code too.
It should:

Code: Select all

  
    gdt_set_gate(0, 0, 0, 0, 0);          
    gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
    gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
    gdt_set_gate(3, 0, 0xFFFFF, 0x9A, 0);   
    gdt_set_gate(4, 0, 0xFFFFF, 0x92, 0);  
Edit: It appears selectors will change based on when I load the real mode IDT

Re: Real Mode Confusion

Posted: Sat Oct 29, 2011 7:31 am
by Chandra
RobertF wrote:

Code: Select all

 
gdt_set_gate(0, 0, 0, 0, 0); 
gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
gdt_set_gate(3, 0, 0xFFFFF, 0x9A, 0); 
gdt_set_gate(4, 0, 0xFFFFF, 0x92, 0); 
That looks fine.
I'm now getting one "SLDT: not recognized in real or v8086 mode"
That's weird. I don't suppose you've executed any such instruction from your code. Now the only way from here is to attach full source code(try to keep it minimal as possible, including only stuffs that are related).

Code: Select all

00436860000i[CPU0 ] | ESP=00115c9b  EBP=00117fe9 
Fix the stack.

Code: Select all

00436860000i[CPU0 ] | EIP=00000407 (00000407)
Quite possible that one of the far jmp is broken.
Edit: It appears selectors will change based on when I load the real mode IDT
Or, probably the Real mode IVT is overwritten.

Re: Real Mode Confusion

Posted: Sat Oct 29, 2011 12:11 pm
by mitikoro
you have code to return to PM, do you? does the code actually change video mode?

Re: Real Mode Confusion

Posted: Sat Oct 29, 2011 12:41 pm
by RobertF
mitikoro wrote:you have code to return to PM, do you? does the code actually change video mode?
Not yet; I'm still working on getting it to change video mode.

Speaking of, I played around a bit and noticed I was overwriting the IVT (stupidly). Although I fixed that issue, it still wouldn't work so I copied the IVT to 0x4000, and now after tweaking the code more, I got to somewhere that looks close to what I need.

Code: Select all

00351898970e[CPU0 ] interrupt(real mode) vector > idtr.limit
00351898970e[CPU0 ] interrupt(real mode) vector > idtr.limit
00351898970e[CPU0 ] interrupt(real mode) vector > idtr.limit
00351898970i[CPU0 ] CPU is in real mode (active)
00351898970i[CPU0 ] CS.d_b = 16 bit
00351898970i[CPU0 ] SS.d_b = 16 bit
00351898970i[CPU0 ] | EAX=60000003  EBX=0002c560  ECX=00000001  EDX=000003d5
00351898970i[CPU0 ] | ESP=00008264  EBP=00117fe8  ESI=0002c6da  EDI=0002c6db
00351898970i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df IF tf sf zf af pf cf
00351898970i[CPU0 ] | SEG selector     base    limit G D
00351898970i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00351898970i[CPU0 ] |  CS:0000( 0003| 0|  0) 00000000 000fffff 0 0
00351898970i[CPU0 ] |  DS:4000( 0004| 0|  0) 00040000 000fffff 0 0
00351898970i[CPU0 ] |  SS:4000( 0004| 0|  0) 00040000 000fffff 0 0
00351898970i[CPU0 ] |  ES:4000( 0004| 0|  0) 00040000 000fffff 0 0
00351898970i[CPU0 ] |  FS:4000( 0004| 0|  0) 00040000 000fffff 0 0
00351898970i[CPU0 ] |  GS:4000( 0004| 0|  0) 00040000 000fffff 0 0
00351898970i[CPU0 ] | EIP=00007e5c (00007e5c)
00351898970i[CPU0 ] | CR0=0x60000010 CR2=0x00000000
00351898970i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00351898970i[CPU0 ] 0x00007e5c>> int 0x10 : CD10
00351898970e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
Although that exception is obviously not a good thing. I'm getting "interrupt(real mode) vector ..." error because I'm loading the IDT after I set the real mode segments. I probably shouldn't do that, but as I said, what I have right now seems close. (I tried changing the limit of the IDT but that didn't seem to fix it)

Re: Real Mode Confusion

Posted: Sat Oct 29, 2011 1:03 pm
by mitikoro
the data segment registers are set to 0x4000, why?

Re: Real Mode Confusion

Posted: Sat Oct 29, 2011 1:10 pm
by RobertF
mitikoro wrote:the data segment registers are set to 0x4000, why?
I thought copying the first 0x400 bytes to 0x4000 and setting the segment registers to 0x4000 would make a difference—apparently I'm wrong because I can set the segment registers to anything and get the same error I've been getting. Back to square one, I guess.

Re: Real Mode Confusion

Posted: Sat Oct 29, 2011 1:24 pm
by mitikoro
In real mode, if you set a segment register to 0x4000, any access using that register will end up at 0x4000*16 + offset.
So if you copy the IDT (using movs) with ES set to 0x4000, you'll end up copying it at 0x40000, not 0x4000.
Anyway, I don't think relocating the IDT is a good idea. Would you mind posting the new code?

Re: Real Mode Confusion

Posted: Sat Oct 29, 2011 1:29 pm
by RobertF

Code: Select all

[bits 32]
[org 0x7E00]

PMode32:
	cli          	        	; disable interrupts 
   
	mov eax, cr0
	and eax, 0x7FFFFFFF      	; clear pg bit 
	mov cr0, eax 
   
	xor eax, eax
	mov cr3, eax    		    ; flush TLB 
   
	jmp 0x18:PMode16     		; far jump to 16-bit protected mode 
[bits 16]
RealIDT:
	dw 0x3FF 
	dd 0x0
PMode16:
	mov ax, 0x20          		; load 16-bit gdt data segment 
	mov ds, ax 
	mov es, ax
	mov fs, ax
	mov gs, ax
	mov ss, ax

	mov eax, cr0
	and eax, 0xFFFFFFFE      	; clear pe bit 
	mov cr0, eax 

	jmp 0:RMode            		; far jump to real mode 
RMode:
	mov esp, stack				; should I be using sp instead?
    
	mov ax, 0x0
	mov ds, ax
	mov es, ax
	mov fs, ax 
	mov gs, ax
	mov ss, ax
   	
	lidt [RealIDT]

	sti

	mov ah,0x0
	mov al,0x13
	int 0x10

	.loop: jmp .loop			; loop for now
[section .bss]
	resb 0x400 ; Reserve 1 kb space   
stack:

Re: Real Mode Confusion

Posted: Sat Oct 29, 2011 1:45 pm
by mitikoro
Try moving the lidt instruction to 32-bit PM, just after the cli opcode. Also, dump the value of the IDTR before the BIOS call
(using bochs debugger, command sregs)