Re: Real Mode Confusion
Posted: Thu Oct 27, 2011 2:02 pm
Well he removed ret, and now I know more about the int command
Thanks
Thanks
The Place to Start for Operating System Developers
http://f.osdev.org/
Code: Select all
int 0x10
[section .bss]
stack:
resb 0x600
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.Combuster wrote:You know what happens after the int 0x10 now?
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)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.
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."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)
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
Take this: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.
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
It should: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.
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.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'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).I'm now getting one "SLDT: not recognized in real or v8086 mode"
Code: Select all
00436860000i[CPU0 ] | ESP=00115c9b EBP=00117fe9
Code: Select all
00436860000i[CPU0 ] | EIP=00000407 (00000407)
Or, probably the Real mode IVT is overwritten.Edit: It appears selectors will change based on when I load the real mode IDT
Not yet; I'm still working on getting it to change video mode.mitikoro wrote:you have code to return to PM, do you? does the code actually change video mode?
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
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.mitikoro wrote:the data segment registers are set to 0x4000, why?
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: