Page 1 of 2

Going into protected mode fails

Posted: Mon Mar 07, 2022 5:05 am
by siavoshkc
I am trying to enable protected mode with this assembly code

Code: Select all

cli
xor ax, ax
mov ds, ax
db 66h
lgdt[gdt_desc]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp 01h:clear_pipe
[BITS 32]
clear_pipe:
mov ax, 2h 
mov ds, ax
;mov ss, ax 
mov esp, 090000h
;mov al, 1Bh
;mov ah, 'P'
;mov edx, 0B8000h
;mov [edx], ax
mov byte [0B8000h], 'P'
mov byte [0B8001h], 1Bh
jmp $
And here is my .data

Code: Select all

gdt:
gdt_null:
dq 0
gdt_code:
dw 0FFFFh ;0-15
dw 0 ;16-31
db 0;0-7
db 10011010b ;8-15
db 11001111b ;GB0(1:avl)(4:limit)
db 0
gdt_data:
dw 0FFFFh
dw 0
db 0
db 10010010b
db 11001111b
db 0
gdt_end:
gdt_desc:
dw gdt_end - gdt
dd gdt
TIMES 510 - ($ - $$) db 0	;Fill the rest of sector with nop
db 0x55,0xAA
This fails in Bochs 2.7 with the following error
00036095263i[BIOS ] Booting from 0000:7c00
00036095377e[CPU0 ] jump_protected: cs == 0
00036095377e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d)
00036095377e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x08)
00036095377i[CPU0 ] CPU is in protected mode (active)
00036095377i[CPU0 ] CS.mode = 16 bit
00036095377i[CPU0 ] SS.mode = 16 bit
00036095377i[CPU0 ] EFER = 0x00000000
00036095377i[CPU0 ] | EAX=60000011 EBX=00000000 ECX=00090000 EDX=00000080
00036095377i[CPU0 ] | ESP=0000ffd6 EBP=00000000 ESI=000e0000 EDI=0000ffac
00036095377i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
00036095377i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00036095377i[CPU0 ] | CS:0000( 0004| 0| 0) 00000000 0000ffff 0 0
00036095377i[CPU0 ] | DS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
00036095377i[CPU0 ] | SS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
00036095377i[CPU0 ] | ES:0000( 0005| 0| 0) 00000000 0000ffff 0 0
00036095377i[CPU0 ] | FS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
00036095377i[CPU0 ] | GS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
00036095377i[CPU0 ] | EIP=00007c15 (00007c15)
00036095377i[CPU0 ] | CR0=0x60000011 CR2=0x00000000
00036095377i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00036095377i[CPU0 ] 0x0000000000007c15>> jmpf 0x0001:7c1a : EA1A7C0100
00036095377e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00036095377i[SYS ] bx_pc_system_c::Reset(HARDWARE) called
Can't figure out why it says jump_protected: cs == 0 while we see jmpf 0x0001:7c1a. Obviously segment selector is 1 not null.

Re: Going into protected mode fails

Posted: Mon Mar 07, 2022 5:28 am
by iansjack
jmp 01h:clear_pipe
01h is never a valid segment selector. You probably mean 08h.

Re: Going into protected mode fails

Posted: Mon Mar 07, 2022 5:40 am
by siavoshkc
iansjack wrote:
jmp 01h:clear_pipe
01h is never a valid segment selector. You probably mean 08h.
Actually it was 8h in my source tutorial text. But I don't understand why. First selector is all zero, second 8 bytes is my code seg descriptor. So I supposed I should set selector to one. Why 8? Manual says processor multiplies selector by 8 to reach the designated location in descriptor table.

Re: Going into protected mode fails

Posted: Mon Mar 07, 2022 6:36 am
by iansjack
It is a bit confusing. The index is bits 3-15 of the selector, so for index 1 the selector is 8, for index 2 it's 16, etc.

See https://wiki.osdev.org/Selector .

Re: Going into protected mode fails

Posted: Mon Mar 07, 2022 1:17 pm
by siavoshkc
I fixed that. And also made ds and ss 10h accordingly. Now there is no error but 'P' is not printed.

It maybe screen mode.

Re: Going into protected mode fails

Posted: Tue Mar 08, 2022 9:13 am
by iansjack
I can't see an obvious reason why that shouldn't work (assuming your data segment descriptor is valid). Have you tried it in qemu as well as Bochs?

Silly question, but your Bochs is booting in text mode, not graphics?

