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.
Hi,
I've written a real-mode OS with a console so the user can give commands to it. The bootsector of the flopp disk just loads sector 1 - 19 to the position 0X1000:0x0000 and jumps to it to execute the OS. This works perfectly. Now if the user enters 'PM' at the console the system shut switch to protected mode. But this doesn't work and I don't why. Maybe I've missed something
; Code is now at 0x1000x0x0000
; Here is some code of my real-mode is.
; User enters 'PM'
jmp kernel_pmode:
; Here are also some functions of my real-mode OS
; Let's try to switch
kernel_pmode:
jmp p_start
gdt:
gdt_null:
dd 0x00
dd 0x00
gdt_code:
dw 0xFFFF ; Size of 65535
dw 0x00
db 0x1000 ;Because code is at 0x1000:0x0000
db 10011010b ;segment is in memory, priority 0, executable and readable
db 11001111b ;4096 KB, 80386 segment
db 0x00
gdt_data:
dw 0xFFFF ; Size of 65535
dw 0x00
db 0x1000 ;Because code is at 0x1000:0x0000
db 10010010b ;segment is in memory, priority 0, writeable and readable
db 11001111b ;4096 KB, 80386 segment
db 0x00
gdt_end:
GDT32:
Limit dw gdt_end - gdt - 1 ;limit (size)
BaseAdr dd gdt
p_start:
lgdt [GDT32]
cli
mov eax, 000000011h
mov cr0, eax
; "FAR-JMP"
db 0eah
dw now_in_prot
dw 0x08
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 32-Bit protected mode
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
now_in_prot:
jmp $
You load it with int 13h at 0X1000:0x0000, but are you sure your above code is actually running there? What's your org xxxx value?
For example, if you have org 0 you would have to adjust all your memory references so they point to 0X1000:0x0000 or else you'd be running code (or even data) contained elsewhere instead of your PM code.
Also, when switching to PM without paging, you usually only have to set the PE bit on (i.e. bit 0):
My bootloader has org 0x7c20, but my kernel didn't has any org xxxx. So I tried org 0x1000, but now the kernel doesn't work correctly. Any other possibilities for org xxxx or something else?
doesn't the limit come *after* the base address in the gdt pointer?
No, the limit is 0-15 and the base is 16-47 (or 16-79).
@sevobal:
My bootloader has org 0x7c20
0x7c20?
org sets the start adresse of the actual segment in which org is placed.
org xxxx sets the address where the rest of your code is expected to be running, i.e. it adds xxxx to every memory reference in your code. Keep in mind it doesn't actually move anything.
looks like the base of your CS is really wrong. why do you have a base anyway. It is way safer to just use zero. Further more you are in protected mode now so set DS en SS also to the correct value 0x10 in your case.
You must add the address (10000h) to all your memory references (including "dw now_in_prot"), but this may be a problem in 16bit code so I suggest you divide all your addresses by 16 (eg: 1000h->100h, 10000h->1000h).
You indeed have to set ds and ss, but that not what's causingthe tripple fault anyway.
p_start:
mov ax,cs
and eax,0FFFFh
shl eax,4
add ax,p_start
your code is assembled to the start of the file while you try to modify the GDT to make the offset relative to some point halfway into the file.
Other than that, you get an error that you are calling a call gate, which is something not present in your GDT. That means it either got corrupted or that you are looking at something that isn't the GDT
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]