Re: Going into protected mode fails

Posted: Tue Mar 08, 2022 2:18 pm
by siavoshkc
I think it is because of VGA mode. when I use int 10h with al = 3 it works after going to protected mode. So my conclusion is that Bochs comes up in graphics mode while we need text mode. Now I like to change video mode in pmode.

Re: Going into protected mode fails

Posted: Tue Mar 08, 2022 2:44 pm
by iansjack
If you are not in a text mode then writing to B8000h will do nothing. In graphics modes you have to construct the text from individual pixels, and the graphics buffer will not be B8000h. Unless you are trying to draw graphics stick with text mode to begin with.

Re: Going into protected mode fails

Posted: Tue Mar 08, 2022 2:50 pm
by Octocontrabass
siavoshkc wrote:So my conclusion is that Bochs comes up in graphics mode while we need text mode.
If you're using the default Bochs BIOS, it definitely does not do that.

It's more likely you have some kind of bug elsewhere that prevents the text from appearing. (Or it could be an emulator bug. I'm not sure if Bochs ever had this problem, but some versions of QEMU won't show the last screen updates when you halt the CPU.)

Re: Going into protected mode fails

Posted: Wed Mar 09, 2022 12:37 am
by iansjack
But the OP's code doesn't halt the processor, and he says it works when using int 10h to set text mode.

I'm not familiar with Bochs but there must be some way to check what mode the video is set to.

Re: Going into protected mode fails

Posted: Wed Mar 09, 2022 3:46 am
by siavoshkc
iansjack wrote:But the OP's code doesn't halt the processor, and he says it works when using int 10h to set text mode.

I'm not familiar with Bochs but there must be some way to check what mode the video is set to.
The way is to read VGA registers which I will do soon.

Re: Going into protected mode fails

Posted: Wed Mar 09, 2022 11:32 am
by Octocontrabass
iansjack wrote:But the OP's code doesn't halt the processor,
Emulators like Bochs could recognize "jmp $" with interrupts disabled as halting the processor, since there's no way to break from the loop.
iansjack wrote:and he says it works when using int 10h to set text mode.
But the reason it works could be anything. Maybe shifting the code to a different address fixes the problem. Maybe the difference in execution time causes Bochs to display the output before halting. Maybe there's something else wrong that would only be apparent if we saw all of the code, including build scripts.
iansjack wrote:I'm not familiar with Bochs but there must be some way to check what mode the video is set to.
When the BIOS jumps to the bootloader, it's mode 3, same as any other PC with color VGA. (Monochrome VGA boots to mode 7, but who has the right hardware to set that up?)

You can call INT 0x10 AH=0x0F to check the current mode if you think it's being changed from the default somehow.

Re: Going into protected mode fails

Posted: Wed Mar 09, 2022 12:56 pm
by iansjack
Qemu doesn't work in the way you suggest, as a loop without "hlt" consumes a lot of CPU time (makes my Mac Mini sound like a jet plane). But, as I said, I'm not familiar with Bochs, so it may be that it inserts the halt instruction. That would, IMO, be a severe fault - perhaps it's as well that I don't use Bochs. I want an emulator to do what I ask, not what it thinks I should want.

I think the OP should try qemu.

Re: Going into protected mode fails

Posted: Wed Mar 09, 2022 2:20 pm
by Octocontrabass
iansjack wrote:Qemu doesn't work in the way you suggest, as a loop without "hlt" consumes a lot of CPU time (makes my Mac Mini sound like a jet plane).
Either QEMU isn't smart enough to recognize the infinite loop or you're using hardware acceleration (which, as far as I know, has no mechanism to recognize such loops).
iansjack wrote:But, as I said, I'm not familiar with Bochs, so it may be that it inserts the halt instruction. That would, IMO, be a severe fault - perhaps it's as well that I don't use Bochs. I want an emulator to do what I ask, not what it thinks I should want.
I'm not suggesting that an emulator should execute any code you didn't write. I'm suggesting that it could recognize the CPU will get stuck in the "jmp $" loop and optimize for that case by waiting for an event that will break the loop instead of wasting host CPU power explicitly executing each iteration. (This type of optimization is very common for emulators of CPUs that don't have a HLT-like instruction.)

Re: Going into protected mode fails

Posted: Wed Mar 09, 2022 2:37 pm
by iansjack
But I can easily think of an example where such behaviour would break a program because it is increasing the text size. "Smart" is the very last word I would use for such behaviour.